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