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