Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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