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