1 /* Copyright (C) 2001-2019 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,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13    CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Color mapping for Ghostscript */
18 #include "gx.h"
19 #include "gserrors.h"
20 #include "gsccolor.h"
21 #include "gxalpha.h"
22 #include "gxcspace.h"
23 #include "gxfarith.h"
24 #include "gxfrac.h"
25 #include "gxdcconv.h"
26 #include "gxdevice.h"
27 #include "gxcmap.h"
28 #include "gxlum.h"
29 #include "gzstate.h"
30 #include "gxdither.h"
31 #include "gxcdevn.h"
32 #include "string_.h"
33 #include "gsicc_manage.h"
34 #include "gdevdevn.h"
35 #include "gsicc_cache.h"
36 #include "gscms.h"
37 #include "gsicc.h"
38 #include "gxdevsop.h"
39 
40 /* If enabled, this makes use of the alternate transform
41    ICC profile for mapping separation and
42    DeviceN colorants from CMYK to output
43    ICC color space iff the profiles make
44    sense.  We should probably make this yet
45    another color command line option. Disabling
46    it for now for the current release. */
47 #define USE_ALT_MAP 0
48 
49 /* Structure descriptor */
50 public_st_device_color();
51 static
ENUM_PTRS_WITH(device_color_enum_ptrs,gx_device_color * cptr)52 ENUM_PTRS_WITH(device_color_enum_ptrs, gx_device_color *cptr)
53 {
54         return ENUM_USING(*cptr->type->stype, vptr, size, index);
55 }
56 ENUM_PTRS_END
RELOC_PTRS_WITH(device_color_reloc_ptrs,gx_device_color * cptr)57 static RELOC_PTRS_WITH(device_color_reloc_ptrs, gx_device_color *cptr)
58 {
59     RELOC_USING(*cptr->type->stype, vptr, size);
60 }
61 RELOC_PTRS_END
62 
63 gx_color_index
gx_default_encode_color(gx_device * dev,const gx_color_value cv[])64 gx_default_encode_color(gx_device * dev, const gx_color_value cv[])
65 {
66     uchar             ncomps = dev->color_info.num_components;
67     uchar             i;
68     const byte *    comp_shift = dev->color_info.comp_shift;
69     const byte *    comp_bits = dev->color_info.comp_bits;
70     gx_color_index  color = 0;
71 
72 #ifdef DEBUG
73     if (!colors_are_separable_and_linear(&dev->color_info)) {
74         dmprintf(dev->memory, "gx_default_encode_color() requires separable and linear\n" );
75         return gx_no_color_index;
76     }
77 #endif
78     for (i = 0; i < ncomps; i++) {
79         COLROUND_VARS;
80         COLROUND_SETUP(comp_bits[i]);
81         color |= COLROUND_ROUND(cv[i]) << comp_shift[i];
82 
83     }
84     return color;
85 }
86 
87 /*
88  * This routine is only used if the device is 'separable'.  See
89  * separable_and_linear in gxdevcli.h for more information.
90  */
91 int
gx_default_decode_color(gx_device * dev,gx_color_index color,gx_color_value cv[])92 gx_default_decode_color(gx_device * dev, gx_color_index color, gx_color_value cv[])
93 {
94     uchar                   ncomps = dev->color_info.num_components;
95     uchar                   i;
96     const byte *            comp_shift = dev->color_info.comp_shift;
97     const byte *            comp_bits = dev->color_info.comp_bits;
98     const gx_color_index *  comp_mask = dev->color_info.comp_mask;
99     uint shift, ivalue, nbits, scale;
100 
101 #ifdef DEBUG
102     if (!colors_are_separable_and_linear(&dev->color_info)) {
103         dmprintf(dev->memory, "gx_default_decode_color() requires separable and linear\n" );
104         return_error(gs_error_rangecheck);
105     }
106 #endif
107 
108     for (i = 0; i < ncomps; i++) {
109         /*
110          * Convert from the gx_color_index bits to a gx_color_value.
111          * Split the conversion into an integer and a fraction calculation
112          * so we can do integer arthmetic.  The calculation is equivalent
113          * to floor(0xffff.fffff * ivalue / ((1 << nbits) - 1))
114          */
115         nbits = comp_bits[i];
116         scale = gx_max_color_value / ((1 << nbits) - 1);
117         ivalue = (color & comp_mask[i]) >> comp_shift[i];
118         cv[i] = ivalue * scale;
119         /*
120          * Since our scaling factor is an integer, we lost the fraction.
121          * Determine what part of the ivalue that the faction would have
122          * added into the result.
123          */
124         shift = nbits - (gx_color_value_bits % nbits);
125         cv[i] += ivalue >> shift;
126     }
127     return 0;
128 }
129 
130 gx_color_index
gx_error_encode_color(gx_device * dev,const gx_color_value colors[])131 gx_error_encode_color(gx_device * dev, const gx_color_value colors[])
132 {
133 #ifdef DEBUG
134     /* The "null" device is expected to be missing encode_color */
135     if (strcmp(dev->dname, "null") != 0)
136         dmprintf(dev->memory, "No encode_color proc defined for device.\n");
137 #endif
138     return gx_no_color_index;
139 }
140 
141 int
gx_error_decode_color(gx_device * dev,gx_color_index cindex,gx_color_value colors[])142 gx_error_decode_color(gx_device * dev, gx_color_index cindex, gx_color_value colors[])
143 {
144      int i=dev->color_info.num_components;
145 
146 #ifdef DEBUG
147      dmprintf(dev->memory, "No decode_color proc defined for device.\n");
148 #endif
149      for(; i>=0; i--)
150         colors[i] = 0;
151      return_error(gs_error_rangecheck);
152 }
153 
154 /*
155  * The "back-stop" default encode_color method. This will be used only
156  * if no applicable color encoding procedure is provided, and the number
157  * of color model components is 1. The encoding is presumed to induce an
158  * additive color model (DeviceGray).
159  *
160  * The particular method employed is a trivial generalization of the
161  * default map_rgb_color method used in the pre-DeviceN code (this was
162  * known as gx_default_w_b_map_rgb_color). Since the DeviceRGB color
163  * model is assumed additive, any of the procedures used as a default
164  * map_rgb_color method are assumed to induce an additive color model.
165  * gx_default_w_b_map_rgb_color mapped white to 1 and black to 0, so
166  * the new procedure is set up with zero-base and positive slope as well.
167  * The generalization is the use of depth; the earlier procedure assumed
168  * a bi-level device.
169  *
170  * Two versions of this procedure are provided, the first of which
171  * applies if max_gray == 2^depth - 1 and is faster, while the second
172  * applies to the general situation. Note that, as with the encoding
173  * procedures used in the pre-DeviceN code, both of these methods induce
174  * a small rounding error if 1 < depth < gx_color_value_bits.
175  */
176 gx_color_index
gx_default_gray_fast_encode(gx_device * dev,const gx_color_value cv[])177 gx_default_gray_fast_encode(gx_device * dev, const gx_color_value cv[])
178 {
179     COLROUND_VARS;
180     COLROUND_SETUP(dev->color_info.depth);
181     return COLROUND_ROUND(cv[0]);
182 }
183 
184 gx_color_index
gx_default_gray_encode(gx_device * dev,const gx_color_value cv[])185 gx_default_gray_encode(gx_device * dev, const gx_color_value cv[])
186 {
187     return (gx_color_index)(cv[0]) * (dev->color_info.max_gray + 1) / (gx_max_color_value + 1);
188 }
189 
190 /**
191  * This routine is provided for old devices which provide a
192  * map_rgb_color routine but not encode_color. New devices are
193  * encouraged either to use the defaults or to set encode_color rather
194  * than map_rgb_color.
195  **/
196 gx_color_index
gx_backwards_compatible_gray_encode(gx_device * dev,const gx_color_value cv[])197 gx_backwards_compatible_gray_encode(gx_device *dev,
198                                     const gx_color_value cv[])
199 {
200     gx_color_value gray_val = cv[0];
201     gx_color_value rgb_cv[3];
202 
203     rgb_cv[0] = gray_val;
204     rgb_cv[1] = gray_val;
205     rgb_cv[2] = gray_val;
206     return (*dev_proc(dev, map_rgb_color))(dev, rgb_cv);
207 }
208 
209 /* -------- Default color space to color model conversion routines -------- */
210 
211 void
gray_cs_to_gray_cm(gx_device * dev,frac gray,frac out[])212 gray_cs_to_gray_cm(gx_device * dev, frac gray, frac out[])
213 {
214     out[0] = gray;
215 }
216 
217 static void
rgb_cs_to_gray_cm(gx_device * dev,const gs_gstate * pgs,frac r,frac g,frac b,frac out[])218 rgb_cs_to_gray_cm(gx_device * dev, const gs_gstate *pgs,
219                                    frac r, frac g, frac b, frac out[])
220 {
221     out[0] = color_rgb_to_gray(r, g, b, NULL);
222 }
223 
224 static void
cmyk_cs_to_gray_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])225 cmyk_cs_to_gray_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
226 {
227     out[0] = color_cmyk_to_gray(c, m, y, k, NULL);
228 }
229 
230 static void
gray_cs_to_rgb_cm(gx_device * dev,frac gray,frac out[])231 gray_cs_to_rgb_cm(gx_device * dev, frac gray, frac out[])
232 {
233     out[0] = out[1] = out[2] = gray;
234 }
235 
236 void
rgb_cs_to_rgb_cm(gx_device * dev,const gs_gstate * pgs,frac r,frac g,frac b,frac out[])237 rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs,
238                                   frac r, frac g, frac b, frac out[])
239 {
240     out[0] = r;
241     out[1] = g;
242     out[2] = b;
243 }
244 
245 static void
cmyk_cs_to_rgb_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])246 cmyk_cs_to_rgb_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
247 {
248     color_cmyk_to_rgb(c, m, y, k, NULL, out, dev->memory);
249 }
250 
251 static void
gray_cs_to_rgbk_cm(gx_device * dev,frac gray,frac out[])252 gray_cs_to_rgbk_cm(gx_device * dev, frac gray, frac out[])
253 {
254     out[0] = out[1] = out[2] = frac_0;
255     out[3] = gray;
256 }
257 
258 static void
rgb_cs_to_rgbk_cm(gx_device * dev,const gs_gstate * pgs,frac r,frac g,frac b,frac out[])259 rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs,
260                                   frac r, frac g, frac b, frac out[])
261 {
262     if ((r == g) && (g == b)) {
263         out[0] = out[1] = out[2] = frac_0;
264         out[3] = r;
265     }
266     else {
267         out[0] = r;
268         out[1] = g;
269         out[2] = b;
270         out[3] = frac_0;
271     }
272 }
273 
274 static void
cmyk_cs_to_rgbk_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])275 cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
276 {
277     frac rgb[3];
278     if ((c == frac_0) && (m == frac_0) && (y == frac_0)) {
279         out[0] = out[1] = out[2] = frac_0;
280         out[3] = frac_1 - k;
281     }
282     else {
283         color_cmyk_to_rgb(c, m, y, k, NULL, rgb, dev->memory);
284         rgb_cs_to_rgbk_cm(dev, NULL, rgb[0], rgb[1], rgb[2], out);
285     }
286 }
287 
288 static void
gray_cs_to_cmyk_cm(gx_device * dev,frac gray,frac out[])289 gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[])
290 {
291     out[0] = out[1] = out[2] = frac_0;
292     out[3] = frac_1 - gray;
293 }
294 
295 /*
296  * Default map from DeviceRGB color space to DeviceCMYK color
297  * model. Since this mapping is defined by the PostScript language
298  * it is unlikely that any device with a DeviceCMYK color model
299  * would define this mapping on its own.
300  *
301  * If the gs_gstate is not available, map as though the black
302  * generation and undercolor removal functions are identity
303  * transformations. This mode is used primarily to support the
304  * raster operation (rop) feature of PCL, which requires that
305  * the raster operation be performed in an RGB color space.
306  * Note that default black generation and undercolor removal
307  * functions in PostScript need NOT be identity transformations:
308  * often they are { pop 0 }.
309  */
310 static void
rgb_cs_to_cmyk_cm(gx_device * dev,const gs_gstate * pgs,frac r,frac g,frac b,frac out[])311 rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs,
312                            frac r, frac g, frac b, frac out[])
313 {
314     if (pgs != 0)
315         color_rgb_to_cmyk(r, g, b, pgs, out, dev->memory);
316     else {
317         frac    c = frac_1 - r, m = frac_1 - g, y = frac_1 - b;
318         frac    k = min(c, min(m, y));
319 
320         out[0] = c - k;
321         out[1] = m - k;
322         out[2] = y - k;
323         out[3] = k;
324     }
325 }
326 
327 void
cmyk_cs_to_cmyk_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])328 cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
329 {
330     out[0] = c;
331     out[1] = m;
332     out[2] = y;
333     out[3] = k;
334 }
335 
336 /* The list of default color space to color model conversion routines. */
337 
338 static const gx_cm_color_map_procs DeviceGray_procs = {
339     gray_cs_to_gray_cm, rgb_cs_to_gray_cm, cmyk_cs_to_gray_cm
340 };
341 
342 static const gx_cm_color_map_procs DeviceRGB_procs = {
343     gray_cs_to_rgb_cm, rgb_cs_to_rgb_cm, cmyk_cs_to_rgb_cm
344 };
345 
346 static const gx_cm_color_map_procs DeviceCMYK_procs = {
347     gray_cs_to_cmyk_cm, rgb_cs_to_cmyk_cm, cmyk_cs_to_cmyk_cm
348 };
349 
350 static const gx_cm_color_map_procs DeviceRGBK_procs = {
351     gray_cs_to_rgbk_cm, rgb_cs_to_rgbk_cm, cmyk_cs_to_rgbk_cm
352 };
353 
354 /*
355  * These are the default handlers for returning the list of color space
356  * to color model conversion routines.
357  */
358 const gx_cm_color_map_procs *
gx_default_DevGray_get_color_mapping_procs(const gx_device * dev)359 gx_default_DevGray_get_color_mapping_procs(const gx_device * dev)
360 {
361     return &DeviceGray_procs;
362 }
363 
364 const gx_cm_color_map_procs *
gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev)365 gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev)
366 {
367     return &DeviceRGB_procs;
368 }
369 
370 const gx_cm_color_map_procs *
gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev)371 gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev)
372 {
373     return &DeviceCMYK_procs;
374 }
375 
376 const gx_cm_color_map_procs *
gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev)377 gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev)
378 {
379     return &DeviceRGBK_procs;
380 }
381 
382 const gx_cm_color_map_procs *
gx_error_get_color_mapping_procs(const gx_device * dev)383 gx_error_get_color_mapping_procs(const gx_device * dev)
384 {
385     /*
386      * We should never get here.  If we do then we do not have a "get_color_mapping_procs"
387      * routine for the device. This will be noisy, but better than returning NULL which
388      * would lead to SEGV (Segmentation Fault) errors when this is used.
389      */
390     emprintf1(dev->memory,
391               "No get_color_mapping_procs proc defined for device '%s'\n",
392               dev->dname);
393     switch (dev->color_info.num_components) {
394       case 1:     /* DeviceGray or DeviceInvertGray */
395         return gx_default_DevGray_get_color_mapping_procs(dev);
396 
397       case 3:
398         return gx_default_DevRGB_get_color_mapping_procs(dev);
399 
400       case 4:
401       default:		/* Unknown color model - punt with CMYK */
402         return gx_default_DevCMYK_get_color_mapping_procs(dev);
403     }
404 }
405 
406 /* ----- Default color component name to colorant index conversion routines ------ */
407 
408 #define compare_color_names(pname, name_size, name_str) \
409     (name_size == (int)strlen(name_str) && strncmp(pname, name_str, name_size) == 0)
410 
411 /* Default color component to index for a DeviceGray color model */
412 int
gx_default_DevGray_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)413 gx_default_DevGray_get_color_comp_index(gx_device * dev, const char * pname,
414                                           int name_size, int component_type)
415 {
416     if (compare_color_names(pname, name_size, "Gray") ||
417         compare_color_names(pname, name_size, "Grey"))
418         return 0;
419     else
420         return -1;		    /* Indicate that the component name is "unknown" */
421 }
422 
423 /* Default color component to index for a DeviceRGB color model */
424 int
gx_default_DevRGB_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)425 gx_default_DevRGB_get_color_comp_index(gx_device * dev, const char * pname,
426                                            int name_size, int component_type)
427 {
428     if (compare_color_names(pname, name_size, "Red"))
429         return 0;
430     if (compare_color_names(pname, name_size, "Green"))
431         return 1;
432     if (compare_color_names(pname, name_size, "Blue"))
433         return 2;
434     else
435         return -1;		    /* Indicate that the component name is "unknown" */
436 }
437 
438 /* Default color component to index for a DeviceCMYK color model */
439 int
gx_default_DevCMYK_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)440 gx_default_DevCMYK_get_color_comp_index(gx_device * dev, const char * pname,
441                                             int name_size, int component_type)
442 {
443     if (compare_color_names(pname, name_size, "Cyan"))
444         return 0;
445     if (compare_color_names(pname, name_size, "Magenta"))
446         return 1;
447     if (compare_color_names(pname, name_size, "Yellow"))
448         return 2;
449     if (compare_color_names(pname, name_size, "Black"))
450         return 3;
451     else
452         return -1;		    /* Indicate that the component name is "unknown" */
453 }
454 
455 /* Default color component to index for a DeviceRGBK color model */
456 int
gx_default_DevRGBK_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)457 gx_default_DevRGBK_get_color_comp_index(gx_device * dev, const char * pname,
458                                             int name_size, int component_type)
459 {
460     if (compare_color_names(pname, name_size, "Red"))
461         return 0;
462     if (compare_color_names(pname, name_size, "Green"))
463         return 1;
464     if (compare_color_names(pname, name_size, "Blue"))
465         return 2;
466     if (compare_color_names(pname, name_size, "Black"))
467         return 3;
468     else
469         return -1;		    /* Indicate that the component name is "unknown" */
470 }
471 
472 /* Default color component to index for an unknown color model */
473 int
gx_error_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)474 gx_error_get_color_comp_index(gx_device * dev, const char * pname,
475                                         int name_size, int component_type)
476 {
477     /*
478      * We should never get here.  If we do then we do not have a "get_color_comp_index"
479      * routine for the device.
480      */
481 #ifdef DEBUG
482     dmprintf(dev->memory, "No get_color_comp_index proc defined for device.\n");
483 #endif
484     return -1;			    /* Always return "unknown" component name */
485 }
486 
487 #undef compare_color_names
488 
489 /* ---------------- Device color rendering ---------------- */
490 
491 static cmap_proc_gray(cmap_gray_halftoned);
492 static cmap_proc_gray(cmap_gray_direct);
493 
494 static cmap_proc_rgb(cmap_rgb_halftoned);
495 static cmap_proc_rgb(cmap_rgb_direct);
496 
497 #define cmap_cmyk_halftoned cmap_cmyk_direct
498 static cmap_proc_cmyk(cmap_cmyk_direct);
499 
500 static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned);
501 static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct);
502 
503 /* Procedure names are only guaranteed unique to 23 characters.... */
504 static cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned);
505 static cmap_proc_rgb_alpha(cmap_rgb_alpha_direct);
506 
507 static cmap_proc_separation(cmap_separation_halftoned);
508 static cmap_proc_separation(cmap_separation_direct);
509 
510 static cmap_proc_devicen(cmap_devicen_halftoned);
511 static cmap_proc_devicen(cmap_devicen_direct);
512 
513 static cmap_proc_is_halftoned(cmap_halftoned_is_halftoned);
514 static cmap_proc_is_halftoned(cmap_direct_is_halftoned);
515 
516 static const gx_color_map_procs cmap_few = {
517      cmap_gray_halftoned,
518      cmap_rgb_halftoned,
519      cmap_cmyk_halftoned,
520      cmap_rgb_alpha_halftoned,
521      cmap_separation_halftoned,
522      cmap_devicen_halftoned,
523      cmap_halftoned_is_halftoned
524     };
525 static const gx_color_map_procs cmap_many = {
526      cmap_gray_direct,
527      cmap_rgb_direct,
528      cmap_cmyk_direct,
529      cmap_rgb_alpha_direct,
530      cmap_separation_direct,
531      cmap_devicen_direct,
532      cmap_direct_is_halftoned
533     };
534 
535 const gx_color_map_procs *const cmap_procs_default = &cmap_many;
536 
537 /* Determine the color mapping procedures for a device. */
538 /* Note that the default procedure doesn't consult the gs_gstate. */
539 const gx_color_map_procs *
gx_get_cmap_procs(const gs_gstate * pgs,const gx_device * dev)540 gx_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
541 {
542     return (pgs->get_cmap_procs)(pgs, dev);
543 }
544 
545 const gx_color_map_procs *
gx_default_get_cmap_procs(const gs_gstate * pgs,const gx_device * dev)546 gx_default_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
547 {
548     return (gx_device_must_halftone(dev) ? &cmap_few : &cmap_many);
549 }
550 
551 /* Set the color mapping procedures in the graphics state. */
552 void
gx_set_cmap_procs(gs_gstate * pgs,const gx_device * dev)553 gx_set_cmap_procs(gs_gstate * pgs, const gx_device * dev)
554 {
555     pgs->cmap_procs = gx_get_cmap_procs(pgs, dev);
556 }
557 
558 /* Remap the color in the graphics state. */
559 int
gx_remap_color(gs_gstate * pgs)560 gx_remap_color(gs_gstate * pgs)
561 {
562     const gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
563     int                   code = 0;
564 
565     /* The current color in the graphics state is always used for */
566     /* the texture, never for the source. */
567     /* skip remap if the dev_color is already set and is type "pure" (a common case) */
568     if (!gx_dc_is_pure(gs_currentdevicecolor_inline(pgs)))
569         code = (*pcs->type->remap_color) (gs_currentcolor_inline(pgs),
570                                           pcs, gs_currentdevicecolor_inline(pgs),
571                                           (gs_gstate *) pgs, pgs->device,
572                                           gs_color_select_texture);
573     return code;
574 }
575 
576 /* Indicate that a color space has no underlying concrete space. */
577 const gs_color_space *
gx_no_concrete_space(const gs_color_space * pcs,const gs_gstate * pgs)578 gx_no_concrete_space(const gs_color_space * pcs, const gs_gstate * pgs)
579 {
580     return NULL;
581 }
582 
583 /* Indicate that a color space is concrete. */
584 const gs_color_space *
gx_same_concrete_space(const gs_color_space * pcs,const gs_gstate * pgs)585 gx_same_concrete_space(const gs_color_space * pcs, const gs_gstate * pgs)
586 {
587     return pcs;
588 }
589 
590 /* Indicate that a color cannot be concretized. */
591 int
gx_no_concretize_color(const gs_client_color * pcc,const gs_color_space * pcs,frac * pconc,const gs_gstate * pgs,gx_device * dev)592 gx_no_concretize_color(const gs_client_color * pcc, const gs_color_space * pcs,
593                        frac * pconc, const gs_gstate * pgs, gx_device *dev)
594 {
595     return_error(gs_error_rangecheck);
596 }
597 
598 /* If someone has specified a table for handling named spot colors then we will
599    be attempting to do the special handling to go directly to the device colors
600    here */
601 bool
gx_remap_named_color(const gs_client_color * pcc,const gs_color_space * pcs,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)602 gx_remap_named_color(const gs_client_color * pcc, const gs_color_space * pcs,
603 gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
604 gs_color_select_t select)
605 {
606     gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS];
607     byte *pname;
608     uint name_size;
609     gsicc_rendering_param_t rendering_params;
610     int code;
611     gsicc_namedcolor_t named_color_sep;
612     gsicc_namedcolor_t *named_color_devn = NULL;
613     gsicc_namedcolor_t *named_color_ptr = NULL;
614     uchar num_des_comps = dev->color_info.num_components;
615     uchar k;
616     frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
617     int i = pcs->type->num_components(pcs);
618     cmm_dev_profile_t *dev_profile = NULL;
619     gs_color_space_index type = gs_color_space_get_index(pcs);
620     int num_src_comps = 1;
621 
622     /* Define the rendering intents. */
623     rendering_params.black_point_comp = pgs->blackptcomp;
624     rendering_params.graphics_type_tag = dev->graphics_type_tag;
625     rendering_params.override_icc = false;
626     rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
627     rendering_params.rendering_intent = pgs->renderingintent;
628     rendering_params.cmm = gsCMM_DEFAULT;
629 
630     if (type == gs_color_space_index_Separation) {
631         named_color_sep.colorant_name = pcs->params.separation.sep_name;
632         named_color_sep.name_size = strlen(pcs->params.separation.sep_name);
633         named_color_ptr = &named_color_sep;
634     } else if (type == gs_color_space_index_DeviceN) {
635         char **names = pcs->params.device_n.names;
636         num_src_comps = pcs->params.device_n.num_components;
637         /* Allocate and initialize name structure */
638         named_color_devn =
639             (gsicc_namedcolor_t*)gs_alloc_bytes(dev->memory->non_gc_memory,
640             num_src_comps * sizeof(gsicc_namedcolor_t),
641             "gx_remap_named_color");
642         if (named_color_devn == NULL)
643             return false; /* Clearly a bigger issue. But lets not end here */
644         for (k = 0; k < num_src_comps; k++) {
645             pname = (byte *)names[k];
646             name_size = strlen(names[k]);
647             named_color_devn[k].colorant_name = (char*)pname;
648             named_color_devn[k].name_size = name_size;
649         }
650         named_color_ptr = named_color_devn;
651     } else
652         return false; /* Only sep and deviceN for named color replacement */
653 
654     code = gsicc_transform_named_color(pcc->paint.values, named_color_ptr,
655         num_src_comps, device_values, pgs, dev, NULL, &rendering_params);
656     if (named_color_devn != NULL)
657         gs_free_object(dev->memory->non_gc_memory, named_color_devn,
658             "gx_remap_named_color");
659 
660     if (code == 0) {
661         /* Named color was found and set.  Note that  gsicc_transform_named_color
662            MUST set ALL the colorant values AND they must be in the proper
663            order already.  If we have specified the colorants with
664            -sICCOutputColors (i.e. if you are using an NCLR output profile) then
665            we should be good. If not or if instead one used SeparationColorNames and
666            SeparationOrder to set up the device, then we need to make a copy
667            of the gs_gstate and make sure that we set color_component_map is
668            properly set up for the gx_remap_concrete_devicen proc. */
669         for (k = 0; k < num_des_comps; k++)
670             conc[k] = float2frac(((float)device_values[k]) / 65535.0);
671 
672         /* If we are looking to create the equivalent CMYK value then no need
673            to worry about NCLR profiles or about altering the colorant map */
674         if (!named_color_equivalent_cmyk_colors(pgs)) {
675             /* We need to apply transfer functions, possibily halftone and
676                encode the color for the device. To get proper mapping of the
677                colors to the device positions, you MUST specify -sICCOutputColors
678                which will enumerate the positions of the colorants and enable
679                proper color management for the CMYK portions IF you are using
680                an NCLR output profile. */
681             code = dev_proc(dev, get_profile)(dev, &dev_profile);
682             if (code < 0)
683                 return false;
684 
685             /* Check if the profile is DeviceN (NCLR) */
686             if (dev_profile->device_profile[0]->data_cs == gsNCHANNEL) {
687                 if (dev_profile->spotnames == NULL)
688                     return false;
689                 if (!dev_profile->spotnames->equiv_cmyk_set) {
690                     /* Note that if the improper NCLR profile is used, then the
691                        composite preview will be wrong. */
692                     code = gsicc_set_devicen_equiv_colors(dev, pgs, dev_profile->device_profile[0]);
693                     if (code < 0)
694                         return false;
695                     dev_profile->spotnames->equiv_cmyk_set = true;
696                 }
697                 gx_remap_concrete_devicen(conc, pdc, pgs, dev, select, pcs);
698             } else {
699                 gs_gstate temp_state = *((const gs_gstate *)pgs);
700 
701                 /* No NCLR profile with spot names.  So set up the
702                    color_component_map in the gs_gstate.  Again, note that
703                    gsicc_transform_named_color must have set ALL the device
704                    colors */
705                 for (k = 0; k < dev->color_info.num_components; k++)
706                     temp_state.color_component_map.color_map[k] = k;
707                 temp_state.color_component_map.num_components = dev->color_info.num_components;
708                 gx_remap_concrete_devicen(conc, pdc, &temp_state, dev, select, pcs);
709             }
710         } else {
711             gx_remap_concrete_devicen(conc, pdc, pgs, dev, select, pcs);
712         }
713         /* Save original color space and color info into dev color */
714         i = any_abs(i);
715         for (i--; i >= 0; i--)
716             pdc->ccolor.paint.values[i] = pcc->paint.values[i];
717         pdc->ccolor_valid = true;
718         return true;
719     }
720     return false;
721 }
722 
723 /* By default, remap a color by concretizing it and then remapping the concrete
724    color. */
725 int
gx_default_remap_color(const gs_client_color * pcc,const gs_color_space * pcs,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)726 gx_default_remap_color(const gs_client_color * pcc, const gs_color_space * pcs,
727         gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
728                        gs_color_select_t select)
729 {
730     frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
731     const gs_color_space *pconcs;
732     int i = pcs->type->num_components(pcs);
733     int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pgs, dev);
734     cmm_dev_profile_t *dev_profile;
735 
736     if (code < 0)
737         return code;
738     pconcs = cs_concrete_space(pcs, pgs);
739     if (!pconcs)
740         return gs_note_error(gs_error_undefined);
741     code = dev_proc(dev, get_profile)(dev, &dev_profile);
742     if (code < 0)
743         return code;
744     code = (*pconcs->type->remap_concrete_color)(pconcs, conc, pdc, pgs, dev, select, dev_profile);
745 
746     /* Save original color space and color info into dev color */
747     i = any_abs(i);
748     for (i--; i >= 0; i--)
749         pdc->ccolor.paint.values[i] = pcc->paint.values[i];
750     pdc->ccolor_valid = true;
751     return code;
752 }
753 
754 /* Color remappers for the standard color spaces. */
755 /* Note that we use D... instead of Device... in some places because */
756 /* gcc under VMS only retains 23 characters of procedure names. */
757 
758 /* DeviceGray */
759 int
gx_concretize_DeviceGray(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_gstate * pgs,gx_device * dev)760 gx_concretize_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs,
761                          frac * pconc, const gs_gstate * pgs, gx_device *dev)
762 {
763     pconc[0] = gx_unit_frac(pc->paint.values[0]);
764     return 0;
765 }
766 int
gx_remap_concrete_DGray(const gs_color_space * pcs,const frac * pconc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const cmm_dev_profile_t * dev_profile)767 gx_remap_concrete_DGray(const gs_color_space * pcs, const frac * pconc,
768                         gx_device_color * pdc, const gs_gstate * pgs,
769                         gx_device * dev, gs_color_select_t select,
770                         const cmm_dev_profile_t *dev_profile)
771 {
772     if (pgs->alpha == gx_max_color_value)
773         (*pgs->cmap_procs->map_gray)
774             (pconc[0], pdc, pgs, dev, select);
775     else
776         (*pgs->cmap_procs->map_rgb_alpha)
777             (pconc[0], pconc[0], pconc[0], cv2frac(pgs->alpha),
778              pdc, pgs, dev, select);
779     return 0;
780 }
781 int
gx_remap_DeviceGray(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)782 gx_remap_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs,
783                     gx_device_color * pdc, const gs_gstate * pgs,
784                     gx_device * dev, gs_color_select_t select)
785 {
786     frac fgray = gx_unit_frac(pc->paint.values[0]);
787     int code;
788 
789     /* We are in here due to the fact that we are using a color space that
790        was set in the graphic state before the ICC manager was intitialized
791        and the color space was never actually "installed" and hence set
792        over to a proper ICC color space. We will "install" this color space
793        at this time */
794     if (pgs->icc_manager->default_gray != NULL) {
795         gs_color_space *pcs_notconst = (gs_color_space*) pcs;
796         pcs_notconst->cmm_icc_profile_data = pgs->icc_manager->default_gray;
797         gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "gx_remap_DeviceGray");
798         pcs_notconst->type = &gs_color_space_type_ICC;
799         code =
800             (*pcs_notconst->type->remap_color)(gs_currentcolor_inline(pgs),
801                                                pcs_notconst,
802                                                gs_currentdevicecolor_inline(pgs),
803                                                pgs, pgs->device,
804                                                gs_color_select_texture);
805         return code;
806     }
807 
808     /* Save original color space and color info into dev color */
809     pdc->ccolor.paint.values[0] = pc->paint.values[0];
810     pdc->ccolor_valid = true;
811     if (pgs->alpha == gx_max_color_value)
812         (*pgs->cmap_procs->map_gray)
813             (fgray, pdc, pgs, dev, select);
814     else
815         (*pgs->cmap_procs->map_rgb_alpha)
816             (fgray, fgray, fgray, cv2frac(pgs->alpha), pdc, pgs, dev, select);
817     return 0;
818 }
819 
820 /* DeviceRGB */
821 int
gx_concretize_DeviceRGB(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_gstate * pgs,gx_device * dev)822 gx_concretize_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs,
823                         frac * pconc, const gs_gstate * pgs, gx_device *dev)
824 {
825     pconc[0] = gx_unit_frac(pc->paint.values[0]);
826     pconc[1] = gx_unit_frac(pc->paint.values[1]);
827     pconc[2] = gx_unit_frac(pc->paint.values[2]);
828     return 0;
829 }
830 int
gx_remap_concrete_DRGB(const gs_color_space * pcs,const frac * pconc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const cmm_dev_profile_t * dev_profile)831 gx_remap_concrete_DRGB(const gs_color_space * pcs, const frac * pconc,
832                        gx_device_color * pdc, const gs_gstate * pgs,
833                        gx_device * dev, gs_color_select_t select,
834                        const cmm_dev_profile_t *dev_profile)
835 {
836     if (pgs->alpha == gx_max_color_value)
837         gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2],
838                               pdc, pgs, dev, select);
839     else
840         gx_remap_concrete_rgb_alpha(pconc[0], pconc[1], pconc[2],
841                                     cv2frac(pgs->alpha),
842                                     pdc, pgs, dev, select);
843     return 0;
844 }
845 int
gx_remap_DeviceRGB(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)846 gx_remap_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs,
847         gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
848                    gs_color_select_t select)
849 {
850     frac fred = gx_unit_frac(pc->paint.values[0]), fgreen = gx_unit_frac(pc->paint.values[1]),
851          fblue = gx_unit_frac(pc->paint.values[2]);
852 
853     /* Save original color space and color info into dev color */
854     pdc->ccolor.paint.values[0] = pc->paint.values[0];
855     pdc->ccolor.paint.values[1] = pc->paint.values[1];
856     pdc->ccolor.paint.values[2] = pc->paint.values[2];
857     pdc->ccolor_valid = true;
858     if (pgs->alpha == gx_max_color_value)
859         gx_remap_concrete_rgb(fred, fgreen, fblue,
860                               pdc, pgs, dev, select);
861     else
862         gx_remap_concrete_rgb_alpha(fred, fgreen, fblue, cv2frac(pgs->alpha),
863                                     pdc, pgs, dev, select);
864     return 0;
865 }
866 
867 /* DeviceCMYK */
868 int
gx_concretize_DeviceCMYK(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_gstate * pgs,gx_device * dev)869 gx_concretize_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs,
870                          frac * pconc, const gs_gstate * pgs, gx_device *dev)
871 {
872     pconc[0] = gx_unit_frac(pc->paint.values[0]);
873     pconc[1] = gx_unit_frac(pc->paint.values[1]);
874     pconc[2] = gx_unit_frac(pc->paint.values[2]);
875     pconc[3] = gx_unit_frac(pc->paint.values[3]);
876     return 0;
877 }
878 int
gx_remap_concrete_DCMYK(const gs_color_space * pcs,const frac * pconc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const cmm_dev_profile_t * dev_profile)879 gx_remap_concrete_DCMYK(const gs_color_space * pcs, const frac * pconc,
880                         gx_device_color * pdc, const gs_gstate * pgs,
881                         gx_device * dev, gs_color_select_t select,
882                         const cmm_dev_profile_t *dev_profile)
883 {
884 /****** IGNORE alpha ******/
885     gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3], pdc,
886                            pgs, dev, select, pcs);
887     return 0;
888 }
889 int
gx_remap_DeviceCMYK(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)890 gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs,
891         gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
892                     gs_color_select_t select)
893 {
894 /****** IGNORE alpha ******/
895     /* Save original color space and color info into dev color */
896     pdc->ccolor.paint.values[0] = pc->paint.values[0];
897     pdc->ccolor.paint.values[1] = pc->paint.values[1];
898     pdc->ccolor.paint.values[2] = pc->paint.values[2];
899     pdc->ccolor.paint.values[3] = pc->paint.values[3];
900     pdc->ccolor_valid = true;
901     gx_remap_concrete_cmyk(gx_unit_frac(pc->paint.values[0]),
902                            gx_unit_frac(pc->paint.values[1]),
903                            gx_unit_frac(pc->paint.values[2]),
904                            gx_unit_frac(pc->paint.values[3]),
905                            pdc, pgs, dev, select, pcs);
906     return 0;
907 }
908 
909 /* ------ Render Gray color. ------ */
910 
911 static void
cmap_gray_halftoned(frac gray,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)912 cmap_gray_halftoned(frac gray, gx_device_color * pdc,
913      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
914 {
915     uchar i, ncomps = dev->color_info.num_components;
916     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
917     subclass_color_mappings scm;
918 
919     /* map to the color model */
920     scm = get_color_mapping_procs_subclass(dev);
921     map_gray_subclass(scm, gray, cm_comps);
922 
923     /* apply the transfer function(s); convert to color values */
924     if (pgs->effective_transfer_non_identity_count == 0) {
925         if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
926             check_cmyk_color_model_comps(dev);
927     } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
928         for (i = 0; i < ncomps; i++)
929             cm_comps[i] = gx_map_color_frac(pgs,
930                                 cm_comps[i], effective_transfer[i]);
931     else {
932         if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
933             check_cmyk_color_model_comps(dev);
934         if (dev->color_info.opmode == GX_CINFO_OPMODE) {  /* CMYK-like color space */
935             i = dev->color_info.black_component;
936             if (i < ncomps)
937                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
938                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
939         } else {
940             for (i = 0; i < ncomps; i++)
941                     cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
942                             (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
943         }
944     }
945     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
946                                         &pgs->screen_phase[select]) == 1)
947         gx_color_load_select(pdc, pgs, dev, select);
948 }
949 
950 static void
cmap_gray_direct(frac gray,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)951 cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
952                  gx_device * dev, gs_color_select_t select)
953 {
954     uchar i, ncomps = dev->color_info.num_components;
955     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
956     gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
957     gx_color_index color;
958     subclass_color_mappings scm;
959 
960     /* map to the color model */
961     scm = get_color_mapping_procs_subclass(dev);
962     map_gray_subclass(scm, gray, cm_comps);
963 
964     /* apply the transfer function(s); convert to color values */
965     if (pgs->effective_transfer_non_identity_count == 0) {
966         if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
967                 check_cmyk_color_model_comps(dev);
968         for (i = 0; i < ncomps; i++)
969             cv[i] = frac2cv(cm_comps[i]);
970     } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
971         for (i = 0; i < ncomps; i++) {
972             cm_comps[i] = gx_map_color_frac(pgs,
973                                 cm_comps[i], effective_transfer[i]);
974             cv[i] = frac2cv(cm_comps[i]);
975         }
976     else {
977         if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
978             check_cmyk_color_model_comps(dev);
979         if (dev->color_info.opmode == GX_CINFO_OPMODE) {  /* CMYK-like color space */
980             i = dev->color_info.black_component;
981             if (i < ncomps)
982                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
983                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
984             for (i = 0; i < ncomps; i++)
985                 cv[i] = frac2cv(cm_comps[i]);
986         } else {
987             for (i = 0; i < ncomps; i++) {
988                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
989                             (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
990                 cv[i] = frac2cv(cm_comps[i]);
991             }
992         }
993     }
994     /* encode as a color index */
995     color = dev_proc(dev, encode_color)(dev, cv);
996 
997     /* check if the encoding was successful; we presume failure is rare */
998     if (color != gx_no_color_index) {
999         color_set_pure(pdc, color);
1000         return;
1001     }
1002     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1003                                         &pgs->screen_phase[select]) == 1)
1004         gx_color_load_select(pdc, pgs, dev, select);
1005 }
1006 
1007 /* ------ Render RGB color. ------ */
1008 
1009 static void
cmap_rgb_halftoned(frac r,frac g,frac b,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)1010 cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc,
1011      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
1012 {
1013     uchar i, ncomps = dev->color_info.num_components;
1014     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1015     subclass_color_mappings scm;
1016 
1017     /* map to the color model */
1018     scm = get_color_mapping_procs_subclass(dev);
1019     map_rgb_subclass(scm, pgs, r, g, b, cm_comps);
1020 
1021     /* apply the transfer function(s); convert to color values */
1022     if (pgs->effective_transfer_non_identity_count != 0) {
1023         if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1024             for (i = 0; i < ncomps; i++)
1025                 cm_comps[i] = gx_map_color_frac(pgs,
1026                                 cm_comps[i], effective_transfer[i]);
1027         else
1028             for (i = 0; i < ncomps; i++)
1029                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1030                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1031     }
1032 
1033     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1034                                         &pgs->screen_phase[select]) == 1)
1035         gx_color_load_select(pdc, pgs, dev, select);
1036 }
1037 
1038 static void
cmap_rgb_direct(frac r,frac g,frac b,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)1039 cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
1040      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
1041 {
1042     uchar i, ncomps = dev->color_info.num_components;
1043     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1044     gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1045     gx_color_index color;
1046     subclass_color_mappings scm;
1047 
1048     /* map to the color model */
1049     scm = get_color_mapping_procs_subclass(dev);
1050     map_rgb_subclass(scm, pgs, r, g, b, cm_comps);
1051 
1052     /* apply the transfer function(s); convert to color values */
1053     if (pgs->effective_transfer_non_identity_count == 0) {
1054         for (i = 0; i < ncomps; i++)
1055             cv[i] = frac2cv(cm_comps[i]);
1056     } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1057         for (i = 0; i < ncomps; i++) {
1058             cm_comps[i] = gx_map_color_frac(pgs,
1059                                 cm_comps[i], effective_transfer[i]);
1060             cv[i] = frac2cv(cm_comps[i]);
1061         }
1062     else
1063         for (i = 0; i < ncomps; i++) {
1064             cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1065                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1066             cv[i] = frac2cv(cm_comps[i]);
1067         }
1068 
1069     /* encode as a color index */
1070     color = dev_proc(dev, encode_color)(dev, cv);
1071 
1072     /* check if the encoding was successful; we presume failure is rare */
1073     if (color != gx_no_color_index) {
1074         color_set_pure(pdc, color);
1075         return;
1076     }
1077     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1078                                         &pgs->screen_phase[select]) == 1)
1079         gx_color_load_select(pdc, pgs, dev, select);
1080 }
1081 
1082 /* ------ Render CMYK color. ------ */
1083 
1084 static void
cmap_cmyk_direct(frac c,frac m,frac y,frac k,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const gs_color_space * source_pcs)1085 cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
1086      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
1087      const gs_color_space *source_pcs)
1088 {
1089     uchar i, ncomps = dev->color_info.num_components;
1090     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1091     gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1092     gx_color_index color;
1093     uint black_index;
1094     cmm_dev_profile_t *dev_profile;
1095     gsicc_colorbuffer_t src_space = gsUNDEFINED;
1096     bool gray_to_k;
1097     subclass_color_mappings scm;
1098 
1099     /* map to the color model */
1100     scm = get_color_mapping_procs_subclass(dev);
1101     map_cmyk_subclass(scm, c, m, y, k, cm_comps);
1102 
1103     /* apply the transfer function(s); convert to color values */
1104     if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
1105         if (pgs->effective_transfer_non_identity_count != 0)
1106             for (i = 0; i < ncomps; i++)
1107                 cm_comps[i] = gx_map_color_frac(pgs,
1108                                 cm_comps[i], effective_transfer[i]);
1109     } else {
1110         /* Check if source space is gray.  In this case we are to use only the
1111            transfer function on the K channel.  Do this only if gray to K is
1112            also set */
1113         dev_proc(dev, get_profile)(dev, &dev_profile);
1114         gray_to_k = dev_profile->devicegraytok;
1115         if (source_pcs != NULL && source_pcs->cmm_icc_profile_data != NULL) {
1116             src_space = source_pcs->cmm_icc_profile_data->data_cs;
1117         } else if (source_pcs != NULL && source_pcs->icc_equivalent != NULL) {
1118             src_space = source_pcs->icc_equivalent->cmm_icc_profile_data->data_cs;
1119         }
1120         if (src_space == gsGRAY && gray_to_k) {
1121             /* Find the black channel location */
1122             black_index = dev_proc(dev, get_color_comp_index)(dev, "Black",
1123                                     strlen("Black"), SEPARATION_NAME);
1124             cm_comps[black_index] = frac_1 - gx_map_color_frac(pgs,
1125                                     (frac)(frac_1 - cm_comps[black_index]),
1126                                     effective_transfer[black_index]);
1127         } else if (pgs->effective_transfer_non_identity_count != 0)
1128             for (i = 0; i < ncomps; i++)
1129                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1130                             (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1131     }
1132     /* We make a test for direct vs. halftoned, rather than */
1133     /* duplicating most of the code of this procedure. */
1134     if (gx_device_must_halftone(dev)) {
1135         if (gx_render_device_DeviceN(cm_comps, pdc, dev,
1136                     pgs->dev_ht, &pgs->screen_phase[select]) == 1)
1137             gx_color_load_select(pdc, pgs, dev, select);
1138         return;
1139     }
1140     /* if output device supports devn, we need to make sure we send it the
1141        proper color type */
1142     if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1143         for (i = 0; i < ncomps; i++)
1144             pdc->colors.devn.values[i] = frac2cv(cm_comps[i]);
1145         pdc->type = gx_dc_type_devn;
1146     } else {
1147         for (i = 0; i < ncomps; i++)
1148             cv[i] = frac2cv(cm_comps[i]);
1149         color = dev_proc(dev, encode_color)(dev, cv);
1150         if (color != gx_no_color_index)
1151             color_set_pure(pdc, color);
1152         else {
1153             if (gx_render_device_DeviceN(cm_comps, pdc, dev,
1154                         pgs->dev_ht, &pgs->screen_phase[select]) == 1)
1155                 gx_color_load_select(pdc, pgs, dev, select);
1156         }
1157     }
1158     return;
1159 }
1160 
1161 static void
cmap_rgb_alpha_halftoned(frac r,frac g,frac b,frac alpha,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)1162 cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha,
1163         gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
1164                          gs_color_select_t select)
1165 {
1166     uchar i, ncomps = dev->color_info.num_components;
1167     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1168     subclass_color_mappings scm;
1169 
1170     /* map to the color model */
1171     scm = get_color_mapping_procs_subclass(dev);
1172     map_rgb_subclass(scm, pgs, r, g, b, cm_comps);
1173 
1174     /* pre-multiply to account for the alpha weighting */
1175     if (alpha != frac_1) {
1176 #ifdef PREMULTIPLY_TOWARDS_WHITE
1177         frac alpha_bias = frac_1 - alpha;
1178 #else
1179         frac alpha_bias = 0;
1180 #endif
1181 
1182         for (i = 0; i < ncomps; i++)
1183             cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias;
1184     }
1185 
1186     /* apply the transfer function(s); convert to color values */
1187     if (pgs->effective_transfer_non_identity_count != 0) {
1188         if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1189             for (i = 0; i < ncomps; i++)
1190                 cm_comps[i] = gx_map_color_frac(pgs,
1191                                 cm_comps[i], effective_transfer[i]);
1192         else
1193             for (i = 0; i < ncomps; i++)
1194                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1195                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1196     }
1197 
1198     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1199                                         &pgs->screen_phase[select]) == 1)
1200         gx_color_load_select(pdc, pgs, dev, select);
1201 }
1202 
1203 static void
cmap_rgb_alpha_direct(frac r,frac g,frac b,frac alpha,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select)1204 cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc,
1205      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
1206 {
1207     uchar i, ncomps = dev->color_info.num_components;
1208     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1209     gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1210     gx_color_index color;
1211     subclass_color_mappings scm;
1212 
1213     /* map to the color model */
1214     scm = get_color_mapping_procs_subclass(dev);
1215     map_rgb_subclass(scm, pgs, r, g, b, cm_comps);
1216 
1217     /* pre-multiply to account for the alpha weighting */
1218     if (alpha != frac_1) {
1219 #ifdef PREMULTIPLY_TOWARDS_WHITE
1220         frac alpha_bias = frac_1 - alpha;
1221 #else
1222         frac alpha_bias = 0;
1223 #endif
1224 
1225         for (i = 0; i < ncomps; i++)
1226             cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias;
1227     }
1228 
1229     /* apply the transfer function(s); convert to color values */
1230     if (pgs->effective_transfer_non_identity_count == 0)
1231         for (i = 0; i < ncomps; i++)
1232             cv[i] = frac2cv(cm_comps[i]);
1233     else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1234         for (i = 0; i < ncomps; i++)
1235             cv[i] = frac2cv(gx_map_color_frac(pgs,
1236                                 cm_comps[i], effective_transfer[i]));
1237     else
1238         for (i = 0; i < ncomps; i++)
1239             cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
1240                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
1241 
1242     /* encode as a color index */
1243     if (dev_proc(dev, map_rgb_alpha_color) != gx_default_map_rgb_alpha_color &&
1244          (cv_alpha = frac2cv(alpha)) != gx_max_color_value)
1245         color = dev_proc(dev, map_rgb_alpha_color)(dev, cv[0], cv[1], cv[2], cv_alpha);
1246     else
1247         color = dev_proc(dev, encode_color)(dev, cv);
1248 
1249     /* check if the encoding was successful; we presume failure is rare */
1250     if (color != gx_no_color_index) {
1251         color_set_pure(pdc, color);
1252         return;
1253     }
1254     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1255                                         &pgs->screen_phase[select]) == 1)
1256         gx_color_load_select(pdc, pgs, dev, select);
1257 }
1258 
1259 /* ------ Render Separation All color. ------ */
1260 
1261 /*
1262  * This routine maps DeviceN components into the order of the device's
1263  * colorants.
1264  *
1265  * Parameters:
1266  *    pcc - Pointer to DeviceN components.
1267  *    pcolor_component_map - Map from DeviceN to the Devices colorants.
1268  *        A negative value indicates component is not to be mapped.
1269  *    plist - Pointer to list for mapped components
1270  *
1271  * Returns:
1272  *    Mapped components in plist.
1273  */
1274 static inline void
map_components_to_colorants(const frac * pcc,const gs_devicen_color_map * pcolor_component_map,frac * plist)1275 map_components_to_colorants(const frac * pcc,
1276         const gs_devicen_color_map * pcolor_component_map, frac * plist)
1277 {
1278     int i = pcolor_component_map->num_colorants - 1;
1279     int pos;
1280 
1281     /* Clear all output colorants first */
1282     for (; i >= 0; i--) {
1283         plist[i] = frac_0;
1284     }
1285 
1286     /* Map color components into output list */
1287     for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
1288         pos = pcolor_component_map->color_map[i];
1289         if (pos >= 0)
1290             plist[pos] = pcc[i];
1291     }
1292 }
1293 
1294 static bool
named_color_supported(const gs_gstate * pgs)1295 named_color_supported(const gs_gstate * pgs)
1296 {
1297     gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
1298     gs_color_space_index type = gs_color_space_get_index(pcs);
1299 
1300     if (pgs->icc_manager->device_named == NULL)
1301         return false;
1302 
1303     if (type == gs_color_space_index_Separation && pcs->params.separation.named_color_supported)
1304         return true;
1305 
1306     if (type == gs_color_space_index_DeviceN && pcs->params.device_n.named_color_supported)
1307         return true;
1308 
1309     return false;
1310 }
1311 
1312 /* Routines for handling CM of CMYK components of a DeviceN color space */
1313 static bool
devicen_has_cmyk(gx_device * dev,cmm_profile_t * des_profile)1314 devicen_has_cmyk(gx_device * dev, cmm_profile_t *des_profile)
1315 {
1316     gs_devn_params *devn_params;
1317 
1318     devn_params = dev_proc(dev, ret_devn_params)(dev);
1319     if (devn_params == NULL) {
1320         if (des_profile != NULL && des_profile->data_cs == gsCMYK)
1321             return true;
1322         else
1323             return false;
1324     }
1325     return(devn_params->num_std_colorant_names == 4);
1326 }
1327 
1328 static void
devicen_sep_icc_cmyk(frac cm_comps[],const gs_gstate * pgs,const gs_color_space * pcs,gx_device * dev)1329 devicen_sep_icc_cmyk(frac cm_comps[], const gs_gstate * pgs,
1330     const gs_color_space * pcs, gx_device *dev)
1331 {
1332     gsicc_link_t *icc_link;
1333     gsicc_rendering_param_t rendering_params;
1334     unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS];
1335     unsigned short psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
1336     int k, code;
1337     unsigned short *psrc_temp;
1338     gsicc_rendering_param_t render_cond;
1339     cmm_dev_profile_t *dev_profile = NULL;
1340     cmm_profile_t *des_profile = NULL;
1341     cmm_profile_t *src_profile = pgs->icc_manager->default_cmyk;
1342 
1343     code = dev_proc(dev, get_profile)(dev, &dev_profile);
1344 
1345     /* If we can't transform them, we will just leave them as is. */
1346     if (code < 0)
1347         return;
1348 
1349     gsicc_extract_profile(dev->graphics_type_tag,
1350         dev_profile, &des_profile, &render_cond);
1351     /* Define the rendering intents. */
1352     rendering_params.black_point_comp = pgs->blackptcomp;
1353     rendering_params.graphics_type_tag = dev->graphics_type_tag;
1354     rendering_params.override_icc = false;
1355     rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
1356     rendering_params.rendering_intent = pgs->renderingintent;
1357     rendering_params.cmm = gsCMM_DEFAULT;
1358     /* Sigh, frac to full 16 bit.  Need to clean this up */
1359     for (k = 0; k < 4; k++) {
1360         psrc[k] = frac2cv(cm_comps[k]);
1361     }
1362 
1363     /* Determine what src profile to use.  First choice is the attributes
1364        process color space if it is the correct type.  Second choice is
1365        the alternate tint transform color space if it is the correct type.
1366        Third type is default_cmyk.  If we have an issue with bad profiles then
1367        the color values will just remain as they were from the source */
1368     if (gs_color_space_get_index(pcs) == gs_color_space_index_DeviceN) {
1369         if (pcs->params.device_n.devn_process_space != NULL &&
1370             pcs->params.device_n.devn_process_space->cmm_icc_profile_data != NULL &&
1371             pcs->params.device_n.devn_process_space->cmm_icc_profile_data->data_cs == gsCMYK) {
1372             src_profile = pcs->params.device_n.devn_process_space->cmm_icc_profile_data;
1373         } else if (pcs->base_space != NULL &&
1374             pcs->base_space->cmm_icc_profile_data != NULL &&
1375             pcs->base_space->cmm_icc_profile_data->data_cs == gsCMYK &&
1376             USE_ALT_MAP) {
1377             src_profile = pcs->base_space->cmm_icc_profile_data;
1378         }
1379     } else if (gs_color_space_get_index(pcs) == gs_color_space_index_Separation) {
1380         if (pcs->base_space != NULL &&
1381             pcs->base_space->cmm_icc_profile_data != NULL &&
1382             pcs->base_space->cmm_icc_profile_data->data_cs == gsCMYK &&
1383             USE_ALT_MAP) {
1384             src_profile = pcs->base_space->cmm_icc_profile_data;
1385         }
1386     }
1387 
1388     icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
1389         &rendering_params, pgs->memory, dev_profile->devicegraytok);
1390 
1391     if (icc_link == NULL && src_profile != pgs->icc_manager->default_cmyk) {
1392         icc_link = gsicc_get_link_profile(pgs, dev,
1393             pgs->icc_manager->default_cmyk, des_profile,
1394             &rendering_params, pgs->memory, dev_profile->devicegraytok);
1395     }
1396 
1397     /* If we can't transform them, we will just leave them as is. */
1398     if (icc_link == NULL)
1399         return;
1400 
1401     /* Transform the color */
1402     if (icc_link->is_identity) {
1403         psrc_temp = &(psrc[0]);
1404     } else {
1405         /* Transform the color */
1406         psrc_temp = &(psrc_cm[0]);
1407         (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
1408     }
1409     /* This needs to be optimized */
1410     for (k = 0; k < 4; k++) {
1411         cm_comps[k] = float2frac(((float)psrc_temp[k]) / 65535.0);
1412     }
1413     /* Release the link */
1414     gsicc_release_link(icc_link);
1415 }
1416 
1417 static void
cmap_separation_halftoned(frac all,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const gs_color_space * pcs)1418 cmap_separation_halftoned(frac all, gx_device_color * pdc,
1419      const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
1420      const gs_color_space *pcs)
1421 {
1422     uchar i, ncomps = dev->color_info.num_components;
1423     bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1424     frac comp_value = all;
1425     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1426     gsicc_rendering_param_t render_cond;
1427     cmm_dev_profile_t *dev_profile = NULL;
1428     cmm_profile_t *des_profile = NULL;
1429 
1430     dev_proc(dev, get_profile)(dev, &dev_profile);
1431     gsicc_extract_profile(dev->graphics_type_tag,
1432         dev_profile, &des_profile, &render_cond);
1433 
1434     if (pgs->color_component_map.sep_type == SEP_ALL) {
1435         /*
1436          * Invert the photometric interpretation for additive
1437          * color spaces because separations are always subtractive.
1438          */
1439         if (additive)
1440             comp_value = frac_1 - comp_value;
1441 
1442         /* Use the "all" value for all components */
1443         for (i = 0; i < pgs->color_component_map.num_colorants; i++)
1444             cm_comps[i] = comp_value;
1445     } else {
1446         /* map to the color model */
1447         map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps);
1448     }
1449 
1450     if (devicen_has_cmyk(dev, des_profile) &&
1451         des_profile->data_cs == gsCMYK &&
1452         !named_color_supported(pgs)) {
1453         devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1454     }
1455 
1456     /* apply the transfer function(s); convert to color values */
1457     if (pgs->effective_transfer_non_identity_count != 0) {
1458         if (additive)
1459             for (i = 0; i < ncomps; i++)
1460                 cm_comps[i] = gx_map_color_frac(pgs,
1461                                 cm_comps[i], effective_transfer[i]);
1462         else
1463             for (i = 0; i < ncomps; i++)
1464                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1465                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1466     }
1467 
1468     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1469                                         &pgs->screen_phase[select]) == 1)
1470         gx_color_load_select(pdc, pgs, dev, select);
1471 }
1472 
1473 static void
cmap_separation_direct(frac all,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const gs_color_space * pcs)1474 cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
1475                  gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
1476 {
1477     uchar i, ncomps = dev->color_info.num_components;
1478     bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1479     frac comp_value = all;
1480     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1481     gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1482     gx_color_index color;
1483     bool use_rgb2dev_icc = false;
1484     gsicc_rendering_param_t render_cond;
1485     cmm_dev_profile_t *dev_profile = NULL;
1486     cmm_profile_t *des_profile = NULL;
1487 
1488     dev_proc(dev, get_profile)(dev,  &dev_profile);
1489     gsicc_extract_profile(dev->graphics_type_tag,
1490                           dev_profile, &des_profile, &render_cond);
1491     if (pgs->color_component_map.sep_type == SEP_ALL) {
1492         /*
1493          * Invert the photometric interpretation for additive
1494          * color spaces because separations are always subtractive.
1495          */
1496         if (additive)
1497             comp_value = frac_1 - comp_value;
1498 
1499         /* Use the "all" value for all components */
1500         for (i = 0; i < pgs->color_component_map.num_colorants; i++)
1501             cm_comps[i] = comp_value;
1502         /* If our device space is CIELAB then we really want to treat this
1503            as RGB during the fill up here of the separation value and then
1504            go ahead and convert from RGB to CIELAB.  The PDF spec is not clear
1505            on how addivite devices should behave with the ALL option but it
1506            is clear from testing the AR 10 does simply do the RGB = 1 - INK
1507            type of mapping */
1508         if (des_profile->data_cs == gsCIELAB || des_profile->islab) {
1509             use_rgb2dev_icc = true;
1510         }
1511     }
1512     else {
1513         /* map to the color model */
1514         map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps);
1515     }
1516 
1517     /* Check if we have the standard colorants.  If yes, then we will apply
1518       ICC color management to those colorants. */
1519     if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK &&
1520         !named_color_supported(pgs)) {
1521         /* We need to do a CMYK to CMYK conversion here.  This will always
1522            use the default CMYK profile and the device's output profile.
1523            We probably need to add some checking here
1524            and possibly permute the colorants, much as is done on the input
1525            side for the case when we add DeviceN icc source profiles for use
1526            in PDF and PS data. Also, don't do this if we are doing mapping
1527            through the named color mapping.  */
1528         devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1529     }
1530 
1531     /* apply the transfer function(s); convert to color values */
1532     if (pgs->effective_transfer_non_identity_count == 0)
1533         for (i = 0; i < ncomps; i++)
1534             cv[i] = frac2cv(cm_comps[i]);
1535     else if (additive)
1536         for (i = 0; i < ncomps; i++) {
1537             cm_comps[i] = gx_map_color_frac(pgs,
1538                                 cm_comps[i], effective_transfer[i]);
1539             cv[i] = frac2cv(cm_comps[i]);
1540         }
1541     else
1542         for (i = 0; i < ncomps; i++) {
1543             cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1544                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1545             cv[i] = frac2cv(cm_comps[i]);
1546         }
1547 
1548     if (use_rgb2dev_icc && pgs->icc_manager->default_rgb != NULL) {
1549         /* After the transfer function go ahead and do the mapping from RGB to
1550            the device profile. */
1551         gsicc_link_t *icc_link;
1552         gsicc_rendering_param_t rendering_params;
1553         unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
1554 
1555         rendering_params.black_point_comp = pgs->blackptcomp;
1556         rendering_params.graphics_type_tag = dev->graphics_type_tag;
1557         rendering_params.override_icc = false;
1558         rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
1559         rendering_params.rendering_intent = pgs->renderingintent;
1560         rendering_params.cmm = gsCMM_DEFAULT;
1561 
1562         icc_link = gsicc_get_link_profile(pgs, dev, pgs->icc_manager->default_rgb,
1563                                           des_profile, &rendering_params,
1564                                           pgs->memory, dev_profile->devicegraytok);
1565         /* Transform the color */
1566         for (i = 0; i < ncomps; i++) {
1567             psrc[i] = cv[i];
1568         }
1569         (icc_link->procs.map_color)(dev, icc_link, &(psrc[0]), &(psrc_cm[0]), 2);
1570         gsicc_release_link(icc_link);
1571         for (i = 0; i < ncomps; i++) {
1572             cv[i] = psrc_cm[i];
1573         }
1574     }
1575     /* if output device supports devn, we need to make sure we send it the
1576        proper color type */
1577     if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1578         for (i = 0; i < ncomps; i++)
1579             pdc->colors.devn.values[i] = cv[i];
1580         pdc->type = gx_dc_type_devn;
1581         return;
1582     }
1583 
1584     /* encode as a color index */
1585     color = dev_proc(dev, encode_color)(dev, cv);
1586 
1587     /* check if the encoding was successful; we presume failure is rare */
1588     if (color != gx_no_color_index) {
1589         color_set_pure(pdc, color);
1590         return;
1591     }
1592 
1593     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1594                                         &pgs->screen_phase[select]) == 1)
1595         gx_color_load_select(pdc, pgs, dev, select);
1596 }
1597 
1598 /* ------ DeviceN color mapping */
1599 
1600 /*
1601  * This routine is called to map a DeviceN colorspace to a DeviceN
1602  * output device which requires halftoning.  T
1603  */
1604 static void
cmap_devicen_halftoned(const frac * pcc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const gs_color_space * pcs)1605 cmap_devicen_halftoned(const frac * pcc,
1606     gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
1607     gs_color_select_t select, const gs_color_space *pcs)
1608 {
1609     uchar i, ncomps = dev->color_info.num_components;
1610     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1611     gsicc_rendering_param_t render_cond;
1612     cmm_dev_profile_t *dev_profile = NULL;
1613     cmm_profile_t *des_profile = NULL;
1614 
1615     dev_proc(dev, get_profile)(dev,  &dev_profile);
1616     gsicc_extract_profile(dev->graphics_type_tag,
1617                           dev_profile, &des_profile, &render_cond);
1618     /* map to the color model */
1619     map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);
1620     /* See comments in cmap_devicen_direct for details on below operations */
1621     if (devicen_has_cmyk(dev, des_profile) &&
1622         des_profile->data_cs == gsCMYK &&
1623         !named_color_supported(pgs)) {
1624         devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1625     }
1626     /* apply the transfer function(s); convert to color values */
1627     if (pgs->effective_transfer_non_identity_count != 0) {
1628         if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1629             for (i = 0; i < ncomps; i++)
1630                 cm_comps[i] = gx_map_color_frac(pgs,
1631                                 cm_comps[i], effective_transfer[i]);
1632         else
1633             for (i = 0; i < ncomps; i++)
1634                 cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1635                         (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1636     }
1637 
1638     /* We need to finish halftoning */
1639     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1640                                         &pgs->screen_phase[select]) == 1)
1641         gx_color_load_select(pdc, pgs, dev, select);
1642 }
1643 
1644 /*
1645  * This routine is called to map a DeviceN colorspace to a DeviceN
1646  * output device which does not require halftoning.
1647  */
1648 static void
cmap_devicen_direct(const frac * pcc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,gs_color_select_t select,const gs_color_space * pcs)1649 cmap_devicen_direct(const frac * pcc,
1650     gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
1651     gs_color_select_t select, const gs_color_space *pcs)
1652 {
1653     uchar i, ncomps = dev->color_info.num_components;
1654     frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1655     gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1656     gx_color_index color;
1657     gsicc_rendering_param_t render_cond;
1658     cmm_dev_profile_t *dev_profile = NULL;
1659     cmm_profile_t *des_profile = NULL;
1660 
1661     dev_proc(dev, get_profile)(dev,  &dev_profile);
1662     gsicc_extract_profile(dev->graphics_type_tag,
1663                           dev_profile, &des_profile, &render_cond);
1664     /*   See the comment below */
1665     /* map to the color model */
1666     if (dev_profile->spotnames != NULL && dev_profile->spotnames->equiv_cmyk_set) {
1667         map_components_to_colorants(pcc, dev_profile->spotnames->color_map,
1668                                     cm_comps);
1669     } else {
1670         map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);
1671     }
1672     /*  Check if we have the standard colorants.  If yes, then we will apply
1673        ICC color management to those colorants. To understand why, consider
1674        the example where I have a Device with CMYK + O  and I have a
1675        DeviceN color in the document that is specified for any set of
1676        these colorants, and suppose that I let them pass through
1677        witout any color management.  This is probably  not the
1678        desired effect since I could have a DeviceN color fill that had 10% C,
1679        20% M 0% Y 0% K and 0% O.  I would like this to look the same
1680        as a CMYK color that will be color managed and specified with 10% C,
1681        20% M 0% Y 0% K. Hence the CMYK values should go through the same
1682        color management as a stand alone CMYK value.  */
1683     if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK &&
1684         !named_color_supported(pgs)) {
1685         /* We need to do a CMYK to CMYK conversion here.  This will always
1686            use the default CMYK profile and the device's output profile.
1687            We probably need to add some checking here
1688            and possibly permute the colorants, much as is done on the input
1689            side for the case when we add DeviceN icc source profiles for use
1690            in PDF and PS data. Also, don't do this if we are doing mapping
1691            through the named color mapping.  */
1692         devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1693     }
1694     /* apply the transfer function(s); convert to color values.
1695        assign directly if output device supports devn */
1696     if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1697         if (pgs->effective_transfer_non_identity_count == 0)
1698             for (i = 0; i < ncomps; i++)
1699                 pdc->colors.devn.values[i] = frac2cv(cm_comps[i]);
1700         else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1701             for (i = 0; i < ncomps; i++)
1702                 pdc->colors.devn.values[i] = frac2cv(gx_map_color_frac(pgs,
1703                                     cm_comps[i], effective_transfer[i]));
1704         else
1705             for (i = 0; i < ncomps; i++)
1706                 pdc->colors.devn.values[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
1707                             (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
1708         pdc->type = gx_dc_type_devn;
1709         return;
1710     }
1711 
1712     if (pgs->effective_transfer_non_identity_count == 0)
1713         for (i = 0; i < ncomps; i++)
1714             cv[i] = frac2cv(cm_comps[i]);
1715     else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1716         for (i = 0; i < ncomps; i++) {
1717             cm_comps[i] = gx_map_color_frac(pgs,
1718                                     cm_comps[i], effective_transfer[i]);
1719             cv[i] = frac2cv(cm_comps[i]);
1720         }
1721     else
1722         for (i = 0; i < ncomps; i++) {
1723             cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1724                             (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1725             cv[i] = frac2cv(cm_comps[i]);
1726         }
1727     /* encode as a color index */
1728     color = dev_proc(dev, encode_color)(dev, cv);
1729     /* check if the encoding was successful; we presume failure is rare */
1730     if (color != gx_no_color_index) {
1731         color_set_pure(pdc, color);
1732         return;
1733     }
1734     if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht,
1735                                         &pgs->screen_phase[select]) == 1)
1736         gx_color_load_select(pdc, pgs, dev, select);
1737 }
1738 
1739 /* ------ Halftoning check ----- */
1740 
1741 static bool
cmap_halftoned_is_halftoned(const gs_gstate * pgs,gx_device * dev)1742 cmap_halftoned_is_halftoned(const gs_gstate * pgs, gx_device * dev)
1743 {
1744     return true;
1745 }
1746 
1747 static bool
cmap_direct_is_halftoned(const gs_gstate * pgs,gx_device * dev)1748 cmap_direct_is_halftoned(const gs_gstate * pgs, gx_device * dev)
1749 {
1750     return false;
1751 }
1752 
1753 /* ------ Transfer function mapping ------ */
1754 
1755 /* Define an identity transfer function. */
1756 float
gs_identity_transfer(double value,const gx_transfer_map * pmap)1757 gs_identity_transfer(double value, const gx_transfer_map * pmap)
1758 {
1759     return (float) value;
1760 }
1761 
1762 /* Define the generic transfer function for the library layer. */
1763 /* This just returns what's already in the map. */
1764 float
gs_mapped_transfer(double value,const gx_transfer_map * pmap)1765 gs_mapped_transfer(double value, const gx_transfer_map * pmap)
1766 {
1767     return gx_map_color_float(pmap, value);
1768 }
1769 
1770 /* Set a transfer map to the identity map. */
1771 void
gx_set_identity_transfer(gx_transfer_map * pmap)1772 gx_set_identity_transfer(gx_transfer_map *pmap)
1773 {
1774     int i;
1775 
1776     pmap->proc = gs_identity_transfer;
1777     /* We still have to fill in the cached values. */
1778     for (i = 0; i < transfer_map_size; ++i)
1779         pmap->values[i] = bits2frac(i, log2_transfer_map_size);
1780 }
1781 
1782 #if FRAC_MAP_INTERPOLATE	/* NOTA BENE */
1783 
1784 /* Map a color fraction through a transfer map. */
1785 /* We only use this if we are interpolating. */
1786 frac
gx_color_frac_map(frac cv,const frac * values)1787 gx_color_frac_map(frac cv, const frac * values)
1788 {
1789 #define cp_frac_bits (frac_bits - log2_transfer_map_size)
1790     int cmi = frac2bits_floor(cv, log2_transfer_map_size);
1791     frac mv = values[cmi];
1792     int rem, mdv;
1793 
1794     /* Interpolate between two adjacent values if needed. */
1795     rem = cv - bits2frac(cmi, log2_transfer_map_size);
1796     if (rem == 0)
1797         return mv;
1798     mdv = values[cmi + 1] - mv;
1799 #if ARCH_INTS_ARE_SHORT
1800     /* Only use long multiplication if necessary. */
1801     if (mdv < -(1 << (16 - cp_frac_bits)) ||
1802         mdv > 1 << (16 - cp_frac_bits)
1803         )
1804         return mv + (uint) (((ulong) rem * mdv) >> cp_frac_bits);
1805 #endif
1806     return mv + ((rem * mdv) >> cp_frac_bits);
1807 #undef cp_frac_bits
1808 }
1809 
1810 #endif /* FRAC_MAP_INTERPOLATE */
1811 
1812 /* ------ Default device color mapping ------ */
1813 /* White-on-black */
1814 gx_color_index
gx_default_w_b_map_rgb_color(gx_device * dev,const gx_color_value cv[])1815 gx_default_w_b_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1816 {				/* Map values >= 1/2 to 1, < 1/2 to 0. */
1817     int i, ncomps = dev->color_info.num_components;
1818     gx_color_value  cv_all = 0;
1819 
1820     for (i = 0; i < ncomps; i++)
1821         cv_all |= cv[i];
1822     return cv_all > gx_max_color_value / 2 ? (gx_color_index)1
1823         : (gx_color_index)0;
1824 
1825 }
1826 
1827 int
gx_default_w_b_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1828 gx_default_w_b_map_color_rgb(gx_device * dev, gx_color_index color,
1829                              gx_color_value prgb[3])
1830 {				/* Map 1 to max_value, 0 to 0. */
1831     prgb[0] = prgb[1] = prgb[2] = -(gx_color_value) color;
1832     return 0;
1833 }
1834 
1835 /* Black-on-white */
1836 gx_color_index
gx_default_b_w_map_rgb_color(gx_device * dev,const gx_color_value cv[])1837 gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1838 {
1839     uchar i, ncomps = dev->color_info.num_components;
1840     gx_color_value  cv_all = 0;
1841 
1842     for (i = 0; i < ncomps; i++)
1843         cv_all |= cv[i];
1844     return cv_all > gx_max_color_value / 2 ? (gx_color_index)0
1845         : (gx_color_index)1;
1846 }
1847 
1848 int
gx_default_b_w_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1849 gx_default_b_w_map_color_rgb(gx_device * dev, gx_color_index color,
1850                              gx_color_value prgb[3])
1851 {				/* Map 0 to max_value, 1 to 0. */
1852     prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
1853     return 0;
1854 }
1855 
1856 /* RGB mapping for gray-scale devices */
1857 
1858 gx_color_index
gx_default_gray_map_rgb_color(gx_device * dev,const gx_color_value cv[])1859 gx_default_gray_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1860 {				/* We round the value rather than truncating it. */
1861     gx_color_value gray =
1862     (((cv[0] * (ulong) lum_red_weight) +
1863       (cv[1] * (ulong) lum_green_weight) +
1864       (cv[2] * (ulong) lum_blue_weight) +
1865       (lum_all_weights / 2)) / lum_all_weights
1866      * dev->color_info.max_gray +
1867      (gx_max_color_value / 2)) / gx_max_color_value;
1868 
1869     return gray;
1870 }
1871 
1872 int
gx_default_gray_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1873 gx_default_gray_map_color_rgb(gx_device * dev, gx_color_index color,
1874                               gx_color_value prgb[3])
1875 {
1876     gx_color_value gray = (gx_color_value)
1877         (color * gx_max_color_value / dev->color_info.max_gray);
1878 
1879     prgb[0] = gray;
1880     prgb[1] = gray;
1881     prgb[2] = gray;
1882     return 0;
1883 }
1884 
1885 gx_color_index
gx_default_8bit_map_gray_color(gx_device * dev,const gx_color_value cv[])1886 gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[])
1887 {
1888     gx_color_index color = gx_color_value_to_byte(cv[0]);
1889 
1890     return (color == gx_no_color_index ? color ^ 1 : color);
1891 }
1892 
1893 int
gx_default_8bit_map_color_gray(gx_device * dev,gx_color_index color,gx_color_value pgray[1])1894 gx_default_8bit_map_color_gray(gx_device * dev, gx_color_index color,
1895                               gx_color_value pgray[1])
1896 {
1897     pgray[0] = (gx_color_value)(color * gx_max_color_value / 255);
1898     return 0;
1899 }
1900 
1901 /* RGB mapping for 24-bit true (RGB) color devices */
1902 
1903 gx_color_index
gx_default_rgb_map_rgb_color(gx_device * dev,const gx_color_value cv[])1904 gx_default_rgb_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1905 {
1906     if (dev->color_info.depth == 24)
1907         return gx_color_value_to_byte(cv[2]) +
1908             ((uint) gx_color_value_to_byte(cv[1]) << 8) +
1909             ((ulong) gx_color_value_to_byte(cv[0]) << 16);
1910     else {
1911         COLROUND_VARS;
1912         int bpc = dev->color_info.depth / 3;
1913         COLROUND_SETUP(bpc);
1914 
1915         return (((COLROUND_ROUND(cv[0]) << bpc) +
1916                  COLROUND_ROUND(cv[1])) << bpc) +
1917                COLROUND_ROUND(cv[2]);
1918     }
1919 }
1920 
1921 /* Map a color index to a r-g-b color. */
1922 int
gx_default_rgb_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1923 gx_default_rgb_map_color_rgb(gx_device * dev, gx_color_index color,
1924                              gx_color_value prgb[3])
1925 {
1926     if (dev->color_info.depth == 24) {
1927         prgb[0] = gx_color_value_from_byte(color >> 16);
1928         prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
1929         prgb[2] = gx_color_value_from_byte(color & 0xff);
1930     } else {
1931         uint bits_per_color = dev->color_info.depth / 3;
1932         uint color_mask = (1 << bits_per_color) - 1;
1933 
1934         prgb[0] = ((color >> (bits_per_color * 2)) & color_mask) *
1935             (ulong) gx_max_color_value / color_mask;
1936         prgb[1] = ((color >> (bits_per_color)) & color_mask) *
1937             (ulong) gx_max_color_value / color_mask;
1938         prgb[2] = (color & color_mask) *
1939             (ulong) gx_max_color_value / color_mask;
1940     }
1941     return 0;
1942 }
1943 
1944 /* CMYK mapping for RGB devices (should never be called!) */
1945 
1946 gx_color_index
gx_default_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1947 gx_default_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1948 {				/* Convert to RGB */
1949     frac rgb[3];
1950     gx_color_value rgb_cv[3];
1951     color_cmyk_to_rgb(cv2frac(cv[0]), cv2frac(cv[1]), cv2frac(cv[2]), cv2frac(cv[3]),
1952                       NULL, rgb, dev->memory);
1953     rgb_cv[0] = frac2cv(rgb[0]);
1954     rgb_cv[1] = frac2cv(rgb[1]);
1955     rgb_cv[2] = frac2cv(rgb[2]);
1956     return (*dev_proc(dev, map_rgb_color)) (dev, rgb_cv);
1957 }
1958 
1959 /* Mapping for CMYK devices */
1960 
1961 gx_color_index
cmyk_1bit_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1962 cmyk_1bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1963 {
1964 #define CV_BIT(v) ((v) >> (gx_color_value_bits - 1))
1965     return (gx_color_index)
1966         (CV_BIT(cv[3]) + (CV_BIT(cv[2]) << 1) + (CV_BIT(cv[1]) << 2) + (CV_BIT(cv[0]) << 3));
1967 #undef CV_BIT
1968 }
1969 
1970 /* Shouldn't be called: decode_color should be cmyk_1bit_map_color_cmyk */
1971 int
cmyk_1bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1972 cmyk_1bit_map_color_rgb(gx_device * dev, gx_color_index color,
1973                         gx_color_value prgb[3])
1974 {
1975     if (color & 1)
1976         prgb[0] = prgb[1] = prgb[2] = 0;
1977     else {
1978         prgb[0] = (color & 8 ? 0 : gx_max_color_value);
1979         prgb[1] = (color & 4 ? 0 : gx_max_color_value);
1980         prgb[2] = (color & 2 ? 0 : gx_max_color_value);
1981     }
1982     return 0;
1983 }
1984 
1985 int
cmyk_1bit_map_color_cmyk(gx_device * dev,gx_color_index color,gx_color_value pcv[4])1986 cmyk_1bit_map_color_cmyk(gx_device * dev, gx_color_index color,
1987                         gx_color_value pcv[4])
1988 {
1989     pcv[0] = (color & 8 ? 0 : gx_max_color_value);
1990     pcv[1] = (color & 4 ? 0 : gx_max_color_value);
1991     pcv[2] = (color & 2 ? 0 : gx_max_color_value);
1992     pcv[3] = (color & 1 ? 0 : gx_max_color_value);
1993     return 0;
1994 }
1995 
1996 gx_color_index
cmyk_8bit_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1997 cmyk_8bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1998 {
1999     gx_color_index color =
2000         gx_color_value_to_byte(cv[3]) +
2001         ((uint)gx_color_value_to_byte(cv[2]) << 8) +
2002         ((uint)gx_color_value_to_byte(cv[1]) << 16) +
2003         ((uint)gx_color_value_to_byte(cv[0]) << 24);
2004 
2005     return (color == gx_no_color_index ? color ^ 1 : color);
2006 }
2007 
2008 gx_color_index
cmyk_16bit_map_cmyk_color(gx_device * dev,const gx_color_value cv[])2009 cmyk_16bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
2010 {
2011     gx_color_index color =
2012         (uint64_t)cv[3] +
2013         ((uint64_t)cv[2] << 16) +
2014         ((uint64_t)cv[1] << 32) +
2015         ((uint64_t)cv[0] << 48);
2016 
2017     return (color == gx_no_color_index ? color ^ 1 : color);
2018 }
2019 
2020 /* Shouldn't be called: decode_color should be cmyk_8bit_map_color_cmyk */
2021 int
cmyk_8bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])2022 cmyk_8bit_map_color_rgb(gx_device * dev, gx_color_index color,
2023                         gx_color_value prgb[3])
2024 {
2025     int
2026         not_k = (int) (~color & 0xff),
2027         r = not_k - (int) (color >> 24),
2028         g = not_k - (int) ((color >> 16) & 0xff),
2029         b = not_k - (int) ((color >> 8) & 0xff);
2030 
2031     prgb[0] = (r < 0 ? 0 : gx_color_value_from_byte(r));
2032     prgb[1] = (g < 0 ? 0 : gx_color_value_from_byte(g));
2033     prgb[2] = (b < 0 ? 0 : gx_color_value_from_byte(b));
2034     return 0;
2035 }
2036 
2037 int
cmyk_8bit_map_color_cmyk(gx_device * dev,gx_color_index color,gx_color_value pcv[4])2038 cmyk_8bit_map_color_cmyk(gx_device * dev, gx_color_index color,
2039                         gx_color_value pcv[4])
2040 {
2041     pcv[0] = gx_color_value_from_byte((color >> 24) & 0xff);
2042     pcv[1] = gx_color_value_from_byte((color >> 16) & 0xff);
2043     pcv[2] = gx_color_value_from_byte((color >> 8) & 0xff);
2044     pcv[3] = gx_color_value_from_byte(color & 0xff);
2045     return 0;
2046 }
2047 
2048 int
cmyk_16bit_map_color_cmyk(gx_device * dev,gx_color_index color,gx_color_value pcv[4])2049 cmyk_16bit_map_color_cmyk(gx_device * dev, gx_color_index color,
2050                           gx_color_value pcv[4])
2051 {
2052     pcv[0] = ((color >> 24) >> 24) & 0xffff;
2053     pcv[1] = ((color >> 16) >> 16) & 0xffff;
2054     pcv[2] = ( color        >> 16) & 0xffff;
2055     pcv[3] = ( color             ) & 0xffff;
2056     return 0;
2057 }
2058 
2059 /* Default mapping between RGB+alpha and RGB. */
2060 
2061 gx_color_index
gx_default_map_rgb_alpha_color(gx_device * dev,gx_color_value r,gx_color_value g,gx_color_value b,gx_color_value alpha)2062 gx_default_map_rgb_alpha_color(gx_device * dev,
2063  gx_color_value r, gx_color_value g, gx_color_value b, gx_color_value alpha)
2064 {				/* Colors have been premultiplied: we don't need to do it here. */
2065     gx_color_value cv[3];
2066     cv[0] = r; cv[1] = g; cv[2] = b;
2067     return (*dev_proc(dev, map_rgb_color))(dev, cv);
2068 }
2069 
2070 int
gx_default_map_color_rgb_alpha(gx_device * dev,gx_color_index color,gx_color_value prgba[4])2071 gx_default_map_color_rgb_alpha(gx_device * dev, gx_color_index color,
2072                                gx_color_value prgba[4])
2073 {
2074     prgba[3] = gx_max_color_value;	/* alpha = 1 */
2075     return (*dev_proc(dev, map_color_rgb)) (dev, color, prgba);
2076 }
2077 
2078 frac
gx_unit_frac(float fvalue)2079 gx_unit_frac(float fvalue)
2080 {
2081     frac f = frac_0;
2082     if (is_fneg(fvalue))
2083         f = frac_0;
2084     else if (is_fge1(fvalue))
2085         f = frac_1;
2086     else
2087         f = float2frac(fvalue);
2088     return f;
2089 }
2090 
2091 static void
cmapper_transfer_halftone_add(gx_cmapper_t * data)2092 cmapper_transfer_halftone_add(gx_cmapper_t *data)
2093 {
2094     gx_color_value *pconc = &data->conc[0];
2095     const gs_gstate * pgs = data->pgs;
2096     gx_device * dev = data->dev;
2097     gs_color_select_t select = data->select;
2098     uchar ncomps = dev->color_info.num_components;
2099     frac frac_value;
2100     uchar i;
2101     frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2102 
2103     /* apply the transfer function(s) */
2104     for (i = 0; i < ncomps; i++) {
2105         frac_value = cv2frac(pconc[i]);
2106         cv_frac[i] = gx_map_color_frac(pgs, frac_value, effective_transfer[i]);
2107     }
2108     /* Halftoning */
2109     if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2110                     pgs->dev_ht, &pgs->screen_phase[select]) == 1)
2111         gx_color_load_select(&data->devc, pgs, dev, select);
2112 }
2113 
2114 static void
cmapper_transfer_halftone_op(gx_cmapper_t * data)2115 cmapper_transfer_halftone_op(gx_cmapper_t *data)
2116 {
2117     gx_color_value *pconc = &data->conc[0];
2118     const gs_gstate * pgs = data->pgs;
2119     gx_device * dev = data->dev;
2120     gs_color_select_t select = data->select;
2121     uchar ncomps = dev->color_info.num_components;
2122     frac frac_value;
2123     uchar i;
2124     frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2125 
2126     /* apply the transfer function(s) */
2127     uint k = dev->color_info.black_component;
2128     for (i = 0; i < ncomps; i++) {
2129         frac_value = cv2frac(pconc[i]);
2130         if (i == k) {
2131             cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2132                 (frac)(frac_1 - frac_value), effective_transfer[i]);
2133         } else {
2134             cv_frac[i] = frac_value;  /* Ignore transfer, see PLRM3 p. 494 */
2135         }
2136     }
2137     /* Halftoning */
2138     if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2139                     pgs->dev_ht, &pgs->screen_phase[select]) == 1)
2140         gx_color_load_select(&data->devc, pgs, dev, select);
2141 }
2142 
2143 static void
cmapper_transfer_halftone_sub(gx_cmapper_t * data)2144 cmapper_transfer_halftone_sub(gx_cmapper_t *data)
2145 {
2146     gx_color_value *pconc = &data->conc[0];
2147     const gs_gstate * pgs = data->pgs;
2148     gx_device * dev = data->dev;
2149     gs_color_select_t select = data->select;
2150     uchar ncomps = dev->color_info.num_components;
2151     frac frac_value;
2152     uchar i;
2153     frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2154 
2155     /* apply the transfer function(s) */
2156     for (i = 0; i < ncomps; i++) {
2157         frac_value = cv2frac(pconc[i]);
2158         cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2159                     (frac)(frac_1 - frac_value), effective_transfer[i]);
2160     }
2161     /* Halftoning */
2162     if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2163                     pgs->dev_ht, &pgs->screen_phase[select]) == 1)
2164         gx_color_load_select(&data->devc, pgs, dev, select);
2165 }
2166 
2167 static void
cmapper_transfer_add(gx_cmapper_t * data)2168 cmapper_transfer_add(gx_cmapper_t *data)
2169 {
2170     gx_color_value *pconc = &data->conc[0];
2171     const gs_gstate * pgs = data->pgs;
2172     gx_device * dev = data->dev;
2173     uchar ncomps = dev->color_info.num_components;
2174     frac frac_value;
2175     uchar i;
2176     gx_color_index color;
2177 
2178     /* apply the transfer function(s) */
2179     for (i = 0; i < ncomps; i++) {
2180         frac_value = cv2frac(pconc[i]);
2181         frac_value = gx_map_color_frac(pgs,
2182                                 frac_value, effective_transfer[i]);
2183         pconc[i] = frac2cv(frac_value);
2184     }
2185     /* Halftoning */
2186     color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2187     /* check if the encoding was successful; we presume failure is rare */
2188     if (color != gx_no_color_index)
2189         color_set_pure(&data->devc, color);
2190 }
2191 
2192 static void
cmapper_transfer_op(gx_cmapper_t * data)2193 cmapper_transfer_op(gx_cmapper_t *data)
2194 {
2195     gx_color_value *pconc = &data->conc[0];
2196     const gs_gstate * pgs = data->pgs;
2197     gx_device * dev = data->dev;
2198     frac frac_value;
2199     gx_color_index color;
2200 
2201     uint k = dev->color_info.black_component;
2202     /* Ignore transfer for non blacks, see PLRM3 p. 494 */
2203     frac_value = cv2frac(pconc[k]);
2204     frac_value = frac_1 - gx_map_color_frac(pgs,
2205                 (frac)(frac_1 - frac_value), effective_transfer[k]);
2206     pconc[k] = frac2cv(frac_value);
2207     /* Halftoning */
2208     color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2209     /* check if the encoding was successful; we presume failure is rare */
2210     if (color != gx_no_color_index)
2211         color_set_pure(&data->devc, color);
2212 }
2213 
2214 static void
cmapper_transfer_sub(gx_cmapper_t * data)2215 cmapper_transfer_sub(gx_cmapper_t *data)
2216 {
2217     gx_color_value *pconc = &data->conc[0];
2218     const gs_gstate * pgs = data->pgs;
2219     gx_device * dev = data->dev;
2220     uchar ncomps = dev->color_info.num_components;
2221     frac frac_value;
2222     uchar i;
2223     gx_color_index color;
2224 
2225     /* apply the transfer function(s) */
2226     for (i = 0; i < ncomps; i++) {
2227         frac_value = cv2frac(pconc[i]);
2228         frac_value = frac_1 - gx_map_color_frac(pgs,
2229                     (frac)(frac_1 - frac_value), effective_transfer[i]);
2230         pconc[i] = frac2cv(frac_value);
2231     }
2232     /* Halftoning */
2233     color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2234     /* check if the encoding was successful; we presume failure is rare */
2235     if (color != gx_no_color_index)
2236         color_set_pure(&data->devc, color);
2237 }
2238 
2239 /* This is used by image color render to handle the cases where we need to
2240    perform either a transfer function or halftoning on the color values
2241    during an ICC color flow.  In this case, the color is already in the
2242    device color space but in 16bpp color values. */
2243 static void
cmapper_halftone(gx_cmapper_t * data)2244 cmapper_halftone(gx_cmapper_t *data)
2245 {
2246     gx_color_value *pconc = &data->conc[0];
2247     const gs_gstate * pgs = data->pgs;
2248     gx_device * dev = data->dev;
2249     gs_color_select_t select = data->select;
2250     uchar ncomps = dev->color_info.num_components;
2251     uchar i;
2252     frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2253 
2254     /* We need this to be in frac form */
2255     for (i = 0; i < ncomps; i++) {
2256         cv_frac[i] = cv2frac(pconc[i]);
2257     }
2258     if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2259                 pgs->dev_ht, &pgs->screen_phase[select]) == 1)
2260         gx_color_load_select(&data->devc, pgs, dev, select);
2261 }
2262 
2263 /* This is used by image color render to handle the cases where we need to
2264    perform either a transfer function or halftoning on the color values
2265    during an ICC color flow.  In this case, the color is already in the
2266    device color space but in 16bpp color values. */
2267 static void
cmapper_vanilla(gx_cmapper_t * data)2268 cmapper_vanilla(gx_cmapper_t *data)
2269 {
2270     gx_color_value *pconc = &data->conc[0];
2271     gx_device * dev = data->dev;
2272     gx_color_index color;
2273 
2274     color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2275     /* check if the encoding was successful; we presume failure is rare */
2276     if (color != gx_no_color_index)
2277         color_set_pure(&data->devc, color);
2278 }
2279 
2280 void
gx_get_cmapper(gx_cmapper_t * data,const gs_gstate * pgs,gx_device * dev,bool has_transfer,bool has_halftone,gs_color_select_t select)2281 gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs,
2282                gx_device *dev, bool has_transfer, bool has_halftone,
2283                gs_color_select_t select)
2284 {
2285     memset(&(data->conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS]));
2286     data->pgs = pgs;
2287     data->dev = dev;
2288     data->select = select;
2289     data->devc.type = gx_dc_type_none;
2290     data->direct = 0;
2291     if (has_transfer && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
2292         check_cmyk_color_model_comps(dev);
2293     if (pgs->effective_transfer_non_identity_count == 0)
2294         has_transfer = 0;
2295     if (has_transfer) {
2296         if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2297             if (has_halftone)
2298                 data->set_color = cmapper_transfer_halftone_add;
2299             else
2300                 data->set_color = cmapper_transfer_add;
2301         } else if (dev->color_info.opmode == GX_CINFO_OPMODE) {
2302             if (has_halftone)
2303                 data->set_color = cmapper_transfer_halftone_op;
2304             else
2305                 data->set_color = cmapper_transfer_op;
2306         } else {
2307             if (has_halftone)
2308                 data->set_color = cmapper_transfer_halftone_sub;
2309             else
2310                 data->set_color = cmapper_transfer_sub;
2311         }
2312     } else {
2313         if (has_halftone)
2314             data->set_color = cmapper_halftone;
2315         else {
2316             int code = dev_proc(dev, dev_spec_op)(dev, gxdso_is_encoding_direct, NULL, 0);
2317             data->set_color = cmapper_vanilla;
2318             data->direct = (code == 1);
2319         }
2320     }
2321 }
2322 
2323 /* This is used by image color render to handle the cases where we need to
2324    perform either a transfer function or halftoning on the color values
2325    during an ICC color flow.  In this case, the color is already in the
2326    device color space but in 16bpp color values. */
2327 void
cmap_transfer_halftone(gx_color_value * pconc,gx_device_color * pdc,const gs_gstate * pgs,gx_device * dev,bool has_transfer,bool has_halftone,gs_color_select_t select)2328 cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc,
2329      const gs_gstate * pgs, gx_device * dev, bool has_transfer,
2330      bool has_halftone, gs_color_select_t select)
2331 {
2332     uchar ncomps = dev->color_info.num_components;
2333     frac frac_value;
2334     uchar i;
2335     frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2336     gx_color_index color;
2337     gx_color_value color_val[GX_DEVICE_COLOR_MAX_COMPONENTS];
2338 
2339     /* apply the transfer function(s) */
2340     if (has_transfer) {
2341         if (pgs->effective_transfer_non_identity_count == 0) {
2342             if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
2343                 check_cmyk_color_model_comps(dev);
2344             for (i = 0; i < ncomps; i++)
2345                 cv_frac[i] = cv2frac(pconc[i]);
2346         } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2347             for (i = 0; i < ncomps; i++) {
2348                 frac_value = cv2frac(pconc[i]);
2349                 cv_frac[i] = gx_map_color_frac(pgs,
2350                                     frac_value, effective_transfer[i]);
2351             }
2352         } else {
2353             if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) {
2354                 check_cmyk_color_model_comps(dev);
2355             }
2356             if (dev->color_info.opmode == GX_CINFO_OPMODE) {  /* CMYK-like color space */
2357                 uint k = dev->color_info.black_component;
2358                 for (i = 0; i < ncomps; i++) {
2359                     frac_value = cv2frac(pconc[i]);
2360                     if (i == k) {
2361                         cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2362                             (frac)(frac_1 - frac_value), effective_transfer[i]);
2363                     } else {
2364                         cv_frac[i] = cv2frac(pconc[i]);  /* Ignore transfer, see PLRM3 p. 494 */
2365                     }
2366                 }
2367             } else {
2368                 for (i = 0; i < ncomps; i++) {
2369                     frac_value = cv2frac(pconc[i]);
2370                     cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2371                                 (frac)(frac_1 - frac_value), effective_transfer[i]);
2372                 }
2373             }
2374         }
2375     } else {
2376         if (has_halftone) {
2377             /* We need this to be in frac form */
2378             for (i = 0; i < ncomps; i++) {
2379                 cv_frac[i] = cv2frac(pconc[i]);
2380             }
2381         }
2382     }
2383     /* Halftoning */
2384     if (has_halftone) {
2385         if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev,
2386                     pgs->dev_ht, &pgs->screen_phase[select]) == 1)
2387             gx_color_load_select(pdc, pgs, dev, select);
2388     } else {
2389         /* We have a frac value from the transfer function.  Do the encode.
2390            which does not take a frac value...  */
2391         for (i = 0; i < ncomps; i++) {
2392             color_val[i] = frac2cv(cv_frac[i]);
2393         }
2394         color = dev_proc(dev, encode_color)(dev, &(color_val[0]));
2395         /* check if the encoding was successful; we presume failure is rare */
2396         if (color != gx_no_color_index)
2397             color_set_pure(pdc, color);
2398     }
2399 }
2400 
2401 /* This is used by image color render to apply only the transfer function.
2402    We follow this up with threshold rendering. */
2403 void
cmap_transfer(gx_color_value * pconc,const gs_gstate * pgs,gx_device * dev)2404 cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev)
2405 {
2406     uchar ncomps = dev->color_info.num_components;
2407     uchar i;
2408 
2409     /* apply the transfer function(s) */
2410     if (pgs->effective_transfer_non_identity_count == 0) {
2411         if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN)
2412             check_cmyk_color_model_comps(dev);
2413     } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
2414         for (i = 0; i < ncomps; i++)
2415             pconc[i] = frac2cv(gx_map_color_frac(pgs,
2416                                cv2frac(pconc[i]), effective_transfer[i]));
2417     else {
2418         if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) {
2419             check_cmyk_color_model_comps(dev);
2420         }
2421         if (dev->color_info.opmode == GX_CINFO_OPMODE) {  /* CMYK-like color space */
2422             i = dev->color_info.black_component;
2423             if (i < ncomps)
2424                 pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
2425                                    (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i]));
2426         } else {
2427             for (i = 0; i < ncomps; i++)
2428                 pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
2429                         (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i]));
2430         }
2431     }
2432 }
2433 
2434 /* A planar version which applies only one transfer function */
2435 void
cmap_transfer_plane(gx_color_value * pconc,const gs_gstate * pgs,gx_device * dev,int plane)2436 cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs,
2437                     gx_device *dev, int plane)
2438 {
2439     frac frac_value;
2440     frac cv_frac;
2441 
2442     /* apply the transfer function(s) */
2443     if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2444         frac_value = cv2frac(pconc[0]);
2445         cv_frac = gx_map_color_frac(pgs, frac_value, effective_transfer[plane]);
2446         pconc[0] = frac2cv(cv_frac);
2447     } else {
2448         if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) {
2449             check_cmyk_color_model_comps(dev);
2450         }
2451         if (dev->color_info.opmode == GX_CINFO_OPMODE) {  /* CMYK-like color space */
2452             uint k = dev->color_info.black_component;
2453             if (plane == k) {
2454                 frac_value = cv2frac(pconc[0]);
2455                 cv_frac = frac_1 - gx_map_color_frac(pgs,
2456                 (frac)(frac_1 - frac_value), effective_transfer[plane]);
2457                 pconc[0] = frac2cv(cv_frac);
2458             }
2459         } else {
2460             frac_value = cv2frac(pconc[0]);
2461             cv_frac = frac_1 - gx_map_color_frac(pgs,
2462                     (frac)(frac_1 - frac_value), effective_transfer[plane]);
2463             pconc[0] = frac2cv(cv_frac);
2464         }
2465     }
2466 }
2467 
2468 
2469 bool
gx_device_uses_std_cmap_procs(gx_device * dev,const gs_gstate * pgs)2470 gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs)
2471 {
2472     subclass_color_mappings scm;
2473     const gx_cm_color_map_procs *pprocs;
2474     gsicc_rendering_param_t render_cond;
2475     cmm_dev_profile_t *dev_profile = NULL;
2476     cmm_profile_t *des_profile = NULL;
2477 
2478     dev_proc(dev, get_profile)(dev,  &dev_profile);
2479     gsicc_extract_profile(dev->graphics_type_tag,
2480                           dev_profile, &des_profile, &render_cond);
2481 
2482     if (des_profile != NULL) {
2483         scm = get_color_mapping_procs_subclass(dev);
2484         pprocs = scm.procs;
2485         /* FIXME: This looks wrong to me. Presumably we should be finding
2486          * the parentmost device, looking at the procs for that, and if
2487          * they are forwarding ones, getting the procs for the forwarded
2488          * device. This is NOT what this code does. */
2489         /* Check if they are forwarding procs */
2490         if (fwd_uses_fwd_cmap_procs(dev)) {
2491             pprocs = fwd_get_target_cmap_procs(dev);
2492         }
2493         switch(des_profile->num_comps) {
2494             case 1:
2495                 if (pprocs == &DeviceGray_procs) {
2496                     return true;
2497                 }
2498                 break;
2499             case 3:
2500                 if (pprocs == &DeviceRGB_procs) {
2501                     return true;
2502                 }
2503                 break;
2504             case 4:
2505                 if (pprocs == &DeviceCMYK_procs) {
2506                     return true;
2507                 }
2508                 break;
2509             default:
2510                 break;
2511         }
2512     }
2513     return false;
2514 }
2515