1 /* Copyright (C) 1992-2005 artofcode LLC. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gxcmap.c,v 1.26 2005/07/13 00:39:50 giles Exp $ */
18 /* Color mapping for Ghostscript */
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gsccolor.h"
22 #include "gxalpha.h"
23 #include "gxcspace.h"
24 #include "gxfarith.h"
25 #include "gxfrac.h"
26 #include "gxdcconv.h"
27 #include "gxdevice.h"
28 #include "gxcmap.h"
29 #include "gxlum.h"
30 #include "gzstate.h"
31 #include "gxdither.h"
32 #include "gxcdevn.h"
33 #include "string_.h"
34
35 /* Structure descriptor */
36 public_st_device_color();
37 private
ENUM_PTRS_WITH(device_color_enum_ptrs,gx_device_color * cptr)38 ENUM_PTRS_WITH(device_color_enum_ptrs, gx_device_color *cptr)
39 {
40 return ENUM_USING(*cptr->type->stype, vptr, size, index);
41 }
42 ENUM_PTRS_END
RELOC_PTRS_WITH(device_color_reloc_ptrs,gx_device_color * cptr)43 private RELOC_PTRS_WITH(device_color_reloc_ptrs, gx_device_color *cptr)
44 {
45 RELOC_USING(*cptr->type->stype, vptr, size);
46 }
47 RELOC_PTRS_END
48
49 gx_color_index
gx_default_encode_color(gx_device * dev,const gx_color_value cv[])50 gx_default_encode_color(gx_device * dev, const gx_color_value cv[])
51 {
52 int ncomps = dev->color_info.num_components;
53 int i;
54 const byte * comp_shift = dev->color_info.comp_shift;
55 const byte * comp_bits = dev->color_info.comp_bits;
56 gx_color_index color = 0;
57
58 #ifdef DEBUG
59 if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) {
60 dprintf( "gx_default_encode_color() requires separable and linear\n" );
61 return gx_no_color_index;
62 }
63 #endif
64 for (i = 0; i < ncomps; i++) {
65 color |= (gx_color_index)(cv[i] >> (gx_color_value_bits - comp_bits[i]))
66 << comp_shift[i];
67
68 }
69 return color;
70 }
71
72 /*
73 * This routine is only used if the device is 'separable'. See
74 * separable_and_linear in gxdevcli.h for more information.
75 */
76 int
gx_default_decode_color(gx_device * dev,gx_color_index color,gx_color_value cv[])77 gx_default_decode_color(gx_device * dev, gx_color_index color, gx_color_value cv[])
78 {
79 int ncomps = dev->color_info.num_components;
80 int i;
81 const byte * comp_shift = dev->color_info.comp_shift;
82 const byte * comp_bits = dev->color_info.comp_bits;
83 const gx_color_index * comp_mask = dev->color_info.comp_mask;
84 uint shift, ivalue, nbits, scale;
85
86 #ifdef DEBUG
87 if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) {
88 dprintf( "gx_default_decode_color() requires separable and linear\n" );
89 return gs_error_rangecheck;
90 }
91 #endif
92
93 for (i = 0; i < ncomps; i++) {
94 /*
95 * Convert from the gx_color_index bits to a gx_color_value.
96 * Split the conversion into an integer and a fraction calculation
97 * so we can do integer arthmetic. The calculation is equivalent
98 * to floor(0xffff.fffff * ivalue / ((1 << nbits) - 1))
99 */
100 nbits = comp_bits[i];
101 scale = gx_max_color_value / ((1 << nbits) - 1);
102 ivalue = (color & comp_mask[i]) >> comp_shift[i];
103 cv[i] = ivalue * scale;
104 /*
105 * Since our scaling factor is an integer, we lost the fraction.
106 * Determine what part of the ivalue that the faction would have
107 * added into the result.
108 */
109 shift = nbits - (gx_color_value_bits % nbits);
110 cv[i] += ivalue >> shift;
111 }
112 return 0;
113 }
114
115 gx_color_index
gx_error_encode_color(gx_device * dev,const gx_color_value colors[])116 gx_error_encode_color(gx_device * dev, const gx_color_value colors[])
117 {
118 #ifdef DEBUG
119 /* The "null" device is expected to be missing encode_color */
120 if (strcmp(dev->dname, "null") != 0)
121 dprintf("No encode_color proc defined for device.\n");
122 #endif
123 return gx_no_color_index;
124 }
125
126 int
gx_error_decode_color(gx_device * dev,gx_color_index cindex,gx_color_value colors[])127 gx_error_decode_color(gx_device * dev, gx_color_index cindex, gx_color_value colors[])
128 {
129 int i=dev->color_info.num_components;
130
131 #ifdef DEBUG
132 dprintf("No decode_color proc defined for device.\n");
133 #endif
134 for(; i>=0; i--)
135 colors[i] = 0;
136 return gs_error_rangecheck;
137 }
138
139 /*
140 * The "back-stop" default encode_color method. This will be used only
141 * if no applicable color encoding procedure is provided, and the number
142 * of color model components is 1. The encoding is presumed to induce an
143 * additive color model (DeviceGray).
144 *
145 * The particular method employed is a trivial generalization of the
146 * default map_rgb_color method used in the pre-DeviceN code (this was
147 * known as gx_default_w_b_map_rgb_color). Since the DeviceRGB color
148 * model is assumed additive, any of the procedures used as a default
149 * map_rgb_color method are assumed to induce an additive color model.
150 * gx_default_w_b_map_rgb_color mapped white to 1 and black to 0, so
151 * the new procedure is set up with zero-base and positive slope as well.
152 * The generalization is the use of depth; the earlier procedure assumed
153 * a bi-level device.
154 *
155 * Two versions of this procedure are provided, the first of which
156 * applies if max_gray == 2^depth - 1 and is faster, while the second
157 * applies to the general situation. Note that, as with the encoding
158 * procedures used in the pre-DeviceN code, both of these methods induce
159 * a small rounding error if 1 < depth < gx_color_value_bits.
160 */
161 gx_color_index
gx_default_gray_fast_encode(gx_device * dev,const gx_color_value cv[])162 gx_default_gray_fast_encode(gx_device * dev, const gx_color_value cv[])
163 {
164 return cv[0] >> (gx_color_value_bits - dev->color_info.depth);
165 }
166
167 gx_color_index
gx_default_gray_encode(gx_device * dev,const gx_color_value cv[])168 gx_default_gray_encode(gx_device * dev, const gx_color_value cv[])
169 {
170 return cv[0] * (dev->color_info.max_gray + 1) / (gx_max_color_value + 1);
171 }
172
173 /**
174 * This routine is provided for old devices which provide a
175 * map_rgb_color routine but not encode_color. New devices are
176 * encouraged either to use the defaults or to set encode_color rather
177 * than map_rgb_color.
178 **/
179 gx_color_index
gx_backwards_compatible_gray_encode(gx_device * dev,const gx_color_value cv[])180 gx_backwards_compatible_gray_encode(gx_device *dev,
181 const gx_color_value cv[])
182 {
183 gx_color_value gray_val = cv[0];
184 gx_color_value rgb_cv[3];
185
186 rgb_cv[0] = gray_val;
187 rgb_cv[1] = gray_val;
188 rgb_cv[2] = gray_val;
189 return (*dev_proc(dev, map_rgb_color))(dev, rgb_cv);
190 }
191
192 /* -------- Default color space to color model conversion routines -------- */
193
194 void
gray_cs_to_gray_cm(gx_device * dev,frac gray,frac out[])195 gray_cs_to_gray_cm(gx_device * dev, frac gray, frac out[])
196 {
197 out[0] = gray;
198 }
199
200 static void
rgb_cs_to_gray_cm(gx_device * dev,const gs_imager_state * pis,frac r,frac g,frac b,frac out[])201 rgb_cs_to_gray_cm(gx_device * dev, const gs_imager_state *pis,
202 frac r, frac g, frac b, frac out[])
203 {
204 out[0] = color_rgb_to_gray(r, g, b, NULL);
205 }
206
207 static void
cmyk_cs_to_gray_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])208 cmyk_cs_to_gray_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
209 {
210 out[0] = color_cmyk_to_gray(c, m, y, k, NULL);
211 }
212
213 static void
gray_cs_to_rgb_cm(gx_device * dev,frac gray,frac out[])214 gray_cs_to_rgb_cm(gx_device * dev, frac gray, frac out[])
215 {
216 out[0] = out[1] = out[2] = gray;
217 }
218
219 void
rgb_cs_to_rgb_cm(gx_device * dev,const gs_imager_state * pis,frac r,frac g,frac b,frac out[])220 rgb_cs_to_rgb_cm(gx_device * dev, const gs_imager_state *pis,
221 frac r, frac g, frac b, frac out[])
222 {
223 out[0] = r;
224 out[1] = g;
225 out[2] = b;
226 }
227
228 static void
cmyk_cs_to_rgb_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])229 cmyk_cs_to_rgb_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
230 {
231 color_cmyk_to_rgb(c, m, y, k, NULL, out);
232 }
233
234 static void
gray_cs_to_rgbk_cm(gx_device * dev,frac gray,frac out[])235 gray_cs_to_rgbk_cm(gx_device * dev, frac gray, frac out[])
236 {
237 out[0] = out[1] = out[2] = frac_0;
238 out[3] = gray;
239 }
240
241 static void
rgb_cs_to_rgbk_cm(gx_device * dev,const gs_imager_state * pis,frac r,frac g,frac b,frac out[])242 rgb_cs_to_rgbk_cm(gx_device * dev, const gs_imager_state *pis,
243 frac r, frac g, frac b, frac out[])
244 {
245 if ((r == g) && (g == b)) {
246 out[0] = out[1] = out[2] = frac_0;
247 out[3] = r;
248 }
249 else {
250 out[0] = r;
251 out[1] = g;
252 out[2] = b;
253 out[3] = frac_0;
254 }
255 }
256
257 static void
cmyk_cs_to_rgbk_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])258 cmyk_cs_to_rgbk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
259 {
260 frac rgb[3];
261 if ((c == frac_0) && (m == frac_0) && (y == frac_0)) {
262 out[0] = out[1] = out[2] = frac_0;
263 out[3] = frac_1 - k;
264 }
265 else {
266 color_cmyk_to_rgb(c, m, y, k, NULL, rgb);
267 rgb_cs_to_rgbk_cm(dev, NULL, rgb[0], rgb[1], rgb[2], out);
268 }
269 }
270
271 static void
gray_cs_to_cmyk_cm(gx_device * dev,frac gray,frac out[])272 gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[])
273 {
274 out[0] = out[1] = out[2] = frac_0;
275 out[3] = frac_1 - gray;
276 }
277
278 /*
279 * Default map from DeviceRGB color space to DeviceCMYK color
280 * model. Since this mapping is defined by the PostScript language
281 * it is unlikely that any device with a DeviceCMYK color model
282 * would define this mapping on its own.
283 *
284 * If the imager state is not available, map as though the black
285 * generation and undercolor removal functions are identity
286 * transformations. This mode is used primarily to support the
287 * raster operation (rop) feature of PCL, which requires that
288 * the raster operation be performed in an RGB color space.
289 * Note that default black generation and undercolor removal
290 * functions in PostScript need NOT be identity transformations:
291 * often they are { pop 0 }.
292 */
293 static void
rgb_cs_to_cmyk_cm(gx_device * dev,const gs_imager_state * pis,frac r,frac g,frac b,frac out[])294 rgb_cs_to_cmyk_cm(gx_device * dev, const gs_imager_state *pis,
295 frac r, frac g, frac b, frac out[])
296 {
297 if (pis != 0)
298 color_rgb_to_cmyk(r, g, b, pis, out);
299 else {
300 frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b;
301 frac k = min(c, min(m, g));
302
303 out[0] = c - k;
304 out[1] = m - k;
305 out[2] = y - k;
306 out[3] = k;
307 }
308 }
309
310 void
cmyk_cs_to_cmyk_cm(gx_device * dev,frac c,frac m,frac y,frac k,frac out[])311 cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
312 {
313 out[0] = c;
314 out[1] = m;
315 out[2] = y;
316 out[3] = k;
317 }
318
319
320 /* The list of default color space to color model conversion routines. */
321
322 static const gx_cm_color_map_procs DeviceGray_procs = {
323 gray_cs_to_gray_cm, rgb_cs_to_gray_cm, cmyk_cs_to_gray_cm
324 };
325
326 static const gx_cm_color_map_procs DeviceRGB_procs = {
327 gray_cs_to_rgb_cm, rgb_cs_to_rgb_cm, cmyk_cs_to_rgb_cm
328 };
329
330 static const gx_cm_color_map_procs DeviceCMYK_procs = {
331 gray_cs_to_cmyk_cm, rgb_cs_to_cmyk_cm, cmyk_cs_to_cmyk_cm
332 };
333
334 static const gx_cm_color_map_procs DeviceRGBK_procs = {
335 gray_cs_to_rgbk_cm, rgb_cs_to_rgbk_cm, cmyk_cs_to_rgbk_cm
336 };
337
338 /*
339 * These are the default handlers for returning the list of color space
340 * to color model conversion routines.
341 */
342 const gx_cm_color_map_procs *
gx_default_DevGray_get_color_mapping_procs(const gx_device * dev)343 gx_default_DevGray_get_color_mapping_procs(const gx_device * dev)
344 {
345 return &DeviceGray_procs;
346 }
347
348 const gx_cm_color_map_procs *
gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev)349 gx_default_DevRGB_get_color_mapping_procs(const gx_device * dev)
350 {
351 return &DeviceRGB_procs;
352 }
353
354 const gx_cm_color_map_procs *
gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev)355 gx_default_DevCMYK_get_color_mapping_procs(const gx_device * dev)
356 {
357 return &DeviceCMYK_procs;
358 }
359
360 const gx_cm_color_map_procs *
gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev)361 gx_default_DevRGBK_get_color_mapping_procs(const gx_device * dev)
362 {
363 return &DeviceRGBK_procs;
364 }
365
366 const gx_cm_color_map_procs *
gx_error_get_color_mapping_procs(const gx_device * dev)367 gx_error_get_color_mapping_procs(const gx_device * dev)
368 {
369 /*
370 * We should never get here. If we do then we do not have a "get_color_mapping_procs"
371 * routine for the device.
372 */
373 #ifdef DEBUG
374 dprintf("No get_color_mapping_procs proc defined for device.\n");
375 #endif
376 return NULL;
377 }
378
379 /* ----- Default color component name to colorant index conversion routines ------ */
380
381 #define compare_color_names(pname, name_size, name_str) \
382 (name_size == (int)strlen(name_str) && strncmp(pname, name_str, name_size) == 0)
383
384 /* Default color component to index for a DeviceGray color model */
385 int
gx_default_DevGray_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)386 gx_default_DevGray_get_color_comp_index(gx_device * dev, const char * pname,
387 int name_size, int component_type)
388 {
389 if (compare_color_names(pname, name_size, "Gray") ||
390 compare_color_names(pname, name_size, "Grey"))
391 return 0;
392 else
393 return -1; /* Indicate that the component name is "unknown" */
394 }
395
396 /* Default color component to index for a DeviceRGB color model */
397 int
gx_default_DevRGB_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)398 gx_default_DevRGB_get_color_comp_index(gx_device * dev, const char * pname,
399 int name_size, int component_type)
400 {
401 if (compare_color_names(pname, name_size, "Red"))
402 return 0;
403 if (compare_color_names(pname, name_size, "Green"))
404 return 1;
405 if (compare_color_names(pname, name_size, "Blue"))
406 return 2;
407 else
408 return -1; /* Indicate that the component name is "unknown" */
409 }
410
411 /* Default color component to index for a DeviceCMYK color model */
412 int
gx_default_DevCMYK_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)413 gx_default_DevCMYK_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, "Cyan"))
417 return 0;
418 if (compare_color_names(pname, name_size, "Magenta"))
419 return 1;
420 if (compare_color_names(pname, name_size, "Yellow"))
421 return 2;
422 if (compare_color_names(pname, name_size, "Black"))
423 return 3;
424 else
425 return -1; /* Indicate that the component name is "unknown" */
426 }
427
428 /* Default color component to index for a DeviceRGBK color model */
429 int
gx_default_DevRGBK_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)430 gx_default_DevRGBK_get_color_comp_index(gx_device * dev, const char * pname,
431 int name_size, int component_type)
432 {
433 if (compare_color_names(pname, name_size, "Red"))
434 return 0;
435 if (compare_color_names(pname, name_size, "Green"))
436 return 1;
437 if (compare_color_names(pname, name_size, "Blue"))
438 return 2;
439 if (compare_color_names(pname, name_size, "Black"))
440 return 3;
441 else
442 return -1; /* Indicate that the component name is "unknown" */
443 }
444
445 /* Default color component to index for an unknown color model */
446 int
gx_error_get_color_comp_index(gx_device * dev,const char * pname,int name_size,int component_type)447 gx_error_get_color_comp_index(gx_device * dev, const char * pname,
448 int name_size, int component_type)
449 {
450 /*
451 * We should never get here. If we do then we do not have a "get_color_comp_index"
452 * routine for the device.
453 */
454 #ifdef DEBUG
455 dprintf("No get_color_comp_index proc defined for device.\n");
456 #endif
457 return -1; /* Always return "unknown" component name */
458 }
459
460 #undef compare_color_names
461
462 /* ---------------- Device color rendering ---------------- */
463
464 private cmap_proc_gray(cmap_gray_halftoned);
465 private cmap_proc_gray(cmap_gray_direct);
466
467 private cmap_proc_rgb(cmap_rgb_halftoned);
468 private cmap_proc_rgb(cmap_rgb_direct);
469
470 #define cmap_cmyk_halftoned cmap_cmyk_direct
471 private cmap_proc_cmyk(cmap_cmyk_direct);
472
473 private cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned);
474 private cmap_proc_rgb_alpha(cmap_rgb_alpha_direct);
475
476 /* Procedure names are only guaranteed unique to 23 characters.... */
477 private cmap_proc_rgb_alpha(cmap_rgb_alpha_halftoned);
478 private cmap_proc_rgb_alpha(cmap_rgb_alpha_direct);
479
480 private cmap_proc_separation(cmap_separation_halftoned);
481 private cmap_proc_separation(cmap_separation_direct);
482
483 private cmap_proc_devicen(cmap_devicen_halftoned);
484 private cmap_proc_devicen(cmap_devicen_direct);
485
486 private cmap_proc_is_halftoned(cmap_halftoned_is_halftoned);
487 private cmap_proc_is_halftoned(cmap_direct_is_halftoned);
488
489 private const gx_color_map_procs cmap_few = {
490 cmap_gray_halftoned,
491 cmap_rgb_halftoned,
492 cmap_cmyk_halftoned,
493 cmap_rgb_alpha_halftoned,
494 cmap_separation_halftoned,
495 cmap_devicen_halftoned,
496 cmap_halftoned_is_halftoned
497 };
498 private const gx_color_map_procs cmap_many = {
499 cmap_gray_direct,
500 cmap_rgb_direct,
501 cmap_cmyk_direct,
502 cmap_rgb_alpha_direct,
503 cmap_separation_direct,
504 cmap_devicen_direct,
505 cmap_direct_is_halftoned
506 };
507
508 const gx_color_map_procs *const cmap_procs_default = &cmap_many;
509
510
511 /* Determine the color mapping procedures for a device. */
512 /* Note that the default procedure doesn't consult the imager state. */
513 const gx_color_map_procs *
gx_get_cmap_procs(const gs_imager_state * pis,const gx_device * dev)514 gx_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev)
515 {
516 return (pis->get_cmap_procs)(pis, dev);
517 }
518
519 const gx_color_map_procs *
gx_default_get_cmap_procs(const gs_imager_state * pis,const gx_device * dev)520 gx_default_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev)
521 {
522 return (gx_device_must_halftone(dev) ? &cmap_few : &cmap_many);
523 }
524
525 /* Set the color mapping procedures in the graphics state. */
526 void
gx_set_cmap_procs(gs_imager_state * pis,const gx_device * dev)527 gx_set_cmap_procs(gs_imager_state * pis, const gx_device * dev)
528 {
529 pis->cmap_procs = gx_get_cmap_procs(pis, dev);
530 }
531
532 /* Remap the color in the graphics state. */
533 int
gx_remap_color(gs_state * pgs)534 gx_remap_color(gs_state * pgs)
535 {
536 const gs_color_space *pcs = pgs->color_space;
537 int code;
538
539 /* The current color in the graphics state is always used for */
540 /* the texture, never for the source. */
541 code = (*pcs->type->remap_color) (pgs->ccolor, pcs, pgs->dev_color,
542 (gs_imager_state *) pgs, pgs->device,
543 gs_color_select_texture);
544 /* if overprint mode is in effect, update the overprint information */
545 if (code >= 0 && pgs->effective_overprint_mode == 1)
546 code = gs_do_set_overprint(pgs);
547 return code;
548 }
549
550 /* Indicate that a color space has no underlying concrete space. */
551 const gs_color_space *
gx_no_concrete_space(const gs_color_space * pcs,const gs_imager_state * pis)552 gx_no_concrete_space(const gs_color_space * pcs, const gs_imager_state * pis)
553 {
554 return NULL;
555 }
556
557 /* Indicate that a color space is concrete. */
558 const gs_color_space *
gx_same_concrete_space(const gs_color_space * pcs,const gs_imager_state * pis)559 gx_same_concrete_space(const gs_color_space * pcs, const gs_imager_state * pis)
560 {
561 return pcs;
562 }
563
564 /* Indicate that a color cannot be concretized. */
565 int
gx_no_concretize_color(const gs_client_color * pcc,const gs_color_space * pcs,frac * pconc,const gs_imager_state * pis)566 gx_no_concretize_color(const gs_client_color * pcc, const gs_color_space * pcs,
567 frac * pconc, const gs_imager_state * pis)
568 {
569 return_error(gs_error_rangecheck);
570 }
571
572 /* By default, remap a color by concretizing it and then */
573 /* remapping the concrete color. */
574 int
gx_default_remap_color(const gs_client_color * pcc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)575 gx_default_remap_color(const gs_client_color * pcc, const gs_color_space * pcs,
576 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
577 gs_color_select_t select)
578 {
579 frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
580 const gs_color_space *pconcs;
581 int i = pcs->type->num_components(pcs);
582 int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pis);
583
584 if (code < 0)
585 return code;
586 pconcs = cs_concrete_space(pcs, pis);
587 code = (*pconcs->type->remap_concrete_color)(conc, pconcs, pdc, pis, dev, select);
588
589 /* Save original color space and color info into dev color */
590 i = any_abs(i);
591 for (i--; i >= 0; i--)
592 pdc->ccolor.paint.values[i] = pcc->paint.values[i];
593 pdc->ccolor_valid = true;
594 return code;
595 }
596
597 /* Color remappers for the standard color spaces. */
598 /* Note that we use D... instead of Device... in some places because */
599 /* gcc under VMS only retains 23 characters of procedure names. */
600
601
602 /* DeviceGray */
603 int
gx_concretize_DeviceGray(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_imager_state * pis)604 gx_concretize_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs,
605 frac * pconc, const gs_imager_state * pis)
606 {
607 float ftemp;
608
609 pconc[0] = unit_frac(pc->paint.values[0], ftemp);
610 return 0;
611 }
612 int
gx_remap_concrete_DGray(const frac * pconc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)613 gx_remap_concrete_DGray(const frac * pconc, const gs_color_space * pcs,
614 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
615 gs_color_select_t select)
616 {
617 if (pis->alpha == gx_max_color_value)
618 (*pis->cmap_procs->map_gray)
619 (pconc[0], pdc, pis, dev, select);
620 else
621 (*pis->cmap_procs->map_rgb_alpha)
622 (pconc[0], pconc[0], pconc[0], cv2frac(pis->alpha),
623 pdc, pis, dev, select);
624 return 0;
625 }
626 int
gx_remap_DeviceGray(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)627 gx_remap_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs,
628 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
629 gs_color_select_t select)
630 {
631 float ftemp;
632 frac fgray = unit_frac(pc->paint.values[0], ftemp);
633
634 /* Save original color space and color info into dev color */
635 pdc->ccolor.paint.values[0] = pc->paint.values[0];
636 pdc->ccolor_valid = true;
637
638 if (pis->alpha == gx_max_color_value)
639 (*pis->cmap_procs->map_gray)
640 (fgray, pdc, pis, dev, select);
641 else
642 (*pis->cmap_procs->map_rgb_alpha)
643 (fgray, fgray, fgray, cv2frac(pis->alpha), pdc, pis, dev, select);
644 return 0;
645 }
646
647 /* DeviceRGB */
648 int
gx_concretize_DeviceRGB(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_imager_state * pis)649 gx_concretize_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs,
650 frac * pconc, const gs_imager_state * pis)
651 {
652 float ftemp;
653
654 pconc[0] = unit_frac(pc->paint.values[0], ftemp);
655 pconc[1] = unit_frac(pc->paint.values[1], ftemp);
656 pconc[2] = unit_frac(pc->paint.values[2], ftemp);
657 return 0;
658 }
659 int
gx_remap_concrete_DRGB(const frac * pconc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)660 gx_remap_concrete_DRGB(const frac * pconc, const gs_color_space * pcs,
661 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
662 gs_color_select_t select)
663 {
664 if (pis->alpha == gx_max_color_value)
665 gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2],
666 pdc, pis, dev, select);
667 else
668 gx_remap_concrete_rgb_alpha(pconc[0], pconc[1], pconc[2],
669 cv2frac(pis->alpha),
670 pdc, pis, dev, select);
671 return 0;
672 }
673 int
gx_remap_DeviceRGB(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)674 gx_remap_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs,
675 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
676 gs_color_select_t select)
677 {
678 float ftemp;
679 frac fred = unit_frac(pc->paint.values[0], ftemp), fgreen = unit_frac(pc->paint.values[1], ftemp),
680 fblue = unit_frac(pc->paint.values[2], ftemp);
681
682 /* Save original color space and color info into dev color */
683 pdc->ccolor.paint.values[0] = pc->paint.values[0];
684 pdc->ccolor.paint.values[1] = pc->paint.values[1];
685 pdc->ccolor.paint.values[2] = pc->paint.values[2];
686 pdc->ccolor_valid = true;
687
688 if (pis->alpha == gx_max_color_value)
689 gx_remap_concrete_rgb(fred, fgreen, fblue,
690 pdc, pis, dev, select);
691 else
692 gx_remap_concrete_rgb_alpha(fred, fgreen, fblue, cv2frac(pis->alpha),
693 pdc, pis, dev, select);
694 return 0;
695 }
696
697 /* DeviceCMYK */
698 int
gx_concretize_DeviceCMYK(const gs_client_color * pc,const gs_color_space * pcs,frac * pconc,const gs_imager_state * pis)699 gx_concretize_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs,
700 frac * pconc, const gs_imager_state * pis)
701 {
702 float ftemp;
703
704 pconc[0] = unit_frac(pc->paint.values[0], ftemp);
705 pconc[1] = unit_frac(pc->paint.values[1], ftemp);
706 pconc[2] = unit_frac(pc->paint.values[2], ftemp);
707 pconc[3] = unit_frac(pc->paint.values[3], ftemp);
708 return 0;
709 }
710 int
gx_remap_concrete_DCMYK(const frac * pconc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)711 gx_remap_concrete_DCMYK(const frac * pconc, const gs_color_space * pcs,
712 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
713 gs_color_select_t select)
714 {
715 /****** IGNORE alpha ******/
716 gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3], pdc,
717 pis, dev, select);
718 return 0;
719 }
720 int
gx_remap_DeviceCMYK(const gs_client_color * pc,const gs_color_space * pcs,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)721 gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs,
722 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
723 gs_color_select_t select)
724 {
725 /****** IGNORE alpha ******/
726 float ft0, ft1, ft2, ft3;
727
728 /* Save original color space and color info into dev color */
729 pdc->ccolor.paint.values[0] = pc->paint.values[0];
730 pdc->ccolor.paint.values[1] = pc->paint.values[1];
731 pdc->ccolor.paint.values[2] = pc->paint.values[2];
732 pdc->ccolor.paint.values[3] = pc->paint.values[3];
733 pdc->ccolor_valid = true;
734
735 gx_remap_concrete_cmyk((frac)unit_frac(pc->paint.values[0], ft0),
736 (frac)unit_frac(pc->paint.values[1], ft1),
737 (frac)unit_frac(pc->paint.values[2], ft2),
738 (frac)unit_frac(pc->paint.values[3], ft3),
739 pdc, pis, dev, select);
740 return 0;
741 }
742
743
744 /* ------ Render Gray color. ------ */
745
746 private void
cmap_gray_halftoned(frac gray,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)747 cmap_gray_halftoned(frac gray, gx_device_color * pdc,
748 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
749 {
750 int i, ncomps = dev->color_info.num_components;
751 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
752
753 /* map to the color model */
754 dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, gray, cm_comps);
755
756 /* apply the transfer function(s); convert to color values */
757 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
758 for (i = 0; i < ncomps; i++)
759 cm_comps[i] = gx_map_color_frac(pis,
760 cm_comps[i], effective_transfer[i]);
761 else
762 for (i = 0; i < ncomps; i++)
763 cm_comps[i] = frac_1 - gx_map_color_frac(pis,
764 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
765
766 if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
767 &pis->screen_phase[select]) == 1)
768 gx_color_load_select(pdc, pis, dev, select);
769 }
770
771 private void
cmap_gray_direct(frac gray,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)772 cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_imager_state * pis,
773 gx_device * dev, gs_color_select_t select)
774 {
775 int i, ncomps = dev->color_info.num_components;
776 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
777 gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
778 gx_color_index color;
779
780 /* map to the color model */
781 dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, gray, cm_comps);
782
783 /* apply the transfer function(s); convert to color values */
784 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
785 for (i = 0; i < ncomps; i++)
786 cv[i] = frac2cv(gx_map_color_frac(pis,
787 cm_comps[i], effective_transfer[i]));
788 else
789 for (i = 0; i < ncomps; i++)
790 cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
791 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
792
793 /* encode as a color index */
794 color = dev_proc(dev, encode_color)(dev, cv);
795
796 /* check if the encoding was successful; we presume failure is rare */
797 if (color != gx_no_color_index)
798 color_set_pure(pdc, color);
799 else
800 cmap_gray_halftoned(gray, pdc, pis, dev, select);
801 }
802
803
804 /* ------ Render RGB color. ------ */
805
806 private void
cmap_rgb_halftoned(frac r,frac g,frac b,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)807 cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc,
808 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
809 {
810 int i, ncomps = dev->color_info.num_components;
811 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
812
813 /* map to the color model */
814 dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
815
816 /* apply the transfer function(s); convert to color values */
817 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
818 for (i = 0; i < ncomps; i++)
819 cm_comps[i] = gx_map_color_frac(pis,
820 cm_comps[i], effective_transfer[i]);
821 else
822 for (i = 0; i < ncomps; i++)
823 cm_comps[i] = frac_1 - gx_map_color_frac(pis,
824 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
825
826 if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
827 &pis->screen_phase[select]) == 1)
828 gx_color_load_select(pdc, pis, dev, select);
829 }
830
831 private void
cmap_rgb_direct(frac r,frac g,frac b,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)832 cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
833 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
834 {
835 int i, ncomps = dev->color_info.num_components;
836 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
837 gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
838 gx_color_index color;
839
840 /* map to the color model */
841 dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
842
843 /* apply the transfer function(s); convert to color values */
844 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
845 for (i = 0; i < ncomps; i++)
846 cv[i] = frac2cv(gx_map_color_frac(pis,
847 cm_comps[i], effective_transfer[i]));
848 else
849 for (i = 0; i < ncomps; i++)
850 cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
851 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
852
853 /* encode as a color index */
854 color = dev_proc(dev, encode_color)(dev, cv);
855
856 /* check if the encoding was successful; we presume failure is rare */
857 if (color != gx_no_color_index)
858 color_set_pure(pdc, color);
859 else
860 cmap_rgb_halftoned(r, g, b, pdc, pis, dev, select);
861 }
862
863
864 /* ------ Render CMYK color. ------ */
865
866 private void
cmap_cmyk_direct(frac c,frac m,frac y,frac k,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)867 cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
868 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
869 {
870 int i, ncomps = dev->color_info.num_components;
871 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
872 gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
873 gx_color_index color;
874
875 /* map to the color model */
876 dev_proc(dev, get_color_mapping_procs)(dev)->map_cmyk(dev, c, m, y, k, cm_comps);
877
878 /* apply the transfer function(s); convert to color values */
879 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
880 for (i = 0; i < ncomps; i++)
881 cm_comps[i] = gx_map_color_frac(pis,
882 cm_comps[i], effective_transfer[i]);
883 else
884 for (i = 0; i < ncomps; i++)
885 cm_comps[i] = frac_1 - gx_map_color_frac(pis,
886 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
887
888 /* We make a test for direct vs. halftoned, rather than */
889 /* duplicating most of the code of this procedure. */
890 if (gx_device_must_halftone(dev)) {
891 if (gx_render_device_DeviceN(cm_comps, pdc, dev,
892 pis->dev_ht, &pis->screen_phase[select]) == 1)
893 gx_color_load_select(pdc, pis, dev, select);
894 return;
895 }
896
897 for (i = 0; i < ncomps; i++)
898 cv[i] = frac2cv(cm_comps[i]);
899
900 color = dev_proc(dev, encode_color)(dev, cv);
901 if (color != gx_no_color_index)
902 color_set_pure(pdc, color);
903 else {
904 if (gx_render_device_DeviceN(cm_comps, pdc, dev,
905 pis->dev_ht, &pis->screen_phase[select]) == 1)
906 gx_color_load_select(pdc, pis, dev, select);
907 return;
908 }
909 }
910
911 private void
cmap_rgb_alpha_halftoned(frac r,frac g,frac b,frac alpha,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)912 cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha,
913 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
914 gs_color_select_t select)
915 {
916 int i, ncomps = dev->color_info.num_components;
917 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
918
919 /* map to the color model */
920 dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
921
922 /* pre-multiply to account for the alpha weighting */
923 if (alpha != frac_1) {
924 #ifdef PREMULTIPLY_TOWARDS_WHITE
925 frac alpha_bias = frac_1 - alpha;
926 #else
927 frac alpha_bias = 0;
928 #endif
929
930 for (i = 0; i < ncomps; i++)
931 cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias;
932 }
933
934 /* apply the transfer function(s); convert to color values */
935 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
936 for (i = 0; i < ncomps; i++)
937 cm_comps[i] = gx_map_color_frac(pis,
938 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(pis,
942 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
943
944 if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
945 &pis->screen_phase[select]) == 1)
946 gx_color_load_select(pdc, pis, dev, select);
947 }
948
949 private void
cmap_rgb_alpha_direct(frac r,frac g,frac b,frac alpha,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)950 cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc,
951 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
952 {
953 int i, ncomps = dev->color_info.num_components;
954 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
955 gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
956 gx_color_index color;
957
958 /* map to the color model */
959 dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps);
960
961 /* pre-multiply to account for the alpha weighting */
962 if (alpha != frac_1) {
963 #ifdef PREMULTIPLY_TOWARDS_WHITE
964 frac alpha_bias = frac_1 - alpha;
965 #else
966 frac alpha_bias = 0;
967 #endif
968
969 for (i = 0; i < ncomps; i++)
970 cm_comps[i] = (frac)((long)cm_comps[i] * alpha) / frac_1 + alpha_bias;
971 }
972
973 /* apply the transfer function(s); convert to color values */
974 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
975 for (i = 0; i < ncomps; i++)
976 cv[i] = frac2cv(gx_map_color_frac(pis,
977 cm_comps[i], effective_transfer[i]));
978 else
979 for (i = 0; i < ncomps; i++)
980 cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
981 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
982
983 /* encode as a color index */
984 if (dev_proc(dev, map_rgb_alpha_color) != gx_default_map_rgb_alpha_color &&
985 (cv_alpha = frac2cv(alpha)) != gx_max_color_value)
986 color = dev_proc(dev, map_rgb_alpha_color)(dev, cv[0], cv[1], cv[2], cv_alpha);
987 else
988 color = dev_proc(dev, encode_color)(dev, cv);
989
990 /* check if the encoding was successful; we presume failure is rare */
991 if (color != gx_no_color_index)
992 color_set_pure(pdc, color);
993 else
994 cmap_rgb_alpha_halftoned(r, g, b, alpha, pdc, pis, dev, select);
995 }
996
997
998 /* ------ Render Separation All color. ------ */
999
1000 /*
1001 * This routine maps DeviceN components into the order of the device's
1002 * colorants.
1003 *
1004 * Parameters:
1005 * pcc - Pointer to DeviceN components.
1006 * pcolor_component_map - Map from DeviceN to the Devices colorants.
1007 * A negative value indicates component is not to be mapped.
1008 * plist - Pointer to list for mapped components
1009 *
1010 * Returns:
1011 * Mapped components in plist.
1012 */
1013 private inline void
map_components_to_colorants(const frac * pcc,const gs_devicen_color_map * pcolor_component_map,frac * plist)1014 map_components_to_colorants(const frac * pcc,
1015 const gs_devicen_color_map * pcolor_component_map, frac * plist)
1016 {
1017 int i = pcolor_component_map->num_colorants - 1;
1018 int pos;
1019
1020 /* Clear all output colorants first */
1021 for (; i >= 0; i--) {
1022 plist[i] = frac_0;
1023 }
1024
1025 /* Map color components into output list */
1026 for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
1027 pos = pcolor_component_map->color_map[i];
1028 if (pos >= 0)
1029 plist[pos] = pcc[i];
1030 }
1031 }
1032
1033 private void
cmap_separation_halftoned(frac all,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1034 cmap_separation_halftoned(frac all, gx_device_color * pdc,
1035 const gs_imager_state * pis, gx_device * dev, gs_color_select_t select)
1036 {
1037 int i, ncomps = dev->color_info.num_components;
1038 bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1039 frac comp_value = all;
1040 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1041
1042 if (pis->color_component_map.sep_type == SEP_ALL) {
1043 /*
1044 * Invert the photometric interpretation for additive
1045 * color spaces because separations are always subtractive.
1046 */
1047 if (additive)
1048 comp_value = frac_1 - comp_value;
1049
1050 /* Use the "all" value for all components */
1051 i = pis->color_component_map.num_colorants - 1;
1052 for (; i >= 0; i--)
1053 cm_comps[i] = comp_value;
1054 }
1055 else {
1056 /* map to the color model */
1057 map_components_to_colorants(&all, &(pis->color_component_map), cm_comps);
1058 }
1059
1060 /* apply the transfer function(s); convert to color values */
1061 if (additive)
1062 for (i = 0; i < ncomps; i++)
1063 cm_comps[i] = gx_map_color_frac(pis,
1064 cm_comps[i], effective_transfer[i]);
1065 else
1066 for (i = 0; i < ncomps; i++)
1067 cm_comps[i] = frac_1 - gx_map_color_frac(pis,
1068 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1069
1070 if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
1071 &pis->screen_phase[select]) == 1)
1072 gx_color_load_select(pdc, pis, dev, select);
1073 }
1074
1075 private void
cmap_separation_direct(frac all,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1076 cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state * pis,
1077 gx_device * dev, gs_color_select_t select)
1078 {
1079 int i, ncomps = dev->color_info.num_components;
1080 bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1081 frac comp_value = all;
1082 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1083 gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1084 gx_color_index color;
1085
1086 if (pis->color_component_map.sep_type == SEP_ALL) {
1087 /*
1088 * Invert the photometric interpretation for additive
1089 * color spaces because separations are always subtractive.
1090 */
1091 if (additive)
1092 comp_value = frac_1 - comp_value;
1093
1094 /* Use the "all" value for all components */
1095 i = pis->color_component_map.num_colorants - 1;
1096 for (; i >= 0; i--)
1097 cm_comps[i] = comp_value;
1098 }
1099 else {
1100 /* map to the color model */
1101 map_components_to_colorants(&comp_value, &(pis->color_component_map), cm_comps);
1102 }
1103
1104 /* apply the transfer function(s); convert to color values */
1105 if (additive)
1106 for (i = 0; i < ncomps; i++)
1107 cv[i] = frac2cv(gx_map_color_frac(pis,
1108 cm_comps[i], effective_transfer[i]));
1109 else
1110 for (i = 0; i < ncomps; i++)
1111 cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
1112 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
1113
1114 /* encode as a color index */
1115 color = dev_proc(dev, encode_color)(dev, cv);
1116
1117 /* check if the encoding was successful; we presume failure is rare */
1118 if (color != gx_no_color_index)
1119 color_set_pure(pdc, color);
1120 else
1121 cmap_separation_halftoned(all, pdc, pis, dev, select);
1122 }
1123
1124
1125 /* ------ DeviceN color mapping */
1126
1127 /*
1128 * This routine is called to map a DeviceN colorspace to a DeviceN
1129 * output device which requires halftoning. T
1130 */
1131 private void
cmap_devicen_halftoned(const frac * pcc,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1132 cmap_devicen_halftoned(const frac * pcc,
1133 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
1134 gs_color_select_t select)
1135 {
1136 int i, ncomps = dev->color_info.num_components;
1137 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1138
1139 /* map to the color model */
1140 map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);
1141
1142 /* apply the transfer function(s); convert to color values */
1143 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1144 for (i = 0; i < ncomps; i++)
1145 cm_comps[i] = gx_map_color_frac(pis,
1146 cm_comps[i], effective_transfer[i]);
1147 else
1148 for (i = 0; i < ncomps; i++)
1149 cm_comps[i] = frac_1 - gx_map_color_frac(pis,
1150 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1151
1152 /* We need to finish halftoning */
1153
1154 if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht,
1155 &pis->screen_phase[select]) == 1)
1156 gx_color_load_select(pdc, pis, dev, select);
1157 }
1158
1159 /*
1160 * This routine is called to map a DeviceN colorspace to a DeviceN
1161 * output device which does not require halftoning.
1162 */
1163 private void
cmap_devicen_direct(const frac * pcc,gx_device_color * pdc,const gs_imager_state * pis,gx_device * dev,gs_color_select_t select)1164 cmap_devicen_direct(const frac * pcc,
1165 gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev,
1166 gs_color_select_t select)
1167 {
1168 int i, ncomps = dev->color_info.num_components;
1169 frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1170 gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1171 gx_color_index color;
1172
1173 /* map to the color model */
1174 map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);;
1175
1176 /* apply the transfer function(s); convert to color values */
1177 if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1178 for (i = 0; i < ncomps; i++)
1179 cv[i] = frac2cv(gx_map_color_frac(pis,
1180 cm_comps[i], effective_transfer[i]));
1181 else
1182 for (i = 0; i < ncomps; i++)
1183 cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis,
1184 (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
1185
1186 /* encode as a color index */
1187 color = dev_proc(dev, encode_color)(dev, cv);
1188
1189 /* check if the encoding was successful; we presume failure is rare */
1190 if (color != gx_no_color_index)
1191 color_set_pure(pdc, color);
1192 else
1193 cmap_devicen_halftoned(pcc, pdc, pis, dev, select);
1194 }
1195
1196 /* ------ Halftoning check ----- */
1197
1198 private bool
cmap_halftoned_is_halftoned(const gs_imager_state * pis,gx_device * dev)1199 cmap_halftoned_is_halftoned(const gs_imager_state * pis, gx_device * dev)
1200 {
1201 return true;
1202 }
1203
1204 private bool
cmap_direct_is_halftoned(const gs_imager_state * pis,gx_device * dev)1205 cmap_direct_is_halftoned(const gs_imager_state * pis, gx_device * dev)
1206 {
1207 return false;
1208 }
1209
1210 /* ------ Transfer function mapping ------ */
1211
1212 /* Define an identity transfer function. */
1213 float
gs_identity_transfer(floatp value,const gx_transfer_map * pmap)1214 gs_identity_transfer(floatp value, const gx_transfer_map * pmap)
1215 {
1216 return (float) value;
1217 }
1218
1219 /* Define the generic transfer function for the library layer. */
1220 /* This just returns what's already in the map. */
1221 float
gs_mapped_transfer(floatp value,const gx_transfer_map * pmap)1222 gs_mapped_transfer(floatp value, const gx_transfer_map * pmap)
1223 {
1224 return gx_map_color_float(pmap, value);
1225 }
1226
1227 /* Set a transfer map to the identity map. */
1228 void
gx_set_identity_transfer(gx_transfer_map * pmap)1229 gx_set_identity_transfer(gx_transfer_map *pmap)
1230 {
1231 int i;
1232
1233 pmap->proc = gs_identity_transfer;
1234 /* We still have to fill in the cached values. */
1235 for (i = 0; i < transfer_map_size; ++i)
1236 pmap->values[i] = bits2frac(i, log2_transfer_map_size);
1237 }
1238
1239 #if FRAC_MAP_INTERPOLATE /* NOTA BENE */
1240
1241 /* Map a color fraction through a transfer map. */
1242 /* We only use this if we are interpolating. */
1243 frac
gx_color_frac_map(frac cv,const frac * values)1244 gx_color_frac_map(frac cv, const frac * values)
1245 {
1246 #define cp_frac_bits (frac_bits - log2_transfer_map_size)
1247 int cmi = frac2bits_floor(cv, log2_transfer_map_size);
1248 frac mv = values[cmi];
1249 int rem, mdv;
1250
1251 /* Interpolate between two adjacent values if needed. */
1252 rem = cv - bits2frac(cmi, log2_transfer_map_size);
1253 if (rem == 0)
1254 return mv;
1255 mdv = values[cmi + 1] - mv;
1256 #if arch_ints_are_short
1257 /* Only use long multiplication if necessary. */
1258 if (mdv < -1 << (16 - cp_frac_bits) ||
1259 mdv > 1 << (16 - cp_frac_bits)
1260 )
1261 return mv + (uint) (((ulong) rem * mdv) >> cp_frac_bits);
1262 #endif
1263 return mv + ((rem * mdv) >> cp_frac_bits);
1264 #undef cp_frac_bits
1265 }
1266
1267 #endif /* FRAC_MAP_INTERPOLATE */
1268
1269 /* ------ Default device color mapping ------ */
1270 /* White-on-black */
1271 gx_color_index
gx_default_w_b_map_rgb_color(gx_device * dev,const gx_color_value cv[])1272 gx_default_w_b_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1273 { /* Map values >= 1/2 to 1, < 1/2 to 0. */
1274 int i, ncomps = dev->color_info.num_components;
1275 gx_color_value cv_all = 0;
1276
1277 for (i = 0; i < ncomps; i++)
1278 cv_all |= cv[i];
1279 return cv_all > gx_max_color_value / 2 ? (gx_color_index)1
1280 : (gx_color_index)0;
1281
1282 }
1283
1284 int
gx_default_w_b_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1285 gx_default_w_b_map_color_rgb(gx_device * dev, gx_color_index color,
1286 gx_color_value prgb[3])
1287 { /* Map 1 to max_value, 0 to 0. */
1288 prgb[0] = prgb[1] = prgb[2] = -(gx_color_value) color;
1289 return 0;
1290 }
1291
1292 /* Black-on-white */
1293 gx_color_index
gx_default_b_w_map_rgb_color(gx_device * dev,const gx_color_value cv[])1294 gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1295 {
1296 int i, ncomps = dev->color_info.num_components;
1297 gx_color_value cv_all = 0;
1298
1299 for (i = 0; i < ncomps; i++)
1300 cv_all |= cv[i];
1301 return cv_all > gx_max_color_value / 2 ? (gx_color_index)0
1302 : (gx_color_index)1;
1303 }
1304
1305 int
gx_default_b_w_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1306 gx_default_b_w_map_color_rgb(gx_device * dev, gx_color_index color,
1307 gx_color_value prgb[3])
1308 { /* Map 0 to max_value, 1 to 0. */
1309 prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
1310 return 0;
1311 }
1312
1313 /* RGB mapping for gray-scale devices */
1314
1315 gx_color_index
gx_default_gray_map_rgb_color(gx_device * dev,const gx_color_value cv[])1316 gx_default_gray_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1317 { /* We round the value rather than truncating it. */
1318 gx_color_value gray =
1319 (((cv[0] * (ulong) lum_red_weight) +
1320 (cv[1] * (ulong) lum_green_weight) +
1321 (cv[2] * (ulong) lum_blue_weight) +
1322 (lum_all_weights / 2)) / lum_all_weights
1323 * dev->color_info.max_gray +
1324 (gx_max_color_value / 2)) / gx_max_color_value;
1325
1326 return gray;
1327 }
1328
1329 int
gx_default_gray_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1330 gx_default_gray_map_color_rgb(gx_device * dev, gx_color_index color,
1331 gx_color_value prgb[3])
1332 {
1333 gx_color_value gray = (gx_color_value)
1334 (color * gx_max_color_value / dev->color_info.max_gray);
1335
1336 prgb[0] = gray;
1337 prgb[1] = gray;
1338 prgb[2] = gray;
1339 return 0;
1340 }
1341
1342 gx_color_index
gx_default_8bit_map_gray_color(gx_device * dev,const gx_color_value cv[])1343 gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[])
1344 {
1345 gx_color_index color = gx_color_value_to_byte(cv[0]);
1346
1347 return (color == gx_no_color_index ? color ^ 1 : color);
1348 }
1349
1350 int
gx_default_8bit_map_color_gray(gx_device * dev,gx_color_index color,gx_color_value pgray[1])1351 gx_default_8bit_map_color_gray(gx_device * dev, gx_color_index color,
1352 gx_color_value pgray[1])
1353 {
1354 pgray[0] = (gx_color_value)(color * gx_max_color_value / 255);
1355 return 0;
1356 }
1357
1358 /* RGB mapping for 24-bit true (RGB) color devices */
1359
1360 gx_color_index
gx_default_rgb_map_rgb_color(gx_device * dev,const gx_color_value cv[])1361 gx_default_rgb_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1362 {
1363 if (dev->color_info.depth == 24)
1364 return gx_color_value_to_byte(cv[2]) +
1365 ((uint) gx_color_value_to_byte(cv[1]) << 8) +
1366 ((ulong) gx_color_value_to_byte(cv[0]) << 16);
1367 else {
1368 int bpc = dev->color_info.depth / 3;
1369 int drop = sizeof(gx_color_value) * 8 - bpc;
1370 return ( ( (((gx_color_index)cv[0] >> drop) << bpc) +
1371 ((gx_color_index)cv[1] >> drop) ) << bpc) +
1372 ((gx_color_index)cv[2] >> drop);
1373 }
1374 }
1375
1376 /* Map a color index to a r-g-b color. */
1377 int
gx_default_rgb_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1378 gx_default_rgb_map_color_rgb(gx_device * dev, gx_color_index color,
1379 gx_color_value prgb[3])
1380 {
1381 if (dev->color_info.depth == 24) {
1382 prgb[0] = gx_color_value_from_byte(color >> 16);
1383 prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
1384 prgb[2] = gx_color_value_from_byte(color & 0xff);
1385 } else {
1386 uint bits_per_color = dev->color_info.depth / 3;
1387 uint color_mask = (1 << bits_per_color) - 1;
1388
1389 prgb[0] = ((color >> (bits_per_color * 2)) & color_mask) *
1390 (ulong) gx_max_color_value / color_mask;
1391 prgb[1] = ((color >> (bits_per_color)) & color_mask) *
1392 (ulong) gx_max_color_value / color_mask;
1393 prgb[2] = (color & color_mask) *
1394 (ulong) gx_max_color_value / color_mask;
1395 }
1396 return 0;
1397 }
1398
1399 /* CMYK mapping for RGB devices (should never be called!) */
1400
1401 gx_color_index
gx_default_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1402 gx_default_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1403 { /* Convert to RGB */
1404 frac rgb[3];
1405 gx_color_value rgb_cv[3];
1406 color_cmyk_to_rgb(cv2frac(cv[0]), cv2frac(cv[1]), cv2frac(cv[2]), cv2frac(cv[3]),
1407 NULL, rgb);
1408 rgb_cv[0] = frac2cv(rgb[0]);
1409 rgb_cv[1] = frac2cv(rgb[1]);
1410 rgb_cv[2] = frac2cv(rgb[2]);
1411 return (*dev_proc(dev, map_rgb_color)) (dev, rgb_cv);
1412 }
1413
1414 /* Mapping for CMYK devices */
1415
1416 gx_color_index
cmyk_1bit_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1417 cmyk_1bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1418 {
1419 #define CV_BIT(v) ((v) >> (gx_color_value_bits - 1))
1420 return (gx_color_index)
1421 (CV_BIT(cv[3]) + (CV_BIT(cv[2]) << 1) + (CV_BIT(cv[1]) << 2) + (CV_BIT(cv[0]) << 3));
1422 #undef CV_BIT
1423 }
1424
1425 /* Shouldn't be called: decode_color should be cmyk_1bit_map_color_cmyk */
1426 int
cmyk_1bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1427 cmyk_1bit_map_color_rgb(gx_device * dev, gx_color_index color,
1428 gx_color_value prgb[3])
1429 {
1430 if (color & 1)
1431 prgb[0] = prgb[1] = prgb[2] = 0;
1432 else {
1433 prgb[0] = (color & 8 ? 0 : gx_max_color_value);
1434 prgb[1] = (color & 4 ? 0 : gx_max_color_value);
1435 prgb[2] = (color & 2 ? 0 : gx_max_color_value);
1436 }
1437 return 0;
1438 }
1439
1440 int
cmyk_1bit_map_color_cmyk(gx_device * dev,gx_color_index color,gx_color_value pcv[4])1441 cmyk_1bit_map_color_cmyk(gx_device * dev, gx_color_index color,
1442 gx_color_value pcv[4])
1443 {
1444 pcv[0] = (color & 8 ? 0 : gx_max_color_value);
1445 pcv[1] = (color & 4 ? 0 : gx_max_color_value);
1446 pcv[2] = (color & 2 ? 0 : gx_max_color_value);
1447 pcv[3] = (color & 1 ? 0 : gx_max_color_value);
1448 return 0;
1449 }
1450
1451 gx_color_index
cmyk_8bit_map_cmyk_color(gx_device * dev,const gx_color_value cv[])1452 cmyk_8bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1453 {
1454 gx_color_index color =
1455 gx_color_value_to_byte(cv[3]) +
1456 ((uint)gx_color_value_to_byte(cv[2]) << 8) +
1457 ((uint)gx_color_value_to_byte(cv[1]) << 16) +
1458 ((uint)gx_color_value_to_byte(cv[0]) << 24);
1459
1460 return (color == gx_no_color_index ? color ^ 1 : color);
1461 }
1462
1463 /* Shouldn't be called: decode_color should be cmyk_8bit_map_color_cmyk */
1464 int
cmyk_8bit_map_color_rgb(gx_device * dev,gx_color_index color,gx_color_value prgb[3])1465 cmyk_8bit_map_color_rgb(gx_device * dev, gx_color_index color,
1466 gx_color_value prgb[3])
1467 {
1468 int
1469 not_k = (int) (~color & 0xff),
1470 r = not_k - (int) (color >> 24),
1471 g = not_k - (int) ((color >> 16) & 0xff),
1472 b = not_k - (int) ((color >> 8) & 0xff);
1473
1474 prgb[0] = (r < 0 ? 0 : gx_color_value_from_byte(r));
1475 prgb[1] = (g < 0 ? 0 : gx_color_value_from_byte(g));
1476 prgb[2] = (b < 0 ? 0 : gx_color_value_from_byte(b));
1477 return 0;
1478 }
1479
1480 int
cmyk_8bit_map_color_cmyk(gx_device * dev,gx_color_index color,gx_color_value pcv[4])1481 cmyk_8bit_map_color_cmyk(gx_device * dev, gx_color_index color,
1482 gx_color_value pcv[4])
1483 {
1484 pcv[0] = gx_color_value_from_byte((color >> 24) & 0xff);
1485 pcv[1] = gx_color_value_from_byte((color >> 16) & 0xff);
1486 pcv[2] = gx_color_value_from_byte((color >> 8) & 0xff);
1487 pcv[3] = gx_color_value_from_byte(color & 0xff);
1488 return 0;
1489 }
1490
1491 /* Default mapping between RGB+alpha and RGB. */
1492
1493 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)1494 gx_default_map_rgb_alpha_color(gx_device * dev,
1495 gx_color_value r, gx_color_value g, gx_color_value b, gx_color_value alpha)
1496 { /* Colors have been premultiplied: we don't need to do it here. */
1497 gx_color_value cv[3];
1498 cv[0] = r; cv[1] = g; cv[2] = b;
1499 return (*dev_proc(dev, map_rgb_color))(dev, cv);
1500 }
1501
1502 int
gx_default_map_color_rgb_alpha(gx_device * dev,gx_color_index color,gx_color_value prgba[4])1503 gx_default_map_color_rgb_alpha(gx_device * dev, gx_color_index color,
1504 gx_color_value prgba[4])
1505 {
1506 prgba[3] = gx_max_color_value; /* alpha = 1 */
1507 return (*dev_proc(dev, map_color_rgb)) (dev, color, prgba);
1508 }
1509