Coverage Report

Created: 2026-02-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gxcldev.h
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Internal definitions for Ghostscript command lists. */
18
19
#ifndef gxcldev_INCLUDED
20
#  define gxcldev_INCLUDED
21
22
#include "gxclist.h"
23
#include "gsropt.h"
24
#include "gxht.h"   /* for gxdht.h */
25
#include "gxtmap.h"   /* ditto */
26
#include "gxdht.h"    /* for halftones */
27
#include "strimpl.h"    /* for compressed bitmaps */
28
#include "scfx.h"   /* ditto */
29
#include "srlx.h"   /* ditto */
30
#include "gsdcolor.h"
31
32
#ifdef HAVE_VALGRIND
33
#include "valgrind/memcheck.h"
34
#endif
35
36
/* ---------------- Commands ---------------- */
37
38
/* Define the compression modes for bitmaps. */
39
/*#define cmd_compress_none 0 *//* (implicit) */
40
67.4M
#define cmd_compress_rle 1
41
73.5M
#define cmd_compress_cfe 2
42
83.9M
#define cmd_compress_const 3
43
#define cmd_mask_compress_any\
44
57.5M
  ((1 << cmd_compress_rle) | (1 << cmd_compress_cfe) | (1 << cmd_compress_const))
45
46
/* Exported by gxclutil.c */
47
void clist_rle_init(stream_RLE_state *ss);
48
void clist_rld_init(stream_RLD_state *ss);
49
void clist_cfe_init(stream_CFE_state *ss, int width, gs_memory_t *mem);
50
void clist_cfd_init(stream_CFD_state *ss, int width, int height,
51
                    gs_memory_t *mem);
52
53
/* Write out a block of data of arbitrary size and content to a      */
54
/* specified band at the given offset PAST the last band in the page */
55
/* Used for various data such as the icc profile table and the       */
56
/* per band color_usage array                                        */
57
/*                                                                   */
58
/* If the size is not well defined, then the data itself should      */
59
/* contain information for length or logical end-of-data.            */
60
int cmd_write_pseudo_band(gx_device_clist_writer *cldev, unsigned char *pbuf,
61
                          int data_size, int pseudo_band_offset);
62
/*
63
 * A command always consists of an operation followed by operands;
64
 * the syntax of the operands depends on the operation.
65
 * In the operation definitions below:
66
 *      + (prefixed) means the operand is in the low 4 bits of the opcode.
67
 *      # means a variable-size operand encoded with the variable-size
68
 *         integer encoding.
69
 *      % means a variable-size operand encoded with the variable-size
70
 *         fixed coordinate encoding.
71
 *      $ means a color sized according to the device depth.
72
 *      <> means the operand size depends on other state information
73
 *         and/or previous operands.
74
 */
75
typedef enum {
76
    cmd_op_misc              = 0x00, /* (see below) */
77
    cmd_opv_end_run          = 0x00, /* (nothing) */
78
    cmd_opv_set_tile_size    = 0x01, /* rs?(1)nry?(1)nrx?(1)depth(5, encoded), */
79
                                     /* rep_width#, rep_height#, */
80
                                     /* [, nreps_x#][, nreps_y #] */
81
                                     /* [, rep_shift#] */
82
    cmd_opv_set_tile_phase   = 0x02, /* x#, y# */
83
    cmd_opv_set_tile_bits    = 0x03, /* index#, offset#, <bits> */
84
    cmd_opv_set_bits         = 0x04, /* depth*4+compress, width#, height#, */
85
                                     /* index#, offset#, <bits> */
86
    cmd_opv_set_tile_color   = 0x05, /* (nothing; next set/delta_color */
87
                                     /* refers to tile) */
88
    cmd_opv_set_misc         = 0x06,
89
1.78M
#define cmd_set_misc_lop      (0 << 6) /* 00: lop_lsb(6), lop_msb# */
90
652k
#define cmd_set_misc_data_x   (1 << 6) /* 01: more(1)dx_lsb(5)[, dx_msb#] */
91
6.39M
#define cmd_set_misc_map      (2 << 6) /* 10: contents(2)map_index(4) */
92
                                       /* [, n x frac] */
93
0
#define cmd_set_misc_halftone (3 << 6) /* 11: type(6), num_comp# */
94
    cmd_opv_enable_lop       = 0x07, /* (nothing) */
95
    cmd_opv_disable_lop      = 0x08, /* (nothing) */
96
    cmd_opv_set_screen_phaseT= 0x09, /* x#, y# */
97
    cmd_opv_set_screen_phaseS= 0x0a, /* x#, y# */
98
    cmd_opv_end_page         = 0x0b, /* (nothing) */
99
    cmd_opv_delta_color0     = 0x0c, /* See cmd_put_color in gxclutil.c */
100
    cmd_opv_delta_color1     = 0x0d, /* <<same as color0>> */
101
    cmd_opv_set_copy_color   = 0x0e, /* (nothing) */
102
    cmd_opv_set_copy_alpha   = 0x0f, /* (nothing) */
103
    cmd_op_set_color0        = 0x10, /* +n = number of low order zero bytes | */
104
12.9M
#define cmd_no_color_index 15        /* +15 = transparent - "no color" */
105
    cmd_op_set_color1        = 0x20, /* <<same as color0>> */
106
    cmd_op_fill_rect         = 0x30, /* +dy2dh2, x#, w# | +0, rect# */
107
    cmd_op_fill_rect_short   = 0x40, /* +dh, dx, dw | +0, rect_short */
108
    cmd_op_fill_rect_tiny    = 0x50, /* +dw+0, rect_tiny | +dw+8 */
109
    cmd_op_tile_rect         = 0x60, /* +dy2dh2, x#, w# | +0, rect# */
110
    cmd_op_tile_rect_short   = 0x70, /* +dh, dx, dw | +0, rect_short */
111
    cmd_op_tile_rect_tiny    = 0x80, /* +dw+0, rect_tiny | +dw+8 */
112
    cmd_op_copy_mono_planes  = 0x90, /* +compress, plane_height, x#, y#, (w+data_x)#, */
113
                                     /* h#, <bits> | */
114
77.5M
#define cmd_copy_use_tile 8          /* +8 (use tile), x#, y# | */
115
    cmd_op_copy_color_alpha  = 0xa0, /* (same as copy_mono, except: */
116
                                     /* if color, ignore ht_color; */
117
                                     /* if alpha & !use_tile, depth is */
118
                                     /*   first operand) */
119
    cmd_op_delta_tile_index  = 0xb0, /* +delta+8 */
120
    cmd_op_set_tile_index    = 0xc0, /* +index[11:8], index[7:0] */
121
    cmd_op_misc2             = 0xd0, /* (see below) */
122
    cmd_opv_set_bits_planar  = 0xd0, /* depth*4+compress, width#, height#, */
123
                                     /* num_planes, index#, offset#, <bits> */
124
    cmd_op_fill_rect_hl      = 0xd1, /* rect fill with devn color */
125
    cmd_opv_set_fill_adjust  = 0xd2, /* adjust_x/y(fixed) */
126
    cmd_opv_set_ctm          = 0xd3, /* [per sput/sget_matrix] */
127
    cmd_opv_set_color_space  = 0xd4, /* base(4)Indexed?(2)0(2) */
128
                                     /* [, hival#, table|map] */
129
    /*
130
     * cmd_opv_set_misc2_value is followed by a mask (a variable-length
131
     * integer), and then by parameter values for the parameters selected
132
     * by the mask.  See gxclpath.h for the "known" mask values.
133
     */
134
    /* cap_join:      0(2)cap(3)join(3) */
135
    /* cj_ac_sa:      0(3)curve_join+1(3)acc.curves(1)stroke_adj(1) */
136
    /* flatness:      (float) */
137
    /* line width:    (float) */
138
    /* miter limit:   (float) */
139
    /* op_bm_tk:      blend mode(5)text knockout(1)o.p.mode(1)o.p.(1) */
140
    /* segment notes: (byte) */
141
    /* opacity/shape: alpha(float)mask(TBD) */
142
    /* alpha:         <<verbatim copy from gs_gstate>> */
143
    cmd_opv_set_misc2        = 0xd5, /* mask#, selected parameters */
144
    cmd_opv_set_dash         = 0xd6, /* adapt(1)abs.dot(1)n(6), dot */
145
                                     /* length(float), offset(float), */
146
                                     /* n x (float) */
147
    cmd_opv_enable_clip      = 0xd7, /* (nothing) */
148
    cmd_opv_disable_clip     = 0xd8, /* (nothing) */
149
    cmd_opv_begin_clip       = 0xd9, /* fill_adjust.x#, fill_adjust.y# */
150
    cmd_opv_end_clip         = 0xda, /* (nothing) */
151
    cmd_opv_begin_image_rect = 0xdb, /* same as begin_image, followed by */
152
                                     /* x0#, w-x1#, y0#, h-y1# */
153
    cmd_opv_begin_image      = 0xdc, /* image_type_table index, */
154
                                     /* [per image type] */
155
    cmd_opv_image_data       = 0xdd, /* height# (premature EOD if 0), */
156
                                     /* raster#, <data> */
157
    cmd_opv_image_plane_data = 0xde, /* height# (premature EOD if 0), */
158
                                     /* flags# (0 = same raster & data_x, */
159
                                     /* 1 = new raster & data_x, lsb first), */
160
                                     /* [raster#, [data_x#,]]* <data> */
161
    cmd_opv_extend           = 0xdf, /* command, varies (see gx_cmd_ext_op below) */
162
163
164
#define cmd_misc2_op_name_strings\
165
  "set_bits_planar", "fill_hl_color", \
166
  "set_fill_adjust", "set_ctm",\
167
  "set_color_space", "set_misc2", "set_dash", "enable_clip",\
168
  "disable_clip", "begin_clip", "end_clip", "begin_image_rect",\
169
  "begin_image", "image_data", "image_plane_data", "extended"
170
171
    cmd_op_segment           = 0xe0, /* (see below) */
172
    cmd_opv_rmoveto          = 0xe0, /* dx%, dy% */
173
    cmd_opv_rlineto          = 0xe1, /* dx%, dy% */
174
    cmd_opv_hlineto          = 0xe2, /* dx% */
175
    cmd_opv_vlineto          = 0xe3, /* dy% */
176
    cmd_opv_rmlineto         = 0xe4, /* dx1%,dy1%, dx2%,dy2% */
177
    cmd_opv_rm2lineto        = 0xe5, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
178
    cmd_opv_rm3lineto        = 0xe6, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3%, */
179
                                     /* [-dx2,-dy2 implicit] */
180
    cmd_opv_rrcurveto        = 0xe7, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */
181
    cmd_opv_min_curveto = cmd_opv_rrcurveto,
182
    cmd_opv_hvcurveto        = 0xe8, /* dx1%, dx2%,dy2%, dy3% */
183
    cmd_opv_vhcurveto        = 0xe9, /* dy1%, dx2%,dy2%, dx3% */
184
    cmd_opv_nrcurveto        = 0xea, /* dx2%,dy2%, dx3%,dy3% */
185
    cmd_opv_rncurveto        = 0xeb, /* dx1%,dy1%, dx2%,dy2% */
186
    cmd_opv_vqcurveto        = 0xec, /* dy1%, dx2%[,dy2=dx2 with sign */
187
                                     /* of dy1, dx3=dy1 with sign of dx2] */
188
    cmd_opv_hqcurveto        = 0xed, /* dx1%, [dx2=dy2 with sign */
189
                                     /* of dx1,]%dy2, [dy3=dx1 with sign */
190
                                     /* of dy2] */
191
    cmd_opv_scurveto         = 0xee, /* all implicit: previous op must have been */
192
                                     /* *curveto with one or more of dx/y1/3 = 0. */
193
                                     /* If h*: -dx3,dy3, -dx2,dy2, -dx1,dy1. */
194
                                     /* If v*: dx3,-dy3, dx2,-dy2, dx1,-dy1. */
195
    cmd_opv_max_curveto = cmd_opv_scurveto,
196
    cmd_opv_closepath        = 0xef, /* (nothing) */
197
198
#define cmd_segment_op_name_strings\
199
  "rmoveto", "rlineto", "hlineto", "vlineto",\
200
  "rmlineto", "rm2lineto", "rm3lineto", "rrcurveto",\
201
  "hvcurveto", "vhcurveto", "nrcurveto", "rncurveto",\
202
  "vqcurveto", "hqcurveto", "scurveto", "closepath"
203
204
    cmd_op_path              = 0xf0, /* (see below) */
205
    cmd_opv_fill             = 0xf0,
206
    cmd_opv_rgapto           = 0xf1, /* dx%, dy% */
207
    cmd_opv_lock_pattern     = 0xf2, /* lock, id */
208
    cmd_opv_eofill           = 0xf3,
209
    cmd_opv_fill_stroke      = 0xf4,
210
    cmd_opv_eofill_stroke    = 0xf5,
211
    cmd_opv_stroke           = 0xf6,
212
    /* UNUSED 0xf7 */
213
    /* UNUSED 0xf8 */
214
    cmd_opv_polyfill         = 0xf9,
215
    /* UNUSED 0xfa */
216
    /* UNUSED 0xfb */
217
    cmd_opv_fill_trapezoid   = 0xfc
218
    /* UNUSED 0xfd */
219
    /* UNUSED 0xfe */
220
    /* UNUSED 0xff */
221
222
#define cmd_path_op_name_strings\
223
  "fill", "rgapto", "lock_pattern", "eofill",\
224
  "fill_stroke", "eofill_stroke", "stroke", "?f7?",\
225
  "?f8?", "polyfill", "?fa?", "?fb?",\
226
  "fill_trapezoid", "?fd?", "?fe?", "?ff?"
227
228
/* unused cmd_op values: 0xf7, 0xf8, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */
229
} gx_cmd_op;
230
231
#define cmd_op_name_strings\
232
  "(misc)", "set_color[0]", "set_color[1]", "fill_rect",\
233
  "fill_rect_short", "fill_rect_tiny", "tile_rect", "tile_rect_short",\
234
  "tile_rect_tiny", "copy_mono_planes", "copy_color_alpha", "delta_tile_index",\
235
  "set_tile_index", "(misc2)", "(segment)", "(path)"
236
237
#define cmd_misc_op_name_strings\
238
  "end_run", "set_tile_size", "set_tile_phase", "set_tile_bits",\
239
  "set_bits", "set_tile_color", "set_misc", "enable_lop",\
240
  "disable_lop", "set_screen_phaseT", "set_screen_phaseS", "end_page",\
241
  "delta2_color0", "delta2_color1", "set_copy_color", "set_copy_alpha",
242
243
#ifdef DEBUG
244
extern const char *const cmd_op_names[16];
245
extern const char *const *const cmd_sub_op_names[16];
246
#endif
247
248
/*
249
 * Define the size of the largest command, not counting any bitmap or
250
 * similar variable-length operands.
251
 * The variable-size integer encoding is little-endian.  The low 7 bits
252
 * of each byte contain data; the top bit is 1 for all but the last byte.
253
 */
254
#define cmd_max_intsize(siz)\
255
12.6M
  (((siz) * 8 + 6) / 7)
256
257
/* NB: Assume that the largest size is for dash patterns. Larger that this
258
 *     need to be read from the cbuf in a loop.
259
 */
260
#define cmd_largest_size\
261
50.7M
  (2 + sizeof(float)    /* dot_length */\
262
50.7M
     + sizeof(float)           /* offset */\
263
50.7M
     + (cmd_max_dash * sizeof(float))\
264
50.7M
  )
265
266
/* ---------------- Command parameters ---------------- */
267
268
/* Rectangle */
269
typedef struct {
270
    int x, y, width, height;
271
} gx_cmd_rect;
272
273
/* Short rectangle */
274
typedef struct {
275
    byte dx, dwidth, dy, dheight; /* dy and dheight are optional */
276
} gx_cmd_rect_short;
277
278
81.6M
#define cmd_min_short (-128)
279
#define cmd_max_short 127
280
/* Tiny rectangle */
281
120M
#define cmd_min_dw_tiny (-4)
282
#define cmd_max_dw_tiny 3
283
typedef struct {
284
    unsigned dx:4;
285
    unsigned dy:4;
286
} gx_cmd_rect_tiny;
287
288
143M
#define cmd_min_dxy_tiny (-8)
289
12.1M
#define cmd_max_dxy_tiny 7
290
291
/*
292
 * Encoding for tile depth information.
293
 *
294
 * The cmd_opv_set_tile_size command code stores tile depth information
295
 * as part of the first byte following the command code. Throughout
296
 * the history of ghostscript, at least 3 different encodings have been used
297
 * here.
298
 *
299
 * Originally, we used 5 bits of the byte to hold 'depth-1'.
300
 *
301
 * Later, the DeviceN code required it to cope with depths of >32 bits, so
302
 * a new encoding was used that represented depth information either directly
303
 * (for depth <= 15), or as a multiple of 8. The high-order bit determined
304
 * which was the case; it was cleared if the depth is represented directly,
305
 * and set if the depth was represented as a multiple of 8.
306
 *
307
 * #define cmd_depth_to_code(d)    ((d) > 0xf ? 0x10 | ((d) >> 3) : (d))
308
 * #define cmd_code_to_depth(v)    \
309
 *    (((v) & 0x10) != 0 ? ((v) & 0xf) << 3 : (v) & 0xf)
310
 *
311
 * With the advent of the planar device, we needed to use one fewer bit in
312
 * the byte, so adopted the following encoding scheme:
313
 *   depth:  1  2 (3) 4 (5) (6) (7) 8  12  16  24  32  40  48  56  64
314
 *   value:  0  1 (2) 3 (4) (5) (6) 7   8   9  10  11  12  13  14  15
315
 * The numbers in brackets represent depths that are represented, but aren't
316
 * used by ghostscript (i.e. are available for future use).
317
 */
318
5.47k
#define cmd_depth_to_code(d)    ((d) > 8 ? 8 | (((d)-5) >> 3) : ((d)-1))
319
#define cmd_code_to_depth(v)    \
320
3.80k
    (((v) & 8) == 0 ? ((v) & 0x7)+1 : ((v) & 0x7 ? ((((v) & 7) << 3) + 8) : 12))
321
322
/*
323
 * When we write bitmaps, we remove raster padding selectively:
324
 *      - If the bitmap is compressed, we don't remove any padding;
325
 *      - If the width is <= 6 bytes, we remove all the padding;
326
 *      - If the bitmap is only 1 scan line high, we remove the padding;
327
 *      - If the bitmap is going to be replicated horizontally (see the
328
 *      definition of decompress_spread below), we remove the padding;
329
 *      - Otherwise, we remove the padding only from the last scan line.
330
 */
331
57.2M
#define cmd_max_short_width_bytes 6
332
#define cmd_max_short_width_bits (cmd_max_short_width_bytes * 8)
333
/*
334
 * Determine the (possibly unpadded) width in bytes for writing a bitmap,
335
 * per the algorithm just outlined.  If compression_mask has any of the
336
 * cmd_mask_compress_any bits set, we assume the bitmap will be compressed.
337
 * Return the total size of the bitmap.
338
 */
339
uint clist_bitmap_bytes(uint width_bits, uint height,
340
                        int compression_mask,
341
                        uint * width_bytes, uint * raster);
342
343
/*
344
 * For halftone cells, we always write an unreplicated bitmap, but we
345
 * reserve cache space for the reading pass based on the replicated size.
346
 * See the clist_change_tile procedure for the algorithm that chooses the
347
 * replication factors.
348
 */
349
350
/* ---------------- Block file entries ---------------- */
351
352
typedef struct cmd_block_s {
353
    int band_min, band_max;
354
2.60G
#define cmd_band_end (-1)  /* end of band file */
355
    int64_t pos;    /* starting position in cfile */
356
} cmd_block;
357
358
/* ---------------- Band state ---------------- */
359
360
/* Remember the current state of one band when writing or reading. */
361
struct gx_clist_state_s {
362
    gx_color_index colors[2]; /* most recent colors */
363
    gx_device_color_saved sdc;  /* last device color for this band */
364
    uint tile_index;    /* most recent tile index */
365
    gx_bitmap_id tile_id; /* most recent tile id */
366
/* Since tile table entries may be deleted and/or moved at any time, */
367
/* the following is the only reliable way to check whether tile_index */
368
/* references a particular tile id: */
369
#define cls_has_tile_id(cldev, pcls, tid, offset_temp)\
370
29.3M
  ((pcls)->tile_id == (tid) &&\
371
29.3M
   (offset_temp = cldev->tile_table[(pcls)->tile_index].offset) != 0 &&\
372
29.3M
   ((tile_slot *)(cldev->data + offset_temp))->id == (tid))
373
    gs_id pattern_id;   /* the last stored pattern id. */
374
    gs_point step_phase;  /* the last stored step phase. */
375
    gs_int_point tile_phase;  /* most recent tile phase */
376
    gs_int_point screen_phase[2]; /* most recent screen phase */
377
    gx_color_index tile_colors[2];  /* most recent tile colors */
378
    gx_device_color tile_color_devn[2];  /* devn tile colors */
379
    gx_cmd_rect rect;   /* most recent rectangle */
380
    gs_logical_operation_t lop; /* most recent logical op */
381
    short lop_enabled;    /* 0 = don't use lop, 1 = use lop, */
382
                                /* -1 is used internally */
383
    short clip_enabled;   /* 0 = don't clip, 1 = do clip, */
384
                                /* -1 is used internally */
385
    bool color_is_alpha;  /* for copy_color_alpha */
386
    bool color_is_devn;     /* more overload of copy_color_alpha for devn support */
387
    uint known;     /* flags for whether this band */
388
                                /* knows various misc. parameters */
389
    /* We assign 'known' flags here from the high end; */
390
    /* gxclpath.h assigns them from the low end. */
391
27.3k
#define tile_params_known (1<<15)
392
6.37M
#define begin_image_known (1<<14) /* gxclimag.c */
393
53.3M
#define initial_known 0x3fff  /* exclude tile & image params */
394
    /* Following are only used when writing */
395
    cmd_list list;    /* list of commands for band */
396
    /* Following are set when writing, read when reading */
397
    gx_color_usage_t color_usage;
398
};
399
400
/* The initial values for a band state */
401
/*static const gx_clist_state cls_initial */
402
#define cls_initial_values\
403
53.3M
         { gx_no_color_index, gx_no_color_index },\
404
53.3M
        { gx_dc_type_none },\
405
53.3M
        0, gx_no_bitmap_id, gs_no_id,\
406
53.3M
         { 0, 0 }, /* step_phase */ \
407
53.3M
         { 0, 0 }, { {0, 0}, {0, 0}}, { gx_no_color_index, gx_no_color_index },\
408
53.3M
        { {NULL}, {NULL} },\
409
53.3M
         { 0, 0, 0, 0 }, lop_default, 0, 0, 0, 0, initial_known,\
410
53.3M
        { 0, 0 }, /* cmd_list */\
411
53.3M
        { 0, /* or */\
412
53.3M
          0, /* slow rop */\
413
53.3M
          { { max_int, max_int }, /* p */ { min_int, min_int } /* q */ } /* trans_bbox */\
414
53.3M
        } /* color_usage */
415
416
/* Define the size of the command buffer used for reading. */
417
5.77M
#define cbuf_size 4096
418
/* This is needed to split up operations with a large amount of data, */
419
/* primarily large copy_ operations. */
420
19.5M
#define data_bits_size 4096
421
422
/* ---------------- Driver procedures ---------------- */
423
424
/* In gxclrect.c */
425
dev_proc_fillpage(clist_fillpage);
426
dev_proc_fill_rectangle(clist_fill_rectangle);
427
dev_proc_copy_mono(clist_copy_mono);
428
dev_proc_copy_color(clist_copy_color);
429
dev_proc_copy_alpha(clist_copy_alpha);
430
dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle);
431
dev_proc_strip_tile_rect_devn(clist_strip_tile_rect_devn);
432
dev_proc_strip_copy_rop2(clist_strip_copy_rop2);
433
dev_proc_fill_trapezoid(clist_fill_trapezoid);
434
dev_proc_fill_linear_color_trapezoid(clist_fill_linear_color_trapezoid);
435
dev_proc_fill_linear_color_triangle(clist_fill_linear_color_triangle);
436
dev_proc_dev_spec_op(clist_dev_spec_op);
437
dev_proc_copy_planes(clist_copy_planes);
438
dev_proc_fill_rectangle_hl_color(clist_fill_rectangle_hl_color);
439
dev_proc_copy_alpha_hl_color(clist_copy_alpha_hl_color);
440
dev_proc_process_page(clist_process_page);
441
442
/* In gxclimag.c */
443
dev_proc_fill_mask(clist_fill_mask);
444
dev_proc_begin_typed_image(clist_begin_typed_image);
445
dev_proc_composite(clist_composite);
446
447
/* In gxclread.c */
448
dev_proc_get_bits_rectangle(clist_get_bits_rectangle);
449
450
/* ---------------- Driver procedure support ---------------- */
451
452
/*
453
 * The procedures and macros defined here are used when writing
454
 * (gxclist.c, gxclbits.c, gxclimag.c, gxclpath.c, gxclrect.c).
455
 * Note that none of the cmd_put_xxx procedures do VMerror recovery;
456
 * they convert low-memory warnings to VMerror errors.
457
 */
458
459
/* ------ Exported by gxclist.c ------ */
460
461
/* Write out device parameters. */
462
int cmd_put_params(gx_device_clist_writer *, gs_param_list *);
463
464
/* Conditionally keep command statistics. */
465
/* #define COLLECT_STATS_CLIST */
466
467
#ifdef COLLECT_STATS_CLIST
468
int cmd_count_op(int op, uint size, const gs_memory_t *mem);
469
int cmd_count_extended_op(int op, uint size, const gs_memory_t *mem);
470
void cmd_uncount_op(int op, uint size);
471
void cmd_print_stats(const gs_memory_t *);
472
#  define cmd_count_add1(v) (v++)
473
#else
474
558M
#  define cmd_count_op(op, size, mem) (op)
475
35.7M
#  define cmd_count_extended_op(op, size, mem) (op)
476
20.1M
#  define cmd_uncount_op(op, size) DO_NOTHING
477
669M
#  define cmd_count_add1(v) DO_NOTHING
478
#endif
479
480
/* Add a command to the appropriate band list, */
481
/* and allocate space for its data. */
482
byte *cmd_put_list_op(gx_device_clist_writer * cldev, cmd_list * pcl, uint size);
483
484
/* Add a extended op command to the appropriate band list, */
485
/* and allocate space for its data. */
486
byte *cmd_put_list_extended_op(gx_device_clist_writer * cldev, cmd_list * pcl, int op, uint size);
487
488
/* Request a space in the buffer.
489
   Writes out the buffer if necessary.
490
   Returns the size of available space. */
491
int cmd_get_buffer_space(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size);
492
493
#ifdef DEBUG
494
void clist_debug_op(gs_memory_t *mem, const unsigned char *op_ptr);
495
byte *cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size);
496
#else
497
0
#define clist_debug_op(mem, op) do { } while (0)
498
#  define cmd_put_op(cldev, pcls, size)\
499
542M
     cmd_put_list_op(cldev, &(pcls)->list, size)
500
#  define cmd_put_extended_op(cldev, pcls, op, size)\
501
     cmd_put_list_extended_op(cldev, &(pcls)->list, op, size)
502
#endif
503
/* Call cmd_put_op and update stats if no error occurs. */
504
static inline int
505
set_cmd_put_op(byte **dp, gx_device_clist_writer * cldev,
506
               gx_clist_state * pcls, int op, uint csize)
507
508M
{
508
508M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
508M
    if (*dp == NULL)
511
1
        return (cldev)->error_code;
512
508M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
508M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
508M
    return 0;
520
508M
}
Unexecuted instantiation: gxp1fill.c:set_cmd_put_op
Unexecuted instantiation: gxpcmap.c:set_cmd_put_op
Unexecuted instantiation: gdevp14.c:set_cmd_put_op
Unexecuted instantiation: gxclist.c:set_cmd_put_op
Unexecuted instantiation: gxclpage.c:set_cmd_put_op
Unexecuted instantiation: gxclread.c:set_cmd_put_op
gxclrect.c:set_cmd_put_op
Line
Count
Source
507
313M
{
508
313M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
313M
    if (*dp == NULL)
511
1
        return (cldev)->error_code;
512
313M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
313M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
313M
    return 0;
520
313M
}
gxclutil.c:set_cmd_put_op
Line
Count
Source
507
30.3M
{
508
30.3M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
30.3M
    if (*dp == NULL)
511
0
        return (cldev)->error_code;
512
30.3M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
30.3M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
30.3M
    return 0;
520
30.3M
}
gxclimag.c:set_cmd_put_op
Line
Count
Source
507
29.8M
{
508
29.8M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
29.8M
    if (*dp == NULL)
511
0
        return (cldev)->error_code;
512
29.8M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
29.8M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
29.8M
    return 0;
520
29.8M
}
gxclpath.c:set_cmd_put_op
Line
Count
Source
507
103M
{
508
103M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
103M
    if (*dp == NULL)
511
0
        return (cldev)->error_code;
512
103M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
103M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
103M
    return 0;
520
103M
}
Unexecuted instantiation: gxclthrd.c:set_cmd_put_op
Unexecuted instantiation: gsicc_manage.c:set_cmd_put_op
Unexecuted instantiation: gsovrc.c:set_cmd_put_op
Unexecuted instantiation: zfapi.c:set_cmd_put_op
gxclbits.c:set_cmd_put_op
Line
Count
Source
507
31.1M
{
508
31.1M
    *dp = cmd_put_op(cldev, pcls, csize);
509
510
31.1M
    if (*dp == NULL)
511
0
        return (cldev)->error_code;
512
31.1M
    **dp = cmd_count_op(op, csize, cldev->memory);
513
514
31.1M
    if (gs_debug_c('L')) {
515
0
        clist_debug_op(cldev->memory, *dp);
516
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
517
0
    }
518
519
31.1M
    return 0;
520
31.1M
}
Unexecuted instantiation: gxclrast.c:set_cmd_put_op
521
/* Call cmd_put_extended_op and update stats if no error occurs. */
522
static inline int
523
set_cmd_put_extended_op(byte **dp, gx_device_clist_writer * cldev,
524
                        gx_clist_state * pcls, int op, uint csize)
525
34.1M
{
526
34.1M
    *dp = cmd_put_op(cldev, pcls, csize);
527
528
34.1M
    if (*dp == NULL)
529
0
        return (cldev)->error_code;
530
34.1M
    **dp = cmd_opv_extend;
531
34.1M
    (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory);
532
533
34.1M
    if (gs_debug_c('L')) {
534
0
        clist_debug_op(cldev->memory, *dp);
535
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
536
0
    }
537
538
34.1M
    return 0;
539
34.1M
}
Unexecuted instantiation: gxp1fill.c:set_cmd_put_extended_op
Unexecuted instantiation: gxpcmap.c:set_cmd_put_extended_op
Unexecuted instantiation: gdevp14.c:set_cmd_put_extended_op
Unexecuted instantiation: gxclist.c:set_cmd_put_extended_op
Unexecuted instantiation: gxclpage.c:set_cmd_put_extended_op
Unexecuted instantiation: gxclread.c:set_cmd_put_extended_op
gxclrect.c:set_cmd_put_extended_op
Line
Count
Source
525
6.49k
{
526
6.49k
    *dp = cmd_put_op(cldev, pcls, csize);
527
528
6.49k
    if (*dp == NULL)
529
0
        return (cldev)->error_code;
530
6.49k
    **dp = cmd_opv_extend;
531
6.49k
    (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory);
532
533
6.49k
    if (gs_debug_c('L')) {
534
0
        clist_debug_op(cldev->memory, *dp);
535
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
536
0
    }
537
538
6.49k
    return 0;
539
6.49k
}
Unexecuted instantiation: gxclutil.c:set_cmd_put_extended_op
gxclimag.c:set_cmd_put_extended_op
Line
Count
Source
525
1.55M
{
526
1.55M
    *dp = cmd_put_op(cldev, pcls, csize);
527
528
1.55M
    if (*dp == NULL)
529
0
        return (cldev)->error_code;
530
1.55M
    **dp = cmd_opv_extend;
531
1.55M
    (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory);
532
533
1.55M
    if (gs_debug_c('L')) {
534
0
        clist_debug_op(cldev->memory, *dp);
535
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
536
0
    }
537
538
1.55M
    return 0;
539
1.55M
}
gxclpath.c:set_cmd_put_extended_op
Line
Count
Source
525
32.5M
{
526
32.5M
    *dp = cmd_put_op(cldev, pcls, csize);
527
528
32.5M
    if (*dp == NULL)
529
0
        return (cldev)->error_code;
530
32.5M
    **dp = cmd_opv_extend;
531
32.5M
    (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory);
532
533
32.5M
    if (gs_debug_c('L')) {
534
0
        clist_debug_op(cldev->memory, *dp);
535
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
536
0
    }
537
538
32.5M
    return 0;
539
32.5M
}
Unexecuted instantiation: gxclthrd.c:set_cmd_put_extended_op
Unexecuted instantiation: gsicc_manage.c:set_cmd_put_extended_op
Unexecuted instantiation: gsovrc.c:set_cmd_put_extended_op
Unexecuted instantiation: zfapi.c:set_cmd_put_extended_op
Unexecuted instantiation: gxclbits.c:set_cmd_put_extended_op
Unexecuted instantiation: gxclrast.c:set_cmd_put_extended_op
540
541
/* Add a command for all bands or a range of bands. */
542
byte *cmd_put_range_op(gx_device_clist_writer * cldev, int band_min,
543
                       int band_max, uint size);
544
545
/* Call cmd_put_all/range_op and update stats if no error occurs. */
546
static inline int
547
set_cmd_put_range_op(byte **dp, gx_device_clist_writer * cldev,
548
                     int op, int bmin, int bmax, uint csize)
549
710k
{
550
710k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
551
710k
    if (*dp == NULL)
552
0
        return (cldev)->error_code;
553
710k
    **dp = cmd_count_op(op, csize, (cldev)->memory);
554
555
710k
    if (gs_debug_c('L')) {
556
0
        clist_debug_op(cldev->memory, *dp);
557
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
558
0
    }
559
560
710k
    return 0;
561
710k
}
Unexecuted instantiation: gxp1fill.c:set_cmd_put_range_op
Unexecuted instantiation: gxpcmap.c:set_cmd_put_range_op
Unexecuted instantiation: gdevp14.c:set_cmd_put_range_op
Unexecuted instantiation: gxclist.c:set_cmd_put_range_op
Unexecuted instantiation: gxclpage.c:set_cmd_put_range_op
Unexecuted instantiation: gxclread.c:set_cmd_put_range_op
gxclrect.c:set_cmd_put_range_op
Line
Count
Source
549
653k
{
550
653k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
551
653k
    if (*dp == NULL)
552
0
        return (cldev)->error_code;
553
653k
    **dp = cmd_count_op(op, csize, (cldev)->memory);
554
555
653k
    if (gs_debug_c('L')) {
556
0
        clist_debug_op(cldev->memory, *dp);
557
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
558
0
    }
559
560
653k
    return 0;
561
653k
}
gxclutil.c:set_cmd_put_range_op
Line
Count
Source
549
3.43k
{
550
3.43k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
551
3.43k
    if (*dp == NULL)
552
0
        return (cldev)->error_code;
553
3.43k
    **dp = cmd_count_op(op, csize, (cldev)->memory);
554
555
3.43k
    if (gs_debug_c('L')) {
556
0
        clist_debug_op(cldev->memory, *dp);
557
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
558
0
    }
559
560
3.43k
    return 0;
561
3.43k
}
Unexecuted instantiation: gxclimag.c:set_cmd_put_range_op
gxclpath.c:set_cmd_put_range_op
Line
Count
Source
549
414
{
550
414
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
551
414
    if (*dp == NULL)
552
0
        return (cldev)->error_code;
553
414
    **dp = cmd_count_op(op, csize, (cldev)->memory);
554
555
414
    if (gs_debug_c('L')) {
556
0
        clist_debug_op(cldev->memory, *dp);
557
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
558
0
    }
559
560
414
    return 0;
561
414
}
Unexecuted instantiation: gxclthrd.c:set_cmd_put_range_op
Unexecuted instantiation: gsicc_manage.c:set_cmd_put_range_op
Unexecuted instantiation: gsovrc.c:set_cmd_put_range_op
Unexecuted instantiation: zfapi.c:set_cmd_put_range_op
gxclbits.c:set_cmd_put_range_op
Line
Count
Source
549
52.9k
{
550
52.9k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
551
52.9k
    if (*dp == NULL)
552
0
        return (cldev)->error_code;
553
52.9k
    **dp = cmd_count_op(op, csize, (cldev)->memory);
554
555
52.9k
    if (gs_debug_c('L')) {
556
0
        clist_debug_op(cldev->memory, *dp);
557
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
558
0
    }
559
560
52.9k
    return 0;
561
52.9k
}
Unexecuted instantiation: gxclrast.c:set_cmd_put_range_op
562
#define set_cmd_put_all_op(dp, cldev, op, csize)\
563
710k
  set_cmd_put_range_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize)
564
static inline int
565
set_cmd_put_range_extended_op(byte **dp, gx_device_clist_writer * cldev,
566
                     int op, int bmin, int bmax, uint csize)
567
1.64M
{
568
1.64M
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
569
1.64M
    if (*dp == NULL)
570
0
        return (cldev)->error_code;
571
1.64M
    **dp = cmd_opv_extend;
572
1.64M
    (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory);
573
574
1.64M
    if (gs_debug_c('L')) {
575
0
        clist_debug_op(cldev->memory, *dp);
576
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
577
0
    }
578
579
1.64M
    return 0;
580
1.64M
}
Unexecuted instantiation: gxp1fill.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxpcmap.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gdevp14.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclist.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclpage.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclread.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclrect.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclutil.c:set_cmd_put_range_extended_op
gxclimag.c:set_cmd_put_range_extended_op
Line
Count
Source
567
956k
{
568
956k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
569
956k
    if (*dp == NULL)
570
0
        return (cldev)->error_code;
571
956k
    **dp = cmd_opv_extend;
572
956k
    (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory);
573
574
956k
    if (gs_debug_c('L')) {
575
0
        clist_debug_op(cldev->memory, *dp);
576
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
577
0
    }
578
579
956k
    return 0;
580
956k
}
gxclpath.c:set_cmd_put_range_extended_op
Line
Count
Source
567
687k
{
568
687k
    *dp = cmd_put_range_op(cldev, bmin, bmax, csize);
569
687k
    if (*dp == NULL)
570
0
        return (cldev)->error_code;
571
687k
    **dp = cmd_opv_extend;
572
687k
    (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory);
573
574
687k
    if (gs_debug_c('L')) {
575
0
        clist_debug_op(cldev->memory, *dp);
576
0
        dmlprintf1(cldev->memory, "[%u]\n", csize);
577
0
    }
578
579
687k
    return 0;
580
687k
}
Unexecuted instantiation: gxclthrd.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gsicc_manage.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gsovrc.c:set_cmd_put_range_extended_op
Unexecuted instantiation: zfapi.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclbits.c:set_cmd_put_range_extended_op
Unexecuted instantiation: gxclrast.c:set_cmd_put_range_extended_op
581
#define set_cmd_put_all_extended_op(dp, cldev, op, csize)\
582
1.64M
  set_cmd_put_range_extended_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize)
583
584
/* Shorten the last allocated command. */
585
/* Note that this does not adjust the statistics. */
586
#define cmd_shorten_list_op(cldev, pcls, delta)\
587
7.55M
  ((pcls)->tail->size -= (delta), (cldev)->cnext -= (delta))
588
#define cmd_shorten_op(cldev, pcls, delta)\
589
5.01M
  cmd_shorten_list_op(cldev, &(pcls)->list, delta)
590
591
/* Write out the buffered commands, and reset the buffer. */
592
/* Return 0 if OK, 1 if OK with low-memory warning, */
593
/* or the usual negative error code. */
594
int cmd_write_buffer(gx_device_clist_writer * cldev, byte cmd_end);
595
596
/* End a page by flushing the buffer and terminating the command list. */
597
int clist_end_page(gx_device_clist_writer *);
598
599
/* Compute the # of bytes required to represent a variable-size integer. */
600
/* (This works for negative integers also; they are written as though */
601
/* they were unsigned.) */
602
int cmd_size_w(uint);
603
604
5.31G
#define w1byte(w) (!((w) & ~0x7f))
605
4.44G
#define w2byte(w) (!((w) & ~0x3fff))
606
#define cmd_sizew(w)\
607
2.63G
  (w1byte(w) ? 1 : w2byte(w) ? 2 : cmd_size_w((uint)(w)))
608
#define cmd_size2w(wx,wy)\
609
32.1M
  (w1byte((wx) | (wy)) ? 2 :\
610
32.1M
   cmd_size_w((uint)(wx)) + cmd_size_w((uint)(wy)))
611
25.9M
#define cmd_sizexy(xy) cmd_size2w((xy).x, (xy).y)
612
#define cmd_sizew_max ((sizeof(uint) * 8 + 6) / 7)
613
614
/* Put a variable-size integer in the buffer. */
615
byte *cmd_put_w(uint, byte *);
616
617
#define cmd_putw(w,dp)\
618
2.60G
  (w1byte(w) ? (**dp = w, ++(*dp)) :\
619
2.60G
   w2byte(w) ? (**dp = (w) | 0x80, (*dp)[1] = (w) >> 7, (*dp) += 2) :\
620
2.21G
   (*dp = cmd_put_w((uint)(w), *dp)))
621
#define cmd_put2w(wx,wy,dp)\
622
45.4M
  (w1byte((wx) | (wy)) ? ((*dp)[0] = (wx), (*dp)[1] = (wy), (*dp) += 2) :\
623
45.4M
   (*dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), *dp))))
624
25.9M
#define cmd_putxy(xy,dp) cmd_put2w((xy).x, (xy).y, dp)
625
626
int cmd_size_frac31(register frac31 w);
627
byte * cmd_put_frac31(register frac31 w, register byte * dp);
628
629
/* Put out a command to set a color. */
630
typedef struct {
631
    byte set_op;
632
    byte delta_op;
633
    bool tile_color;
634
    bool devn;
635
} clist_select_color_t;
636
637
extern const clist_select_color_t
638
      clist_select_color0, clist_select_color1, clist_select_tile_color0,
639
      clist_select_tile_color1, clist_select_devn_color0,
640
      clist_select_devn_color1;
641
642
/* See comments in gxclutil.c */
643
int cmd_put_color(gx_device_clist_writer * cldev, gx_clist_state * pcls,
644
                  const clist_select_color_t * select,
645
                  gx_color_index color, gx_color_index * pcolor);
646
647
extern const gx_color_index cmd_delta_offsets[];  /* In gxclutil.c */
648
649
#define cmd_set_color0(dev, pcls, color0)\
650
1.96k
  cmd_put_color(dev, pcls, &clist_select_color0, color0, &(pcls)->colors[0])
651
#define cmd_set_color1(dev, pcls, color1)\
652
90.0k
  cmd_put_color(dev, pcls, &clist_select_color1, color1, &(pcls)->colors[1])
653
654
/* Put out a command to set the tile colors. */
655
int cmd_set_tile_colors(gx_device_clist_writer *cldev, gx_clist_state * pcls,
656
                        gx_color_index color0, gx_color_index color1);
657
658
/* Put out a command to set the tile phase. */
659
int
660
cmd_set_tile_phase_generic(gx_device_clist_writer * cldev, gx_clist_state * pcls,
661
                   int px, int py, bool all_bands);
662
int cmd_set_tile_phase(gx_device_clist_writer *cldev, gx_clist_state * pcls,
663
                       int px, int py);
664
/* Put out a command to set the screen phase. */
665
int
666
cmd_set_screen_phase_generic(gx_device_clist_writer * cldev, gx_clist_state * pcls,
667
                             int px, int py, gs_color_select_t color_select, bool all_bands);
668
int
669
cmd_set_screen_phase(gx_device_clist_writer * cldev, gx_clist_state * pcls,
670
                     int px, int py, gs_color_select_t color_select);
671
672
/* Enable or disable the logical operation. */
673
int cmd_put_enable_lop(gx_device_clist_writer *, gx_clist_state *, int);
674
#define cmd_do_enable_lop(cldev, pcls, enable)\
675
332M
  ( (pcls)->lop_enabled == ((enable) ^ 1) &&\
676
332M
    cmd_put_enable_lop(cldev, pcls, enable) < 0 ?\
677
332M
      (cldev)->error_code : 0 )
678
#define cmd_enable_lop(cldev, pcls)\
679
1.00M
  cmd_do_enable_lop(cldev, pcls, 1)
680
#define cmd_disable_lop(cldev, pcls)\
681
331M
  cmd_do_enable_lop(cldev, pcls, 0)
682
683
/* Enable or disable clipping. */
684
int cmd_put_enable_clip(gx_device_clist_writer *, gx_clist_state *, int);
685
686
#define cmd_do_enable_clip(cldev, pcls, enable)\
687
44.4M
  ( (pcls)->clip_enabled == ((enable) ^ 1) &&\
688
44.4M
    cmd_put_enable_clip(cldev, pcls, enable) < 0 ?\
689
44.4M
      (cldev)->error_code : 0 )
690
#define cmd_enable_clip(cldev, pcls)\
691
  cmd_do_enable_clip(cldev, pcls, 1)
692
#define cmd_disable_clip(cldev, pcls)\
693
5.66M
  cmd_do_enable_clip(cldev, pcls, 0)
694
695
/* Write a command to set the logical operation. */
696
int cmd_set_lop(gx_device_clist_writer *, gx_clist_state *,
697
                gs_logical_operation_t);
698
699
/* Disable (if default) or enable the logical operation, setting it if */
700
/* needed. */
701
int cmd_update_lop(gx_device_clist_writer *, gx_clist_state *,
702
                   gs_logical_operation_t);
703
704
/*
705
 * For dividing up an operation into bands, use the control pattern :
706
 *
707
 *   cmd_rects_enum_t re;
708
 *   RECT_ENUM_INIT(re, ry, rheight);
709
 *   do {
710
 *  RECT_STEP_INIT(re);
711
 *  ... process rectangle x, y, width, height in band pcls ...
712
 *
713
 *  ........
714
 *   } while ((re.y += re.height) < re.yend);
715
 *
716
 * Note that RECT_STEP_INIT(re) sets re.height.  It is OK for the code that
717
 * processes each band to reset height to a smaller (positive) value; the
718
 * vertical subdivision code in copy_mono, copy_color, and copy_alpha makes
719
 * use of this.  The band processing code may `continue' (to reduce nesting
720
 * of conditionals).
721
 *
722
 * If a put_params call fails, the device will be left in a closed state,
723
 * but higher-level code won't notice this fact.  We flag this by setting
724
 * permanent_error, which prevents writing to the command list.
725
 */
726
727
typedef struct cmd_rects_enum_s {
728
        int y;
729
        int height;
730
        int yend;
731
        int band_height;
732
        int band;
733
        gx_clist_state *pcls;
734
        int band_end;
735
        int rect_nbands;
736
} cmd_rects_enum_t;
737
738
#define RECT_ENUM_INIT(re, yvar, heightvar)\
739
323M
        re.y = yvar;\
740
323M
        re.height = heightvar;\
741
323M
        re.yend = re.y + re.height;\
742
323M
        re.band_height = cdev->page_info.band_params.BandHeight;\
743
323M
        re.rect_nbands = (re.yend - re.y + re.band_height - 1) / re.band_height;
744
745
#define RECT_STEP_INIT(re)\
746
361M
            re.band = re.y / re.band_height;\
747
361M
            re.pcls = cdev->states + re.band;\
748
361M
            re.band_end = (re.band + 1) * re.band_height;\
749
361M
            re.height = min(re.band_end, re.yend) - re.y;
750
751
/* Read a transformation matrix. */
752
const byte *cmd_read_matrix(gs_matrix * pmat, const byte * cbp);
753
754
/* ------ Exported by gxclrect.c ------ */
755
756
/* Put out a fill or tile rectangle command. */
757
int cmd_write_rect_cmd(gx_device_clist_writer * cldev, gx_clist_state * pcls,
758
                       int op, int x, int y, int width, int height);
759
/* Put out a fill with a devn color */
760
int cmd_write_rect_hl_cmd(gx_device_clist_writer * cldev,
761
                             gx_clist_state * pcls, int op, int x, int y,
762
                             int width, int height, bool extended_command);
763
/* Put out a fill or tile rectangle command for fillpage. */
764
int cmd_write_page_rect_cmd(gx_device_clist_writer * cldev, int op);
765
766
/* ------ Exported by gxclbits.c ------ */
767
768
/*
769
 * Put a bitmap in the buffer, compressing if appropriate.
770
 * pcls == 0 means put the bitmap in all bands.
771
 * Return <0 if error, otherwise the compression method.
772
 * A return value of gs_error_limitcheck means that the bitmap was too big
773
 * to fit in the command reading buffer.
774
 * Note that this leaves room for the command and initial arguments,
775
 * but doesn't fill them in.
776
 *
777
 * If decompress_elsewhere is set in the compression_mask, it is OK
778
 * to write out a compressed bitmap whose decompressed size is too large
779
 * to fit in the command reading buffer.  (This is OK when reading a
780
 * cached bitmap, but not a bitmap for a one-time copy operation.)
781
 */
782
17.1M
#define decompress_elsewhere 0x100
783
/*
784
 * If decompress_spread is set, the decompressed data will be spread out
785
 * for replication, so we drop all the padding even if the width is
786
 * greater than cmd_max_short_width_bytes (see above).
787
 */
788
481k
#define decompress_spread 0x200
789
790
/* clist_copy_mono and clist_copy_color have a max_size, but tiles to the */
791
/* cache do not (clist_change_bits and clist_change_tile).      */
792
14.7M
#define allow_large_bitmap 0x400
793
794
int cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls,
795
                 const byte * data, uint width_bits, uint height,
796
                 uint raster, int op_size, int compression_mask,
797
                 byte ** pdp, uint * psize);
798
799
/*
800
 * Put out commands for a color map (transfer function, black generation, or
801
 * undercolor removal).  If pid != 0, write the map only if its ID differs
802
 * from the current one, and update the saved ID in the case.
803
 */
804
typedef enum {
805
    cmd_map_transfer = 0, /* all transfer functions */
806
    cmd_map_transfer_0,   /* transfer[0] */
807
    cmd_map_transfer_1,   /* transfer[1] */
808
    cmd_map_transfer_2,   /* transfer[2] */
809
    cmd_map_transfer_3,   /* transfer[3] */
810
    cmd_map_black_generation,
811
    cmd_map_undercolor_removal
812
} cmd_map_index;
813
typedef enum {
814
    cmd_map_none = 0,   /* no map, use default */
815
    cmd_map_identity,   /* identity map */
816
    cmd_map_other   /* other map */
817
} cmd_map_contents;
818
int cmd_put_color_map(gx_device_clist_writer * cldev,
819
                      cmd_map_index map_index, int comp_num,
820
                      const gx_transfer_map * map, gs_id * pid);
821
822
/*
823
 * Change tiles for clist_tile_rectangle.  (We make this a separate
824
 * procedure primarily for readability.)
825
 */
826
int clist_change_tile(gx_device_clist_writer * cldev, gx_clist_state * pcls,
827
                      const gx_strip_bitmap * tiles, int depth);
828
829
/*
830
 * Change "tile" for clist_copy_*.  Only uses tiles->{data, id, raster,
831
 * rep_width, rep_height}.  tiles->[rep_]shift must be zero.
832
 */
833
int clist_change_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls,
834
                      const gx_strip_bitmap * tiles, int depth);
835
836
/* ------ Exported by gxclimag.c ------ */
837
838
/*
839
 * Write out any necessary color mapping data.
840
 */
841
int cmd_put_color_mapping(gx_device_clist_writer * cldev,
842
                                  const gs_gstate * pgs);
843
/*
844
 * Add commands to represent a full (device) halftone.
845
 * (This routine should probably be in some other module.)
846
 */
847
int cmd_put_halftone(gx_device_clist_writer * cldev,
848
                     const gx_device_halftone * pdht);
849
850
/* ------ Exported by gxclrast.c for gxclread.c ------ */
851
852
/*
853
 * Define whether we are actually rendering a band, or just executing
854
 * the put_params that occurs at the beginning of each page.
855
 */
856
typedef enum {
857
    playback_action_render,
858
    playback_action_render_no_pdf14,
859
    playback_action_setup
860
} clist_playback_action;
861
862
/* Play back and rasterize one band. */
863
int clist_playback_band(clist_playback_action action,
864
                        gx_device_clist_reader *cdev,
865
                        stream *s, gx_device *target,
866
                        int x0, int y0, gs_memory_t *mem);
867
868
/* Playback the band file, taking the indicated action w/ its contents. */
869
int clist_playback_file_bands(clist_playback_action action,
870
                          gx_device_clist_reader *crdev,
871
                          gx_band_page_info_t *page_info, gx_device *target,
872
                          int band_first, int band_last, int x0, int y0);
873
#ifdef DEBUG
874
int64_t clist_file_offset(const stream_state *st, uint buffer_offset);
875
void top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end);
876
void offset_map_next_data_out_of_band(stream_state *st);
877
void clist_debug_op(gs_memory_t *mem, const unsigned char *op_ptr);
878
void adjust_offset_map_for_skipped_data(stream_state *st, uint buffer_offset, uint skipped);
879
#endif
880
881
int clist_writer_push_no_cropping(gx_device_clist_writer *cdev);
882
int clist_writer_push_cropping(gx_device_clist_writer *cdev, int ry, int rheight);
883
int clist_writer_pop_cropping(gx_device_clist_writer *cdev);
884
int clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev);
885
int clist_read_icctable(gx_device_clist_reader *crdev);
886
int clist_read_color_usage_array(gx_device_clist_reader *crdev);
887
int clist_read_op_equiv_cmyk_colors(gx_device_clist_reader *crdev,
888
    equivalent_cmyk_color_params *op_equiv);
889
890
/* Special write out for the serialized icc profile table */
891
892
int cmd_write_icctable(gx_device_clist_writer * cldev, unsigned char *pbuf, int data_size);
893
894
/* Enumeration of psuedo band offsets for extra c-list data.
895
   This includes the ICC profile table and and color_usage and
896
   may later include compressed image data */
897
898
typedef enum {
899
    COLOR_USAGE_OFFSET = 1,
900
    SPOT_EQUIV_COLORS = 2,
901
    ICC_TABLE_OFFSET = 3
902
903
} psuedoband_offset;
904
905
/* Enumeration of compositor actions for band cropping. */
906
907
typedef enum {
908
    ALLBANDS = 0,
909
    PUSHCROP,
910
    POPCROP,
911
    CURRBANDS,
912
    SAMEAS_PUSHCROP_BUTNOPUSH
913
} cl_crop_action;
914
915
/* Valgrind helper macro */
916
#ifdef HAVE_VALGRIND
917
#define CMD_CHECK_LAST_OP_BLOCK_DEFINED(cldev) \
918
do {\
919
    gx_device_clist_writer *CLDEV = (gx_device_clist_writer *)(cldev);\
920
    if (CLDEV->ccl != NULL)\
921
        VALGRIND_CHECK_MEM_IS_DEFINED(&CLDEV->ccl->tail[1], CLDEV->ccl->tail->size);\
922
} while (0 == 1)
923
#else
924
763M
#define CMD_CHECK_LAST_OP_BLOCK_DEFINED(cldev) do { } while (0)
925
#endif
926
927
#endif /* gxcldev_INCLUDED */