Coverage Report

Created: 2025-11-16 07:40

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