1 /* Copyright (C) 1998, 2000 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /*$Id: gxclrast.c,v 1.33 2005/03/14 18:08:36 dan Exp $ */
18 /* Command list interpreter/rasterizer */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gp.h" /* for gp_fmode_rb */
22 #include "gpcheck.h"
23 #include "gserrors.h"
24 #include "gscdefs.h" /* for image type table */
25 #include "gsbitops.h"
26 #include "gsparams.h"
27 #include "gsstate.h" /* (should only be imager state) */
28 #include "gxdcolor.h"
29 #include "gxdevice.h"
30 #include "gscoord.h" /* requires gsmatrix.h */
31 #include "gsdevice.h" /* for gs_deviceinitialmatrix */
32 #include "gsiparm4.h"
33 #include "gxdevmem.h" /* must precede gxcldev.h */
34 #include "gxcldev.h"
35 #include "gxclpath.h"
36 #include "gxcmap.h"
37 #include "gxcolor2.h"
38 #include "gxcspace.h" /* for gs_color_space_type */
39 #include "gxdhtres.h"
40 #include "gxgetbit.h"
41 #include "gxpaint.h" /* for gx_fill/stroke_params */
42 #include "gxhttile.h"
43 #include "gxiparam.h"
44 #include "gzpath.h"
45 #include "gzcpath.h"
46 #include "gzacpath.h"
47 #include "stream.h"
48 #include "strimpl.h"
49 #include "gxcomp.h"
50 #include "gsserial.h"
51 #include "gxdhtserial.h"
52 #include "gzht.h"
53
54 extern_gx_device_halftone_list();
55 extern_gx_image_type_table();
56
57 /* We need color space types for constructing temporary color spaces. */
58 extern const gs_color_space_type gs_color_space_type_Indexed;
59
60 /* Print a bitmap for tracing */
61 #ifdef DEBUG
62 private void
cmd_print_bits(const byte * data,int width,int height,int raster)63 cmd_print_bits(const byte * data, int width, int height, int raster)
64 {
65 int i, j;
66
67 dlprintf3("[L]width=%d, height=%d, raster=%d\n",
68 width, height, raster);
69 for (i = 0; i < height; i++) {
70 const byte *row = data + i * raster;
71
72 dlprintf("[L]");
73 for (j = 0; j < raster; j++)
74 dprintf1(" %02x", row[j]);
75 dputc('\n');
76 }
77 }
78 #else
79 # define cmd_print_bits(data, width, height, raster) DO_NOTHING
80 #endif
81
82 /* Get a variable-length integer operand. */
83 #define cmd_getw(var, p)\
84 BEGIN\
85 if ( *p < 0x80 ) var = *p++;\
86 else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
87 END
88
89 private long
cmd_get_w(const byte * p,const byte ** rp)90 cmd_get_w(const byte * p, const byte ** rp)
91 {
92 long val = *p++ & 0x7f;
93 int shift = 7;
94
95 for (; val += (long)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
96 *rp = p;
97 return val;
98 }
99
100 /*
101 * Define the structure for keeping track of the command reading buffer.
102 *
103 * The ptr member is only used for passing the current pointer to, and
104 * receiving an updated pointer from, commands implemented as separate
105 * procedures: normally it is kept in a register.
106 */
107 typedef struct command_buf_s {
108 byte *data; /* actual buffer, guaranteed aligned */
109 uint size;
110 const byte *ptr; /* next byte to be read (see above) */
111 const byte *limit; /* refill warning point */
112 const byte *end; /* byte just beyond valid data */
113 stream *s; /* for refilling buffer */
114 int end_status;
115 } command_buf_t;
116
117 /* Set the end of a command buffer. */
118 private void
set_cb_end(command_buf_t * pcb,const byte * end)119 set_cb_end(command_buf_t *pcb, const byte *end)
120 {
121 pcb->end = end;
122 pcb->limit = pcb->data + (pcb->size - cmd_largest_size + 1);
123 if ( pcb->limit > pcb->end )
124 pcb->limit = pcb->end;
125 }
126
127 /* Read more data into a command buffer. */
128 private const byte *
top_up_cbuf(command_buf_t * pcb,const byte * cbp)129 top_up_cbuf(command_buf_t *pcb, const byte *cbp)
130 {
131 uint nread;
132 byte *cb_top = pcb->data + (pcb->end - cbp);
133
134 memmove(pcb->data, cbp, pcb->end - cbp);
135 nread = pcb->end - cb_top;
136 pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
137 if ( nread == 0 ) {
138 /* No data for this band at all. */
139 *cb_top = cmd_opv_end_run;
140 nread = 1;
141 }
142 set_cb_end(pcb, cb_top + nread);
143 process_interrupts(pcb->s->memory);
144 return pcb->data;
145 }
146
147 /* Read data from the command buffer and stream. */
148 private const byte *
cmd_read_data(command_buf_t * pcb,byte * ptr,uint rsize,const byte * cbp)149 cmd_read_data(command_buf_t *pcb, byte *ptr, uint rsize, const byte *cbp)
150 {
151 if (pcb->end - cbp >= rsize) {
152 memcpy(ptr, cbp, rsize);
153 return cbp + rsize;
154 } else {
155 uint cleft = pcb->end - cbp;
156 uint rleft = rsize - cleft;
157
158 memcpy(ptr, cbp, cleft);
159 sgets(pcb->s, ptr + cleft, rleft, &rleft);
160 return pcb->end;
161 }
162 }
163 #define cmd_read(ptr, rsize, cbp)\
164 cbp = cmd_read_data(&cbuf, ptr, rsize, cbp)
165
166 /* Read a fixed-size value from the command buffer. */
167 inline private const byte *
cmd_copy_value(void * pvar,int var_size,const byte * cbp)168 cmd_copy_value(void *pvar, int var_size, const byte *cbp)
169 {
170 memcpy(pvar, cbp, var_size);
171 return cbp + var_size;
172 }
173 #define cmd_get_value(var, cbp)\
174 cbp = cmd_copy_value(&var, sizeof(var), cbp)
175
176
177 /*
178 * Define a buffer structure to hold a serialized halftone. This is
179 * used only if the serialized halftone is too large to fit into
180 * the command buffer.
181 */
182 typedef struct ht_buff_s {
183 uint ht_size, read_size;
184 byte * pcurr;
185 byte * pbuff;
186 } ht_buff_t;
187
188 /*
189 * Render one band to a specified target device. Note that if
190 * action == setup, target may be 0.
191 */
192 private int read_set_tile_size(command_buf_t *pcb, tile_slot *bits);
193 private int read_set_bits(command_buf_t *pcb, tile_slot *bits,
194 int compress, gx_clist_state *pcls,
195 gx_strip_bitmap *tile, tile_slot **pslot,
196 gx_device_clist_reader *cdev, gs_memory_t *mem);
197 private int read_set_misc2(command_buf_t *pcb, gs_imager_state *pis,
198 segment_notes *pnotes);
199 private int read_set_color_space(command_buf_t *pcb, gs_imager_state *pis,
200 const gs_color_space **ppcs,
201 gs_color_space *pcolor_space,
202 gs_memory_t *mem);
203 private int read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
204 const gs_color_space *pcs);
205 private int read_put_params(command_buf_t *pcb, gs_imager_state *pis,
206 gx_device_clist_reader *cdev,
207 gs_memory_t *mem);
208 private int read_create_compositor(command_buf_t *pcb, gs_imager_state *pis,
209 gx_device_clist_reader *cdev,
210 gs_memory_t *mem, gx_device ** ptarget);
211 private int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *);
212 private int read_ht_segment(ht_buff_t *, command_buf_t *, gs_imager_state *,
213 gx_device *, gs_memory_t *);
214
215 private const byte *cmd_read_rect(int, gx_cmd_rect *, const byte *);
216 private const byte *cmd_read_matrix(gs_matrix *, const byte *);
217 private const byte *cmd_read_short_bits(command_buf_t *pcb, byte *data,
218 int width_bytes, int height,
219 uint raster, const byte *cbp);
220 private int cmd_select_map(cmd_map_index, cmd_map_contents,
221 gs_imager_state *, int **,
222 frac **, uint *, gs_memory_t *);
223 private int cmd_create_dev_ht(gx_device_halftone **, gs_memory_t *);
224 private int cmd_resize_halftone(gx_device_halftone **, uint,
225 gs_memory_t *);
226 private int clist_decode_segment(gx_path *, int, fixed[6],
227 gs_fixed_point *, int, int,
228 segment_notes);
229 private int clist_do_polyfill(gx_device *, gx_path *,
230 const gx_drawing_color *,
231 gs_logical_operation_t);
232
233 int
clist_playback_band(clist_playback_action playback_action,gx_device_clist_reader * cdev,stream * s,gx_device * target,int x0,int y0,gs_memory_t * mem)234 clist_playback_band(clist_playback_action playback_action,
235 gx_device_clist_reader *cdev, stream *s,
236 gx_device *target, int x0, int y0, gs_memory_t * mem)
237 {
238 /* cbuf must be maximally aligned, but still be a byte *. */
239 typedef union { void *p; double d; long l; } aligner_t;
240 aligner_t cbuf_storage[cbuf_size / sizeof(aligner_t) + 1];
241 command_buf_t cbuf;
242 /* data_bits is for short copy_* bits and copy_* compressed, */
243 /* must be aligned */
244 #define data_bits_size cbuf_size
245 byte *data_bits = 0;
246 register const byte *cbp;
247 int dev_depth; /* May vary due to compositing devices */
248 int dev_depth_bytes;
249 int odd_delta_shift;
250 int num_zero_bytes;
251 gx_device *tdev;
252 gx_clist_state state;
253 gx_color_index *set_colors;
254 tile_slot *state_slot;
255 gx_strip_bitmap state_tile; /* parameters for reading tiles */
256 tile_slot tile_bits; /* parameters of current tile */
257 gs_int_point tile_phase, color_phase;
258 gx_path path;
259 bool in_path;
260 gs_fixed_point ppos;
261 gx_clip_path clip_path;
262 bool use_clip;
263 gx_clip_path *pcpath;
264 gx_device_cpath_accum clip_accum;
265 gs_fixed_rect target_box;
266 struct _cas {
267 bool lop_enabled;
268 gs_fixed_point fill_adjust;
269 gx_device_color dcolor;
270 } clip_save;
271 bool in_clip = false;
272 gs_imager_state imager_state;
273 gx_device_color dev_color;
274 float dash_pattern[cmd_max_dash];
275 gx_fill_params fill_params;
276 gx_stroke_params stroke_params;
277 gs_halftone_type halftone_type;
278 union im_ {
279 gs_image_common_t c;
280 gs_data_image_t d;
281 gs_image1_t i1;
282 gs_image4_t i4;
283 } image;
284 gs_int_rect image_rect;
285 gs_color_space color_space; /* only used for indexed spaces */
286 const gs_color_space *pcs;
287 gs_color_space cs;
288 gx_image_enum_common_t *image_info;
289 gx_image_plane_t planes[32];
290 uint data_height;
291 uint data_size;
292 byte *data_on_heap;
293 fixed vs[6];
294 segment_notes notes;
295 int data_x;
296 int code = 0;
297 ht_buff_t ht_buff;
298 gx_device *const orig_target = target;
299
300 cbuf.data = (byte *)cbuf_storage;
301 cbuf.size = cbuf_size;
302 cbuf.s = s;
303 cbuf.end_status = 0;
304 set_cb_end(&cbuf, cbuf.data + cbuf.size);
305 cbp = cbuf.end;
306
307 memset(&ht_buff, 0, sizeof(ht_buff));
308
309 in: /* Initialize for a new page. */
310 tdev = target;
311 set_colors = state.colors;
312 use_clip = false;
313 pcpath = NULL;
314 notes = sn_none;
315 data_x = 0;
316 {
317 static const gx_clist_state cls_initial = { cls_initial_values };
318
319 state = cls_initial;
320 }
321 state_tile.id = gx_no_bitmap_id;
322 state_tile.shift = state_tile.rep_shift = 0;
323 tile_phase.x = color_phase.x = x0;
324 tile_phase.y = color_phase.y = y0;
325 gx_path_init_local(&path, mem);
326 in_path = false;
327 /*
328 * Initialize the clipping region to the full page.
329 * (Since we also initialize use_clip to false, this is arbitrary.)
330 */
331 {
332 gs_fixed_rect cbox;
333
334 gx_cpath_init_local(&clip_path, mem);
335 cbox.p.x = 0;
336 cbox.p.y = 0;
337 cbox.q.x = cdev->width;
338 cbox.q.y = cdev->height;
339 gx_cpath_from_rectangle(&clip_path, &cbox);
340 }
341 if (target != 0)
342 (*dev_proc(target, get_clipping_box))(target, &target_box);
343 imager_state = clist_imager_state_initial;
344 code = gs_imager_state_initialize(&imager_state, mem);
345 if (code < 0)
346 goto out;
347 imager_state.line_params.dash.pattern = dash_pattern;
348 if (tdev != 0)
349 gx_set_cmap_procs(&imager_state, tdev);
350 gx_imager_setscreenphase(&imager_state, -x0, -y0, gs_color_select_all);
351 halftone_type = ht_type_none;
352 fill_params.fill_zero_width = false;
353 gs_cspace_init_DeviceGray(mem, &cs);
354 pcs = &cs;
355 color_unset(&dev_color);
356 color_space.params.indexed.use_proc = 0;
357 color_space.params.indexed.lookup.table.size = 0;
358 data_bits = gs_alloc_bytes(mem, data_bits_size,
359 "clist_playback_band(data_bits)");
360 if (data_bits == 0) {
361 code = gs_note_error(gs_error_VMerror);
362 goto out;
363 }
364 while (code >= 0) {
365 int op;
366 int compress;
367 int depth = 0x7badf00d; /* Initialize against indeterminizm. */
368 int raster = 0x7badf00d; /* Initialize against indeterminizm. */
369 byte *source = NULL; /* Initialize against indeterminizm. */
370 gx_color_index colors[2];
371 gx_color_index *pcolor;
372 gs_logical_operation_t log_op;
373 tile_slot bits; /* parameters for reading bits */
374
375 /* Make sure the buffer contains a full command. */
376 if (cbp >= cbuf.limit) {
377 if (cbuf.end_status < 0) { /* End of file or error. */
378 if (cbp == cbuf.end) {
379 code = (cbuf.end_status == EOFC ? 0 :
380 gs_note_error(gs_error_ioerror));
381 break;
382 }
383 } else {
384 cbp = top_up_cbuf(&cbuf, cbp);
385 }
386 }
387 op = *cbp++;
388 #ifdef DEBUG
389 if (gs_debug_c('L')) {
390 const char *const *sub = cmd_sub_op_names[op >> 4];
391
392 if (sub)
393 dlprintf1("[L]%s:", sub[op & 0xf]);
394 else
395 dlprintf2("[L]%s %d:", cmd_op_names[op >> 4], op & 0xf);
396 }
397 #endif
398 switch (op >> 4) {
399 case cmd_op_misc >> 4:
400 switch (op) {
401 case cmd_opv_end_run:
402 if_debug0('L', "\n");
403 continue;
404 case cmd_opv_set_tile_size:
405 cbuf.ptr = cbp;
406 code = read_set_tile_size(&cbuf, &tile_bits);
407 cbp = cbuf.ptr;
408 if (code < 0)
409 goto out;
410 continue;
411 case cmd_opv_set_tile_phase:
412 cmd_getw(state.tile_phase.x, cbp);
413 cmd_getw(state.tile_phase.y, cbp);
414 if_debug2('L', " (%d,%d)\n",
415 state.tile_phase.x,
416 state.tile_phase.y);
417 goto set_phase;
418 case cmd_opv_set_tile_bits:
419 bits = tile_bits;
420 compress = 0;
421 stb:
422 cbuf.ptr = cbp;
423 code = read_set_bits(&cbuf, &bits, compress,
424 &state, &state_tile, &state_slot,
425 cdev, mem);
426 cbp = cbuf.ptr;
427 if (code < 0)
428 goto out;
429 goto stp;
430 case cmd_opv_set_bits:
431 compress = *cbp & 3;
432 bits.cb_depth = *cbp++ >> 2;
433 cmd_getw(bits.width, cbp);
434 cmd_getw(bits.height, cbp);
435 if_debug4('L', " compress=%d depth=%d size=(%d,%d)",
436 compress, bits.cb_depth,
437 bits.width, bits.height);
438 bits.cb_raster =
439 bitmap_raster(bits.width * bits.cb_depth);
440 bits.x_reps = bits.y_reps = 1;
441 bits.shift = bits.rep_shift = 0;
442 goto stb;
443 case cmd_opv_set_tile_color:
444 set_colors = state.tile_colors;
445 if_debug0('L', "\n");
446 continue;
447 case cmd_opv_set_misc:
448 {
449 uint cb = *cbp++;
450
451 switch (cb >> 6) {
452 case cmd_set_misc_lop >> 6:
453 cmd_getw(state.lop, cbp);
454 state.lop = (state.lop << 6) + (cb & 0x3f);
455 if_debug1('L', " lop=0x%x\n", state.lop);
456 if (state.lop_enabled)
457 imager_state.log_op = state.lop;
458 break;
459 case cmd_set_misc_data_x >> 6:
460 if (cb & 0x20)
461 cmd_getw(data_x, cbp);
462 else
463 data_x = 0;
464 data_x = (data_x << 5) + (cb & 0x1f);
465 if_debug1('L', " data_x=%d\n", data_x);
466 break;
467 case cmd_set_misc_map >> 6:
468 {
469 frac *mdata;
470 int *pcomp_num;
471 uint count;
472 cmd_map_contents cont =
473 (cmd_map_contents)(cb & 0x30) >> 4;
474
475 code = cmd_select_map(cb & 0xf, cont,
476 &imager_state,
477 &pcomp_num,
478 &mdata, &count, mem);
479
480 if (code < 0)
481 goto out;
482 /* Get component number if relevant */
483 if (pcomp_num == NULL)
484 cbp++;
485 else {
486 *pcomp_num = (int) *cbp++;
487 if_debug1('L', " comp_num=%d",
488 *pcomp_num);
489 }
490 if (cont == cmd_map_other) {
491 cmd_read((byte *)mdata, count, cbp);
492 #ifdef DEBUG
493 if (gs_debug_c('L')) {
494 uint i;
495
496 for (i = 0; i < count / sizeof(*mdata); ++i)
497 dprintf1(" 0x%04x", mdata[i]);
498 dputc('\n');
499 }
500 } else {
501 if_debug0('L', " none\n");
502 #endif
503 }
504 }
505 /* Recompute the effective transfer, */
506 /* in case this was a transfer map. */
507 gx_imager_set_effective_xfer(&imager_state);
508 break;
509 case cmd_set_misc_halftone >> 6: {
510 uint num_comp;
511
512 halftone_type = cb & 0x3f;
513 cmd_getw(num_comp, cbp);
514 if_debug2('L', " halftone type=%d num_comp=%u\n",
515 halftone_type, num_comp);
516 code = cmd_resize_halftone(
517 &imager_state.dev_ht,
518 num_comp, mem);
519 if (code < 0)
520 goto out;
521 break;
522 }
523 default:
524 goto bad_op;
525 }
526 }
527 continue;
528 case cmd_opv_enable_lop:
529 state.lop_enabled = true;
530 imager_state.log_op = state.lop;
531 if_debug0('L', "\n");
532 continue;
533 case cmd_opv_disable_lop:
534 state.lop_enabled = false;
535 imager_state.log_op = lop_default;
536 if_debug0('L', "\n");
537 continue;
538 case cmd_opv_end_page:
539 if_debug0('L', "\n");
540 /*
541 * Do end-of-page cleanup, then reinitialize if
542 * there are more pages to come.
543 */
544 goto out;
545 case cmd_opv_delta_color0:
546 pcolor = &set_colors[0];
547 goto delta2_c;
548 case cmd_opv_delta_color1:
549 pcolor = &set_colors[1];
550 delta2_c:set_colors = state.colors;
551 /* See comments for cmd_put_color() in gxclutil.c. */
552 {
553 gx_color_index delta = 0;
554 uint data;
555
556 dev_depth = cdev->color_info.depth;
557 dev_depth_bytes = (dev_depth + 7) >> 3;
558 switch (dev_depth_bytes) {
559 /* For cases with an even number of bytes */
560 case 8:
561 data = *cbp++;
562 delta = ((gx_color_index)
563 ((data & 0xf0) << 4) + (data & 0x0f)) << 48;
564 case 6:
565 data = *cbp++;
566 delta |= ((gx_color_index)
567 ((data & 0xf0) << 4) + (data & 0x0f)) << 32;
568 case 4:
569 data = *cbp++;
570 delta |= ((gx_color_index)
571 ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
572 case 2:
573 data = *cbp++;
574 delta |= ((gx_color_index)
575 ((data & 0xf0) << 4) + (data & 0x0f));
576 break;
577 /* For cases with an odd number of bytes */
578 case 7:
579 data = *cbp++;
580 delta = ((gx_color_index)
581 ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
582 case 5:
583 data = *cbp++;
584 delta |= ((gx_color_index)
585 ((data & 0xf0) << 4) + (data & 0x0f));
586 case 3:
587 data = *cbp++;
588 odd_delta_shift = (dev_depth_bytes - 3) * 8;
589 delta |= ((gx_color_index)
590 ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
591 data = *cbp++;
592 delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
593 << (odd_delta_shift + 11);
594 }
595 *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
596 }
597 if_debug1('L', " 0x%lx\n", *pcolor);
598 continue;
599 case cmd_opv_set_copy_color:
600 state.color_is_alpha = 0;
601 if_debug0('L', "\n");
602 continue;
603 case cmd_opv_set_copy_alpha:
604 state.color_is_alpha = 1;
605 if_debug0('L', "\n");
606 continue;
607 default:
608 goto bad_op;
609 }
610 /*NOTREACHED */
611 case cmd_op_set_color0 >> 4:
612 pcolor = &set_colors[0];
613 goto set_color;
614 case cmd_op_set_color1 >> 4:
615 pcolor = &set_colors[1];
616 set_color:set_colors = state.colors;
617 /*
618 * We have a special case for gx_no_color_index. If the low
619 * order 4 bits are "cmd_no_color_index" then we really
620 * have a value of gx_no_color_index. Otherwise the these
621 * bits indicate the number of low order zero bytes in the
622 * value. See comments for cmd_put_color() in gxclutil.c.
623 */
624 num_zero_bytes = op & 0x0f;
625
626 if (num_zero_bytes == cmd_no_color_index)
627 *pcolor = gx_no_color_index;
628 else {
629 gx_color_index color = 0;
630
631 dev_depth = cdev->color_info.depth;
632 dev_depth_bytes = (dev_depth + 7) >> 3;
633 switch (dev_depth_bytes - num_zero_bytes) {
634 case 8:
635 color = (gx_color_index) * cbp++;
636 case 7:
637 color = (color << 8) | (gx_color_index) * cbp++;
638 case 6:
639 color = (color << 8) | (gx_color_index) * cbp++;
640 case 5:
641 color = (color << 8) | (gx_color_index) * cbp++;
642 case 4:
643 color = (color << 8) | (gx_color_index) * cbp++;
644 case 3:
645 color = (color << 8) | (gx_color_index) * cbp++;
646 case 2:
647 color = (color << 8) | (gx_color_index) * cbp++;
648 case 1:
649 color = (color << 8) | (gx_color_index) * cbp++;
650 default:
651 break;
652 }
653 color <<= num_zero_bytes * 8;
654 *pcolor = color;
655 }
656 if_debug1('L', " 0x%lx\n", *pcolor);
657 continue;
658 case cmd_op_fill_rect >> 4:
659 case cmd_op_tile_rect >> 4:
660 cbp = cmd_read_rect(op, &state.rect, cbp);
661 break;
662 case cmd_op_fill_rect_short >> 4:
663 case cmd_op_tile_rect_short >> 4:
664 state.rect.x += *cbp + cmd_min_short;
665 state.rect.width += cbp[1] + cmd_min_short;
666 if (op & 0xf) {
667 state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
668 cbp += 2;
669 } else {
670 state.rect.y += cbp[2] + cmd_min_short;
671 state.rect.height += cbp[3] + cmd_min_short;
672 cbp += 4;
673 }
674 break;
675 case cmd_op_fill_rect_tiny >> 4:
676 case cmd_op_tile_rect_tiny >> 4:
677 if (op & 8)
678 state.rect.x += state.rect.width;
679 else {
680 int txy = *cbp++;
681
682 state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
683 state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
684 }
685 state.rect.width += (op & 7) + cmd_min_dw_tiny;
686 break;
687 case cmd_op_copy_mono >> 4:
688 depth = 1;
689 goto copy;
690 case cmd_op_copy_color_alpha >> 4:
691 if (state.color_is_alpha) {
692 if (!(op & 8))
693 depth = *cbp++;
694 } else
695 depth = cdev->color_info.depth;
696 copy:cmd_getw(state.rect.x, cbp);
697 cmd_getw(state.rect.y, cbp);
698 if (op & 8) { /* Use the current "tile". */
699 #ifdef DEBUG
700 if (state_slot->index != state.tile_index) {
701 lprintf2("state_slot->index = %d, state.tile_index = %d!\n",
702 state_slot->index,
703 state.tile_index);
704 code = gs_note_error(gs_error_ioerror);
705 goto out;
706 }
707 #endif
708 depth = state_slot->cb_depth;
709 state.rect.width = state_slot->width;
710 state.rect.height = state_slot->height;
711 raster = state_slot->cb_raster;
712 source = (byte *) (state_slot + 1);
713 } else { /* Read width, height, bits. */
714 /* depth was set already. */
715 uint width_bits, width_bytes;
716 uint bytes;
717
718 cmd_getw(state.rect.width, cbp);
719 cmd_getw(state.rect.height, cbp);
720 width_bits = state.rect.width * depth;
721 bytes =
722 clist_bitmap_bytes(width_bits,
723 state.rect.height,
724 op & 3, &width_bytes,
725 (uint *)&raster);
726 /* copy_mono and copy_color/alpha */
727 /* ensure that the bits will fit in a single buffer, */
728 /* even after decompression if compressed. */
729 #ifdef DEBUG
730 if (bytes > cbuf_size) {
731 lprintf6("bitmap size exceeds buffer! width=%d raster=%d height=%d\n file pos %ld buf pos %d/%d\n",
732 state.rect.width, raster,
733 state.rect.height,
734 stell(s), (int)(cbp - cbuf.data),
735 (int)(cbuf.end - cbuf.data));
736 code = gs_note_error(gs_error_ioerror);
737 goto out;
738 }
739 #endif
740 if (op & 3) { /* Decompress the image data. */
741 stream_cursor_read r;
742 stream_cursor_write w;
743
744 /* We don't know the data length a priori, */
745 /* so to be conservative, we read */
746 /* the uncompressed size. */
747 uint cleft = cbuf.end - cbp;
748
749 if (cleft < bytes) {
750 uint nread = cbuf_size - cleft;
751
752 memmove(cbuf.data, cbp, cleft);
753 cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
754 set_cb_end(&cbuf, cbuf.data + cleft + nread);
755 cbp = cbuf.data;
756 }
757 r.ptr = cbp - 1;
758 r.limit = cbuf.end - 1;
759 w.ptr = data_bits - 1;
760 w.limit = w.ptr + data_bits_size;
761 switch (op & 3) {
762 case cmd_compress_rle:
763 {
764 stream_RLD_state sstate;
765
766 clist_rld_init(&sstate);
767 /* The process procedure can't fail. */
768 (*s_RLD_template.process)
769 ((stream_state *)&sstate, &r, &w, true);
770 }
771 break;
772 case cmd_compress_cfe:
773 {
774 stream_CFD_state sstate;
775
776 clist_cfd_init(&sstate,
777 width_bytes << 3 /*state.rect.width */ ,
778 state.rect.height, mem);
779 /* The process procedure can't fail. */
780 (*s_CFD_template.process)
781 ((stream_state *)&sstate, &r, &w, true);
782 (*s_CFD_template.release)
783 ((stream_state *)&sstate);
784 }
785 break;
786 default:
787 goto bad_op;
788 }
789 cbp = r.ptr + 1;
790 source = data_bits;
791 } else if (state.rect.height > 1 &&
792 width_bytes != raster
793 ) {
794 source = data_bits;
795 cbp = cmd_read_short_bits(&cbuf, source, width_bytes,
796 state.rect.height,
797 raster, cbp);
798 } else {
799 cmd_read(cbuf.data, bytes, cbp);
800 source = cbuf.data;
801 }
802 #ifdef DEBUG
803 if (gs_debug_c('L')) {
804 dprintf2(" depth=%d, data_x=%d\n",
805 depth, data_x);
806 cmd_print_bits(source, state.rect.width,
807 state.rect.height, raster);
808 }
809 #endif
810 }
811 break;
812 case cmd_op_delta_tile_index >> 4:
813 state.tile_index += (int)(op & 0xf) - 8;
814 goto sti;
815 case cmd_op_set_tile_index >> 4:
816 state.tile_index =
817 ((op & 0xf) << 8) + *cbp++;
818 sti:state_slot =
819 (tile_slot *) (cdev->chunk.data +
820 cdev->tile_table[state.tile_index].offset);
821 if_debug2('L', " index=%u offset=%lu\n",
822 state.tile_index,
823 cdev->tile_table[state.tile_index].offset);
824 state_tile.data = (byte *) (state_slot + 1);
825 stp:state_tile.size.x = state_slot->width;
826 state_tile.size.y = state_slot->height;
827 state_tile.raster = state_slot->cb_raster;
828 state_tile.rep_width = state_tile.size.x /
829 state_slot->x_reps;
830 state_tile.rep_height = state_tile.size.y /
831 state_slot->y_reps;
832 state_tile.rep_shift = state_slot->rep_shift;
833 state_tile.shift = state_slot->shift;
834 set_phase: /*
835 * state.tile_phase is overloaded according to the command
836 * to which it will apply:
837 * For fill_path, stroke_path, fill_triangle/p'gram,
838 * fill_mask, and (mask or CombineWithColor) images,
839 * it is pdcolor->phase. For these operations, we
840 * precompute the color_phase values.
841 * For strip_tile_rectangle and strip_copy_rop,
842 * it is the phase arguments of the call, used with
843 * state_tile. For these operations, we precompute the
844 * tile_phase values.
845 *
846 * Note that control may get here before one or both of
847 * state_tile or dev_ht has been set.
848 */
849 if (state_tile.size.x)
850 tile_phase.x =
851 (state.tile_phase.x + x0) % state_tile.size.x;
852 if (imager_state.dev_ht && imager_state.dev_ht->lcm_width)
853 color_phase.x =
854 (state.tile_phase.x + x0) %
855 imager_state.dev_ht->lcm_width;
856 /*
857 * The true tile height for shifted tiles is not
858 * size.y: see gxbitmap.h for the computation.
859 */
860 if (state_tile.size.y) {
861 int full_height;
862
863 if (state_tile.shift == 0)
864 full_height = state_tile.size.y;
865 else
866 full_height = state_tile.rep_height *
867 (state_tile.rep_width /
868 igcd(state_tile.rep_shift,
869 state_tile.rep_width));
870 tile_phase.y =
871 (state.tile_phase.y + y0) % full_height;
872 }
873 if (imager_state.dev_ht && imager_state.dev_ht->lcm_height)
874 color_phase.y =
875 (state.tile_phase.y + y0) %
876 imager_state.dev_ht->lcm_height;
877 gx_imager_setscreenphase(&imager_state,
878 -(state.tile_phase.x + x0),
879 -(state.tile_phase.y + y0),
880 gs_color_select_all);
881 continue;
882 case cmd_op_misc2 >> 4:
883 switch (op) {
884 case cmd_opv_set_fill_adjust:
885 cmd_get_value(imager_state.fill_adjust.x, cbp);
886 cmd_get_value(imager_state.fill_adjust.y, cbp);
887 if_debug2('L', " (%g,%g)\n",
888 fixed2float(imager_state.fill_adjust.x),
889 fixed2float(imager_state.fill_adjust.y));
890 continue;
891 case cmd_opv_set_ctm:
892 {
893 gs_matrix mat;
894
895 cbp = cmd_read_matrix(&mat, cbp);
896 mat.tx -= x0;
897 mat.ty -= y0;
898 gs_imager_setmatrix(&imager_state, &mat);
899 if_debug6('L', " [%g %g %g %g %g %g]\n",
900 mat.xx, mat.xy, mat.yx, mat.yy,
901 mat.tx, mat.ty);
902 }
903 continue;
904 case cmd_opv_set_misc2:
905 cbuf.ptr = cbp;
906 code = read_set_misc2(&cbuf, &imager_state, ¬es);
907 cbp = cbuf.ptr;
908 if (code < 0)
909 goto out;
910 continue;
911 case cmd_opv_set_dash:
912 {
913 int nb = *cbp++;
914 int n = nb & 0x3f;
915 float dot_length, offset;
916
917 cmd_get_value(dot_length, cbp);
918 cmd_get_value(offset, cbp);
919 memcpy(dash_pattern, cbp, n * sizeof(float));
920
921 gx_set_dash(&imager_state.line_params.dash,
922 dash_pattern, n, offset,
923 NULL);
924 gx_set_dash_adapt(&imager_state.line_params.dash,
925 (nb & 0x80) != 0);
926 gx_set_dot_length(&imager_state.line_params,
927 dot_length,
928 (nb & 0x40) != 0);
929 #ifdef DEBUG
930 if (gs_debug_c('L')) {
931 int i;
932
933 dprintf4(" dot=%g(mode %d) adapt=%d offset=%g [",
934 dot_length,
935 (nb & 0x40) != 0,
936 (nb & 0x80) != 0, offset);
937 for (i = 0; i < n; ++i)
938 dprintf1("%g ", dash_pattern[i]);
939 dputs("]\n");
940 }
941 #endif
942 cbp += n * sizeof(float);
943 }
944 break;
945 case cmd_opv_enable_clip:
946 pcpath = (use_clip ? &clip_path : NULL);
947 if_debug0('L', "\n");
948 break;
949 case cmd_opv_disable_clip:
950 pcpath = NULL;
951 if_debug0('L', "\n");
952 break;
953 case cmd_opv_begin_clip:
954 pcpath = NULL;
955 in_clip = true;
956 if_debug0('L', "\n");
957 code = gx_cpath_reset(&clip_path);
958 if (code < 0)
959 goto out;
960 gx_cpath_accum_begin(&clip_accum, mem);
961 gx_cpath_accum_set_cbox(&clip_accum,
962 &target_box);
963 tdev = (gx_device *)&clip_accum;
964 clip_save.lop_enabled = state.lop_enabled;
965 clip_save.fill_adjust =
966 imager_state.fill_adjust;
967 clip_save.dcolor = dev_color;
968 /* temporarily set a solid color */
969 color_set_pure(&dev_color, (gx_color_index)1);
970 state.lop_enabled = false;
971 imager_state.log_op = lop_default;
972 imager_state.fill_adjust.x =
973 imager_state.fill_adjust.y = fixed_half;
974 break;
975 case cmd_opv_end_clip:
976 if_debug0('L', "\n");
977 gx_cpath_accum_end(&clip_accum, &clip_path);
978 tdev = target;
979 /*
980 * If the entire band falls within the clip
981 * path, no clipping is needed.
982 */
983 {
984 gs_fixed_rect cbox;
985
986 gx_cpath_inner_box(&clip_path, &cbox);
987 use_clip =
988 !(cbox.p.x <= target_box.p.x &&
989 cbox.q.x >= target_box.q.x &&
990 cbox.p.y <= target_box.p.y &&
991 cbox.q.y >= target_box.q.y);
992 }
993 pcpath = (use_clip ? &clip_path : NULL);
994 state.lop_enabled = clip_save.lop_enabled;
995 imager_state.log_op =
996 (state.lop_enabled ? state.lop :
997 lop_default);
998 imager_state.fill_adjust =
999 clip_save.fill_adjust;
1000 dev_color = clip_save.dcolor;
1001 in_clip = false;
1002 break;
1003 case cmd_opv_set_color_space:
1004 cbuf.ptr = cbp;
1005 code = read_set_color_space(&cbuf, &imager_state,
1006 &pcs, &color_space, mem);
1007 cbp = cbuf.ptr;
1008 if (code < 0) {
1009 if (code == gs_error_rangecheck)
1010 goto bad_op;
1011 goto out;
1012 }
1013 break;
1014 case cmd_opv_begin_image_rect:
1015 cbuf.ptr = cbp;
1016 code = read_begin_image(&cbuf, &image.c, pcs);
1017 cbp = cbuf.ptr;
1018 if (code < 0)
1019 goto out;
1020 {
1021 uint diff;
1022
1023 cmd_getw(image_rect.p.x, cbp);
1024 cmd_getw(image_rect.p.y, cbp);
1025 cmd_getw(diff, cbp);
1026 image_rect.q.x = image.d.Width - diff;
1027 cmd_getw(diff, cbp);
1028 image_rect.q.y = image.d.Height - diff;
1029 if_debug4('L', " rect=(%d,%d),(%d,%d)",
1030 image_rect.p.x, image_rect.p.y,
1031 image_rect.q.x, image_rect.q.y);
1032 }
1033 goto ibegin;
1034 case cmd_opv_begin_image:
1035 cbuf.ptr = cbp;
1036 code = read_begin_image(&cbuf, &image.c, pcs);
1037 cbp = cbuf.ptr;
1038 if (code < 0)
1039 goto out;
1040 image_rect.p.x = 0;
1041 image_rect.p.y = 0;
1042 image_rect.q.x = image.d.Width;
1043 image_rect.q.y = image.d.Height;
1044 if_debug2('L', " size=(%d,%d)",
1045 image.d.Width, image.d.Height);
1046 ibegin: if_debug0('L', "\n");
1047 {
1048 code = (*dev_proc(tdev, begin_typed_image))
1049 (tdev, &imager_state, NULL,
1050 (const gs_image_common_t *)&image,
1051 &image_rect, &dev_color, pcpath, mem,
1052 &image_info);
1053 }
1054 if (code < 0)
1055 goto out;
1056 break;
1057 case cmd_opv_image_plane_data:
1058 cmd_getw(data_height, cbp);
1059 if (data_height == 0) {
1060 if_debug0('L', " done image\n");
1061 code = gx_image_end(image_info, true);
1062 if (code < 0)
1063 goto out;
1064 continue;
1065 }
1066 {
1067 uint flags;
1068 int plane;
1069 uint raster1 = 0xbaadf00d; /* Initialize against indeterminizm. */
1070
1071 cmd_getw(flags, cbp);
1072 for (plane = 0;
1073 plane < image_info->num_planes;
1074 ++plane, flags >>= 1
1075 ) {
1076 if (flags & 1) {
1077 if (cbuf.end - cbp <
1078 2 * cmd_max_intsize(sizeof(uint)))
1079 cbp = top_up_cbuf(&cbuf, cbp);
1080 cmd_getw(planes[plane].raster, cbp);
1081 if ((raster1 = planes[plane].raster) != 0)
1082 cmd_getw(data_x, cbp);
1083 } else {
1084 planes[plane].raster = raster1;
1085 }
1086 planes[plane].data_x = data_x;
1087 }
1088 }
1089 goto idata;
1090 case cmd_opv_image_data:
1091 cmd_getw(data_height, cbp);
1092 if (data_height == 0) {
1093 if_debug0('L', " done image\n");
1094 code = gx_image_end(image_info, true);
1095 if (code < 0)
1096 goto out;
1097 continue;
1098 }
1099 {
1100 uint bytes_per_plane;
1101 int plane;
1102
1103 cmd_getw(bytes_per_plane, cbp);
1104 if_debug2('L', " height=%u raster=%u\n",
1105 data_height, bytes_per_plane);
1106 for (plane = 0;
1107 plane < image_info->num_planes;
1108 ++plane
1109 ) {
1110 planes[plane].data_x = data_x;
1111 planes[plane].raster = bytes_per_plane;
1112 }
1113 }
1114 idata: data_size = 0;
1115 {
1116 int plane;
1117
1118 for (plane = 0; plane < image_info->num_planes;
1119 ++plane)
1120 data_size += planes[plane].raster;
1121 }
1122 data_size *= data_height;
1123 data_on_heap = 0;
1124 if (cbuf.end - cbp < data_size)
1125 cbp = top_up_cbuf(&cbuf, cbp);
1126 if (cbuf.end - cbp >= data_size) {
1127 planes[0].data = cbp;
1128 cbp += data_size;
1129 } else {
1130 uint cleft = cbuf.end - cbp;
1131 uint rleft = data_size - cleft;
1132 byte *rdata;
1133
1134 if (data_size > cbuf.end - cbuf.data) {
1135 /* Allocate a separate buffer. */
1136 rdata = data_on_heap =
1137 gs_alloc_bytes(mem, data_size,
1138 "clist image_data");
1139 if (rdata == 0) {
1140 code = gs_note_error(gs_error_VMerror);
1141 goto out;
1142 }
1143 } else
1144 rdata = cbuf.data;
1145 memmove(rdata, cbp, cleft);
1146 sgets(s, rdata + cleft, rleft,
1147 &rleft);
1148 planes[0].data = rdata;
1149 cbp = cbuf.end; /* force refill */
1150 }
1151 {
1152 int plane;
1153 const byte *data = planes[0].data;
1154
1155 for (plane = 0;
1156 plane < image_info->num_planes;
1157 ++plane
1158 ) {
1159 if (planes[plane].raster == 0)
1160 planes[plane].data = 0;
1161 else {
1162 planes[plane].data = data;
1163 data += planes[plane].raster *
1164 data_height;
1165 }
1166 }
1167 }
1168 #ifdef DEBUG
1169 if (gs_debug_c('L')) {
1170 int plane;
1171
1172 for (plane = 0; plane < image_info->num_planes;
1173 ++plane)
1174 if (planes[plane].data != 0)
1175 cmd_print_bits(planes[plane].data,
1176 image_rect.q.x -
1177 image_rect.p.x,
1178 data_height,
1179 planes[plane].raster);
1180 }
1181 #endif
1182 code = gx_image_plane_data(image_info, planes,
1183 data_height);
1184 if (data_on_heap)
1185 gs_free_object(mem, data_on_heap,
1186 "clist image_data");
1187 data_x = 0;
1188 if (code < 0)
1189 goto out;
1190 continue;
1191 case cmd_opv_extend:
1192 switch (*cbp++) {
1193 case cmd_opv_ext_put_params:
1194 cbuf.ptr = cbp;
1195 code = read_put_params(&cbuf, &imager_state,
1196 cdev, mem);
1197 cbp = cbuf.ptr;
1198 if (code > 0)
1199 break; /* empty list */
1200 if (code < 0)
1201 goto out;
1202 if (playback_action == playback_action_setup)
1203 goto out;
1204 break;
1205 case cmd_opv_ext_create_compositor:
1206 cbuf.ptr = cbp;
1207 /*
1208 * The screen phase may have been changed during
1209 * the processing of masked images.
1210 */
1211 gx_imager_setscreenphase(&imager_state,
1212 -x0, -y0, gs_color_select_all);
1213 code = read_create_compositor(&cbuf, &imager_state,
1214 cdev, mem, &target);
1215 cbp = cbuf.ptr;
1216 tdev = target;
1217 if (code < 0)
1218 goto out;
1219 break;
1220 case cmd_opv_ext_put_halftone:
1221 {
1222 uint ht_size;
1223
1224 enc_u_getw(ht_size, cbp);
1225 code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1226 if (code < 0)
1227 goto out;
1228 }
1229 break;
1230 case cmd_opv_ext_put_ht_seg:
1231 cbuf.ptr = cbp;
1232 code = read_ht_segment(&ht_buff, &cbuf,
1233 &imager_state, tdev,
1234 mem);
1235 cbp = cbuf.ptr;
1236 if (code < 0)
1237 goto out;
1238 break;
1239 case cmd_opv_ext_put_drawing_color:
1240 {
1241 uint color_size;
1242 const gx_device_color_type_t * pdct;
1243
1244 pdct = gx_get_dc_type_from_index(*cbp++);
1245 if (pdct == 0) {
1246 code = gs_note_error(gs_error_rangecheck);
1247 goto out;
1248 }
1249 enc_u_getw(color_size, cbp);
1250 if (cbp + color_size > cbuf.limit)
1251 cbp = top_up_cbuf(&cbuf, cbp);
1252 code = pdct->read(&dev_color, &imager_state,
1253 &dev_color, tdev, cbp,
1254 color_size, mem);
1255 if (code < 0)
1256 goto out;
1257 cbp += color_size;
1258 code = gx_color_load(&dev_color,
1259 &imager_state, tdev);
1260 if (code < 0)
1261 goto out;
1262 }
1263 break;
1264 default:
1265 goto bad_op;
1266 }
1267 break;
1268 default:
1269 goto bad_op;
1270 }
1271 continue;
1272 case cmd_op_segment >> 4:
1273 {
1274 int i, code;
1275 static const byte op_num_operands[] = {
1276 cmd_segment_op_num_operands_values
1277 };
1278
1279 if (!in_path) {
1280 ppos.x = int2fixed(state.rect.x);
1281 ppos.y = int2fixed(state.rect.y);
1282 if_debug2('L', " (%d,%d)", state.rect.x,
1283 state.rect.y);
1284 notes = sn_none;
1285 in_path = true;
1286 }
1287 for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1288 fixed v;
1289 int b = *cbp;
1290
1291 switch (b >> 5) {
1292 case 0:
1293 case 1:
1294 vs[i++] =
1295 ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1296 ((int)cbp[1] << 5) + (cbp[2] >> 3);
1297 if_debug1('L', " %g", fixed2float(vs[i - 1]));
1298 cbp += 2;
1299 v = (int)((*cbp & 7) ^ 4) - 4;
1300 break;
1301 case 2:
1302 case 3:
1303 v = (b ^ 0x60) - 0x20;
1304 break;
1305 case 4:
1306 case 5:
1307 /*
1308 * Without the following cast, C's
1309 * brain-damaged coercion rules cause the
1310 * result to be considered unsigned, and not
1311 * sign-extended on machines where
1312 * sizeof(long) > sizeof(int).
1313 */
1314 v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
1315 break;
1316 case 6:
1317 v = (b ^ 0xd0) - 0x10;
1318 vs[i] =
1319 ((v << 8) + cbp[1]) << (_fixed_shift - 2);
1320 if_debug1('L', " %g", fixed2float(vs[i]));
1321 cbp += 2;
1322 continue;
1323 default /*case 7 */ :
1324 v = (int)(*++cbp ^ 0x80) - 0x80;
1325 for (b = 0; b < sizeof(fixed) - 3; ++b)
1326 v = (v << 8) + *++cbp;
1327 break;
1328 }
1329 cbp += 3;
1330 /* Absent the cast in the next statement, */
1331 /* the Borland C++ 4.5 compiler incorrectly */
1332 /* sign-extends the result of the shift. */
1333 vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
1334 if_debug1('L', " %g", fixed2float(vs[i]));
1335 }
1336 if_debug0('L', "\n");
1337 code = clist_decode_segment(&path, op, vs, &ppos,
1338 x0, y0, notes);
1339 if (code < 0)
1340 goto out;
1341 }
1342 continue;
1343 case cmd_op_path >> 4:
1344 {
1345 gx_path fpath;
1346 gx_path * ppath = &path;
1347
1348 if_debug0('L', "\n");
1349 /* if in clip, flatten path first */
1350 if (in_clip) {
1351 gx_path_init_local(&fpath, mem);
1352 code = gx_path_add_flattened_accurate(&path, &fpath,
1353 gs_currentflat_inline(&imager_state),
1354 imager_state.accurate_curves);
1355 if (code < 0)
1356 goto out;
1357 ppath = &fpath;
1358 }
1359 switch (op) {
1360 case cmd_opv_fill:
1361 fill_params.rule = gx_rule_winding_number;
1362 goto fill;
1363 case cmd_opv_eofill:
1364 fill_params.rule = gx_rule_even_odd;
1365 fill:
1366 fill_params.adjust = imager_state.fill_adjust;
1367 fill_params.flatness = imager_state.flatness;
1368 fill_params.fill_zero_width =
1369 fill_params.adjust.x != 0 ||
1370 fill_params.adjust.y != 0;
1371 code = gx_fill_path_only(ppath, tdev,
1372 &imager_state,
1373 &fill_params,
1374 &dev_color, pcpath);
1375 break;
1376 case cmd_opv_stroke:
1377 stroke_params.flatness = imager_state.flatness;
1378 code = gx_stroke_path_only(ppath,
1379 (gx_path *) 0, tdev,
1380 &imager_state, &stroke_params,
1381 &dev_color, pcpath);
1382 break;
1383 case cmd_opv_polyfill:
1384 code = clist_do_polyfill(tdev, ppath, &dev_color,
1385 imager_state.log_op);
1386 break;
1387 default:
1388 goto bad_op;
1389 }
1390 if (ppath != &path)
1391 gx_path_free(ppath, "clist_render_band");
1392 }
1393 if (in_path) { /* path might be empty! */
1394 state.rect.x = fixed2int_var(ppos.x);
1395 state.rect.y = fixed2int_var(ppos.y);
1396 in_path = false;
1397 }
1398 gx_path_free(&path, "clist_render_band");
1399 gx_path_init_local(&path, mem);
1400 if (code < 0)
1401 goto out;
1402 continue;
1403 default:
1404 bad_op:lprintf5("Bad op %02x band y0 = %d file pos %ld buf pos %d/%d\n",
1405 op, y0, stell(s), (int)(cbp - cbuf.data), (int)(cbuf.end - cbuf.data));
1406 {
1407 const byte *pp;
1408
1409 for (pp = cbuf.data; pp < cbuf.end; pp += 10) {
1410 dlprintf1("%4d:", (int)(pp - cbuf.data));
1411 dprintf10(" %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
1412 pp[0], pp[1], pp[2], pp[3], pp[4],
1413 pp[5], pp[6], pp[7], pp[8], pp[9]);
1414 }
1415 }
1416 code = gs_note_error(gs_error_Fatal);
1417 goto out;
1418 }
1419 if_debug4('L', " x=%d y=%d w=%d h=%d\n",
1420 state.rect.x, state.rect.y, state.rect.width,
1421 state.rect.height);
1422 switch (op >> 4) {
1423 case cmd_op_fill_rect >> 4:
1424 case cmd_op_fill_rect_short >> 4:
1425 case cmd_op_fill_rect_tiny >> 4:
1426 if (!state.lop_enabled) {
1427 code = (*dev_proc(tdev, fill_rectangle))
1428 (tdev, state.rect.x - x0, state.rect.y - y0,
1429 state.rect.width, state.rect.height,
1430 state.colors[1]);
1431 break;
1432 }
1433 source = NULL;
1434 data_x = 0;
1435 raster = 0;
1436 colors[0] = colors[1] = state.colors[1];
1437 log_op = state.lop;
1438 pcolor = colors;
1439 do_rop:code = (*dev_proc(tdev, strip_copy_rop))
1440 (tdev, source, data_x, raster, gx_no_bitmap_id,
1441 pcolor, &state_tile,
1442 (state.tile_colors[0] == gx_no_color_index &&
1443 state.tile_colors[1] == gx_no_color_index ?
1444 NULL : state.tile_colors),
1445 state.rect.x - x0, state.rect.y - y0,
1446 state.rect.width - data_x, state.rect.height,
1447 tile_phase.x, tile_phase.y, log_op);
1448 data_x = 0;
1449 break;
1450 case cmd_op_tile_rect >> 4:
1451 case cmd_op_tile_rect_short >> 4:
1452 case cmd_op_tile_rect_tiny >> 4:
1453 /* Currently we don't use lop with tile_rectangle. */
1454 code = (*dev_proc(tdev, strip_tile_rectangle))
1455 (tdev, &state_tile,
1456 state.rect.x - x0, state.rect.y - y0,
1457 state.rect.width, state.rect.height,
1458 state.tile_colors[0], state.tile_colors[1],
1459 tile_phase.x, tile_phase.y);
1460 break;
1461 case cmd_op_copy_mono >> 4:
1462 if (state.lop_enabled) {
1463 pcolor = state.colors;
1464 log_op = state.lop;
1465 goto do_rop;
1466 }
1467 if ((op & cmd_copy_use_tile) || pcpath != NULL) { /*
1468 * This call of copy_mono originated as a call
1469 * of fill_mask.
1470 */
1471 code = (*dev_proc(tdev, fill_mask))
1472 (tdev, source, data_x, raster, gx_no_bitmap_id,
1473 state.rect.x - x0, state.rect.y - y0,
1474 state.rect.width - data_x, state.rect.height,
1475 &dev_color, 1, imager_state.log_op, pcpath);
1476 } else
1477 code = (*dev_proc(tdev, copy_mono))
1478 (tdev, source, data_x, raster, gx_no_bitmap_id,
1479 state.rect.x - x0, state.rect.y - y0,
1480 state.rect.width - data_x, state.rect.height,
1481 state.colors[0], state.colors[1]);
1482 data_x = 0;
1483 break;
1484 case cmd_op_copy_color_alpha >> 4:
1485 if (state.color_is_alpha) {
1486 /****** CAN'T DO ROP WITH ALPHA ******/
1487 code = (*dev_proc(tdev, copy_alpha))
1488 (tdev, source, data_x, raster, gx_no_bitmap_id,
1489 state.rect.x - x0, state.rect.y - y0,
1490 state.rect.width - data_x, state.rect.height,
1491 state.colors[1], depth);
1492 } else {
1493 if (state.lop_enabled) {
1494 pcolor = NULL;
1495 log_op = state.lop;
1496 goto do_rop;
1497 }
1498 code = (*dev_proc(tdev, copy_color))
1499 (tdev, source, data_x, raster, gx_no_bitmap_id,
1500 state.rect.x - x0, state.rect.y - y0,
1501 state.rect.width - data_x, state.rect.height);
1502 }
1503 data_x = 0;
1504 break;
1505 default: /* can't happen */
1506 goto bad_op;
1507 }
1508 }
1509 /* Clean up before we exit. */
1510 out:
1511 if (ht_buff.pbuff != 0) {
1512 gs_free_object(mem, ht_buff.pbuff, "clist_playback_band(ht_buff)");
1513 ht_buff.pbuff = 0;
1514 ht_buff.pcurr = 0;
1515 }
1516 ht_buff.ht_size = 0;
1517 ht_buff.read_size = 0;
1518
1519 if (color_space.params.indexed.lookup.table.size)
1520 gs_free_const_string(mem,
1521 color_space.params.indexed.lookup.table.data,
1522 color_space.params.indexed.lookup.table.size,
1523 "color_space indexed table");
1524 gx_cpath_free(&clip_path, "clist_render_band exit");
1525 gx_path_free(&path, "clist_render_band exit");
1526 gs_imager_state_release(&imager_state);
1527 gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
1528 if (target != orig_target) {
1529 dev_proc(target, close_device)(target);
1530 gs_free_object(target->memory, target, "gxclrast discard compositor");
1531 target = orig_target;
1532 }
1533 if (code < 0)
1534 return_error(code);
1535 /* Check whether we have more pages to process. */
1536 if (playback_action != playback_action_setup &&
1537 (cbp < cbuf.end || !seofp(s))
1538 )
1539 goto in;
1540 return code;
1541 }
1542
1543 /* ---------------- Individual commands ---------------- */
1544
1545 /*
1546 * These single-use procedures implement a few large individual commands,
1547 * primarily for readability but also to avoid overflowing compilers'
1548 * optimization limits. They all take the command buffer as their first
1549 * parameter (pcb), assume that the current buffer pointer is in pcb->ptr,
1550 * and update it there.
1551 */
1552
1553 private int
read_set_tile_size(command_buf_t * pcb,tile_slot * bits)1554 read_set_tile_size(command_buf_t *pcb, tile_slot *bits)
1555 {
1556 const byte *cbp = pcb->ptr;
1557 uint rep_width, rep_height;
1558 byte bd = *cbp++;
1559
1560 bits->cb_depth = cmd_code_to_depth(bd);
1561 cmd_getw(rep_width, cbp);
1562 cmd_getw(rep_height, cbp);
1563 if (bd & 0x20) {
1564 cmd_getw(bits->x_reps, cbp);
1565 bits->width = rep_width * bits->x_reps;
1566 } else {
1567 bits->x_reps = 1;
1568 bits->width = rep_width;
1569 }
1570 if (bd & 0x40) {
1571 cmd_getw(bits->y_reps, cbp);
1572 bits->height = rep_height * bits->y_reps;
1573 } else {
1574 bits->y_reps = 1;
1575 bits->height = rep_height;
1576 }
1577 if (bd & 0x80)
1578 cmd_getw(bits->rep_shift, cbp);
1579 else
1580 bits->rep_shift = 0;
1581 if_debug6('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d\n",
1582 bits->cb_depth, bits->width,
1583 bits->height, rep_width,
1584 rep_height, bits->rep_shift);
1585 bits->shift =
1586 (bits->rep_shift == 0 ? 0 :
1587 (bits->rep_shift * (bits->height / rep_height)) % rep_width);
1588 bits->cb_raster = bitmap_raster(bits->width * bits->cb_depth);
1589 pcb->ptr = cbp;
1590 return 0;
1591 }
1592
1593 private int
read_set_bits(command_buf_t * pcb,tile_slot * bits,int compress,gx_clist_state * pcls,gx_strip_bitmap * tile,tile_slot ** pslot,gx_device_clist_reader * cdev,gs_memory_t * mem)1594 read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
1595 gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot,
1596 gx_device_clist_reader *cdev, gs_memory_t *mem)
1597 {
1598 const byte *cbp = pcb->ptr;
1599 uint rep_width = bits->width / bits->x_reps;
1600 uint rep_height = bits->height / bits->y_reps;
1601 uint index;
1602 ulong offset;
1603 uint width_bits = rep_width * bits->cb_depth;
1604 uint width_bytes;
1605 uint raster;
1606 uint bytes =
1607 clist_bitmap_bytes(width_bits, rep_height,
1608 compress |
1609 (rep_width < bits->width ?
1610 decompress_spread : 0) |
1611 decompress_elsewhere,
1612 &width_bytes,
1613 (uint *)&raster);
1614 byte *data;
1615 tile_slot *slot;
1616
1617 cmd_getw(index, cbp);
1618 cmd_getw(offset, cbp);
1619 if_debug2('L', " index=%d offset=%lu\n", pcls->tile_index, offset);
1620 pcls->tile_index = index;
1621 cdev->tile_table[pcls->tile_index].offset = offset;
1622 slot = (tile_slot *)(cdev->chunk.data + offset);
1623 *pslot = slot;
1624 *slot = *bits;
1625 tile->data = data = (byte *)(slot + 1);
1626 #ifdef DEBUG
1627 slot->index = pcls->tile_index;
1628 #endif
1629 if (compress) {
1630 /*
1631 * Decompress the image data. We'd like to share this code with the
1632 * similar code in copy_*, but right now we don't see how.
1633 */
1634 stream_cursor_read r;
1635 stream_cursor_write w;
1636 /*
1637 * We don't know the data length a priori, so to be conservative, we
1638 * read the uncompressed size.
1639 */
1640 uint cleft = pcb->end - cbp;
1641
1642 if (cleft < bytes) {
1643 uint nread = cbuf_size - cleft;
1644
1645 memmove(pcb->data, cbp, cleft);
1646 pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
1647 set_cb_end(pcb, pcb->data + cleft + nread);
1648 cbp = pcb->data;
1649 }
1650 r.ptr = cbp - 1;
1651 r.limit = pcb->end - 1;
1652 w.ptr = data - 1;
1653 w.limit = w.ptr + bytes;
1654 switch (compress) {
1655 case cmd_compress_rle:
1656 {
1657 stream_RLD_state sstate;
1658
1659 clist_rld_init(&sstate);
1660 (*s_RLD_template.process)
1661 ((stream_state *)&sstate, &r, &w, true);
1662 }
1663 break;
1664 case cmd_compress_cfe:
1665 {
1666 stream_CFD_state sstate;
1667
1668 clist_cfd_init(&sstate,
1669 width_bytes << 3 /*width_bits */ ,
1670 rep_height, mem);
1671 (*s_CFD_template.process)
1672 ((stream_state *)&sstate, &r, &w, true);
1673 (*s_CFD_template.release)
1674 ((stream_state *)&sstate);
1675 }
1676 break;
1677 default:
1678 return_error(gs_error_unregistered);
1679 }
1680 cbp = r.ptr + 1;
1681 } else if (rep_height > 1 && width_bytes != bits->cb_raster) {
1682 cbp = cmd_read_short_bits(pcb, data,
1683 width_bytes, rep_height,
1684 bits->cb_raster, cbp);
1685 } else {
1686 cbp = cmd_read_data(pcb, data, bytes, cbp);
1687 }
1688 if (bits->width > rep_width)
1689 bits_replicate_horizontally(data,
1690 rep_width * bits->cb_depth, rep_height,
1691 bits->cb_raster,
1692 bits->width * bits->cb_depth,
1693 bits->cb_raster);
1694 if (bits->height > rep_height)
1695 bits_replicate_vertically(data,
1696 rep_height, bits->cb_raster,
1697 bits->height);
1698 #ifdef DEBUG
1699 if (gs_debug_c('L'))
1700 cmd_print_bits(data, bits->width, bits->height, bits->cb_raster);
1701 #endif
1702 pcb->ptr = cbp;
1703 return 0;
1704 }
1705
1706 /* if necessary, allocate a buffer to hold a serialized halftone */
1707 private int
read_alloc_ht_buff(ht_buff_t * pht_buff,uint ht_size,gs_memory_t * mem)1708 read_alloc_ht_buff(ht_buff_t * pht_buff, uint ht_size, gs_memory_t * mem)
1709 {
1710 /* free the existing buffer, if any (usually none) */
1711 if (pht_buff->pbuff != 0) {
1712 gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
1713 pht_buff->pbuff = 0;
1714 }
1715
1716 /*
1717 * If the serialized halftone fits in the command buffer, no
1718 * additional buffer is required.
1719 */
1720 if (ht_size > cbuf_ht_seg_max_size) {
1721 pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
1722 if (pht_buff->pbuff == 0)
1723 return_error(gs_error_VMerror);
1724 }
1725 pht_buff->ht_size = ht_size;
1726 pht_buff->read_size = 0;
1727 pht_buff->pcurr = pht_buff->pbuff;
1728 return 0;
1729 }
1730
1731 /* read a halftone segment; if it is the final segment, build the halftone */
1732 private int
read_ht_segment(ht_buff_t * pht_buff,command_buf_t * pcb,gs_imager_state * pis,gx_device * dev,gs_memory_t * mem)1733 read_ht_segment(
1734 ht_buff_t * pht_buff,
1735 command_buf_t * pcb,
1736 gs_imager_state * pis,
1737 gx_device * dev,
1738 gs_memory_t * mem )
1739 {
1740 const byte * cbp = pcb->ptr;
1741 const byte * pbuff = 0;
1742 uint ht_size = pht_buff->ht_size, seg_size;
1743 int code = 0;
1744
1745 /* get the segment size; refill command buffer if necessary */
1746 enc_u_getw(seg_size, cbp);
1747 if (cbp + seg_size > pcb->limit)
1748 cbp = top_up_cbuf(pcb, cbp);
1749
1750 if (pht_buff->pbuff == 0) {
1751 /* if not separate buffer, must be only one segment */
1752 if (seg_size != ht_size)
1753 return_error(gs_error_unknownerror);
1754 pbuff = cbp;
1755 } else {
1756 if (seg_size + pht_buff->read_size > pht_buff->ht_size)
1757 return_error(gs_error_unknownerror);
1758 memcpy(pht_buff->pcurr, cbp, seg_size);
1759 pht_buff->pcurr += seg_size;
1760 if ((pht_buff->read_size += seg_size) == ht_size)
1761 pbuff = pht_buff->pbuff;
1762 }
1763
1764 /* if everything has be read, covert back to a halftone */
1765 if (pbuff != 0) {
1766 code = gx_ht_read_and_install(pis, dev, pbuff, ht_size, mem);
1767
1768 /* release any buffered information */
1769 if (pht_buff->pbuff != 0) {
1770 gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
1771 pht_buff->pbuff = 0;
1772 pht_buff->pcurr = 0;
1773 }
1774 pht_buff->ht_size = 0;
1775 pht_buff->read_size = 0;
1776 }
1777
1778 /* update the command buffer ponter */
1779 pcb->ptr = cbp + seg_size;
1780
1781 return code;
1782 }
1783
1784
1785 private int
read_set_misc2(command_buf_t * pcb,gs_imager_state * pis,segment_notes * pnotes)1786 read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, segment_notes *pnotes)
1787 {
1788 const byte *cbp = pcb->ptr;
1789 uint mask, cb;
1790
1791 cmd_getw(mask, cbp);
1792 if (mask & cap_join_known) {
1793 cb = *cbp++;
1794 pis->line_params.cap = (gs_line_cap)((cb >> 3) & 7);
1795 pis->line_params.join = (gs_line_join)(cb & 7);
1796 if_debug2('L', " cap=%d join=%d\n",
1797 pis->line_params.cap, pis->line_params.join);
1798 }
1799 if (mask & cj_ac_sa_known) {
1800 cb = *cbp++;
1801 pis->line_params.curve_join = ((cb >> 2) & 7) - 1;
1802 pis->accurate_curves = (cb & 2) != 0;
1803 pis->stroke_adjust = cb & 1;
1804 if_debug3('L', " CJ=%d AC=%d SA=%d\n",
1805 pis->line_params.curve_join, pis->accurate_curves,
1806 pis->stroke_adjust);
1807 }
1808 if (mask & flatness_known) {
1809 cmd_get_value(pis->flatness, cbp);
1810 if_debug1('L', " flatness=%g\n", pis->flatness);
1811 }
1812 if (mask & line_width_known) {
1813 float width;
1814
1815 cmd_get_value(width, cbp);
1816 if_debug1('L', " line_width=%g\n", width);
1817 gx_set_line_width(&pis->line_params, width);
1818 }
1819 if (mask & miter_limit_known) {
1820 float limit;
1821
1822 cmd_get_value(limit, cbp);
1823 if_debug1('L', " miter_limit=%g\n", limit);
1824 gx_set_miter_limit(&pis->line_params, limit);
1825 }
1826 if (mask & op_bm_tk_known) {
1827 cb = *cbp++;
1828 pis->blend_mode = cb >> 3;
1829 pis->text_knockout = (cb & 4) != 0;
1830 /* the following usually have no effect; see gxclpath.c */
1831 pis->overprint_mode = (cb >> 1) & 1;
1832 pis->effective_overprint_mode = pis->overprint_mode;
1833 pis->overprint = cb & 1;
1834 if_debug4('L', " BM=%d TK=%d OPM=%d OP=%d\n",
1835 pis->blend_mode, pis->text_knockout, pis->overprint_mode,
1836 pis->overprint);
1837 }
1838 if (mask & segment_notes_known) {
1839 cb = *cbp++;
1840 *pnotes = (segment_notes)(cb & 0x3f);
1841 if_debug1('L', " notes=%d\n", *pnotes);
1842 }
1843 if (mask & opacity_alpha_known) {
1844 cmd_get_value(pis->opacity.alpha, cbp);
1845 if_debug1('L', " opacity.alpha=%g\n", pis->opacity.alpha);
1846 }
1847 if (mask & shape_alpha_known) {
1848 cmd_get_value(pis->shape.alpha, cbp);
1849 if_debug1('L', " shape.alpha=%g\n", pis->shape.alpha);
1850 }
1851 if (mask & alpha_known) {
1852 cmd_get_value(pis->alpha, cbp);
1853 if_debug1('L', " alpha=%u\n", pis->alpha);
1854 }
1855 pcb->ptr = cbp;
1856 return 0;
1857 }
1858
1859 private int
read_set_color_space(command_buf_t * pcb,gs_imager_state * pis,const gs_color_space ** ppcs,gs_color_space * pcolor_space,gs_memory_t * mem)1860 read_set_color_space(command_buf_t *pcb, gs_imager_state *pis,
1861 const gs_color_space **ppcs, gs_color_space *pcolor_space,
1862 gs_memory_t *mem)
1863 {
1864 const byte *cbp = pcb->ptr;
1865 byte b = *cbp++;
1866 int index = b >> 4;
1867 const gs_color_space *pcs;
1868 int code = 0;
1869
1870 /*
1871 * The following are used only for a single, parameterless color space,
1872 * so they do not introduce any re-entrancy problems.
1873 */
1874 static gs_color_space gray_cs, rgb_cs, cmyk_cs;
1875
1876 if_debug3('L', " %d%s%s\n", index,
1877 (b & 8 ? " (indexed)" : ""),
1878 (b & 4 ? "(proc)" : ""));
1879 switch (index) {
1880 case gs_color_space_index_DeviceGray:
1881 gs_cspace_init_DeviceGray(mem, &gray_cs);
1882 pcs = &gray_cs;
1883 break;
1884 case gs_color_space_index_DeviceRGB:
1885 gs_cspace_init_DeviceRGB(mem, &rgb_cs);
1886 pcs = &rgb_cs;
1887 break;
1888 case gs_color_space_index_DeviceCMYK:
1889 gs_cspace_init_DeviceCMYK(mem, &cmyk_cs);
1890 pcs = &cmyk_cs;
1891 break;
1892 default:
1893 code = gs_note_error(gs_error_rangecheck); /* others are NYI */
1894 goto out;
1895 }
1896
1897 /* Free any old indexed color space data. */
1898 if (pcolor_space->params.indexed.use_proc) {
1899 if (pcolor_space->params.indexed.lookup.map)
1900 gs_free_object(mem,
1901 pcolor_space->params.indexed.lookup.map->values,
1902 "old indexed map values");
1903 gs_free_object(mem, pcolor_space->params.indexed.lookup.map,
1904 "old indexed map");
1905 pcolor_space->params.indexed.lookup.map = 0;
1906 } else {
1907 if (pcolor_space->params.indexed.lookup.table.size)
1908 gs_free_const_string(mem,
1909 pcolor_space->params.indexed.lookup.table.data,
1910 pcolor_space->params.indexed.lookup.table.size,
1911 "color_spapce indexed table");
1912 pcolor_space->params.indexed.lookup.table.size = 0;
1913 }
1914 if (b & 8) {
1915 bool use_proc = (b & 4) != 0;
1916 int hival;
1917 int num_values;
1918 byte *data;
1919 uint data_size;
1920
1921 cmd_getw(hival, cbp);
1922 num_values = (hival + 1) * gs_color_space_num_components(pcs);
1923 if (use_proc) {
1924 gs_indexed_map *map;
1925
1926 code = alloc_indexed_map(&map, num_values, mem, "indexed map");
1927 if (code < 0)
1928 goto out;
1929 map->proc.lookup_index = lookup_indexed_map;
1930 pcolor_space->params.indexed.lookup.map = map;
1931 data = (byte *)map->values;
1932 data_size = num_values * sizeof(map->values[0]);
1933 } else {
1934 byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
1935
1936 if (table == 0) {
1937 code = gs_note_error(gs_error_VMerror);
1938 goto out;
1939 }
1940 pcolor_space->params.indexed.lookup.table.data = table;
1941 pcolor_space->params.indexed.lookup.table.size = num_values;
1942 data = table;
1943 data_size = num_values;
1944 }
1945 cbp = cmd_read_data(pcb, data, data_size, cbp);
1946 pcolor_space->type =
1947 &gs_color_space_type_Indexed;
1948 memmove(&pcolor_space->params.indexed.base_space, pcs,
1949 sizeof(pcolor_space->params.indexed.base_space));
1950 pcolor_space->params.indexed.hival = hival;
1951 pcolor_space->params.indexed.use_proc = use_proc;
1952 pcs = pcolor_space;
1953 }
1954 *ppcs = pcs;
1955 out:
1956 pcb->ptr = cbp;
1957 return code;
1958 }
1959
1960 private int
read_begin_image(command_buf_t * pcb,gs_image_common_t * pic,const gs_color_space * pcs)1961 read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
1962 const gs_color_space *pcs)
1963 {
1964 uint index = *(pcb->ptr)++;
1965 const gx_image_type_t *image_type = gx_image_type_table[index];
1966 stream s;
1967 int code;
1968
1969 /* This is sloppy, but we don't have enough information to do better. */
1970 pcb->ptr = top_up_cbuf(pcb, pcb->ptr);
1971 s_init(&s, NULL);
1972 sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
1973 code = image_type->sget(pic, &s, pcs);
1974 pcb->ptr = sbufptr(&s);
1975 return code;
1976 }
1977
1978 private int
read_put_params(command_buf_t * pcb,gs_imager_state * pis,gx_device_clist_reader * cdev,gs_memory_t * mem)1979 read_put_params(command_buf_t *pcb, gs_imager_state *pis,
1980 gx_device_clist_reader *cdev, gs_memory_t *mem)
1981 {
1982 const byte *cbp = pcb->ptr;
1983 gs_c_param_list param_list;
1984 uint cleft;
1985 uint rleft;
1986 bool alloc_data_on_heap = false;
1987 byte *param_buf;
1988 uint param_length;
1989 int code = 0;
1990
1991 cmd_get_value(param_length, cbp);
1992 if_debug1('L', " length=%d\n", param_length);
1993 if (param_length == 0) {
1994 code = 1; /* empty list */
1995 goto out;
1996 }
1997
1998 /* Make sure entire serialized param list is in cbuf */
1999 /* + force void* alignment */
2000 cbp = top_up_cbuf(pcb, cbp);
2001 if (pcb->end - cbp >= param_length) {
2002 param_buf = (byte *)cbp;
2003 cbp += param_length;
2004 } else {
2005 /* NOTE: param_buf must be maximally aligned */
2006 param_buf = gs_alloc_bytes(mem, param_length,
2007 "clist put_params");
2008 if (param_buf == 0) {
2009 code = gs_note_error(gs_error_VMerror);
2010 goto out;
2011 }
2012 alloc_data_on_heap = true;
2013 cleft = pcb->end - cbp;
2014 rleft = param_length - cleft;
2015 memmove(param_buf, cbp, cleft);
2016 pcb->end_status = sgets(pcb->s, param_buf + cleft, rleft, &rleft);
2017 cbp = pcb->end; /* force refill */
2018 }
2019
2020 /*
2021 * Create a gs_c_param_list & expand into it.
2022 * NB that gs_c_param_list doesn't copy objects into
2023 * it, but rather keeps *pointers* to what's passed.
2024 * That's OK because the serialized format keeps enough
2025 * space to hold expanded versions of the structures,
2026 * but this means we cannot deallocate source buffer
2027 * until the gs_c_param_list is deleted.
2028 */
2029 gs_c_param_list_write(¶m_list, mem);
2030 code = gs_param_list_unserialize
2031 ( (gs_param_list *)¶m_list, param_buf );
2032 if (code >= 0 && code != param_length)
2033 code = gs_error_unknownerror; /* must match */
2034 if (code >= 0) {
2035 gs_c_param_list_read(¶m_list);
2036 code = gs_imager_putdeviceparams(pis, (gx_device *)cdev,
2037 (gs_param_list *)¶m_list);
2038 }
2039 gs_c_param_list_release(¶m_list);
2040 if (alloc_data_on_heap)
2041 gs_free_object(mem, param_buf, "clist put_params");
2042
2043 out:
2044 pcb->ptr = cbp;
2045 return code;
2046 }
2047
2048 /*
2049 * Read a "create_compositor" command, and execute the command.
2050 *
2051 * This code assumes that a the largest create compositor command,
2052 * including the compositor name size, is smaller than the data buffer
2053 * size. This assumption is inherent in the basic design of the coding
2054 * and the de-serializer interface, as no length field is provided.
2055 * At the time of this writing, no compositor comes remotely close to
2056 * violating this assumption (largest create_compositor is about 16
2057 * bytes, while the command data buffer is 800 bytes), nor is any likely
2058 * to do so in the future. In the unlikely event that this assumption
2059 * is violated, a change in the encoding would be called for).
2060 */
2061 extern_gs_find_compositor();
2062
2063 private int
read_create_compositor(command_buf_t * pcb,gs_imager_state * pis,gx_device_clist_reader * cdev,gs_memory_t * mem,gx_device ** ptarget)2064 read_create_compositor(
2065 command_buf_t * pcb,
2066 gs_imager_state * pis,
2067 gx_device_clist_reader * cdev,
2068 gs_memory_t * mem,
2069 gx_device ** ptarget )
2070 {
2071 const byte * cbp = pcb->ptr;
2072 int comp_id = 0, code = 0;
2073 const gs_composite_type_t * pcomp_type = 0;
2074 gs_composite_t * pcomp;
2075 gx_device * tdev = *ptarget;
2076
2077 /* fill the command buffer (see comment above) */
2078 cbp = top_up_cbuf(pcb, cbp);
2079
2080 /* find the appropriate compositor method vector */
2081 comp_id = *cbp++;
2082 if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
2083 return_error(gs_error_unknownerror);
2084
2085 /* de-serialize the compositor */
2086 code = pcomp_type->procs.read(&pcomp, cbp, pcb->end - cbp, mem);
2087 if (code > 0)
2088 cbp += code;
2089 pcb->ptr = cbp;
2090 if (code < 0 || pcomp == 0)
2091 return code;
2092
2093 /*
2094 * Apply the compositor to the target device; note that this may
2095 * change the target device.
2096 */
2097 code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pis, mem);
2098 if (code >= 0 && tdev != *ptarget) {
2099 rc_increment(tdev);
2100 *ptarget = tdev;
2101 }
2102
2103 /* Perform any updates for the clist device required */
2104 code = pcomp->type->procs.clist_compositor_read_update(pcomp,
2105 (gx_device *)cdev, tdev, pis, mem);
2106 if (code < 0)
2107 return code;
2108
2109 /* free the compositor object */
2110 if (pcomp != 0)
2111 gs_free_object(mem, pcomp, "read_create_compositor");
2112
2113 return code;
2114 }
2115
2116 /* ---------------- Utilities ---------------- */
2117
2118 /* Read and unpack a short bitmap */
2119 private const byte *
cmd_read_short_bits(command_buf_t * pcb,byte * data,int width_bytes,int height,uint raster,const byte * cbp)2120 cmd_read_short_bits(command_buf_t *pcb, byte *data, int width_bytes,
2121 int height, uint raster, const byte *cbp)
2122 {
2123 uint bytes = width_bytes * height;
2124 const byte *pdata = data /*src*/ + bytes;
2125 byte *udata = data /*dest*/ + height * raster;
2126
2127 cbp = cmd_read_data(pcb, data, width_bytes * height, cbp);
2128 while (--height >= 0) {
2129 udata -= raster, pdata -= width_bytes;
2130 switch (width_bytes) {
2131 default:
2132 memmove(udata, pdata, width_bytes);
2133 break;
2134 case 6:
2135 udata[5] = pdata[5];
2136 case 5:
2137 udata[4] = pdata[4];
2138 case 4:
2139 udata[3] = pdata[3];
2140 case 3:
2141 udata[2] = pdata[2];
2142 case 2:
2143 udata[1] = pdata[1];
2144 case 1:
2145 udata[0] = pdata[0];
2146 case 0:; /* shouldn't happen */
2147 }
2148 }
2149 return cbp;
2150 }
2151
2152 /* Read a rectangle. */
2153 private const byte *
cmd_read_rect(int op,gx_cmd_rect * prect,const byte * cbp)2154 cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
2155 {
2156 cmd_getw(prect->x, cbp);
2157 if (op & 0xf)
2158 prect->y += ((op >> 2) & 3) - 2;
2159 else {
2160 cmd_getw(prect->y, cbp);
2161 }
2162 cmd_getw(prect->width, cbp);
2163 if (op & 0xf)
2164 prect->height += (op & 3) - 2;
2165 else {
2166 cmd_getw(prect->height, cbp);
2167 }
2168 return cbp;
2169 }
2170
2171 /* Read a transformation matrix. */
2172 private const byte *
cmd_read_matrix(gs_matrix * pmat,const byte * cbp)2173 cmd_read_matrix(gs_matrix * pmat, const byte * cbp)
2174 {
2175 stream s;
2176
2177 s_init(&s, NULL);
2178 sread_string(&s, cbp, 1 + sizeof(*pmat));
2179 sget_matrix(&s, pmat);
2180 return cbp + stell(&s);
2181 }
2182
2183 /*
2184 * Select a map for loading with data.
2185 *
2186 * This routine has three outputs:
2187 * *pmdata - points to the map data.
2188 * *pcomp_num - points to a component number if the map is a transfer
2189 * map which has been set via the setcolortransfer operator.
2190 * A. value of NULL indicates that no component number is to
2191 * be sent for this map.
2192 * *pcount - the size of the map (in bytes).
2193 */
2194 private int
cmd_select_map(cmd_map_index map_index,cmd_map_contents cont,gs_imager_state * pis,int ** pcomp_num,frac ** pmdata,uint * pcount,gs_memory_t * mem)2195 cmd_select_map(cmd_map_index map_index, cmd_map_contents cont,
2196 gs_imager_state * pis, int ** pcomp_num, frac ** pmdata,
2197 uint * pcount, gs_memory_t * mem)
2198 {
2199 gx_transfer_map *map;
2200 gx_transfer_map **pmap;
2201 const char *cname;
2202
2203 *pcomp_num = NULL; /* Only used for color transfer maps */
2204 switch (map_index) {
2205 case cmd_map_transfer:
2206 if_debug0('L', " transfer");
2207 rc_unshare_struct(pis->set_transfer.gray, gx_transfer_map,
2208 &st_transfer_map, mem, return_error(gs_error_VMerror),
2209 "cmd_select_map(default_transfer)");
2210 map = pis->set_transfer.gray;
2211 /* Release all current maps */
2212 rc_decrement(pis->set_transfer.red, "cmd_select_map(red)");
2213 pis->set_transfer.red = NULL;
2214 pis->set_transfer.red_component_num = -1;
2215 rc_decrement(pis->set_transfer.green, "cmd_select_map(green)");
2216 pis->set_transfer.green = NULL;
2217 pis->set_transfer.green_component_num = -1;
2218 rc_decrement(pis->set_transfer.blue, "cmd_select_map(blue)");
2219 pis->set_transfer.blue = NULL;
2220 pis->set_transfer.blue_component_num = -1;
2221 goto transfer2;
2222 case cmd_map_transfer_0:
2223 pmap = &pis->set_transfer.red;
2224 *pcomp_num = &pis->set_transfer.red_component_num;
2225 goto transfer1;
2226 case cmd_map_transfer_1:
2227 pmap = &pis->set_transfer.green;
2228 *pcomp_num = &pis->set_transfer.green_component_num;
2229 goto transfer1;
2230 case cmd_map_transfer_2:
2231 pmap = &pis->set_transfer.blue;
2232 *pcomp_num = &pis->set_transfer.blue_component_num;
2233 goto transfer1;
2234 case cmd_map_transfer_3:
2235 pmap = &pis->set_transfer.gray;
2236 *pcomp_num = &pis->set_transfer.gray_component_num;
2237 transfer1: {
2238 int i = map_index - cmd_map_transfer_0;
2239
2240 if_debug1('L', " transfer[%d]", i);
2241 }
2242 rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
2243 return_error(gs_error_VMerror), "cmd_select_map(transfer)");
2244 map = *pmap;
2245
2246 transfer2: if (cont != cmd_map_other) {
2247 gx_set_identity_transfer(map);
2248 *pmdata = 0;
2249 *pcount = 0;
2250 return 0;
2251 }
2252 break;
2253 case cmd_map_black_generation:
2254 if_debug0('L', " black generation");
2255 pmap = &pis->black_generation;
2256 cname = "cmd_select_map(black generation)";
2257 goto alloc;
2258 case cmd_map_undercolor_removal:
2259 if_debug0('L', " undercolor removal");
2260 pmap = &pis->undercolor_removal;
2261 cname = "cmd_select_map(undercolor removal)";
2262 alloc: if (cont == cmd_map_none) {
2263 rc_decrement(*pmap, cname);
2264 *pmap = 0;
2265 *pmdata = 0;
2266 *pcount = 0;
2267 return 0;
2268 }
2269 rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
2270 mem, return_error(gs_error_VMerror), cname);
2271 map = *pmap;
2272 if (cont == cmd_map_identity) {
2273 gx_set_identity_transfer(map);
2274 *pmdata = 0;
2275 *pcount = 0;
2276 return 0;
2277 }
2278 break;
2279 default:
2280 *pmdata = 0;
2281 return 0;
2282 }
2283 map->proc = gs_mapped_transfer;
2284 *pmdata = map->values;
2285 *pcount = sizeof(map->values);
2286 return 0;
2287 }
2288
2289 /* Create a device halftone for the imager if necessary. */
2290 private int
cmd_create_dev_ht(gx_device_halftone ** ppdht,gs_memory_t * mem)2291 cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
2292 {
2293 gx_device_halftone *pdht = *ppdht;
2294
2295 if (pdht == 0) {
2296 rc_header rc;
2297
2298 rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
2299 return_error(gs_error_VMerror),
2300 "cmd_create_dev_ht");
2301 rc = pdht->rc;
2302 memset(pdht, 0, sizeof(*pdht));
2303 pdht->rc = rc;
2304 *ppdht = pdht;
2305 }
2306 return 0;
2307 }
2308
2309 /* Resize the halftone components array if necessary. */
2310 private int
cmd_resize_halftone(gx_device_halftone ** ppdht,uint num_comp,gs_memory_t * mem)2311 cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
2312 gs_memory_t * mem)
2313 {
2314 int code = cmd_create_dev_ht(ppdht, mem);
2315 gx_device_halftone *pdht = *ppdht;
2316
2317 if (code < 0)
2318 return code;
2319 if (num_comp != pdht->num_comp) {
2320 gx_ht_order_component *pcomp;
2321
2322 /*
2323 * We must be careful not to shrink or free the components array
2324 * before releasing any relevant elements.
2325 */
2326 if (num_comp < pdht->num_comp) {
2327 uint i;
2328
2329 /* Don't release the default order. */
2330 for (i = pdht->num_comp; i-- > num_comp;)
2331 if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
2332 gx_ht_order_release(&pdht->components[i].corder, mem, true);
2333 if (num_comp == 0) {
2334 gs_free_object(mem, pdht->components, "cmd_resize_halftone");
2335 pcomp = 0;
2336 } else {
2337 pcomp = gs_resize_object(mem, pdht->components, num_comp,
2338 "cmd_resize_halftone");
2339 if (pcomp == 0) {
2340 pdht->num_comp = num_comp; /* attempt consistency */
2341 return_error(gs_error_VMerror);
2342 }
2343 }
2344 } else {
2345 /* num_comp > pdht->num_comp */
2346 if (pdht->num_comp == 0)
2347 pcomp = gs_alloc_struct_array(mem, num_comp,
2348 gx_ht_order_component,
2349 &st_ht_order_component_element,
2350 "cmd_resize_halftone");
2351 else
2352 pcomp = gs_resize_object(mem, pdht->components, num_comp,
2353 "cmd_resize_halftone");
2354 if (pcomp == 0)
2355 return_error(gs_error_VMerror);
2356 memset(&pcomp[pdht->num_comp], 0,
2357 sizeof(*pcomp) * (num_comp - pdht->num_comp));
2358 }
2359 pdht->num_comp = num_comp;
2360 pdht->components = pcomp;
2361 }
2362 return 0;
2363 }
2364
2365 /* ------ Path operations ------ */
2366
2367 /* Decode a path segment. */
2368 private int
clist_decode_segment(gx_path * ppath,int op,fixed vs[6],gs_fixed_point * ppos,int x0,int y0,segment_notes notes)2369 clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
2370 gs_fixed_point * ppos, int x0, int y0, segment_notes notes)
2371 {
2372 fixed px = ppos->x - int2fixed(x0);
2373 fixed py = ppos->y - int2fixed(y0);
2374 int code;
2375
2376 #define A vs[0]
2377 #define B vs[1]
2378 #define C vs[2]
2379 #define D vs[3]
2380 #define E vs[4]
2381 #define F vs[5]
2382
2383 switch (op) {
2384 case cmd_opv_rmoveto:
2385 code = gx_path_add_point(ppath, px += A, py += B);
2386 break;
2387 case cmd_opv_rlineto:
2388 code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
2389 break;
2390 case cmd_opv_hlineto:
2391 code = gx_path_add_line_notes(ppath, px += A, py, notes);
2392 break;
2393 case cmd_opv_vlineto:
2394 code = gx_path_add_line_notes(ppath, px, py += A, notes);
2395 break;
2396 case cmd_opv_rmlineto:
2397 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
2398 break;
2399 code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
2400 break;
2401 case cmd_opv_rm2lineto:
2402 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
2403 (code = gx_path_add_line_notes(ppath, px += C, py += D,
2404 notes)) < 0
2405 )
2406 break;
2407 code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
2408 break;
2409 case cmd_opv_rm3lineto:
2410 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
2411 (code = gx_path_add_line_notes(ppath, px += C, py += D,
2412 notes)) < 0 ||
2413 (code = gx_path_add_line_notes(ppath, px += E, py += F,
2414 notes)) < 0
2415 )
2416 break;
2417 code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
2418 break;
2419 case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
2420 rrc: E += (C += A);
2421 F += (D += B);
2422 curve: code = gx_path_add_curve_notes(ppath, px + A, py + B,
2423 px + C, py + D,
2424 px + E, py + F, notes);
2425 px += E, py += F;
2426 break;
2427 case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
2428 hvc: F = C + D, D = C, E = C = A + B, B = 0;
2429 goto curve;
2430 case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
2431 vhc: E = B + D, F = D = A + C, C = B, B = A, A = 0;
2432 goto curve;
2433 case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
2434 F = B + D, E = A + C, D = B, C = A, B = A = 0;
2435 goto curve;
2436 case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
2437 F = D += B, E = C += A;
2438 goto curve;
2439 case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
2440 if ((A ^ B) < 0)
2441 C = -B, D = -A;
2442 else
2443 C = B, D = A;
2444 goto vhc;
2445 case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
2446 if ((A ^ B) < 0)
2447 D = -A, C = B, B = -B;
2448 else
2449 D = A, C = B;
2450 goto hvc;
2451 case cmd_opv_scurveto: /* (a b c d e f) => */
2452 {
2453 fixed a = A, b = B;
2454
2455 /* See gxclpath.h for details on the following. */
2456 if (A == 0) {
2457 /* Previous curve was vh or vv */
2458 A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
2459 } else {
2460 /* Previous curve was hv or hh */
2461 A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
2462 }
2463 }
2464 goto rrc;
2465 case cmd_opv_closepath:
2466 code = gx_path_close_subpath(ppath);
2467 gx_path_current_point(ppath, (gs_fixed_point *) vs);
2468 px = A, py = B;
2469 break;
2470 default:
2471 return_error(gs_error_rangecheck);
2472 }
2473 #undef A
2474 #undef B
2475 #undef C
2476 #undef D
2477 #undef E
2478 #undef F
2479 ppos->x = px + int2fixed(x0);
2480 ppos->y = py + int2fixed(y0);
2481 return code;
2482 }
2483
2484 /*
2485 * Execute a polyfill -- either a fill_parallelogram or a fill_triangle.
2486 * If we ever implement fill_trapezoid in the band list, that will be
2487 * detected here too.
2488 *
2489 * Note that degenerate parallelograms or triangles may collapse into
2490 * a single line or point. We must check for this so we don't try to
2491 * access non-existent segments.
2492 */
2493 private int
clist_do_polyfill(gx_device * dev,gx_path * ppath,const gx_drawing_color * pdcolor,gs_logical_operation_t lop)2494 clist_do_polyfill(gx_device *dev, gx_path *ppath,
2495 const gx_drawing_color *pdcolor,
2496 gs_logical_operation_t lop)
2497 {
2498 const subpath *psub = ppath->first_subpath;
2499 const segment *pseg1;
2500 const segment *pseg2;
2501 int code;
2502
2503 if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
2504 fixed px = psub->pt.x, py = psub->pt.y;
2505 fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
2506 fixed bx, by;
2507 /*
2508 * We take advantage of the fact that the parameter lists for
2509 * fill_parallelogram and fill_triangle are identical.
2510 */
2511 dev_proc_fill_parallelogram((*fill));
2512
2513 if (pseg2->next) {
2514 /* Parallelogram */
2515 fill = dev_proc(dev, fill_parallelogram);
2516 bx = pseg2->pt.x - pseg1->pt.x;
2517 by = pseg2->pt.y - pseg1->pt.y;
2518 } else {
2519 /* Triangle */
2520 fill = dev_proc(dev, fill_triangle);
2521 bx = pseg2->pt.x - px;
2522 by = pseg2->pt.y - py;
2523 }
2524 code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
2525 } else
2526 code = 0;
2527 gx_path_new(ppath);
2528 return code;
2529 }
2530