Coverage Report

Created: 2022-04-16 11:23

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