1 /* Copyright (C) 2001-2019 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., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16
17 /* Command list interpreter/rasterizer */
18 #include "memory_.h"
19 #include "gx.h"
20 #include "gp.h" /* for gp_fmode_rb */
21 #include "gpcheck.h"
22 #include "gserrors.h"
23 #include "gscdefs.h" /* for image type table */
24 #include "gsbitops.h"
25 #include "gsparams.h"
26 #include "gsstate.h" /* (should only be gs_gstate) */
27 #include "gstrans.h" /* for gs_is_pdf14trans_compositor */
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 "gxpcolor.h"
43 #include "gxhttile.h"
44 #include "gxiparam.h"
45 #include "gximask.h"
46 #include "gzpath.h"
47 #include "gzcpath.h"
48 #include "gzacpath.h"
49 #include "stream.h"
50 #include "strimpl.h"
51 #include "gxcomp.h"
52 #include "gsserial.h"
53 #include "gxdhtserial.h"
54 #include "gzht.h"
55 #include "gxshade.h"
56 #include "gxshade4.h"
57 #include "gsicc_manage.h"
58 #include "gsicc.h"
59
60 extern_gx_device_halftone_list();
61 extern_gx_image_type_table();
62
63 /* We need color space types for constructing temporary color spaces. */
64 extern const gs_color_space_type gs_color_space_type_Indexed;
65
66 /* Print a bitmap for tracing */
67 #ifdef DEBUG
68 static void
cmd_print_bits(gs_memory_t * mem,const byte * data,int width,int height,int raster)69 cmd_print_bits(gs_memory_t *mem, const byte * data, int width, int height, int raster)
70 {
71 int i, j;
72
73 dmlprintf3(mem, "[L]width=%d, height=%d, raster=%d\n",
74 width, height, raster);
75 for (i = 0; i < height; i++) {
76 const byte *row = data + i * raster;
77
78 dmlprintf(mem, "[L]");
79 for (j = 0; j < raster; j++)
80 dmprintf1(mem, " %02x", row[j]);
81 dmputc(mem, '\n');
82 }
83 }
84 #else
85 # define cmd_print_bits(mem, data, width, height, raster) DO_NOTHING
86 #endif
87
88 /* Get a variable-length integer operand. */
89 #define cmd_getw(var, p)\
90 BEGIN\
91 if ( *p < 0x80 ) var = *p++;\
92 else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93 END
94
95 static long
cmd_get_w(const byte * p,const byte ** rp)96 cmd_get_w(const byte * p, const byte ** rp)
97 {
98 int val = *p++ & 0x7f;
99 int shift = 7;
100
101 for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102 *rp = p;
103 return val;
104 }
105
106 /* Get a variable-length fractional operand. */
107 #define cmd_getfrac(var, p)\
108 BEGIN\
109 if ( !(*p & 1) ) var = (*p++) << 24;\
110 else { const byte *_cbp; var = cmd_get_frac31(p, &_cbp); p = _cbp; }\
111 END
112 static frac31
cmd_get_frac31(const byte * p,const byte ** rp)113 cmd_get_frac31(const byte * p, const byte ** rp)
114 {
115 frac31 val = (*p++ & 0xFE) << 24;
116 int shift = 24 - 7;
117
118 for (; val |= (frac31)(*p & 0xFE) << shift, *p++ & 1; shift -= 7);
119 *rp = p;
120 return val;
121 }
122
123 /*
124 * Define the structure for keeping track of the command reading buffer.
125 *
126 * The ptr member is only used for passing the current pointer to, and
127 * receiving an updated pointer from, commands implemented as separate
128 * procedures: normally it is kept in a register.
129 */
130 typedef struct command_buf_s {
131 byte *data; /* actual buffer, guaranteed aligned */
132 uint size;
133 const byte *ptr; /* next byte to be read (see above) */
134 const byte *warn_limit; /* refill warning point */
135 const byte *end; /* byte just beyond valid data */
136 stream *s; /* for refilling buffer */
137 int end_status;
138 } command_buf_t;
139
140 /* Set the end of a command buffer. */
141 static void
set_cb_end(command_buf_t * pcb,const byte * end)142 set_cb_end(command_buf_t *pcb, const byte *end)
143 {
144 pcb->end = end;
145 pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146 if ( pcb->warn_limit > pcb->end )
147 pcb->warn_limit = pcb->end; /**** This is dangerous. Other places ****/
148 /**** assume that the limit is a soft ****/
149 /**** limit and should check 'end' ****/
150 }
151
152 /* Read more data into a command buffer. */
153 static int
top_up_cbuf(command_buf_t * pcb,const byte ** pcbp)154 top_up_cbuf(command_buf_t *pcb, const byte **pcbp)
155 {
156 uint nread;
157 const byte *cbp = *pcbp;
158 byte *cb_top = pcb->data + (pcb->end - cbp);
159 # ifdef DEBUG
160 stream_state *st = pcb->s->state;
161 # endif
162
163 if (pcb->end - cbp >= pcb->size) {
164 errprintf(pcb->s->memory, "Clist I/O error: cbp past end of buffer\n");
165 return (gs_error_ioerror);
166 }
167
168 if (seofp(pcb->s)) {
169 /* Can't use offset_map, because s_close resets s->state. Don't top up. */
170 pcb->end_status = pcb->s->end_status;
171 return 0;
172 }
173 # ifdef DEBUG
174 {
175 int code = top_up_offset_map(st, pcb->data, cbp, pcb->end);
176
177 if (code < 0)
178 return code;
179 }
180 # endif
181 memmove(pcb->data, cbp, pcb->end - cbp);
182 nread = pcb->end - cb_top;
183 pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
184 if ( nread == 0 ) {
185 /* No data for this band at all. */
186 if (cb_top >= pcb->end) {
187 /* should not happen */
188 *pcbp = pcb->data;
189 pcb->data[0] = cmd_opv_end_run;
190 return_error(gs_error_ioerror);
191 }
192 *cb_top = cmd_opv_end_run;
193 nread = 1;
194 }
195 set_cb_end(pcb, cb_top + nread);
196 process_interrupts(pcb->s->memory);
197 *pcbp = pcb->data;
198 return 0;
199 }
200
201 /* Read data from the command buffer and stream. */
202 static const byte *
cmd_read_data(command_buf_t * pcb,byte * ptr,uint rsize,const byte * cbp)203 cmd_read_data(command_buf_t *pcb, byte *ptr, uint rsize, const byte *cbp)
204 {
205 if (pcb->end - cbp >= rsize) {
206 memmove(ptr, cbp, rsize);
207 return cbp + rsize;
208 } else {
209 uint cleft = pcb->end - cbp;
210 uint rleft = rsize - cleft;
211
212 memmove(ptr, cbp, cleft);
213 sgets(pcb->s, ptr + cleft, rleft, &rleft);
214 return pcb->end;
215 }
216 }
217 #define cmd_read(ptr, rsize, cbp)\
218 cbp = cmd_read_data(&cbuf, ptr, rsize, cbp)
219
220 /* Read a fixed-size value from the command buffer. */
221 static inline const byte *
cmd_copy_value(void * pvar,int var_size,const byte * cbp)222 cmd_copy_value(void *pvar, int var_size, const byte *cbp)
223 {
224 memcpy(pvar, cbp, var_size);
225 return cbp + var_size;
226 }
227 #define cmd_get_value(var, cbp)\
228 cbp = cmd_copy_value(&var, sizeof(var), cbp)
229
230 /*
231 * Define a buffer structure to hold a serialized halftone. This is
232 * used only if the serialized halftone is too large to fit into
233 * the command buffer.
234 */
235 typedef struct ht_buff_s {
236 uint ht_size, read_size;
237 byte * pcurr;
238 byte * pbuff;
239 } ht_buff_t;
240
241 /*
242 * Render one band to a specified target device. Note that if
243 * action == setup, target may be 0.
244 */
245 static int read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern);
246 static int read_set_bits(command_buf_t *pcb, tile_slot *bits,
247 int compress, gx_clist_state *pcls,
248 gx_strip_bitmap *tile, tile_slot **pslot,
249 gx_device_clist_reader *cdev, gs_memory_t *mem);
250 static int read_set_misc2(command_buf_t *pcb, gs_gstate *pgs,
251 segment_notes *pnotes);
252 static int read_set_color_space(command_buf_t *pcb, gs_gstate *pgs,
253 gx_device_clist_reader *cdev, gs_memory_t *mem);
254 static int read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
255 gs_color_space *pcs);
256 static int read_put_params(command_buf_t *pcb, gs_gstate *pgs,
257 gx_device_clist_reader *cdev,
258 gs_memory_t *mem);
259 static int read_create_compositor(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp);
260 static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs,
261 gs_memory_t *mem, gs_composite_t *pcomp,
262 int x0, int y0, gx_device **ptarget);
263 static int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *);
264 static int read_ht_segment(ht_buff_t *, command_buf_t *, gs_gstate *,
265 gx_device *, gs_memory_t *);
266
267 static const byte *cmd_read_rect(int, gx_cmd_rect *, const byte *);
268 static const byte *cmd_read_short_bits(command_buf_t *pcb, byte *data, int tot_bytes,
269 int width_bytes, int height,
270 uint raster, const byte *cbp);
271 static int cmd_select_map(cmd_map_index, cmd_map_contents,
272 gs_gstate *, int **,
273 frac **, uint *, gs_memory_t *);
274 static int cmd_create_dev_ht(gx_device_halftone **, gs_memory_t *);
275 static int cmd_resize_halftone(gx_device_halftone **, uint,
276 gs_memory_t *);
277 static int clist_decode_segment(gx_path *, int, fixed[6],
278 gs_fixed_point *, int, int,
279 segment_notes);
280 static int clist_do_polyfill(gx_device *, gx_path *,
281 const gx_drawing_color *,
282 gs_logical_operation_t);
283
284 static inline void
enqueue_compositor(gs_composite_t ** ppcomp_first,gs_composite_t ** ppcomp_last,gs_composite_t * pcomp)285 enqueue_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp)
286 {
287 if (*ppcomp_last == NULL) {
288 pcomp->prev = pcomp->next = NULL;
289 *ppcomp_last = *ppcomp_first = pcomp;
290 } else {
291 (*ppcomp_last)->next = pcomp;
292 pcomp->prev = *ppcomp_last;
293 pcomp->next = NULL;
294 *ppcomp_last = pcomp;
295 }
296 }
297
298 #if 0 /* Appears unused - keep for a while. */
299 static inline gs_composite_t *
300 dequeue_last_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last)
301 {
302 gs_composite_t *pcomp = *ppcomp_last;
303
304 if (*ppcomp_first == *ppcomp_last)
305 *ppcomp_first = *ppcomp_last = NULL;
306 else {
307 *ppcomp_last = (*ppcomp_last)->prev;
308 pcomp->prev = NULL;
309 (*ppcomp_last)->next = NULL;
310 }
311 return pcomp;
312 }
313
314 static inline gs_composite_t *
315 dequeue_first_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last)
316 {
317 gs_composite_t *pcomp = *ppcomp_first;
318
319 if (*ppcomp_first == *ppcomp_last)
320 *ppcomp_first = *ppcomp_last = NULL;
321 else {
322 *ppcomp_first = (*ppcomp_first)->next;
323 pcomp->next = NULL;
324 (*ppcomp_last)->prev = NULL;
325 }
326 return pcomp;
327 }
328 #endif
329
330 static inline int
dequeue_compositor(gs_composite_t ** ppcomp_first,gs_composite_t ** ppcomp_last,gs_composite_t * pcomp)331 dequeue_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp)
332 {
333 if (*ppcomp_last == *ppcomp_first) {
334 if (*ppcomp_last == pcomp) {
335 *ppcomp_last = *ppcomp_first = NULL;
336 return 0;
337 } else
338 return_error(gs_error_unregistered); /* Must not happen. */
339 } else {
340 gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
341
342 if (*ppcomp_last == pcomp)
343 *ppcomp_last = pcomp->prev;
344 else
345 pcomp_next->prev = pcomp_prev;
346 if (*ppcomp_first == pcomp)
347 *ppcomp_first = pcomp->next;
348 else
349 pcomp_prev->next = pcomp_next;
350 pcomp->next = pcomp->prev = NULL;
351 return 0;
352 }
353 }
354
355 static inline void
free_compositor(gs_composite_t * pcomp,gs_memory_t * mem)356 free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
357 {
358 gs_free_object(mem, pcomp, "free_compositor");
359 }
360
361 static inline bool
is_null_compositor_op(const byte * cbp,int * length)362 is_null_compositor_op(const byte *cbp, int *length)
363 {
364 if (cbp[0] == cmd_opv_end_run) {
365 *length = 1;
366 return true;
367 }
368 return false;
369 }
370
371 static int
execute_compositor_queue(gx_device_clist_reader * cdev,gx_device ** target,gx_device ** tdev,gs_gstate * pgs,gs_composite_t ** ppcomp_first,gs_composite_t ** ppcomp_last,gs_composite_t * pcomp_from,int x0,int y0,gs_memory_t * mem,bool idle)372 execute_compositor_queue(gx_device_clist_reader *cdev, gx_device **target, gx_device **tdev, gs_gstate *pgs,
373 gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp_from,
374 int x0, int y0, gs_memory_t *mem, bool idle)
375 {
376 while (pcomp_from != NULL) {
377 gs_composite_t *pcomp = pcomp_from;
378 int code;
379
380 pcomp_from = pcomp->next;
381 code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
382 if (code < 0)
383 return code;
384 pcomp->idle |= idle;
385 code = apply_create_compositor(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
386 if (code < 0)
387 return code;
388 *tdev = *target;
389 }
390 return 0;
391 }
392
393 static void
mark_as_idle(gs_composite_t * pcomp_start,gs_composite_t * pcomp_end)394 mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
395 {
396 gs_composite_t *pcomp = pcomp_start;
397
398 while (pcomp != NULL) {
399 pcomp->idle = true;
400 if (pcomp == pcomp_end)
401 break;
402 pcomp = pcomp->next;
403 }
404 }
405
406 static inline int
drop_compositor_queue(gs_composite_t ** ppcomp_first,gs_composite_t ** ppcomp_last,gs_composite_t * pcomp_from,gs_memory_t * mem,int x0,int y0,gs_gstate * pgs)407 drop_compositor_queue(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last,
408 gs_composite_t *pcomp_from, gs_memory_t *mem, int x0, int y0,
409 gs_gstate *pgs)
410 {
411 gs_composite_t *pcomp;
412
413 do {
414 int code;
415
416 pcomp = *ppcomp_last;
417 if (pcomp == NULL)
418 return 0;
419 dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
420 code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
421 if (code < 0)
422 return code;
423 free_compositor(pcomp, mem);
424 } while (pcomp != pcomp_from);
425 return 0;
426 }
427
428 static int
read_set_misc_map(byte cb,command_buf_t * pcb,gs_gstate * pgs,gs_memory_t * mem)429 read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
430 {
431 const byte *cbp = pcb->ptr;
432 frac *mdata;
433 int *pcomp_num;
434 uint count = 0; /* quiet compiler */
435 cmd_map_contents cont =
436 (cmd_map_contents)(cb & 0x30) >> 4;
437 int code;
438
439 code = cmd_select_map(cb & 0xf, cont,
440 pgs,
441 &pcomp_num,
442 &mdata, &count, mem);
443
444 if (code < 0)
445 return code;
446 /* Get component number if relevant */
447 if (pcomp_num == NULL)
448 cbp++;
449 else {
450 *pcomp_num = (int) *cbp++;
451 if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
452 }
453 if (cont == cmd_map_other) {
454 cbp = cmd_read_data(pcb, (byte *)mdata, count, cbp);
455
456 #ifdef DEBUG
457 if (gs_debug_c('L')) {
458 uint i;
459
460 for (i = 0; i < count / sizeof(*mdata); ++i)
461 dmprintf1(mem, " 0x%04x", mdata[i]);
462 dmputc(mem, '\n');
463 }
464 } else {
465 if_debug0m('L', mem, " none\n");
466 #endif
467 }
468 /* Recompute the effective transfer, */
469 /* in case this was a transfer map. */
470 gx_gstate_set_effective_xfer(pgs);
471 pcb->ptr = cbp;
472 return 0;
473 }
474
475 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)476 clist_playback_band(clist_playback_action playback_action,
477 gx_device_clist_reader *cdev, stream *s,
478 gx_device *target, int x0, int y0, gs_memory_t * mem)
479 {
480 byte *cbuf_storage;
481 command_buf_t cbuf;
482 /* data_bits is for short copy_* bits and copy_* compressed, */
483 /* must be aligned */
484 byte *data_bits = 0;
485 const byte *cbp;
486 int dev_depth; /* May vary due to compositing devices */
487 int dev_depth_bytes;
488 int odd_delta_shift;
489 int num_zero_bytes;
490 gx_device *tdev;
491 gx_clist_state state;
492 gx_color_index *set_colors;
493 gx_device_color *set_dev_colors;
494 tile_slot *state_slot;
495 gx_strip_bitmap state_tile; /* parameters for reading tiles */
496 tile_slot tile_bits; /* parameters of current tile */
497 gs_int_point tile_phase, color_phase;
498 gx_path path;
499 bool in_path;
500 gs_fixed_point ppos;
501 gx_clip_path clip_path;
502 bool use_clip;
503 gx_clip_path *pcpath;
504 gx_device_cpath_accum clip_accum;
505 gs_fixed_rect target_box;
506 struct _cas {
507 bool lop_enabled;
508 gx_device_color dcolor;
509 gs_fixed_point fa_save;
510 } clip_save;
511 bool in_clip = false;
512 gs_gstate gs_gstate;
513 gx_device_color fill_color;
514 gx_device_color stroke_color;
515 float dash_pattern[cmd_max_dash];
516 gx_fill_params fill_params;
517 gx_stroke_params stroke_params;
518 #ifdef DEBUG
519 gs_halftone_type halftone_type;
520 #endif
521 union im_ {
522 gs_image_common_t c;
523 gs_data_image_t d;
524 gs_image1_t i1;
525 gs_image4_t i4;
526 } image;
527 gs_int_rect image_rect;
528 gs_color_space *pcs = NULL;
529 gx_image_enum_common_t *image_info;
530 gx_image_plane_t planes[32];
531 uint data_height;
532 uint data_size;
533 byte *data_on_heap;
534 fixed vs[6];
535 segment_notes notes;
536 int data_x;
537 int code = 0;
538 ht_buff_t ht_buff;
539 gx_device *const orig_target = target;
540 gx_device_clip clipper_dev;
541 bool clipper_dev_open;
542 patch_fill_state_t pfs;
543 int op = 0;
544 int plane_height = 0;
545
546 #ifdef DEBUG
547 stream_state *st = s->state; /* Save because s_close resets s->state. */
548 #endif
549 gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
550 tile_slot bits; /* parameters for reading bits */
551
552 /* pad the cbuf data area a bit (just in case) */
553 if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
554 "clist_playback_band(cbuf_storage)")) == NULL) {
555 return_error(gs_error_VMerror);
556 }
557 cbuf.data = (byte *)cbuf_storage;
558 cbuf.size = cbuf_size;
559 cbuf.s = s;
560 cbuf.end_status = 0;
561 set_cb_end(&cbuf, cbuf.data + cbuf.size);
562 cbp = cbuf.end;
563
564 pfs.dev = NULL; /* Indicate "not initialized". */
565 memset(&ht_buff, 0, sizeof(ht_buff));
566
567 /* The following initializations are to quiet gcc warnings. */
568 memset(&bits, 0, sizeof(bits));
569 memset(&tile_bits, 0, sizeof(tile_bits));
570 memset(&clip_save, 0, sizeof(clip_save));
571 memset(&state_slot, 0, sizeof(state_slot));
572 ppos.x = ppos.y = 0;
573
574 in: /* Initialize for a new page. */
575 tdev = target;
576 set_colors = state.colors;
577 set_dev_colors = state.tile_color_devn;
578 use_clip = false;
579 pcpath = NULL;
580 clipper_dev_open = false;
581 notes = sn_none;
582 data_x = 0;
583 {
584 static const gx_clist_state cls_initial = { cls_initial_values };
585
586 state = cls_initial;
587 }
588 state_tile.id = gx_no_bitmap_id;
589 state_tile.shift = state_tile.rep_shift = 0;
590 state_tile.size.x = state_tile.size.y = 0;
591 state_tile.num_planes = 1;
592 tile_phase.x = color_phase.x = x0;
593 tile_phase.y = color_phase.y = y0;
594 gx_path_init_local(&path, mem);
595 in_path = false;
596 /*
597 * Initialize the clipping region to the full page.
598 * (Since we also initialize use_clip to false, this is arbitrary.)
599 */
600 {
601 gs_fixed_rect cbox;
602
603 gx_cpath_init_local(&clip_path, mem);
604 cbox.p.x = 0;
605 cbox.p.y = 0;
606 cbox.q.x = cdev->width;
607 cbox.q.y = cdev->height;
608 gx_cpath_from_rectangle(&clip_path, &cbox);
609 }
610 if (target != 0)
611 (*dev_proc(target, get_clipping_box))(target, &target_box);
612 memset(&gs_gstate, 0, sizeof(gs_gstate));
613 GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
614 code = gs_gstate_initialize(&gs_gstate, mem);
615 gs_gstate.device = tdev;
616 gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
617 gs_gstate.clip_path = &clip_path;
618 pcs = gs_cspace_new_DeviceGray(mem);
619 if (pcs == NULL) {
620 code = gs_note_error(gs_error_VMerror);
621 goto out;
622 }
623 pcs->type->install_cspace(pcs, &gs_gstate);
624 gs_gstate.color[0].color_space = pcs;
625 rc_increment_cs(pcs);
626 gs_gstate.color[1].color_space = pcs;
627 rc_increment_cs(pcs);
628 /* Remove the ICC link cache and replace with the device link cache
629 so that we share the cache across bands */
630 rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
631 gs_gstate.icc_link_cache = cdev->icc_cache_cl;
632 /* Need to lock during the increment of the link cache */
633 gx_monitor_enter(cdev->icc_cache_cl->lock);
634 rc_increment(cdev->icc_cache_cl);
635 gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
636 if (code < 0)
637 goto out;
638
639 gs_gstate.line_params.dash.pattern = dash_pattern;
640 if (tdev != 0) {
641 gx_set_cmap_procs(&gs_gstate, tdev);
642 }
643 gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
644 #ifdef DEBUG
645 halftone_type = ht_type_none;
646 #endif
647 fill_color.ccolor_valid = false;
648 color_unset(&fill_color);
649 data_bits = gs_alloc_bytes(mem, data_bits_size,
650 "clist_playback_band(data_bits)");
651 if (data_bits == 0) {
652 code = gs_note_error(gs_error_VMerror);
653 goto out;
654 }
655 while (code >= 0) {
656 int compress;
657 int depth = 0x7badf00d; /* Initialize against indeterminizm. */
658 int raster = 0x7badf00d; /* Initialize against indeterminizm. */
659 byte *source = NULL; /* Initialize against indeterminizm. */
660 gx_color_index colors[2];
661 gx_color_index *pcolor;
662 gx_device_color *pdcolor = NULL;
663 gs_logical_operation_t log_op;
664
665 /* Make sure the buffer contains a full command. */
666 if (cbp >= cbuf.warn_limit) {
667 if (cbuf.end_status < 0) { /* End of file or error. */
668 if (cbp >= cbuf.end) {
669 code = (cbuf.end_status == EOFC ? 0 :
670 gs_note_error(gs_error_ioerror));
671 break;
672 }
673 } else {
674 code = top_up_cbuf(&cbuf, &cbp);
675 if (code < 0)
676 goto top_up_failed;
677 }
678 }
679 op = *cbp++;
680 #ifdef DEBUG
681 if (gs_debug_c('L')) {
682 const char *const *sub = cmd_sub_op_names[op >> 4];
683 long offset = (long)clist_file_offset(st, cbp - 1 - cbuf.data);
684
685 if (sub)
686 dmlprintf1(mem, "[L]%s", sub[op & 0xf]);
687 else
688 dmlprintf2(mem, "[L]%s %d", cmd_op_names[op >> 4], op & 0xf);
689 dmlprintf1(mem, "(offset=%ld):", offset);
690 }
691 #endif
692 switch (op >> 4) {
693 case cmd_op_misc >> 4:
694 switch (op) {
695 case cmd_opv_end_run:
696 if_debug0m('L', mem, "\n");
697 continue;
698 case cmd_opv_set_tile_size:
699 cbuf.ptr = cbp;
700 code = read_set_tile_size(&cbuf, &tile_bits,
701 gx_device_is_pattern_clist((gx_device *)cdev));
702 cbp = cbuf.ptr;
703 if (code < 0)
704 goto out;
705 continue;
706 case cmd_opv_set_tile_phase:
707 cmd_getw(state.tile_phase.x, cbp);
708 cmd_getw(state.tile_phase.y, cbp);
709 if_debug2m('L', mem, " (%d,%d)\n",
710 state.tile_phase.x,
711 state.tile_phase.y);
712 goto set_phase;
713 case cmd_opv_set_tile_bits:
714 bits = tile_bits;
715 compress = 0;
716 stb:
717 cbuf.ptr = cbp;
718 code = read_set_bits(&cbuf, &bits, compress,
719 &state, &state_tile, &state_slot,
720 cdev, mem);
721 cbp = cbuf.ptr;
722 if (code < 0)
723 goto out;
724 goto stp;
725 case cmd_opv_set_bits:
726 compress = *cbp & 3;
727 bits.cb_depth = *cbp++ >> 2;
728 cmd_getw(bits.width, cbp);
729 cmd_getw(bits.height, cbp);
730 if_debug4m('L', mem, " compress=%d depth=%d size=(%d,%d)",
731 compress, bits.cb_depth,
732 bits.width, bits.height);
733 bits.cb_raster =
734 bitmap_raster(bits.width * bits.cb_depth);
735 bits.x_reps = bits.y_reps = 1;
736 bits.shift = bits.rep_shift = 0;
737 bits.num_planes = 1;
738 goto stb;
739 case cmd_opv_set_tile_color:
740 set_colors = state.tile_colors;
741 if_debug0m('L', mem, "\n");
742 continue;
743 case cmd_opv_set_misc:
744 {
745 uint cb = *cbp++;
746
747 switch (cb >> 6) {
748 case cmd_set_misc_lop >> 6:
749 cmd_getw(state.lop, cbp);
750 state.lop = (state.lop << 6) + (cb & 0x3f);
751 if_debug1m('L', mem, " lop=0x%x\n", state.lop);
752 if (state.lop_enabled)
753 gs_gstate.log_op = state.lop;
754 break;
755 case cmd_set_misc_data_x >> 6:
756 if (cb & 0x20)
757 cmd_getw(data_x, cbp);
758 else
759 data_x = 0;
760 data_x = (data_x << 5) + (cb & 0x1f);
761 if_debug1m('L', mem, " data_x=%d\n", data_x);
762 break;
763 case cmd_set_misc_map >> 6:
764 cbuf.ptr = cbp;
765 code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
766 if (code < 0)
767 goto out;
768 cbp = cbuf.ptr;
769 break;
770 case cmd_set_misc_halftone >> 6: {
771 uint num_comp;
772 #ifdef DEBUG
773 halftone_type = cb & 0x3f;
774 #endif
775 cmd_getw(num_comp, cbp);
776 #ifdef DEBUG
777 if_debug2m('L', mem, " halftone type=%d num_comp=%u\n",
778 halftone_type, num_comp);
779 #endif
780 code = cmd_resize_halftone(
781 &gs_gstate.dev_ht,
782 num_comp, mem);
783 if (code < 0)
784 goto out;
785 break;
786 }
787 default:
788 goto bad_op;
789 }
790 }
791 continue;
792 case cmd_opv_enable_lop:
793 state.lop_enabled = true;
794 gs_gstate.log_op = state.lop;
795 if_debug0m('L', mem, "\n");
796 continue;
797 case cmd_opv_disable_lop:
798 state.lop_enabled = false;
799 gs_gstate.log_op = lop_default;
800 if_debug0m('L', mem, "\n");
801 continue;
802 case cmd_opv_end_page:
803 if_debug0m('L', mem, "\n");
804 /*
805 * Do end-of-page cleanup, then reinitialize if
806 * there are more pages to come.
807 */
808 goto out;
809 case cmd_opv_delta_color0:
810 pcolor = &set_colors[0];
811 goto delta2_c;
812 case cmd_opv_delta_color1:
813 pcolor = &set_colors[1];
814 delta2_c:set_colors = state.colors;
815 /* See comments for cmd_put_color() in gxclutil.c. */
816 {
817 gx_color_index delta = 0;
818 uint data;
819
820 dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
821 tdev->color_info.depth : 8*sizeof(gx_color_index));
822 dev_depth_bytes = (dev_depth + 7) >> 3;
823 switch (dev_depth_bytes) {
824 /* For cases with an even number of bytes */
825 case 8:
826 data = *cbp++;
827 delta = (((gx_color_index)
828 ((data & 0xf0) << 4) + (data & 0x0f)) << 24) << 24;
829 /* fall through */
830 case 6:
831 data = *cbp++;
832 delta |= (((gx_color_index)
833 ((data & 0xf0) << 4) + (data & 0x0f)) << 16) << 16;
834 /* fall through */
835 case 4:
836 data = *cbp++;
837 delta |= ((gx_color_index)
838 ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
839 /* fall through */
840 case 2:
841 data = *cbp++;
842 delta |= ((gx_color_index)
843 ((data & 0xf0) << 4) + (data & 0x0f));
844 break;
845 /* For cases with an odd number of bytes */
846 case 7:
847 data = *cbp++;
848 delta = ((gx_color_index)
849 ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
850 /* fall through */
851 case 5:
852 data = *cbp++;
853 delta |= ((gx_color_index)
854 ((data & 0xf0) << 4) + (data & 0x0f));
855 /* fall through */
856 case 3:
857 data = *cbp++;
858 odd_delta_shift = (dev_depth_bytes - 3) * 8;
859 delta |= ((gx_color_index)
860 ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
861 data = *cbp++;
862 delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
863 << (odd_delta_shift + 11);
864 }
865 *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
866 }
867 if (sizeof(*pcolor) <= sizeof(ulong))
868 if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
869 else
870 if_debug2m('L', mem, " 0x%8lx%08lx\n",
871 (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
872 continue;
873 case cmd_opv_set_copy_color:
874 state.color_is_alpha = 0;
875 if_debug0m('L', mem, "\n");
876 continue;
877 case cmd_opv_set_copy_alpha:
878 state.color_is_alpha = 1;
879 if_debug0m('L', mem, "\n");
880 continue;
881 default:
882 goto bad_op;
883 }
884 /*NOTREACHED */
885 case cmd_op_set_color0 >> 4:
886 pcolor = &set_colors[0];
887 goto set_color;
888 case cmd_op_set_color1 >> 4:
889 pcolor = &set_colors[1];
890 set_color:set_colors = state.colors;
891 /*
892 * We have a special case for gx_no_color_index. If the low
893 * order 4 bits are "cmd_no_color_index" then we really
894 * have a value of gx_no_color_index. Otherwise the these
895 * bits indicate the number of low order zero bytes in the
896 * value. See comments for cmd_put_color() in gxclutil.c.
897 */
898 num_zero_bytes = op & 0x0f;
899
900 if (num_zero_bytes == cmd_no_color_index)
901 *pcolor = gx_no_color_index;
902 else {
903 gx_color_index color = 0;
904
905 dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
906 tdev->color_info.depth : 8*sizeof(gx_color_index));
907 dev_depth_bytes = (dev_depth + 7) >> 3;
908 switch (dev_depth_bytes - num_zero_bytes) {
909 case 8:
910 color = (gx_color_index) * cbp++;
911 case 7:
912 color = (color << 8) | (gx_color_index) * cbp++;
913 case 6:
914 color = (color << 8) | (gx_color_index) * cbp++;
915 case 5:
916 color = (color << 8) | (gx_color_index) * cbp++;
917 case 4:
918 color = (color << 8) | (gx_color_index) * cbp++;
919 case 3:
920 color = (color << 8) | (gx_color_index) * cbp++;
921 case 2:
922 color = (color << 8) | (gx_color_index) * cbp++;
923 case 1:
924 color = (color << 8) | (gx_color_index) * cbp++;
925 default:
926 break;
927 }
928 color <<= num_zero_bytes * 8;
929 *pcolor = color;
930 }
931 if (sizeof(*pcolor) <= sizeof(ulong))
932 if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
933 else
934 if_debug2m('L', mem, " 0x%8lx%08lx\n",
935 (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
936 continue;
937 case cmd_op_fill_rect >> 4:
938 case cmd_op_tile_rect >> 4:
939 cbp = cmd_read_rect(op, &state.rect, cbp);
940 break;
941 case cmd_op_fill_rect_short >> 4:
942 case cmd_op_tile_rect_short >> 4:
943 state.rect.x += *cbp + cmd_min_short;
944 state.rect.width += cbp[1] + cmd_min_short;
945 if (op & 0xf) {
946 state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
947 cbp += 2;
948 } else {
949 state.rect.y += cbp[2] + cmd_min_short;
950 state.rect.height += cbp[3] + cmd_min_short;
951 cbp += 4;
952 }
953 break;
954 case cmd_op_fill_rect_tiny >> 4:
955 case cmd_op_tile_rect_tiny >> 4:
956 if (op & 8)
957 state.rect.x += state.rect.width;
958 else {
959 int txy = *cbp++;
960
961 state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
962 state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
963 }
964 state.rect.width += (op & 7) + cmd_min_dw_tiny;
965 break;
966 case cmd_op_copy_mono_planes >> 4:
967 cmd_getw(plane_height, cbp);
968 if (plane_height == 0) {
969 /* We are doing a copy mono */
970 depth = 1;
971 } else {
972 depth = tdev->color_info.depth;
973 }
974 if_debug1m('L', mem, " plane_height=0x%x", plane_height);
975 goto copy;
976 case cmd_op_copy_color_alpha >> 4:
977 if (state.color_is_alpha) {
978 if (!(op & 8))
979 depth = *cbp++;
980 } else
981 depth = tdev->color_info.depth;
982 plane_height = 0;
983 copy:cmd_getw(state.rect.x, cbp);
984 cmd_getw(state.rect.y, cbp);
985 if (op & cmd_copy_use_tile) { /* Use the current "tile". */
986 #ifdef DEBUG
987 if (state_slot->index != state.tile_index) {
988 mlprintf2(mem, "state_slot->index = %d, state.tile_index = %d!\n",
989 state_slot->index,
990 state.tile_index);
991 code = gs_note_error(gs_error_ioerror);
992 goto out;
993 }
994 #endif
995 depth = state_slot->cb_depth;
996 state.rect.width = state_slot->width;
997 state.rect.height = state_slot->height;
998 if (state.rect.y + state.rect.height > cdev->height)
999 state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1000 raster = state_slot->cb_raster;
1001 source = (byte *) (state_slot + 1);
1002 } else { /* Read width, height, bits. */
1003 /* depth was set already. */
1004 uint width_bits, width_bytes;
1005 uint bytes;
1006 uchar planes = 1;
1007 uint plane_depth = depth;
1008 uint pln;
1009 byte compression = op & 3;
1010 uint out_bytes;
1011
1012 cmd_getw(state.rect.width, cbp);
1013 cmd_getw(state.rect.height, cbp);
1014 if (plane_height != 0) {
1015 planes = tdev->color_info.num_components;
1016 plane_depth /= planes;
1017 }
1018 width_bits = state.rect.width * plane_depth;
1019 bytes = clist_bitmap_bytes(width_bits,
1020 state.rect.height,
1021 op & 3, &width_bytes,
1022 (uint *)&raster);
1023 if (planes > 1) {
1024 out_bytes = raster * state.rect.height;
1025 plane_height = state.rect.height;
1026 } else {
1027 out_bytes = bytes;
1028 }
1029 /* copy_mono and copy_color/alpha */
1030 /* ensure that the bits will fit in a single buffer, */
1031 /* even after decompression if compressed. */
1032 #ifdef DEBUG
1033 if (planes * out_bytes > data_bits_size) {
1034 mlprintf6(mem, "bitmap size exceeds buffer! width=%d raster=%d height=%d\n file pos %"PRId64" buf pos %d/%d\n",
1035 state.rect.width, raster,
1036 state.rect.height,
1037 stell(s), (int)(cbp - cbuf.data),
1038 (int)(cbuf.end - cbuf.data));
1039 code = gs_note_error(gs_error_ioerror);
1040 goto out;
1041 }
1042 #endif
1043 for (pln = 0; pln < planes; pln++) {
1044 byte *plane_bits = data_bits + pln * plane_height * raster;
1045
1046 /* Fill the cbuf if needed to get the data for the plane */
1047 if (cbp + out_bytes >= cbuf.warn_limit) {
1048 code = top_up_cbuf(&cbuf, &cbp);
1049 if (code < 0)
1050 goto top_up_failed;
1051 }
1052 if (pln)
1053 compression = *cbp++;
1054
1055 if (compression == cmd_compress_const) {
1056 cbp = cmd_read_data(&cbuf, plane_bits, 1, cbp);
1057 if (width_bytes > 0 && state.rect.height > 0)
1058 memset(plane_bits+1, *plane_bits, width_bytes * state.rect.height - 1);
1059
1060 } else if (compression) { /* Decompress the image data. */
1061 stream_cursor_read r;
1062 stream_cursor_write w;
1063
1064 /* We don't know the data length a priori, */
1065 /* so to be conservative, we read */
1066 /* the uncompressed size. */
1067 uint cleft = cbuf.end - cbp;
1068
1069 if (cleft < bytes && !cbuf.end_status) {
1070 uint nread = cbuf_size - cleft;
1071
1072 # ifdef DEBUG
1073 code = top_up_offset_map(st, cbuf.data, cbp, cbuf.end);
1074 if (code < 0)
1075 goto top_up_failed;
1076 # endif
1077 memmove(cbuf.data, cbp, cleft);
1078 cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
1079 set_cb_end(&cbuf, cbuf.data + cleft + nread);
1080 cbp = cbuf.data;
1081 }
1082 r.ptr = cbp - 1;
1083 r.limit = cbuf.end - 1;
1084 w.ptr = plane_bits - 1;
1085 w.limit = w.ptr + data_bits_size;
1086 switch (compression) {
1087 case cmd_compress_rle:
1088 {
1089 stream_RLD_state sstate;
1090
1091 clist_rld_init(&sstate);
1092 /* The process procedure can't fail. */
1093 (*s_RLD_template.process)
1094 ((stream_state *)&sstate, &r, &w, true);
1095 }
1096 break;
1097 case cmd_compress_cfe:
1098 {
1099 stream_CFD_state sstate;
1100
1101 clist_cfd_init(&sstate,
1102 width_bytes << 3 /*state.rect.width */ ,
1103 state.rect.height, mem);
1104 /* The process procedure can't fail. */
1105 (*s_CFD_template.process)
1106 ((stream_state *)&sstate, &r, &w, true);
1107 (*s_CFD_template.release)
1108 ((stream_state *)&sstate);
1109 }
1110 break;
1111 default:
1112 goto bad_op;
1113 }
1114 cbp = r.ptr + 1;
1115 if (pln == 0)
1116 source = data_bits;
1117 } else if ((state.rect.height > 1 && width_bytes != raster) ||
1118 (plane_height != 0)) {
1119 cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1120 state.rect.height, raster, cbp);
1121 if (pln == 0)
1122 source = data_bits;
1123 } else {
1124 /* Never used for planar data */
1125 cmd_read(cbuf.data, bytes, cbp);
1126 source = cbuf.data;
1127 }
1128 }
1129 #ifdef DEBUG
1130 if (gs_debug_c('L')) {
1131 dmprintf2(mem, " depth=%d, data_x=%d\n",
1132 depth, data_x);
1133 cmd_print_bits(mem, source, state.rect.width,
1134 state.rect.height, raster);
1135 }
1136 #endif
1137 }
1138 break;
1139 case cmd_op_delta_tile_index >> 4:
1140 state.tile_index += (int)(op & 0xf) - 8;
1141 goto sti;
1142 case cmd_op_set_tile_index >> 4:
1143 state.tile_index =
1144 ((op & 0xf) << 8) + *cbp++;
1145 sti:state_slot =
1146 (tile_slot *) (cdev->cache_chunk->data +
1147 cdev->tile_table[state.tile_index].offset);
1148 if_debug2m('L', mem, " index=%u offset=%lu\n",
1149 state.tile_index,
1150 cdev->tile_table[state.tile_index].offset);
1151 state_tile.data = (byte *) (state_slot + 1);
1152 stp:state_tile.size.x = state_slot->width;
1153 state_tile.size.y = state_slot->height;
1154 state_tile.raster = state_slot->cb_raster;
1155 state_tile.rep_width = state_tile.size.x /
1156 state_slot->x_reps;
1157 state_tile.rep_height = state_tile.size.y /
1158 state_slot->y_reps;
1159 state_tile.rep_shift = state_slot->rep_shift;
1160 state_tile.shift = state_slot->shift;
1161 state_tile.id = state_slot->id;
1162 state_tile.num_planes = state_slot->num_planes;
1163 set_phase: /*
1164 * state.tile_phase is overloaded according to the command
1165 * to which it will apply:
1166 * For fill_path, stroke_path, fill_triangle/p'gram,
1167 * fill_mask, and (mask or CombineWithColor) images,
1168 * it is pdcolor->phase. For these operations, we
1169 * precompute the color_phase values.
1170 * For strip_tile_rectangle and strip_copy_rop,
1171 * it is the phase arguments of the call, used with
1172 * state_tile. For these operations, we precompute the
1173 * tile_phase values.
1174 *
1175 * Note that control may get here before one or both of
1176 * state_tile or dev_ht has been set.
1177 */
1178 if (state_tile.size.x)
1179 tile_phase.x =
1180 (state.tile_phase.x + x0) % state_tile.size.x;
1181 if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_width)
1182 color_phase.x =
1183 (state.tile_phase.x + x0) %
1184 gs_gstate.dev_ht->lcm_width;
1185 /*
1186 * The true tile height for shifted tiles is not
1187 * size.y: see gxbitmap.h for the computation.
1188 */
1189 if (state_tile.size.y) {
1190 int full_height;
1191
1192 if (state_tile.shift == 0)
1193 full_height = state_tile.size.y;
1194 else
1195 full_height = state_tile.rep_height *
1196 (state_tile.rep_width /
1197 igcd(state_tile.rep_shift,
1198 state_tile.rep_width));
1199 tile_phase.y =
1200 (state.tile_phase.y + y0) % full_height;
1201 }
1202 if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_height)
1203 color_phase.y =
1204 (state.tile_phase.y + y0) %
1205 gs_gstate.dev_ht->lcm_height;
1206 gx_gstate_setscreenphase(&gs_gstate,
1207 -(state.tile_phase.x + x0),
1208 -(state.tile_phase.y + y0),
1209 gs_color_select_all);
1210 continue;
1211 case cmd_op_misc2 >> 4:
1212 switch (op) {
1213 case cmd_opv_set_fill_adjust:
1214 cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1215 cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1216 if_debug2m('L', mem, " (%g,%g)\n",
1217 fixed2float(gs_gstate.fill_adjust.x),
1218 fixed2float(gs_gstate.fill_adjust.y));
1219 continue;
1220 case cmd_opv_set_ctm:
1221 {
1222 gs_matrix mat;
1223
1224 cbp = cmd_read_matrix(&mat, cbp);
1225 if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1226 mat.xx, mat.xy, mat.yx, mat.yy,
1227 mat.tx, mat.ty);
1228 mat.tx -= x0;
1229 mat.ty -= y0;
1230 gs_gstate_setmatrix(&gs_gstate, &mat);
1231 }
1232 continue;
1233 case cmd_opv_set_misc2:
1234 cbuf.ptr = cbp;
1235 code = read_set_misc2(&cbuf, &gs_gstate, ¬es);
1236 cbp = cbuf.ptr;
1237 if (code < 0)
1238 goto out;
1239 continue;
1240 case cmd_opv_set_dash:
1241 {
1242 int nb = *cbp++;
1243 int n = nb & 0x3f;
1244 float dot_length, offset;
1245
1246 cmd_get_value(dot_length, cbp);
1247 cmd_get_value(offset, cbp);
1248 memcpy(dash_pattern, cbp, n * sizeof(float));
1249
1250 gx_set_dash(&gs_gstate.line_params.dash,
1251 dash_pattern, n, offset,
1252 NULL);
1253 gx_set_dash_adapt(&gs_gstate.line_params.dash,
1254 (nb & 0x80) != 0);
1255 gx_set_dot_length(&gs_gstate.line_params,
1256 dot_length,
1257 (nb & 0x40) != 0);
1258 #ifdef DEBUG
1259 if (gs_debug_c('L')) {
1260 int i;
1261
1262 dmprintf4(mem, " dot=%g(mode %d) adapt=%d offset=%g [",
1263 dot_length,
1264 (nb & 0x40) != 0,
1265 (nb & 0x80) != 0, offset);
1266 for (i = 0; i < n; ++i)
1267 dmprintf1(mem, "%g ", dash_pattern[i]);
1268 dmputs(mem, "]\n");
1269 }
1270 #endif
1271 cbp += n * sizeof(float);
1272 }
1273 break;
1274 case cmd_opv_enable_clip:
1275 pcpath = (use_clip ? &clip_path : NULL);
1276 if (pcpath) {
1277 code = gx_cpath_ensure_path_list(pcpath);
1278 if (code < 0)
1279 goto out;
1280 }
1281 clipper_dev_open = false;
1282 if_debug0m('L', mem, "\n");
1283 break;
1284 case cmd_opv_disable_clip:
1285 pcpath = NULL;
1286 clipper_dev_open = false;
1287 if_debug0m('L', mem, "\n");
1288 break;
1289 case cmd_opv_begin_clip:
1290 pcpath = NULL;
1291 clipper_dev_open = false;
1292 in_clip = true;
1293 if_debug0m('L', mem, "\n");
1294 code = gx_cpath_reset(&clip_path);
1295 if (code < 0)
1296 goto out;
1297 gx_cpath_accum_begin(&clip_accum, mem, false);
1298 gx_cpath_accum_set_cbox(&clip_accum,
1299 &target_box);
1300 tdev = (gx_device *)&clip_accum;
1301 clip_save.lop_enabled = state.lop_enabled;
1302 clip_save.dcolor = fill_color;
1303 clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1304 clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1305 /* clip_path should match fill_path, i.e., with fill_adjust applied */
1306 /* If we get here with the fill_adjust = [0, 0], set it to [0.5, 0.5]i */
1307 if (clip_save.fa_save.x == 0 || clip_save.fa_save.y == 0)
1308 gs_gstate.fill_adjust.x = gs_gstate.fill_adjust.y = fixed_half;
1309 /* temporarily set a solid color */
1310 color_set_pure(&fill_color, (gx_color_index)1);
1311 state.lop_enabled = false;
1312 gs_gstate.log_op = lop_default;
1313 break;
1314 case cmd_opv_end_clip:
1315 if_debug0m('L', mem, "\n");
1316 gx_cpath_accum_end(&clip_accum, &clip_path);
1317 tdev = target;
1318 /*
1319 * If the entire band falls within the clip
1320 * path, no clipping is needed.
1321 */
1322 {
1323 gs_fixed_rect cbox;
1324
1325 gx_cpath_inner_box(&clip_path, &cbox);
1326 use_clip =
1327 !(cbox.p.x <= target_box.p.x &&
1328 cbox.q.x >= target_box.q.x &&
1329 cbox.p.y <= target_box.p.y &&
1330 cbox.q.y >= target_box.q.y);
1331 }
1332 pcpath = (use_clip ? &clip_path : NULL);
1333 if (pcpath) {
1334 code = gx_cpath_ensure_path_list(pcpath);
1335 if (code < 0)
1336 goto out;
1337 }
1338 clipper_dev_open = false;
1339 state.lop_enabled = clip_save.lop_enabled;
1340 gs_gstate.log_op =
1341 (state.lop_enabled ? state.lop :
1342 lop_default);
1343 fill_color = clip_save.dcolor;
1344 /* restore the fill_adjust if it was changed by begin_clip */
1345 gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1346 gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1347 in_clip = false;
1348 break;
1349 case cmd_opv_set_color_space:
1350 cbuf.ptr = cbp;
1351 code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1352 pcs = gs_gstate.color[0].color_space;
1353 cbp = cbuf.ptr;
1354 if (code < 0) {
1355 if (code == gs_error_rangecheck)
1356 goto bad_op;
1357 goto out;
1358 }
1359 break;
1360 case cmd_op_fill_rect_hl:
1361 {
1362 gs_fixed_rect rect_hl;
1363
1364 cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1365 if (fill_color.type != gx_dc_type_devn) {
1366 if_debug0m('L', mem, "hl rect fill without devn color\n");
1367 code = gs_note_error(gs_error_typecheck);
1368 goto out;
1369 }
1370 if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1371 state.rect.x, state.rect.y,
1372 state.rect.width,state.rect.height);
1373 rect_hl.p.x = int2fixed(state.rect.x - x0);
1374 rect_hl.p.y = int2fixed(state.rect.y - y0);
1375 rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1376 rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1377 code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1378 &rect_hl, NULL,
1379 &fill_color, NULL);
1380 }
1381 continue;
1382 case cmd_opv_begin_image_rect:
1383 cbuf.ptr = cbp;
1384 code = read_begin_image(&cbuf, &image.c, pcs);
1385 cbp = cbuf.ptr;
1386 if (code < 0)
1387 goto out;
1388 {
1389 uint diff;
1390
1391 cmd_getw(image_rect.p.x, cbp);
1392 cmd_getw(image_rect.p.y, cbp);
1393 cmd_getw(diff, cbp);
1394 image_rect.q.x = image.d.Width - diff;
1395 cmd_getw(diff, cbp);
1396 image_rect.q.y = image.d.Height - diff;
1397 if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1398 image_rect.p.x, image_rect.p.y,
1399 image_rect.q.x, image_rect.q.y);
1400 }
1401 goto ibegin;
1402 case cmd_opv_begin_image:
1403 cbuf.ptr = cbp;
1404 code = read_begin_image(&cbuf, &image.c, pcs);
1405 cbp = cbuf.ptr;
1406 if (code < 0)
1407 goto out;
1408 image_rect.p.x = 0;
1409 image_rect.p.y = 0;
1410 image_rect.q.x = image.d.Width;
1411 image_rect.q.y = image.d.Height;
1412 if_debug2m('L', mem, " size=(%d,%d)",
1413 image.d.Width, image.d.Height);
1414 ibegin: if_debug0m('L', mem, "\n");
1415 {
1416 /* Processing an image operation */
1417 dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1418 image.i4.override_in_smask = 0;
1419 code = (*dev_proc(tdev, begin_typed_image))
1420 (tdev, &gs_gstate, NULL,
1421 (const gs_image_common_t *)&image,
1422 &image_rect, &fill_color, pcpath, mem,
1423 &image_info);
1424 }
1425 if (code < 0)
1426 goto out;
1427 break;
1428 case cmd_opv_image_plane_data:
1429 cmd_getw(data_height, cbp);
1430 if (data_height == 0) {
1431 if_debug0m('L', mem, " done image\n");
1432 code = gx_image_end(image_info, true);
1433 if (code < 0)
1434 goto out;
1435 continue;
1436 }
1437 {
1438 uint flags;
1439 int plane;
1440 uint raster1 = 0xbaadf00d; /* Initialize against indeterminizm. */
1441
1442 cmd_getw(flags, cbp);
1443 for (plane = 0;
1444 plane < image_info->num_planes;
1445 ++plane, flags >>= 1) {
1446 if (flags & 1) {
1447 if (cbuf.end - cbp <
1448 2 * cmd_max_intsize(sizeof(uint))) {
1449 code = top_up_cbuf(&cbuf, &cbp);
1450 if (code < 0)
1451 goto top_up_failed;
1452 }
1453 cmd_getw(planes[plane].raster, cbp) ;
1454 if ((raster1 = planes[plane].raster) != 0)
1455 cmd_getw(data_x, cbp);
1456 } else {
1457 planes[plane].raster = raster1;
1458 }
1459 planes[plane].data_x = data_x;
1460 }
1461 }
1462 goto idata;
1463 case cmd_opv_image_data:
1464 cmd_getw(data_height, cbp);
1465 if (data_height == 0) {
1466 if_debug0m('L', mem, " done image\n");
1467 code = gx_image_end(image_info, true);
1468 if (code < 0)
1469 goto out;
1470 continue;
1471 }
1472 {
1473 uint bytes_per_plane;
1474 int plane;
1475
1476 cmd_getw(bytes_per_plane, cbp);
1477 if_debug2m('L', mem, " height=%u raster=%u\n",
1478 data_height, bytes_per_plane);
1479 for (plane = 0;
1480 plane < image_info->num_planes;
1481 ++plane
1482 ) {
1483 planes[plane].data_x = data_x;
1484 planes[plane].raster = bytes_per_plane;
1485 }
1486 }
1487 idata: data_size = 0;
1488 {
1489 int plane;
1490
1491 for (plane = 0; plane < image_info->num_planes;
1492 ++plane)
1493 data_size += planes[plane].raster;
1494 }
1495 data_size *= data_height;
1496 data_on_heap = 0;
1497 if (cbuf.end - cbp < data_size) {
1498 code = top_up_cbuf(&cbuf, &cbp);
1499 if (code < 0)
1500 goto top_up_failed;
1501 }
1502 if (cbuf.end - cbp >= data_size) {
1503 planes[0].data = cbp;
1504 cbp += data_size;
1505 } else {
1506 uint cleft = cbuf.end - cbp;
1507 uint rleft = data_size - cleft;
1508 byte *rdata;
1509
1510 if (data_size > cbuf.end - cbuf.data) {
1511 /* Allocate a separate buffer. */
1512 rdata = data_on_heap =
1513 gs_alloc_bytes(mem, data_size,
1514 "clist image_data");
1515 if (rdata == 0) {
1516 code = gs_note_error(gs_error_VMerror);
1517 goto out;
1518 }
1519 } else
1520 rdata = cbuf.data;
1521 memmove(rdata, cbp, cleft);
1522 if (sgets(s, rdata + cleft, rleft, &rleft) < 0) {
1523 code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1524 goto out;
1525 }
1526 planes[0].data = rdata;
1527 cbp = cbuf.end; /* force refill */
1528 }
1529 {
1530 int plane;
1531 const byte *data = planes[0].data;
1532
1533 for (plane = 0;
1534 plane < image_info->num_planes;
1535 ++plane
1536 ) {
1537 if (planes[plane].raster == 0)
1538 planes[plane].data = 0;
1539 else {
1540 planes[plane].data = data;
1541 data += planes[plane].raster *
1542 data_height;
1543 }
1544 }
1545 }
1546 #ifdef DEBUG
1547 if (gs_debug_c('L')) {
1548 int plane;
1549
1550 for (plane = 0; plane < image_info->num_planes;
1551 ++plane)
1552 if (planes[plane].data != 0)
1553 cmd_print_bits(mem,
1554 planes[plane].data,
1555 image_rect.q.x -
1556 image_rect.p.x,
1557 data_height,
1558 planes[plane].raster);
1559 }
1560 #endif
1561 code = gx_image_plane_data(image_info, planes,
1562 data_height);
1563 if (code < 0)
1564 gx_image_end(image_info, false);
1565 if (data_on_heap)
1566 gs_free_object(mem, data_on_heap,
1567 "clist image_data");
1568 data_x = 0;
1569 if (code < 0)
1570 goto out;
1571 continue;
1572 case cmd_opv_extend:
1573 switch (*cbp++) {
1574 case cmd_opv_ext_put_params:
1575 if_debug0m('L', mem, "put_params\n");
1576 cbuf.ptr = cbp;
1577 code = read_put_params(&cbuf, &gs_gstate,
1578 cdev, mem);
1579 cbp = cbuf.ptr;
1580 if (code > 0)
1581 break; /* empty list */
1582 if (code < 0)
1583 goto out;
1584 if (playback_action == playback_action_setup)
1585 goto out;
1586 break;
1587 case cmd_opv_ext_create_compositor:
1588 if_debug0m('L', mem, " ext_create_compositor\n");
1589 cbuf.ptr = cbp;
1590 /*
1591 * The screen phase may have been changed during
1592 * the processing of masked images.
1593 */
1594 gx_gstate_setscreenphase(&gs_gstate,
1595 -x0, -y0, gs_color_select_all);
1596 cbp -= 2; /* Step back to simplify the cycle invariant below. */
1597 for (;;) {
1598 /* This internal loop looks ahead for compositor commands and
1599 copies them into a temporary queue. Compositors, which do not paint something,
1600 are marked as idle and later executed with a reduced functionality
1601 for reducing time and memory expense. */
1602 int len;
1603
1604 if (cbp >= cbuf.warn_limit) {
1605 code = top_up_cbuf(&cbuf, &cbp);
1606 if (code < 0)
1607 goto out;
1608 }
1609 if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_create_compositor) {
1610 gs_composite_t *pcomp, *pcomp_opening;
1611 gs_compositor_closing_state closing_state;
1612
1613 cbuf.ptr = cbp += 2;
1614 code = read_create_compositor(&cbuf, mem, &pcomp);
1615 if (code < 0)
1616 goto out;
1617 cbp = cbuf.ptr;
1618 if (pcomp == NULL)
1619 continue;
1620 if (gs_is_pdf14trans_compositor(pcomp) &&
1621 playback_action == playback_action_render_no_pdf14) {
1622 /* free the compositor object */
1623 gs_free_object(mem, pcomp, "read_create_compositor");
1624 pcomp = NULL;
1625 continue;
1626 }
1627 pcomp_opening = pcomp_last;
1628 closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1629 switch(closing_state)
1630 {
1631 default:
1632 code = (int)closing_state;
1633 if (code >= 0)
1634 code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1635 goto out;
1636 case COMP_ENQUEUE:
1637 /* Enqueue. */
1638 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1639 break;
1640 case COMP_EXEC_IDLE:
1641 /* Execute idle. */
1642 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1643 code = execute_compositor_queue(cdev, &target, &tdev,
1644 &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1645 if (code < 0)
1646 goto out;
1647 break;
1648 case COMP_EXEC_QUEUE:
1649 /* The opening command was executed. Execute the queue. */
1650 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1651 code = execute_compositor_queue(cdev, &target, &tdev,
1652 &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1653 if (code < 0)
1654 goto out;
1655 break;
1656 case COMP_REPLACE_PREV:
1657 /* Replace last compositors. */
1658 code = execute_compositor_queue(cdev, &target, &tdev,
1659 &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1660 if (code < 0)
1661 goto out;
1662 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1663 break;
1664 case COMP_REPLACE_CURR:
1665 /* Replace specific compositor. */
1666 code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1667 if (code < 0)
1668 goto out;
1669 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1670 free_compositor(pcomp_opening, mem);
1671 break;
1672 case COMP_DROP_QUEUE:
1673 /* Annihilate the last compositors. */
1674 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1675 code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1676 if (code < 0)
1677 goto out;
1678 break;
1679 case COMP_MARK_IDLE:
1680 /* Mark as idle. */
1681 enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1682 mark_as_idle(pcomp_opening, pcomp);
1683 }
1684 } else if (is_null_compositor_op(cbp, &len)) {
1685 cbuf.ptr = cbp += len;
1686 } else if (cbp[0] == cmd_opv_end_page) {
1687 /* End page, drop the queue. */
1688 code = execute_compositor_queue(cdev, &target, &tdev,
1689 &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1690 if (code < 0)
1691 goto out;
1692 break;
1693 } else if (pcomp_last != NULL &&
1694 pcomp_last->type->procs.is_friendly(pcomp_last, cbp[0], cbp[1])) {
1695 /* Immediately execute friendly commands
1696 inside the compositor lookahead loop.
1697 Currently there are few friendly commands for the pdf14 compositor only
1698 due to the logic defined in c_pdf14trans_is_friendly.
1699 This code duplicates some code portions from the main loop,
1700 but we have no better idea with no slowdown to the main loop.
1701 */
1702 uint cb;
1703
1704 switch (*cbp++) {
1705 case cmd_opv_extend:
1706 switch (*cbp++) {
1707 case cmd_opv_ext_put_halftone:
1708 {
1709 uint ht_size;
1710
1711 enc_u_getw(ht_size, cbp);
1712 code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1713 if (code < 0)
1714 goto out;
1715 }
1716 break;
1717 case cmd_opv_ext_put_ht_seg:
1718 cbuf.ptr = cbp;
1719 code = read_ht_segment(&ht_buff, &cbuf,
1720 &gs_gstate, tdev,
1721 mem);
1722 cbp = cbuf.ptr;
1723 if (code < 0)
1724 goto out;
1725 break;
1726 default:
1727 code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1728 goto out;
1729 }
1730 break;
1731 case cmd_opv_set_misc:
1732 cb = *cbp++;
1733 switch (cb >> 6) {
1734 case cmd_set_misc_map >> 6:
1735 cbuf.ptr = cbp;
1736 code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1737 if (code < 0)
1738 goto out;
1739 cbp = cbuf.ptr;
1740 break;
1741 default:
1742 code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1743 goto out;
1744 }
1745 break;
1746 default:
1747 code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1748 goto out;
1749 }
1750 } else {
1751 /* A drawing command, execute entire queue. */
1752 code = execute_compositor_queue(cdev, &target, &tdev,
1753 &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1754 if (code < 0)
1755 goto out;
1756 break;
1757 }
1758 }
1759 if (pcomp_last != NULL) {
1760 code = gs_note_error(gs_error_unregistered);
1761 goto out;
1762 }
1763 break;
1764 case cmd_opv_ext_put_halftone:
1765 {
1766 uint ht_size;
1767
1768 if_debug0m('L', mem, " ext_put_halftone\n");
1769 enc_u_getw(ht_size, cbp);
1770 code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1771 if (code < 0)
1772 goto out;
1773 }
1774 break;
1775 case cmd_opv_ext_put_ht_seg:
1776 if_debug0m('L', mem, " ext_put_ht_seg\n");
1777 cbuf.ptr = cbp;
1778 code = read_ht_segment(&ht_buff, &cbuf,
1779 &gs_gstate, tdev,
1780 mem);
1781 cbp = cbuf.ptr;
1782 if (code < 0)
1783 goto out;
1784 break;
1785 case cmd_opv_ext_set_color_is_devn:
1786 state.color_is_devn = true;
1787 if_debug0m('L', mem, " ext_set_color_is_devn\n");
1788 break;
1789 case cmd_opv_ext_unset_color_is_devn:
1790 state.color_is_devn = false;
1791 if_debug0m('L', mem, " ext_unset_color_is_devn\n");
1792 break;
1793 case cmd_opv_ext_tile_rect_hl:
1794 /* Strip tile with devn colors */
1795 cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1796 if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1797 state.rect.x, state.rect.y,
1798 state.rect.width,state.rect.height);
1799 code = (*dev_proc(tdev, strip_tile_rect_devn))
1800 (tdev, &state_tile,
1801 state.rect.x - x0, state.rect.y - y0,
1802 state.rect.width, state.rect.height,
1803 &(state.tile_color_devn[0]),
1804 &(state.tile_color_devn[1]),
1805 tile_phase.x, tile_phase.y);
1806 break;
1807 case cmd_opv_ext_put_fill_dcolor:
1808 pdcolor = &fill_color;
1809 goto load_dcolor;
1810 case cmd_opv_ext_put_stroke_dcolor:
1811 pdcolor = &stroke_color;
1812 goto load_dcolor;
1813 case cmd_opv_ext_put_tile_devn_color0:
1814 pdcolor = &set_dev_colors[0];
1815 goto load_dcolor;
1816 case cmd_opv_ext_put_tile_devn_color1:
1817 pdcolor = &set_dev_colors[1];
1818 load_dcolor:{
1819 uint color_size;
1820 int left, offset, l;
1821 const gx_device_color_type_t * pdct;
1822 byte type_and_flag = *cbp++;
1823 byte is_continuation = type_and_flag & 0x80;
1824
1825 if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1826 pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1827 if (pdct == 0) {
1828 code = gs_note_error(gs_error_rangecheck);
1829 goto out;
1830 }
1831 offset = 0;
1832 if (is_continuation)
1833 enc_u_getw(offset, cbp);
1834 enc_u_getw(color_size, cbp);
1835 left = color_size;
1836 if (!left) {
1837 /* We still need to call pdct->read because it may change dev_color.type -
1838 see gx_dc_null_read.*/
1839 code = pdct->read(pdcolor, &gs_gstate,
1840 pdcolor, tdev, offset,
1841 cbp, 0, mem);
1842 if (code < 0)
1843 goto out;
1844 }
1845 while (left) {
1846 if (cbuf.warn_limit - cbp < (int)left) { /* cbp can be past warn_limit */
1847 code = top_up_cbuf(&cbuf, &cbp);
1848 if (code < 0)
1849 goto top_up_failed;
1850 }
1851 l = min(left, cbuf.end - cbp);
1852 code = pdct->read(pdcolor, &gs_gstate,
1853 pdcolor, tdev, offset,
1854 cbp, l, mem);
1855 if (code < 0)
1856 goto out;
1857 l = code;
1858 cbp += l;
1859 offset += l;
1860 left -= l;
1861 }
1862 code = gx_color_load(pdcolor, &gs_gstate,
1863 tdev);
1864 if (code < 0)
1865 goto out;
1866 }
1867 break;
1868 default:
1869 goto bad_op;
1870 }
1871 break;
1872 default:
1873 goto bad_op;
1874 }
1875 continue;
1876 case cmd_op_segment >> 4:
1877 {
1878 int i;
1879 static const byte op_num_operands[] = {
1880 cmd_segment_op_num_operands_values
1881 };
1882 rgapto:
1883 if (!in_path) {
1884 ppos.x = int2fixed(state.rect.x);
1885 ppos.y = int2fixed(state.rect.y);
1886 if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1887 state.rect.y);
1888 notes = sn_none;
1889 in_path = true;
1890 }
1891 for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1892 fixed v;
1893 int b = *cbp;
1894
1895 switch (b >> 5) {
1896 case 0:
1897 case 1:
1898 vs[i++] =
1899 ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1900 ((int)cbp[1] << 5) + (cbp[2] >> 3);
1901 if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1902 cbp += 2;
1903 v = (int)((*cbp & 7) ^ 4) - 4;
1904 break;
1905 case 2:
1906 case 3:
1907 v = (b ^ 0x60) - 0x20;
1908 break;
1909 case 4:
1910 case 5:
1911 /*
1912 * Without the following cast, C's
1913 * brain-damaged coercion rules cause the
1914 * result to be considered unsigned, and not
1915 * sign-extended on machines where
1916 * sizeof(long) > sizeof(int).
1917 */
1918 v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
1919 break;
1920 case 6:
1921 v = (b ^ 0xd0) - 0x10;
1922 vs[i] =
1923 ((v << 8) + cbp[1]) << (_fixed_shift - 2);
1924 if_debug1m('L', mem, " %g", fixed2float(vs[i]));
1925 cbp += 2;
1926 continue;
1927 default /*case 7 */ :
1928 v = (int)(*++cbp ^ 0x80) - 0x80;
1929 for (b = 0; b < sizeof(fixed) - 3; ++b)
1930 v = (v << 8) + *++cbp;
1931 break;
1932 }
1933 cbp += 3;
1934 /* Absent the cast in the next statement, */
1935 /* the Borland C++ 4.5 compiler incorrectly */
1936 /* sign-extends the result of the shift. */
1937 vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
1938 if_debug1m('L', mem, " %g", fixed2float(vs[i]));
1939 }
1940 if_debug0m('L', mem, "\n");
1941 code = clist_decode_segment(&path, op, vs, &ppos,
1942 x0, y0, notes);
1943 if (code < 0)
1944 goto out;
1945 }
1946 continue;
1947 case cmd_op_path >> 4:
1948 {
1949 gx_path fpath;
1950 gx_path *ppath;
1951
1952 if (op == cmd_opv_rgapto)
1953 goto rgapto;
1954
1955 ppath = &path;
1956
1957 if_debug0m('L', mem, "\n");
1958 /* if in clip, flatten path first */
1959 if (in_clip) {
1960 gx_path_init_local(&fpath, mem);
1961 code = gx_path_add_flattened_accurate(&path, &fpath,
1962 gs_currentflat_inline(&gs_gstate),
1963 gs_gstate.accurate_curves);
1964 if (code < 0)
1965 goto out;
1966 ppath = &fpath;
1967 }
1968 switch (op) {
1969 case cmd_opv_fill:
1970 fill_params.rule = gx_rule_winding_number;
1971 goto fill;
1972 case cmd_opv_eofill:
1973 fill_params.rule = gx_rule_even_odd;
1974 fill:
1975 fill_params.adjust = gs_gstate.fill_adjust;
1976 fill_params.flatness = gs_gstate.flatness;
1977 code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
1978 &fill_params, &fill_color, pcpath);
1979 break;
1980 case cmd_opv_fill_stroke:
1981 fill_params.rule = gx_rule_winding_number;
1982 goto fill_stroke;
1983 case cmd_opv_eofill_stroke:
1984 fill_params.rule = gx_rule_even_odd;
1985 fill_stroke:
1986 fill_params.adjust = gs_gstate.fill_adjust;
1987 fill_params.flatness = gs_gstate.flatness;
1988 stroke_params.flatness = gs_gstate.flatness;
1989 stroke_params.traditional = false;
1990 code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
1991 &fill_params, &fill_color,
1992 &stroke_params, &stroke_color, pcpath);
1993 /* if the color is a pattern, it may have had the "is_locked" flag set */
1994 /* clear those now (see do_fill_stroke). */
1995 if (gx_dc_is_pattern1_color(&stroke_color)) {
1996 gs_id id = stroke_color.colors.pattern.p_tile->id;
1997
1998 code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, false);
1999 if (code < 0)
2000 return code; /* unlock failed -- should not happen */
2001 }
2002 if (gx_dc_is_pattern1_color(&fill_color)) {
2003 gs_id id = fill_color.colors.pattern.p_tile->id;
2004
2005 code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, false);
2006 if (code < 0)
2007 return code; /* unlock failed -- should not happen */
2008 }
2009 break;
2010 case cmd_opv_stroke:
2011 stroke_params.flatness = gs_gstate.flatness;
2012 stroke_params.traditional = false;
2013 code = (*dev_proc(tdev, stroke_path))
2014 (tdev, &gs_gstate,
2015 ppath, &stroke_params,
2016 &stroke_color, pcpath);
2017 break;
2018 case cmd_opv_polyfill:
2019 code = clist_do_polyfill(tdev, ppath, &fill_color,
2020 gs_gstate.log_op);
2021 break;
2022 case cmd_opv_fill_trapezoid:
2023 {
2024 gs_fixed_edge left, right;
2025 fixed ybot, ytop;
2026 int options, swap_axes, wh;
2027 fixed x0f;
2028 fixed y0f;
2029 gx_device *ttdev = tdev;
2030
2031 if (pcpath != NULL && !clipper_dev_open) {
2032 gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2033 clipper_dev_open = true;
2034 }
2035 if (clipper_dev_open)
2036 ttdev = (gx_device *)&clipper_dev;
2037 /* Note that if we have transparency present, the clipper device may need to have
2038 its color information updated to be synced up with the target device.
2039 This can occur if we had fills of a path first with a transparency mask to get
2040 an XPS opacity followed by a fill with a transparency group. This occurs in
2041 the XPS gradient code */
2042 if (tdev->color_info.num_components != ttdev->color_info.num_components){
2043 /* Reset the clipper device color information. Only worry about
2044 the information that is used in the trap code */
2045 ttdev->color_info.num_components = tdev->color_info.num_components;
2046 ttdev->color_info.depth = tdev->color_info.depth;
2047 ttdev->color_info.polarity = tdev->color_info.polarity;
2048 memcpy(&(ttdev->color_info.comp_bits),&(tdev->color_info.comp_bits),GX_DEVICE_COLOR_MAX_COMPONENTS);
2049 memcpy(&(ttdev->color_info.comp_shift),&(tdev->color_info.comp_shift),GX_DEVICE_COLOR_MAX_COMPONENTS);
2050 }
2051 cmd_getw(left.start.x, cbp);
2052 cmd_getw(left.start.y, cbp);
2053 cmd_getw(left.end.x, cbp);
2054 cmd_getw(left.end.y, cbp);
2055 cmd_getw(right.start.x, cbp);
2056 cmd_getw(right.start.y, cbp);
2057 cmd_getw(right.end.x, cbp);
2058 cmd_getw(right.end.y, cbp);
2059 cmd_getw(options, cbp);
2060 if (!(options & 4)) {
2061 cmd_getw(ybot, cbp);
2062 cmd_getw(ytop, cbp);
2063 } else
2064 ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2065 swap_axes = options & 1;
2066 wh = swap_axes ? tdev->width : tdev->height;
2067 x0f = int2fixed(swap_axes ? y0 : x0);
2068 y0f = int2fixed(swap_axes ? x0 : y0);
2069 left.start.x -= x0f;
2070 left.start.y -= y0f;
2071 left.end.x -= x0f;
2072 left.end.y -= y0f;
2073 right.start.x -= x0f;
2074 right.start.y -= y0f;
2075 right.end.x -= x0f;
2076 right.end.y -= y0f;
2077 if (options & 2) {
2078 uchar num_components = tdev->color_info.num_components;
2079 frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4];
2080 byte colors_mask, i, j, m = 1;
2081 gs_fill_attributes fa;
2082 gs_fixed_rect clip;
2083 fixed hh = int2fixed(swap_axes ? target->width : target->height);
2084
2085 if (cbuf.end - cbp < 5 * cmd_max_intsize(sizeof(frac31))) {
2086 code = top_up_cbuf(&cbuf, &cbp);
2087 if (code < 0)
2088 goto top_up_failed;
2089 }
2090 cmd_getw(clip.p.x, cbp);
2091 cmd_getw(clip.p.y, cbp);
2092 cmd_getw(clip.q.x, cbp);
2093 cmd_getw(clip.q.y, cbp);
2094 clip.p.x -= x0f;
2095 clip.p.y -= y0f;
2096 clip.q.x -= x0f;
2097 clip.q.y -= y0f;
2098 if (clip.p.y < 0)
2099 clip.p.y = 0;
2100 if (clip.q.y > hh)
2101 clip.q.y = hh;
2102 fa.clip = &clip;
2103 fa.swap_axes = swap_axes;
2104 fa.ht = NULL;
2105 fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */
2106 fa.ystart = ybot - y0f;
2107 fa.yend = ytop - y0f;
2108 cmd_getw(colors_mask, cbp);
2109 for (i = 0; i < 4; i++, m <<= 1) {
2110 if (colors_mask & m) {
2111 if (cbuf.end - cbp < num_components * cmd_max_intsize(sizeof(frac31))) {
2112 code = top_up_cbuf(&cbuf, &cbp);
2113 if (code < 0)
2114 goto top_up_failed;
2115 }
2116 cc[i] = c[i];
2117 for (j = 0; j < num_components; j++)
2118 cmd_getfrac(c[i][j], cbp);
2119 } else
2120 cc[i] = NULL;
2121 }
2122 if (options & 4) {
2123 # if 1 /* Disable to debug gx_fill_triangle_small. */
2124 code = dev_proc(ttdev, fill_linear_color_triangle)(ttdev, &fa,
2125 &left.start, &left.end, &right.start,
2126 cc[0], cc[1], cc[2]);
2127 # else
2128 code = 0;
2129 # endif
2130 if (code == 0) {
2131 /* The target device didn't fill the trapezoid and
2132 requests a decomposition. Subdivide into smaller triangles : */
2133 if (pfs.dev == NULL)
2134 code = gx_init_patch_fill_state_for_clist(tdev, &pfs, mem);
2135 if (code >= 0) {
2136 pfs.dev = ttdev;
2137 pfs.rect = clip; /* fixme: eliminate 'clip'. */
2138 fa.pfs = &pfs;
2139 code = gx_fill_triangle_small(ttdev, &fa,
2140 &left.start, &left.end, &right.start,
2141 cc[0], cc[1], cc[2]);
2142 }
2143 }
2144 } else {
2145 code = dev_proc(ttdev, fill_linear_color_trapezoid)(ttdev, &fa,
2146 &left.start, &left.end, &right.start, &right.end,
2147 cc[0], cc[1], cc[2], cc[3]);
2148 if (code == 0) {
2149 /* Fixme : The target device didn't fill the trapezoid and
2150 requests a decomposition.
2151 Currently we never call it with 4 colors (see gxshade6.c)
2152 and 2 colors must not return 0 - see comment to
2153 dev_t_proc_fill_linear_color_trapezoid in gxdevcli.c .
2154 Must not happen. */
2155 code = gs_note_error(gs_error_unregistered);
2156 }
2157 }
2158 } else
2159 code = gx_default_fill_trapezoid(ttdev, &left, &right,
2160 max(ybot - y0f, fixed_half),
2161 min(ytop - y0f, int2fixed(wh)), swap_axes,
2162 &fill_color, gs_gstate.log_op);
2163 }
2164 break;
2165 default:
2166 goto bad_op;
2167 }
2168 if (ppath != &path)
2169 gx_path_free(ppath, "clist_render_band");
2170 }
2171 if (in_path) { /* path might be empty! */
2172 state.rect.x = fixed2int_var(ppos.x);
2173 state.rect.y = fixed2int_var(ppos.y);
2174 in_path = false;
2175 }
2176 gx_path_free(&path, "clist_render_band");
2177 gx_path_init_local(&path, mem);
2178 if (code < 0)
2179 goto out;
2180 continue;
2181 default:
2182 bad_op:mlprintf5(mem, "Bad op %02x band y0 = %d file pos %"PRId64" buf pos %d/%d\n",
2183 op, y0, stell(s), (int)(cbp - cbuf.data), (int)(cbuf.end - cbuf.data));
2184 {
2185 const byte *pp;
2186
2187 for (pp = cbuf.data; pp < cbuf.end; pp += 10) {
2188 dmlprintf1(mem, "%4d:", (int)(pp - cbuf.data));
2189 dmprintf10(mem, " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2190 pp[0], pp[1], pp[2], pp[3], pp[4],
2191 pp[5], pp[6], pp[7], pp[8], pp[9]);
2192 }
2193 }
2194 code = gs_note_error(gs_error_Fatal);
2195 goto out;
2196 }
2197 if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2198 state.rect.x, state.rect.y, state.rect.width,
2199 state.rect.height);
2200 switch (op >> 4) {
2201 case cmd_op_fill_rect >> 4:
2202 if (state.rect.width == 0 && state.rect.height == 0 &&
2203 state.rect.x == 0 && state.rect.y == 0) {
2204 /* FIXME: This test should be unnecessary. Bug 692076
2205 * is open pending a proper fix. */
2206 code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2207 (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2208 &fill_color));
2209 break;
2210 }
2211 case cmd_op_fill_rect_short >> 4:
2212 case cmd_op_fill_rect_tiny >> 4:
2213 if (!state.lop_enabled) {
2214 code = (*dev_proc(tdev, fill_rectangle))
2215 (tdev, state.rect.x - x0, state.rect.y - y0,
2216 state.rect.width, state.rect.height,
2217 state.colors[1]);
2218 break;
2219 }
2220 source = NULL;
2221 data_x = 0;
2222 raster = 0;
2223 colors[0] = colors[1] = state.colors[1];
2224 log_op = state.lop;
2225 pcolor = colors;
2226 do_rop:if (plane_height == 0) {
2227 code = (*dev_proc(tdev, strip_copy_rop))
2228 (tdev, source, data_x, raster, gx_no_bitmap_id,
2229 pcolor, &state_tile,
2230 (state.tile_colors[0] == gx_no_color_index &&
2231 state.tile_colors[1] == gx_no_color_index ?
2232 NULL : state.tile_colors),
2233 state.rect.x - x0, state.rect.y - y0,
2234 state.rect.width - data_x, state.rect.height,
2235 tile_phase.x, tile_phase.y, log_op);
2236 } else {
2237 code = (*dev_proc(tdev, strip_copy_rop2))
2238 (tdev, source, data_x, raster, gx_no_bitmap_id,
2239 pcolor, &state_tile,
2240 (state.tile_colors[0] == gx_no_color_index &&
2241 state.tile_colors[1] == gx_no_color_index ?
2242 NULL : state.tile_colors),
2243 state.rect.x - x0, state.rect.y - y0,
2244 state.rect.width - data_x, state.rect.height,
2245 tile_phase.x, tile_phase.y, log_op,
2246 plane_height);
2247 plane_height = 0;
2248 }
2249 data_x = 0;
2250 break;
2251 case cmd_op_tile_rect >> 4:
2252 if (state.rect.width == 0 && state.rect.height == 0 &&
2253 state.rect.x == 0 && state.rect.y == 0) {
2254 code = (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &fill_color);
2255 break;
2256 }
2257 case cmd_op_tile_rect_short >> 4:
2258 case cmd_op_tile_rect_tiny >> 4:
2259 /* Currently we don't use lop with tile_rectangle. */
2260 code = (*dev_proc(tdev, strip_tile_rectangle))
2261 (tdev, &state_tile,
2262 state.rect.x - x0, state.rect.y - y0,
2263 state.rect.width, state.rect.height,
2264 state.tile_colors[0], state.tile_colors[1],
2265 tile_phase.x, tile_phase.y);
2266 break;
2267 case cmd_op_copy_mono_planes >> 4:
2268 if (state.lop_enabled) {
2269 pcolor = state.colors;
2270 log_op = state.lop;
2271 goto do_rop;
2272 }
2273 if ((op & cmd_copy_use_tile) || pcpath != NULL) { /*
2274 * This call of copy_mono originated as a call
2275 * of fill_mask.
2276 */
2277 code = gx_image_fill_masked
2278 (tdev, source, data_x, raster, gx_no_bitmap_id,
2279 state.rect.x - x0, state.rect.y - y0,
2280 state.rect.width - data_x, state.rect.height,
2281 &fill_color, 1, gs_gstate.log_op, pcpath);
2282 } else {
2283 if (plane_height == 0) {
2284 code = (*dev_proc(tdev, copy_mono))
2285 (tdev, source, data_x, raster, gx_no_bitmap_id,
2286 state.rect.x - x0, state.rect.y - y0,
2287 state.rect.width - data_x, state.rect.height,
2288 state.colors[0], state.colors[1]);
2289 } else {
2290 code = (*dev_proc(tdev, copy_planes))
2291 (tdev, source, data_x, raster, gx_no_bitmap_id,
2292 state.rect.x - x0, state.rect.y - y0,
2293 state.rect.width - data_x, state.rect.height,
2294 plane_height);
2295 }
2296 }
2297 plane_height = 0;
2298 data_x = 0;
2299 break;
2300 case cmd_op_copy_color_alpha >> 4:
2301 if (state.color_is_alpha) {
2302 /****** CAN'T DO ROP WITH ALPHA ******/
2303 if (state.color_is_devn &&
2304 dev_proc(tdev, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) { /* FIXME */
2305 code = (*dev_proc(tdev, copy_alpha_hl_color))
2306 (tdev, source, data_x, raster, gx_no_bitmap_id,
2307 state.rect.x - x0, state.rect.y - y0,
2308 state.rect.width - data_x, state.rect.height,
2309 &fill_color, depth);
2310 } else {
2311 code = (*dev_proc(tdev, copy_alpha))
2312 (tdev, source, data_x, raster, gx_no_bitmap_id,
2313 state.rect.x - x0, state.rect.y - y0,
2314 state.rect.width - data_x, state.rect.height,
2315 state.colors[1], depth);
2316 }
2317 } else {
2318 if (state.lop_enabled) {
2319 pcolor = NULL;
2320 log_op = state.lop;
2321 goto do_rop;
2322 }
2323 code = (*dev_proc(tdev, copy_color))
2324 (tdev, source, data_x, raster, gx_no_bitmap_id,
2325 state.rect.x - x0, state.rect.y - y0,
2326 state.rect.width - data_x, state.rect.height);
2327 }
2328 data_x = 0;
2329 break;
2330 default: /* can't happen */
2331 goto bad_op;
2332 }
2333 }
2334 /* Clean up before we exit. */
2335 out:
2336 if (ht_buff.pbuff != 0) {
2337 gs_free_object(mem, ht_buff.pbuff, "clist_playback_band(ht_buff)");
2338 ht_buff.pbuff = 0;
2339 ht_buff.pcurr = 0;
2340 }
2341 ht_buff.ht_size = 0;
2342 ht_buff.read_size = 0;
2343
2344 if (pcomp_last != NULL) {
2345 int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &gs_gstate);
2346
2347 if (code == 0)
2348 code = code1;
2349 }
2350 gx_cpath_free(&clip_path, "clist_render_band exit");
2351 gx_path_free(&path, "clist_render_band exit");
2352 if (gs_gstate.pattern_cache != NULL) {
2353 gx_pattern_cache_free(gs_gstate.pattern_cache);
2354 gs_gstate.pattern_cache = NULL;
2355 }
2356 /* The imager state release will decrement the icc link cache. To avoid
2357 race conditions lock the cache */
2358 gx_monitor_enter(cdev->icc_cache_cl->lock);
2359 gs_gstate_release(&gs_gstate);
2360 gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2361 gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2362 if (target != orig_target) {
2363 if (target->rc.ref_count != 1) {
2364 /* This can occur if we are coming from a pattern clist that
2365 includes transparency. In this case, we do not want to
2366 free the compositor since it is really the main target that
2367 we are tiling into. i.e. the tile itself does not have
2368 a pdf14 device, but rather we push a trans group, draw and
2369 then pop the group to properly blend */
2370 rc_decrement(target, "gxclrast(target compositor)");
2371 } else {
2372 /* Ref count was 1. close the device and then free it */
2373 if (target->is_open)
2374 dev_proc(target, close_device)(target);
2375 gs_free_object(target->memory, target, "gxclrast discard compositor");
2376 }
2377 target = orig_target;
2378 }
2379 if (code < 0) {
2380 if (pfs.dev != NULL)
2381 term_patch_fill_state(&pfs);
2382 gx_cpath_free(&clip_path, "clist_playback_band");
2383 if (pcpath != &clip_path)
2384 gx_cpath_free(pcpath, "clist_playback_band");
2385 return_error(code);
2386 }
2387 /* Check whether we have more pages to process. */
2388 if ((playback_action != playback_action_setup &&
2389 (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2390 )
2391 goto in;
2392 if (pfs.dev != NULL)
2393 term_patch_fill_state(&pfs);
2394 gs_free_object(mem, pcs, "clist_playback_band(pcs)");
2395 gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2396 gx_cpath_free(&clip_path, "clist_playback_band");
2397 if (pcpath != &clip_path)
2398 gx_cpath_free(pcpath, "clist_playback_band");
2399 return code;
2400 top_up_failed:
2401 gx_cpath_free(&clip_path, "clist_playback_band");
2402 if (pcpath != &clip_path)
2403 gx_cpath_free(pcpath, "clist_playback_band");
2404 return code;
2405 }
2406
2407 /* ---------------- Individual commands ---------------- */
2408
2409 /*
2410 * These single-use procedures implement a few large individual commands,
2411 * primarily for readability but also to avoid overflowing compilers'
2412 * optimization limits. They all take the command buffer as their first
2413 * parameter (pcb), assume that the current buffer pointer is in pcb->ptr,
2414 * and update it there.
2415 */
2416
2417 static int
read_set_tile_size(command_buf_t * pcb,tile_slot * bits,bool for_pattern)2418 read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern)
2419 {
2420 const byte *cbp = pcb->ptr;
2421 uint rep_width, rep_height;
2422 uint pdepth;
2423 byte bd = *cbp++;
2424
2425 bits->cb_depth = cmd_code_to_depth(bd);
2426 if (for_pattern)
2427 cmd_getw(bits->id, cbp);
2428 cmd_getw(rep_width, cbp);
2429 cmd_getw(rep_height, cbp);
2430 if (bd & 0x20) {
2431 cmd_getw(bits->x_reps, cbp);
2432 bits->width = rep_width * bits->x_reps;
2433 } else {
2434 bits->x_reps = 1;
2435 bits->width = rep_width;
2436 }
2437 if (bd & 0x40) {
2438 cmd_getw(bits->y_reps, cbp);
2439 bits->height = rep_height * bits->y_reps;
2440 } else {
2441 bits->y_reps = 1;
2442 bits->height = rep_height;
2443 }
2444 if (bd & 0x80)
2445 cmd_getw(bits->rep_shift, cbp);
2446 else
2447 bits->rep_shift = 0;
2448 if (bd & 0x10)
2449 bits->num_planes = *cbp++;
2450 else
2451 bits->num_planes = 1;
2452 if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2453 bits->cb_depth, bits->width,
2454 bits->height, rep_width,
2455 rep_height, bits->rep_shift, bits->num_planes);
2456 bits->shift =
2457 (bits->rep_shift == 0 ? 0 :
2458 (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2459 pdepth = bits->cb_depth;
2460 if (bits->num_planes != 1)
2461 pdepth /= bits->num_planes;
2462 bits->cb_raster = bitmap_raster(bits->width * pdepth);
2463 pcb->ptr = cbp;
2464 return 0;
2465 }
2466
2467 static 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)2468 read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
2469 gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot,
2470 gx_device_clist_reader *cdev, gs_memory_t *mem)
2471 {
2472 const byte *cbp = pcb->ptr;
2473 uint rep_width = bits->width / bits->x_reps;
2474 uint rep_height = bits->height / bits->y_reps;
2475 uint index;
2476 ulong offset;
2477 uint width_bits;
2478 uint width_bytes;
2479 uint raster;
2480 uint bytes;
2481 byte *data;
2482 tile_slot *slot;
2483 uint depth = bits->cb_depth;
2484
2485 if (bits->num_planes != 1)
2486 depth /= bits->num_planes;
2487 width_bits = rep_width * depth;
2488
2489 bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2490 compress |
2491 (rep_width < bits->width ?
2492 decompress_spread : 0) |
2493 decompress_elsewhere,
2494 &width_bytes,
2495 (uint *)&raster);
2496
2497 cmd_getw(index, cbp);
2498 cmd_getw(offset, cbp);
2499 if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2500 pcls->tile_index = index;
2501 cdev->tile_table[pcls->tile_index].offset = offset;
2502 slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2503 *pslot = slot;
2504 *slot = *bits;
2505 tile->data = data = (byte *)(slot + 1);
2506 #ifdef DEBUG
2507 slot->index = pcls->tile_index;
2508 #endif
2509 if (compress == cmd_compress_const) {
2510 cbp = cmd_read_data(pcb, data, 1, cbp);
2511 if (width_bytes > 0 && rep_height > 0)
2512 memset(data+1, *data, width_bytes * rep_height - 1);
2513 } else if (compress) {
2514 /*
2515 * Decompress the image data. We'd like to share this code with the
2516 * similar code in copy_*, but right now we don't see how.
2517 */
2518 stream_cursor_read r;
2519 stream_cursor_write w;
2520 /*
2521 * We don't know the data length a priori, so to be conservative, we
2522 * read the uncompressed size.
2523 */
2524 uint cleft = pcb->end - cbp;
2525
2526 if (cleft < bytes && !pcb->end_status) {
2527 uint nread = cbuf_size - cleft;
2528 # ifdef DEBUG
2529 stream_state *st = pcb->s->state;
2530 # endif
2531
2532 # ifdef DEBUG
2533 {
2534 int code = top_up_offset_map(st, pcb->data, cbp, pcb->end);
2535
2536 if (code < 0)
2537 return code;
2538 }
2539 # endif
2540 memmove(pcb->data, cbp, cleft);
2541 pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2542 set_cb_end(pcb, pcb->data + cleft + nread);
2543 cbp = pcb->data;
2544 }
2545 r.ptr = cbp - 1;
2546 r.limit = pcb->end - 1;
2547 w.ptr = data - 1;
2548 w.limit = w.ptr + bytes;
2549 switch (compress) {
2550 case cmd_compress_rle:
2551 {
2552 stream_RLD_state sstate;
2553
2554 clist_rld_init(&sstate);
2555 (*s_RLD_template.process)
2556 ((stream_state *)&sstate, &r, &w, true);
2557 }
2558 break;
2559 case cmd_compress_cfe:
2560 {
2561 stream_CFD_state sstate;
2562
2563 clist_cfd_init(&sstate,
2564 width_bytes << 3 /*width_bits */ ,
2565 rep_height, mem);
2566 (*s_CFD_template.process)
2567 ((stream_state *)&sstate, &r, &w, true);
2568 (*s_CFD_template.release)
2569 ((stream_state *)&sstate);
2570 }
2571 break;
2572 default:
2573 return_error(gs_error_unregistered);
2574 }
2575 cbp = r.ptr + 1;
2576 } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->cb_raster) {
2577 cbp = cmd_read_short_bits(pcb, data, bytes,
2578 width_bytes, rep_height * bits->num_planes,
2579 bits->cb_raster, cbp);
2580 } else {
2581 cbp = cmd_read_data(pcb, data, bytes, cbp);
2582 }
2583 if (bits->width > rep_width)
2584 bits_replicate_horizontally(data,
2585 rep_width * depth, rep_height * bits->num_planes,
2586 bits->cb_raster,
2587 bits->width * depth,
2588 bits->cb_raster);
2589 if (bits->height > rep_height)
2590 bits_replicate_vertically(data,
2591 rep_height, bits->cb_raster,
2592 bits->height);
2593 #ifdef DEBUG
2594 if (gs_debug_c('L'))
2595 cmd_print_bits(mem, data, bits->width, bits->height, bits->cb_raster);
2596 #endif
2597 pcb->ptr = cbp;
2598 return 0;
2599 }
2600
2601 /* if necessary, allocate a buffer to hold a serialized halftone */
2602 static int
read_alloc_ht_buff(ht_buff_t * pht_buff,uint ht_size,gs_memory_t * mem)2603 read_alloc_ht_buff(ht_buff_t * pht_buff, uint ht_size, gs_memory_t * mem)
2604 {
2605 /* free the existing buffer, if any (usually none) */
2606 if (pht_buff->pbuff != 0) {
2607 gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2608 pht_buff->pbuff = 0;
2609 }
2610
2611 /*
2612 * If the serialized halftone fits in the command buffer, no
2613 * additional buffer is required.
2614 */
2615 if (ht_size > cbuf_ht_seg_max_size) {
2616 pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2617 if (pht_buff->pbuff == 0)
2618 return_error(gs_error_VMerror);
2619 }
2620 pht_buff->ht_size = ht_size;
2621 pht_buff->read_size = 0;
2622 pht_buff->pcurr = pht_buff->pbuff;
2623 return 0;
2624 }
2625
2626 /* read a halftone segment; if it is the final segment, build the halftone */
2627 static int
read_ht_segment(ht_buff_t * pht_buff,command_buf_t * pcb,gs_gstate * pgs,gx_device * dev,gs_memory_t * mem)2628 read_ht_segment(
2629 ht_buff_t * pht_buff,
2630 command_buf_t * pcb,
2631 gs_gstate * pgs,
2632 gx_device * dev,
2633 gs_memory_t * mem )
2634 {
2635 const byte * cbp = pcb->ptr;
2636 const byte * pbuff = 0;
2637 uint ht_size = pht_buff->ht_size, seg_size;
2638 int code = 0;
2639
2640 /* get the segment size; refill command buffer if necessary */
2641 enc_u_getw(seg_size, cbp);
2642 if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2643 code = top_up_cbuf(pcb, &cbp);
2644 if (code < 0)
2645 return code;
2646 if (pcb->end - cbp < (int)seg_size) {
2647 emprintf(mem, " *** ht segment size doesn't fit in buffer ***\n");
2648 return_error(gs_error_unknownerror);
2649 }
2650 }
2651
2652 if (pht_buff->pbuff == 0) {
2653 /* if not separate buffer, must be only one segment */
2654 if (seg_size != ht_size)
2655 return_error(gs_error_unknownerror);
2656 pbuff = cbp;
2657 } else {
2658 if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2659 return_error(gs_error_unknownerror);
2660 memcpy(pht_buff->pcurr, cbp, seg_size);
2661 pht_buff->pcurr += seg_size;
2662 if ((pht_buff->read_size += seg_size) == ht_size)
2663 pbuff = pht_buff->pbuff;
2664 }
2665
2666 /* if everything has been read, convert back to a halftone */
2667 if (pbuff != 0) {
2668 code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2669
2670 /* release any buffered information */
2671 if (pht_buff->pbuff != 0) {
2672 gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2673 pht_buff->pbuff = 0;
2674 pht_buff->pcurr = 0;
2675 }
2676 pht_buff->ht_size = 0;
2677 pht_buff->read_size = 0;
2678 }
2679
2680 /* update the command buffer ponter */
2681 pcb->ptr = cbp + seg_size;
2682
2683 return code;
2684 }
2685
2686 static int
read_set_misc2(command_buf_t * pcb,gs_gstate * pgs,segment_notes * pnotes)2687 read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2688 {
2689 const byte *cbp = pcb->ptr;
2690 uint mask, cb;
2691
2692 cmd_getw(mask, cbp);
2693 if (mask & cap_join_known) {
2694 cb = *cbp++;
2695 pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2696 pgs->line_params.join = (gs_line_join)(cb & 7);
2697 if_debug2m('L', pgs->memory, " start_cap=%d join=%d\n",
2698 pgs->line_params.start_cap, pgs->line_params.join);
2699 cb = *cbp++;
2700 pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2701 pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2702 if_debug2m('L', pgs->memory, "end_cap=%d dash_cap=%d\n",
2703 pgs->line_params.end_cap, pgs->line_params.dash_cap);
2704 }
2705 if (mask & cj_ac_sa_known) {
2706 cb = *cbp++;
2707 pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2708 pgs->accurate_curves = (cb & 2) != 0;
2709 pgs->stroke_adjust = cb & 1;
2710 if_debug3m('L', pgs->memory, " CJ=%d AC=%d SA=%d\n",
2711 pgs->line_params.curve_join, pgs->accurate_curves,
2712 pgs->stroke_adjust);
2713 }
2714 if (mask & flatness_known) {
2715 cmd_get_value(pgs->flatness, cbp);
2716 if_debug1m('L', pgs->memory, " flatness=%g\n", pgs->flatness);
2717 }
2718 if (mask & line_width_known) {
2719 float width;
2720
2721 cmd_get_value(width, cbp);
2722 if_debug1m('L', pgs->memory, " line_width=%g\n", width);
2723 gx_set_line_width(&pgs->line_params, width);
2724 }
2725 if (mask & miter_limit_known) {
2726 float limit;
2727
2728 cmd_get_value(limit, cbp);
2729 if_debug1m('L', pgs->memory, " miter_limit=%g\n", limit);
2730 gx_set_miter_limit(&pgs->line_params, limit);
2731 }
2732 if (mask & op_bm_tk_known) {
2733 cb = *cbp++;
2734 pgs->blend_mode = cb >> 3;
2735 pgs->text_knockout = cb & 1;
2736 /* the following usually have no effect; see gxclpath.c */
2737 cb = *cbp++;
2738 pgs->overprint_mode = (cb >> 2) & 1;
2739 pgs->stroke_overprint = (cb >> 1) & 1;
2740 pgs->overprint = cb & 1;
2741 cb = *cbp++;
2742 pgs->renderingintent = cb;
2743 if_debug6m('L', pgs->memory, " BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2744 pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2745 pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2746 }
2747 if (mask & segment_notes_known) {
2748 cb = *cbp++;
2749 *pnotes = (segment_notes)(cb & 0x3f);
2750 if_debug1m('L', pgs->memory, " notes=%d\n", *pnotes);
2751 }
2752 if (mask & opacity_alpha_known) {
2753 cmd_get_value(pgs->opacity.alpha, cbp);
2754 if_debug1m('L', pgs->memory, " opacity.alpha=%g\n", pgs->opacity.alpha);
2755 }
2756 if (mask & shape_alpha_known) {
2757 cmd_get_value(pgs->shape.alpha, cbp);
2758 if_debug1m('L', pgs->memory, " shape.alpha=%g\n", pgs->shape.alpha);
2759 }
2760 if (mask & alpha_known) {
2761 cmd_get_value(pgs->alpha, cbp);
2762 if_debug1m('L', pgs->memory, " alpha=%u\n", pgs->alpha);
2763 }
2764 pcb->ptr = cbp;
2765 return 0;
2766 }
2767
2768 static int
read_set_color_space(command_buf_t * pcb,gs_gstate * pgs,gx_device_clist_reader * cdev,gs_memory_t * mem)2769 read_set_color_space(command_buf_t *pcb, gs_gstate *pgs,
2770 gx_device_clist_reader *cdev, gs_memory_t *mem)
2771 {
2772 const byte *cbp = pcb->ptr;
2773 byte b = *cbp++;
2774 int index = b >> 4;
2775 gs_color_space *pcs;
2776 int code = 0;
2777 cmm_profile_t *picc_profile;
2778 clist_icc_color_t icc_information;
2779
2780 if_debug3m('L', mem, " %d%s%s\n", index,
2781 (b & 8 ? " (indexed)" : ""),
2782 (b & 4 ? "(proc)" : ""));
2783 /* They all store the ICC information. Even if it is NULL
2784 it is used in the ICC case to avoid reading from the
2785 serialized profile data which is stored elsewhere in the
2786 clist. Hence we avoid jumping around in the file. */
2787 memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2788 cbp = cbp + sizeof(clist_icc_color_t);
2789 switch (index) {
2790 case gs_color_space_index_DeviceGray:
2791 pcs = gs_cspace_new_DeviceGray(mem);
2792 break;
2793 case gs_color_space_index_DeviceRGB:
2794 pcs = gs_cspace_new_DeviceRGB(mem);
2795 break;
2796 case gs_color_space_index_DeviceCMYK:
2797 pcs = gs_cspace_new_DeviceCMYK(mem);
2798 break;
2799 case gs_color_space_index_ICC:
2800 /* build the color space object */
2801 code = gs_cspace_build_ICC(&pcs, NULL, mem);
2802 /* Don't bother getting the ICC stuff from the clist yet */
2803 picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2804 if (picc_profile == NULL)
2805 return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2806 picc_profile->num_comps = icc_information.icc_num_components;
2807 picc_profile->hashcode = icc_information.icc_hash;
2808 picc_profile->hash_is_valid = true;
2809 picc_profile->islab = icc_information.is_lab;
2810 picc_profile->default_match = icc_information.default_match;
2811 picc_profile->data_cs = icc_information.data_cs;
2812 /* Store the clist reader address in the profile
2813 structure so that we can get to the buffer
2814 data if we really neeed it. Ideally, we
2815 will use a cached link and only access this once. */
2816 picc_profile->dev = (gx_device*) cdev;
2817 /* Assign it to the colorspace */
2818 code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2819 /* And we no longer need our reference to the profile */
2820 gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2821 break;
2822 default:
2823 code = gs_note_error(gs_error_rangecheck); /* others are NYI */
2824 goto out;
2825 }
2826
2827 if (pcs == NULL) {
2828 code = gs_note_error(gs_error_VMerror);
2829 goto out;
2830 }
2831
2832 if (b & 8) {
2833 bool use_proc = (b & 4) != 0;
2834 int hival;
2835 int num_values;
2836 byte *data;
2837 uint data_size;
2838 gs_color_space *pcs_indexed;
2839
2840 pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2841 if (pcs_indexed == 0) {
2842 rc_decrement_cs(pcs, "read_set_color_space");
2843 code = gs_note_error(gs_error_VMerror);
2844 goto out;
2845 }
2846 pcs_indexed->base_space = pcs;
2847 pcs = pcs_indexed;
2848 pcs->params.indexed.use_proc = 0;
2849 pcs->params.indexed.lookup.table.data = 0;
2850 pcs->params.indexed.lookup.table.size = 0;
2851 cmd_getw(hival, cbp);
2852 pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2853 num_values = (hival + 1) * pcs->params.indexed.n_comps;
2854 if (use_proc) {
2855 gs_indexed_map *map;
2856
2857 code = alloc_indexed_map(&map, num_values, mem, "indexed map");
2858 if (code < 0) {
2859 rc_decrement_cs(pcs, "read_set_color_space");
2860 goto out;
2861 }
2862 map->proc.lookup_index = lookup_indexed_map;
2863 pcs->params.indexed.lookup.map = map;
2864 data = (byte *)map->values;
2865 data_size = num_values * sizeof(map->values[0]);
2866 } else {
2867 byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2868
2869 if (table == 0) {
2870 code = gs_note_error(gs_error_VMerror);
2871 rc_decrement_cs(pcs, "read_set_color_space");
2872 goto out;
2873 }
2874 pcs->params.indexed.lookup.table.data = table;
2875 pcs->params.indexed.lookup.table.size = num_values;
2876 data = table;
2877 data_size = num_values;
2878 }
2879 cbp = cmd_read_data(pcb, data, data_size, cbp);
2880 pcs->params.indexed.hival = hival;
2881 pcs->params.indexed.use_proc = use_proc;
2882 }
2883
2884 /* Release reference to old color space before installing new one. */
2885 if (pgs->color[0].color_space != NULL)
2886 rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2887 pgs->color[0].color_space = pcs;
2888 out:
2889 pcb->ptr = cbp;
2890 return code;
2891 }
2892
2893 static int
read_begin_image(command_buf_t * pcb,gs_image_common_t * pic,gs_color_space * pcs)2894 read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2895 gs_color_space *pcs)
2896 {
2897 uint index = *(pcb->ptr)++;
2898 const gx_image_type_t *image_type = gx_image_type_table[index];
2899 stream s;
2900 int code;
2901
2902 /* This is sloppy, but we don't have enough information to do better. */
2903 code = top_up_cbuf(pcb, &pcb->ptr);
2904 if (code < 0)
2905 return code;
2906 s_init(&s, NULL);
2907 sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2908 code = image_type->sget(pic, &s, pcs);
2909 pcb->ptr = sbufptr(&s);
2910 return code;
2911 }
2912
2913 static int
read_put_params(command_buf_t * pcb,gs_gstate * pgs,gx_device_clist_reader * cdev,gs_memory_t * mem)2914 read_put_params(command_buf_t *pcb, gs_gstate *pgs,
2915 gx_device_clist_reader *cdev, gs_memory_t *mem)
2916 {
2917 const byte *cbp = pcb->ptr;
2918 gs_c_param_list param_list;
2919 uint cleft;
2920 uint rleft;
2921 bool alloc_data_on_heap = false;
2922 byte *param_buf;
2923 uint param_length;
2924 int code;
2925
2926 cmd_get_value(param_length, cbp);
2927 if_debug1m('L', mem, " length=%d\n", param_length);
2928 if (param_length == 0) {
2929 code = 1; /* empty list */
2930 goto out;
2931 }
2932
2933 /* Make sure entire serialized param list is in cbuf */
2934 /* + force void* alignment */
2935 code = top_up_cbuf(pcb, &cbp);
2936 if (code < 0)
2937 return code;
2938 if (pcb->end - cbp >= param_length) {
2939 param_buf = (byte *)cbp;
2940 cbp += param_length;
2941 } else {
2942 /* NOTE: param_buf must be maximally aligned */
2943 param_buf = gs_alloc_bytes(mem, param_length,
2944 "clist put_params");
2945 if (param_buf == 0) {
2946 code = gs_note_error(gs_error_VMerror);
2947 goto out;
2948 }
2949 alloc_data_on_heap = true;
2950 cleft = pcb->end - cbp;
2951 rleft = param_length - cleft;
2952 memmove(param_buf, cbp, cleft);
2953 pcb->end_status = sgets(pcb->s, param_buf + cleft, rleft, &rleft);
2954 cbp = pcb->end; /* force refill */
2955 }
2956
2957 /*
2958 * Create a gs_c_param_list & expand into it.
2959 * NB that gs_c_param_list doesn't copy objects into
2960 * it, but rather keeps *pointers* to what's passed.
2961 * That's OK because the serialized format keeps enough
2962 * space to hold expanded versions of the structures,
2963 * but this means we cannot deallocate source buffer
2964 * until the gs_c_param_list is deleted.
2965 */
2966 gs_c_param_list_write(¶m_list, mem);
2967 code = gs_param_list_unserialize
2968 ( (gs_param_list *)¶m_list, param_buf );
2969 if (code >= 0 && code != param_length)
2970 code = gs_error_unknownerror; /* must match */
2971 if (code >= 0) {
2972 gs_c_param_list_read(¶m_list);
2973 code = gs_gstate_putdeviceparams(pgs, (gx_device *)cdev,
2974 (gs_param_list *)¶m_list);
2975 }
2976 gs_c_param_list_release(¶m_list);
2977 if (alloc_data_on_heap)
2978 gs_free_object(mem, param_buf, "clist put_params");
2979
2980 out:
2981 pcb->ptr = cbp;
2982 return code;
2983 }
2984
2985 /*
2986 * Read a "create_compositor" command, and execute the command.
2987 *
2988 * This code assumes that a the largest create compositor command,
2989 * including the compositor name size, is smaller than the data buffer
2990 * size. This assumption is inherent in the basic design of the coding
2991 * and the de-serializer interface, as no length field is provided.
2992 *
2993 * At the time of this writing, no compositor violates this assumption.
2994 * The largest create_compositor is currently 1275 bytes, while the command
2995 * data buffer is 4096 bytes.
2996 *
2997 * In the event that this assumption is violated, a change in the encoding
2998 * would be called for.
2999 *
3000 * See comment in gdevp14.c c_pdf14trans_read PDF14_BEGIN_TRANS_MASK case.
3001 */
3002 extern_gs_find_compositor();
3003
3004 static int
read_create_compositor(command_buf_t * pcb,gs_memory_t * mem,gs_composite_t ** ppcomp)3005 read_create_compositor(
3006 command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp)
3007 {
3008 const byte * cbp = pcb->ptr;
3009 int comp_id = 0, code = 0;
3010 const gs_composite_type_t * pcomp_type = 0;
3011
3012 /* fill the command buffer (see comment above) */
3013 if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3014 code = top_up_cbuf(pcb, &cbp);
3015 if (code < 0)
3016 return code;
3017 }
3018
3019 /* find the appropriate compositor method vector */
3020 comp_id = *cbp++;
3021 if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3022 return_error(gs_error_unknownerror);
3023
3024 /* de-serialize the compositor */
3025 code = pcomp_type->procs.read(ppcomp, cbp, pcb->end - cbp, mem);
3026
3027 /* If we read more than the maximum expected, return a rangecheck error */
3028 if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3029 return_error(gs_error_rangecheck);
3030
3031 if (code > 0)
3032 cbp += code;
3033 pcb->ptr = cbp;
3034 return code;
3035 }
3036
apply_create_compositor(gx_device_clist_reader * cdev,gs_gstate * pgs,gs_memory_t * mem,gs_composite_t * pcomp,int x0,int y0,gx_device ** ptarget)3037 static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs,
3038 gs_memory_t *mem, gs_composite_t *pcomp,
3039 int x0, int y0, gx_device **ptarget)
3040 {
3041 gx_device *tdev = *ptarget;
3042 int code;
3043
3044 code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3045 if (code < 0)
3046 return code;
3047 /*
3048 * Apply the compositor to the target device; note that this may
3049 * change the target device.
3050 */
3051 code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3052 if (code >= 0 && tdev != *ptarget) {
3053 /* If we created a new compositor here, then that new compositor should
3054 * become the device to which we send all future drawing requests. If
3055 * the above create_compositor call found an existing compositor
3056 * already in the chain of devices (such as might happen when we are
3057 * playing back a clist based pattern, and the top device is a clip
3058 * device that forwards to a pdf14 device), then we'll just reuse
3059 * that one. We do not want to send new drawing operations to the
3060 * compositor, as that will sidestep the clipping. We therefore check
3061 * the reference count to see if this is a new device or not. */
3062 if (tdev->rc.ref_count == 1)
3063 *ptarget = tdev;
3064 }
3065 if (code < 0)
3066 return code;
3067
3068 /* Perform any updates for the clist device required */
3069 code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3070 (gx_device *)cdev, tdev, pgs, mem);
3071 if (code < 0)
3072 return code;
3073
3074 /* free the compositor object */
3075 gs_free_object(mem, pcomp, "read_create_compositor");
3076
3077 return code;
3078 }
3079
3080 /* ---------------- Utilities ---------------- */
3081
3082 /* Read and unpack a short bitmap */
3083 /*
3084 * The 'raster' in the dest buffer may be larger than the 'width_bytes'
3085 * in the src, so after reading we memmove data down to the proper
3086 * alignment from the last line backwards.
3087 * THIS RELIES on width_bytes <= raster to work.
3088 */
3089 static const byte *
cmd_read_short_bits(command_buf_t * pcb,byte * data,int tot_bytes,int width_bytes,int height,uint raster,const byte * cbp)3090 cmd_read_short_bits(command_buf_t *pcb, byte *data, int tot_bytes,
3091 int width_bytes, int height, uint raster, const byte *cbp)
3092 {
3093 /* Note the following may read from the file past the end of the buffer */
3094 /* leaving cbp at pcb->end. No further reading using cbp can be done */
3095 /* without top_up_cbuf to reload the buffer. */
3096 cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3097
3098 /* if needed, adjust buffer contents for dest raster > width_bytes */
3099 if (width_bytes < raster) {
3100 const byte *pdata = data /*src*/ + width_bytes * height;
3101 byte *udata = data /*dest*/ + height * raster;
3102
3103 while (--height > 0) { /* don't need to move the first line to itself */
3104 udata -= raster, pdata -= width_bytes;
3105 switch (width_bytes) {
3106 default:
3107 memmove(udata, pdata, width_bytes);
3108 break;
3109 case 6:
3110 udata[5] = pdata[5];
3111 case 5:
3112 udata[4] = pdata[4];
3113 case 4:
3114 udata[3] = pdata[3];
3115 case 3:
3116 udata[2] = pdata[2];
3117 case 2:
3118 udata[1] = pdata[1];
3119 case 1:
3120 udata[0] = pdata[0];
3121 case 0:; /* shouldn't happen */
3122 }
3123 }
3124 }
3125 return cbp;
3126 }
3127
3128 /* Read a rectangle. */
3129 static const byte *
cmd_read_rect(int op,gx_cmd_rect * prect,const byte * cbp)3130 cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3131 {
3132 cmd_getw(prect->x, cbp);
3133 if (op & 0xf)
3134 prect->y += ((op >> 2) & 3) - 2;
3135 else {
3136 cmd_getw(prect->y, cbp);
3137 }
3138 cmd_getw(prect->width, cbp);
3139 if (op & 0xf)
3140 prect->height += (op & 3) - 2;
3141 else {
3142 cmd_getw(prect->height, cbp);
3143 }
3144 return cbp;
3145 }
3146
3147 /*
3148 * Select a map for loading with data.
3149 *
3150 * This routine has three outputs:
3151 * *pmdata - points to the map data.
3152 * *pcomp_num - points to a component number if the map is a transfer
3153 * map which has been set via the setcolortransfer operator.
3154 * A. value of NULL indicates that no component number is to
3155 * be sent for this map.
3156 * *pcount - the size of the map (in bytes).
3157 */
3158 static int
cmd_select_map(cmd_map_index map_index,cmd_map_contents cont,gs_gstate * pgs,int ** pcomp_num,frac ** pmdata,uint * pcount,gs_memory_t * mem)3159 cmd_select_map(cmd_map_index map_index, cmd_map_contents cont,
3160 gs_gstate * pgs, int ** pcomp_num, frac ** pmdata,
3161 uint * pcount, gs_memory_t * mem)
3162 {
3163 gx_transfer_map *map;
3164 gx_transfer_map **pmap;
3165 const char *cname;
3166
3167 *pcomp_num = NULL; /* Only used for color transfer maps */
3168 switch (map_index) {
3169 case cmd_map_transfer:
3170 if_debug0m('L', mem, " transfer");
3171 rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3172 &st_transfer_map, mem, return_error(gs_error_VMerror),
3173 "cmd_select_map(default_transfer)");
3174 map = pgs->set_transfer.gray;
3175 /* Release all current maps */
3176 rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3177 pgs->set_transfer.red = NULL;
3178 pgs->set_transfer.red_component_num = -1;
3179 rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3180 pgs->set_transfer.green = NULL;
3181 pgs->set_transfer.green_component_num = -1;
3182 rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3183 pgs->set_transfer.blue = NULL;
3184 pgs->set_transfer.blue_component_num = -1;
3185 goto transfer2;
3186 case cmd_map_transfer_0:
3187 pmap = &pgs->set_transfer.red;
3188 *pcomp_num = &pgs->set_transfer.red_component_num;
3189 goto transfer1;
3190 case cmd_map_transfer_1:
3191 pmap = &pgs->set_transfer.green;
3192 *pcomp_num = &pgs->set_transfer.green_component_num;
3193 goto transfer1;
3194 case cmd_map_transfer_2:
3195 pmap = &pgs->set_transfer.blue;
3196 *pcomp_num = &pgs->set_transfer.blue_component_num;
3197 goto transfer1;
3198 case cmd_map_transfer_3:
3199 pmap = &pgs->set_transfer.gray;
3200 *pcomp_num = &pgs->set_transfer.gray_component_num;
3201 transfer1: if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3202 rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3203 return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3204 map = *pmap;
3205
3206 transfer2: if (cont != cmd_map_other) {
3207 gx_set_identity_transfer(map);
3208 *pmdata = 0;
3209 *pcount = 0;
3210 return 0;
3211 }
3212 break;
3213 case cmd_map_black_generation:
3214 if_debug0m('L', mem, " black generation");
3215 pmap = &pgs->black_generation;
3216 cname = "cmd_select_map(black generation)";
3217 goto alloc;
3218 case cmd_map_undercolor_removal:
3219 if_debug0m('L', mem, " undercolor removal");
3220 pmap = &pgs->undercolor_removal;
3221 cname = "cmd_select_map(undercolor removal)";
3222 alloc: if (cont == cmd_map_none) {
3223 rc_decrement(*pmap, cname);
3224 *pmap = 0;
3225 *pmdata = 0;
3226 *pcount = 0;
3227 return 0;
3228 }
3229 rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3230 mem, return_error(gs_error_VMerror), cname);
3231 map = *pmap;
3232 if (cont == cmd_map_identity) {
3233 gx_set_identity_transfer(map);
3234 *pmdata = 0;
3235 *pcount = 0;
3236 return 0;
3237 }
3238 break;
3239 default:
3240 *pmdata = 0;
3241 return 0;
3242 }
3243 map->proc = gs_mapped_transfer;
3244 *pmdata = map->values;
3245 *pcount = sizeof(map->values);
3246 return 0;
3247 }
3248
3249 /* Create a device halftone for the imager if necessary. */
3250 static int
cmd_create_dev_ht(gx_device_halftone ** ppdht,gs_memory_t * mem)3251 cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
3252 {
3253 gx_device_halftone *pdht = *ppdht;
3254
3255 if (pdht == 0) {
3256 rc_header rc;
3257
3258 rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
3259 return_error(gs_error_VMerror),
3260 "cmd_create_dev_ht");
3261 rc = pdht->rc;
3262 memset(pdht, 0, sizeof(*pdht));
3263 pdht->rc = rc;
3264 *ppdht = pdht;
3265 }
3266 return 0;
3267 }
3268
3269 /* Resize the halftone components array if necessary. */
3270 static int
cmd_resize_halftone(gx_device_halftone ** ppdht,uint num_comp,gs_memory_t * mem)3271 cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
3272 gs_memory_t * mem)
3273 {
3274 int code = cmd_create_dev_ht(ppdht, mem);
3275 gx_device_halftone *pdht = *ppdht;
3276
3277 if (code < 0)
3278 return code;
3279 if (num_comp != pdht->num_comp) {
3280 gx_ht_order_component *pcomp;
3281
3282 /*
3283 * We must be careful not to shrink or free the components array
3284 * before releasing any relevant elements.
3285 */
3286 if (num_comp < pdht->num_comp) {
3287 uint i;
3288
3289 /* Don't release the default order. */
3290 for (i = pdht->num_comp; i-- > num_comp;)
3291 if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
3292 gx_ht_order_release(&pdht->components[i].corder, mem, true);
3293 if (num_comp == 0) {
3294 gs_free_object(mem, pdht->components, "cmd_resize_halftone");
3295 pcomp = 0;
3296 } else {
3297 pcomp = gs_resize_object(mem, pdht->components, num_comp,
3298 "cmd_resize_halftone");
3299 if (pcomp == 0) {
3300 pdht->num_comp = num_comp; /* attempt consistency */
3301 return_error(gs_error_VMerror);
3302 }
3303 }
3304 } else {
3305 /* num_comp > pdht->num_comp */
3306 if (pdht->num_comp == 0)
3307 pcomp = gs_alloc_struct_array(mem, num_comp,
3308 gx_ht_order_component,
3309 &st_ht_order_component_element,
3310 "cmd_resize_halftone");
3311 else
3312 pcomp = gs_resize_object(mem, pdht->components, num_comp,
3313 "cmd_resize_halftone");
3314 if (pcomp == 0)
3315 return_error(gs_error_VMerror);
3316 memset(&pcomp[pdht->num_comp], 0,
3317 sizeof(*pcomp) * (num_comp - pdht->num_comp));
3318 }
3319 pdht->num_comp = num_comp;
3320 pdht->components = pcomp;
3321 }
3322 return 0;
3323 }
3324
3325 /* ------ Path operations ------ */
3326
3327 /* Decode a path segment. */
3328 static int
clist_decode_segment(gx_path * ppath,int op,fixed vs[6],gs_fixed_point * ppos,int x0,int y0,segment_notes notes)3329 clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
3330 gs_fixed_point * ppos, int x0, int y0, segment_notes notes)
3331 {
3332 fixed px = ppos->x - int2fixed(x0);
3333 fixed py = ppos->y - int2fixed(y0);
3334 int code;
3335
3336 #define A vs[0]
3337 #define B vs[1]
3338 #define C vs[2]
3339 #define D vs[3]
3340 #define E vs[4]
3341 #define F vs[5]
3342
3343 switch (op) {
3344 case cmd_opv_rmoveto:
3345 code = gx_path_add_point(ppath, px += A, py += B);
3346 break;
3347 case cmd_opv_rlineto:
3348 code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3349 break;
3350 case cmd_opv_rgapto:
3351 code = gx_path_add_gap_notes(ppath, px += A, py += B, notes);
3352 break;
3353 case cmd_opv_hlineto:
3354 code = gx_path_add_line_notes(ppath, px += A, py, notes);
3355 break;
3356 case cmd_opv_vlineto:
3357 code = gx_path_add_line_notes(ppath, px, py += A, notes);
3358 break;
3359 case cmd_opv_rmlineto:
3360 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3361 break;
3362 code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3363 break;
3364 case cmd_opv_rm2lineto:
3365 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3366 (code = gx_path_add_line_notes(ppath, px += C, py += D,
3367 notes)) < 0
3368 )
3369 break;
3370 code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3371 break;
3372 case cmd_opv_rm3lineto:
3373 if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3374 (code = gx_path_add_line_notes(ppath, px += C, py += D,
3375 notes)) < 0 ||
3376 (code = gx_path_add_line_notes(ppath, px += E, py += F,
3377 notes)) < 0
3378 )
3379 break;
3380 code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3381 break;
3382 case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3383 rrc: E += (C += A);
3384 F += (D += B);
3385 curve: code = gx_path_add_curve_notes(ppath, px + A, py + B,
3386 px + C, py + D,
3387 px + E, py + F, notes);
3388 px += E, py += F;
3389 break;
3390 case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3391 hvc: F = C + D, D = C, E = C = A + B, B = 0;
3392 goto curve;
3393 case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3394 vhc: E = B + D, F = D = A + C, C = B, B = A, A = 0;
3395 goto curve;
3396 case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3397 F = B + D, E = A + C, D = B, C = A, B = A = 0;
3398 goto curve;
3399 case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3400 F = D += B, E = C += A;
3401 goto curve;
3402 case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3403 if ((A ^ B) < 0)
3404 C = -B, D = -A;
3405 else
3406 C = B, D = A;
3407 goto vhc;
3408 case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3409 if ((A ^ B) < 0)
3410 D = -A, C = B, B = -B;
3411 else
3412 D = A, C = B;
3413 goto hvc;
3414 case cmd_opv_scurveto: /* (a b c d e f) => */
3415 {
3416 fixed a = A, b = B;
3417
3418 /* See gxclpath.h for details on the following. */
3419 if (A == 0) {
3420 /* Previous curve was vh or vv */
3421 A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3422 } else {
3423 /* Previous curve was hv or hh */
3424 A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3425 }
3426 }
3427 goto rrc;
3428 case cmd_opv_closepath:
3429 if ((code = gx_path_close_subpath(ppath)) < 0)
3430 return code;;
3431 if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3432 return code;;
3433 px = A, py = B;
3434 break;
3435 default:
3436 return_error(gs_error_rangecheck);
3437 }
3438 #undef A
3439 #undef B
3440 #undef C
3441 #undef D
3442 #undef E
3443 #undef F
3444 ppos->x = px + int2fixed(x0);
3445 ppos->y = py + int2fixed(y0);
3446 return code;
3447 }
3448
3449 /*
3450 * Execute a polyfill -- either a fill_parallelogram or a fill_triangle.
3451 *
3452 * Note that degenerate parallelograms or triangles may collapse into
3453 * a single line or point. We must check for this so we don't try to
3454 * access non-existent segments.
3455 */
3456 static int
clist_do_polyfill(gx_device * dev,gx_path * ppath,const gx_drawing_color * pdcolor,gs_logical_operation_t lop)3457 clist_do_polyfill(gx_device *dev, gx_path *ppath,
3458 const gx_drawing_color *pdcolor,
3459 gs_logical_operation_t lop)
3460 {
3461 const subpath *psub = ppath->first_subpath;
3462 const segment *pseg1;
3463 const segment *pseg2;
3464 int code;
3465
3466 if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3467 fixed px = psub->pt.x, py = psub->pt.y;
3468 fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3469 fixed bx, by;
3470 /*
3471 * We take advantage of the fact that the parameter lists for
3472 * fill_parallelogram and fill_triangle are identical.
3473 */
3474 dev_proc_fill_parallelogram((*fill));
3475
3476 /* close_path of 3 point triangle adds 4th point, detected here.*/
3477 /* close_path on parallelogram adds 5th point also ignored. */
3478 if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3479 /* Parallelogram */
3480 fill = dev_proc(dev, fill_parallelogram);
3481 bx = pseg2->pt.x - pseg1->pt.x;
3482 by = pseg2->pt.y - pseg1->pt.y;
3483 } else {
3484 /* Triangle */
3485 fill = dev_proc(dev, fill_triangle);
3486 bx = pseg2->pt.x - px;
3487 by = pseg2->pt.y - py;
3488 }
3489 code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3490 } else
3491 code = 0;
3492 gx_path_new(ppath);
3493 return code;
3494 }
3495