Coverage Report

Created: 2026-08-08 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pcl/pcl/pcindxed.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* pcindexed.c - PCL indexed color space implementation */
18
#include "math_.h"
19
#include "string_.h"
20
#include "gx.h"
21
#include "pcmtx3.h"
22
#include "pccid.h"
23
#include "pccsbase.h"
24
#include "pcpalet.h"
25
26
/* default GL/2 pen width, in plotter units (1016 plotter units per inch) */
27
static const float dflt_pen_width = 14.0;
28
29
/* the image data configuration for the default color space */
30
static const pcl_cid_hdr_t dflt_cid_hdr = {
31
    pcl_cspace_RGB,             /* color space type */
32
    pcl_penc_indexed_by_plane,  /* pixel encoding type */
33
    1,                          /* bits per index */
34
    {1, 1, 1}                   /* bits per primary (3 components) */
35
};
36
37
gs_private_st_simple(st_cs_indexed_t, pcl_cs_indexed_t,
38
                     "pcl indexed color space");
39
40
/*
41
 * Find the smallest non-negative integral exponent of 2 larger than
42
 * or equal to the given number; 8 => 2^3 12 => 2^4
43
 * Note: in/out should be unsigned.
44
 */
45
static int
46
get_pow_2(int num)
47
20.9k
{
48
20.9k
    int i;
49
20.9k
    unsigned power_2 = 1;
50
51
51.5k
    for (i = 0; (unsigned)num > power_2; ++i)
52
30.5k
        power_2 <<= 1;
53
20.9k
    return i;
54
20.9k
}
55
56
/*
57
 * Free a PCL indexed color space structure.
58
 */
59
static void
60
free_indexed_cspace(gs_memory_t * pmem, void *pvindexed, client_name_t cname)
61
24.8k
{
62
24.8k
    pcl_cs_indexed_t *pindexed = (pcl_cs_indexed_t *) pvindexed;
63
64
24.8k
    pcl_cs_base_release(pindexed->pbase);
65
24.8k
    rc_decrement(pindexed->pcspace, "free_indexed_cspace");
66
24.8k
    gs_free_object(pmem, pvindexed, cname);
67
24.8k
}
68
69
/*
70
 * Allocate a PCL indexed color space.
71
 *
72
 * Because a PCL indexed color space and the associated graphic library
73
 * indexed color space must be kept in a one-to-one relationship, the latter
74
 * color space is allocated here as well. This requires that the base color
75
 * space be an operand.
76
 *
77
 * Returns 0 on success, < 0 in the event of an error.
78
 */
79
static int
80
alloc_indexed_cspace(pcl_cs_indexed_t ** ppindexed,
81
                     pcl_cs_base_t * pbase,
82
                     uint num_entries, gs_memory_t * pmem)
83
24.9k
{
84
24.9k
    pcl_cs_indexed_t *pindexed = 0;
85
24.9k
    int code = 0;
86
24.9k
    byte *bp = 0;
87
24.9k
    uint palette_size = 3 * num_entries;
88
24.9k
    int i;
89
90
24.9k
    if_debug1m('c', pmem, "[c]alloc_indexed_cspace entries:%d\n",
91
24.9k
               num_entries);
92
93
24.9k
    rc_alloc_struct_1(pindexed,
94
24.9k
                      pcl_cs_indexed_t,
95
24.9k
                      &st_cs_indexed_t,
96
24.9k
                      pmem,
97
24.9k
                      return e_Memory, "allocate pcl indexed color space");
98
99
24.9k
    pindexed->rc.free = free_indexed_cspace;
100
24.9k
    pindexed->pfixed = false;
101
24.9k
    pindexed->is_GL = false;
102
24.9k
    pcl_cs_base_init_from(pindexed->pbase, pbase);
103
24.9k
    pindexed->pcspace = 0;
104
24.9k
    pindexed->num_entries = 0;
105
24.9k
    pindexed->palette.data = 0;
106
24.9k
    pindexed->palette.size = 0;
107
108
24.9k
    bp = gs_alloc_string(pmem,
109
24.9k
                         palette_size, "allocate pcl indexed color space");
110
24.9k
    if (bp == 0) {
111
0
        free_indexed_cspace(pmem, pindexed,
112
0
                            "allocate pcl indexed color space");
113
0
        return e_Memory;
114
0
    }
115
24.9k
    pindexed->palette.data = bp;
116
24.9k
    pindexed->palette.size = palette_size;
117
104k
    for (i = 0; i < num_entries; i++)
118
79.2k
        pindexed->pen_widths[i] = dflt_pen_width;
119
120
24.9k
    code = gs_cspace_build_Indexed(&(pindexed->pcspace),
121
24.9k
                                   pbase->pcspace,
122
24.9k
                                   num_entries,
123
24.9k
                                   (gs_const_string *) & (pindexed->palette),
124
24.9k
                                   pmem);
125
24.9k
    if (code < 0) {
126
0
        free_indexed_cspace(pmem, pindexed,
127
0
                            "allocate pcl indexed color space");
128
0
        gs_free_object(pmem, bp, "allocate pcl indexed color space");
129
0
        return code;
130
0
    }
131
132
24.9k
    *ppindexed = pindexed;
133
24.9k
    return 0;
134
24.9k
}
135
136
/* Resize the palette of an indexed color space */
137
static int
138
resize_indexed_cspace(pcl_cs_indexed_t * pindexed, uint num_entries)
139
20.9k
{
140
20.9k
    byte *pdata;
141
20.9k
    gs_memory_t *pmem = pindexed->rc.memory;
142
20.9k
    uint new_size = num_entries * 3;
143
20.9k
    int i;
144
20.9k
    uint num_old_entries;
145
146
20.9k
    if_debug2m('c', pmem, "[c]resizing_indexed_cspace new:%d old:%d\n",
147
20.9k
               num_entries, pindexed->num_entries);
148
149
20.9k
    pdata =
150
20.9k
        gs_resize_string(pmem, pindexed->palette.data, pindexed->palette.size,
151
20.9k
                         new_size, "resize pcl indexed color space");
152
20.9k
    if (pdata == NULL)
153
0
        return gs_error_VMerror;
154
20.9k
    num_old_entries = pindexed->num_entries;
155
20.9k
    pindexed->num_entries = num_entries;
156
20.9k
    pindexed->palette.data = pdata;
157
    /* NB duplicate data storage */
158
20.9k
    pindexed->palette.size =
159
20.9k
        pindexed->pcspace->params.indexed.lookup.table.size = new_size;
160
20.9k
    pindexed->pcspace->params.indexed.lookup.table.data = (const byte *)pdata;
161
20.9k
    pindexed->palette.data = pdata;
162
20.9k
    pindexed->pcspace->params.indexed.hival = num_entries - 1;
163
    /* if the palette has grown we have to fill in the default line
164
       width values */
165
91.7k
    for (i = num_old_entries; i < num_entries; i++)
166
70.8k
        pindexed->pen_widths[i] = dflt_pen_width;
167
20.9k
    return 0;
168
20.9k
}
169
170
/*
171
 * Make a PCL indexed color space unique.
172
 *
173
 * Note that neither the palette nor the graphic state indexed color space can
174
 * be shared between two PCL indexed color spaces. The two would need to be
175
 * shared in tandem, which would require common reference counting between the
176
 * pair, which would require yet another PCL object, and so on.
177
 *
178
 * Returns 0 on success, < 0 in the event of an error.
179
 */
180
static int
181
unshare_indexed_cspace(pcl_cs_indexed_t ** ppindexed)
182
54.0k
{
183
54.0k
    pcl_cs_indexed_t *pindexed = *ppindexed;
184
54.0k
    pcl_cs_indexed_t *pnew = 0;
185
54.0k
    int code = 0;
186
54.0k
    int num_entries = pindexed->num_entries;
187
188
    /* check if there is anything to do */
189
54.0k
    if (pindexed->rc.ref_count == 1)
190
53.2k
        return 0;
191
792
    rc_decrement(pindexed, "unshare PCL indexed color space");
192
193
    /* allocate a new indexed color space */
194
792
    code = alloc_indexed_cspace(ppindexed,
195
792
                                pindexed->pbase,
196
792
                                pindexed->num_entries, pindexed->rc.memory);
197
792
    if (code < 0)
198
0
        return code;
199
792
    pnew = *ppindexed;
200
201
    /* copy fields various and sundry */
202
792
    pnew->pfixed = pindexed->pfixed;
203
792
    pnew->cid = pindexed->cid;
204
792
    pnew->original_cspace = pindexed->original_cspace;
205
792
    pnew->num_entries = pindexed->num_entries;
206
792
    pnew->palette.size = pindexed->palette.size;
207
792
    memcpy(pnew->palette.data, pindexed->palette.data,
208
792
           pindexed->palette.size);
209
792
    memcpy(pnew->pen_widths, pindexed->pen_widths,
210
792
           num_entries * sizeof(float));
211
212
    /* Coverity thinks next memcpy() might need to be memmove(), so we
213
    explicitly check for the buffers being equal. */
214
792
    if (pnew->norm != pindexed->norm) {
215
792
        memcpy(pnew->norm, pindexed->norm, 3 * sizeof(pindexed->norm[0]));
216
792
    }
217
218
    /* Coverity thinks next memcpy() might need to be memmove(), so we
219
    explicitly check for the buffers being equal. */
220
792
    if (pnew->Decode != pindexed->Decode) {
221
792
        memcpy(pnew->Decode, pindexed->Decode, 6 * sizeof(float));
222
792
    }
223
224
792
    return 0;
225
792
}
226
227
/*
228
 * Fill in the default entries in a color palette. This is handled separately
229
 * for each color space type.
230
 *
231
 * The manner in which the default color palette is specified by HP is,
232
 * unfortunately, completely dependent on their particular implementation.
233
 * HP maintains palettes in device space, and initializes palettes with
234
 * device space colors. Hence, these palettes are affected by gamma correction
235
 * and the lookup tables for the device color space, but not by any lookup
236
 * tables for device independent color spaces (even if the base color space is
237
 * device independent), nor by range specifications in the color space
238
 * parameters.
239
 *
240
 * Because this implementation of PCL 5c works strictly in source color space,
241
 * it is not possible to achieve the same result. Instead, this implementation
242
 * will give accurate default color space values only for the RGB and CMY
243
 * color space values, and will give approximate results for the other color
244
 * spaces. The default colors will be modified by all applicable color lookup
245
 * tables, though some compensation is provided for component ranges.
246
 *
247
 * For applications, this should not matter: presumably an application does
248
 * not select a device independent color space in order to achieve a device-
249
 * specific color. For tests such as the PCL 5c FTS, it is more likely that
250
 * a discrepancy will be visible, because these tests illustrate the default
251
 * palette for each color space.
252
 */
253
254
/*
255
 * Convert a device-independent color intensity value to the range [0, 255].
256
 */
257
static int
258
convert_comp_val(double val, double min_val, double range)
259
0
{
260
0
    val = 255.0 * (val - min_val) / range;
261
0
    return (val < 0.0 ? 0 : (val > 255.0 ? 255 : (int)floor(val + 0.5)));
262
0
}
263
264
/*
265
 * Set the default palette for device specific color spaces.
266
 */
267
static void
268
set_dev_specific_default_palette(pcl_cs_base_t * pbase, /* ignored in this case */
269
                                 byte * palette,
270
                                 const byte * porder, int start, int num)
271
20.9k
{
272
20.9k
    int i;
273
20.9k
    static const byte cmy_default[(8 * 3) + 1] = {
274
20.9k
        255, 255, 255,          /* white */
275
20.9k
        0, 255, 255,            /* cyan */
276
20.9k
        255, 0, 255,            /* magenta */
277
20.9k
        0, 0, 255,              /* blue */
278
20.9k
        255, 255, 0,            /* yellow */
279
20.9k
        0, 255, 0,              /* green */
280
20.9k
        255, 0, 0,              /* red */
281
20.9k
        0, 0, 0,                /* black */
282
20.9k
        0                       /* Sacrificial, for porder[i] = 7 and 'num' > 8 */
283
20.9k
    };
284
285
    /* fill in the num_entries - 1 values from the RGB default */
286
91.7k
    for (i = start; i < num + start; i++) {
287
70.8k
        palette[3 * i] = cmy_default[3 * porder[i]];
288
70.8k
        palette[3 * i + 1] = cmy_default[3 * porder[i] + 1];
289
70.8k
        palette[3 * i + 2] = cmy_default[3 * porder[i] + 2];
290
70.8k
        if (num > 8)
291
0
            palette[3 * i + 3] = cmy_default[3 * porder[i] + 3];
292
70.8k
    }
293
20.9k
}
294
295
/*
296
 * Set the default palette for a colorimetric RGB space.
297
 *
298
 * The assumption used in this case is that if the user specified primaries,
299
 * presumably they want those primaries. Further, it is assumed that the red
300
 * primary is associated with red, the green with green, and so on. Should
301
 * the user specify a "blue" color as the red primary, then the default
302
 * palette will have blue where red is normally expected.
303
 *
304
 * An adjustment is made for the specified ranges.
305
 */
306
static void
307
set_colmet_default_palette(pcl_cs_base_t * pbase,
308
                           byte * palette,
309
                           const byte * porder, int start, int num)
310
0
{
311
0
    float *pmin = pbase->client_data.min_val;
312
0
    float *prange = pbase->client_data.range;
313
0
    int i;
314
315
0
    static const float colmet_default[8 * 3] = {
316
0
        1.0, 1.0, 1.0,          /* white */
317
0
        0.0, 1.0, 1.0,          /* cyan */
318
0
        1.0, 0.0, 1.0,          /* magenta */
319
0
        0.0, 0.0, 1.0,          /* blue */
320
0
        1.0, 1.0, 0.0,          /* yellow */
321
0
        0.0, 1.0, 0.0,          /* green */
322
0
        1.0, 0.0, 0.0,          /* red */
323
0
        0.0, 0.0, 0.0           /* black */
324
0
    };
325
326
    /* fill in the num_entries - 1 values from the colorimetric default */
327
0
    for (i = start; i < start + num; i++) {
328
0
        int j;
329
0
        byte *pb = palette + 3 * i;
330
0
        const float *pdef = colmet_default + 3 * porder[i];
331
332
0
        for (j = 0; j < 3; j++)
333
0
            pb[j] = convert_comp_val(pdef[j], pmin[j], prange[j]);
334
0
    }
335
0
}
336
337
/*
338
 * Set the default palette for a CIE L*a*b* color space.
339
 *
340
 * The values provided will, for a sufficiently capable device, generate the
341
 * SMPTE-C primaries (assuming that ranges and/or color lookup tables don't
342
 * get in the way). Most printing devices cannot generate these colors, so
343
 * a somewhat different output is produced, but this is as close as we can
344
 * come to a "device independent" set of default entries.
345
 *
346
 * The code provides some compensation for range: if the desired value is
347
 * within the permitted range, the palette entry intensity (always in the range
348
 * [0, 1]) will be adjusted so as to achieve it; otherwise the intensity will
349
 * be set to the appropriate bound. Obviously, none of this works if a
350
 * color lookup table is subsequently installed, but it is as much as can be
351
 * achieved under the current arrangement.
352
 */
353
static void
354
set_CIELab_default_palette(pcl_cs_base_t * pbase,
355
                           byte * palette,
356
                           const byte * porder, int start, int num)
357
0
{
358
0
    float *pmin = pbase->client_data.min_val;
359
0
    float *prange = pbase->client_data.range;
360
0
    int i;
361
362
0
    static const float lab_default[8 * 3] = {
363
0
        100.0f, 0.0f, 0.0f,     /* white */
364
0
        91.1f, -43.4f, -14.1f,  /* cyan */
365
0
        61.6f, 91.0f, -59.2f,   /* magenta */
366
0
        35.3f, 72.0f, -100.0f,  /* blue */
367
0
        96.6f, -21.3f, 95.4f,   /* yellow */
368
0
        87.0f, -80.7f, 84.0f,   /* green */
369
0
        53.2f, 74.4f, 67.7f,    /* red */
370
0
        0.0f, 0.0f, 0.0f        /* black */
371
0
    };
372
373
0
    for (i = start; i < start + num; i++) {
374
0
        int j;
375
0
        byte *pb = palette + 3 * i;
376
0
        const float *pdef = lab_default + 3 * porder[i];
377
378
0
        for (j = 0; j < 3; j++)
379
0
            pb[j] = convert_comp_val(pdef[j], pmin[j], prange[j]);
380
0
    }
381
0
}
382
383
/*
384
 * Set the default palette for a luminance-chrominance color space.
385
 *
386
 * The arrangement used for this color space is based on the one used for
387
 * the colorimetric color space. The user specifies a set of primaries
388
 * for the color space underlying the luminance-chrominance color space,
389
 * and we provide those primaries in the default palette. Since the
390
 * palette entries themselves are in the luminance-chrominance color space,
391
 * the default values must be converted to that color space.
392
 *
393
 * An adjustment is made for the specified ranges.
394
 */
395
static void
396
set_lumchrom_default_palette(pcl_cs_base_t * pbase,
397
                             byte * palette,
398
                             const byte * porder, int start, int num)
399
0
{
400
0
    gs_matrix3 *pxfm = gs_cie_abc_MatrixABC(pbase->pcspace);
401
0
    float *pmin = pbase->client_data.min_val;
402
0
    float *prange = pbase->client_data.range;
403
0
    pcl_mtx3_t tmp_mtx;
404
0
    int i;
405
406
0
    static const pcl_vec3_t lumchrom_default[8] = {
407
0
        {{1.0, 1.0, 1.0}},      /* white */
408
0
        {{0.0, 1.0, 1.0}},      /* cyan */
409
0
        {{1.0, 0.0, 1.0}},      /* magenta */
410
0
        {{0.0, 0.0, 1.0}},      /* blue */
411
0
        {{1.0, 1.0, 0.0}},      /* yellow */
412
0
        {{0.0, 1.0, 0.0}},      /* green */
413
0
        {{1.0, 0.0, 0.0}},      /* red */
414
0
        {{0.0, 0.0, 0.0}}       /* black */
415
0
    };
416
417
    /* form the primaries to component values matrix */
418
0
    pcl_mtx3_convert_from_gs(&tmp_mtx, pxfm);
419
0
    pcl_mtx3_invert(&tmp_mtx, &tmp_mtx);
420
421
0
    for (i = start; i < start + num; i++) {
422
0
        pcl_vec3_t compvec;
423
0
        byte *pb = palette + 3 * i;
424
0
        int j;
425
426
0
        pcl_vec3_xform(&(lumchrom_default[porder[i]]), &compvec, &tmp_mtx);
427
0
        for (j = 0; j < 3; j++)
428
0
            pb[j] = convert_comp_val(compvec.va[j], pmin[j], prange[j]);
429
0
    }
430
0
}
431
432
/*
433
 * Set the default values for a specific range of an indexed PCL color space.
434
 * The starting point is indicated by start; the number of subsequent entires
435
 * to be set by num (for PCL, start is always 0 and num is always the number of
436
 * entires in the palette, but that may not be the case for GL/2).
437
 *
438
 * If gl2 is true, this call is being made from GL/2, hence the GL/2 default
439
 * palettes should be used.
440
 *
441
 * Returns 0 if successful, < 0 in case of an error.
442
 */
443
static int
444
set_default_entries(pcl_cs_indexed_t * pindexed, int start, int num, bool gl2)
445
20.9k
{
446
    /* array of procedures to set the default palette entries */
447
20.9k
    static void (*const
448
20.9k
                 set_default_palette[(int)pcl_cspace_num]) (pcl_cs_base_t *
449
20.9k
                                                            pbase,
450
20.9k
                                                            byte * palette,
451
20.9k
                                                            const byte *
452
20.9k
                                                            porder, int start,
453
20.9k
                                                            int num) = {
454
20.9k
        set_dev_specific_default_palette,       /* RGB */
455
20.9k
            set_dev_specific_default_palette,   /* CMY */
456
20.9k
            set_colmet_default_palette, /* colorimetric RGB */
457
20.9k
            set_CIELab_default_palette, /* CIE L*a*b* */
458
20.9k
            set_lumchrom_default_palette,        /* luminance-
459
                                                 * chrominance */
460
20.9k
            set_dev_specific_default_palette   /* KCMY */
461
20.9k
    };
462
463
    /*
464
     * For each color space, 8 or 16 palette entries are stored in the canonical
465
     * CMY order; any palette entries beyond the first 8 or 16 always default to
466
     * black. These arrays are incorporated into procedures that handle the
467
     * generation of colors for each color space type. For the bits per index
468
     * settings of 1, 2, 3, or >= 4, an order array is provided, to indicate the
469
     * order in which the default palette entries should be entered into the
470
     * palette. Separate arrays are provided for the RGB and CMY color spaces,
471
     * and for GL/2 default colors.
472
     */
473
20.9k
    static const byte order_1[] = { 0, 7 };
474
20.9k
    static const byte cmy_order_2[] = { 0, 1, 2, 7 };
475
20.9k
    static const byte cmy_order_3[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
476
20.9k
    static const byte cmy_order_4[] = { 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7 };
477
20.9k
    static const byte rgb_order_2[] = { 7, 6, 5, 0 };
478
20.9k
    static const byte rgb_order_3[] = { 7, 6, 5, 4, 3, 2, 1, 0 };
479
20.9k
    static const byte gl2_order_2[] = { 0, 7, 6, 5 };
480
20.9k
    static const byte gl2_order_3[] = { 0, 7, 6, 5, 4, 3, 2, 1 };
481
20.9k
    static const byte *cmy_order[4] = { order_1, cmy_order_2, cmy_order_3, cmy_order_4 };
482
20.9k
    static const byte *rgb_order[3] = { order_1, rgb_order_2, rgb_order_3 };
483
20.9k
    static const byte *gl2_order[3] = { order_1, gl2_order_2, gl2_order_3 };
484
20.9k
    int type = pindexed->cid.cspace;
485
20.9k
    int orig_type = pindexed->original_cspace;
486
20.9k
    int bits = pindexed->cid.bits_per_index - 1;
487
20.9k
    const byte *porder;
488
20.9k
    int cnt = (num + start > 8 ? 8 - start : num);
489
20.9k
    int i;
490
491
20.9k
    if (bits > 2)
492
0
        bits = 2;
493
20.9k
    if (gl2)
494
4.82k
        porder = gl2_order[bits];
495
    /* check for a rgb or colorimetric.  If the colorimetric is being
496
       substituted for device CMY use the cmy order */
497
16.1k
    else if (((type == pcl_cspace_RGB) || (type == pcl_cspace_Colorimetric))
498
16.1k
             && (orig_type != pcl_cspace_CMY))
499
16.1k
        porder = rgb_order[bits];
500
0
    else
501
0
        porder = cmy_order[bits];
502
503
    /* If 4-plane simple color KCMY graphics, set cnt for larger palette. */
504
20.9k
    if (type == pcl_cspace_KCMY) {
505
        /* This seems to be plain wrong, the size of the palette data is set from the number of bits, without
506
         * regard to the colour space. I can't see any reason to set the number of entries to 15, and it
507
         * overruns the palette if we do. So I'm commenting it out.
508
         cnt = 15;
509
         */
510
0
        porder = cmy_order_4;
511
0
    }
512
    /* set the default colors for up to the first 16 entries */
513
20.9k
    set_default_palette[(int)type] (pindexed->pbase,
514
20.9k
                                    pindexed->palette.data,
515
20.9k
                                    porder, start, cnt);
516
517
    /* set the remaining entries to black */
518
20.9k
    {
519
20.9k
        int s = start + cnt;
520
20.9k
        int e = start + num;
521
522
20.9k
        for (i = s; i < e; i++) {
523
0
            byte *bp = pindexed->palette.data + i * 3;
524
525
0
            bp[0] = bp[1] = bp[2] = 0;
526
0
        }
527
20.9k
    }
528
20.9k
    return 0;
529
20.9k
}
530
531
/*
532
 * Generate the normalization and, if appropriate, Decode arrays that correspond
533
 * to a pcl_cid_data structure.
534
 *
535
 * Normalization in PCL and GL/2 involves a modification of a component color
536
 * setting prior to its being stored in the palette. This is set in PCL via
537
 * the black and white reference points for device specific color spaces, and
538
 * in GL/2 via the CR command. The latter provides the much more general
539
 * interface, which in turn drives the implementation.
540
 *
541
 * In PCL, white and black reference points may be set only for the device-
542
 * dependent color spaces, and may only be set once when a palette is created
543
 * (via the configure image data command; the min/max ranges for the device
544
 * independent color spaces have a different interpretation). The CR command,
545
 * on the other hand, applies to all color spaces, and can used to modfiy the
546
 * range without otherwise changing the current color palette.
547
 *
548
 * All color spaces in this implementation are set up so that, in the palette,
549
 * 0 represents the minimum intensity, and 1 the maximum intensity. For a
550
 * component that has black and white reference points of blk and wht,
551
 * respectively, the normalization applied is:
552
 *
553
 *     tmp_val = ((i_val - blk) / (wht - blk)
554
 *
555
 *     o_val = (tmp_val < 0 ? 0 : (tmp_val > 1 ? 1 : tmp_val))
556
 *
557
 * Because palette entries are stored as integers in the range [0, 255], the
558
 * actual form in which the normalization data are stored (and the modified
559
 * normalization calculation) are:
560
 *
561
 *     blkref = blk
562
 *
563
 *     inv_range = 255.0 / (wht - blk)
564
 *
565
 *     tmp_val = (i_val - blkref) * inv_range + 0.5;
566
 *
567
 *     o_val = (tmp_val < 0 ? 0 : (tmp_val > 255 ? 255 : floor(tmp_val + 0.5)))
568
 *
569
 * For a primary that uses an n-bit representation, the default values for
570
 * blk and wht are 0 and 2^n - 1, respectively. (For HP's implementation this
571
 * only applies to device-dependent color spaces; wht for device-independent
572
 * color spaces is always 255. There seems to be no reason for such a
573
 * restriction, hence it is not used here. This is unlikely to cause difficulty
574
 * in practice, as it is unlikely a device-independent color space will ever
575
 * be used with anything other than 8-bits per primary.)
576
 *
577
 * Note that for the CMY color space, the white and black points are reversed.
578
 * This is the only distinction between the RGB and CMY color spaces.
579
 *
580
 * The Decode array is used for images, and thus has different forms
581
 * depending on the pixel encoding mode. For the "direct by" cases
582
 * it incorporates normalization information; for the "indexed by"
583
 * cases its contents are dictated by the size of the palette.
584
 */
585
int
586
pcl_cs_indexed_set_norm_and_Decode(pcl_cs_indexed_t ** ppindexed,
587
                                   double wht0,
588
                                   double wht1,
589
                                   double wht2,
590
                                   double blk0, double blk1, double blk2)
591
24.1k
{
592
24.1k
    pcl_cs_indexed_t *pindexed = *ppindexed;
593
24.1k
    pcl_encoding_type_t enc = (pcl_encoding_type_t) pindexed->cid.encoding;
594
24.1k
    pcl_cs_indexed_norm_t *pnorm;
595
24.1k
    int code = 0;
596
597
    /* ignore request if palette is fixed */
598
24.1k
    if (pindexed->pfixed)
599
0
        return 0;
600
601
    /* get a unique copy of the color space */
602
24.1k
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
603
0
        return code;
604
24.1k
    pindexed = *ppindexed;
605
24.1k
    pnorm = pindexed->norm;
606
607
    /* set up for the additive space */
608
24.1k
    pnorm[0].blkref = blk0;
609
24.1k
    pnorm[0].inv_range = (wht0 == blk0 ? 0.0 : 255.0 / (wht0 - blk0));
610
24.1k
    pnorm[1].blkref = blk1;
611
24.1k
    pnorm[1].inv_range = (wht1 == blk1 ? 0.0 : 255.0 / (wht1 - blk1));
612
24.1k
    pnorm[2].blkref = blk2;
613
24.1k
    pnorm[2].inv_range = (wht2 == blk2 ? 0.0 : 255.0 / (wht2 - blk2));
614
615
    /*
616
     * Build the Decode array to be used with images.
617
     *
618
     * If an "indexed by" pixel encoding scheme is being used, the color
619
     * space for images is the same color space used for the foreground, and
620
     * the Decode array is the canonical array for Indexed color spaces.
621
     *
622
     * If a "direct by" pixel encoding is being used, the Decode array must
623
     * yield the same color component values as would be produced by use of
624
     * the "color component" commands. Thus, for any color component intensity
625
     * a, we must have
626
     *
627
     *    (a - blkref) / range = Dmin + a * (Dmax - Dmin) / (2^n - 1)
628
     *
629
     * where blkref and range are the black reference point and range value for
630
     * this component (computed above), Dmin and Dmax are the first and second
631
     * elements of the Decode array for this component, and n is the number of
632
     * bits per pixel. Setting a = 0, this yields:
633
     *
634
     *    -blkref / range = Dmin
635
     *
636
     * Substituting this into the original equation yields:
637
     *
638
     *    (a - blkref) / range = a * (Dmax + blkref/range) / (2^n - 1)
639
     *                                - blkref / range;
640
     *
641
     * Adding blkref / range to both sides,  and multiplying both sides by
642
     * range * (2^n - 1) / a yields:
643
     *
644
     *     2^n - 1 = range * Dmax + blkref
645
     *
646
     * or
647
     *
648
     *     (2^n - 1 - blkref) / range = Dmax
649
     *
650
     * Note that this arrangement requires the image/color space code to
651
     * properly handle out of range values.
652
     */
653
24.1k
    if (enc >= pcl_penc_direct_by_plane) {
654
0
        int i;
655
0
        float *pdecode = pindexed->Decode;
656
657
0
        for (i = 0; i < 3; i++) {
658
0
            int nbits = pindexed->cid.bits_per_primary[i];
659
0
            double inv_range = pnorm[i].inv_range;
660
661
0
            if (inv_range == 0.0)
662
0
                inv_range = 254;
663
0
            pdecode[2 * i] = -pnorm[i].blkref * inv_range / 255.0;
664
0
            pdecode[2 * i + 1] =
665
0
                ((float)((1L << nbits) - 1) - pnorm[i].blkref)
666
0
                * inv_range / 255.0;
667
0
        }
668
24.1k
    } else {
669
24.1k
        pindexed->Decode[0] = 0.0;
670
24.1k
        pindexed->Decode[1] = 0.0;      /* modified subsequently */
671
24.1k
    }
672
24.1k
    return 0;
673
24.1k
}
674
675
/*
676
 * Change the number of entries in an PCL indexed color space palette. For
677
 * PCL itself, this occurs only when a palette is created, and is determined
678
 * by the number of bits per index. The NP command in GL/2, on the other hand,
679
 * can override the palette size for an existing palette.
680
 *
681
 * The gl2 boolean indicates if this call is being made from GL/2 (either the
682
 * IN or NP command). The routine needs to know this so as to set the
683
 * appropriate default colors.
684
 *
685
 * Returns 0 on success, < 0 in the event of an error.
686
 */
687
int
688
pcl_cs_indexed_set_num_entries(pcl_cs_indexed_t ** ppindexed,
689
                               int new_num, bool gl2)
690
20.9k
{
691
20.9k
    pcl_cs_indexed_t *pindexed = *ppindexed;
692
20.9k
    int bits = get_pow_2(new_num);
693
20.9k
    int old_num = pindexed->num_entries;
694
20.9k
    int code = 0;
695
696
    /* ignore request if palette is fixed */
697
20.9k
    if (pindexed->pfixed)
698
0
        return 0;
699
700
20.9k
    pindexed->is_GL = gl2;
701
702
20.9k
    if_debug3m('c', pindexed->rc.memory,
703
20.9k
               "pcl_cs_indexed_set_num_entries, is gl2:%d, entries old:%d, new:%d\n",
704
20.9k
               gl2, old_num, new_num);
705
706
    /*
707
     * Set new_num to the smallest larger power of 2 less than
708
     * pcl_cs_indexed_palette_size.
709
     */
710
20.9k
    bits = (bits > pcl_cs_indexed_palette_size_log
711
20.9k
            ? pcl_cs_indexed_palette_size_log : bits);
712
20.9k
    new_num = 1L << bits;
713
714
    /* make sure the palette is unique */
715
20.9k
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
716
0
        return code;
717
20.9k
    pindexed = *ppindexed;
718
20.9k
    pindexed->cid.bits_per_index = bits;
719
720
    /* check if the Decode array must be updated */
721
20.9k
    if (pindexed->cid.encoding < pcl_penc_direct_by_plane)
722
20.9k
        pindexed->Decode[1] = (float)(new_num - 1);
723
724
725
    /* resize the palette if necessary */
726
20.9k
    if (old_num != new_num)
727
20.9k
        resize_indexed_cspace(pindexed, new_num);
728
729
    /* update the number of entries in the palette */
730
20.9k
    pindexed->num_entries = new_num;
731
732
    /* if the palette grew, write in default colors and widths */
733
20.9k
    if (new_num > old_num)
734
20.9k
        set_default_entries(pindexed, old_num, new_num - old_num, gl2);
735
736
20.9k
    return 0;
737
20.9k
}
738
739
/*
740
 * Update the lookup table information for an indexed color space.
741
 *
742
 * Because lookup tables can modify base color spaces, this operation is
743
 * rather ugly. If the base color space is changed, it is necessary to release
744
 * and re-build the graphic library indexed color space as well, as this will
745
 * now have references to obsolete parts of the graphic library base color
746
 * space.
747
 *
748
 * Fortunately, this operation does not happen very often.
749
 *
750
 * Returns 0 if successful, < 0 in the event of an error.
751
 */
752
int
753
pcl_cs_indexed_update_lookup_tbl(pcl_cs_indexed_t ** ppindexed,
754
                                 pcl_lookup_tbl_t * plktbl)
755
0
{
756
0
    pcl_cs_indexed_t *pindexed = *ppindexed;
757
0
    pcl_cspace_type_t cstype = (pcl_cspace_type_t) pindexed->cid.cspace;
758
0
    pcl_cspace_type_t lktype;
759
0
    int code = 0;
760
761
    /* make some simple checks for not-interesting color spaces */
762
0
    if (plktbl != 0)
763
0
        lktype = pcl_lookup_tbl_get_cspace(plktbl);
764
0
    if ((plktbl != 0) &&
765
0
        ((cstype < lktype) || (lktype < pcl_cspace_Colorimetric)))
766
0
        return 0;
767
768
    /* make a unique copy of the indexed color space */
769
0
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
770
0
        return code;
771
0
    pindexed = *ppindexed;
772
773
    /* update the base color space, if appropriate */
774
0
    code = pcl_cs_base_update_lookup_tbl(&(pindexed->pbase), plktbl);
775
0
    if (code <= 0)
776
0
        return code;
777
778
    /* a positive return code indicates we have to rebuild the
779
       palette.  First copy the paletted data, it will be freed when
780
       the color space is released. */
781
0
    {
782
0
        uint size = 3 * pcl_cs_indexed_palette_size;
783
0
        byte *bp = gs_alloc_string(pindexed->rc.memory, size,
784
0
                                   "pcl_cs_indexed_update_lookup_tbl");
785
786
0
        if (bp == NULL)
787
0
            return e_Memory;
788
0
        memcpy(bp, pindexed->palette.data, 3 * pcl_cs_indexed_palette_size);
789
0
        rc_decrement(pindexed->pcspace, "pcl_cs_indexed_update_lookup_tbl");
790
0
        pindexed->palette.data = bp;
791
0
    }
792
793
    /* now rebuild it */
794
0
    return gs_cspace_build_Indexed(&(pindexed->pcspace),
795
0
                                   pindexed->pbase->pcspace,
796
0
                                   pcl_cs_indexed_palette_size,
797
0
                                   (gs_const_string *) & (pindexed->palette),
798
0
                                   pindexed->rc.memory);
799
800
0
}
801
802
/*
803
 * Update an entry in the palette of a PCL indexed color space.
804
 *
805
 * Returns 0 on success, < 0 in the event of an error.
806
 */
807
int
808
pcl_cs_indexed_set_palette_entry(pcl_cs_indexed_t ** ppindexed,
809
                                 int indx, const float comps[3]
810
    )
811
0
{
812
0
    pcl_cs_indexed_t *pindexed = *ppindexed;
813
0
    int code;
814
0
    int i;
815
816
    /* ignore request if palette is fixed */
817
0
    if (pindexed->pfixed)
818
0
        return 0;
819
820
    /*
821
     * Verify that the index is in range. This code obeys HP's documentation,
822
     * and the implementation in the CLJ 5/5M. The DJ 1600C/CM behaves
823
     * differently; it sets indx = indx % num_entries, but only if indx is
824
     * non-negative.
825
     */
826
0
    if ((indx < 0) || (indx >= pindexed->num_entries))
827
0
        return e_Range;
828
829
    /* get a unique copy of the indexed color space */
830
0
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
831
0
        return code;
832
0
    pindexed = *ppindexed;
833
834
    /* normalize and store the entry */
835
0
    indx *= 3;
836
0
    for (i = 0; i < 3; i++) {
837
0
        pcl_cs_indexed_norm_t *pn = &(pindexed->norm[i]);
838
0
        double val = comps[i];
839
840
0
        if (pn->inv_range == 0)
841
0
            val = (val >= pn->blkref ? 255.0 : 0.0);
842
0
        else {
843
0
            val = (val - pn->blkref) * pn->inv_range;
844
0
            val = (val < 0.0 ? 0.0 : (val > 255.0 ? 255.0 : val));
845
0
        }
846
0
        pindexed->palette.data[indx + i] = (byte) val;
847
0
    }
848
0
    return 0;
849
0
}
850
851
/*
852
 * Default the contents of a palette entry.
853
 *
854
 * This request can only come from GL/2, hence there is no gl2 boolean.
855
 *
856
 * Returns 0 on success, < 0 in the event of an error.
857
 */
858
int
859
pcl_cs_indexed_set_default_palette_entry(pcl_cs_indexed_t ** ppindexed,
860
                                         int indx)
861
0
{
862
0
    pcl_cs_indexed_t *pindexed = *ppindexed;
863
0
    int code;
864
865
    /*
866
     * Verify that the index is in range. This code obeys HP's documentation,
867
     * and the implementation in the CLJ 5/5M. The DJ 1600C/CM behaves
868
     * differently; it sets indx = indx % num_entries, but only if indx is
869
     * non-negative.
870
     */
871
0
    if ((indx < 0) || (indx >= pindexed->num_entries))
872
0
        return e_Range;
873
874
    /* get a unique copy of the indexed color space */
875
0
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
876
0
        return code;
877
878
0
    return set_default_entries(*ppindexed, indx, 1, true);
879
0
}
880
881
/*
882
 * Set a pen width in a palette. Units used are still TBD.
883
 *
884
 * Returns 0 if successful, < 0 in case of error.
885
 */
886
int
887
pcl_cs_indexed_set_pen_width(pcl_cs_indexed_t ** ppindexed,
888
                             int pen, double width)
889
8.99k
{
890
8.99k
    pcl_cs_indexed_t *pindexed = *ppindexed;
891
8.99k
    int code;
892
893
    /* check for out-of-range pen */
894
8.99k
    if ((pen < 0) || (pen > pindexed->num_entries))
895
0
        return e_Range;         /* probably should be a different error */
896
897
8.99k
    if ((code = unshare_indexed_cspace(ppindexed)) < 0)
898
0
        return code;
899
8.99k
    pindexed = *ppindexed;
900
901
8.99k
    pindexed->pen_widths[pen] = width;
902
8.99k
    return 0;
903
8.99k
}
904
905
/*
906
 * Build a PCL indexed color space.
907
 *
908
 * To maintain the one-to-one relationship between the PCL indexed color space
909
 * and the graphic library indexed color space, the latter is created at the
910
 * same time as the former. Hence, the base PCL color space must be created
911
 * first (it is required to create the graphics library indexed color space),
912
 * and released once it has been referenced by the (PCL) indexed color space.
913
 *
914
 * The boolean gl2 indicates if this request came from the GL/2 IN command.
915
 *
916
 * Returns 0 if successful, < 0 in case of error.
917
 */
918
919
int
920
pcl_cs_indexed_build_cspace(pcl_state_t * pcs,
921
                            pcl_cs_indexed_t ** ppindexed,
922
                            const pcl_cid_data_t * pcid,
923
                            bool pfixed, bool gl2, gs_memory_t * pmem)
924
20.9k
{
925
20.9k
    pcl_cs_indexed_t *pindexed = *ppindexed;
926
20.9k
    pcl_cspace_type_t type = pcl_cid_get_cspace(pcid);
927
20.9k
    int bits = pcl_cid_get_bits_per_index(pcid);
928
20.9k
    double wht_ref[3];
929
20.9k
    double blk_ref[3];
930
20.9k
    pcl_cs_base_t *pbase = 0;
931
20.9k
    bool is_default = false;
932
20.9k
    int code = 0;
933
934
    /*
935
     * Check if the default color space is being requested. Since there are
936
     * only three fixed spaces, it is sufficient to check that palette is
937
     * fixed and has 1-bit per pixel.
938
     */
939
20.9k
    if (pfixed && (pcid->u.hdr.bits_per_index == dflt_cid_hdr.bits_per_index)) {
940
16.1k
        is_default = true;
941
16.1k
        if (pcs->pdflt_cs_indexed != 0) {
942
0
            if_debug0m('c', pmem,
943
0
                       "[c]build request for default color space\n");
944
0
            pcl_cs_indexed_copy_from(*ppindexed, pcs->pdflt_cs_indexed);
945
0
            return 0;
946
0
        }
947
16.1k
    }
948
949
    /* release the existing color space, if present */
950
20.9k
    if (pindexed != 0) {
951
4.82k
        if_debug1m('c', pmem,
952
4.82k
                   "[c]releasing index for underlying color space:%s\n",
953
4.82k
                   pcl_cid_cspace_get_debug_name(pmem,
954
4.82k
                                                 pindexed->pbase->type));
955
4.82k
        rc_decrement(pindexed, "build indexed color space");
956
4.82k
    }
957
958
    /* build the base color space */
959
20.9k
    if ((code = pcl_cs_base_build_cspace(&pbase, pcid, pmem)) < 0)
960
0
        return code;
961
962
    /* build the indexed color space */
963
20.9k
    if ((code = alloc_indexed_cspace(ppindexed, pbase, 1L << bits, pmem)) < 0) {
964
0
        pcl_cs_base_release(pbase);
965
0
        return code;
966
0
    }
967
20.9k
    pindexed = *ppindexed;
968
969
20.9k
    if_debug1m('c', pmem, "[c]built base and index for color space:%s\n",
970
20.9k
               pcl_cid_cspace_get_debug_name(pmem, pindexed->pbase->type));
971
972
    /* release our extra reference of the base color space */
973
20.9k
    pcl_cs_base_release(pbase);
974
20.9k
    pbase = 0;
975
976
    /* copy the header of the configure image data structure */
977
20.9k
    pindexed->cid = pcid->u.hdr;
978
979
    /* copy in the original color space if there is a substitution in
980
       effect.  There will be the no color spaces type if no use cie
981
       substitution is in effect */
982
20.9k
    pindexed->original_cspace = pcid->original_cspace;
983
984
    /* set up the normalization information */
985
20.9k
    if ((pcid->len > 6) && (type < pcl_cspace_Colorimetric)) {
986
0
        const pcl_cid_dev_long_t *pdev = &(pcid->u.dev);
987
0
        int i;
988
989
0
        for (i = 0; i < 3; i++) {
990
0
            wht_ref[i] = pdev->white_ref[i];
991
0
            blk_ref[i] = pdev->black_ref[i];
992
0
        }
993
20.9k
    } else {
994
20.9k
        int i;
995
996
83.7k
        for (i = 0; i < 3; i++) {
997
62.8k
            wht_ref[i] = (1L << pcl_cid_get_bits_per_primary(pcid, i)) - 1;
998
62.8k
            blk_ref[i] = 0.0;
999
62.8k
        }
1000
1001
        /* reverse for the CMY color space */
1002
20.9k
        if ((type == pcl_cspace_CMY)
1003
20.9k
            || (pcid->original_cspace == pcl_cspace_CMY)) {
1004
0
            int i;
1005
1006
0
            for (i = 0; i < 3; i++) {
1007
0
                double ftmp = wht_ref[i];
1008
1009
0
                wht_ref[i] = blk_ref[i];
1010
0
                blk_ref[i] = ftmp;
1011
0
            }
1012
0
        }
1013
20.9k
    }
1014
20.9k
    code = pcl_cs_indexed_set_norm_and_Decode(ppindexed,
1015
20.9k
                                       wht_ref[0], wht_ref[1], wht_ref[2],
1016
20.9k
                                       blk_ref[0], blk_ref[1], blk_ref[2]
1017
20.9k
        );
1018
20.9k
    if (code < 0)
1019
0
        return code;
1020
1021
    /* set the palette size and the default palette entries */
1022
20.9k
    code = pcl_cs_indexed_set_num_entries(ppindexed, 1L << bits, gl2);
1023
20.9k
    if (code < 0)
1024
0
        return code;
1025
1026
    /* now can indicate if the palette is fixed */
1027
20.9k
    pindexed->pfixed = pfixed;
1028
1029
    /* record if this is the default. */
1030
20.9k
    if (is_default)
1031
20.9k
        pcl_cs_indexed_init_from(pcs->pdflt_cs_indexed, pindexed);
1032
1033
20.9k
    return 0;
1034
20.9k
}
1035
1036
/*
1037
 * Build the default indexed color space. This function is usually called only
1038
 * once, at initialization time.
1039
 *
1040
 * Returns 0 on success, < 0
1041
 */
1042
int
1043
pcl_cs_indexed_build_default_cspace(pcl_state_t * pcs,
1044
                                    pcl_cs_indexed_t ** ppindexed,
1045
                                    gs_memory_t * pmem)
1046
16.1k
{
1047
16.1k
    if (pcs->pdflt_cs_indexed == 0) {
1048
16.1k
        pcs->dflt_cid_data.len = 6;
1049
16.1k
        pcs->dflt_cid_data.u.hdr = dflt_cid_hdr;
1050
16.1k
        pcs->dflt_cid_data.original_cspace = pcl_cspace_num;
1051
16.1k
        return pcl_cs_indexed_build_cspace(pcs,
1052
16.1k
                                           ppindexed,
1053
16.1k
                                           &pcs->dflt_cid_data,
1054
16.1k
                                           true, false, pmem);
1055
16.1k
    } else {
1056
0
        pcl_cs_indexed_copy_from(*ppindexed, pcs->pdflt_cs_indexed);
1057
0
        return 0;
1058
0
    }
1059
16.1k
}
1060
1061
/*
1062
 * Special indexed color space constructor, for building a 2 entry indexed color
1063
 * space based on an existing base color space. The first color is always set
1064
 * to white, while the second entry takes the value indicated by pcolor1.
1065
 *
1066
 * This reoutine is used to build the two-entry indexed color spaces required
1067
 * for creating opaque "uncolored" patterns.
1068
 */
1069
int
1070
pcl_cs_indexed_build_special(pcl_cs_indexed_t ** ppindexed,
1071
                             pcl_cs_base_t * pbase,
1072
                             const byte * pcolor1, gs_memory_t * pmem)
1073
3.18k
{
1074
3.18k
    static const pcl_cid_hdr_t cid = { pcl_cspace_White,        /* ignored */
1075
3.18k
        pcl_penc_indexed_by_pixel,
1076
3.18k
        1,
1077
3.18k
        {8, 8, 8} /* ignored */
1078
3.18k
    };
1079
3.18k
    static const double wht_ref[3] = { 255.0, 255.0, 255.0 };
1080
3.18k
    static const double blk_ref[3] = { 0.0, 0.0, 0.0 };
1081
3.18k
    pcl_cs_indexed_t *pindexed;
1082
3.18k
    int i, code = 0;
1083
1084
    /* build the indexed color space */
1085
3.18k
    if ((code = alloc_indexed_cspace(ppindexed, pbase, 2, pmem)) < 0)
1086
0
        return code;
1087
3.18k
    pindexed = *ppindexed;
1088
3.18k
    pindexed->pfixed = false;
1089
3.18k
    pindexed->cid = cid;
1090
3.18k
    pindexed->num_entries = 2;
1091
    /* set up the normalization information - not strictly necessary */
1092
3.18k
    code = pcl_cs_indexed_set_norm_and_Decode(ppindexed,
1093
3.18k
                                       wht_ref[0], wht_ref[1], wht_ref[2],
1094
3.18k
                                       blk_ref[0], blk_ref[1], blk_ref[2]
1095
3.18k
        );
1096
3.18k
    if (code < 0)
1097
0
        return code;
1098
1099
3.18k
    pindexed->Decode[1] = 1;
1100
1101
12.7k
    for (i = 0; i < 3; i++) {
1102
9.54k
        pindexed->palette.data[i] = 255;
1103
9.54k
        pindexed->palette.data[i + 3] = pcolor1[i];
1104
9.54k
    }
1105
1106
    /* the latter are not strictly necessary */
1107
3.18k
    pindexed->pen_widths[0] = dflt_pen_width;
1108
3.18k
    pindexed->pen_widths[1] = dflt_pen_width;
1109
1110
3.18k
    return 0;
1111
3.18k
}
1112
1113
/*
1114
 * Install an indexed color space into the graphic state. If no indexed color
1115
 * space exists yet, build a default color space.
1116
 *
1117
 * Returns 0 on success, < 0 in the event of an error.
1118
 */
1119
int
1120
pcl_cs_indexed_install(pcl_cs_indexed_t ** ppindexed, pcl_state_t * pcs)
1121
205k
{
1122
205k
    pcl_cs_indexed_t *pindexed = *ppindexed;
1123
205k
    int code = 0;
1124
1125
205k
    if (pindexed == 0) {
1126
0
        code =
1127
0
            pcl_cs_indexed_build_default_cspace(pcs, ppindexed, pcs->memory);
1128
0
        if (code < 0)
1129
0
            return code;
1130
0
        pindexed = *ppindexed;
1131
0
    }
1132
    /* Really, to be consistent with the other interpreter's usage of the graphics library,
1133
     * we should call gs_setcolorspace(pindexed->pcspace->base_space), but if we do that
1134
     * we get a lot of differences in halftoned output. Just calling the 'install' procedure
1135
     * for the base space doesn't modify pgs->color[0].ccolor elements for RGB, which
1136
     * gs_setcolorspace() does. I think it would be worthwhile someone investigating why this is
1137
     * one day, some of the differences looked like progressions.
1138
     */
1139
205k
    code = (*pindexed->pcspace->base_space->type->install_cspace)
1140
205k
        (pindexed->pcspace->base_space, pcs->pgs);
1141
205k
    if (code < 0)
1142
0
        return code;
1143
205k
    return gs_setcolorspace(pcs->pgs, pindexed->pcspace);
1144
205k
}
1145
1146
/*
1147
 * Return true if the given entry in the color palette represents white,
1148
 * false otherwise.
1149
 *
1150
 * As with many other parts of this code, the determination of what is "white"
1151
 * is done, for practical reasons, in source color space.  HP's implementations
1152
 * make the same determination in device color space (but prior to dithering).
1153
 * In the absence of color lookup tables, the two will give the same result.
1154
 * An inverting color lookup table will, however, cause the two approaches to
1155
 * vary.
1156
 */
1157
bool
1158
pcl_cs_indexed_is_white(const pcl_cs_indexed_t * pindexed, int indx)
1159
3.62M
{
1160
3.62M
    const byte *pb = 0;
1161
1162
3.62M
    if (pindexed == 0)
1163
0
        return true;
1164
3.62M
    if ((indx < 0) || (indx >= pindexed->num_entries))
1165
0
        return false;
1166
3.62M
    pb = pindexed->palette.data + 3 * indx;
1167
3.62M
    return (pb[0] == 0xff) && (pb[1] == 0xff) && (pb[2] == 0xff);
1168
3.62M
}
1169
1170
/*
1171
 * Return true if the given entry in the color palette is black, false
1172
 * otherwise.
1173
 *
1174
 * The determination of "blackness" is made in source space, rather than in
1175
 * device space (prior to dither). The latter would be more correct, but is
1176
 * not as easily accomplished, and only in very unusual circumstances will the
1177
 * two produce different results.
1178
 */
1179
bool
1180
pcl_cs_indexed_is_black(const pcl_cs_indexed_t * pindexed, int indx)
1181
6.36k
{
1182
6.36k
    const byte *pb = 0;
1183
1184
6.36k
    if ((pindexed == 0) || (indx < 0) || (indx >= pindexed->num_entries))
1185
0
        return false;
1186
6.36k
    pb = pindexed->palette.data + 3 * indx;
1187
6.36k
    return (pb[0] == 0) && (pb[1] == 0) && (pb[2] == 0);
1188
6.36k
}
1189
1190
/*
1191
 * One time initialization. This exists only because of the possibility that
1192
 * BSS may not be initialized.
1193
 */
1194
void
1195
pcl_cs_indexed_init(pcl_state_t * pcs)
1196
16.1k
{
1197
16.1k
    pcs->pdflt_cs_indexed = 0;
1198
16.1k
}