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