gxcldev.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /* Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gxcldev.h,v 1.4 2000/11/05 00:34:24 lpd Exp $ */
  16. /* Internal definitions for Ghostscript command lists. */
  17. #ifndef gxcldev_INCLUDED
  18. # define gxcldev_INCLUDED
  19. #include "gxclist.h"
  20. #include "gsropt.h"
  21. #include "gxht.h" /* for gxdht.h */
  22. #include "gxtmap.h" /* ditto */
  23. #include "gxdht.h" /* for halftones */
  24. #include "strimpl.h" /* for compressed bitmaps */
  25. #include "scfx.h" /* ditto */
  26. #include "srlx.h" /* ditto */
  27. /* ---------------- Commands ---------------- */
  28. /* Define the compression modes for bitmaps. */
  29. /*#define cmd_compress_none 0 *//* (implicit) */
  30. #define cmd_compress_rle 1
  31. #define cmd_compress_cfe 2
  32. #define cmd_mask_compress_any\
  33. ((1 << cmd_compress_rle) | (1 << cmd_compress_cfe))
  34. /* Exported by gxclutil.c */
  35. void clist_rle_init(P1(stream_RLE_state *ss));
  36. void clist_rld_init(P1(stream_RLD_state *ss));
  37. void clist_cfe_init(P3(stream_CFE_state *ss, int width, gs_memory_t *mem));
  38. void clist_cfd_init(P4(stream_CFD_state *ss, int width, int height,
  39. gs_memory_t *mem));
  40. /*
  41. * A command always consists of an operation followed by operands;
  42. * the syntax of the operands depends on the operation.
  43. * In the operation definitions below:
  44. * + (prefixed) means the operand is in the low 4 bits of the opcode.
  45. * # means a variable-size operand encoded with the variable-size
  46. * integer encoding.
  47. * % means a variable-size operand encoded with the variable-size
  48. * fixed coordinate encoding.
  49. * $ means a color sized according to the device depth.
  50. * <> means the operand size depends on other state information
  51. * and/or previous operands.
  52. */
  53. typedef enum {
  54. cmd_op_misc = 0x00, /* (see below) */
  55. cmd_opv_end_run = 0x00, /* (nothing) */
  56. cmd_opv_set_tile_size = 0x01, /* rs?(1)nry?(1)nrx?(1)depth-1(5), */
  57. /* rep_width#, rep_height#, */
  58. /* [, nreps_x#][, nreps_y #] */
  59. /* [, rep_shift#] */
  60. cmd_opv_set_tile_phase = 0x02, /* x#, y# */
  61. cmd_opv_set_tile_bits = 0x03, /* index#, offset#, <bits> */
  62. cmd_opv_set_bits = 0x04, /* depth*4+compress, width#, height#, */
  63. /* index#, offset#, <bits> */
  64. cmd_opv_set_tile_color = 0x05, /* (nothing; next set/delta_color */
  65. /* refers to tile) */
  66. cmd_opv_set_misc = 0x06,
  67. #define cmd_set_misc_lop (0 << 6) /* 00: lop_lsb(6), lop_msb# */
  68. #define cmd_set_misc_data_x (1 << 6) /* 01: more(1)dx_lsb(5)[, dx_msb#] */
  69. #define cmd_set_misc_map (2 << 6) /* 10: contents(2)map_index(4) */
  70. /* [, n x frac] */
  71. #define cmd_set_misc_halftone (3 << 6) /* 11: type(6), num_comp# */
  72. cmd_opv_enable_lop = 0x07, /* (nothing) */
  73. cmd_opv_disable_lop = 0x08, /* (nothing) */
  74. cmd_opv_set_ht_order = 0x09, /* component+1#[, cname#], */
  75. /* width#, height#, raster#, */
  76. /* shift#, num_levels#, num_bits#, */
  77. /* order_procs_index */
  78. cmd_opv_set_ht_data = 0x0a, /* n, n x (uint|gx_ht_bit|ushort) */
  79. cmd_opv_end_page = 0x0b, /* (nothing) */
  80. cmd_opv_delta2_color0 = 0x0c, /* dr5dg6db5 or dc4dm4dy4dk4 */
  81. #define cmd_delta2_24_bias 0x00102010
  82. #define cmd_delta2_24_mask 0x001f3f1f
  83. #define cmd_delta2_32_bias 0x08080808
  84. #define cmd_delta2_32_mask 0x0f0f0f0f
  85. cmd_opv_delta2_color1 = 0x0d, /* <<same as color0>> */
  86. cmd_opv_set_copy_color = 0x0e, /* (nothing) */
  87. cmd_opv_set_copy_alpha = 0x0f, /* (nothing) */
  88. cmd_op_set_color0 = 0x10, /* +15 = transparent | */
  89. /* +0, color$ | +dcolor+8 | */
  90. /* +dr4, dg4db4 | */
  91. /* +dc3dm1, dm2dy3dk3 */
  92. cmd_op_set_color1 = 0x20, /* <<same as color0>> */
  93. #define cmd_delta1_24_bias 0x00080808
  94. #define cmd_delta1_24_mask 0x000f0f0f
  95. #define cmd_delta1_32_bias 0x04040404
  96. #define cmd_delta1_32_mask 0x07070707
  97. cmd_op_fill_rect = 0x30, /* +dy2dh2, x#, w# | +0, rect# */
  98. cmd_op_fill_rect_short = 0x40, /* +dh, dx, dw | +0, rect_short */
  99. cmd_op_fill_rect_tiny = 0x50, /* +dw+0, rect_tiny | +dw+8 */
  100. cmd_op_tile_rect = 0x60, /* +dy2dh2, x#, w# | +0, rect# */
  101. cmd_op_tile_rect_short = 0x70, /* +dh, dx, dw | +0, rect_short */
  102. cmd_op_tile_rect_tiny = 0x80, /* +dw+0, rect_tiny | +dw+8 */
  103. cmd_op_copy_mono = 0x90, /* +compress, x#, y#, (w+data_x)#, */
  104. /* h#, <bits> | */
  105. #define cmd_copy_ht_color 4
  106. /* +4+compress, x#, y#, (w+data_x)#, */
  107. /* h#, <bits> | */
  108. #define cmd_copy_use_tile 8
  109. /* +8 (use tile), x#, y# | */
  110. /* +12 (use tile), x#, y# */
  111. cmd_op_copy_color_alpha = 0xa0, /* (same as copy_mono, except: */
  112. /* if color, ignore ht_color; */
  113. /* if alpha & !use_tile, depth is */
  114. /* first operand) */
  115. cmd_op_delta_tile_index = 0xb0, /* +delta+8 */
  116. cmd_op_set_tile_index = 0xc0 /* +index[11:8], index[7:0] */
  117. } gx_cmd_op;
  118. #define cmd_op_name_strings\
  119. "(misc)", "set_color[0]", "set_color[1]", "fill_rect",\
  120. "fill_rect_short", "fill_rect_tiny", "tile_rect", "tile_rect_short",\
  121. "tile_rect_tiny", "copy_mono", "copy_color_alpha", "delta_tile_index",\
  122. "set_tile_index", "(misc2)", "(segment)", "(path)"
  123. #define cmd_misc_op_name_strings\
  124. "end_run", "set_tile_size", "set_tile_phase", "set_tile_bits",\
  125. "set_bits", "set_tile_color", "set_misc", "enable_lop",\
  126. "disable_lop", "set_ht_order", "set_ht_data", "end_page",\
  127. "delta2_color0", "delta2_color1", "set_copy_color", "set_copy_alpha",
  128. #ifdef DEBUG
  129. extern const char *const cmd_op_names[16];
  130. extern const char *const *const cmd_sub_op_names[16];
  131. #endif
  132. /*
  133. * Define the size of the largest command, not counting any bitmap or
  134. * similar variable-length operands.
  135. * The variable-size integer encoding is little-endian. The low 7 bits
  136. * of each byte contain data; the top bit is 1 for all but the last byte.
  137. */
  138. #define cmd_max_intsize(siz)\
  139. (((siz) * 8 + 6) / 7)
  140. #define cmd_largest_size\
  141. (2 + (1 + cmd_max_dash) * sizeof(float))
  142. /* ---------------- Command parameters ---------------- */
  143. /* Rectangle */
  144. typedef struct {
  145. int x, y, width, height;
  146. } gx_cmd_rect;
  147. /* Short rectangle */
  148. typedef struct {
  149. byte dx, dwidth, dy, dheight; /* dy and dheight are optional */
  150. } gx_cmd_rect_short;
  151. #define cmd_min_short (-128)
  152. #define cmd_max_short 127
  153. /* Tiny rectangle */
  154. #define cmd_min_dw_tiny (-4)
  155. #define cmd_max_dw_tiny 3
  156. typedef struct {
  157. unsigned dx:4;
  158. unsigned dy:4;
  159. } gx_cmd_rect_tiny;
  160. #define cmd_min_dxy_tiny (-8)
  161. #define cmd_max_dxy_tiny 7
  162. /*
  163. * When we write bitmaps, we remove raster padding selectively:
  164. * - If the bitmap is compressed, we don't remove any padding;
  165. * - If the width is <= 6 bytes, we remove all the padding;
  166. * - If the bitmap is only 1 scan line high, we remove the padding;
  167. * - If the bitmap is going to be replicated horizontally (see the
  168. * definition of decompress_spread below), we remove the padding;
  169. * - Otherwise, we remove the padding only from the last scan line.
  170. */
  171. #define cmd_max_short_width_bytes 6
  172. #define cmd_max_short_width_bits (cmd_max_short_width_bytes * 8)
  173. /*
  174. * Determine the (possibly unpadded) width in bytes for writing a bitmap,
  175. * per the algorithm just outlined. If compression_mask has any of the
  176. * cmd_mask_compress_any bits set, we assume the bitmap will be compressed.
  177. * Return the total size of the bitmap.
  178. */
  179. uint clist_bitmap_bytes(P5(uint width_bits, uint height,
  180. int compression_mask,
  181. uint * width_bytes, uint * raster));
  182. /*
  183. * For halftone cells, we always write an unreplicated bitmap, but we
  184. * reserve cache space for the reading pass based on the replicated size.
  185. * See the clist_change_tile procedure for the algorithm that chooses the
  186. * replication factors.
  187. */
  188. /* ---------------- Block file entries ---------------- */
  189. typedef struct cmd_block_s {
  190. int band_min, band_max;
  191. #define cmd_band_end (-1) /* end of band file */
  192. long pos; /* starting position in cfile */
  193. } cmd_block;
  194. /* ---------------- Band state ---------------- */
  195. /* Remember the current state of one band when writing or reading. */
  196. struct gx_clist_state_s {
  197. gx_color_index colors[2]; /* most recent colors */
  198. uint tile_index; /* most recent tile index */
  199. gx_bitmap_id tile_id; /* most recent tile id */
  200. /* Since tile table entries may be deleted and/or moved at any time, */
  201. /* the following is the only reliable way to check whether tile_index */
  202. /* references a particular tile id: */
  203. #define cls_has_tile_id(cldev, pcls, tid, offset_temp)\
  204. ((pcls)->tile_id == (tid) &&\
  205. (offset_temp = cldev->tile_table[(pcls)->tile_index].offset) != 0 &&\
  206. ((tile_slot *)(cldev->data + offset_temp))->id == (tid))
  207. gs_int_point tile_phase; /* most recent tile phase */
  208. gx_color_index tile_colors[2]; /* most recent tile colors */
  209. gx_cmd_rect rect; /* most recent rectangle */
  210. gs_logical_operation_t lop; /* most recent logical op */
  211. short lop_enabled; /* 0 = don't use lop, 1 = use lop, */
  212. /* -1 is used internally */
  213. short clip_enabled; /* 0 = don't clip, 1 = do clip, */
  214. /* -1 is used internally */
  215. bool color_is_alpha; /* for copy_color_alpha */
  216. uint known; /* flags for whether this band */
  217. /* knows various misc. parameters */
  218. /* We assign 'known' flags here from the high end; */
  219. /* gxclpath.h assigns them from the low end. */
  220. #define tile_params_known (1<<15)
  221. #define begin_image_known (1<<14) /* gxclimag.c */
  222. #define initial_known 0x3fff /* exclude tile & image params */
  223. /* Following are only used when writing */
  224. cmd_list list; /* list of commands for band */
  225. /* Following are set when writing, read when reading */
  226. ulong cost; /* cost of rendering the band */
  227. gx_colors_used_t colors_used;
  228. };
  229. /* The initial values for a band state */
  230. /*static const gx_clist_state cls_initial */
  231. #define cls_initial_values\
  232. { gx_no_color_index, gx_no_color_index },\
  233. 0, gx_no_bitmap_id,\
  234. { 0, 0 }, { gx_no_color_index, gx_no_color_index },\
  235. { 0, 0, 0, 0 }, lop_default, 0, 0, 0, initial_known,\
  236. { 0, 0 }, 0, { 0 }
  237. /* Define the size of the command buffer used for reading. */
  238. /* This is needed to split up operations with a large amount of data, */
  239. /* primarily large copy_ operations. */
  240. #define cbuf_size 800
  241. /* ---------------- Driver procedures ---------------- */
  242. /* In gxclrect.c */
  243. dev_proc_fill_rectangle(clist_fill_rectangle);
  244. dev_proc_copy_mono(clist_copy_mono);
  245. dev_proc_copy_color(clist_copy_color);
  246. dev_proc_copy_alpha(clist_copy_alpha);
  247. dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle);
  248. dev_proc_strip_copy_rop(clist_strip_copy_rop);
  249. /* In gxclimag.c */
  250. dev_proc_fill_mask(clist_fill_mask);
  251. dev_proc_begin_typed_image(clist_begin_typed_image);
  252. dev_proc_create_compositor(clist_create_compositor);
  253. /* In gxclread.c */
  254. dev_proc_get_bits_rectangle(clist_get_bits_rectangle);
  255. /* ---------------- Driver procedure support ---------------- */
  256. /*
  257. * The procedures and macros defined here are used when writing
  258. * (gxclist.c, gxclbits.c, gxclimag.c, gxclpath.c, gxclrect.c).
  259. * Note that none of the cmd_put_xxx procedures do VMerror recovery;
  260. * they convert low-memory warnings to VMerror errors.
  261. */
  262. /* ------ Exported by gxclist.c ------ */
  263. /*
  264. * Error recovery procedures for writer-side VMerrors, for async rendering
  265. * support. This logic assumes that the command list file and/or the
  266. * renderer allocate memory from the same pool as the writer. Hence, when
  267. * the writer runs out of memory, it tries to pause and let the renderer run
  268. * for a while in hope that enough memory will be freed by it to allow the
  269. * writer to allocate enough memory to proceed. Once a VMerror is detected,
  270. * error recovery proceeds in two escalating stages:
  271. *
  272. * 1) The recovery logic repeatedly calls clist_VMerror_recover(), which
  273. * waits until the next page has finished rendering. The recovery logic
  274. * keeps calling clist_VMerror_recover() until enough memory is freed,
  275. * or until clist_VMerror_recover() signals that no more pages
  276. * remain to be rendered (when return code < 0).
  277. *
  278. * 2) If enough memory is not free, the recovery logic calls
  279. * clist_VMerror_recover_flush() once. This routine terminates and
  280. * flushes out the partially-completed page that the writer is currently
  281. * writing to the command file, then waits for the partial page to finish
  282. * rendering. It then opens up a new command list "file" and resets the
  283. * state of the command list machinery to an initial state as if a new
  284. * page were beginning.
  285. *
  286. * If insufficient memory is available after the 2nd step, the situation
  287. * is the same as if it ocurred in a non-async setup: the writer program
  288. * simply used up too much memory and cannot continue.
  289. *
  290. * The first stage of error recovery (no flush) is performed without
  291. * flushing out the current page, so failing commands can simply be
  292. * restarted after such recovery. This is not true of 2nd stage recovery
  293. * (flush): as part of its operation, the flush resets the state of both
  294. * writer and renderer to initial values. In this event, the recovery logic
  295. * which called clist_try_recover_VMerror_flush() must force any pertinent
  296. * state information to be re-emitted before re-issuing the failing command.
  297. *
  298. * In case of a VMerror, the internal procedures that support the driver
  299. * procedures simply return the error code: they do not attempt recovery.
  300. * Note that all such procedures must take care that (1) they don't update
  301. * any writer state to reflect information written to the band list unless
  302. * the write actually succeeds, and (2) they are idempotent, since they may
  303. * be re-executed after first-stage VMerror recovery.
  304. *
  305. * Error recovery is only performed by the driver procedures themselves
  306. * (fill_rectangle, copy_mono, fill_path, etc.) and a few other procedures
  307. * at the same level of control. The implementation of error recovery is
  308. * packaged up in the FOR_RECTS et al macros defined below, but -- as noted
  309. * above -- recovery is not fully transparent. Other routines which perform
  310. * error recovery are those which open the device, begin a new page, or
  311. * reopen the device (put_params).
  312. */
  313. int clist_VMerror_recover(P2(gx_device_clist_writer *, int));
  314. int clist_VMerror_recover_flush(P2(gx_device_clist_writer *, int));
  315. /* Write out device parameters. */
  316. int cmd_put_params(P2(gx_device_clist_writer *, gs_param_list *));
  317. /* Conditionally keep command statistics. */
  318. #ifdef DEBUG
  319. int cmd_count_op(P2(int op, uint size));
  320. void cmd_uncount_op(P2(int op, uint size));
  321. # define cmd_count_add1(v) (v++)
  322. #else
  323. # define cmd_count_op(op, size) (op)
  324. # define cmd_uncount_op(op, size) DO_NOTHING
  325. # define cmd_count_add1(v) DO_NOTHING
  326. #endif
  327. /* Add a command to the appropriate band list, */
  328. /* and allocate space for its data. */
  329. byte *cmd_put_list_op(P3(gx_device_clist_writer * cldev, cmd_list * pcl, uint size));
  330. #ifdef DEBUG
  331. byte *cmd_put_op(P3(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size));
  332. #else
  333. # define cmd_put_op(cldev, pcls, size)\
  334. cmd_put_list_op(cldev, &(pcls)->list, size)
  335. #endif
  336. /* Call cmd_put_op and update stats if no error occurs. */
  337. #define set_cmd_put_op(dp, cldev, pcls, op, csize)\
  338. ( (dp = cmd_put_op(cldev, pcls, csize)) == 0 ?\
  339. (cldev)->error_code :\
  340. (*dp = cmd_count_op(op, csize), 0) )
  341. /* Add a command for all bands or a range of bands. */
  342. byte *cmd_put_range_op(P4(gx_device_clist_writer * cldev, int band_min,
  343. int band_max, uint size));
  344. #define cmd_put_all_op(cldev, size)\
  345. cmd_put_range_op(cldev, 0, (cldev)->nbands - 1, size)
  346. /* Call cmd_put_all/range_op and update stats if no error occurs. */
  347. #define set_cmd_put_range_op(dp, cldev, op, bmin, bmax, csize)\
  348. ( (dp = cmd_put_range_op(cldev, bmin, bmax, csize)) == 0 ?\
  349. (cldev)->error_code :\
  350. (*dp = cmd_count_op(op, csize), 0) )
  351. #define set_cmd_put_all_op(dp, cldev, op, csize)\
  352. set_cmd_put_range_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize)
  353. /* Shorten the last allocated command. */
  354. /* Note that this does not adjust the statistics. */
  355. #define cmd_shorten_list_op(cldev, pcls, delta)\
  356. ((pcls)->tail->size -= (delta), (cldev)->cnext -= (delta))
  357. #define cmd_shorten_op(cldev, pcls, delta)\
  358. cmd_shorten_list_op(cldev, &(pcls)->list, delta)
  359. /* Write out the buffered commands, and reset the buffer. */
  360. /* Return 0 if OK, 1 if OK with low-memory warning, */
  361. /* or the usual negative error code. */
  362. int cmd_write_buffer(P2(gx_device_clist_writer * cldev, byte cmd_end));
  363. /* End a page by flushing the buffer and terminating the command list. */
  364. int clist_end_page(P1(gx_device_clist_writer *));
  365. /* Compute the # of bytes required to represent a variable-size integer. */
  366. /* (This works for negative integers also; they are written as though */
  367. /* they were unsigned.) */
  368. int cmd_size_w(P1(uint));
  369. #define w1byte(w) (!((w) & ~0x7f))
  370. #define w2byte(w) (!((w) & ~0x3fff))
  371. #define cmd_sizew(w)\
  372. (w1byte(w) ? 1 : w2byte(w) ? 2 : cmd_size_w((uint)(w)))
  373. #define cmd_size2w(wx,wy)\
  374. (w1byte((wx) | (wy)) ? 2 :\
  375. cmd_size_w((uint)(wx)) + cmd_size_w((uint)(wy)))
  376. #define cmd_sizexy(xy) cmd_size2w((xy).x, (xy).y)
  377. #define cmd_sizew_max ((sizeof(uint) * 8 + 6) / 7)
  378. /* Put a variable-size integer in the buffer. */
  379. byte *cmd_put_w(P2(uint, byte *));
  380. #define cmd_putw(w,dp)\
  381. (w1byte(w) ? (*dp = w, ++dp) :\
  382. w2byte(w) ? (*dp = (w) | 0x80, dp[1] = (w) >> 7, dp += 2) :\
  383. (dp = cmd_put_w((uint)(w), dp)))
  384. #define cmd_put2w(wx,wy,dp)\
  385. (w1byte((wx) | (wy)) ? (dp[0] = (wx), dp[1] = (wy), dp += 2) :\
  386. (dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), dp))))
  387. #define cmd_putxy(xy,dp) cmd_put2w((xy).x, (xy).y, dp)
  388. /* Put out a command to set a color. */
  389. typedef struct {
  390. byte set_op;
  391. byte delta2_op;
  392. bool tile_color;
  393. } clist_select_color_t;
  394. extern const clist_select_color_t
  395. clist_select_color0, clist_select_color1, clist_select_tile_color0,
  396. clist_select_tile_color1;
  397. int cmd_put_color(P5(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  398. const clist_select_color_t * select,
  399. gx_color_index color, gx_color_index * pcolor));
  400. #define cmd_set_color0(dev, pcls, color0)\
  401. cmd_put_color(dev, pcls, &clist_select_color0, color0, &(pcls)->colors[0])
  402. #define cmd_set_color1(dev, pcls, color1)\
  403. cmd_put_color(dev, pcls, &clist_select_color1, color1, &(pcls)->colors[1])
  404. /* Put out a command to set the tile colors. */
  405. int cmd_set_tile_colors(P4(gx_device_clist_writer *cldev,
  406. gx_clist_state * pcls,
  407. gx_color_index color0, gx_color_index color1));
  408. /* Put out a command to set the tile phase. */
  409. int cmd_set_tile_phase(P4(gx_device_clist_writer *cldev,
  410. gx_clist_state * pcls,
  411. int px, int py));
  412. /* Enable or disable the logical operation. */
  413. int cmd_put_enable_lop(P3(gx_device_clist_writer *, gx_clist_state *, int));
  414. #define cmd_do_enable_lop(cldev, pcls, enable)\
  415. ( (pcls)->lop_enabled == ((enable) ^ 1) &&\
  416. cmd_put_enable_lop(cldev, pcls, enable) < 0 ?\
  417. (cldev)->error_code : 0 )
  418. #define cmd_enable_lop(cldev, pcls)\
  419. cmd_do_enable_lop(cldev, pcls, 1)
  420. #define cmd_disable_lop(cldev, pcls)\
  421. cmd_do_enable_lop(cldev, pcls, 0)
  422. /* Enable or disable clipping. */
  423. int cmd_put_enable_clip(P3(gx_device_clist_writer *, gx_clist_state *, int));
  424. #define cmd_do_enable_clip(cldev, pcls, enable)\
  425. ( (pcls)->clip_enabled == ((enable) ^ 1) &&\
  426. cmd_put_enable_clip(cldev, pcls, enable) < 0 ?\
  427. (cldev)->error_code : 0 )
  428. #define cmd_enable_clip(cldev, pcls)\
  429. cmd_do_enable_clip(cldev, pcls, 1)
  430. #define cmd_disable_clip(cldev, pcls)\
  431. cmd_do_enable_clip(cldev, pcls, 0)
  432. /* Write a command to set the logical operation. */
  433. int cmd_set_lop(P3(gx_device_clist_writer *, gx_clist_state *,
  434. gs_logical_operation_t));
  435. /* Disable (if default) or enable the logical operation, setting it if */
  436. /* needed. */
  437. int cmd_update_lop(P3(gx_device_clist_writer *, gx_clist_state *,
  438. gs_logical_operation_t));
  439. /*
  440. * Define macros for dividing up an operation into bands, per the
  441. * template
  442. FOR_RECTS[_NO_ERROR] {
  443. ... process rectangle x, y, width, height in band pcls ...
  444. } END_RECTS[_NO_ERROR];
  445. * Note that FOR_RECTS resets y and height. It is OK for the code that
  446. * processes each band to reset height to a smaller (positive) value; the
  447. * vertical subdivision code in copy_mono, copy_color, and copy_alpha makes
  448. * use of this. The band processing code may `continue' (to reduce nesting
  449. * of conditionals).
  450. *
  451. * If the processing code detects an error that may be a recoverable
  452. * VMerror, the code may call ERROR_RECT(), which will attempt to fix the
  453. * VMerror by flushing and closing the band and resetting the imager state,
  454. * and then restart emitting the entire band. Before flushing the file, the
  455. * 'on_error' clause of END_RECTS_ON_ERROR (defaults to the constant 1 if
  456. * END_RECT is used) is evaluated and tested. The 'on_error' clause enables
  457. * mop-up actions to be executed before flushing, and/or selectively
  458. * inhibits the flush, close, reset and restart process. Similarly, the
  459. * 'after_recovering' clause of END_RECTS_ON_ERROR allows an action to get
  460. * performed after successfully recovering.
  461. *
  462. * The band processing code may wrap an operation with TRY_RECT { ... }
  463. * HANDLE_RECT_UNLESS(code, unless_action) (or HANDLE_RECT(code)). This will
  464. * perform local first-stage VMerror recovery, by waiting for some memory to
  465. * become free and then retrying the failed operation starting at the
  466. * TRY_RECT. If local recovery is unsuccessful, the local recovery code
  467. * calls ERROR_RECT.
  468. *
  469. * The band processing loop should use the _NO_ERROR macros iff it doesn't
  470. * call ERROR_RECT anywhere.
  471. *
  472. * In a few cases, the band processing code calls other driver procedures
  473. * (e.g., clist_copy_mono calls itself recursively if it must split up the
  474. * operation into smaller pieces) or other procedures that may attempt
  475. * VMerror recovery. In such cases, the recursive call must not attempt
  476. * second-stage VMerror recovery, since the caller would have no way of
  477. * knowing that the writer state had been reset. Such recursive calls
  478. * should be wrapped in NEST_RECT { ... } UNNEST_RECT, which causes
  479. * ERROR_RECT simply to return the error code rather than attempting
  480. * recovery. (TRY/HANDLE_RECT will still attempt local recovery, as
  481. * described above, but this is harmless since it is transparent.) By
  482. * convention, calls to cmd_put_xxx or cmd_set_xxx never attempt recovery
  483. * and so never require NEST_RECTs.
  484. *
  485. * If a put_params call fails, the device will be left in a closed state,
  486. * but higher-level code won't notice this fact. We flag this by setting
  487. * permanent_error, which prevents writing to the command list.
  488. */
  489. /*
  490. * The "if (1)" statements in the following macros are there to prevent
  491. * stupid compilers from giving "statement not reached" warnings.
  492. */
  493. #define FOR_RECTS_NO_ERROR\
  494. BEGIN\
  495. int yend = y + height;\
  496. int band_height = cdev->page_band_height;\
  497. /* no band_code */\
  498. \
  499. if (cdev->permanent_error < 0)\
  500. return (cdev->permanent_error);\
  501. do {\
  502. int band = y / band_height;\
  503. gx_clist_state *pcls = cdev->states + band;\
  504. int band_end = (band + 1) * band_height;\
  505. \
  506. height = min(band_end, yend) - y;\
  507. /* no retry_rect: */
  508. #define FOR_RECTS\
  509. BEGIN\
  510. int yend = y + height;\
  511. int band_height = cdev->page_band_height;\
  512. int band_code;\
  513. \
  514. if (cdev->permanent_error < 0)\
  515. return (cdev->permanent_error);\
  516. do {\
  517. int band = y / band_height;\
  518. gx_clist_state *pcls = cdev->states + band;\
  519. int band_end = (band + 1) * band_height;\
  520. \
  521. height = min(band_end, yend) - y;\
  522. retry_rect:\
  523. ;
  524. #define NEST_RECT ++cdev->driver_call_nesting;
  525. #define UNNEST_RECT --cdev->driver_call_nesting
  526. #define ERROR_RECT(code_value)\
  527. BEGIN\
  528. band_code = (code_value);\
  529. if (1) goto error_in_rect;\
  530. END
  531. #define TRY_RECT\
  532. BEGIN\
  533. do
  534. #define HANDLE_RECT_UNLESS(codevar, unless_clause)\
  535. while (codevar < 0 &&\
  536. (codevar = clist_VMerror_recover(cdev, codevar)) >= 0\
  537. );\
  538. if (codevar < 0 && !(unless_clause))\
  539. ERROR_RECT(codevar);\
  540. END
  541. #define HANDLE_RECT(codevar)\
  542. HANDLE_RECT_UNLESS(codevar, 0)
  543. #define END_RECTS_ON_ERROR(retry_cleanup, is_error, after_recovering)\
  544. continue;\
  545. error_in_rect:\
  546. if (cdev->error_is_retryable) {\
  547. retry_cleanup;\
  548. if ((is_error) &&\
  549. cdev->driver_call_nesting == 0 &&\
  550. (band_code =\
  551. clist_VMerror_recover_flush(cdev, band_code)) >= 0 &&\
  552. (after_recovering)\
  553. )\
  554. goto retry_rect;\
  555. }\
  556. if (1) return band_code;\
  557. } while ((y += height) < yend);\
  558. END
  559. #define END_RECTS END_RECTS_ON_ERROR(DO_NOTHING, 1, 1)
  560. #define END_RECTS_NO_ERROR\
  561. } while ((y += height) < yend);\
  562. END
  563. /* ------ Exported by gxclrect.c ------ */
  564. /* Put out a fill or tile rectangle command. */
  565. int cmd_write_rect_cmd(P7(gx_device_clist_writer * cldev,
  566. gx_clist_state * pcls,
  567. int op, int x, int y, int width, int height));
  568. /* ------ Exported by gxclbits.c ------ */
  569. /*
  570. * Put a bitmap in the buffer, compressing if appropriate.
  571. * pcls == 0 means put the bitmap in all bands.
  572. * Return <0 if error, otherwise the compression method.
  573. * A return value of gs_error_limitcheck means that the bitmap was too big
  574. * to fit in the command reading buffer.
  575. * Note that this leaves room for the command and initial arguments,
  576. * but doesn't fill them in.
  577. *
  578. * If decompress_elsewhere is set in the compression_mask, it is OK
  579. * to write out a compressed bitmap whose decompressed size is too large
  580. * to fit in the command reading buffer. (This is OK when reading a
  581. * cached bitmap, but not a bitmap for a one-time copy operation.)
  582. */
  583. #define decompress_elsewhere 0x100
  584. /*
  585. * If decompress_spread is set, the decompressed data will be spread out
  586. * for replication, so we drop all the padding even if the width is
  587. * greater than cmd_max_short_width_bytes (see above).
  588. */
  589. #define decompress_spread 0x200
  590. int cmd_put_bits(P10(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  591. const byte * data, uint width_bits, uint height,
  592. uint raster, int op_size, int compression_mask,
  593. byte ** pdp, uint * psize));
  594. /*
  595. * Put out commands for a color map (transfer function, black generation, or
  596. * undercolor removal). If pid != 0, write the map only if its ID differs
  597. * from the current one, and update the saved ID in the case.
  598. */
  599. typedef enum {
  600. cmd_map_transfer = 0, /* all transfer functions */
  601. cmd_map_transfer_0, /* transfer[0] */
  602. cmd_map_transfer_1, /* transfer[1] */
  603. cmd_map_transfer_2, /* transfer[2] */
  604. cmd_map_transfer_3, /* transfer[3] */
  605. cmd_map_ht_transfer, /* transfer fn of most recent halftone order */
  606. cmd_map_black_generation,
  607. cmd_map_undercolor_removal
  608. } cmd_map_index;
  609. typedef enum {
  610. cmd_map_none = 0, /* no map, use default */
  611. cmd_map_identity, /* identity map */
  612. cmd_map_other /* other map */
  613. } cmd_map_contents;
  614. int cmd_put_color_map(P4(gx_device_clist_writer * cldev,
  615. cmd_map_index map_index,
  616. const gx_transfer_map * map, gs_id * pid));
  617. /*
  618. * Change tiles for clist_tile_rectangle. (We make this a separate
  619. * procedure primarily for readability.)
  620. */
  621. int clist_change_tile(P4(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  622. const gx_strip_bitmap * tiles, int depth));
  623. /*
  624. * Change "tile" for clist_copy_*. Only uses tiles->{data, id, raster,
  625. * rep_width, rep_height}. tiles->[rep_]shift must be zero.
  626. */
  627. int clist_change_bits(P4(gx_device_clist_writer * cldev, gx_clist_state * pcls,
  628. const gx_strip_bitmap * tiles, int depth));
  629. /* ------ Exported by gxclimag.c ------ */
  630. /*
  631. * Add commands to represent a full (device) halftone.
  632. * (This routine should probably be in some other module.)
  633. * ****** Note: the type parameter is now unnecessary, because device
  634. * halftones record the type. ******
  635. */
  636. int cmd_put_halftone(P3(gx_device_clist_writer * cldev,
  637. const gx_device_halftone * pdht, gs_halftone_type type));
  638. /* ------ Exported by gxclrast.c for gxclread.c ------ */
  639. /*
  640. * Define whether we are actually rendering a band, or just executing
  641. * the put_params that occurs at the beginning of each page.
  642. */
  643. typedef enum {
  644. playback_action_render,
  645. playback_action_setup
  646. } clist_playback_action;
  647. /* Play back and rasterize one band. */
  648. int clist_playback_band(P7(clist_playback_action action,
  649. gx_device_clist_reader *cdev,
  650. stream *s, gx_device *target,
  651. int x0, int y0, gs_memory_t *mem));
  652. #endif /* gxcldev_INCLUDED */