changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/gs/src/gxclrast.c

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