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