Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gxcmap.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* Color mapping for Ghostscript */
18
#include "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
776
#define USE_ALT_MAP 0
50
51
/* Structure descriptor */
52
public_st_device_color();
53
static
54
1.46M
ENUM_PTRS_WITH(device_color_enum_ptrs, gx_device_color *cptr)
55
1.46M
{
56
1.46M
        return ENUM_USING(*cptr->type->stype, vptr, size, index);
57
0
}
58
1.46M
ENUM_PTRS_END
59
1.46M
static RELOC_PTRS_WITH(device_color_reloc_ptrs, gx_device_color *cptr)
60
1.46M
{
61
1.46M
    RELOC_USING(*cptr->type->stype, vptr, size);
62
1.46M
}
63
1.46M
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
1.00M
{
181
1.00M
    COLROUND_VARS;
182
1.00M
    COLROUND_SETUP(dev->color_info.depth);
183
1.00M
    return COLROUND_ROUND(cv[0]);
184
1.00M
}
185
186
gx_color_index
187
gx_default_gray_encode(gx_device * dev, const gx_color_value cv[])
188
2
{
189
2
    return (gx_color_index)(cv[0]) * (dev->color_info.max_gray + 1) / (gx_max_color_value + 1);
190
2
}
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
770k
{
202
770k
    gx_color_value gray_val = cv[0];
203
770k
    gx_color_value rgb_cv[3];
204
205
770k
    rgb_cv[0] = gray_val;
206
770k
    rgb_cv[1] = gray_val;
207
770k
    rgb_cv[2] = gray_val;
208
770k
    return (*dev_proc(dev, map_rgb_color))(dev, rgb_cv);
209
770k
}
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
3.59M
{
216
3.59M
    out[0] = gray;
217
3.59M
}
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
6.86k
{
223
6.86k
    out[0] = color_rgb_to_gray(r, g, b, NULL);
224
6.86k
}
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
1.93k
{
229
1.93k
    out[0] = color_cmyk_to_gray(c, m, y, k, NULL);
230
1.93k
}
231
232
static void
233
gray_cs_to_rgb_cm(const gx_device * dev, frac gray, frac out[])
234
119k
{
235
119k
    out[0] = out[1] = out[2] = gray;
236
119k
}
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
28.8M
{
242
28.8M
    out[0] = r;
243
28.8M
    out[1] = g;
244
28.8M
    out[2] = b;
245
28.8M
}
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
0
{
293
0
    out[0] = out[1] = out[2] = frac_0;
294
0
    out[3] = frac_1 - gray;
295
0
}
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
4.18M
{
332
4.18M
    out[0] = c;
333
4.18M
    out[1] = m;
334
4.18M
    out[2] = y;
335
4.18M
    out[3] = k;
336
4.18M
}
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
3.60M
{
364
3.60M
    *tdev = dev;
365
3.60M
    return &DeviceGray_procs;
366
3.60M
}
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
29.1M
{
372
29.1M
    *tdev = dev;
373
29.1M
    return &DeviceRGB_procs;
374
29.1M
}
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
4.18M
{
380
4.18M
    *tdev = dev;
381
4.18M
    return &DeviceCMYK_procs;
382
4.18M
}
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
1.37M
    (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
452k
{
427
452k
    if (compare_color_names(pname, name_size, "Gray") ||
428
452k
        compare_color_names(pname, name_size, "Grey"))
429
61.6k
        return 0;
430
390k
    else
431
390k
        return -1;       /* Indicate that the component name is "unknown" */
432
452k
}
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
23.0k
{
439
23.0k
    if (compare_color_names(pname, name_size, "Red"))
440
4
        return 0;
441
23.0k
    if (compare_color_names(pname, name_size, "Green"))
442
4
        return 1;
443
23.0k
    if (compare_color_names(pname, name_size, "Blue"))
444
4
        return 2;
445
23.0k
    else
446
23.0k
        return -1;       /* Indicate that the component name is "unknown" */
447
23.0k
}
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
2.84k
{
454
2.84k
    if (compare_color_names(pname, name_size, "Cyan"))
455
36
        return 0;
456
2.81k
    if (compare_color_names(pname, name_size, "Magenta"))
457
220
        return 1;
458
2.59k
    if (compare_color_names(pname, name_size, "Yellow"))
459
184
        return 2;
460
2.40k
    if (compare_color_names(pname, name_size, "Black"))
461
2.40k
        return 3;
462
0
    else
463
0
        return -1;       /* Indicate that the component name is "unknown" */
464
2.40k
}
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
2.49M
{
545
2.49M
    return (pgs->get_cmap_procs)(pgs, dev);
546
2.49M
}
547
548
const gx_color_map_procs *
549
gx_default_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
550
2.01M
{
551
2.01M
    return (gx_device_must_halftone(dev) ? &cmap_few : &cmap_many);
552
2.01M
}
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
2.14M
{
558
2.14M
    pgs->cmap_procs = gx_get_cmap_procs(pgs, dev);
559
2.14M
}
560
561
/* Remap the color in the graphics state. */
562
int
563
gx_remap_color(gs_gstate * pgs)
564
5.20M
{
565
5.20M
    const gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
566
5.20M
    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
5.20M
    if (!gx_dc_is_pure(gs_currentdevicecolor_inline(pgs)))
572
5.20M
        code = (*pcs->type->remap_color) (gs_currentcolor_inline(pgs),
573
5.20M
                                          pcs, gs_currentdevicecolor_inline(pgs),
574
5.20M
                                          (gs_gstate *) pgs, pgs->device,
575
5.20M
                                          gs_color_select_texture);
576
5.20M
    return code;
577
5.20M
}
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
16.8M
{
590
16.8M
    return pcs;
591
16.8M
}
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
bool
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
16.8M
{
734
16.8M
    frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS];
735
16.8M
    const gs_color_space *pconcs;
736
16.8M
    int i = pcs->type->num_components(pcs);
737
16.8M
    int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pgs, dev);
738
16.8M
    cmm_dev_profile_t *dev_profile;
739
740
16.8M
    if (code < 0)
741
229
        return code;
742
16.8M
    pconcs = cs_concrete_space(pcs, pgs);
743
16.8M
    if (!pconcs)
744
0
        return gs_note_error(gs_error_undefined);
745
16.8M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
746
16.8M
    if (code < 0)
747
0
        return code;
748
16.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
16.8M
    i = any_abs(i);
752
33.6M
    for (i--; i >= 0; i--)
753
16.8M
        pdc->ccolor.paint.values[i] = pcc->paint.values[i];
754
16.8M
    pdc->ccolor_valid = true;
755
16.8M
    return code;
756
16.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
3.43M
{
776
3.43M
    (*pgs->cmap_procs->map_gray)(pconc[0], pdc, pgs, dev, select);
777
3.43M
    return 0;
778
3.43M
}
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
267k
{
784
267k
    frac fgray = gx_unit_frac(pc->paint.values[0]);
785
267k
    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
267k
    if (pgs->icc_manager->default_gray != NULL) {
793
89.2k
        gs_color_space *pcs_notconst = (gs_color_space*) pcs;
794
89.2k
        pcs_notconst->cmm_icc_profile_data = pgs->icc_manager->default_gray;
795
89.2k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "gx_remap_DeviceGray");
796
89.2k
        pcs_notconst->type = &gs_color_space_type_ICC;
797
89.2k
        code =
798
89.2k
            (*pcs_notconst->type->remap_color)(gs_currentcolor_inline(pgs),
799
89.2k
                                               pcs_notconst,
800
89.2k
                                               gs_currentdevicecolor_inline(pgs),
801
89.2k
                                               pgs, pgs->device,
802
89.2k
                                               gs_color_select_texture);
803
89.2k
        return code;
804
89.2k
    }
805
806
    /* Save original color space and color info into dev color */
807
178k
    pdc->ccolor.paint.values[0] = pc->paint.values[0];
808
178k
    pdc->ccolor_valid = true;
809
810
178k
    (*pgs->cmap_procs->map_gray)(fgray, pdc, pgs, dev, select);
811
178k
    return 0;
812
267k
}
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
139M
{
830
831
139M
    gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2], pdc, pgs, dev, select);
832
139M
    return 0;
833
139M
}
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
21.4M
{
869
/****** IGNORE alpha ******/
870
21.4M
    gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3], pdc,
871
21.4M
                           pgs, dev, select, pcs);
872
21.4M
    return 0;
873
21.4M
}
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
120M
{
909
120M
    gs_HT_objtype_t objtype;
910
911
    /* This function only works with 3 bits currently. Flag here in case we add object types */
912
120M
    assert(HT_OBJTYPE_COUNT == 4);
913
914
120M
    objtype = tag_to_HT_objtype[pgs->device->graphics_type_tag & 7];
915
120M
    if (pgs->dev_ht[objtype] == NULL)
916
120M
        objtype = HT_OBJTYPE_DEFAULT;
917
120M
    return pgs->dev_ht[objtype];
918
120M
}
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
844k
{
926
844k
    uchar i, ncomps = dev->color_info.num_components;
927
844k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
928
844k
    const gx_device *cmdev;
929
844k
    const gx_cm_color_map_procs *cmprocs;
930
931
    /* map to the color model */
932
844k
    cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
933
844k
    cmprocs->map_gray(cmdev, gray, cm_comps);
934
935
    /* apply the transfer function(s); convert to color values */
936
844k
    if (pgs->effective_transfer_non_identity_count == 0) {
937
        /* No transfer function to apply */
938
570k
    } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
939
1.08M
        for (i = 0; i < ncomps; i++)
940
543k
            cm_comps[i] = gx_map_color_frac(pgs,
941
570k
                                cm_comps[i], effective_transfer[i]);
942
26.8k
    else {
943
26.8k
        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
26.8k
        } else {
949
53.7k
            for (i = 0; i < ncomps; i++)
950
26.8k
                    cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
951
26.8k
                            (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
952
26.8k
        }
953
26.8k
    }
954
844k
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
955
844k
                                        &pgs->screen_phase[select]) == 1)
956
185k
        gx_color_load_select(pdc, pgs, dev, select);
957
844k
}
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
624k
{
963
624k
    uchar i, ncomps = dev->color_info.num_components;
964
624k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
965
624k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
966
624k
    gx_color_index color;
967
624k
    const gx_device *cmdev;
968
624k
    const gx_cm_color_map_procs *cmprocs;
969
970
    /* map to the color model */
971
624k
    cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
972
624k
    cmprocs->map_gray(cmdev, gray, cm_comps);
973
974
    /* apply the transfer function(s); convert to color values */
975
624k
    if (pgs->effective_transfer_non_identity_count == 0) {
976
1.24M
        for (i = 0; i < ncomps; i++)
977
624k
            cv[i] = frac2cv(cm_comps[i]);
978
624k
    } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
979
190
        for (i = 0; i < ncomps; i++) {
980
95
            cm_comps[i] = gx_map_color_frac(pgs,
981
95
                                cm_comps[i], effective_transfer[i]);
982
95
            cv[i] = frac2cv(cm_comps[i]);
983
95
        }
984
0
    else {
985
0
        if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) {  /* CMYK-like color space */
986
0
            i = dev->color_info.black_component;
987
0
            if (i < ncomps)
988
0
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
989
0
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
990
0
            for (i = 0; i < ncomps; i++)
991
0
                cv[i] = frac2cv(cm_comps[i]);
992
0
        } else {
993
0
            for (i = 0; i < ncomps; i++) {
994
0
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
995
0
                            (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
996
0
                cv[i] = frac2cv(cm_comps[i]);
997
0
            }
998
0
        }
999
0
    }
1000
    /* encode as a color index */
1001
624k
    color = dev_proc(dev, encode_color)(dev, cv);
1002
1003
    /* check if the encoding was successful; we presume failure is rare */
1004
624k
    if (color != gx_no_color_index) {
1005
624k
        color_set_pure(pdc, color);
1006
624k
        return;
1007
624k
    }
1008
0
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1009
0
                                        &pgs->screen_phase[select]) == 1)
1010
0
        gx_color_load_select(pdc, pgs, dev, select);
1011
0
}
1012
1013
/* ------ Render RGB color. ------ */
1014
1015
static void
1016
cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc,
1017
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
1018
106M
{
1019
106M
    uchar i, ncomps = dev->color_info.num_components;
1020
106M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1021
106M
    const gx_device *cmdev;
1022
106M
    const gx_cm_color_map_procs *cmprocs;
1023
1024
    /* map to the color model */
1025
106M
    cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
1026
106M
    cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps);
1027
1028
    /* apply the transfer function(s); convert to color values */
1029
106M
    if (pgs->effective_transfer_non_identity_count != 0) {
1030
106M
        if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1031
424M
            for (i = 0; i < ncomps; i++)
1032
318M
                cm_comps[i] = gx_map_color_frac(pgs,
1033
106M
                                cm_comps[i], effective_transfer[i]);
1034
0
        else
1035
0
            for (i = 0; i < ncomps; i++)
1036
0
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1037
106M
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1038
106M
    }
1039
1040
106M
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1041
106M
                                        &pgs->screen_phase[select]) == 1)
1042
58.2M
        gx_color_load_select(pdc, pgs, dev, select);
1043
106M
}
1044
1045
static void
1046
cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
1047
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
1048
28.7M
{
1049
28.7M
    uchar i, ncomps = dev->color_info.num_components;
1050
28.7M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1051
28.7M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1052
28.7M
    gx_color_index color;
1053
28.7M
    const gx_device *cmdev;
1054
28.7M
    const gx_cm_color_map_procs *cmprocs;
1055
1056
    /* map to the color model */
1057
28.7M
    cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
1058
28.7M
    cmprocs->map_rgb(cmdev, pgs, r, g, b, cm_comps);
1059
1060
    /* apply the transfer function(s); convert to color values */
1061
28.7M
    if (pgs->effective_transfer_non_identity_count == 0) {
1062
114M
        for (i = 0; i < ncomps; i++)
1063
86.1M
            cv[i] = frac2cv(cm_comps[i]);
1064
28.7M
    } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1065
16
        for (i = 0; i < ncomps; i++) {
1066
12
            cm_comps[i] = gx_map_color_frac(pgs,
1067
12
                                cm_comps[i], effective_transfer[i]);
1068
12
            cv[i] = frac2cv(cm_comps[i]);
1069
12
        }
1070
0
    else
1071
0
        for (i = 0; i < ncomps; i++) {
1072
0
            cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1073
0
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1074
0
            cv[i] = frac2cv(cm_comps[i]);
1075
0
        }
1076
1077
    /* encode as a color index */
1078
28.7M
    color = dev_proc(dev, encode_color)(dev, cv);
1079
1080
    /* check if the encoding was successful; we presume failure is rare */
1081
28.7M
    if (color != gx_no_color_index) {
1082
28.7M
        color_set_pure(pdc, color);
1083
28.7M
        return;
1084
28.7M
    }
1085
0
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1086
0
                                        &pgs->screen_phase[select]) == 1)
1087
0
        gx_color_load_select(pdc, pgs, dev, select);
1088
0
}
1089
1090
/* ------ Render CMYK color. ------ */
1091
1092
static void
1093
cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
1094
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
1095
     const gs_color_space *source_pcs)
1096
15.0M
{
1097
15.0M
    uchar i, ncomps = dev->color_info.num_components;
1098
15.0M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1099
15.0M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1100
15.0M
    gx_color_index color;
1101
15.0M
    uint black_index;
1102
15.0M
    cmm_dev_profile_t *dev_profile;
1103
15.0M
    gsicc_colorbuffer_t src_space = gsUNDEFINED;
1104
15.0M
    bool gray_to_k;
1105
15.0M
    const gx_device *cmdev;
1106
15.0M
    const gx_cm_color_map_procs *cmprocs;
1107
1108
    /* map to the color model */
1109
15.0M
    cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
1110
15.0M
    cmprocs->map_cmyk(cmdev, c, m, y, k, cm_comps);
1111
1112
    /* apply the transfer function(s); convert to color values */
1113
15.0M
    if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
1114
1
        if (pgs->effective_transfer_non_identity_count != 0)
1115
2
            for (i = 0; i < ncomps; i++)
1116
1
                cm_comps[i] = gx_map_color_frac(pgs,
1117
1
                                cm_comps[i], effective_transfer[i]);
1118
15.0M
    } else {
1119
        /* Check if source space is gray.  In this case we are to use only the
1120
           transfer function on the K channel.  Do this only if gray to K is
1121
           also set */
1122
15.0M
        dev_proc(dev, get_profile)(dev, &dev_profile);
1123
15.0M
        gray_to_k = dev_profile->devicegraytok;
1124
15.0M
        if (source_pcs != NULL && source_pcs->cmm_icc_profile_data != NULL) {
1125
15.0M
            src_space = source_pcs->cmm_icc_profile_data->data_cs;
1126
15.0M
        } else if (source_pcs != NULL && source_pcs->icc_equivalent != NULL) {
1127
0
            src_space = source_pcs->icc_equivalent->cmm_icc_profile_data->data_cs;
1128
0
        }
1129
15.0M
        if (src_space == gsGRAY && gray_to_k) {
1130
            /* Find the black channel location */
1131
371k
            black_index = dev_proc(dev, get_color_comp_index)(dev, "Black",
1132
371k
                                    strlen("Black"), SEPARATION_NAME);
1133
371k
            cm_comps[black_index] = frac_1 - gx_map_color_frac(pgs,
1134
371k
                                    (frac)(frac_1 - cm_comps[black_index]),
1135
371k
                                    effective_transfer[black_index]);
1136
14.7M
        } else if (pgs->effective_transfer_non_identity_count != 0)
1137
65.8M
            for (i = 0; i < ncomps; i++)
1138
52.6M
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1139
15.0M
                            (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1140
15.0M
    }
1141
    /* We make a test for direct vs. halftoned, rather than */
1142
    /* duplicating most of the code of this procedure. */
1143
15.0M
    if (gx_device_must_halftone(dev)) {
1144
13.3M
        if (gx_render_device_DeviceN(cm_comps, pdc, dev,
1145
13.3M
                    gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
1146
8.27M
            gx_color_load_select(pdc, pgs, dev, select);
1147
13.3M
        return;
1148
13.3M
    }
1149
    /* if output device supports devn, we need to make sure we send it the
1150
       proper color type */
1151
1.70M
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1152
9.17M
        for (i = 0; i < ncomps; i++)
1153
7.46M
            pdc->colors.devn.values[i] = frac2cv(cm_comps[i]);
1154
1.70M
        pdc->type = gx_dc_type_devn;
1155
1.70M
    } else {
1156
0
        for (i = 0; i < ncomps; i++)
1157
0
            cv[i] = frac2cv(cm_comps[i]);
1158
0
        color = dev_proc(dev, encode_color)(dev, cv);
1159
0
        if (color != gx_no_color_index)
1160
0
            color_set_pure(pdc, color);
1161
0
        else {
1162
0
            if (gx_render_device_DeviceN(cm_comps, pdc, dev,
1163
0
                        gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
1164
0
                gx_color_load_select(pdc, pgs, dev, select);
1165
0
        }
1166
0
    }
1167
1.70M
    return;
1168
15.0M
}
1169
1170
/* ------ Render Separation All color. ------ */
1171
1172
/*
1173
 * This routine maps DeviceN components into the order of the device's
1174
 * colorants.
1175
 *
1176
 * Parameters:
1177
 *    pcc - Pointer to DeviceN components.
1178
 *    pcolor_component_map - Map from DeviceN to the Devices colorants.
1179
 *        A negative value indicates component is not to be mapped.
1180
 *    plist - Pointer to list for mapped components
1181
 *    num_comps - num_comps that we need to zero (may be more than
1182
 *                is set if we are mapping values for an NCLR ICC profile
1183
 *                via an alternate tint transform for a sep value) --
1184
 *                i.e. cmyk+og values and we may have some spots that
1185
 *                are supported but may have reached the limit and
1186
 *                using the alt tint values.  Need to make sure to zero all.
1187
 *
1188
 * Returns:
1189
 *    Mapped components in plist.
1190
 */
1191
static inline void
1192
map_components_to_colorants(const frac * pcc,
1193
        const gs_devicen_color_map * pcolor_component_map, frac * plist,
1194
        int num_colorants)
1195
4.44k
{
1196
4.44k
    int i;
1197
4.44k
    int pos;
1198
1199
    /* Clear all output colorants first */
1200
23.9k
    for (i = num_colorants - 1; i >= 0; i--) {
1201
19.5k
        plist[i] = frac_0;
1202
19.5k
    }
1203
1204
    /* Map color components into output list */
1205
11.3k
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
1206
6.88k
        pos = pcolor_component_map->color_map[i];
1207
6.88k
        if (pos >= 0)
1208
4.46k
            plist[pos] = pcc[i];
1209
6.88k
    }
1210
4.44k
}
1211
1212
static bool
1213
named_color_supported(const gs_gstate * pgs)
1214
4.44k
{
1215
4.44k
    gs_color_space *pcs = gs_currentcolorspace_inline(pgs);
1216
4.44k
    gs_color_space_index type = gs_color_space_get_index(pcs);
1217
1218
4.44k
    if (pgs->icc_manager->device_named == NULL)
1219
4.44k
        return false;
1220
1221
0
    if (type == gs_color_space_index_Separation && pcs->params.separation.named_color_supported)
1222
0
        return true;
1223
1224
0
    if (type == gs_color_space_index_DeviceN && pcs->params.device_n.named_color_supported)
1225
0
        return true;
1226
1227
0
    return false;
1228
0
}
1229
1230
/* Routines for handling CM of CMYK components of a DeviceN color space */
1231
static bool
1232
devicen_has_cmyk(gx_device * dev, cmm_profile_t *des_profile)
1233
4.44k
{
1234
4.44k
    gs_devn_params *devn_params;
1235
1236
4.44k
    devn_params = dev_proc(dev, ret_devn_params)(dev);
1237
4.44k
    if (devn_params == NULL) {
1238
0
        if (des_profile != NULL && des_profile->data_cs == gsCMYK)
1239
0
            return true;
1240
0
        else
1241
0
            return false;
1242
0
    }
1243
4.44k
    return(devn_params->num_std_colorant_names == 4);
1244
4.44k
}
1245
1246
static void
1247
devicen_sep_icc_cmyk(frac cm_comps[], const gs_gstate * pgs,
1248
    const gs_color_space * pcs, gx_device *dev)
1249
4.44k
{
1250
4.44k
    gsicc_link_t *icc_link;
1251
4.44k
    gsicc_rendering_param_t rendering_params;
1252
4.44k
    unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS];
1253
4.44k
    unsigned short psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
1254
4.44k
    int k, code;
1255
4.44k
    unsigned short *psrc_temp;
1256
4.44k
    gsicc_rendering_param_t render_cond;
1257
4.44k
    cmm_dev_profile_t *dev_profile = NULL;
1258
4.44k
    cmm_profile_t *des_profile = NULL;
1259
4.44k
    cmm_profile_t *src_profile = pgs->icc_manager->default_cmyk;
1260
1261
4.44k
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
1262
1263
    /* If we can't transform them, we will just leave them as is. */
1264
4.44k
    if (code < 0)
1265
0
        return;
1266
1267
4.44k
    gsicc_extract_profile(dev->graphics_type_tag,
1268
4.44k
        dev_profile, &des_profile, &render_cond);
1269
    /* Define the rendering intents. */
1270
4.44k
    rendering_params.black_point_comp = pgs->blackptcomp;
1271
4.44k
    rendering_params.graphics_type_tag = dev->graphics_type_tag;
1272
4.44k
    rendering_params.override_icc = false;
1273
4.44k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
1274
4.44k
    rendering_params.rendering_intent = pgs->renderingintent;
1275
4.44k
    rendering_params.cmm = gsCMM_DEFAULT;
1276
    /* Sigh, frac to full 16 bit.  Need to clean this up */
1277
22.2k
    for (k = 0; k < 4; k++) {
1278
17.7k
        psrc[k] = frac2cv(cm_comps[k]);
1279
17.7k
    }
1280
1281
    /* Determine what src profile to use.  First choice is the attributes
1282
       process color space if it is the correct type.  Second choice is
1283
       the alternate tint transform color space if it is the correct type.
1284
       Third type is default_cmyk.  If we have an issue with bad profiles then
1285
       the color values will just remain as they were from the source */
1286
4.44k
    if (gs_color_space_get_index(pcs) == gs_color_space_index_DeviceN) {
1287
819
        if (pcs->params.device_n.devn_process_space != NULL &&
1288
819
            pcs->params.device_n.devn_process_space->cmm_icc_profile_data != NULL &&
1289
819
            pcs->params.device_n.devn_process_space->cmm_icc_profile_data->data_cs == gsCMYK) {
1290
2
            src_profile = pcs->params.device_n.devn_process_space->cmm_icc_profile_data;
1291
817
        } else if (pcs->base_space != NULL &&
1292
817
            pcs->base_space->cmm_icc_profile_data != NULL &&
1293
817
            pcs->base_space->cmm_icc_profile_data->data_cs == gsCMYK &&
1294
817
            USE_ALT_MAP) {
1295
0
            src_profile = pcs->base_space->cmm_icc_profile_data;
1296
0
        }
1297
3.62k
    } else if (gs_color_space_get_index(pcs) == gs_color_space_index_Separation) {
1298
3.62k
        if (pcs->base_space != NULL &&
1299
3.62k
            pcs->base_space->cmm_icc_profile_data != NULL &&
1300
3.62k
            pcs->base_space->cmm_icc_profile_data->data_cs == gsCMYK &&
1301
3.62k
            USE_ALT_MAP) {
1302
0
            src_profile = pcs->base_space->cmm_icc_profile_data;
1303
0
        }
1304
3.62k
    }
1305
1306
4.44k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
1307
4.44k
        &rendering_params, pgs->memory, dev_profile->devicegraytok);
1308
1309
4.44k
    if (icc_link == NULL && src_profile != pgs->icc_manager->default_cmyk) {
1310
0
        icc_link = gsicc_get_link_profile(pgs, dev,
1311
0
            pgs->icc_manager->default_cmyk, des_profile,
1312
0
            &rendering_params, pgs->memory, dev_profile->devicegraytok);
1313
0
    }
1314
1315
    /* If we can't transform them, we will just leave them as is. */
1316
4.44k
    if (icc_link == NULL)
1317
0
        return;
1318
1319
    /* Transform the color */
1320
4.44k
    if (icc_link->is_identity) {
1321
4.44k
        psrc_temp = &(psrc[0]);
1322
4.44k
    } else {
1323
        /* Transform the color */
1324
0
        psrc_temp = &(psrc_cm[0]);
1325
0
        (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2);
1326
0
    }
1327
    /* This needs to be optimized */
1328
22.2k
    for (k = 0; k < 4; k++) {
1329
17.7k
        cm_comps[k] = float2frac(((float)psrc_temp[k]) / 65535.0);
1330
17.7k
    }
1331
    /* Release the link */
1332
4.44k
    gsicc_release_link(icc_link);
1333
4.44k
}
1334
1335
static void
1336
cmap_separation_halftoned(frac all, gx_device_color * pdc,
1337
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
1338
     const gs_color_space *pcs)
1339
923
{
1340
923
    uint i, ncomps = dev->color_info.num_components;
1341
923
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1342
923
    frac comp_value = all;
1343
923
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1344
923
    gsicc_rendering_param_t render_cond;
1345
923
    cmm_dev_profile_t *dev_profile = NULL;
1346
923
    cmm_profile_t *des_profile = NULL;
1347
1348
923
    dev_proc(dev, get_profile)(dev, &dev_profile);
1349
923
    gsicc_extract_profile(dev->graphics_type_tag,
1350
923
        dev_profile, &des_profile, &render_cond);
1351
1352
923
    if (pgs->color_component_map.sep_type == SEP_ALL) {
1353
        /*
1354
         * Invert the photometric interpretation for additive
1355
         * color spaces because separations are always subtractive.
1356
         */
1357
0
        if (additive)
1358
0
            comp_value = frac_1 - comp_value;
1359
1360
        /* Use the "all" value for all components */
1361
0
        for (i = 0; i < pgs->color_component_map.num_colorants; i++)
1362
0
            cm_comps[i] = comp_value;
1363
923
    } else {
1364
923
        if (pgs->color_component_map.sep_type == SEP_NONE) {
1365
0
            color_set_null(pdc);
1366
0
            return;
1367
0
        }
1368
1369
        /* map to the color model */
1370
923
        map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps,
1371
923
            pgs->color_component_map.num_colorants);
1372
923
    }
1373
1374
923
    if (devicen_has_cmyk(dev, des_profile) &&
1375
923
        des_profile->data_cs == gsCMYK &&
1376
923
        !named_color_supported(pgs)) {
1377
923
        devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1378
923
    }
1379
1380
    /* apply the transfer function(s); convert to color values */
1381
923
    if (pgs->effective_transfer_non_identity_count != 0) {
1382
605
        if (additive)
1383
0
            for (i = 0; i < ncomps; i++)
1384
0
                cm_comps[i] = gx_map_color_frac(pgs,
1385
605
                                cm_comps[i], effective_transfer[i]);
1386
605
        else
1387
3.22k
            for (i = 0; i < ncomps; i++)
1388
2.62k
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1389
605
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1390
605
    }
1391
1392
923
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1393
923
                                        &pgs->screen_phase[select]) == 1)
1394
364
        gx_color_load_select(pdc, pgs, dev, select);
1395
923
}
1396
1397
static void
1398
cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
1399
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
1400
2.69k
{
1401
2.69k
    uint i, ncomps = dev->color_info.num_components;
1402
2.69k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
1403
2.69k
    frac comp_value = all;
1404
2.69k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1405
2.69k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1406
2.69k
    gx_color_index color;
1407
2.69k
    bool use_rgb2dev_icc = false;
1408
2.69k
    gsicc_rendering_param_t render_cond;
1409
2.69k
    cmm_dev_profile_t *dev_profile = NULL;
1410
2.69k
    cmm_profile_t *des_profile = NULL;
1411
1412
2.69k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1413
2.69k
    gsicc_extract_profile(dev->graphics_type_tag,
1414
2.69k
                          dev_profile, &des_profile, &render_cond);
1415
2.69k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
1416
        /*
1417
         * Invert the photometric interpretation for additive
1418
         * color spaces because separations are always subtractive.
1419
         */
1420
0
        if (additive)
1421
0
            comp_value = frac_1 - comp_value;
1422
1423
        /* Use the "all" value for all components */
1424
0
        for (i = 0; i < pgs->color_component_map.num_colorants; i++)
1425
0
            cm_comps[i] = comp_value;
1426
        /* If our device space is CIELAB then we really want to treat this
1427
           as RGB during the fill up here of the separation value and then
1428
           go ahead and convert from RGB to CIELAB.  The PDF spec is not clear
1429
           on how addivite devices should behave with the ALL option but it
1430
           is clear from testing the AR 10 does simply do the RGB = 1 - INK
1431
           type of mapping */
1432
0
        if (des_profile->data_cs == gsCIELAB || des_profile->islab) {
1433
0
            use_rgb2dev_icc = true;
1434
0
        }
1435
2.69k
    } else {
1436
2.69k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
1437
0
            color_set_null(pdc);
1438
0
            return;
1439
0
        }
1440
1441
        /* map to the color model */
1442
2.69k
        map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps,
1443
2.69k
            pgs->color_component_map.num_colorants);
1444
2.69k
    }
1445
1446
    /* Check if we have the standard colorants.  If yes, then we will apply
1447
      ICC color management to those colorants. */
1448
2.69k
    if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK &&
1449
2.69k
        !named_color_supported(pgs) && pgs->color_component_map.sep_type != SEP_ALL) {
1450
        /* We need to do a CMYK to CMYK conversion here.  This will always
1451
           use the default CMYK profile and the device's output profile.
1452
           We probably need to add some checking here
1453
           and possibly permute the colorants, much as is done on the input
1454
           side for the case when we add DeviceN icc source profiles for use
1455
           in PDF and PS data. Also, don't do this if we are doing mapping
1456
           through the named color mapping.  */
1457
2.69k
        devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1458
2.69k
    }
1459
1460
    /* apply the transfer function(s); convert to color values */
1461
2.69k
    if (pgs->effective_transfer_non_identity_count == 0)
1462
13.8k
        for (i = 0; i < ncomps; i++)
1463
11.1k
            cv[i] = frac2cv(cm_comps[i]);
1464
0
    else if (additive)
1465
0
        for (i = 0; i < ncomps; i++) {
1466
0
            cm_comps[i] = gx_map_color_frac(pgs,
1467
0
                                cm_comps[i], effective_transfer[i]);
1468
0
            cv[i] = frac2cv(cm_comps[i]);
1469
0
        }
1470
0
    else
1471
0
        for (i = 0; i < ncomps; i++) {
1472
0
            cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1473
0
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1474
0
            cv[i] = frac2cv(cm_comps[i]);
1475
0
        }
1476
1477
2.69k
    if (use_rgb2dev_icc && pgs->icc_manager->default_rgb != NULL) {
1478
        /* After the transfer function go ahead and do the mapping from RGB to
1479
           the device profile. */
1480
0
        gsicc_link_t *icc_link;
1481
0
        gsicc_rendering_param_t rendering_params;
1482
0
        unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS];
1483
1484
0
        rendering_params.black_point_comp = pgs->blackptcomp;
1485
0
        rendering_params.graphics_type_tag = dev->graphics_type_tag;
1486
0
        rendering_params.override_icc = false;
1487
0
        rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
1488
0
        rendering_params.rendering_intent = pgs->renderingintent;
1489
0
        rendering_params.cmm = gsCMM_DEFAULT;
1490
1491
0
        icc_link = gsicc_get_link_profile(pgs, dev, pgs->icc_manager->default_rgb,
1492
0
                                          des_profile, &rendering_params,
1493
0
                                          pgs->memory, dev_profile->devicegraytok);
1494
        /* Transform the color */
1495
0
        for (i = 0; i < ncomps; i++) {
1496
0
            psrc[i] = cv[i];
1497
0
        }
1498
0
        (icc_link->procs.map_color)(dev, icc_link, &(psrc[0]), &(psrc_cm[0]), 2);
1499
0
        gsicc_release_link(icc_link);
1500
0
        for (i = 0; i < ncomps; i++) {
1501
0
            cv[i] = psrc_cm[i];
1502
0
        }
1503
0
    }
1504
    /* if output device supports devn, we need to make sure we send it the
1505
       proper color type */
1506
2.69k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1507
13.8k
        for (i = 0; i < ncomps; i++)
1508
11.1k
            pdc->colors.devn.values[i] = cv[i];
1509
2.69k
        pdc->type = gx_dc_type_devn;
1510
1511
        /* Let device set the tags if present */
1512
2.69k
        if (device_encodes_tags(dev)) {
1513
0
          const gx_device *cmdev;
1514
0
          const gx_cm_color_map_procs *cmprocs;
1515
1516
0
            cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
1517
0
            cmprocs->map_cmyk(cmdev, 0, 0, 0, 0, cm_comps);
1518
0
            pdc->colors.devn.values[ncomps - 1] = frac2cv(cm_comps[ncomps - 1]);
1519
0
        }
1520
2.69k
        return;
1521
2.69k
    }
1522
1523
    /* encode as a color index */
1524
0
    color = dev_proc(dev, encode_color)(dev, cv);
1525
1526
    /* check if the encoding was successful; we presume failure is rare */
1527
0
    if (color != gx_no_color_index) {
1528
0
        color_set_pure(pdc, color);
1529
0
        return;
1530
0
    }
1531
1532
0
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1533
0
                                        &pgs->screen_phase[select]) == 1)
1534
0
        gx_color_load_select(pdc, pgs, dev, select);
1535
0
}
1536
1537
/* ------ DeviceN color mapping */
1538
1539
/*
1540
 * This routine is called to map a DeviceN colorspace to a DeviceN
1541
 * output device which requires halftoning.  T
1542
 */
1543
static void
1544
cmap_devicen_halftoned(const frac * pcc,
1545
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
1546
    gs_color_select_t select, const gs_color_space *pcs)
1547
404
{
1548
404
    uchar i, ncomps = dev->color_info.num_components;
1549
404
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1550
404
    gsicc_rendering_param_t render_cond;
1551
404
    cmm_dev_profile_t *dev_profile = NULL;
1552
404
    cmm_profile_t *des_profile = NULL;
1553
1554
404
    if (pcs->params.device_n.all_none == true) {
1555
0
        color_set_null(pdc);
1556
0
        return;
1557
0
    }
1558
1559
404
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1560
404
    gsicc_extract_profile(dev->graphics_type_tag,
1561
404
                          dev_profile, &des_profile, &render_cond);
1562
    /* map to the color model */
1563
404
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps,
1564
404
        pgs->color_component_map.num_colorants);
1565
    /* See comments in cmap_devicen_direct for details on below operations */
1566
404
    if (devicen_has_cmyk(dev, des_profile) &&
1567
404
        des_profile->data_cs == gsCMYK &&
1568
404
        !named_color_supported(pgs)) {
1569
404
        devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1570
404
    }
1571
    /* apply the transfer function(s); convert to color values */
1572
404
    if (pgs->effective_transfer_non_identity_count != 0) {
1573
404
        if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1574
0
            for (i = 0; i < ncomps; i++)
1575
0
                cm_comps[i] = gx_map_color_frac(pgs,
1576
404
                                cm_comps[i], effective_transfer[i]);
1577
404
        else
1578
2.42k
            for (i = 0; i < ncomps; i++)
1579
2.02k
                cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1580
404
                        (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1581
404
    }
1582
1583
    /* We need to finish halftoning */
1584
404
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1585
404
                                        &pgs->screen_phase[select]) == 1)
1586
366
        gx_color_load_select(pdc, pgs, dev, select);
1587
404
}
1588
1589
/*
1590
 * This routine is called to map a DeviceN colorspace to a DeviceN
1591
 * output device which does not require halftoning.
1592
 */
1593
static void
1594
cmap_devicen_direct(const frac * pcc,
1595
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
1596
    gs_color_select_t select, const gs_color_space *pcs)
1597
415
{
1598
415
    uchar i, ncomps = dev->color_info.num_components;
1599
415
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
1600
415
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
1601
415
    gx_color_index color;
1602
415
    gsicc_rendering_param_t render_cond;
1603
415
    cmm_dev_profile_t *dev_profile = NULL;
1604
415
    cmm_profile_t *des_profile = NULL;
1605
1606
415
    if (pcs->params.device_n.all_none == true) {
1607
0
        color_set_null(pdc);
1608
0
        return;
1609
0
    }
1610
1611
415
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1612
415
    gsicc_extract_profile(dev->graphics_type_tag,
1613
415
                          dev_profile, &des_profile, &render_cond);
1614
    /*   See the comment below */
1615
    /* map to the color model */
1616
415
    if (dev_profile->spotnames != NULL && dev_profile->spotnames->equiv_cmyk_set) {
1617
0
        map_components_to_colorants(pcc, dev_profile->spotnames->color_map,
1618
0
                                    cm_comps, ncomps);
1619
415
    } else {
1620
415
        map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps,
1621
415
            pgs->color_component_map.num_colorants);
1622
415
    }
1623
    /*  Check if we have the standard colorants.  If yes, then we will apply
1624
       ICC color management to those colorants. To understand why, consider
1625
       the example where I have a Device with CMYK + O  and I have a
1626
       DeviceN color in the document that is specified for any set of
1627
       these colorants, and suppose that I let them pass through
1628
       witout any color management.  This is probably  not the
1629
       desired effect since I could have a DeviceN color fill that had 10% C,
1630
       20% M 0% Y 0% K and 0% O.  I would like this to look the same
1631
       as a CMYK color that will be color managed and specified with 10% C,
1632
       20% M 0% Y 0% K. Hence the CMYK values should go through the same
1633
       color management as a stand alone CMYK value.  */
1634
415
    if (devicen_has_cmyk(dev, des_profile) && des_profile->data_cs == gsCMYK &&
1635
415
        !named_color_supported(pgs)) {
1636
        /* We need to do a CMYK to CMYK conversion here.  This will always
1637
           use the default CMYK profile and the device's output profile.
1638
           We probably need to add some checking here
1639
           and possibly permute the colorants, much as is done on the input
1640
           side for the case when we add DeviceN icc source profiles for use
1641
           in PDF and PS data. Also, don't do this if we are doing mapping
1642
           through the named color mapping.  */
1643
415
        devicen_sep_icc_cmyk(cm_comps, pgs, pcs, dev);
1644
415
    }
1645
    /* apply the transfer function(s); convert to color values.
1646
       assign directly if output device supports devn */
1647
415
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
1648
415
        if (pgs->effective_transfer_non_identity_count == 0)
1649
2.50k
            for (i = 0; i < ncomps; i++)
1650
2.09k
                pdc->colors.devn.values[i] = frac2cv(cm_comps[i]);
1651
0
        else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1652
0
            for (i = 0; i < ncomps; i++)
1653
0
                pdc->colors.devn.values[i] = frac2cv(gx_map_color_frac(pgs,
1654
0
                                    cm_comps[i], effective_transfer[i]));
1655
0
        else
1656
0
            for (i = 0; i < ncomps; i++)
1657
0
                pdc->colors.devn.values[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
1658
415
                            (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
1659
415
        pdc->type = gx_dc_type_devn;
1660
1661
        /* Let device set the tags if present */
1662
415
        if (device_encodes_tags(dev)) {
1663
0
          const gx_device *cmdev;
1664
0
          const gx_cm_color_map_procs *cmprocs;
1665
1666
0
            cmprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
1667
0
            cmprocs->map_cmyk(cmdev, 0, 0, 0, 0, cm_comps);
1668
0
            pdc->colors.devn.values[ncomps - 1] = frac2cv(cm_comps[ncomps - 1]);
1669
0
        }
1670
1671
415
        return;
1672
415
    }
1673
1674
0
    if (pgs->effective_transfer_non_identity_count == 0)
1675
0
        for (i = 0; i < ncomps; i++)
1676
0
            cv[i] = frac2cv(cm_comps[i]);
1677
0
    else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
1678
0
        for (i = 0; i < ncomps; i++) {
1679
0
            cm_comps[i] = gx_map_color_frac(pgs,
1680
0
                                    cm_comps[i], effective_transfer[i]);
1681
0
            cv[i] = frac2cv(cm_comps[i]);
1682
0
        }
1683
0
    else
1684
0
        for (i = 0; i < ncomps; i++) {
1685
0
            cm_comps[i] = frac_1 - gx_map_color_frac(pgs,
1686
0
                            (frac)(frac_1 - cm_comps[i]), effective_transfer[i]);
1687
0
            cv[i] = frac2cv(cm_comps[i]);
1688
0
        }
1689
    /* encode as a color index */
1690
0
    color = dev_proc(dev, encode_color)(dev, cv);
1691
    /* check if the encoding was successful; we presume failure is rare */
1692
0
    if (color != gx_no_color_index) {
1693
0
        color_set_pure(pdc, color);
1694
0
        return;
1695
0
    }
1696
0
    if (gx_render_device_DeviceN(cm_comps, pdc, dev, gx_select_dev_ht(pgs),
1697
0
                                        &pgs->screen_phase[select]) == 1)
1698
0
        gx_color_load_select(pdc, pgs, dev, select);
1699
0
}
1700
1701
/* ------ Halftoning check ----- */
1702
1703
static bool
1704
cmap_halftoned_is_halftoned(const gs_gstate * pgs, gx_device * dev)
1705
6.47k
{
1706
6.47k
    return true;
1707
6.47k
}
1708
1709
static bool
1710
cmap_direct_is_halftoned(const gs_gstate * pgs, gx_device * dev)
1711
304k
{
1712
304k
    return false;
1713
304k
}
1714
1715
/* ------ Transfer function mapping ------ */
1716
1717
/* Define an identity transfer function. */
1718
float
1719
gs_identity_transfer(double value, const gx_transfer_map * pmap)
1720
33.3M
{
1721
33.3M
    return (float) value;
1722
33.3M
}
1723
1724
/* Define the generic transfer function for the library layer. */
1725
/* This just returns what's already in the map. */
1726
float
1727
gs_mapped_transfer(double value, const gx_transfer_map * pmap)
1728
0
{
1729
0
    return gx_map_color_float(pmap, value);
1730
0
}
1731
1732
/* Set a transfer map to the identity map. */
1733
void
1734
gx_set_identity_transfer(gx_transfer_map *pmap)
1735
247k
{
1736
247k
    int i;
1737
1738
247k
    pmap->proc = gs_identity_transfer;
1739
    /* We still have to fill in the cached values. */
1740
63.6M
    for (i = 0; i < transfer_map_size; ++i)
1741
63.4M
        pmap->values[i] = bits2frac(i, log2_transfer_map_size);
1742
247k
}
1743
1744
#if FRAC_MAP_INTERPOLATE  /* NOTA BENE */
1745
1746
/* Map a color fraction through a transfer map. */
1747
/* We only use this if we are interpolating. */
1748
frac
1749
gx_color_frac_map(frac cv, const frac * values)
1750
451M
{
1751
451M
#define cp_frac_bits (frac_bits - log2_transfer_map_size)
1752
451M
    int cmi = frac2bits_floor(cv, log2_transfer_map_size);
1753
451M
    frac mv = values[cmi];
1754
451M
    int rem, mdv;
1755
1756
    /* Interpolate between two adjacent values if needed. */
1757
451M
    rem = cv - bits2frac(cmi, log2_transfer_map_size);
1758
451M
    if (rem == 0)
1759
332M
        return mv;
1760
119M
    mdv = values[cmi + 1] - mv;
1761
#if ARCH_INTS_ARE_SHORT
1762
    /* Only use long multiplication if necessary. */
1763
    if (mdv < -(1 << (16 - cp_frac_bits)) ||
1764
        mdv > 1 << (16 - cp_frac_bits)
1765
        )
1766
        return mv + (uint) (((ulong) rem * mdv) >> cp_frac_bits);
1767
#endif
1768
119M
    return mv + ((rem * mdv) >> cp_frac_bits);
1769
451M
#undef cp_frac_bits
1770
451M
}
1771
1772
#endif /* FRAC_MAP_INTERPOLATE */
1773
1774
/* ------ Default device color mapping ------ */
1775
/* White-on-black */
1776
gx_color_index
1777
gx_default_w_b_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1778
74
{       /* Map values >= 1/2 to 1, < 1/2 to 0. */
1779
74
    int i, ncomps = dev->color_info.num_components;
1780
74
    gx_color_value  cv_all = 0;
1781
1782
148
    for (i = 0; i < ncomps; i++)
1783
74
        cv_all |= cv[i];
1784
74
    return cv_all > gx_max_color_value / 2 ? (gx_color_index)1
1785
74
        : (gx_color_index)0;
1786
1787
74
}
1788
1789
int
1790
gx_default_w_b_map_color_rgb(gx_device * dev, gx_color_index color,
1791
                             gx_color_value prgb[3])
1792
422k
{       /* Map 1 to max_value, 0 to 0. */
1793
422k
    prgb[0] = prgb[1] = prgb[2] = -(gx_color_value) color;
1794
422k
    return 0;
1795
422k
}
1796
1797
gx_color_index
1798
gx_default_w_b_mono_encode_color(gx_device *dev, const gx_color_value cv[])
1799
0
{
1800
0
    return cv[0] > gx_max_color_value / 2 ? (gx_color_index)1
1801
0
                                          : (gx_color_index)0;
1802
0
}
1803
1804
int
1805
gx_default_w_b_mono_decode_color(gx_device * dev, gx_color_index color,
1806
                                 gx_color_value pgray[1])
1807
0
{       /* Map 0 to max_value, 1 to 0. */
1808
0
    pgray[0] = -(gx_color_value) color;
1809
0
    return 0;
1810
0
}
1811
1812
/* Black-on-white */
1813
gx_color_index
1814
gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1815
31.3M
{
1816
31.3M
    uchar i, ncomps = dev->color_info.num_components;
1817
31.3M
    gx_color_value  cv_all = 0;
1818
1819
62.6M
    for (i = 0; i < ncomps; i++)
1820
31.3M
        cv_all |= cv[i];
1821
31.3M
    return cv_all > gx_max_color_value / 2 ? (gx_color_index)0
1822
31.3M
        : (gx_color_index)1;
1823
31.3M
}
1824
1825
int
1826
gx_default_b_w_map_color_rgb(gx_device * dev, gx_color_index color,
1827
                             gx_color_value prgb[3])
1828
76.3k
{       /* Map 0 to max_value, 1 to 0. */
1829
76.3k
    prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1);
1830
76.3k
    return 0;
1831
76.3k
}
1832
1833
gx_color_index
1834
gx_default_b_w_mono_encode_color(gx_device *dev, const gx_color_value cv[])
1835
0
{
1836
0
    return cv[0] > gx_max_color_value / 2 ? (gx_color_index)0
1837
0
                                          : (gx_color_index)1;
1838
0
}
1839
1840
int
1841
gx_default_b_w_mono_decode_color(gx_device * dev, gx_color_index color,
1842
                                 gx_color_value pgray[1])
1843
0
{       /* Map 0 to max_value, 1 to 0. */
1844
0
    pgray[0] = -((gx_color_value) color ^ 1);
1845
0
    return 0;
1846
0
}
1847
1848
/* RGB mapping for gray-scale devices */
1849
1850
gx_color_index
1851
gx_default_gray_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1852
770k
{       /* We round the value rather than truncating it. */
1853
770k
    gx_color_value gray =
1854
770k
    (((cv[0] * (ulong) lum_red_weight) +
1855
770k
      (cv[1] * (ulong) lum_green_weight) +
1856
770k
      (cv[2] * (ulong) lum_blue_weight) +
1857
770k
      (lum_all_weights / 2)) / lum_all_weights
1858
770k
     * dev->color_info.max_gray +
1859
770k
     (gx_max_color_value / 2)) / gx_max_color_value;
1860
1861
770k
    return gray;
1862
770k
}
1863
1864
int
1865
gx_default_gray_map_color_rgb(gx_device * dev, gx_color_index color,
1866
                              gx_color_value prgb[3])
1867
5.11M
{
1868
5.11M
    gx_color_value gray = (gx_color_value)
1869
5.11M
        (color * gx_max_color_value / dev->color_info.max_gray);
1870
1871
5.11M
    prgb[0] = gray;
1872
5.11M
    prgb[1] = gray;
1873
5.11M
    prgb[2] = gray;
1874
5.11M
    return 0;
1875
5.11M
}
1876
1877
gx_color_index
1878
gx_default_gray_encode_color(gx_device * dev, const gx_color_value cv[])
1879
0
{
1880
0
    gx_color_value gray = (cv[0] * dev->color_info.max_gray +
1881
0
                           (gx_max_color_value / 2)) / gx_max_color_value;
1882
1883
0
    return gray;
1884
0
}
1885
1886
int
1887
gx_default_gray_decode_color(gx_device * dev, gx_color_index color,
1888
                             gx_color_value *cv)
1889
0
{
1890
0
    gx_color_value gray = (gx_color_value)
1891
0
        (color * gx_max_color_value / dev->color_info.max_gray);
1892
1893
0
    cv[0] = gray;
1894
0
    return 0;
1895
0
}
1896
1897
gx_color_index
1898
gx_default_8bit_map_gray_color(gx_device * dev, const gx_color_value cv[])
1899
1.64M
{
1900
1.64M
    gx_color_index color = gx_color_value_to_byte(cv[0]);
1901
1902
1.64M
    return color;
1903
1.64M
}
1904
1905
int
1906
gx_default_8bit_map_color_gray(gx_device * dev, gx_color_index color,
1907
                              gx_color_value pgray[1])
1908
0
{
1909
0
    pgray[0] = (gx_color_value)(color * gx_max_color_value / 255);
1910
0
    return 0;
1911
0
}
1912
1913
/* RGB mapping for 24-bit true (RGB) color devices */
1914
1915
gx_color_index
1916
gx_default_rgb_map_rgb_color(gx_device * dev, const gx_color_value cv[])
1917
32.4M
{
1918
32.4M
    if (dev->color_info.depth == 24)
1919
32.4M
        return gx_color_value_to_byte(cv[2]) +
1920
32.4M
            ((uint) gx_color_value_to_byte(cv[1]) << 8) +
1921
32.4M
            ((ulong) gx_color_value_to_byte(cv[0]) << 16);
1922
0
    else {
1923
0
        COLROUND_VARS;
1924
0
        int bpc = dev->color_info.depth / 3;
1925
0
        COLROUND_SETUP(bpc);
1926
1927
0
        return (((COLROUND_ROUND(cv[0]) << bpc) +
1928
0
                 COLROUND_ROUND(cv[1])) << bpc) +
1929
0
               COLROUND_ROUND(cv[2]);
1930
0
    }
1931
32.4M
}
1932
1933
/* Map a color index to a r-g-b color. */
1934
int
1935
gx_default_rgb_map_color_rgb(gx_device * dev, gx_color_index color,
1936
                             gx_color_value prgb[3])
1937
3.06M
{
1938
3.06M
    if (dev->color_info.depth == 24) {
1939
3.06M
        prgb[0] = gx_color_value_from_byte(color >> 16);
1940
3.06M
        prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
1941
3.06M
        prgb[2] = gx_color_value_from_byte(color & 0xff);
1942
3.06M
    } else {
1943
0
        uint bits_per_color = dev->color_info.depth / 3;
1944
0
        uint color_mask = (1 << bits_per_color) - 1;
1945
1946
0
        prgb[0] = ((color >> (bits_per_color * 2)) & color_mask) *
1947
0
            (ulong) gx_max_color_value / color_mask;
1948
0
        prgb[1] = ((color >> (bits_per_color)) & color_mask) *
1949
0
            (ulong) gx_max_color_value / color_mask;
1950
0
        prgb[2] = (color & color_mask) *
1951
0
            (ulong) gx_max_color_value / color_mask;
1952
0
    }
1953
3.06M
    return 0;
1954
3.06M
}
1955
1956
/* CMYK mapping for RGB devices (should never be called!) */
1957
1958
gx_color_index
1959
gx_default_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1960
0
{       /* Convert to RGB */
1961
0
    frac rgb[3];
1962
0
    gx_color_value rgb_cv[3];
1963
0
    color_cmyk_to_rgb(cv2frac(cv[0]), cv2frac(cv[1]), cv2frac(cv[2]), cv2frac(cv[3]),
1964
0
                      NULL, rgb, dev->memory);
1965
0
    rgb_cv[0] = frac2cv(rgb[0]);
1966
0
    rgb_cv[1] = frac2cv(rgb[1]);
1967
0
    rgb_cv[2] = frac2cv(rgb[2]);
1968
0
    return (*dev_proc(dev, map_rgb_color)) (dev, rgb_cv);
1969
0
}
1970
1971
/* Mapping for CMYK devices */
1972
1973
gx_color_index
1974
cmyk_1bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
1975
0
{
1976
0
#define CV_BIT(v) ((v) >> (gx_color_value_bits - 1))
1977
0
    return (gx_color_index)
1978
0
        (CV_BIT(cv[3]) + (CV_BIT(cv[2]) << 1) + (CV_BIT(cv[1]) << 2) + (CV_BIT(cv[0]) << 3));
1979
0
#undef CV_BIT
1980
0
}
1981
1982
/* Shouldn't be called: decode_color should be cmyk_1bit_map_color_cmyk */
1983
int
1984
cmyk_1bit_map_color_rgb(gx_device * dev, gx_color_index color,
1985
                        gx_color_value prgb[3])
1986
0
{
1987
0
    if (color & 1)
1988
0
        prgb[0] = prgb[1] = prgb[2] = 0;
1989
0
    else {
1990
0
        prgb[0] = (color & 8 ? 0 : gx_max_color_value);
1991
0
        prgb[1] = (color & 4 ? 0 : gx_max_color_value);
1992
0
        prgb[2] = (color & 2 ? 0 : gx_max_color_value);
1993
0
    }
1994
0
    return 0;
1995
0
}
1996
1997
int
1998
cmyk_1bit_map_color_cmyk(gx_device * dev, gx_color_index color,
1999
                        gx_color_value pcv[4])
2000
0
{
2001
0
    pcv[0] = (color & 8 ? 0 : gx_max_color_value);
2002
0
    pcv[1] = (color & 4 ? 0 : gx_max_color_value);
2003
0
    pcv[2] = (color & 2 ? 0 : gx_max_color_value);
2004
0
    pcv[3] = (color & 1 ? 0 : gx_max_color_value);
2005
0
    return 0;
2006
0
}
2007
2008
gx_color_index
2009
cmyk_8bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
2010
0
{
2011
0
    gx_color_index color =
2012
0
        gx_color_value_to_byte(cv[3]) +
2013
0
        ((uint)gx_color_value_to_byte(cv[2]) << 8) +
2014
0
        ((uint)gx_color_value_to_byte(cv[1]) << 16) +
2015
0
        ((uint)gx_color_value_to_byte(cv[0]) << 24);
2016
2017
0
#if ARCH_SIZEOF_GX_COLOR_INDEX > 4
2018
0
    return color;
2019
#else
2020
    return (color == gx_no_color_index ? color ^ 1 : color);
2021
#endif
2022
0
}
2023
2024
gx_color_index
2025
cmyk_16bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
2026
0
{
2027
0
    gx_color_index color =
2028
0
        (uint64_t)cv[3] +
2029
0
        ((uint64_t)cv[2] << 16) +
2030
0
        ((uint64_t)cv[1] << 32) +
2031
0
        ((uint64_t)cv[0] << 48);
2032
2033
0
    return (color == gx_no_color_index ? color ^ 1 : color);
2034
0
}
2035
2036
/* Shouldn't be called: decode_color should be cmyk_8bit_map_color_cmyk */
2037
int
2038
cmyk_8bit_map_color_rgb(gx_device * dev, gx_color_index color,
2039
                        gx_color_value prgb[3])
2040
0
{
2041
0
    int
2042
0
        not_k = (int) (~color & 0xff),
2043
0
        r = not_k - (int) (color >> 24),
2044
0
        g = not_k - (int) ((color >> 16) & 0xff),
2045
0
        b = not_k - (int) ((color >> 8) & 0xff);
2046
2047
0
    prgb[0] = (r < 0 ? 0 : gx_color_value_from_byte(r));
2048
0
    prgb[1] = (g < 0 ? 0 : gx_color_value_from_byte(g));
2049
0
    prgb[2] = (b < 0 ? 0 : gx_color_value_from_byte(b));
2050
0
    return 0;
2051
0
}
2052
2053
int
2054
cmyk_8bit_map_color_cmyk(gx_device * dev, gx_color_index color,
2055
                        gx_color_value pcv[4])
2056
0
{
2057
0
    pcv[0] = gx_color_value_from_byte((color >> 24) & 0xff);
2058
0
    pcv[1] = gx_color_value_from_byte((color >> 16) & 0xff);
2059
0
    pcv[2] = gx_color_value_from_byte((color >> 8) & 0xff);
2060
0
    pcv[3] = gx_color_value_from_byte(color & 0xff);
2061
0
    return 0;
2062
0
}
2063
2064
int
2065
cmyk_16bit_map_color_cmyk(gx_device * dev, gx_color_index color,
2066
                          gx_color_value pcv[4])
2067
0
{
2068
0
    pcv[0] = ((color >> 24) >> 24) & 0xffff;
2069
0
    pcv[1] = ((color >> 16) >> 16) & 0xffff;
2070
0
    pcv[2] = ( color        >> 16) & 0xffff;
2071
0
    pcv[3] = ( color             ) & 0xffff;
2072
0
    return 0;
2073
0
}
2074
2075
int
2076
cmyk_16bit_map_color_rgb(gx_device * dev, gx_color_index color,
2077
                         gx_color_value prgb[3])
2078
0
{
2079
0
    gx_color_value c     = ((color >> 24) >> 24) & 0xffff;
2080
0
    gx_color_value m     = ((color >> 16) >> 16) & 0xffff;
2081
0
    gx_color_value y     = ( color        >> 16) & 0xffff;
2082
0
    gx_color_value not_k = (~color             ) & 0xffff;
2083
0
    int r     = not_k - c;
2084
0
    int g     = not_k - m;
2085
0
    int b     = not_k - y;
2086
2087
0
    prgb[0] = (r < 0 ? 0 : r);
2088
0
    prgb[1] = (g < 0 ? 0 : g);
2089
0
    prgb[2] = (b < 0 ? 0 : b);
2090
0
    return 0;
2091
0
}
2092
2093
frac
2094
gx_unit_frac(float fvalue)
2095
519k
{
2096
519k
    frac f = frac_0;
2097
519k
    if (is_fneg(fvalue))
2098
0
        f = frac_0;
2099
519k
    else if (is_fge1(fvalue))
2100
94.0k
        f = frac_1;
2101
425k
    else
2102
425k
        f = float2frac(fvalue);
2103
519k
    return f;
2104
519k
}
2105
2106
static void
2107
cmapper_transfer_halftone_add(gx_cmapper_t *data)
2108
0
{
2109
0
    gx_color_value *pconc = &data->conc[0];
2110
0
    const gs_gstate * pgs = data->pgs;
2111
0
    gx_device * dev = data->dev;
2112
0
    gs_color_select_t select = data->select;
2113
0
    uchar ncomps = dev->color_info.num_components;
2114
0
    frac frac_value;
2115
0
    uchar i;
2116
0
    frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2117
2118
    /* apply the transfer function(s) */
2119
0
    for (i = 0; i < ncomps; i++) {
2120
0
        frac_value = cv2frac(pconc[i]);
2121
0
        cv_frac[i] = gx_map_color_frac(pgs, frac_value, effective_transfer[i]);
2122
0
    }
2123
    /* Halftoning */
2124
0
    if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2125
0
                    gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
2126
0
        gx_color_load_select(&data->devc, pgs, dev, select);
2127
0
}
2128
2129
static void
2130
cmapper_transfer_halftone_op(gx_cmapper_t *data)
2131
0
{
2132
0
    gx_color_value *pconc = &data->conc[0];
2133
0
    const gs_gstate * pgs = data->pgs;
2134
0
    gx_device * dev = data->dev;
2135
0
    gs_color_select_t select = data->select;
2136
0
    uchar ncomps = dev->color_info.num_components;
2137
0
    frac frac_value;
2138
0
    uchar i;
2139
0
    frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2140
2141
    /* apply the transfer function(s) */
2142
0
    uint k = dev->color_info.black_component;
2143
0
    for (i = 0; i < ncomps; i++) {
2144
0
        frac_value = cv2frac(pconc[i]);
2145
0
        if (i == k) {
2146
0
            cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2147
0
                (frac)(frac_1 - frac_value), effective_transfer[i]);
2148
0
        } else {
2149
0
            cv_frac[i] = frac_value;  /* Ignore transfer, see PLRM3 p. 494 */
2150
0
        }
2151
0
    }
2152
    /* Halftoning */
2153
0
    if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2154
0
                    gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
2155
0
        gx_color_load_select(&data->devc, pgs, dev, select);
2156
0
}
2157
2158
static void
2159
cmapper_transfer_halftone_sub(gx_cmapper_t *data)
2160
0
{
2161
0
    gx_color_value *pconc = &data->conc[0];
2162
0
    const gs_gstate * pgs = data->pgs;
2163
0
    gx_device * dev = data->dev;
2164
0
    gs_color_select_t select = data->select;
2165
0
    uchar ncomps = dev->color_info.num_components;
2166
0
    frac frac_value;
2167
0
    uchar i;
2168
0
    frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2169
2170
    /* apply the transfer function(s) */
2171
0
    for (i = 0; i < ncomps; i++) {
2172
0
        frac_value = cv2frac(pconc[i]);
2173
0
        cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2174
0
                    (frac)(frac_1 - frac_value), effective_transfer[i]);
2175
0
    }
2176
    /* Halftoning */
2177
0
    if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2178
0
                    gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
2179
0
        gx_color_load_select(&data->devc, pgs, dev, select);
2180
0
}
2181
2182
static void
2183
cmapper_transfer_add(gx_cmapper_t *data)
2184
6.19M
{
2185
6.19M
    gx_color_value *pconc = &data->conc[0];
2186
6.19M
    const gs_gstate * pgs = data->pgs;
2187
6.19M
    gx_device * dev = data->dev;
2188
6.19M
    uchar ncomps = dev->color_info.num_components;
2189
6.19M
    frac frac_value;
2190
6.19M
    uchar i;
2191
6.19M
    gx_color_index color;
2192
2193
    /* apply the transfer function(s) */
2194
24.3M
    for (i = 0; i < ncomps; i++) {
2195
18.1M
        frac_value = cv2frac(pconc[i]);
2196
18.1M
        frac_value = gx_map_color_frac(pgs,
2197
18.1M
                                frac_value, effective_transfer[i]);
2198
18.1M
        pconc[i] = frac2cv(frac_value);
2199
18.1M
    }
2200
    /* Halftoning */
2201
6.19M
    color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2202
    /* check if the encoding was successful; we presume failure is rare */
2203
6.19M
    if (color != gx_no_color_index)
2204
6.19M
        color_set_pure(&data->devc, color);
2205
6.19M
}
2206
2207
static void
2208
cmapper_transfer_op(gx_cmapper_t *data)
2209
0
{
2210
0
    gx_color_value *pconc = &data->conc[0];
2211
0
    const gs_gstate * pgs = data->pgs;
2212
0
    gx_device * dev = data->dev;
2213
0
    frac frac_value;
2214
0
    gx_color_index color;
2215
2216
0
    uint k = dev->color_info.black_component;
2217
    /* Ignore transfer for non blacks, see PLRM3 p. 494 */
2218
0
    frac_value = cv2frac(pconc[k]);
2219
0
    frac_value = frac_1 - gx_map_color_frac(pgs,
2220
0
                (frac)(frac_1 - frac_value), effective_transfer[k]);
2221
0
    pconc[k] = frac2cv(frac_value);
2222
    /* Halftoning */
2223
0
    color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2224
    /* check if the encoding was successful; we presume failure is rare */
2225
0
    if (color != gx_no_color_index)
2226
0
        color_set_pure(&data->devc, color);
2227
0
}
2228
2229
static void
2230
cmapper_transfer_sub(gx_cmapper_t *data)
2231
0
{
2232
0
    gx_color_value *pconc = &data->conc[0];
2233
0
    const gs_gstate * pgs = data->pgs;
2234
0
    gx_device * dev = data->dev;
2235
0
    uchar ncomps = dev->color_info.num_components;
2236
0
    frac frac_value;
2237
0
    uchar i;
2238
0
    gx_color_index color;
2239
2240
    /* apply the transfer function(s) */
2241
0
    for (i = 0; i < ncomps; i++) {
2242
0
        frac_value = cv2frac(pconc[i]);
2243
0
        frac_value = frac_1 - gx_map_color_frac(pgs,
2244
0
                    (frac)(frac_1 - frac_value), effective_transfer[i]);
2245
0
        pconc[i] = frac2cv(frac_value);
2246
0
    }
2247
    /* Halftoning */
2248
0
    color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2249
    /* check if the encoding was successful; we presume failure is rare */
2250
0
    if (color != gx_no_color_index)
2251
0
        color_set_pure(&data->devc, color);
2252
0
}
2253
2254
/* This is used by image color render to handle the cases where we need to
2255
   perform either a transfer function or halftoning on the color values
2256
   during an ICC color flow.  In this case, the color is already in the
2257
   device color space but in 16bpp color values. */
2258
static void
2259
cmapper_halftone(gx_cmapper_t *data)
2260
0
{
2261
0
    gx_color_value *pconc = &data->conc[0];
2262
0
    const gs_gstate * pgs = data->pgs;
2263
0
    gx_device * dev = data->dev;
2264
0
    gs_color_select_t select = data->select;
2265
0
    uchar ncomps = dev->color_info.num_components;
2266
0
    uchar i;
2267
0
    frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2268
2269
    /* We need this to be in frac form */
2270
0
    for (i = 0; i < ncomps; i++) {
2271
0
        cv_frac[i] = cv2frac(pconc[i]);
2272
0
    }
2273
0
    if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev,
2274
0
                gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
2275
0
        gx_color_load_select(&data->devc, pgs, dev, select);
2276
0
}
2277
2278
/* This is used by image color render to handle the cases where we need to
2279
   perform either a transfer function or halftoning on the color values
2280
   during an ICC color flow.  In this case, the color is already in the
2281
   device color space but in 16bpp color values. */
2282
static void
2283
cmapper_vanilla(gx_cmapper_t *data)
2284
52.0M
{
2285
52.0M
    gx_color_value *pconc = &data->conc[0];
2286
52.0M
    gx_device * dev = data->dev;
2287
52.0M
    gx_color_index color;
2288
2289
52.0M
    color = dev_proc(dev, encode_color)(dev, &(pconc[0]));
2290
    /* check if the encoding was successful; we presume failure is rare */
2291
52.0M
    if (color != gx_no_color_index)
2292
52.0M
        color_set_pure(&data->devc, color);
2293
52.0M
}
2294
2295
void
2296
gx_get_cmapper(gx_cmapper_t *data, const gs_gstate *pgs,
2297
               gx_device *dev, bool has_transfer, bool has_halftone,
2298
               gs_color_select_t select)
2299
1.77M
{
2300
1.77M
    memset(&(data->conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS]));
2301
1.77M
    data->pgs = pgs;
2302
1.77M
    data->dev = dev;
2303
1.77M
    data->select = select;
2304
1.77M
    data->devc.type = gx_dc_type_none;
2305
1.77M
    data->direct = 0;
2306
    /* Per spec. Images with soft mask, and the mask, do not use transfer function */
2307
1.77M
    if (pgs->effective_transfer_non_identity_count == 0 ||
2308
1.77M
        (dev_proc(dev, dev_spec_op)(dev, gxdso_in_smask, NULL, 0)) > 0)
2309
1.70M
        has_transfer = 0;
2310
1.77M
    if (has_transfer) {
2311
63.6k
        if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2312
63.6k
            if (has_halftone)
2313
0
                data->set_color = cmapper_transfer_halftone_add;
2314
63.6k
            else
2315
63.6k
                data->set_color = cmapper_transfer_add;
2316
63.6k
        } else if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) {
2317
0
            if (has_halftone)
2318
0
                data->set_color = cmapper_transfer_halftone_op;
2319
0
            else
2320
0
                data->set_color = cmapper_transfer_op;
2321
0
        } else {
2322
0
            if (has_halftone)
2323
0
                data->set_color = cmapper_transfer_halftone_sub;
2324
0
            else
2325
0
                data->set_color = cmapper_transfer_sub;
2326
0
        }
2327
1.70M
    } else {
2328
1.70M
        if (has_halftone)
2329
0
            data->set_color = cmapper_halftone;
2330
1.70M
        else {
2331
1.70M
            int code = dev_proc(dev, dev_spec_op)(dev, gxdso_is_encoding_direct, NULL, 0);
2332
1.70M
            data->set_color = cmapper_vanilla;
2333
1.70M
            data->direct = (code == 1);
2334
1.70M
        }
2335
1.70M
    }
2336
1.77M
}
2337
2338
/* This is used by image color render to handle the cases where we need to
2339
   perform either a transfer function or halftoning on the color values
2340
   during an ICC color flow.  In this case, the color is already in the
2341
   device color space but in 16bpp color values. */
2342
void
2343
cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc,
2344
     const gs_gstate * pgs, gx_device * dev, bool has_transfer,
2345
     bool has_halftone, gs_color_select_t select)
2346
0
{
2347
0
    uchar ncomps = dev->color_info.num_components;
2348
0
    frac frac_value;
2349
0
    uchar i;
2350
0
    frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS];
2351
0
    gx_color_index color;
2352
0
    gx_color_value color_val[GX_DEVICE_COLOR_MAX_COMPONENTS];
2353
2354
    /* apply the transfer function(s) */
2355
0
    if (has_transfer) {
2356
0
        if (pgs->effective_transfer_non_identity_count == 0) {
2357
0
            for (i = 0; i < ncomps; i++)
2358
0
                cv_frac[i] = cv2frac(pconc[i]);
2359
0
        } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2360
0
            for (i = 0; i < ncomps; i++) {
2361
0
                frac_value = cv2frac(pconc[i]);
2362
0
                cv_frac[i] = gx_map_color_frac(pgs,
2363
0
                                    frac_value, effective_transfer[i]);
2364
0
            }
2365
0
        } else {
2366
0
            if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) {  /* CMYK-like color space */
2367
0
                uint k = dev->color_info.black_component;
2368
0
                for (i = 0; i < ncomps; i++) {
2369
0
                    frac_value = cv2frac(pconc[i]);
2370
0
                    if (i == k) {
2371
0
                        cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2372
0
                            (frac)(frac_1 - frac_value), effective_transfer[i]);
2373
0
                    } else {
2374
0
                        cv_frac[i] = cv2frac(pconc[i]);  /* Ignore transfer, see PLRM3 p. 494 */
2375
0
                    }
2376
0
                }
2377
0
            } else {
2378
0
                for (i = 0; i < ncomps; i++) {
2379
0
                    frac_value = cv2frac(pconc[i]);
2380
0
                    cv_frac[i] = frac_1 - gx_map_color_frac(pgs,
2381
0
                                (frac)(frac_1 - frac_value), effective_transfer[i]);
2382
0
                }
2383
0
            }
2384
0
        }
2385
0
    } else {
2386
0
        if (has_halftone) {
2387
            /* We need this to be in frac form */
2388
0
            for (i = 0; i < ncomps; i++) {
2389
0
                cv_frac[i] = cv2frac(pconc[i]);
2390
0
            }
2391
0
        }
2392
0
    }
2393
    /* Halftoning */
2394
0
    if (has_halftone) {
2395
0
        if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev,
2396
0
                    gx_select_dev_ht(pgs), &pgs->screen_phase[select]) == 1)
2397
0
            gx_color_load_select(pdc, pgs, dev, select);
2398
0
    } else {
2399
        /* We have a frac value from the transfer function.  Do the encode.
2400
           which does not take a frac value...  */
2401
0
        for (i = 0; i < ncomps; i++) {
2402
0
            color_val[i] = frac2cv(cv_frac[i]);
2403
0
        }
2404
0
        color = dev_proc(dev, encode_color)(dev, &(color_val[0]));
2405
        /* check if the encoding was successful; we presume failure is rare */
2406
0
        if (color != gx_no_color_index)
2407
0
            color_set_pure(pdc, color);
2408
0
    }
2409
0
}
2410
2411
/* This is used by image color render to apply only the transfer function.
2412
   We follow this up with threshold rendering. */
2413
void
2414
cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev)
2415
0
{
2416
0
    uchar ncomps = dev->color_info.num_components;
2417
0
    uchar i;
2418
2419
    /* apply the transfer function(s) */
2420
0
    if (pgs->effective_transfer_non_identity_count == 0) {
2421
        /* No transfer function to apply */
2422
0
    } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
2423
0
        for (i = 0; i < ncomps; i++)
2424
0
            pconc[i] = frac2cv(gx_map_color_frac(pgs,
2425
0
                               cv2frac(pconc[i]), effective_transfer[i]));
2426
0
    else {
2427
0
        if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) {  /* CMYK-like color space */
2428
0
            i = dev->color_info.black_component;
2429
0
            if (i < ncomps)
2430
0
                pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
2431
0
                                   (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i]));
2432
0
        } else {
2433
0
            for (i = 0; i < ncomps; i++)
2434
0
                pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs,
2435
0
                        (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i]));
2436
0
        }
2437
0
    }
2438
0
}
2439
2440
/* A planar version which applies only one transfer function */
2441
void
2442
cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs,
2443
                    gx_device *dev, int plane)
2444
0
{
2445
0
    frac frac_value;
2446
0
    frac cv_frac;
2447
2448
    /* apply the transfer function(s) */
2449
0
    if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
2450
0
        frac_value = cv2frac(pconc[0]);
2451
0
        cv_frac = gx_map_color_frac(pgs, frac_value, effective_transfer[plane]);
2452
0
        pconc[0] = frac2cv(cv_frac);
2453
0
    } else {
2454
0
        if (gx_get_opmsupported(dev) == GX_CINFO_OPMSUPPORTED) {  /* CMYK-like color space */
2455
0
            uint k = dev->color_info.black_component;
2456
0
            if (plane == k) {
2457
0
                frac_value = cv2frac(pconc[0]);
2458
0
                cv_frac = frac_1 - gx_map_color_frac(pgs,
2459
0
                (frac)(frac_1 - frac_value), effective_transfer[plane]);
2460
0
                pconc[0] = frac2cv(cv_frac);
2461
0
            }
2462
0
        } else {
2463
0
            frac_value = cv2frac(pconc[0]);
2464
0
            cv_frac = frac_1 - gx_map_color_frac(pgs,
2465
0
                    (frac)(frac_1 - frac_value), effective_transfer[plane]);
2466
0
            pconc[0] = frac2cv(cv_frac);
2467
0
        }
2468
0
    }
2469
0
}
2470
2471
2472
bool
2473
gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs)
2474
236k
{
2475
236k
    const gx_cm_color_map_procs *pprocs;
2476
236k
    gsicc_rendering_param_t render_cond;
2477
236k
    cmm_dev_profile_t *dev_profile = NULL;
2478
236k
    cmm_profile_t *des_profile = NULL;
2479
2480
236k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
2481
236k
    gsicc_extract_profile(dev->graphics_type_tag,
2482
236k
                          dev_profile, &des_profile, &render_cond);
2483
2484
236k
    if (des_profile != NULL) {
2485
236k
        const gx_device *cmdev;
2486
2487
236k
        pprocs = dev_proc(dev, get_color_mapping_procs)(dev, &cmdev);
2488
        /* Check if they are forwarding procs */
2489
236k
        switch(des_profile->num_comps) {
2490
6.52k
            case 1:
2491
6.52k
                if (pprocs == &DeviceGray_procs) {
2492
6.51k
                    return true;
2493
6.51k
                }
2494
8
                break;
2495
220k
            case 3:
2496
220k
                if (pprocs == &DeviceRGB_procs) {
2497
137k
                    return true;
2498
137k
                }
2499
83.4k
                break;
2500
83.4k
            case 4:
2501
9.01k
                if (pprocs == &DeviceCMYK_procs) {
2502
0
                    return true;
2503
0
                }
2504
9.01k
                break;
2505
9.01k
            default:
2506
0
                break;
2507
236k
        }
2508
236k
    }
2509
92.4k
    return false;
2510
236k
}