/src/ghostpdl/base/gxcldev.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2024 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 | 168k | #define cmd_compress_rle 1 |
41 | 226k | #define cmd_compress_cfe 2 |
42 | 231k | #define cmd_compress_const 3 |
43 | | #define cmd_mask_compress_any\ |
44 | 158k | ((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.06k | #define cmd_set_misc_lop (0 << 6) /* 00: lop_lsb(6), lop_msb# */ |
90 | 226 | #define cmd_set_misc_data_x (1 << 6) /* 01: more(1)dx_lsb(5)[, dx_msb#] */ |
91 | 23.0k | #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 | 291 | #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 | 281k | #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 | 0 | (((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 | 1.50M | (2 + sizeof(float) /* dot_length */\ |
262 | 1.50M | + sizeof(float) /* offset */\ |
263 | 1.50M | + (cmd_max_dash * sizeof(float))\ |
264 | 1.50M | ) |
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 | 1.62M | #define cmd_min_short (-128) |
279 | | #define cmd_max_short 127 |
280 | | /* Tiny rectangle */ |
281 | 165k | #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 | 860k | #define cmd_min_dxy_tiny (-8) |
289 | 203k | #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 | 1 | #define cmd_depth_to_code(d) ((d) > 8 ? 8 | (((d)-5) >> 3) : ((d)-1)) |
319 | | #define cmd_code_to_depth(v) \ |
320 | 1 | (((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 | 145k | #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 | 24.3M | #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 | 93.3k | ((pcls)->tile_id == (tid) &&\ |
371 | 93.3k | (offset_temp = cldev->tile_table[(pcls)->tile_index].offset) != 0 &&\ |
372 | 93.3k | ((tile_slot *)(cldev->data + offset_temp))->id == (tid)) |
373 | | gs_id pattern_id; /* the last stored pattern id. */ |
374 | | gs_int_point tile_phase; /* most recent tile phase */ |
375 | | gs_int_point screen_phase[2]; /* most recent screen phase */ |
376 | | gx_color_index tile_colors[2]; /* most recent tile colors */ |
377 | | gx_device_color tile_color_devn[2]; /* devn tile colors */ |
378 | | gx_cmd_rect rect; /* most recent rectangle */ |
379 | | gs_logical_operation_t lop; /* most recent logical op */ |
380 | | short lop_enabled; /* 0 = don't use lop, 1 = use lop, */ |
381 | | /* -1 is used internally */ |
382 | | short clip_enabled; /* 0 = don't clip, 1 = do clip, */ |
383 | | /* -1 is used internally */ |
384 | | bool color_is_alpha; /* for copy_color_alpha */ |
385 | | bool color_is_devn; /* more overload of copy_color_alpha for devn support */ |
386 | | uint known; /* flags for whether this band */ |
387 | | /* knows various misc. parameters */ |
388 | | /* We assign 'known' flags here from the high end; */ |
389 | | /* gxclpath.h assigns them from the low end. */ |
390 | 3 | #define tile_params_known (1<<15) |
391 | 3.12k | #define begin_image_known (1<<14) /* gxclimag.c */ |
392 | 3.97M | #define initial_known 0x3fff /* exclude tile & image params */ |
393 | | /* Following are only used when writing */ |
394 | | cmd_list list; /* list of commands for band */ |
395 | | /* Following are set when writing, read when reading */ |
396 | | gx_color_usage_t color_usage; |
397 | | }; |
398 | | |
399 | | /* The initial values for a band state */ |
400 | | /*static const gx_clist_state cls_initial */ |
401 | | #define cls_initial_values\ |
402 | 3.97M | { gx_no_color_index, gx_no_color_index },\ |
403 | 3.97M | { gx_dc_type_none },\ |
404 | 3.97M | 0, gx_no_bitmap_id, gs_no_id,\ |
405 | 3.97M | { 0, 0 }, { {0, 0}, {0, 0}}, { gx_no_color_index, gx_no_color_index },\ |
406 | 3.97M | { {NULL}, {NULL} },\ |
407 | 3.97M | { 0, 0, 0, 0 }, lop_default, 0, 0, 0, 0, initial_known,\ |
408 | 3.97M | { 0, 0 }, /* cmd_list */\ |
409 | 3.97M | { 0, /* or */\ |
410 | 3.97M | 0, /* slow rop */\ |
411 | 3.97M | { { max_int, max_int }, /* p */ { min_int, min_int } /* q */ } /* trans_bbox */\ |
412 | 3.97M | } /* color_usage */ |
413 | | |
414 | | /* Define the size of the command buffer used for reading. */ |
415 | 207k | #define cbuf_size 4096 |
416 | | /* This is needed to split up operations with a large amount of data, */ |
417 | | /* primarily large copy_ operations. */ |
418 | 209k | #define data_bits_size 4096 |
419 | | |
420 | | /* ---------------- Driver procedures ---------------- */ |
421 | | |
422 | | /* In gxclrect.c */ |
423 | | dev_proc_fillpage(clist_fillpage); |
424 | | dev_proc_fill_rectangle(clist_fill_rectangle); |
425 | | dev_proc_copy_mono(clist_copy_mono); |
426 | | dev_proc_copy_color(clist_copy_color); |
427 | | dev_proc_copy_alpha(clist_copy_alpha); |
428 | | dev_proc_strip_tile_rectangle(clist_strip_tile_rectangle); |
429 | | dev_proc_strip_tile_rect_devn(clist_strip_tile_rect_devn); |
430 | | dev_proc_strip_copy_rop2(clist_strip_copy_rop2); |
431 | | dev_proc_fill_trapezoid(clist_fill_trapezoid); |
432 | | dev_proc_fill_linear_color_trapezoid(clist_fill_linear_color_trapezoid); |
433 | | dev_proc_fill_linear_color_triangle(clist_fill_linear_color_triangle); |
434 | | dev_proc_dev_spec_op(clist_dev_spec_op); |
435 | | dev_proc_copy_planes(clist_copy_planes); |
436 | | dev_proc_fill_rectangle_hl_color(clist_fill_rectangle_hl_color); |
437 | | dev_proc_copy_alpha_hl_color(clist_copy_alpha_hl_color); |
438 | | dev_proc_process_page(clist_process_page); |
439 | | |
440 | | /* In gxclimag.c */ |
441 | | dev_proc_fill_mask(clist_fill_mask); |
442 | | dev_proc_begin_typed_image(clist_begin_typed_image); |
443 | | dev_proc_composite(clist_composite); |
444 | | |
445 | | /* In gxclread.c */ |
446 | | dev_proc_get_bits_rectangle(clist_get_bits_rectangle); |
447 | | |
448 | | /* ---------------- Driver procedure support ---------------- */ |
449 | | |
450 | | /* |
451 | | * The procedures and macros defined here are used when writing |
452 | | * (gxclist.c, gxclbits.c, gxclimag.c, gxclpath.c, gxclrect.c). |
453 | | * Note that none of the cmd_put_xxx procedures do VMerror recovery; |
454 | | * they convert low-memory warnings to VMerror errors. |
455 | | */ |
456 | | |
457 | | /* ------ Exported by gxclist.c ------ */ |
458 | | |
459 | | /* Write out device parameters. */ |
460 | | int cmd_put_params(gx_device_clist_writer *, gs_param_list *); |
461 | | |
462 | | /* Conditionally keep command statistics. */ |
463 | | /* #define COLLECT_STATS_CLIST */ |
464 | | |
465 | | #ifdef COLLECT_STATS_CLIST |
466 | | int cmd_count_op(int op, uint size, const gs_memory_t *mem); |
467 | | int cmd_count_extended_op(int op, uint size, const gs_memory_t *mem); |
468 | | void cmd_uncount_op(int op, uint size); |
469 | | void cmd_print_stats(const gs_memory_t *); |
470 | | # define cmd_count_add1(v) (v++) |
471 | | #else |
472 | 4.26M | # define cmd_count_op(op, size, mem) (op) |
473 | 149k | # define cmd_count_extended_op(op, size, mem) (op) |
474 | 69.2k | # define cmd_uncount_op(op, size) DO_NOTHING |
475 | 3.72M | # define cmd_count_add1(v) DO_NOTHING |
476 | | #endif |
477 | | |
478 | | /* Add a command to the appropriate band list, */ |
479 | | /* and allocate space for its data. */ |
480 | | byte *cmd_put_list_op(gx_device_clist_writer * cldev, cmd_list * pcl, uint size); |
481 | | |
482 | | /* Add a extended op command to the appropriate band list, */ |
483 | | /* and allocate space for its data. */ |
484 | | byte *cmd_put_list_extended_op(gx_device_clist_writer * cldev, cmd_list * pcl, int op, uint size); |
485 | | |
486 | | /* Request a space in the buffer. |
487 | | Writes out the buffer if necessary. |
488 | | Returns the size of available space. */ |
489 | | int cmd_get_buffer_space(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size); |
490 | | |
491 | | #ifdef DEBUG |
492 | | void clist_debug_op(gs_memory_t *mem, const unsigned char *op_ptr); |
493 | | byte *cmd_put_op(gx_device_clist_writer * cldev, gx_clist_state * pcls, uint size); |
494 | | #else |
495 | 0 | #define clist_debug_op(mem, op) do { } while (0) |
496 | | # define cmd_put_op(cldev, pcls, size)\ |
497 | 1.45M | cmd_put_list_op(cldev, &(pcls)->list, size) |
498 | | # define cmd_put_extended_op(cldev, pcls, op, size)\ |
499 | | cmd_put_list_extended_op(cldev, &(pcls)->list, op, size) |
500 | | #endif |
501 | | /* Call cmd_put_op and update stats if no error occurs. */ |
502 | | static inline int |
503 | | set_cmd_put_op(byte **dp, gx_device_clist_writer * cldev, |
504 | | gx_clist_state * pcls, int op, uint csize) |
505 | 1.43M | { |
506 | 1.43M | *dp = cmd_put_op(cldev, pcls, csize); |
507 | | |
508 | 1.43M | if (*dp == NULL) |
509 | 0 | return (cldev)->error_code; |
510 | 1.43M | **dp = cmd_count_op(op, csize, cldev->memory); |
511 | | |
512 | 1.43M | if (gs_debug_c('L')) { |
513 | 0 | clist_debug_op(cldev->memory, *dp); |
514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); |
515 | 0 | } |
516 | | |
517 | 1.43M | return 0; |
518 | 1.43M | } 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 | 505 | 340k | { | 506 | 340k | *dp = cmd_put_op(cldev, pcls, csize); | 507 | | | 508 | 340k | if (*dp == NULL) | 509 | 0 | return (cldev)->error_code; | 510 | 340k | **dp = cmd_count_op(op, csize, cldev->memory); | 511 | | | 512 | 340k | if (gs_debug_c('L')) { | 513 | 0 | clist_debug_op(cldev->memory, *dp); | 514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 515 | 0 | } | 516 | | | 517 | 340k | return 0; | 518 | 340k | } |
gxclutil.c:set_cmd_put_op Line | Count | Source | 505 | 1.96k | { | 506 | 1.96k | *dp = cmd_put_op(cldev, pcls, csize); | 507 | | | 508 | 1.96k | if (*dp == NULL) | 509 | 0 | return (cldev)->error_code; | 510 | 1.96k | **dp = cmd_count_op(op, csize, cldev->memory); | 511 | | | 512 | 1.96k | if (gs_debug_c('L')) { | 513 | 0 | clist_debug_op(cldev->memory, *dp); | 514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 515 | 0 | } | 516 | | | 517 | 1.96k | return 0; | 518 | 1.96k | } |
gxclimag.c:set_cmd_put_op Line | Count | Source | 505 | 95.1k | { | 506 | 95.1k | *dp = cmd_put_op(cldev, pcls, csize); | 507 | | | 508 | 95.1k | if (*dp == NULL) | 509 | 0 | return (cldev)->error_code; | 510 | 95.1k | **dp = cmd_count_op(op, csize, cldev->memory); | 511 | | | 512 | 95.1k | if (gs_debug_c('L')) { | 513 | 0 | clist_debug_op(cldev->memory, *dp); | 514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 515 | 0 | } | 516 | | | 517 | 95.1k | return 0; | 518 | 95.1k | } |
gxclpath.c:set_cmd_put_op Line | Count | Source | 505 | 906k | { | 506 | 906k | *dp = cmd_put_op(cldev, pcls, csize); | 507 | | | 508 | 906k | if (*dp == NULL) | 509 | 0 | return (cldev)->error_code; | 510 | 906k | **dp = cmd_count_op(op, csize, cldev->memory); | 511 | | | 512 | 906k | if (gs_debug_c('L')) { | 513 | 0 | clist_debug_op(cldev->memory, *dp); | 514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 515 | 0 | } | 516 | | | 517 | 906k | return 0; | 518 | 906k | } |
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 | 505 | 90.5k | { | 506 | 90.5k | *dp = cmd_put_op(cldev, pcls, csize); | 507 | | | 508 | 90.5k | if (*dp == NULL) | 509 | 0 | return (cldev)->error_code; | 510 | 90.5k | **dp = cmd_count_op(op, csize, cldev->memory); | 511 | | | 512 | 90.5k | if (gs_debug_c('L')) { | 513 | 0 | clist_debug_op(cldev->memory, *dp); | 514 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 515 | 0 | } | 516 | | | 517 | 90.5k | return 0; | 518 | 90.5k | } |
Unexecuted instantiation: gxclrast.c:set_cmd_put_op |
519 | | /* Call cmd_put_extended_op and update stats if no error occurs. */ |
520 | | static inline int |
521 | | set_cmd_put_extended_op(byte **dp, gx_device_clist_writer * cldev, |
522 | | gx_clist_state * pcls, int op, uint csize) |
523 | 24.7k | { |
524 | 24.7k | *dp = cmd_put_op(cldev, pcls, csize); |
525 | | |
526 | 24.7k | if (*dp == NULL) |
527 | 0 | return (cldev)->error_code; |
528 | 24.7k | **dp = cmd_opv_extend; |
529 | 24.7k | (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory); |
530 | | |
531 | 24.7k | if (gs_debug_c('L')) { |
532 | 0 | clist_debug_op(cldev->memory, *dp); |
533 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); |
534 | 0 | } |
535 | | |
536 | 24.7k | return 0; |
537 | 24.7k | } 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 Unexecuted instantiation: gxclrect.c:set_cmd_put_extended_op Unexecuted instantiation: gxclutil.c:set_cmd_put_extended_op gxclimag.c:set_cmd_put_extended_op Line | Count | Source | 523 | 8 | { | 524 | 8 | *dp = cmd_put_op(cldev, pcls, csize); | 525 | | | 526 | 8 | if (*dp == NULL) | 527 | 0 | return (cldev)->error_code; | 528 | 8 | **dp = cmd_opv_extend; | 529 | 8 | (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory); | 530 | | | 531 | 8 | if (gs_debug_c('L')) { | 532 | 0 | clist_debug_op(cldev->memory, *dp); | 533 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 534 | 0 | } | 535 | | | 536 | 8 | return 0; | 537 | 8 | } |
gxclpath.c:set_cmd_put_extended_op Line | Count | Source | 523 | 24.7k | { | 524 | 24.7k | *dp = cmd_put_op(cldev, pcls, csize); | 525 | | | 526 | 24.7k | if (*dp == NULL) | 527 | 0 | return (cldev)->error_code; | 528 | 24.7k | **dp = cmd_opv_extend; | 529 | 24.7k | (*dp)[1] = cmd_count_extended_op(op, csize, cldev->memory); | 530 | | | 531 | 24.7k | if (gs_debug_c('L')) { | 532 | 0 | clist_debug_op(cldev->memory, *dp); | 533 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 534 | 0 | } | 535 | | | 536 | 24.7k | return 0; | 537 | 24.7k | } |
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 |
538 | | |
539 | | /* Add a command for all bands or a range of bands. */ |
540 | | byte *cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, |
541 | | int band_max, uint size); |
542 | | |
543 | | /* Call cmd_put_all/range_op and update stats if no error occurs. */ |
544 | | static inline int |
545 | | set_cmd_put_range_op(byte **dp, gx_device_clist_writer * cldev, |
546 | | int op, int bmin, int bmax, uint csize) |
547 | 124k | { |
548 | 124k | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); |
549 | 124k | if (*dp == NULL) |
550 | 0 | return (cldev)->error_code; |
551 | 124k | **dp = cmd_count_op(op, csize, (cldev)->memory); |
552 | | |
553 | 124k | if (gs_debug_c('L')) { |
554 | 0 | clist_debug_op(cldev->memory, *dp); |
555 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); |
556 | 0 | } |
557 | | |
558 | 124k | return 0; |
559 | 124k | } 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 | 547 | 123k | { | 548 | 123k | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 549 | 123k | if (*dp == NULL) | 550 | 0 | return (cldev)->error_code; | 551 | 123k | **dp = cmd_count_op(op, csize, (cldev)->memory); | 552 | | | 553 | 123k | if (gs_debug_c('L')) { | 554 | 0 | clist_debug_op(cldev->memory, *dp); | 555 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 556 | 0 | } | 557 | | | 558 | 123k | return 0; | 559 | 123k | } |
gxclutil.c:set_cmd_put_range_op Line | Count | Source | 547 | 18 | { | 548 | 18 | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 549 | 18 | if (*dp == NULL) | 550 | 0 | return (cldev)->error_code; | 551 | 18 | **dp = cmd_count_op(op, csize, (cldev)->memory); | 552 | | | 553 | 18 | if (gs_debug_c('L')) { | 554 | 0 | clist_debug_op(cldev->memory, *dp); | 555 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 556 | 0 | } | 557 | | | 558 | 18 | return 0; | 559 | 18 | } |
Unexecuted instantiation: gxclimag.c:set_cmd_put_range_op gxclpath.c:set_cmd_put_range_op Line | Count | Source | 547 | 1 | { | 548 | 1 | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 549 | 1 | if (*dp == NULL) | 550 | 0 | return (cldev)->error_code; | 551 | 1 | **dp = cmd_count_op(op, csize, (cldev)->memory); | 552 | | | 553 | 1 | if (gs_debug_c('L')) { | 554 | 0 | clist_debug_op(cldev->memory, *dp); | 555 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 556 | 0 | } | 557 | | | 558 | 1 | return 0; | 559 | 1 | } |
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 | 547 | 234 | { | 548 | 234 | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 549 | 234 | if (*dp == NULL) | 550 | 0 | return (cldev)->error_code; | 551 | 234 | **dp = cmd_count_op(op, csize, (cldev)->memory); | 552 | | | 553 | 234 | if (gs_debug_c('L')) { | 554 | 0 | clist_debug_op(cldev->memory, *dp); | 555 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 556 | 0 | } | 557 | | | 558 | 234 | return 0; | 559 | 234 | } |
Unexecuted instantiation: gxclrast.c:set_cmd_put_range_op |
560 | | #define set_cmd_put_all_op(dp, cldev, op, csize)\ |
561 | 124k | set_cmd_put_range_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize) |
562 | | static inline int |
563 | | set_cmd_put_range_extended_op(byte **dp, gx_device_clist_writer * cldev, |
564 | | int op, int bmin, int bmax, uint csize) |
565 | 124k | { |
566 | 124k | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); |
567 | 124k | if (*dp == NULL) |
568 | 0 | return (cldev)->error_code; |
569 | 124k | **dp = cmd_opv_extend; |
570 | 124k | (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory); |
571 | | |
572 | 124k | if (gs_debug_c('L')) { |
573 | 0 | clist_debug_op(cldev->memory, *dp); |
574 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); |
575 | 0 | } |
576 | | |
577 | 124k | return 0; |
578 | 124k | } 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 | 565 | 709 | { | 566 | 709 | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 567 | 709 | if (*dp == NULL) | 568 | 0 | return (cldev)->error_code; | 569 | 709 | **dp = cmd_opv_extend; | 570 | 709 | (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory); | 571 | | | 572 | 709 | if (gs_debug_c('L')) { | 573 | 0 | clist_debug_op(cldev->memory, *dp); | 574 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 575 | 0 | } | 576 | | | 577 | 709 | return 0; | 578 | 709 | } |
gxclpath.c:set_cmd_put_range_extended_op Line | Count | Source | 565 | 124k | { | 566 | 124k | *dp = cmd_put_range_op(cldev, bmin, bmax, csize); | 567 | 124k | if (*dp == NULL) | 568 | 0 | return (cldev)->error_code; | 569 | 124k | **dp = cmd_opv_extend; | 570 | 124k | (*dp)[1] = cmd_count_extended_op(op, csize, (cldev)->memory); | 571 | | | 572 | 124k | if (gs_debug_c('L')) { | 573 | 0 | clist_debug_op(cldev->memory, *dp); | 574 | 0 | dmlprintf1(cldev->memory, "[%u]\n", csize); | 575 | 0 | } | 576 | | | 577 | 124k | return 0; | 578 | 124k | } |
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 |
579 | | #define set_cmd_put_all_extended_op(dp, cldev, op, csize)\ |
580 | 124k | set_cmd_put_range_extended_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize) |
581 | | |
582 | | /* Shorten the last allocated command. */ |
583 | | /* Note that this does not adjust the statistics. */ |
584 | | #define cmd_shorten_list_op(cldev, pcls, delta)\ |
585 | 37.5k | ((pcls)->tail->size -= (delta), (cldev)->cnext -= (delta)) |
586 | | #define cmd_shorten_op(cldev, pcls, delta)\ |
587 | 29.6k | cmd_shorten_list_op(cldev, &(pcls)->list, delta) |
588 | | |
589 | | /* Write out the buffered commands, and reset the buffer. */ |
590 | | /* Return 0 if OK, 1 if OK with low-memory warning, */ |
591 | | /* or the usual negative error code. */ |
592 | | int cmd_write_buffer(gx_device_clist_writer * cldev, byte cmd_end); |
593 | | |
594 | | /* End a page by flushing the buffer and terminating the command list. */ |
595 | | int clist_end_page(gx_device_clist_writer *); |
596 | | |
597 | | /* Compute the # of bytes required to represent a variable-size integer. */ |
598 | | /* (This works for negative integers also; they are written as though */ |
599 | | /* they were unsigned.) */ |
600 | | int cmd_size_w(uint); |
601 | | |
602 | 1.38M | #define w1byte(w) (!((w) & ~0x7f)) |
603 | 146k | #define w2byte(w) (!((w) & ~0x3fff)) |
604 | | #define cmd_sizew(w)\ |
605 | 412k | (w1byte(w) ? 1 : w2byte(w) ? 2 : cmd_size_w((uint)(w))) |
606 | | #define cmd_size2w(wx,wy)\ |
607 | 122k | (w1byte((wx) | (wy)) ? 2 :\ |
608 | 122k | cmd_size_w((uint)(wx)) + cmd_size_w((uint)(wy))) |
609 | 93.1k | #define cmd_sizexy(xy) cmd_size2w((xy).x, (xy).y) |
610 | | #define cmd_sizew_max ((sizeof(uint) * 8 + 6) / 7) |
611 | | |
612 | | /* Put a variable-size integer in the buffer. */ |
613 | | byte *cmd_put_w(uint, byte *); |
614 | | |
615 | | #define cmd_putw(w,dp)\ |
616 | 702k | (w1byte(w) ? (**dp = w, ++(*dp)) :\ |
617 | 702k | w2byte(w) ? (**dp = (w) | 0x80, (*dp)[1] = (w) >> 7, (*dp) += 2) :\ |
618 | 57.6k | (*dp = cmd_put_w((uint)(w), *dp))) |
619 | | #define cmd_put2w(wx,wy,dp)\ |
620 | 152k | (w1byte((wx) | (wy)) ? ((*dp)[0] = (wx), (*dp)[1] = (wy), (*dp) += 2) :\ |
621 | 152k | (*dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), *dp)))) |
622 | 93.1k | #define cmd_putxy(xy,dp) cmd_put2w((xy).x, (xy).y, dp) |
623 | | |
624 | | int cmd_size_frac31(register frac31 w); |
625 | | byte * cmd_put_frac31(register frac31 w, register byte * dp); |
626 | | |
627 | | /* Put out a command to set a color. */ |
628 | | typedef struct { |
629 | | byte set_op; |
630 | | byte delta_op; |
631 | | bool tile_color; |
632 | | bool devn; |
633 | | } clist_select_color_t; |
634 | | |
635 | | extern const clist_select_color_t |
636 | | clist_select_color0, clist_select_color1, clist_select_tile_color0, |
637 | | clist_select_tile_color1, clist_select_devn_color0, |
638 | | clist_select_devn_color1; |
639 | | |
640 | | /* See comments in gxclutil.c */ |
641 | | int cmd_put_color(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
642 | | const clist_select_color_t * select, |
643 | | gx_color_index color, gx_color_index * pcolor); |
644 | | |
645 | | extern const gx_color_index cmd_delta_offsets[]; /* In gxclutil.c */ |
646 | | |
647 | | #define cmd_set_color0(dev, pcls, color0)\ |
648 | 0 | cmd_put_color(dev, pcls, &clist_select_color0, color0, &(pcls)->colors[0]) |
649 | | #define cmd_set_color1(dev, pcls, color1)\ |
650 | 287 | cmd_put_color(dev, pcls, &clist_select_color1, color1, &(pcls)->colors[1]) |
651 | | |
652 | | /* Put out a command to set the tile colors. */ |
653 | | int cmd_set_tile_colors(gx_device_clist_writer *cldev, gx_clist_state * pcls, |
654 | | gx_color_index color0, gx_color_index color1); |
655 | | |
656 | | /* Put out a command to set the tile phase. */ |
657 | | int |
658 | | cmd_set_tile_phase_generic(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
659 | | int px, int py, bool all_bands); |
660 | | int cmd_set_tile_phase(gx_device_clist_writer *cldev, gx_clist_state * pcls, |
661 | | int px, int py); |
662 | | /* Put out a command to set the screen phase. */ |
663 | | int |
664 | | cmd_set_screen_phase_generic(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
665 | | int px, int py, gs_color_select_t color_select, bool all_bands); |
666 | | int |
667 | | cmd_set_screen_phase(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
668 | | int px, int py, gs_color_select_t color_select); |
669 | | |
670 | | /* Enable or disable the logical operation. */ |
671 | | int cmd_put_enable_lop(gx_device_clist_writer *, gx_clist_state *, int); |
672 | | #define cmd_do_enable_lop(cldev, pcls, enable)\ |
673 | 178k | ( (pcls)->lop_enabled == ((enable) ^ 1) &&\ |
674 | 178k | cmd_put_enable_lop(cldev, pcls, enable) < 0 ?\ |
675 | 178k | (cldev)->error_code : 0 ) |
676 | | #define cmd_enable_lop(cldev, pcls)\ |
677 | 532 | cmd_do_enable_lop(cldev, pcls, 1) |
678 | | #define cmd_disable_lop(cldev, pcls)\ |
679 | 178k | cmd_do_enable_lop(cldev, pcls, 0) |
680 | | |
681 | | /* Enable or disable clipping. */ |
682 | | int cmd_put_enable_clip(gx_device_clist_writer *, gx_clist_state *, int); |
683 | | |
684 | | #define cmd_do_enable_clip(cldev, pcls, enable)\ |
685 | 177k | ( (pcls)->clip_enabled == ((enable) ^ 1) &&\ |
686 | 177k | cmd_put_enable_clip(cldev, pcls, enable) < 0 ?\ |
687 | 177k | (cldev)->error_code : 0 ) |
688 | | #define cmd_enable_clip(cldev, pcls)\ |
689 | | cmd_do_enable_clip(cldev, pcls, 1) |
690 | | #define cmd_disable_clip(cldev, pcls)\ |
691 | 1.17k | cmd_do_enable_clip(cldev, pcls, 0) |
692 | | |
693 | | /* Write a command to set the logical operation. */ |
694 | | int cmd_set_lop(gx_device_clist_writer *, gx_clist_state *, |
695 | | gs_logical_operation_t); |
696 | | |
697 | | /* Disable (if default) or enable the logical operation, setting it if */ |
698 | | /* needed. */ |
699 | | int cmd_update_lop(gx_device_clist_writer *, gx_clist_state *, |
700 | | gs_logical_operation_t); |
701 | | |
702 | | /* |
703 | | * For dividing up an operation into bands, use the control pattern : |
704 | | * |
705 | | * cmd_rects_enum_t re; |
706 | | * RECT_ENUM_INIT(re, ry, rheight); |
707 | | * do { |
708 | | * RECT_STEP_INIT(re); |
709 | | * ... process rectangle x, y, width, height in band pcls ... |
710 | | * |
711 | | * ........ |
712 | | * } while ((re.y += re.height) < re.yend); |
713 | | * |
714 | | * Note that RECT_STEP_INIT(re) sets re.height. It is OK for the code that |
715 | | * processes each band to reset height to a smaller (positive) value; the |
716 | | * vertical subdivision code in copy_mono, copy_color, and copy_alpha makes |
717 | | * use of this. The band processing code may `continue' (to reduce nesting |
718 | | * of conditionals). |
719 | | * |
720 | | * If a put_params call fails, the device will be left in a closed state, |
721 | | * but higher-level code won't notice this fact. We flag this by setting |
722 | | * permanent_error, which prevents writing to the command list. |
723 | | */ |
724 | | |
725 | | typedef struct cmd_rects_enum_s { |
726 | | int y; |
727 | | int height; |
728 | | int yend; |
729 | | int band_height; |
730 | | int band; |
731 | | gx_clist_state *pcls; |
732 | | int band_end; |
733 | | int rect_nbands; |
734 | | } cmd_rects_enum_t; |
735 | | |
736 | | #define RECT_ENUM_INIT(re, yvar, heightvar)\ |
737 | 108k | re.y = yvar;\ |
738 | 108k | re.height = heightvar;\ |
739 | 108k | re.yend = re.y + re.height;\ |
740 | 108k | re.band_height = cdev->page_info.band_params.BandHeight;\ |
741 | 108k | re.rect_nbands = (re.yend - re.y + re.band_height - 1) / re.band_height; |
742 | | |
743 | | #define RECT_STEP_INIT(re)\ |
744 | 179k | re.band = re.y / re.band_height;\ |
745 | 179k | re.pcls = cdev->states + re.band;\ |
746 | 179k | re.band_end = (re.band + 1) * re.band_height;\ |
747 | 179k | re.height = min(re.band_end, re.yend) - re.y; |
748 | | |
749 | | /* Read a transformation matrix. */ |
750 | | const byte *cmd_read_matrix(gs_matrix * pmat, const byte * cbp); |
751 | | |
752 | | /* ------ Exported by gxclrect.c ------ */ |
753 | | |
754 | | /* Put out a fill or tile rectangle command. */ |
755 | | int cmd_write_rect_cmd(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
756 | | int op, int x, int y, int width, int height); |
757 | | /* Put out a fill with a devn color */ |
758 | | int cmd_write_rect_hl_cmd(gx_device_clist_writer * cldev, |
759 | | gx_clist_state * pcls, int op, int x, int y, |
760 | | int width, int height, bool extended_command); |
761 | | /* Put out a fill or tile rectangle command for fillpage. */ |
762 | | int cmd_write_page_rect_cmd(gx_device_clist_writer * cldev, int op); |
763 | | |
764 | | /* ------ Exported by gxclbits.c ------ */ |
765 | | |
766 | | /* |
767 | | * Put a bitmap in the buffer, compressing if appropriate. |
768 | | * pcls == 0 means put the bitmap in all bands. |
769 | | * Return <0 if error, otherwise the compression method. |
770 | | * A return value of gs_error_limitcheck means that the bitmap was too big |
771 | | * to fit in the command reading buffer. |
772 | | * Note that this leaves room for the command and initial arguments, |
773 | | * but doesn't fill them in. |
774 | | * |
775 | | * If decompress_elsewhere is set in the compression_mask, it is OK |
776 | | * to write out a compressed bitmap whose decompressed size is too large |
777 | | * to fit in the command reading buffer. (This is OK when reading a |
778 | | * cached bitmap, but not a bitmap for a one-time copy operation.) |
779 | | */ |
780 | 76.8k | #define decompress_elsewhere 0x100 |
781 | | /* |
782 | | * If decompress_spread is set, the decompressed data will be spread out |
783 | | * for replication, so we drop all the padding even if the width is |
784 | | * greater than cmd_max_short_width_bytes (see above). |
785 | | */ |
786 | 1.24k | #define decompress_spread 0x200 |
787 | | |
788 | | /* clist_copy_mono and clist_copy_color have a max_size, but tiles to the */ |
789 | | /* cache do not (clist_change_bits and clist_change_tile). */ |
790 | 39.6k | #define allow_large_bitmap 0x400 |
791 | | |
792 | | int cmd_put_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
793 | | const byte * data, uint width_bits, uint height, |
794 | | uint raster, int op_size, int compression_mask, |
795 | | byte ** pdp, uint * psize); |
796 | | |
797 | | /* |
798 | | * Put out commands for a color map (transfer function, black generation, or |
799 | | * undercolor removal). If pid != 0, write the map only if its ID differs |
800 | | * from the current one, and update the saved ID in the case. |
801 | | */ |
802 | | typedef enum { |
803 | | cmd_map_transfer = 0, /* all transfer functions */ |
804 | | cmd_map_transfer_0, /* transfer[0] */ |
805 | | cmd_map_transfer_1, /* transfer[1] */ |
806 | | cmd_map_transfer_2, /* transfer[2] */ |
807 | | cmd_map_transfer_3, /* transfer[3] */ |
808 | | cmd_map_black_generation, |
809 | | cmd_map_undercolor_removal |
810 | | } cmd_map_index; |
811 | | typedef enum { |
812 | | cmd_map_none = 0, /* no map, use default */ |
813 | | cmd_map_identity, /* identity map */ |
814 | | cmd_map_other /* other map */ |
815 | | } cmd_map_contents; |
816 | | int cmd_put_color_map(gx_device_clist_writer * cldev, |
817 | | cmd_map_index map_index, int comp_num, |
818 | | const gx_transfer_map * map, gs_id * pid); |
819 | | |
820 | | /* |
821 | | * Change tiles for clist_tile_rectangle. (We make this a separate |
822 | | * procedure primarily for readability.) |
823 | | */ |
824 | | int clist_change_tile(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
825 | | const gx_strip_bitmap * tiles, int depth); |
826 | | |
827 | | /* |
828 | | * Change "tile" for clist_copy_*. Only uses tiles->{data, id, raster, |
829 | | * rep_width, rep_height}. tiles->[rep_]shift must be zero. |
830 | | */ |
831 | | int clist_change_bits(gx_device_clist_writer * cldev, gx_clist_state * pcls, |
832 | | const gx_strip_bitmap * tiles, int depth); |
833 | | |
834 | | /* ------ Exported by gxclimag.c ------ */ |
835 | | |
836 | | /* |
837 | | * Write out any necessary color mapping data. |
838 | | */ |
839 | | int cmd_put_color_mapping(gx_device_clist_writer * cldev, |
840 | | const gs_gstate * pgs); |
841 | | /* |
842 | | * Add commands to represent a full (device) halftone. |
843 | | * (This routine should probably be in some other module.) |
844 | | */ |
845 | | int cmd_put_halftone(gx_device_clist_writer * cldev, |
846 | | const gx_device_halftone * pdht); |
847 | | |
848 | | /* ------ Exported by gxclrast.c for gxclread.c ------ */ |
849 | | |
850 | | /* |
851 | | * Define whether we are actually rendering a band, or just executing |
852 | | * the put_params that occurs at the beginning of each page. |
853 | | */ |
854 | | typedef enum { |
855 | | playback_action_render, |
856 | | playback_action_render_no_pdf14, |
857 | | playback_action_setup |
858 | | } clist_playback_action; |
859 | | |
860 | | /* Play back and rasterize one band. */ |
861 | | int clist_playback_band(clist_playback_action action, |
862 | | gx_device_clist_reader *cdev, |
863 | | stream *s, gx_device *target, |
864 | | int x0, int y0, gs_memory_t *mem); |
865 | | |
866 | | /* Playback the band file, taking the indicated action w/ its contents. */ |
867 | | int clist_playback_file_bands(clist_playback_action action, |
868 | | gx_device_clist_reader *crdev, |
869 | | gx_band_page_info_t *page_info, gx_device *target, |
870 | | int band_first, int band_last, int x0, int y0); |
871 | | #ifdef DEBUG |
872 | | int64_t clist_file_offset(const stream_state *st, uint buffer_offset); |
873 | | void top_up_offset_map(stream_state * st, const byte *buf, const byte *ptr, const byte *end); |
874 | | void offset_map_next_data_out_of_band(stream_state *st); |
875 | | void clist_debug_op(gs_memory_t *mem, const unsigned char *op_ptr); |
876 | | void adjust_offset_map_for_skipped_data(stream_state *st, uint buffer_offset, uint skipped); |
877 | | #endif |
878 | | |
879 | | int clist_writer_push_no_cropping(gx_device_clist_writer *cdev); |
880 | | int clist_writer_push_cropping(gx_device_clist_writer *cdev, int ry, int rheight); |
881 | | int clist_writer_pop_cropping(gx_device_clist_writer *cdev); |
882 | | int clist_writer_check_empty_cropping_stack(gx_device_clist_writer *cdev); |
883 | | int clist_read_icctable(gx_device_clist_reader *crdev); |
884 | | int clist_read_color_usage_array(gx_device_clist_reader *crdev); |
885 | | int clist_read_op_equiv_cmyk_colors(gx_device_clist_reader *crdev, |
886 | | equivalent_cmyk_color_params *op_equiv); |
887 | | |
888 | | /* Special write out for the serialized icc profile table */ |
889 | | |
890 | | int cmd_write_icctable(gx_device_clist_writer * cldev, unsigned char *pbuf, int data_size); |
891 | | |
892 | | /* Enumeration of psuedo band offsets for extra c-list data. |
893 | | This includes the ICC profile table and and color_usage and |
894 | | may later include compressed image data */ |
895 | | |
896 | | typedef enum { |
897 | | COLOR_USAGE_OFFSET = 1, |
898 | | SPOT_EQUIV_COLORS = 2, |
899 | | ICC_TABLE_OFFSET = 3 |
900 | | |
901 | | } psuedoband_offset; |
902 | | |
903 | | /* Enumeration of compositor actions for band cropping. */ |
904 | | |
905 | | typedef enum { |
906 | | ALLBANDS = 0, |
907 | | PUSHCROP, |
908 | | POPCROP, |
909 | | CURRBANDS, |
910 | | SAMEAS_PUSHCROP_BUTNOPUSH |
911 | | } cl_crop_action; |
912 | | |
913 | | /* Valgrind helper macro */ |
914 | | #ifdef HAVE_VALGRIND |
915 | | #define CMD_CHECK_LAST_OP_BLOCK_DEFINED(cldev) \ |
916 | | do {\ |
917 | | gx_device_clist_writer *CLDEV = (gx_device_clist_writer *)(cldev);\ |
918 | | if (CLDEV->ccl != NULL)\ |
919 | | VALGRIND_CHECK_MEM_IS_DEFINED(&CLDEV->ccl->tail[1], CLDEV->ccl->tail->size);\ |
920 | | } while (0 == 1) |
921 | | #else |
922 | 2.93M | #define CMD_CHECK_LAST_OP_BLOCK_DEFINED(cldev) do { } while (0) |
923 | | #endif |
924 | | |
925 | | #endif /* gxcldev_INCLUDED */ |