1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
7    This software is distributed under license and may not be copied, modified
8    or distributed except as expressly authorized under the terms of that
9    license.  Refer to licensing information at http://www.artifex.com/
10    or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11    San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12 */
13 
14 /* $Id: gsovrc.c 10200 2009-10-21 03:50:46Z mvrhel $ */
15 /* overprint/overprint mode compositor implementation */
16 
17 #include "memory_.h"
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gsutil.h"             /* for gs_next_ids */
21 #include "gxcomp.h"
22 #include "gxdevice.h"
23 #include "gsdevice.h"
24 #include "gxgetbit.h"
25 #include "gsovrc.h"
26 #include "gxdcolor.h"
27 #include "gxoprect.h"
28 #include "gsbitops.h"
29 #include "gxistate.h"
30 
31 
32 /* GC descriptor for gs_overprint_t */
33 private_st_gs_overprint_t();
34 
35 /*
36  * Utility routine for encoding or decoding a color index. We cannot use
37  * the general integer encoding routins for these, as they may be 64 bits
38  * in length (the general routines are only designed for 32 bits). We also
39  * cannot use the color-specific routines, as we do not have the required
40  * device color information available.
41  *
42  * The scheme employed is the potentially 64-bit analog of the 32-bit
43  * routines: the low order seven bits of each bytes represents a base-128
44  * digit, and the high order bit is set if there is another digit. The
45  * encoding order is little-endian.
46  *
47  * The write routine returns 0 on success, with *psize set to the number
48  * of bytes used. Alternatively, the return value will be gs_error_rangecheck,
49  * with *psize set to the number of bytes required, if there was insufficient
50  * space.
51  *
52  * The read routine returns the number of bytes read on success, or < 0 in
53  * the event of an error.
54  */
55 static int
write_color_index(gx_color_index cindex,byte * data,uint * psize)56 write_color_index(gx_color_index cindex, byte * data, uint * psize)
57 {
58     int             num_bytes = 0;
59     gx_color_index  ctmp = cindex;
60 
61     for (num_bytes = 1; (ctmp >>= 7) != 0; ++num_bytes)
62         ;
63     if (num_bytes > *psize) {
64         *psize = num_bytes;
65         return gs_error_rangecheck;
66     }
67     ctmp = cindex;
68     *psize = num_bytes;
69     for (; num_bytes > 1; ctmp >>= 7, --num_bytes)
70         *data++ = 0x80 | (ctmp & 0x7f);
71     *data = ctmp & 0x7f;
72     return 0;
73 }
74 
75 static int
read_color_index(gx_color_index * pcindex,const byte * data,uint size)76 read_color_index(gx_color_index * pcindex, const byte * data, uint size)
77 {
78     gx_color_index  cindex = 0;
79     int             nbytes = 0, shift = 0;
80 
81     for (;; shift += 7, data++) {
82         if (++nbytes > size)
83             return_error(gs_error_rangecheck);
84         else {
85             unsigned char byte = *data;
86             gx_color_index c = byte;
87 
88             cindex += (c & 0x7f) << shift;
89             if ((c & 0x80) == 0)
90                 break;
91         }
92     }
93     *pcindex = cindex;
94     return nbytes;
95 }
96 
97 /*
98  * Check for equality of two overprint compositor objects.
99  *
100  * This is fairly simple.
101  */
102 static bool
c_overprint_equal(const gs_composite_t * pct0,const gs_composite_t * pct1)103 c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
104 {
105     if (pct0->type == pct1->type) {
106         const gs_overprint_params_t *    pparams0;
107         const gs_overprint_params_t *    pparams1;
108 
109         pparams0 = &((const gs_overprint_t *)(pct0))->params;
110         pparams1 = &((const gs_overprint_t *)(pct1))->params;
111         if (!pparams0->retain_any_comps)
112             return !pparams1->retain_any_comps;
113         else if (pparams0->retain_spot_comps)
114             return pparams1->retain_spot_comps;
115         else
116             return pparams0->drawn_comps == pparams1->drawn_comps;
117     } else
118         return false;
119 }
120 
121 /*
122  * Bits corresponding to boolean values in the first byte of the string
123  * representation of an overprint compositor.
124  */
125 #define OVERPRINT_ANY_COMPS     1
126 #define OVERPRINT_SPOT_COMPS    2
127 
128 /*
129  * Convert an overprint compositor to string form for use by the command
130  * list device.
131  */
132 static int
c_overprint_write(const gs_composite_t * pct,byte * data,uint * psize,gx_device_clist_writer * cdev)133 c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_device_clist_writer *cdev)
134 {
135     const gs_overprint_params_t *   pparams = &((const gs_overprint_t *)pct)->params;
136     byte                            flags = 0;
137     int                             used = 1, avail = *psize;
138 
139     /* encoded the booleans in a single byte */
140     if (pparams->retain_any_comps) {
141         flags |= OVERPRINT_ANY_COMPS;
142 
143         /* write out the component bits only if necessary (and possible) */
144         if (pparams->retain_spot_comps)
145             flags |= OVERPRINT_SPOT_COMPS;
146         else {
147             uint    tmp_size = (avail > 0 ? avail - 1 : 0);
148             int     code = write_color_index( pparams->drawn_comps,
149                                               data + 1,
150                                               &tmp_size );
151 
152             if (code < 0 && code != gs_error_rangecheck)
153                 return code;
154             used += tmp_size;
155         }
156     }
157 
158     /* check for overflow */
159     *psize = used;
160     if (used > avail)
161         return_error(gs_error_rangecheck);
162     data[0] = flags;
163     if_debug1('v', "[v]c_overprint_write(%d)\n", flags);
164     return 0;
165 }
166 
167 /*
168  * Convert the string representation of the overprint parameter into the
169  * full compositor.
170  */
171 static int
c_overprint_read(gs_composite_t ** ppct,const byte * data,uint size,gs_memory_t * mem)172 c_overprint_read(
173     gs_composite_t **       ppct,
174     const byte *            data,
175     uint                    size,
176     gs_memory_t *           mem )
177 {
178     gs_overprint_params_t   params;
179     byte                    flags = 0;
180     int                     code = 0, nbytes = 1;
181 
182     if (size < 1)
183         return_error(gs_error_rangecheck);
184     flags = *data;
185     if_debug1('v', "[v]c_overprint_read(%d)\n", flags);
186     params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0;
187     params.retain_spot_comps = (flags & OVERPRINT_SPOT_COMPS) != 0;
188     params.idle = 0;
189 
190     /* check if the drawn_comps array is present */
191     if (params.retain_any_comps && !params.retain_spot_comps) {
192         code = read_color_index(&params.drawn_comps, data + 1, size - 1);
193         if (code < 0)
194             return code;
195          nbytes += code;
196     }
197 
198     code = gs_create_overprint(ppct, &params, mem);
199 
200     return code < 0 ? code : nbytes;
201 }
202 
203 /*
204  * Check for closing compositor.
205  */
206 static int
c_overprint_is_closing(const gs_composite_t * this,gs_composite_t ** ppcte,gx_device * dev)207 c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev)
208 {
209     if (*ppcte != NULL && (*ppcte)->type->comp_id != GX_COMPOSITOR_OVERPRINT)
210 	return 0;
211     return 3;
212 }
213 
214 static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
215 static composite_create_default_compositor_proc(c_overprint_create_default_compositor);
216 static composite_equal_proc(c_overprint_equal);
217 static composite_write_proc(c_overprint_write);
218 static composite_is_closing_proc(c_overprint_is_closing);
219 static composite_read_proc(c_overprint_read);
220 
221 /* methods for the overprint compositor */
222 const gs_composite_type_t   gs_composite_overprint_type = {
223     GX_COMPOSITOR_OVERPRINT,
224     {
225         c_overprint_create_default_compositor,  /* procs.create_default_compositor */
226         c_overprint_equal,                      /* procs.equal */
227         c_overprint_write,                      /* procs.write */
228         c_overprint_read,                       /* procs.read */
229 	gx_default_composite_adjust_ctm,
230 	c_overprint_is_closing,
231 	gx_default_composite_is_friendly,
232 	gx_default_composite_clist_write_update,/* procs.composite_clist_write_update */
233 	gx_default_composite_clist_read_update,	/* procs.composite_clist_reade_update */
234 	gx_default_composite_get_cropping	/* procs.composite_get_cropping */
235     }                                           /* procs */
236 };
237 
238 
239 /*
240  * Create an overprint compositor data structure.
241  *
242  * Currently this just a stub.
243  */
244 int
gs_create_overprint(gs_composite_t ** ppct,const gs_overprint_params_t * pparams,gs_memory_t * mem)245 gs_create_overprint(
246     gs_composite_t **               ppct,
247     const gs_overprint_params_t *   pparams,
248     gs_memory_t *                   mem )
249 {
250     gs_overprint_t *                pct;
251 
252     pct = gs_alloc_struct(mem, gs_overprint_t, &st_overprint,
253 			     "gs_create_overprint");
254     if (pct == NULL)
255 	return_error(gs_error_VMerror);
256     pct->type = &gs_composite_overprint_type;
257     pct->id = gs_next_ids(mem, 1);
258     pct->params = *pparams;
259     pct->idle = false;
260     *ppct = (gs_composite_t *)pct;
261     return 0;
262 }
263 
264 
265 /*
266  * Verify that a compositor data structure is for the overprint compositor.
267  * This is used by the gs_pdf1.4_device (and eventually the PDFWrite
268  * device), which implements overprint and overprint mode directly.
269  */
270 int
gs_is_overprint_compositor(const gs_composite_t * pct)271 gs_is_overprint_compositor(const gs_composite_t * pct)
272 {
273     return pct->type == &gs_composite_overprint_type;
274 }
275 
276 
277 /*
278  * The overprint device.
279  *
280  * In principle there are two versions of this device: one if the traget
281  * device is separable and linear, the other if it is not. The two have
282  * slightly different data structures, but differ primarily in terms of
283  * the standard set of methods. Because methods are non-static in
284  * GhostScript, we make use of the same data structure and handle the
285  * distinction during initialization.
286  *
287  * The data fields reflect entries in the gs_overprint_params_t
288  * structure. There is no explicit retain_any_comps field, as the current
289  * setting of this field can be determined by checking the fill_rectangle
290  * method. There is also no retain_spot_comps field, as the code will
291  * will determine explicitly which components are to be drawn.
292  */
293 typedef struct overprint_device_s {
294     gx_device_forward_common;
295 
296     /*
297      * The set of components to be drawn. This field is used only if the
298      * target color space is not separable and linear.
299      */
300     gx_color_index  drawn_comps;
301 
302     /*
303      * The mask of gx_color_index bits to be retained during a drawing
304      * operation. A bit in this mask is 1 if the corresponding bit or
305      * the color index is to be retained; otherwise it is 0.
306      *
307      * The "non-drawn" region of the drawing gx_color_index is assumed
308      * to have the value zero, so for a separable and linear color
309      * encoding, the per-pixel drawing operation is:
310      *
311      *  output = (output & retain_mask) | src
312      *
313      * (For the fully general case, replace src by (src & ~retain_mask).)
314      * Because of byte-alignment, byte-order and performance consideration,
315      * the actually implement operation may be more complex, but this does
316      * not change the overall effect.
317      *
318      * The actual value of retain_mask will be byte swap if this is
319      * required. It will be required if depth > 8 and the host processor
320      * is little-endian.
321      */
322     gx_color_index  retain_mask;
323 
324 } overprint_device_t;
325 
326 gs_private_st_suffix_add0_final( st_overprint_device_t,
327                                  overprint_device_t,
328                                  "overprint_device_t",
329                                  overprint_device_t_enum_ptrs,
330                                  overprint_device_t_reloc_ptrs,
331                                  gx_device_finalize,
332                                  st_device_forward );
333 
334 
335 /*
336  * In the default (overprint false) case, the overprint device is almost
337  * a pure forwarding device: only the open_device and create_compositor
338  * methods are not pure-forwarding methods. The
339  * gx_device_foward_fill_in_procs procedure does not fill in all of the
340  * necessary procedures, so some of them are provided explicitly below.
341  * The put_params procedure also requires a small modification, so that
342  * the open/close state of this device always reflects that of its
343  * target.
344  *
345  * This and other method arrays are not declared const so that they may
346  * be initialized once via gx_device_forward_fill_in_procs. They are
347  * constant once this initialization is complete.
348  */
349 static dev_proc_open_device(overprint_open_device);
350 static dev_proc_put_params(overprint_put_params);
351 static dev_proc_get_page_device(overprint_get_page_device);
352 static dev_proc_create_compositor(overprint_create_compositor);
353 static dev_proc_get_color_comp_index(overprint_get_color_comp_index);
354 
355 static gx_device_procs no_overprint_procs = {
356     overprint_open_device,              /* open_device */
357     0,                                  /* get_initial_matrix */
358     0,                                  /* sync_output */
359     0,                                  /* output_page */
360     0,                                  /* close_device */
361     0,                                  /* map_rgb_color */
362     0,                                  /* map_color_rgb */
363     gx_forward_fill_rectangle,          /* fill_rectangle */
364     gx_forward_tile_rectangle,          /* tile_rectangle */
365     gx_forward_copy_mono,               /* copy_mono */
366     gx_forward_copy_color,              /* copy_color */
367     0,                                  /* draw_line (obsolete) */
368     0,                                  /* get_bits */
369     0,                                  /* get_params */
370     overprint_put_params,               /* put_params */
371     0,                                  /* map_cmyk_color */
372     0,                                  /* get_xfont_procs */
373     0,                                  /* get_xfont_device */
374     0,                                  /* map_rgb_alpha_color */
375     overprint_get_page_device,          /* get_page_device */
376     0,                                  /* get_alpha_bits (obsolete) */
377     0,                                  /* copy alpha */
378     0,                                  /* get_band */
379     0,                                  /* copy_rop */
380     0,                                  /* fill_path */
381     0,                                  /* stroke_path */
382     0,                                  /* fill_mask */
383     0,                                  /* fill_trapezoid */
384     0,                                  /* fill_parallelogram */
385     0,                                  /* fill_triangle */
386     0,                                  /* draw_thin_line */
387     0,                                  /* begin_image */
388     0,                                  /* image_data (obsolete) */
389     0,                                  /* end_image (obsolete) */
390     gx_forward_strip_tile_rectangle,    /* strip_tile_rectangle */
391     0,                                  /* strip_copy_rop */
392     0,                                  /* get_clipping_box */
393     0,                                  /* begin_typed_image */
394     0,                                  /* get_bits_rectangle */
395     0,                                  /* map_color_rgb_alpha */
396     overprint_create_compositor,        /* create_compositor */
397     0,                                  /* get_hardware_params */
398     0,                                  /* text_begin */
399     0,                                  /* gx_finish_copydevice */
400     0,                                  /* begin_transparency_group */
401     0,                                  /* end_transparency_group */
402     0,                                  /* being_transparency_mask */
403     0,                                  /* end_transparency_mask */
404     0,                                  /* discard_transparency_layer */
405     0,                                  /* get_color_mapping_procs */
406     overprint_get_color_comp_index,	/* get_color_comp_index */
407     0,                                  /* encode_color */
408     0,                                  /* decode_color */
409     0,					/* pattern_manage */
410     0,					/* fill_rectangle_hl_color */
411     0,					/* include_color_space */
412     0,					/* fill_linear_color_scanline */
413     0,					/* fill_linear_color_trapezoid */
414     0,					/* fill_linear_color_triangle */
415     0,					/* update_spot_equivalent_colors */
416     0,					/* ret_devn_params */
417     gx_forward_fillpage,
418     0,                                  /* push_transparency_state */
419     0                                   /* pop_transparency_state */
420 
421 };
422 
423 /*
424  * If overprint is set, the high and mid-level rendering methods are
425  * replaced by the default routines. The low-level color rendering methods
426  * are replaced with one of two sets of functions, depending on whether or
427  * not the target device has a separable and linear color encoding.
428  *
429  *  1. If the target device does not have a separable and linear
430  *     encoding, an overprint-specific fill_rectangle method is used,
431  *     and the default methods are used for all other low-level rendering
432  *     methods. There is no way to achieve good rendering performance
433  *     when overprint is true and the color encoding is not separable
434  *     and linear, so there is little reason to use more elaborate
435  *     methods int this case.
436  *
437  *  2. If the target device does have a separable and linear color
438  *     model, at least the fill_rectangle method and potentially other
439  *     methods will be replaced by overprint-specific methods. Those
440  *     methods not replaced will have their default values. The number
441  *     of methods replaced is dependent on the desired level of
442  *     performance: the more methods, the better the performance.
443  *
444  *     Note that certain procedures, such as copy_alpha and copy_rop,
445  *     are likely to always be given their default values, as the concepts
446  *     of alpha-compositing and raster operations are not compatible in
447  *     a strict sense.
448  */
449 static dev_proc_fill_rectangle(overprint_generic_fill_rectangle);
450 static dev_proc_fill_rectangle(overprint_sep_fill_rectangle);
451 /* other low-level overprint_sep_* rendering methods prototypes go here */
452 
453 static gx_device_procs generic_overprint_procs = {
454     overprint_open_device,              /* open_device */
455     0,                                  /* get_initial_matrix */
456     0,                                  /* sync_output */
457     0,                                  /* output_page */
458     0,                                  /* close_device */
459     0,                                  /* map_rgb_color */
460     0,                                  /* map_color_rgb */
461     overprint_generic_fill_rectangle,   /* fill_rectangle */
462     gx_default_tile_rectangle,          /* tile_rectangle */
463     gx_default_copy_mono,               /* copy_mono */
464     gx_default_copy_color,              /* copy_color */
465     gx_default_draw_line,               /* draw_line (obsolete) */
466     0,                                  /* get_bits */
467     0,                                  /* get_params */
468     overprint_put_params,               /* put_params */
469     0,                                  /* map_cmyk_color */
470     0,                                  /* get_xfont_procs */
471     gx_default_get_xfont_device,        /* get_xfont_device */
472     0,                                  /* map_rgb_alpha_color */
473     overprint_get_page_device,          /* get_page_device */
474     0,                                  /* get_alpha_bits (obsolete) */
475     gx_default_copy_alpha,              /* copy alpha */
476     0,                                  /* get_band */
477     gx_default_copy_rop,                /* copy_rop */
478     gx_default_fill_path,               /* fill_path */
479     gx_default_stroke_path,             /* stroke_path */
480     gx_default_fill_mask,               /* fill_mask */
481     gx_default_fill_trapezoid,          /* fill_trapezoid */
482     gx_default_fill_parallelogram,      /* fill_parallelogram */
483     gx_default_fill_triangle,           /* fill_triangle */
484     gx_default_draw_thin_line,          /* draw_thin_line */
485     gx_default_begin_image,             /* begin_image */
486     0,                                  /* image_data (obsolete) */
487     0,                                  /* end_image (obsolete) */
488     gx_default_strip_tile_rectangle,    /* strip_tile_rectangle */
489     gx_default_strip_copy_rop,          /* strip_copy_rop */
490     0,                                  /* get_clipping_box */
491     gx_default_begin_typed_image,       /* begin_typed_image */
492     0,                                  /* get_bits_rectangle */
493     0,                                  /* map_color_rgb_alpha */
494     overprint_create_compositor,        /* create_compositor */
495     0,                                  /* get_hardware_params */
496     gx_default_text_begin,              /* text_begin */
497     0,                                  /* gx_finish_copydevice */
498     0,                                  /* begin_transparency_group */
499     0,                                  /* end_transparency_group */
500     0,                                  /* begin_transparency_mask */
501     0,                                  /* end_transparency_mask */
502     0,                                  /* discard_transparency_layer */
503     0,                                  /* get_color_mapping_procs */
504     overprint_get_color_comp_index,	/* get_color_comp_index */
505     0,                                  /* encode_color */
506     0                                   /* decode_color */
507 };
508 
509 static gx_device_procs sep_overprint_procs = {
510     overprint_open_device,              /* open_device */
511     0,                                  /* get_initial_matrix */
512     0,                                  /* sync_output */
513     0,                                  /* output_page */
514     0,                                  /* close_device */
515     0,                                  /* map_rgb_color */
516     0,                                  /* map_color_rgb */
517     overprint_sep_fill_rectangle,       /* fill_rectangle */
518     gx_default_tile_rectangle,          /* tile_rectangle */
519     gx_default_copy_mono,               /* copy_mono */
520     gx_default_copy_color,              /* copy_color */
521     gx_default_draw_line,               /* draw_line (obsolete) */
522     0,                                  /* get_bits */
523     0,                                  /* get_params */
524     overprint_put_params,               /* put_params */
525     0,                                  /* map_cmyk_color */
526     0,                                  /* get_xfont_procs */
527     gx_default_get_xfont_device,        /* get_xfont_device */
528     0,                                  /* map_rgb_alpha_color */
529     overprint_get_page_device,          /* get_page_device */
530     0,                                  /* get_alpha_bits (obsolete) */
531     gx_default_copy_alpha,              /* copy alpha */
532     0,                                  /* get_band */
533     gx_default_copy_rop,                /* copy_rop */
534     gx_default_fill_path,               /* fill_path */
535     gx_default_stroke_path,             /* stroke_path */
536     gx_default_fill_mask,               /* fill_mask */
537     gx_default_fill_trapezoid,          /* fill_trapezoid */
538     gx_default_fill_parallelogram,      /* fill_parallelogram */
539     gx_default_fill_triangle,           /* fill_triangle */
540     gx_default_draw_thin_line,          /* draw_thin_line */
541     gx_default_begin_image,             /* begin_image */
542     0,                                  /* image_data (obsolete) */
543     0,                                  /* end_image (obsolete) */
544     gx_default_strip_tile_rectangle,    /* strip_tile_rectangle */
545     gx_default_strip_copy_rop,          /* strip_copy_rop */
546     0,                                  /* get_clipping_box */
547     gx_default_begin_typed_image,       /* begin_typed_image */
548     0,                                  /* get_bits_rectangle */
549     0,                                  /* map_color_rgb_alpha */
550     overprint_create_compositor,        /* create_compositor */
551     0,                                  /* get_hardware_params */
552     gx_default_text_begin,              /* text_begin */
553     0,                                  /* gx_finish_copydevice */
554     0,                                  /* begin_transparency_group */
555     0,                                  /* end_transparency_group */
556     0,                                  /* begin_transparency_mask */
557     0,                                  /* end_transparency_mask */
558     0,                                  /* discard_transparency_layer */
559     0,                                  /* get_color_mapping_procs */
560     overprint_get_color_comp_index,	/* get_color_comp_index */
561     0,                                  /* encode_color */
562     0                                   /* decode_color */
563 };
564 
565 /*
566  * The prototype for the overprint device does not provide much
567  * information; it exists primarily to facilitate use gx_init_device
568  * and sundry other device utility routines.
569  */
570 const overprint_device_t    gs_overprint_device = {
571     std_device_std_body_open( overprint_device_t,   /* device type */
572                               0,                    /* static_procs */
573                               "overprint_device",   /* dname */
574                               0, 0,                 /* width, height */
575                               1, 1 ),               /* HWResolution */
576     { 0 }                                           /* procs */
577 };
578 
579 
580 
581 /*
582  * Utility to reorder bytes in a color or mask based on the endianness of
583  * the current device. This is required on little-endian machines if the
584  * depth is larger 8. The resulting value is also replicated to fill the
585  * entire gx_color_index if the depth is a divisor of the color index
586  * size. If this is not the case, the result will be in the low-order
587  * bytes of the color index.
588  *
589  * Though this process can be handled in full generality, the code below
590  * takes advantage of the fact that depths that are > 8 must be a multiple
591  * of 8 and <= 64
592  */
593 #if !arch_is_big_endian
594 
595 static gx_color_index
swap_color_index(int depth,gx_color_index color)596 swap_color_index(int depth, gx_color_index color)
597 {
598     int             shift = depth - 8;
599     gx_color_index  mask = 0xff;
600 
601     color =  ((color >> shift) & mask)
602            | ((color & mask) << shift)
603            | (color & ~((mask << shift) | mask));
604     if (depth > 24) {
605         shift -= 16;
606         mask <<= 8;
607         color =  ((color >> shift) & mask)
608                | ((color & mask) << shift)
609                | (color & ~((mask << shift) | mask));
610 
611         if (depth > 40) {
612             shift -= 16;
613             mask <<= 8;
614             color =  ((color >> shift) & mask)
615                    | ((color & mask) << shift)
616                    | (color & ~((mask << shift) | mask));
617 
618             if (depth > 56) {
619                 shift -= 16;
620                 mask <<= 8;
621                 color =  ((color >> shift) & mask)
622                        | ((color & mask) << shift)
623                        | (color & ~((mask << shift) | mask));
624             }
625         }
626     }
627 
628     return color;
629 }
630 
631 #endif  /* !arch_is_big_endian */
632 
633 /*
634  * Update the retain_mask field to reflect the information in the
635  * drawn_comps field. This is useful only if the device color model
636  * is separable.
637  */
638 static void
set_retain_mask(overprint_device_t * opdev)639 set_retain_mask(overprint_device_t * opdev)
640 {
641     int             i, ncomps = opdev->color_info.num_components;
642     gx_color_index  drawn_comps = opdev->drawn_comps, retain_mask = 0;
643 #if !arch_is_big_endian
644     int             depth = opdev->color_info.depth;
645 #endif
646 
647     for (i = 0; i < ncomps; i++, drawn_comps >>= 1) {
648         if ((drawn_comps & 0x1) == 0)
649             retain_mask |= opdev->color_info.comp_mask[i];
650     }
651 #if !arch_is_big_endian
652     if (depth > 8)
653         retain_mask = swap_color_index(depth, retain_mask);
654 #endif
655     opdev->retain_mask = retain_mask;
656 }
657 
658 /* enlarge mask of non-zero components */
659 static gx_color_index
check_drawn_comps(int ncomps,frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS])660 check_drawn_comps(int ncomps, frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS])
661 {
662     int              i;
663     gx_color_index   mask = 0x1, drawn_comps = 0;
664 
665     for (i = 0; i < ncomps; i++, mask <<= 1) {
666         if (cvals[i] != frac_0)
667             drawn_comps |= mask;
668     }
669     return drawn_comps;
670 }
671 
672 /*
673  * Update the overprint-specific device parameters.
674  *
675  * If spot colors are to be retain, the set of process (non-spot) colors is
676  * determined by mapping through the standard color spaces and check which
677  * components assume non-zero values.
678  */
679 static int
update_overprint_params(overprint_device_t * opdev,const gs_overprint_params_t * pparams)680 update_overprint_params(
681     overprint_device_t *            opdev,
682     const gs_overprint_params_t *   pparams )
683 {
684     int                             ncomps = opdev->color_info.num_components;
685 
686     /* check if overprint is to be turned off */
687     if (!pparams->retain_any_comps || pparams->idle) {
688         /* if fill_rectangle forwards, overprint is already off */
689         if (dev_proc(opdev, fill_rectangle) != gx_forward_fill_rectangle)
690             memcpy( &opdev->procs,
691                     &no_overprint_procs,
692                     sizeof(no_overprint_procs) );
693         return 0;
694     }
695 
696     /* set the procedures according to the color model */
697     if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
698         memcpy( &opdev->procs,
699                 &sep_overprint_procs,
700                 sizeof(sep_overprint_procs) );
701     else
702         memcpy( &opdev->procs,
703                 &generic_overprint_procs,
704                 sizeof(generic_overprint_procs) );
705 
706     /* see if we need to determine the spot color components */
707     if (!pparams->retain_spot_comps)
708         opdev->drawn_comps = pparams->drawn_comps;
709     else {
710         gx_device *                     dev = (gx_device *)opdev;
711         const gx_cm_color_map_procs *   pprocs;
712         frac                            cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
713         gx_color_index                  drawn_comps = 0;
714         static const frac               frac_13 = float2frac(1.0 / 3.0);
715 
716         if ((pprocs = dev_proc(opdev, get_color_mapping_procs)(dev)) == 0 ||
717             pprocs->map_gray == 0                                         ||
718             pprocs->map_rgb == 0                                          ||
719             pprocs->map_cmyk == 0                                           )
720             return_error(gs_error_unknownerror);
721 
722         pprocs->map_gray(dev, frac_13, cvals);
723         drawn_comps |= check_drawn_comps(ncomps, cvals);
724 
725         pprocs->map_rgb(dev, 0, frac_13, frac_0, frac_0, cvals);
726         drawn_comps |= check_drawn_comps(ncomps, cvals);
727         pprocs->map_rgb(dev, 0, frac_0, frac_13, frac_0, cvals);
728         drawn_comps |= check_drawn_comps(ncomps, cvals);
729         pprocs->map_rgb(dev, 0, frac_0, frac_0, frac_13, cvals);
730         drawn_comps |= check_drawn_comps(ncomps, cvals);
731 
732         pprocs->map_cmyk(dev, frac_13, frac_0, frac_0, frac_0, cvals);
733         drawn_comps |= check_drawn_comps(ncomps, cvals);
734         pprocs->map_cmyk(dev, frac_0, frac_13, frac_0, frac_0, cvals);
735         drawn_comps |= check_drawn_comps(ncomps, cvals);
736         pprocs->map_cmyk(dev, frac_0, frac_0, frac_13, frac_0, cvals);
737         drawn_comps |= check_drawn_comps(ncomps, cvals);
738         pprocs->map_cmyk(dev, frac_0, frac_0, frac_0, frac_13, cvals);
739         drawn_comps |= check_drawn_comps(ncomps, cvals);
740 
741         opdev->drawn_comps = drawn_comps;
742     }
743 
744     /* check for degenerate case */
745     if (opdev->drawn_comps == ((gx_color_index)1 << ncomps) - 1) {
746         memcpy( &opdev->procs,
747                 &no_overprint_procs,
748                 sizeof(no_overprint_procs) );
749         return 0;
750     }
751 
752     /* if appropriate, update the retain_mask field */
753     if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN)
754         set_retain_mask(opdev);
755 
756     return 0;
757 }
758 
759 
760 /*
761  * The open_device method for the overprint device is about as close to
762  * a pure "forwarding" open_device operation as is possible. Its only
763  * significant function is to ensure that the is_open field of the
764  * overprint device matches that of the target device.
765  *
766  * We assume this procedure is called only if the device is not already
767  * open, and that gs_opendevice will take care of the is_open flag.
768  */
769 static int
overprint_open_device(gx_device * dev)770 overprint_open_device(gx_device * dev)
771 {
772     overprint_device_t *    opdev = (overprint_device_t *)dev;
773     gx_device *             tdev = opdev->target;
774     int                     code = 0;
775 
776     /* the overprint device must have a target */
777     if (tdev == 0)
778         return_error(gs_error_unknownerror);
779     if ((code = gs_opendevice(tdev)) >= 0)
780         gx_device_copy_params(dev, tdev);
781     return code;
782 }
783 
784 /*
785  * The put_params method for the overprint device will check if the
786  * target device has closed and, if so, close itself.
787  */
788 static int
overprint_put_params(gx_device * dev,gs_param_list * plist)789 overprint_put_params(gx_device * dev, gs_param_list * plist)
790 {
791     overprint_device_t *    opdev = (overprint_device_t *)dev;
792     gx_device *             tdev = opdev->target;
793     int                     code = 0;
794 
795 
796     if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
797         gx_device_decache_colors(dev);
798         if (!tdev->is_open)
799             code = gs_closedevice(dev);
800     }
801     return code;
802 }
803 
804 /*
805  * If the target device 'auto detects' new spot colors, then it will
806  * change its color_info data.  Make sure that we have a current copy.
807  */
808 int
overprint_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)809 overprint_get_color_comp_index(gx_device * dev, const char * pname,
810 					int name_size, int component_type)
811 {
812     overprint_device_t * opdev = (overprint_device_t *)dev;
813     gx_device * tdev = opdev->target;
814     int code;
815 
816     if (tdev == 0)
817 	code = gx_error_get_color_comp_index(dev, pname,
818 				name_size, component_type);
819     else {
820 	code = dev_proc(tdev, get_color_comp_index)(tdev, pname,
821 				name_size, component_type);
822         opdev->color_info = tdev->color_info;
823     }
824     return code;
825 }
826 
827 /*
828  * The overprint device must never be confused with a page device.
829  * Thus, we always forward the request for the page device to the
830  * target, as should all forwarding devices.
831  */
832 static gx_device *
overprint_get_page_device(gx_device * dev)833 overprint_get_page_device(gx_device * dev)
834 {
835     overprint_device_t *    opdev = (overprint_device_t *)dev;
836     gx_device *             tdev = opdev->target;
837 
838     return tdev == 0 ? 0 : dev_proc(tdev, get_page_device)(tdev);
839 }
840 
841 /*
842  * Calling create_compositor on the overprint device just updates the
843  * overprint parameters; no new device is created.
844  */
845 static int
overprint_create_compositor(gx_device * dev,gx_device ** pcdev,const gs_composite_t * pct,gs_imager_state * pis,gs_memory_t * memory)846 overprint_create_compositor(
847     gx_device *             dev,
848     gx_device **            pcdev,
849     const gs_composite_t *  pct,
850     gs_imager_state *	    pis,
851     gs_memory_t *           memory )
852 {
853     if (pct->type != &gs_composite_overprint_type)
854         return gx_default_create_compositor(dev, pcdev, pct, pis, memory);
855     else {
856 	gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params;
857         int     code;
858 
859 	params.idle = pct->idle;
860         /* device must already exist, so just update the parameters */
861         code = update_overprint_params(
862                        (overprint_device_t *)dev,
863                        &params );
864         if (code >= 0)
865             *pcdev = dev;
866         return code;
867     }
868 }
869 
870 
871 /*
872  * The two rectangle-filling routines (which do the actual work) are just
873  * stubbs for the time being. The actual routines would allocate a buffer,
874  * use get_bits_rectangle to build a buffer of the existing data, modify
875  * the appropriate components, then invoke the copy_color procedure on the
876  * target device.
877  */
878 static int
overprint_generic_fill_rectangle(gx_device * dev,int x,int y,int width,int height,gx_color_index color)879 overprint_generic_fill_rectangle(
880     gx_device *     dev,
881     int             x,
882     int             y,
883     int             width,
884     int             height,
885     gx_color_index  color )
886 {
887     overprint_device_t *    opdev = (overprint_device_t *)dev;
888     gx_device *             tdev = opdev->target;
889 
890     if (tdev == 0)
891         return 0;
892     else
893         return gx_overprint_generic_fill_rectangle( tdev,
894                                                     opdev->drawn_comps,
895                                                     x, y, width, height,
896                                                     color,
897                                                     dev->memory );
898 }
899 
900 static int
overprint_sep_fill_rectangle(gx_device * dev,int x,int y,int width,int height,gx_color_index color)901 overprint_sep_fill_rectangle(
902     gx_device *     dev,
903     int             x,
904     int             y,
905     int             width,
906     int             height,
907     gx_color_index  color )
908 {
909     overprint_device_t *    opdev = (overprint_device_t *)dev;
910     gx_device *             tdev = opdev->target;
911 
912     if (tdev == 0)
913         return 0;
914     else {
915         int     depth = tdev->color_info.depth;
916 
917         /*
918          * Swap the color index into the order required by a byte-oriented
919          * bitmap. This is required only for littl-endian processors, and
920          * then only if the depth > 8.
921          */
922 #if !arch_is_big_endian
923         if (depth > 8)
924             color = swap_color_index(depth, color);
925 #endif
926 
927         /*
928          * We can handle rectangle filling via bits_fill_rectangle_masked
929          * if the depth is a divisor of 8 * sizeof(mono_fill_chunk). The
930          * non-masked fill_rectangle code uses a byte-oriented routine
931          * if depth > 8, but there is not much advantage to doing so if
932          * masking is required.
933          *
934          * Directly testing (8 * sizeof(mono_fill_chunk)) % depth is
935          * potentially expensive, since many rectangles are small. We
936          * can avoid the modulus operation by noting that
937          * 8 * sizeof(mono_fill_chunk) will be a power of 2, and so
938          * we need only check that depth is a power of 2 and
939          * depth < 8 * sizeof(mono_fill_chunk).
940          */
941         if ( depth <= 8 * sizeof(mono_fill_chunk) &&
942              (depth & (depth - 1)) == 0             )
943             return gx_overprint_sep_fill_rectangle_1( tdev,
944                                                       opdev->retain_mask,
945                                                       x, y, width, height,
946                                                       color,
947                                                       dev->memory );
948         else
949             return gx_overprint_sep_fill_rectangle_2( tdev,
950                                                       opdev->retain_mask,
951                                                       x, y, width, height,
952                                                       color,
953                                                       dev->memory );
954     }
955 }
956 
957 
958 /* complete a porcedure set */
959 static void
fill_in_procs(gx_device_procs * pprocs)960 fill_in_procs(gx_device_procs * pprocs)
961 {
962     gx_device_forward   tmpdev;
963 
964     /*
965      * gx_device_forward_fill_in_procs calls gx_device_fill_in_procs, which
966      * requires the color_info field of the device be set to "reasonable"
967      * values. Which values is irrelevant in this case, but they must not
968      * contain dangling pointers, excessive numbers of components, etc.
969      */
970     memcpy( &tmpdev.color_info,
971             &gs_overprint_device.color_info,
972             sizeof(tmpdev.color_info) );
973     /*
974      * Prevent the check_device_separable routine from executing while we
975      * fill in the procs.  Our tmpdev is not complete enough for it.
976      */
977     tmpdev.color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
978     tmpdev.static_procs = 0;
979     memcpy(&tmpdev.procs, pprocs, sizeof(tmpdev.procs));
980     gx_device_forward_fill_in_procs(&tmpdev);
981     memcpy(pprocs, &tmpdev.procs, sizeof(tmpdev.procs));
982 }
983 
984 /*
985  * Create an overprint compositor.
986  *
987  * Note that this routine will be called only if the device is not already
988  * an overprint compositor. Hence, if pct->params.retain_any_comps is
989  * false, we can just return.
990  *
991  * We also suppress use of overprint if the current device color model has only
992  * a single component. In this case overprint mode is inapplicable (it applies
993  * only to CMYK devices), and nothing can possibly be gained by using overprint.
994  * More significantly, this cause avoids erroneous use of overprint when a
995  * mask caching device is the current device, which would otherwise require
996  * elaborate special handling in the caching device create_compositor
997  * procedure.
998  */
999 static int
c_overprint_create_default_compositor(const gs_composite_t * pct,gx_device ** popdev,gx_device * tdev,gs_imager_state * pis,gs_memory_t * mem)1000 c_overprint_create_default_compositor(
1001     const gs_composite_t *  pct,
1002     gx_device **            popdev,
1003     gx_device *             tdev,
1004     gs_imager_state *	    pis,
1005     gs_memory_t *           mem )
1006 {
1007     const gs_overprint_t *  ovrpct = (const gs_overprint_t *)pct;
1008     overprint_device_t *    opdev = 0;
1009     gs_overprint_params_t params;
1010 
1011     /* see if there is anything to do */
1012     if ( !ovrpct->params.retain_any_comps) {
1013         *popdev = tdev;
1014         return 0;
1015     }
1016     if (pct->idle) {
1017         *popdev = tdev;
1018 	return 0;
1019     }
1020 
1021     /* check if the procedure arrays have been initialized */
1022     if (no_overprint_procs.get_xfont_procs == 0) {
1023         fill_in_procs(&no_overprint_procs);
1024         fill_in_procs(&generic_overprint_procs);
1025         fill_in_procs(&sep_overprint_procs);
1026     }
1027 
1028     /* build the overprint device */
1029     opdev = gs_alloc_struct_immovable( mem,
1030                                        overprint_device_t,
1031                                        &st_overprint_device_t,
1032                                        "create overprint compositor" );
1033     if ((*popdev = (gx_device *)opdev) == 0)
1034         return_error(gs_error_VMerror);
1035     gx_device_init( (gx_device *)opdev,
1036                     (const gx_device *)&gs_overprint_device,
1037                     mem,
1038                     true );
1039     gx_device_copy_params((gx_device *)opdev, tdev);
1040     gx_device_set_target((gx_device_forward *)opdev, tdev);
1041 
1042     params = ovrpct->params;
1043     params.idle = ovrpct->idle;
1044 
1045     /* set up the overprint parameters */
1046     return update_overprint_params( opdev, &params);
1047 }
1048