123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- /* Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
- /*$Id: gxcldev.h,v 1.4 2000/11/05 00:34:24 lpd Exp $ */
- /* Internal definitions for Ghostscript command lists. */
- #ifndef gxcldev_INCLUDED
- # define gxcldev_INCLUDED
- #include "gxclist.h"
- #include "gsropt.h"
- #include "gxht.h" /* for gxdht.h */
- #include "gxtmap.h" /* ditto */
- #include "gxdht.h" /* for halftones */
- #include "strimpl.h" /* for compressed bitmaps */
- #include "scfx.h" /* ditto */
- #include "srlx.h" /* ditto */
- /* ---------------- Commands ---------------- */
- /* Define the compression modes for bitmaps. */
- /*#define cmd_compress_none 0 *//* (implicit) */
- #define cmd_compress_rle 1
- #define cmd_compress_cfe 2
- #define cmd_mask_compress_any\
- ((1 << cmd_compress_rle) | (1 << cmd_compress_cfe))
- /* Exported by gxclutil.c */
- void clist_rle_init(P1(stream_RLE_state *ss));
- void clist_rld_init(P1(stream_RLD_state *ss));
- void clist_cfe_init(P3(stream_CFE_state *ss, int width, gs_memory_t *mem));
- void clist_cfd_init(P4(stream_CFD_state *ss, int width, int height,
- gs_memory_t *mem));
- /*
- * A command always consists of an operation followed by operands;
- * the syntax of the operands depends on the operation.
- * In the operation definitions below:
- * + (prefixed) means the operand is in the low 4 bits of the opcode.
- * # means a variable-size operand encoded with the variable-size
- * integer encoding.
- * % means a variable-size operand encoded with the variable-size
- * fixed coordinate encoding.
- * $ means a color sized according to the device depth.
- * <> means the operand size depends on other state information
- * and/or previous operands.
- */
- typedef enum {
- cmd_op_misc = 0x00, /* (see below) */
- cmd_opv_end_run = 0x00, /* (nothing) */
- cmd_opv_set_tile_size = 0x01, /* rs?(1)nry?(1)nrx?(1)depth-1(5), */
- /* rep_width#, rep_height#, */
- /* [, nreps_x#][, nreps_y #] */
- /* [, rep_shift#] */
- cmd_opv_set_tile_phase = 0x02, /* x#, y# */
- cmd_opv_set_tile_bits = 0x03, /* index#, offset#, <bits> */
- cmd_opv_set_bits = 0x04, /* depth*4+compress, width#, height#, */
- /* index#, offset#, <bits> */
- cmd_opv_set_tile_color = 0x05, /* (nothing; next set/delta_color */
- /* refers to tile) */
- cmd_opv_set_misc = 0x06,
- #define cmd_set_misc_lop (0 << 6) /* 00: lop_lsb(6), lop_msb# */
- #define cmd_set_misc_data_x (1 << 6) /* 01: more(1)dx_lsb(5)[, dx_msb#] */
- #define cmd_set_misc_map (2 << 6) /* 10: contents(2)map_index(4) */
- /* [, n x frac] */
- #define cmd_set_misc_halftone (3 << 6) /* 11: type(6), num_comp# */
- cmd_opv_enable_lop = 0x07, /* (nothing) */
- cmd_opv_disable_lop = 0x08, /* (nothing) */
- cmd_opv_set_ht_order = 0x09, /* component+1#[, cname#], */
- /* width#, height#, raster#, */
- /* shift#, num_levels#, num_bits#, */
- /* order_procs_index */
- cmd_opv_set_ht_data = 0x0a, /* n, n x (uint|gx_ht_bit|ushort) */
- cmd_opv_end_page = 0x0b, /* (nothing) */
- cmd_opv_delta2_color0 = 0x0c, /* dr5dg6db5 or dc4dm4dy4dk4 */
- #define cmd_delta2_24_bias 0x00102010
- #define cmd_delta2_24_mask 0x001f3f1f
- #define cmd_delta2_32_bias 0x08080808
- #define cmd_delta2_32_mask 0x0f0f0f0f
- cmd_opv_delta2_color1 = 0x0d, /* <<same as color0>> */
- cmd_opv_set_copy_color = 0x0e, /* (nothing) */
- cmd_opv_set_copy_alpha = 0x0f, /* (nothing) */
- cmd_op_set_color0 = 0x10, /* +15 = transparent | */
- /* +0, color$ | +dcolor+8 | */
- /* +dr4, dg4db4 | */
- /* +dc3dm1, dm2dy3dk3 */
- cmd_op_set_color1 = 0x20, /* <<same as color0>> */
- #define cmd_delta1_24_bias 0x00080808
- #define cmd_delta1_24_mask 0x000f0f0f
- #define cmd_delta1_32_bias 0x04040404
- #define cmd_delta1_32_mask 0x07070707
- cmd_op_fill_rect = 0x30, /* +dy2dh2, x#, w# | +0, rect# */
- cmd_op_fill_rect_short = 0x40, /* +dh, dx, dw | +0, rect_short */
- cmd_op_fill_rect_tiny = 0x50, /* +dw+0, rect_tiny | +dw+8 */
- cmd_op_tile_rect = 0x60, /* +dy2dh2, x#, w# | +0, rect# */
- cmd_op_tile_rect_short = 0x70, /* +dh, dx, dw | +0, rect_short */
- cmd_op_tile_rect_tiny = 0x80, /* +dw+0, rect_tiny | +dw+8 */
- cmd_op_copy_mono = 0x90, /* +compress, x#, y#, (w+data_x)#, */
- /* h#, <bits> | */
- #define cmd_copy_ht_color 4
- /* +4+compress, x#, y#, (w+data_x)#, */
- /* h#, <bits> | */
- #define cmd_copy_use_tile 8
- /* +8 (use tile), x#, y# | */
- /* +12 (use tile), x#, y# */
- cmd_op_copy_color_alpha = 0xa0, /* (same as copy_mono, except: */
- /* if color, ignore ht_color; */
- /* if alpha & !use_tile, depth is */
- /* first operand) */
- cmd_op_delta_tile_index = 0xb0, /* +delta+8 */
- cmd_op_set_tile_index = 0xc0 /* +index[11:8], index[7:0] */
- } gx_cmd_op;
- #define cmd_op_name_strings\
- "(misc)", "set_color[0]", "set_color[1]", "fill_rect",\
- "fill_rect_short", "fill_rect_tiny", "tile_rect", "tile_rect_short",\
- "tile_rect_tiny", "copy_mono", "copy_color_alpha", "delta_tile_index",\
- "set_tile_index", "(misc2)", "(segment)", "(path)"
- #define cmd_misc_op_name_strings\
- "end_run", "set_tile_size", "set_tile_phase", "set_tile_bits",\
- "set_bits", "set_tile_color", "set_misc", "enable_lop",\
- "disable_lop", "set_ht_order", "set_ht_data", "end_page",\
- "delta2_color0", "delta2_color1", "set_copy_color", "set_copy_alpha",
- #ifdef DEBUG
- extern const char *const cmd_op_names[16];
- extern const char *const *const cmd_sub_op_names[16];
- #endif
- /*
- * Define the size of the largest command, not counting any bitmap or
- * similar variable-length operands.
- * The variable-size integer encoding is little-endian. The low 7 bits
- * of each byte contain data; the top bit is 1 for all but the last byte.
- */
- #define cmd_max_intsize(siz)\
- (((siz) * 8 + 6) / 7)
- #define cmd_largest_size\
- (2 + (1 + cmd_max_dash) * sizeof(float))
- /* ---------------- Command parameters ---------------- */
- /* Rectangle */
- typedef struct {
- int x, y, width, height;
- } gx_cmd_rect;
- /* Short rectangle */
- typedef struct {
- byte dx, dwidth, dy, dheight; /* dy and dheight are optional */
- } gx_cmd_rect_short;
- #define cmd_min_short (-128)
- #define cmd_max_short 127
- /* Tiny rectangle */
- #define cmd_min_dw_tiny (-4)
- #define cmd_max_dw_tiny 3
- typedef struct {
- unsigned dx:4;
- unsigned dy:4;
- } gx_cmd_rect_tiny;
- #define cmd_min_dxy_tiny (-8)
- #define cmd_max_dxy_tiny 7
- /*
- * When we write bitmaps, we remove raster padding selectively:
- * - If the bitmap is compressed, we don't remove any padding;
- * - If the width is <= 6 bytes, we remove all the padding;
- * - If the bitmap is only 1 scan line high, we remove the padding;
- * - If the bitmap is going to be replicated horizontally (see the
- * definition of decompress_spread below), we remove the padding;
- * - Otherwise, we remove the padding only from the last scan line.
- */
- #define cmd_max_short_width_bytes 6
- #define cmd_max_short_width_bits (cmd_max_short_width_bytes * 8)
- /*
- * Determine the (possibly unpadded) width in bytes for writing a bitmap,
- * per the algorithm just outlined. If compression_mask has any of the
- * cmd_mask_compress_any bits set, we assume the bitmap will be compressed.
- * Return the total size of the bitmap.
- */
- uint clist_bitmap_bytes(P5(uint width_bits, uint height,
- int compression_mask,
- uint * width_bytes, uint * raster));
- /*
- * For halftone cells, we always write an unreplicated bitmap, but we
- * reserve cache space for the reading pass based on the replicated size.
- * See the clist_change_tile procedure for the algorithm that chooses the
- * replication factors.
- */
- /* ---------------- Block file entries ---------------- */
- typedef struct cmd_block_s {
- int band_min, band_max;
- #define cmd_band_end (-1) /* end of band file */
- long pos; /* starting position in cfile */
- } cmd_block;
- /* ---------------- Band state ---------------- */
- /* Remember the current state of one band when writing or reading. */
- struct gx_clist_state_s {
- gx_color_index colors[2]; /* most recent colors */
- uint tile_index; /* most recent tile index */
- gx_bitmap_id tile_id; /* most recent tile id */
- /* Since tile table entries may be deleted and/or moved at any time, */
- /* the following is the only reliable way to check whether tile_index */
- /* references a particular tile id: */
- #define cls_has_tile_id(cldev, pcls, tid, offset_temp)\
- ((pcls)->tile_id == (tid) &&\
- (offset_temp = cldev->tile_table[(pcls)->tile_index].offset) != 0 &&\
- ((tile_slot *)(cldev->data + offset_temp))->id == (tid))
- gs_int_point tile_phase; /* most recent tile phase */
- gx_color_index tile_colors[2]; /* most recent tile colors */
- gx_cmd_rect rect; /* most recent rectangle */
- gs_logical_operation_t lop; /* most recent logical op */
- short lop_enabled; /* 0 = don't use lop, 1 = use lop, */
- /* -1 is used internally */
- short clip_enabled; /* 0 = don't clip, 1 = do clip, */
- /* -1 is used internally */
- bool color_is_alpha; /* for copy_color_alpha */
- uint known; /* flags for whether this band */
- /* knows various misc. parameters */
- /* We assign 'known' flags here from the high end; */
- /* gxclpath.h assigns them from the low end. */
- #define tile_params_known (1<<15)
- #define begin_image_known (1<<14) /* gxclimag.c */
- #define initial_known 0x3fff /* exclude tile & image params */
- /* Following are only used when writing */
- cmd_list list; /* list of commands for band */
- /* Following are set when writing, read when reading */
- ulong cost; /* cost of rendering the band */
- gx_colors_used_t colors_used;
- };
- /* The initial values for a band state */
- /*static const gx_clist_state cls_initial */
- #define cls_initial_values\
- { gx_no_color_index, gx_no_color_index },\
- 0, gx_no_bitmap_id,\
- { 0, 0 }, { gx_no_color_index, gx_no_color_index },\
- { 0, 0, 0, 0 }, lop_default, 0, 0, 0, initial_known,\
- { 0, 0 }, 0, { 0 }
- /* Define the size of the command buffer used for reading. */
- /* This is needed to split up operations with a large amount of data, */
- /* primarily large copy_ operations. */
- #define cbuf_size 800
- /* ---------------- Driver procedures ---------------- */
- /* In gxclrect.c */
- dev_proc_fill_rectangle(clist_fill_rectangle);
- dev_proc_copy_mono(clist_copy_mono);
- dev_proc_copy_color(clist_copy_color);
- dev_proc_copy_alpha(clist_copy_alpha);
- dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle);
- dev_proc_strip_copy_rop(clist_strip_copy_rop);
- /* In gxclimag.c */
- dev_proc_fill_mask(clist_fill_mask);
- dev_proc_begin_typed_image(clist_begin_typed_image);
- dev_proc_create_compositor(clist_create_compositor);
- /* In gxclread.c */
- dev_proc_get_bits_rectangle(clist_get_bits_rectangle);
- /* ---------------- Driver procedure support ---------------- */
- /*
- * The procedures and macros defined here are used when writing
- * (gxclist.c, gxclbits.c, gxclimag.c, gxclpath.c, gxclrect.c).
- * Note that none of the cmd_put_xxx procedures do VMerror recovery;
- * they convert low-memory warnings to VMerror errors.
- */
- /* ------ Exported by gxclist.c ------ */
- /*
- * Error recovery procedures for writer-side VMerrors, for async rendering
- * support. This logic assumes that the command list file and/or the
- * renderer allocate memory from the same pool as the writer. Hence, when
- * the writer runs out of memory, it tries to pause and let the renderer run
- * for a while in hope that enough memory will be freed by it to allow the
- * writer to allocate enough memory to proceed. Once a VMerror is detected,
- * error recovery proceeds in two escalating stages:
- *
- * 1) The recovery logic repeatedly calls clist_VMerror_recover(), which
- * waits until the next page has finished rendering. The recovery logic
- * keeps calling clist_VMerror_recover() until enough memory is freed,
- * or until clist_VMerror_recover() signals that no more pages
- * remain to be rendered (when return code < 0).
- *
- * 2) If enough memory is not free, the recovery logic calls
- * clist_VMerror_recover_flush() once. This routine terminates and
- * flushes out the partially-completed page that the writer is currently
- * writing to the command file, then waits for the partial page to finish
- * rendering. It then opens up a new command list "file" and resets the
- * state of the command list machinery to an initial state as if a new
- * page were beginning.
- *
- * If insufficient memory is available after the 2nd step, the situation
- * is the same as if it ocurred in a non-async setup: the writer program
- * simply used up too much memory and cannot continue.
- *
- * The first stage of error recovery (no flush) is performed without
- * flushing out the current page, so failing commands can simply be
- * restarted after such recovery. This is not true of 2nd stage recovery
- * (flush): as part of its operation, the flush resets the state of both
- * writer and renderer to initial values. In this event, the recovery logic
- * which called clist_try_recover_VMerror_flush() must force any pertinent
- * state information to be re-emitted before re-issuing the failing command.
- *
- * In case of a VMerror, the internal procedures that support the driver
- * procedures simply return the error code: they do not attempt recovery.
- * Note that all such procedures must take care that (1) they don't update
- * any writer state to reflect information written to the band list unless
- * the write actually succeeds, and (2) they are idempotent, since they may
- * be re-executed after first-stage VMerror recovery.
- *
- * Error recovery is only performed by the driver procedures themselves
- * (fill_rectangle, copy_mono, fill_path, etc.) and a few other procedures
- * at the same level of control. The implementation of error recovery is
- * packaged up in the FOR_RECTS et al macros defined below, but -- as noted
- * above -- recovery is not fully transparent. Other routines which perform
- * error recovery are those which open the device, begin a new page, or
- * reopen the device (put_params).
- */
- int clist_VMerror_recover(P2(gx_device_clist_writer *, int));
- int clist_VMerror_recover_flush(P2(gx_device_clist_writer *, int));
- /* Write out device parameters. */
- int cmd_put_params(P2(gx_device_clist_writer *, gs_param_list *));
- /* Conditionally keep command statistics. */
- #ifdef DEBUG
- int cmd_count_op(P2(int op, uint size));
- void cmd_uncount_op(P2(int op, uint size));
- # define cmd_count_add1(v) (v++)
- #else
- # define cmd_count_op(op, size) (op)
- # define cmd_uncount_op(op, size) DO_NOTHING
- # define cmd_count_add1(v) DO_NOTHING
- #endif
- /* Add a command to the appropriate band list, */
- /* and allocate space for its data. */
- byte *cmd_put_list_op(P3(gx_device_clist_writer * cldev, cmd_list * pcl, uint size));
- #ifdef DEBUG
- byte *cmd_put_op(P3(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size));
- #else
- # define cmd_put_op(cldev, pcls, size)\
- cmd_put_list_op(cldev, &(pcls)->list, size)
- #endif
- /* Call cmd_put_op and update stats if no error occurs. */
- #define set_cmd_put_op(dp, cldev, pcls, op, csize)\
- ( (dp = cmd_put_op(cldev, pcls, csize)) == 0 ?\
- (cldev)->error_code :\
- (*dp = cmd_count_op(op, csize), 0) )
- /* Add a command for all bands or a range of bands. */
- byte *cmd_put_range_op(P4(gx_device_clist_writer * cldev, int band_min,
- int band_max, uint size));
- #define cmd_put_all_op(cldev, size)\
- cmd_put_range_op(cldev, 0, (cldev)->nbands - 1, size)
- /* Call cmd_put_all/range_op and update stats if no error occurs. */
- #define set_cmd_put_range_op(dp, cldev, op, bmin, bmax, csize)\
- ( (dp = cmd_put_range_op(cldev, bmin, bmax, csize)) == 0 ?\
- (cldev)->error_code :\
- (*dp = cmd_count_op(op, csize), 0) )
- #define set_cmd_put_all_op(dp, cldev, op, csize)\
- set_cmd_put_range_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize)
- /* Shorten the last allocated command. */
- /* Note that this does not adjust the statistics. */
- #define cmd_shorten_list_op(cldev, pcls, delta)\
- ((pcls)->tail->size -= (delta), (cldev)->cnext -= (delta))
- #define cmd_shorten_op(cldev, pcls, delta)\
- cmd_shorten_list_op(cldev, &(pcls)->list, delta)
- /* Write out the buffered commands, and reset the buffer. */
- /* Return 0 if OK, 1 if OK with low-memory warning, */
- /* or the usual negative error code. */
- int cmd_write_buffer(P2(gx_device_clist_writer * cldev, byte cmd_end));
- /* End a page by flushing the buffer and terminating the command list. */
- int clist_end_page(P1(gx_device_clist_writer *));
- /* Compute the # of bytes required to represent a variable-size integer. */
- /* (This works for negative integers also; they are written as though */
- /* they were unsigned.) */
- int cmd_size_w(P1(uint));
- #define w1byte(w) (!((w) & ~0x7f))
- #define w2byte(w) (!((w) & ~0x3fff))
- #define cmd_sizew(w)\
- (w1byte(w) ? 1 : w2byte(w) ? 2 : cmd_size_w((uint)(w)))
- #define cmd_size2w(wx,wy)\
- (w1byte((wx) | (wy)) ? 2 :\
- cmd_size_w((uint)(wx)) + cmd_size_w((uint)(wy)))
- #define cmd_sizexy(xy) cmd_size2w((xy).x, (xy).y)
- #define cmd_sizew_max ((sizeof(uint) * 8 + 6) / 7)
- /* Put a variable-size integer in the buffer. */
- byte *cmd_put_w(P2(uint, byte *));
- #define cmd_putw(w,dp)\
- (w1byte(w) ? (*dp = w, ++dp) :\
- w2byte(w) ? (*dp = (w) | 0x80, dp[1] = (w) >> 7, dp += 2) :\
- (dp = cmd_put_w((uint)(w), dp)))
- #define cmd_put2w(wx,wy,dp)\
- (w1byte((wx) | (wy)) ? (dp[0] = (wx), dp[1] = (wy), dp += 2) :\
- (dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), dp))))
- #define cmd_putxy(xy,dp) cmd_put2w((xy).x, (xy).y, dp)
- /* Put out a command to set a color. */
- typedef struct {
- byte set_op;
- byte delta2_op;
- bool tile_color;
- } clist_select_color_t;
- extern const clist_select_color_t
- clist_select_color0, clist_select_color1, clist_select_tile_color0,
- clist_select_tile_color1;
- int cmd_put_color(P5(gx_device_clist_writer * cldev, gx_clist_state * pcls,
- const clist_select_color_t * select,
- gx_color_index color, gx_color_index * pcolor));
- #define cmd_set_color0(dev, pcls, color0)\
- cmd_put_color(dev, pcls, &clist_select_color0, color0, &(pcls)->colors[0])
- #define cmd_set_color1(dev, pcls, color1)\
- cmd_put_color(dev, pcls, &clist_select_color1, color1, &(pcls)->colors[1])
- /* Put out a command to set the tile colors. */
- int cmd_set_tile_colors(P4(gx_device_clist_writer *cldev,
- gx_clist_state * pcls,
- gx_color_index color0, gx_color_index color1));
- /* Put out a command to set the tile phase. */
- int cmd_set_tile_phase(P4(gx_device_clist_writer *cldev,
- gx_clist_state * pcls,
- int px, int py));
- /* Enable or disable the logical operation. */
- int cmd_put_enable_lop(P3(gx_device_clist_writer *, gx_clist_state *, int));
- #define cmd_do_enable_lop(cldev, pcls, enable)\
- ( (pcls)->lop_enabled == ((enable) ^ 1) &&\
- cmd_put_enable_lop(cldev, pcls, enable) < 0 ?\
- (cldev)->error_code : 0 )
- #define cmd_enable_lop(cldev, pcls)\
- cmd_do_enable_lop(cldev, pcls, 1)
- #define cmd_disable_lop(cldev, pcls)\
- cmd_do_enable_lop(cldev, pcls, 0)
- /* Enable or disable clipping. */
- int cmd_put_enable_clip(P3(gx_device_clist_writer *, gx_clist_state *, int));
- #define cmd_do_enable_clip(cldev, pcls, enable)\
- ( (pcls)->clip_enabled == ((enable) ^ 1) &&\
- cmd_put_enable_clip(cldev, pcls, enable) < 0 ?\
- (cldev)->error_code : 0 )
- #define cmd_enable_clip(cldev, pcls)\
- cmd_do_enable_clip(cldev, pcls, 1)
- #define cmd_disable_clip(cldev, pcls)\
- cmd_do_enable_clip(cldev, pcls, 0)
- /* Write a command to set the logical operation. */
- int cmd_set_lop(P3(gx_device_clist_writer *, gx_clist_state *,
- gs_logical_operation_t));
- /* Disable (if default) or enable the logical operation, setting it if */
- /* needed. */
- int cmd_update_lop(P3(gx_device_clist_writer *, gx_clist_state *,
- gs_logical_operation_t));
- /*
- * Define macros for dividing up an operation into bands, per the
- * template
- FOR_RECTS[_NO_ERROR] {
- ... process rectangle x, y, width, height in band pcls ...
- } END_RECTS[_NO_ERROR];
- * Note that FOR_RECTS resets y and height. It is OK for the code that
- * processes each band to reset height to a smaller (positive) value; the
- * vertical subdivision code in copy_mono, copy_color, and copy_alpha makes
- * use of this. The band processing code may `continue' (to reduce nesting
- * of conditionals).
- *
- * If the processing code detects an error that may be a recoverable
- * VMerror, the code may call ERROR_RECT(), which will attempt to fix the
- * VMerror by flushing and closing the band and resetting the imager state,
- * and then restart emitting the entire band. Before flushing the file, the
- * 'on_error' clause of END_RECTS_ON_ERROR (defaults to the constant 1 if
- * END_RECT is used) is evaluated and tested. The 'on_error' clause enables
- * mop-up actions to be executed before flushing, and/or selectively
- * inhibits the flush, close, reset and restart process. Similarly, the
- * 'after_recovering' clause of END_RECTS_ON_ERROR allows an action to get
- * performed after successfully recovering.
- *
- * The band processing code may wrap an operation with TRY_RECT { ... }
- * HANDLE_RECT_UNLESS(code, unless_action) (or HANDLE_RECT(code)). This will
- * perform local first-stage VMerror recovery, by waiting for some memory to
- * become free and then retrying the failed operation starting at the
- * TRY_RECT. If local recovery is unsuccessful, the local recovery code
- * calls ERROR_RECT.
- *
- * The band processing loop should use the _NO_ERROR macros iff it doesn't
- * call ERROR_RECT anywhere.
- *
- * In a few cases, the band processing code calls other driver procedures
- * (e.g., clist_copy_mono calls itself recursively if it must split up the
- * operation into smaller pieces) or other procedures that may attempt
- * VMerror recovery. In such cases, the recursive call must not attempt
- * second-stage VMerror recovery, since the caller would have no way of
- * knowing that the writer state had been reset. Such recursive calls
- * should be wrapped in NEST_RECT { ... } UNNEST_RECT, which causes
- * ERROR_RECT simply to return the error code rather than attempting
- * recovery. (TRY/HANDLE_RECT will still attempt local recovery, as
- * described above, but this is harmless since it is transparent.) By
- * convention, calls to cmd_put_xxx or cmd_set_xxx never attempt recovery
- * and so never require NEST_RECTs.
- *
- * If a put_params call fails, the device will be left in a closed state,
- * but higher-level code won't notice this fact. We flag this by setting
- * permanent_error, which prevents writing to the command list.
- */
- /*
- * The "if (1)" statements in the following macros are there to prevent
- * stupid compilers from giving "statement not reached" warnings.
- */
- #define FOR_RECTS_NO_ERROR\
- BEGIN\
- int yend = y + height;\
- int band_height = cdev->page_band_height;\
- /* no band_code */\
- \
- if (cdev->permanent_error < 0)\
- return (cdev->permanent_error);\
- do {\
- int band = y / band_height;\
- gx_clist_state *pcls = cdev->states + band;\
- int band_end = (band + 1) * band_height;\
- \
- height = min(band_end, yend) - y;\
- /* no retry_rect: */
- #define FOR_RECTS\
- BEGIN\
- int yend = y + height;\
- int band_height = cdev->page_band_height;\
- int band_code;\
- \
- if (cdev->permanent_error < 0)\
- return (cdev->permanent_error);\
- do {\
- int band = y / band_height;\
- gx_clist_state *pcls = cdev->states + band;\
- int band_end = (band + 1) * band_height;\
- \
- height = min(band_end, yend) - y;\
- retry_rect:\
- ;
- #define NEST_RECT ++cdev->driver_call_nesting;
- #define UNNEST_RECT --cdev->driver_call_nesting
- #define ERROR_RECT(code_value)\
- BEGIN\
- band_code = (code_value);\
- if (1) goto error_in_rect;\
- END
- #define TRY_RECT\
- BEGIN\
- do
- #define HANDLE_RECT_UNLESS(codevar, unless_clause)\
- while (codevar < 0 &&\
- (codevar = clist_VMerror_recover(cdev, codevar)) >= 0\
- );\
- if (codevar < 0 && !(unless_clause))\
- ERROR_RECT(codevar);\
- END
- #define HANDLE_RECT(codevar)\
- HANDLE_RECT_UNLESS(codevar, 0)
- #define END_RECTS_ON_ERROR(retry_cleanup, is_error, after_recovering)\
- continue;\
- error_in_rect:\
- if (cdev->error_is_retryable) {\
- retry_cleanup;\
- if ((is_error) &&\
- cdev->driver_call_nesting == 0 &&\
- (band_code =\
- clist_VMerror_recover_flush(cdev, band_code)) >= 0 &&\
- (after_recovering)\
- )\
- goto retry_rect;\
- }\
- if (1) return band_code;\
- } while ((y += height) < yend);\
- END
- #define END_RECTS END_RECTS_ON_ERROR(DO_NOTHING, 1, 1)
- #define END_RECTS_NO_ERROR\
- } while ((y += height) < yend);\
- END
- /* ------ Exported by gxclrect.c ------ */
- /* Put out a fill or tile rectangle command. */
- int cmd_write_rect_cmd(P7(gx_device_clist_writer * cldev,
- gx_clist_state * pcls,
- int op, int x, int y, int width, int height));
- /* ------ Exported by gxclbits.c ------ */
- /*
- * Put a bitmap in the buffer, compressing if appropriate.
- * pcls == 0 means put the bitmap in all bands.
- * Return <0 if error, otherwise the compression method.
- * A return value of gs_error_limitcheck means that the bitmap was too big
- * to fit in the command reading buffer.
- * Note that this leaves room for the command and initial arguments,
- * but doesn't fill them in.
- *
- * If decompress_elsewhere is set in the compression_mask, it is OK
- * to write out a compressed bitmap whose decompressed size is too large
- * to fit in the command reading buffer. (This is OK when reading a
- * cached bitmap, but not a bitmap for a one-time copy operation.)
- */
- #define decompress_elsewhere 0x100
- /*
- * If decompress_spread is set, the decompressed data will be spread out
- * for replication, so we drop all the padding even if the width is
- * greater than cmd_max_short_width_bytes (see above).
- */
- #define decompress_spread 0x200
- int cmd_put_bits(P10(gx_device_clist_writer * cldev, gx_clist_state * pcls,
- const byte * data, uint width_bits, uint height,
- uint raster, int op_size, int compression_mask,
- byte ** pdp, uint * psize));
- /*
- * Put out commands for a color map (transfer function, black generation, or
- * undercolor removal). If pid != 0, write the map only if its ID differs
- * from the current one, and update the saved ID in the case.
- */
- typedef enum {
- cmd_map_transfer = 0, /* all transfer functions */
- cmd_map_transfer_0, /* transfer[0] */
- cmd_map_transfer_1, /* transfer[1] */
- cmd_map_transfer_2, /* transfer[2] */
- cmd_map_transfer_3, /* transfer[3] */
- cmd_map_ht_transfer, /* transfer fn of most recent halftone order */
- cmd_map_black_generation,
- cmd_map_undercolor_removal
- } cmd_map_index;
- typedef enum {
- cmd_map_none = 0, /* no map, use default */
- cmd_map_identity, /* identity map */
- cmd_map_other /* other map */
- } cmd_map_contents;
- int cmd_put_color_map(P4(gx_device_clist_writer * cldev,
- cmd_map_index map_index,
- const gx_transfer_map * map, gs_id * pid));
- /*
- * Change tiles for clist_tile_rectangle. (We make this a separate
- * procedure primarily for readability.)
- */
- int clist_change_tile(P4(gx_device_clist_writer * cldev, gx_clist_state * pcls,
- const gx_strip_bitmap * tiles, int depth));
- /*
- * Change "tile" for clist_copy_*. Only uses tiles->{data, id, raster,
- * rep_width, rep_height}. tiles->[rep_]shift must be zero.
- */
- int clist_change_bits(P4(gx_device_clist_writer * cldev, gx_clist_state * pcls,
- const gx_strip_bitmap * tiles, int depth));
- /* ------ Exported by gxclimag.c ------ */
- /*
- * Add commands to represent a full (device) halftone.
- * (This routine should probably be in some other module.)
- * ****** Note: the type parameter is now unnecessary, because device
- * halftones record the type. ******
- */
- int cmd_put_halftone(P3(gx_device_clist_writer * cldev,
- const gx_device_halftone * pdht, gs_halftone_type type));
- /* ------ Exported by gxclrast.c for gxclread.c ------ */
- /*
- * Define whether we are actually rendering a band, or just executing
- * the put_params that occurs at the beginning of each page.
- */
- typedef enum {
- playback_action_render,
- playback_action_setup
- } clist_playback_action;
- /* Play back and rasterize one band. */
- int clist_playback_band(P7(clist_playback_action action,
- gx_device_clist_reader *cdev,
- stream *s, gx_device *target,
- int x0, int y0, gs_memory_t *mem));
- #endif /* gxcldev_INCLUDED */
|