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, &notes);
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(&param_list, mem);
2967     code = gs_param_list_unserialize
2968         ( (gs_param_list *)&param_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(&param_list);
2973         code = gs_gstate_putdeviceparams(pgs, (gx_device *)cdev,
2974                                          (gs_param_list *)&param_list);
2975     }
2976     gs_c_param_list_release(&param_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