Coverage Report

Created: 2025-06-24 07:01

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