Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/base/gsicc_manage.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/*  GS ICC Manager.  Initial stubbing of functions.  */
17
18
#include "std.h"
19
#include "stdpre.h"
20
#include "gstypes.h"
21
#include "gsmemory.h"
22
#include "gsstruct.h"
23
#include "scommon.h"
24
#include "strmio.h"
25
#include "gx.h"
26
#include "gp.h"
27
#include "gxgstate.h"
28
#include "gxcspace.h"
29
#include "gscms.h"
30
#include "gsicc_manage.h"
31
#include "gsicc_cache.h"
32
#include "gsicc_profilecache.h"
33
#include "gsicc_cms.h"
34
#include "gserrors.h"
35
#include "string_.h"
36
#include "gxclist.h"
37
#include "gxcldev.h"
38
#include "gzstate.h"
39
#include "gsicc_create.h"
40
#include "gpmisc.h"
41
#include "gxdevice.h"
42
#include "gxdevsop.h"
43
#include "assert_.h"
44
45
1.11M
#define ICC_HEADER_SIZE 128
46
#define CREATE_V2_DATA 0
47
48
#if ICC_DUMP
49
unsigned int global_icc_index = 0;
50
#endif
51
52
/* Needed for gsicc_set_devicen_equiv_colors. */
53
extern const gs_color_space_type gs_color_space_type_ICC;
54
55
/* Static prototypes */
56
57
static void gsicc_set_default_cs_value(cmm_profile_t *picc_profile,
58
                                       gs_gstate *pgs);
59
static gsicc_namelist_t* gsicc_new_namelist(gs_memory_t *memory);
60
static gsicc_colorname_t* gsicc_new_colorname(gs_memory_t *memory);
61
static gsicc_namelist_t* gsicc_get_spotnames(gcmmhprofile_t profile,
62
                                             gs_memory_t *memory);
63
static void gsicc_manager_free_contents(gsicc_manager_t *icc_man,
64
                                        client_name_t cname);
65
66
static void rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in,
67
                                  client_name_t cname);
68
static void rc_free_icc_profile(gs_memory_t * mem, void *ptr_in,
69
                                client_name_t cname);
70
static int gsicc_load_profile_buffer(cmm_profile_t *profile, stream *s,
71
                                     gs_memory_t *memory);
72
static int64_t gsicc_search_icc_table(clist_icctable_t *icc_table,
73
                                      int64_t icc_hashcode, int *size);
74
static int gsicc_load_namedcolor_buffer(cmm_profile_t *profile, stream *s,
75
                          gs_memory_t *memory);
76
static cmm_srcgtag_profile_t* gsicc_new_srcgtag_profile(gs_memory_t *memory);
77
static void gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem);
78
79
static void
80
gsicc_manager_finalize(const gs_memory_t *memory, void * vptr);
81
82
static void
83
gsicc_smask_finalize(const gs_memory_t *memory, void * vptr);
84
85
/* profile data structure */
86
/* profile_handle should NOT be garbage collected since it is allocated by the external CMS */
87
gs_private_st_ptrs2(st_gsicc_colorname, gsicc_colorname_t, "gsicc_colorname",
88
                    gsicc_colorname_enum_ptrs, gsicc_colorname_reloc_ptrs, name, next);
89
90
gs_private_st_ptrs2_final(st_gsicc_manager, gsicc_manager_t, "gsicc_manager",
91
                    gsicc_manager_enum_ptrs, gsicc_manager_profile_reloc_ptrs,
92
                    gsicc_manager_finalize, smask_profiles, device_n);
93
94
gs_private_st_simple_final(st_gsicc_smask, gsicc_smask_t, "gsicc_smask", gsicc_smask_finalize);
95
96
gs_private_st_ptrs2(st_gsicc_devicen, gsicc_devicen_t, "gsicc_devicen",
97
                gsicc_devicen_enum_ptrs, gsicc_devicen_reloc_ptrs, head, final);
98
99
gs_private_st_ptrs1(st_gsicc_devicen_entry, gsicc_devicen_entry_t,
100
                    "gsicc_devicen_entry", gsicc_devicen_entry_enum_ptrs,
101
                    gsicc_devicen_entry_reloc_ptrs, next);
102
103
typedef struct default_profile_def_s {
104
    const char *path;
105
    gsicc_profile_t default_type;
106
} default_profile_def_t;
107
108
static default_profile_def_t default_profile_params[] =
109
{
110
    {DEFAULT_GRAY_ICC, DEFAULT_GRAY},
111
    {DEFAULT_RGB_ICC, DEFAULT_RGB},
112
    {DEFAULT_CMYK_ICC, DEFAULT_CMYK},
113
    {LAB_ICC, LAB_TYPE}
114
};
115
116
void
117
gsicc_setcoloraccuracy(gs_memory_t *mem, uint level)
118
79.0k
{
119
79.0k
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
120
121
79.0k
    ctx->icc_color_accuracy = level;
122
79.0k
}
123
124
uint
125
gsicc_currentcoloraccuracy(gs_memory_t *mem)
126
79.0k
{
127
79.0k
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
128
129
79.0k
    return ctx->icc_color_accuracy;
130
79.0k
}
131
132
/* Get the size of the ICC profile that is in the buffer */
133
unsigned int
134
gsicc_getprofilesize(unsigned char *buffer)
135
0
{
136
0
    return ( (buffer[0] << 24) + (buffer[1] << 16) +
137
0
             (buffer[2] << 8)  +  buffer[3] );
138
0
}
139
140
/* Get major and minor ICC version number */
141
int
142
gsicc_getprofilevers(cmm_profile_t *icc_profile, unsigned char *major,
143
    unsigned char *minor)
144
0
{
145
0
    if (icc_profile == NULL || icc_profile->buffer == NULL)
146
0
        return -1;
147
148
0
    *major = icc_profile->buffer[8];
149
0
    *minor = icc_profile->buffer[9];
150
151
0
    return 0;
152
0
}
153
154
void
155
gsicc_set_icc_range(cmm_profile_t **icc_profile)
156
1.13M
{
157
1.13M
    int num_comp = (*icc_profile)->num_comps;
158
1.13M
    int k;
159
160
4.26M
    for ( k = 0; k < num_comp; k++) {
161
3.13M
        (*icc_profile)->Range.ranges[k].rmin = 0.0;
162
3.13M
        (*icc_profile)->Range.ranges[k].rmax = 1.0;
163
3.13M
    }
164
1.13M
}
165
166
cmm_profile_t*
167
gsicc_set_iccsmaskprofile(const char *pname,
168
                          int namelen, gsicc_manager_t *icc_manager,
169
                          gs_memory_t *mem)
170
1.19k
{
171
1.19k
    stream *str;
172
1.19k
    int code;
173
1.19k
    cmm_profile_t *icc_profile;
174
175
1.19k
    if (icc_manager == NULL) {
176
0
        code = gsicc_open_search(pname, namelen, mem, NULL, 0, &str);
177
1.19k
    } else {
178
1.19k
        code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
179
1.19k
                                 mem->gs_lib_ctx->profiledir_len, &str);
180
1.19k
    }
181
1.19k
    if (code < 0 || str == NULL)
182
0
        return NULL;
183
1.19k
    icc_profile = gsicc_profile_new(str, mem, pname, namelen);
184
1.19k
    code = sfclose(str);
185
1.19k
    if (icc_profile == NULL)
186
0
        return NULL;
187
    /* Get the profile handle */
188
1.19k
    icc_profile->profile_handle =
189
1.19k
            gsicc_get_profile_handle_buffer(icc_profile->buffer,
190
1.19k
                                            icc_profile->buffer_size,
191
1.19k
                                            mem);
192
1.19k
    if (!icc_profile->profile_handle) {
193
0
        rc_free_icc_profile(mem, icc_profile, "gsicc_set_iccsmaskprofile");
194
0
        return NULL;
195
0
    }
196
    /* Compute the hash code of the profile. Everything in the
197
       ICC manager will have it's hash code precomputed */
198
1.19k
    gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode),
199
1.19k
                            icc_profile->buffer_size);
200
1.19k
    icc_profile->hash_is_valid = true;
201
1.19k
    icc_profile->num_comps =
202
1.19k
            gscms_get_input_channel_count(icc_profile->profile_handle, icc_profile->memory);
203
1.19k
    icc_profile->num_comps_out =
204
1.19k
            gscms_get_output_channel_count(icc_profile->profile_handle, icc_profile->memory);
205
1.19k
    icc_profile->data_cs =
206
1.19k
            gscms_get_profile_data_space(icc_profile->profile_handle, icc_profile->memory);
207
1.19k
    gsicc_set_icc_range(&icc_profile);
208
1.19k
    return icc_profile;
209
1.19k
}
210
211
static void
212
gsicc_smask_finalize(const gs_memory_t *memory, void * vptr)
213
4.06k
{
214
4.06k
    gsicc_smask_t *iccsmask = (gsicc_smask_t *)vptr;
215
216
4.06k
    gsicc_adjust_profile_rc(iccsmask->smask_gray, -1,
217
4.06k
        "gsicc_smask_finalize");
218
4.06k
    gsicc_adjust_profile_rc(iccsmask->smask_rgb, -1,
219
4.06k
        "gsicc_smask_finalize");
220
4.06k
    gsicc_adjust_profile_rc(iccsmask->smask_cmyk, -1,
221
4.06k
        "gsicc_smask_finalize");
222
4.06k
}
223
224
gsicc_smask_t*
225
gsicc_new_iccsmask(gs_memory_t *memory)
226
4.06k
{
227
4.06k
    gsicc_smask_t *result;
228
229
4.06k
    result = (gsicc_smask_t *) gs_alloc_struct(memory, gsicc_smask_t, &st_gsicc_smask, "gsicc_new_iccsmask");
230
4.06k
    if (result != NULL) {
231
4.06k
        result->smask_gray = NULL;
232
4.06k
        result->smask_rgb = NULL;
233
4.06k
        result->smask_cmyk = NULL;
234
4.06k
        result->memory = memory;
235
4.06k
        result->swapped = false;
236
4.06k
    }
237
4.06k
    return result;
238
4.06k
}
239
240
/* Allocate a new structure to hold the profiles that contains the profiles
241
   used when we are in a softmask group */
242
int
243
gsicc_initialize_iccsmask(gsicc_manager_t *icc_manager)
244
394
{
245
394
    gs_memory_t *stable_mem = icc_manager->memory->stable_memory;
246
247
    /* Allocations need to be done in stable memory.  We want to maintain
248
       the smask_profiles object */
249
394
    icc_manager->smask_profiles = gsicc_new_iccsmask(stable_mem);
250
394
    if (icc_manager->smask_profiles == NULL)
251
0
        return gs_throw(gs_error_VMerror, "insufficient memory to allocate smask profiles");
252
    /* Load the gray, rgb, and cmyk profiles */
253
394
    if ((icc_manager->smask_profiles->smask_gray =
254
394
        gsicc_set_iccsmaskprofile(SMASK_GRAY_ICC, strlen(SMASK_GRAY_ICC),
255
394
        icc_manager, stable_mem) ) == NULL)
256
0
        goto error;
257
394
    if ((icc_manager->smask_profiles->smask_rgb =
258
394
        gsicc_set_iccsmaskprofile(SMASK_RGB_ICC, strlen(SMASK_RGB_ICC),
259
394
        icc_manager, stable_mem)) == NULL)
260
0
        goto error;
261
394
    if ((icc_manager->smask_profiles->smask_cmyk =
262
394
        gsicc_set_iccsmaskprofile(SMASK_CMYK_ICC, strlen(SMASK_CMYK_ICC),
263
394
        icc_manager, stable_mem)) == NULL)
264
0
        goto error;
265
266
    /* Set these as "default" so that pdfwrite or other high level devices
267
       will know that these are manufactured profiles, and default spaces
268
       should be used */
269
394
    icc_manager->smask_profiles->smask_gray->default_match = DEFAULT_GRAY;
270
394
    icc_manager->smask_profiles->smask_rgb->default_match = DEFAULT_RGB;
271
394
    icc_manager->smask_profiles->smask_cmyk->default_match = DEFAULT_CMYK;
272
394
    return 0;
273
274
0
error:
275
0
    if (icc_manager->smask_profiles->smask_gray)
276
0
        rc_free_icc_profile(stable_mem, icc_manager->smask_profiles->smask_gray, "gsicc_initialize_iccsmask");
277
0
    icc_manager->smask_profiles->smask_gray = NULL;
278
0
    if (icc_manager->smask_profiles->smask_rgb)
279
0
        rc_free_icc_profile(stable_mem, icc_manager->smask_profiles->smask_rgb, "gsicc_initialize_iccsmask");
280
0
    icc_manager->smask_profiles->smask_rgb = NULL;
281
0
    if (icc_manager->smask_profiles->smask_cmyk)
282
0
        rc_free_icc_profile(stable_mem, icc_manager->smask_profiles->smask_cmyk, "gsicc_initialize_iccsmask");
283
0
    icc_manager->smask_profiles->smask_cmyk = NULL;
284
0
    gs_free_object(stable_mem, icc_manager->smask_profiles, "gsicc_initialize_iccsmask");
285
0
    icc_manager->smask_profiles = NULL;
286
0
    return gs_throw(-1, "failed to load an smask profile");
287
394
}
288
289
static int
290
gsicc_new_devicen(gsicc_manager_t *icc_manager)
291
0
{
292
/* Allocate a new deviceN ICC profile entry in the deviceN list */
293
0
    gsicc_devicen_entry_t *device_n_entry =
294
0
        gs_alloc_struct(icc_manager->memory, gsicc_devicen_entry_t,
295
0
                &st_gsicc_devicen_entry, "gsicc_new_devicen");
296
0
    if (device_n_entry == NULL)
297
0
        return gs_throw(gs_error_VMerror, "insufficient memory to allocate device n profile");
298
0
    device_n_entry->next = NULL;
299
0
    device_n_entry->iccprofile = NULL;
300
/* Check if we already have one in the manager */
301
0
    if ( icc_manager->device_n == NULL ) {
302
        /* First one.  Need to allocate the DeviceN main object */
303
0
        icc_manager->device_n = gs_alloc_struct(icc_manager->memory,
304
0
            gsicc_devicen_t, &st_gsicc_devicen, "gsicc_new_devicen");
305
306
0
        if (icc_manager->device_n == NULL)
307
0
            return gs_throw(gs_error_VMerror, "insufficient memory to allocate device n profile");
308
309
0
        icc_manager->device_n->head = device_n_entry;
310
0
        icc_manager->device_n->final = device_n_entry;
311
0
        icc_manager->device_n->count = 1;
312
0
        return 0;
313
0
    } else {
314
        /* We have one or more in the list. */
315
0
        icc_manager->device_n->final->next = device_n_entry;
316
0
        icc_manager->device_n->final = device_n_entry;
317
0
        icc_manager->device_n->count++;
318
0
        return 0;
319
0
    }
320
0
}
321
322
cmm_profile_t*
323
gsicc_finddevicen(const gs_color_space *pcs, gsicc_manager_t *icc_manager)
324
0
{
325
0
    int k,j,i;
326
0
    gsicc_devicen_entry_t *curr_entry;
327
0
    int num_comps;
328
0
    char **names = pcs->params.device_n.names;
329
0
    unsigned char *pname;
330
0
    unsigned int name_size;
331
0
    gsicc_devicen_t *devicen_profiles = icc_manager->device_n;
332
0
    gsicc_colorname_t *icc_spot_entry;
333
0
    int match_count = 0;
334
0
    bool permute_needed = false;
335
336
0
    num_comps = gs_color_space_num_components(pcs);
337
338
    /* Go through the list looking for a match */
339
0
    curr_entry = devicen_profiles->head;
340
0
    for ( k = 0; k < devicen_profiles->count; k++ ) {
341
0
        if (curr_entry->iccprofile->num_comps == num_comps ) {
342
343
            /* Now check the names.  The order is important
344
               since this is supposed to be the laydown order.
345
               If the order is off, the ICC profile will likely
346
               not be accurate.  The ICC profile drives the laydown
347
               order here.  A permutation vector is used to
348
               reorganize the data prior to the transform application */
349
0
            for ( j = 0; j < num_comps; j++) {
350
                /* Get the character string and length for the component name. */
351
0
                pname = (unsigned char *)names[j];
352
0
                name_size = strlen(names[j]);
353
                /* Compare to the jth entry in the ICC profile */
354
0
                icc_spot_entry = curr_entry->iccprofile->spotnames->head;
355
0
                for ( i = 0; i < num_comps; i++) {
356
0
                    if( strncmp((const char *) pname,
357
0
                        icc_spot_entry->name, name_size) == 0 ) {
358
                        /* Found a match */
359
0
                        match_count++;
360
0
                        curr_entry->iccprofile->devicen_permute[j] = i;
361
0
                        if ( j != i) {
362
                            /* Document ink order does not match ICC
363
                               profile ink order */
364
0
                            permute_needed = true;
365
0
                        }
366
0
                        break;
367
0
                    } else
368
0
                        icc_spot_entry = icc_spot_entry->next;
369
0
                }
370
0
                if (match_count < j+1)
371
0
                    return(NULL);
372
0
            }
373
0
            if ( match_count == num_comps) {
374
                /* We have a match.  Order of components does not match laydown
375
                   order specified by the ICC profile.  Set a flag.  This may
376
                   be an issue if we are using 2 DeviceN color spaces with the
377
                   same colorants but with different component orders.  The problem
378
                   comes about since we would be sharing the profile in the
379
                   DeviceN entry of the icc manager. */
380
0
                curr_entry->iccprofile->devicen_permute_needed = permute_needed;
381
0
                return(curr_entry->iccprofile);
382
0
            }
383
0
            match_count = 0;
384
0
        }
385
0
    }
386
0
    return NULL;
387
0
}
388
389
/* Populate the color names entries that should
390
   be contained in the DeviceN ICC profile */
391
static gsicc_namelist_t*
392
gsicc_get_spotnames(gcmmhprofile_t profile, gs_memory_t *memory)
393
0
{
394
0
    int k;
395
0
    gsicc_namelist_t *list;
396
0
    gsicc_colorname_t *name;
397
0
    gsicc_colorname_t **curr_entry;
398
0
    int num_colors;
399
0
    char *clr_name;
400
401
0
    num_colors = gscms_get_numberclrtnames(profile, memory);
402
0
    if (num_colors == 0)
403
0
        return(NULL);
404
    /* Allocate structure for managing this */
405
0
    list = gsicc_new_namelist(memory);
406
0
    if (list == NULL)
407
0
        return(NULL);
408
0
    curr_entry = &(list->head);
409
0
    list->count = num_colors;
410
0
    for (k = 0; k < num_colors; k++) {
411
        /* Allocate a new name object */
412
0
        clr_name = gscms_get_clrtname(profile, k, memory);
413
0
        if (clr_name == NULL)
414
0
            break;
415
0
        name = gsicc_new_colorname(memory);
416
0
        if (name == NULL) {
417
            /* FIXME: Free clr_name */
418
0
            gs_free_object(memory, clr_name, "gsicc_get_spotnames");
419
0
            break;
420
0
        }
421
        /* Get the name */
422
0
        name->name = clr_name;
423
0
        name->length = strlen(clr_name);
424
0
        *curr_entry = name;
425
0
        curr_entry = &(name->next);
426
0
    }
427
0
    if (k < num_colors) {
428
        /* Failed allocation */
429
0
        gsicc_free_spotnames(list, memory);
430
0
        return NULL;
431
0
    }
432
0
    return list;
433
0
}
434
435
static void
436
gsicc_get_devicen_names(cmm_profile_t *icc_profile, gs_memory_t *memory)
437
0
{
438
    /* The names are contained in the
439
       named color tag.  We use the
440
       CMM to extract the data from the
441
       profile */
442
0
    if (icc_profile->profile_handle == NULL) {
443
0
        if (icc_profile->buffer != NULL) {
444
0
            icc_profile->profile_handle =
445
0
                gsicc_get_profile_handle_buffer(icc_profile->buffer,
446
0
                                                icc_profile->buffer_size,
447
0
                                                memory);
448
0
        } else
449
0
            return;
450
0
    }
451
0
    icc_profile->spotnames =
452
0
        gsicc_get_spotnames(icc_profile->profile_handle, memory->non_gc_memory);
453
0
    return;
454
0
}
455
456
/* Allocate new spot name list object.  */
457
static gsicc_namelist_t*
458
gsicc_new_namelist(gs_memory_t *memory)
459
0
{
460
0
    gsicc_namelist_t *result;
461
462
0
    result = (gsicc_namelist_t *) gs_alloc_bytes(memory->non_gc_memory, sizeof(gsicc_namelist_t),
463
0
                                                 "gsicc_new_namelist");
464
0
    if (result == NULL)
465
0
        return NULL;
466
0
    result->count = 0;
467
0
    result->head = NULL;
468
0
    result->name_str = NULL;
469
0
    result->color_map = NULL;
470
0
    return result;
471
0
}
472
473
/* Allocate new spot name.  */
474
static gsicc_colorname_t*
475
gsicc_new_colorname(gs_memory_t *memory)
476
0
{
477
0
    gsicc_colorname_t *result;
478
479
0
    result = gs_alloc_struct(memory,gsicc_colorname_t,
480
0
                &st_gsicc_colorname, "gsicc_new_colorname");
481
0
    if (result == NULL)
482
0
        return NULL;
483
0
    result->length = 0;
484
0
    result->name = NULL;
485
0
    result->next = NULL;
486
0
    return result;
487
0
}
488
489
/* If the profile is one of the default types that were set in the iccmanager,
490
   then the index for that type is returned.  Otherwise the ICC index is returned.
491
   This is currently used to keep us from writing out the default profiles for
492
   high level devices, if desired. */
493
gs_color_space_index
494
gsicc_get_default_type(cmm_profile_t *profile_data)
495
0
{
496
0
    switch (profile_data->default_match) {
497
0
        case DEFAULT_GRAY:
498
0
            return gs_color_space_index_DeviceGray;
499
0
        case DEFAULT_RGB:
500
0
            return gs_color_space_index_DeviceRGB;
501
0
        case DEFAULT_CMYK:
502
0
            return gs_color_space_index_DeviceCMYK;
503
0
        case CIE_A:
504
0
            return gs_color_space_index_CIEA;
505
0
        case CIE_ABC:
506
0
            return gs_color_space_index_CIEABC;
507
0
        case CIE_DEF:
508
0
            return gs_color_space_index_CIEDEF;
509
0
        case CIE_DEFG:
510
0
            return gs_color_space_index_CIEDEFG;
511
0
        default:
512
0
            return gs_color_space_index_ICC;
513
0
    }
514
0
}
515
516
int
517
gsicc_use_fast_color(cmm_profile_t* profile_data)
518
16.1M
{
519
16.1M
    switch (profile_data->default_match) {
520
0
    case CIE_A:
521
0
    case CIE_ABC:
522
0
    case CIE_DEF:
523
0
    case CIE_DEFG:
524
3.12k
    case LAB_TYPE:
525
3.12k
    case NAMED_TYPE:
526
3.12k
    case DEVICEN_TYPE:
527
3.12k
        return 0;
528
16.1M
    default:
529
16.1M
        return profile_data->num_comps;
530
16.1M
    }
531
16.1M
}
532
533
bool
534
gsicc_is_default_profile(cmm_profile_t *profile_data)
535
0
{
536
0
    switch (profile_data->default_match) {
537
0
        case DEFAULT_GRAY:
538
0
        case DEFAULT_RGB:
539
0
        case DEFAULT_CMYK:
540
0
            return true;
541
0
        default:
542
0
            return false;
543
0
    }
544
0
}
545
546
bool
547
gsicc_profile_from_ps(cmm_profile_t *profile_data)
548
25.7k
{
549
25.7k
    switch ( profile_data->default_match ) {
550
0
        case CIE_A:
551
0
        case CIE_ABC:
552
0
        case CIE_DEF:
553
0
        case CIE_DEFG:
554
0
            return true;
555
25.7k
        default:
556
25.7k
            return false;
557
25.7k
    }
558
25.7k
}
559
560
/*
561
 * Adjust the reference count of the profile. This is intended to support
562
 * applications (such as XPS) which maintain ICC profiles outside of the
563
 * graphic state.
564
 */
565
/* for multi-threaded use, we need to adjust the ref_count safely */
566
void
567
gsicc_adjust_profile_rc(cmm_profile_t *profile_data, int delta, const char *name_str)
568
9.01M
{
569
9.01M
    if (profile_data != NULL) {
570
8.48M
        gx_monitor_enter(profile_data->lock);
571
8.48M
        if (profile_data->rc.ref_count == 1 && delta < 0) {
572
1.26M
            profile_data->rc.ref_count = 0;   /* while locked */
573
1.26M
            gx_monitor_leave(profile_data->lock);
574
1.26M
            rc_free_struct(profile_data, name_str);
575
7.21M
        } else {
576
7.21M
            rc_adjust(profile_data, delta, name_str);
577
7.21M
            gx_monitor_leave(profile_data->lock);
578
7.21M
        }
579
8.48M
    }
580
9.01M
}
581
582
/* Fill in the actual source structure rending information */
583
static int
584
gsicc_fill_srcgtag_item(gsicc_rendering_param_t *r_params, char **pstrlast, bool cmyk)
585
0
{
586
0
    char *curr_ptr;
587
0
    int blackptcomp;
588
0
    int or_icc, preserve_k;
589
0
    int ri;
590
591
    /* Get the intent */
592
0
    curr_ptr = gs_strtok(NULL, "\t, \n\r", pstrlast);
593
0
    if (sscanf(curr_ptr, "%d", &ri) != 1)
594
0
        return_error(gs_error_unknownerror);
595
0
    r_params->rendering_intent = ri | gsRI_OVERRIDE;
596
    /* Get the black point compensation setting */
597
0
    curr_ptr = gs_strtok(NULL, "\t, \n\r", pstrlast);
598
0
    if (sscanf(curr_ptr, "%d", &blackptcomp) != 1)
599
0
        return_error(gs_error_unknownerror);
600
0
    r_params->black_point_comp = blackptcomp | gsBP_OVERRIDE;
601
    /* Get the over-ride embedded ICC boolean */
602
0
    curr_ptr = gs_strtok(NULL, "\t, \n\r", pstrlast);
603
0
    if (sscanf(curr_ptr, "%d", &or_icc) != 1)
604
0
        return_error(gs_error_unknownerror);
605
0
    r_params->override_icc = or_icc;
606
0
    if (cmyk) {
607
        /* Get the preserve K control */
608
0
        curr_ptr = gs_strtok(NULL, "\t, \n\r", pstrlast);
609
0
        if (sscanf(curr_ptr, "%d", &preserve_k) < 1)
610
0
            return_error(gs_error_unknownerror);
611
0
        r_params->preserve_black = preserve_k | gsKP_OVERRIDE;
612
0
    } else {
613
0
        r_params->preserve_black = gsBKPRESNOTSPECIFIED;
614
0
    }
615
0
    return 0;
616
0
}
617
618
static int
619
gsicc_check_device_link(cmm_profile_t *icc_profile, gs_memory_t *memory)
620
0
{
621
0
    bool value;
622
623
0
    value = gscms_is_device_link(icc_profile->profile_handle, memory);
624
0
    icc_profile->isdevlink = value;
625
626
0
    return value;
627
0
}
628
629
int
630
gsicc_get_device_class(cmm_profile_t *icc_profile)
631
0
{
632
0
    return gscms_get_device_class(icc_profile->profile_handle, icc_profile->memory);
633
0
}
634
635
/* This inititializes the srcgtag structure in the ICC manager */
636
static int
637
gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname,
638
                        int namelen)
639
0
{
640
0
    gs_memory_t *mem;
641
0
    stream *str;
642
0
    int code;
643
0
    int info_size;
644
0
    char *buffer_ptr, *curr_ptr, *last;
645
0
    int num_bytes;
646
0
    int k;
647
0
    static const char *const srcgtag_keys[] = {GSICC_SRCGTAG_KEYS};
648
0
    cmm_profile_t *icc_profile;
649
0
    cmm_srcgtag_profile_t *srcgtag;
650
0
    bool start = true;
651
0
    gsicc_cmm_t cmm = gsCMM_DEFAULT;
652
653
    /* If we don't have an icc manager or if this thing is already set
654
       then ignore the call.  For now, I am going to allow it to
655
       be set one time. */
656
0
    if (icc_manager == NULL || icc_manager->srcgtag_profile != NULL) {
657
0
        return 0;
658
0
    } else {
659
0
        mem = icc_manager->memory->non_gc_memory;
660
0
        code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
661
0
                                 mem->gs_lib_ctx->profiledir_len, &str);
662
0
        if (code < 0)
663
0
            return code;
664
0
    }
665
0
    if (str != NULL) {
666
        /* Get the information in the file */
667
0
        code = sfseek(str,0,SEEK_END);
668
0
        if (code < 0)
669
0
            return code;
670
0
        info_size = sftell(str);
671
0
        code = srewind(str);
672
0
        if (code < 0)
673
0
            return code;
674
0
        if (info_size > (GSICC_NUM_SRCGTAG_KEYS + 1) * FILENAME_MAX) {
675
0
            return gs_throw1(-1, "setting of %s src obj color info failed",
676
0
                               pname);
677
0
        }
678
        /* Allocate the buffer, stuff with the data */
679
0
        buffer_ptr = (char*) gs_alloc_bytes(mem, info_size+1,
680
0
                                            "gsicc_set_srcgtag_struct");
681
0
        if (buffer_ptr == NULL) {
682
0
            return gs_throw1(gs_error_VMerror, "setting of %s src obj color info failed",
683
0
                               pname);
684
0
        }
685
0
        num_bytes = sfread(buffer_ptr,sizeof(unsigned char), info_size, str);
686
0
        code = sfclose(str);
687
0
        if (code < 0) {
688
0
            gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
689
0
             return code;
690
0
        }
691
0
        buffer_ptr[info_size] = 0;
692
0
        if (num_bytes != info_size) {
693
0
            gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
694
0
            return gs_throw1(-1, "setting of %s src obj color info failed",
695
0
                               pname);
696
0
        }
697
        /* Create the structure in which we will store this data */
698
0
        srcgtag = gsicc_new_srcgtag_profile(mem);
699
0
        if (srcgtag == NULL) {
700
0
            gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
701
0
            return gs_throw1(gs_error_VMerror, "creation of profile for %s failed",
702
0
                               pname);
703
0
        }
704
        /* Now parse through the data opening the profiles that are needed */
705
0
        curr_ptr = buffer_ptr;
706
        /* Initialize that we want color management.  Then if profile is not
707
           present we know we did not want anything special done with that
708
           source type.  Else if we have no profile and don't want color
709
           management we will make sure to do that */
710
0
        for (k = 0; k < NUM_SOURCE_PROFILES; k++) {
711
0
            srcgtag->rgb_rend_cond[k].cmm = gsCMM_DEFAULT;
712
0
            srcgtag->cmyk_rend_cond[k].cmm = gsCMM_DEFAULT;
713
0
            srcgtag->gray_rend_cond[k].cmm = gsCMM_DEFAULT;
714
0
        }
715
0
        while (start || strlen(curr_ptr) > 0) {
716
0
            if (start) {
717
0
                curr_ptr = gs_strtok(buffer_ptr, "\t, \n\r", &last);
718
0
                start = false;
719
0
            } else {
720
0
                curr_ptr = gs_strtok(NULL, "\t, \n\r", &last);
721
0
            }
722
0
            if (curr_ptr == NULL) break;
723
            /* Now go ahead and see if we have a match */
724
0
            for (k = 0; k < GSICC_NUM_SRCGTAG_KEYS; k++) {
725
0
                if (strncmp(curr_ptr, srcgtag_keys[k], strlen(srcgtag_keys[k])) == 0 ) {
726
                    /* Check if the curr_ptr is None which indicates that this
727
                       object is not to be color managed.  Also, if the
728
                       curr_ptr is Replace which indicates we will be doing
729
                       direct replacement of the colors.  */
730
0
                    curr_ptr = gs_strtok(NULL, "\t, \n\r", &last);
731
0
                    if (strncmp(curr_ptr, GSICC_SRCTAG_NOCM, strlen(GSICC_SRCTAG_NOCM)) == 0 &&
732
0
                        strlen(curr_ptr) == strlen(GSICC_SRCTAG_NOCM)) {
733
0
                        cmm = gsCMM_NONE;
734
0
                        icc_profile = NULL;
735
0
                        break;
736
0
                    } else if ((strncmp(curr_ptr, GSICC_SRCTAG_REPLACE, strlen(GSICC_SRCTAG_REPLACE)) == 0 &&
737
0
                        strlen(curr_ptr) == strlen(GSICC_SRCTAG_REPLACE))) {
738
0
                        cmm = gsCMM_REPLACE;
739
0
                        icc_profile = NULL;
740
0
                        break;
741
0
                    } else {
742
                        /* Try to open the file and set the profile */
743
0
                        code = gsicc_open_search(curr_ptr, strlen(curr_ptr), mem,
744
0
                                                 mem->gs_lib_ctx->profiledir,
745
0
                                                 mem->gs_lib_ctx->profiledir_len, &str);
746
0
                        if (code < 0)
747
0
                            return code;
748
0
                        if (str != NULL) {
749
0
                            icc_profile =
750
0
                                gsicc_profile_new(str, mem, curr_ptr, strlen(curr_ptr));
751
0
                            code = sfclose(str);
752
0
                            if (code < 0)
753
0
                                return code;
754
0
                        }
755
0
                        if (str != NULL && icc_profile != NULL) {
756
0
                            code = gsicc_init_profile_info(icc_profile);
757
0
                            if (code < 0)
758
0
                                return code;
759
0
                            cmm = gsCMM_DEFAULT;
760
                            /* Check if this object is a devicelink profile.
761
                               If it is then the intent, blackpoint etc. are not
762
                               read nor used when dealing with these profiles */
763
0
                            gsicc_check_device_link(icc_profile, icc_profile->memory);
764
0
                            break;
765
0
                        } else {
766
                            /* Failed to open profile file. End this now. */
767
0
                            gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
768
0
                            rc_decrement(srcgtag, "gsicc_set_srcgtag_struct");
769
0
                            return gs_throw1(-1,
770
0
                                    "setting of %s src obj color info failed", pname);
771
0
                        }
772
0
                    }
773
0
                }
774
0
            }
775
            /* Get the intent now and set the profile. If GSICC_SRCGTAG_KEYS
776
               order changes this switch needs to change also */
777
0
            switch (k) {
778
0
                case COLOR_TUNE:
779
                    /* Color tune profile. No intent */
780
0
                    srcgtag->color_warp_profile = icc_profile;
781
0
                    break;
782
0
                case VECTOR_CMYK:
783
0
                    srcgtag->cmyk_profiles[gsSRC_GRAPPRO] = icc_profile;
784
0
                    srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO].cmm = cmm;
785
0
                    if (cmm == gsCMM_DEFAULT) {
786
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO]), &last, true);
787
0
                        if (code < 0)
788
0
                            return code;
789
0
                    }
790
0
                    break;
791
0
                case IMAGE_CMYK:
792
0
                    srcgtag->cmyk_profiles[gsSRC_IMAGPRO] = icc_profile;
793
0
                    srcgtag->cmyk_rend_cond[gsSRC_IMAGPRO].cmm = cmm;
794
0
                    if (cmm == gsCMM_DEFAULT) {
795
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_IMAGPRO]), &last, true);
796
0
                        if (code < 0)
797
0
                            return code;
798
0
                    }
799
0
                    break;
800
0
                case TEXT_CMYK:
801
0
                    srcgtag->cmyk_profiles[gsSRC_TEXTPRO] = icc_profile;
802
0
                    srcgtag->cmyk_rend_cond[gsSRC_TEXTPRO].cmm = cmm;
803
0
                    if (cmm == gsCMM_DEFAULT) {
804
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_TEXTPRO]), &last, true);
805
0
                        if (code < 0)
806
0
                            return code;
807
0
                    }
808
0
                    break;
809
0
                case VECTOR_RGB:
810
0
                    srcgtag->rgb_profiles[gsSRC_GRAPPRO] = icc_profile;
811
0
                    srcgtag->rgb_rend_cond[gsSRC_GRAPPRO].cmm = cmm;
812
0
                    if (cmm == gsCMM_DEFAULT) {
813
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_GRAPPRO]), &last, false);
814
0
                        if (code < 0)
815
0
                            return code;
816
0
                    }
817
0
                   break;
818
0
                case IMAGE_RGB:
819
0
                    srcgtag->rgb_profiles[gsSRC_IMAGPRO] = icc_profile;
820
0
                    srcgtag->rgb_rend_cond[gsSRC_IMAGPRO].cmm = cmm;
821
0
                    if (cmm == gsCMM_DEFAULT) {
822
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_IMAGPRO]), &last, false);
823
0
                        if (code < 0)
824
0
                            return code;
825
0
                    }
826
0
                    break;
827
0
                case TEXT_RGB:
828
0
                    srcgtag->rgb_profiles[gsSRC_TEXTPRO] = icc_profile;
829
0
                    srcgtag->rgb_rend_cond[gsSRC_TEXTPRO].cmm = cmm;
830
0
                    if (cmm == gsCMM_DEFAULT) {
831
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_TEXTPRO]), &last, false);
832
0
                        if (code < 0)
833
0
                            return code;
834
0
                    }
835
0
                    break;
836
0
                case VECTOR_GRAY:
837
0
                    srcgtag->gray_profiles[gsSRC_GRAPPRO] = icc_profile;
838
0
                    srcgtag->gray_rend_cond[gsSRC_GRAPPRO].cmm = cmm;
839
0
                    if (cmm == gsCMM_DEFAULT) {
840
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_GRAPPRO]), &last, false);
841
0
                        if (code < 0)
842
0
                            return code;
843
0
                    }
844
0
                    break;
845
0
                case IMAGE_GRAY:
846
0
                    srcgtag->gray_profiles[gsSRC_IMAGPRO] = icc_profile;
847
0
                    srcgtag->gray_rend_cond[gsSRC_IMAGPRO].cmm = cmm;
848
0
                    if (cmm == gsCMM_DEFAULT) {
849
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_IMAGPRO]), &last, false);
850
0
                        if (code < 0)
851
0
                            return code;
852
0
                    }
853
0
                    break;
854
0
                case TEXT_GRAY:
855
0
                    srcgtag->gray_profiles[gsSRC_TEXTPRO] = icc_profile;
856
0
                    srcgtag->gray_rend_cond[gsSRC_TEXTPRO].cmm = cmm;
857
0
                    if (cmm == gsCMM_DEFAULT) {
858
0
                        code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_TEXTPRO]), &last, false);
859
0
                        if (code < 0)
860
0
                            return code;
861
0
                    }
862
0
                    break;
863
0
                case GSICC_NUM_SRCGTAG_KEYS:
864
                    /* Failed to match the key */
865
0
                    gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
866
0
                    rc_decrement(srcgtag, "gsicc_set_srcgtag_struct");
867
0
                    return gs_throw1(-1, "failed to find key in %s", pname);
868
0
                    break;
869
0
                default:
870
                    /* Some issue */
871
0
                    gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
872
0
                    rc_decrement(srcgtag, "gsicc_set_srcgtag_struct");
873
0
                    return gs_throw1(-1, "Error in srcgtag data %s", pname);
874
0
                    break;
875
0
            }
876
0
        }
877
0
    } else {
878
0
        return gs_throw1(-1, "setting of %s src obj color info failed", pname);
879
0
    }
880
0
    gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct");
881
0
    srcgtag->name_length = namelen;
882
0
    srcgtag->name = (char*) gs_alloc_bytes(mem, srcgtag->name_length + 1,
883
0
                                  "gsicc_set_srcgtag_struct");
884
0
    if (srcgtag->name == NULL)
885
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for tag name");
886
0
    memcpy(srcgtag->name, pname, namelen);
887
0
    srcgtag->name[namelen] = 0x00;
888
0
    icc_manager->srcgtag_profile = srcgtag;
889
0
    return 0;
890
0
}
891
892
/*  This computes the hash code for the ICC data and assigns the code and the
893
    profile to the appropriate member variable in the ICC manager */
894
int
895
gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen,
896
                  gsicc_profile_t defaulttype)
897
1.17M
{
898
1.17M
    cmm_profile_t *icc_profile;
899
1.17M
    cmm_profile_t **manager_default_profile = NULL; /* quite compiler */
900
1.17M
    stream *str;
901
1.17M
    gs_memory_t *mem_gc = icc_manager->memory;
902
1.17M
    int code;
903
1.17M
    int k;
904
1.17M
    int num_comps = 0;
905
1.17M
    gsicc_colorbuffer_t default_space; /* Used to verify that we have the correct type */
906
907
    /* We need to check for the smask swapped profile condition.  If we are in
908
       that state, then any requests for setting the profile will be ignored.
909
       This is valid, since we are in the middle of drawing right now and this
910
       only would occur if we are doing a vmreclaim while in the middle of
911
       soft mask rendering */
912
1.17M
    default_space = gsUNDEFINED;
913
1.17M
    if (icc_manager->smask_profiles !=NULL &&
914
1.17M
        icc_manager->smask_profiles->swapped == true) {
915
0
            return 0;
916
1.17M
    } else {
917
1.17M
        switch(defaulttype) {
918
293k
            case DEFAULT_GRAY:
919
293k
                manager_default_profile = &(icc_manager->default_gray);
920
293k
                default_space = gsGRAY;
921
293k
                num_comps = 1;
922
293k
                break;
923
293k
            case DEFAULT_RGB:
924
293k
                manager_default_profile = &(icc_manager->default_rgb);
925
293k
                default_space = gsRGB;
926
293k
                num_comps = 3;
927
293k
                break;
928
293k
            case DEFAULT_CMYK:
929
293k
                 manager_default_profile = &(icc_manager->default_cmyk);
930
293k
                 default_space = gsCMYK;
931
293k
                 num_comps = 4;
932
293k
                 break;
933
0
            case NAMED_TYPE:
934
0
                 manager_default_profile = &(icc_manager->device_named);
935
0
                 default_space = gsNAMED;
936
0
                 break;
937
298k
            case LAB_TYPE:
938
298k
                 manager_default_profile = &(icc_manager->lab_profile);
939
298k
                 num_comps = 3;
940
298k
                 default_space = gsCIELAB;
941
298k
                 break;
942
0
            case DEVICEN_TYPE:
943
0
                manager_default_profile = NULL;
944
0
                default_space = gsNCHANNEL;
945
0
                break;
946
0
            case DEFAULT_NONE:
947
0
            default:
948
0
                return 0;
949
0
                break;
950
1.17M
        }
951
1.17M
    }
952
    /* If it is not NULL then it has already been set. If it is different than
953
       what we already have then we will want to free it.  Since other
954
       gs_gstates could have different default profiles, this is done via reference
955
       counting.  If it is the same as what we already have then we DONT
956
       increment, since that is done when the gs_gstate is duplicated.  It
957
       could be the same, due to a resetting of the user params. To avoid
958
       recreating the profile data, we compare the string names. */
959
1.17M
    if (defaulttype != DEVICEN_TYPE && (*manager_default_profile) != NULL) {
960
        /* Check if this is what we already have.  Also check if it is the
961
           output intent profile.  */
962
138k
        icc_profile = *manager_default_profile;
963
138k
        if ( namelen == icc_profile->name_length ) {
964
138k
            if( memcmp(pname, icc_profile->name, namelen) == 0)
965
138k
                return 0;
966
138k
        }
967
0
        if (strncmp(icc_profile->name, OI_PROFILE,
968
0
                    icc_profile->name_length) == 0) {
969
0
                return 0;
970
0
        }
971
0
        gsicc_adjust_profile_rc(icc_profile, -1,"gsicc_set_profile");
972
        /* Icky - if the creation of the new profile fails, we end up with a dangling
973
           pointer, or a wrong reference count - so NULL the appropriate entry here
974
         */
975
0
        switch(defaulttype) {
976
0
            case DEFAULT_GRAY:
977
0
                icc_manager->default_gray = NULL;
978
0
                break;
979
0
            case DEFAULT_RGB:
980
0
                icc_manager->default_rgb = NULL;
981
0
                break;
982
0
            case DEFAULT_CMYK:
983
0
                 icc_manager->default_cmyk = NULL;
984
0
                 break;
985
0
            case NAMED_TYPE:
986
0
                 icc_manager->device_named = NULL;
987
0
                 break;
988
0
            case LAB_TYPE:
989
0
                 icc_manager->lab_profile = NULL;
990
0
                 break;
991
0
            default:
992
0
                break;
993
0
        }
994
0
    }
995
    /* We need to do a special check for DeviceN since we have a linked list of
996
       profiles and we can have multiple specifications */
997
1.04M
    if (defaulttype == DEVICEN_TYPE) {
998
0
        if (icc_manager->device_n != NULL) {
999
0
            gsicc_devicen_entry_t *current_entry = icc_manager->device_n->head;
1000
0
            for (k = 0; k < icc_manager->device_n->count; k++) {
1001
0
                if (current_entry->iccprofile != NULL) {
1002
0
                    icc_profile = current_entry->iccprofile;
1003
0
                    if (namelen == icc_profile->name_length)
1004
0
                    if (memcmp(pname, icc_profile->name, namelen) == 0)
1005
0
                        return 0;
1006
0
                }
1007
0
                current_entry = current_entry->next;
1008
0
            }
1009
0
        }
1010
        /* An entry was not found.  We need to create a new one to use */
1011
0
        code = gsicc_new_devicen(icc_manager);
1012
0
        if (code < 0)
1013
0
            return code;
1014
0
        manager_default_profile = &(icc_manager->device_n->final->iccprofile);
1015
0
    }
1016
1.04M
    code = gsicc_open_search(pname, namelen, mem_gc, mem_gc->gs_lib_ctx->profiledir,
1017
1.04M
                             mem_gc->gs_lib_ctx->profiledir_len, &str);
1018
1.04M
    if (code < 0)
1019
0
        return code;
1020
1.04M
    if (str != NULL) {
1021
1.04M
        icc_profile = gsicc_profile_new(str, mem_gc, pname, namelen);
1022
        /* Add check so that we detect cases where we are loading a named
1023
           color structure that is not a standard profile type */
1024
1.04M
        if (icc_profile == NULL && defaulttype == NAMED_TYPE) {
1025
            /* Failed to load the named color profile.  Just load the file
1026
               into the buffer as it is.  The profile_handle member
1027
               variable can then be used to hold the named color
1028
               structure that is actually search. This is created later
1029
               when needed. */
1030
0
            char *nameptr;
1031
1032
0
            icc_profile = gsicc_profile_new(NULL, mem_gc, NULL, 0);
1033
0
            if (icc_profile == NULL)
1034
0
                return gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1035
0
            icc_profile->data_cs = gsNAMED;
1036
0
            code = gsicc_load_namedcolor_buffer(icc_profile, str, mem_gc);
1037
0
            if (code < 0) return gs_throw1(-1, "problems with profile %s", pname);
1038
0
            *manager_default_profile = icc_profile;
1039
0
            nameptr = (char*) gs_alloc_bytes(icc_profile->memory, namelen+1,
1040
0
                                             "gsicc_set_profile");
1041
0
            if (nameptr == NULL)
1042
0
                return gs_throw(gs_error_VMerror, "Insufficient memory for profile name");
1043
0
            memcpy(nameptr, pname, namelen);
1044
0
            nameptr[namelen] = '\0';
1045
0
            icc_profile->name = nameptr;
1046
0
            icc_profile->name_length = namelen;
1047
0
            return 0;  /* Done now, since this is not a standard ICC profile */
1048
0
        }
1049
1.04M
        code = sfclose(str);
1050
1.04M
        if (icc_profile == NULL) {
1051
0
            return gs_throw1(-1, "problems with profile %s",pname);
1052
0
        }
1053
1.04M
         *manager_default_profile = icc_profile;
1054
1.04M
        icc_profile->default_match = defaulttype;
1055
1.04M
        if (defaulttype == LAB_TYPE)
1056
260k
            icc_profile->islab = true;
1057
1.04M
        if ( defaulttype == DEVICEN_TYPE ) {
1058
            /* Lets get the name information out of the profile.
1059
               The names are contained in the icSigNamedColor2Tag
1060
               item.  The table is in the A2B0Tag item.
1061
               The names are in the order such that the fastest
1062
               index in the table is the first name */
1063
0
            gsicc_get_devicen_names(icc_profile, icc_manager->memory);
1064
            /* Init this profile now */
1065
0
            code = gsicc_init_profile_info(icc_profile);
1066
0
            if (code < 0) return gs_throw1(-1, "problems with profile %s", pname);
1067
1.04M
        } else {
1068
            /* Delay the loading of the handle buffer until we need the profile.
1069
               But set some basic stuff that we need. Take care of DeviceN
1070
               profile now, since we don't know the number of components etc */
1071
1.04M
            icc_profile->num_comps = num_comps;
1072
1.04M
            icc_profile->num_comps_out = 3;
1073
1.04M
            gsicc_set_icc_range(&icc_profile);
1074
1.04M
            icc_profile->data_cs = default_space;
1075
1.04M
        }
1076
1.04M
        return 0;
1077
1.04M
    }
1078
0
    return -1;
1079
1.04M
}
1080
1081
/* This is used ONLY for delayed initialization of the "default" ICC profiles
1082
   that are in the ICC manager.  This way we avoid getting these profile handles
1083
   until we actually need them. Note that defaulttype is preset.  These are
1084
   the *only* profiles that are delayed in this manner.  All embedded profiles
1085
   and internally generated profiles have their handles found immediately */
1086
int
1087
gsicc_initialize_default_profile(cmm_profile_t *icc_profile)
1088
19.8k
{
1089
19.8k
    gsicc_profile_t defaulttype = icc_profile->default_match;
1090
19.8k
    gsicc_colorbuffer_t default_space = gsUNDEFINED;
1091
19.8k
    int num_comps, num_comps_out;
1092
19.8k
    gs_memory_t *mem = icc_profile->memory;
1093
1094
    /* Get the profile handle if it is not already set */
1095
19.8k
    if (icc_profile->profile_handle == NULL) {
1096
0
        icc_profile->profile_handle =
1097
0
                        gsicc_get_profile_handle_buffer(icc_profile->buffer,
1098
0
                                                        icc_profile->buffer_size,
1099
0
                                                        mem);
1100
0
        if (icc_profile->profile_handle == NULL) {
1101
0
            return gs_rethrow1(gs_error_VMerror, "allocation of profile %s handle failed",
1102
0
                               icc_profile->name);
1103
0
        }
1104
0
    }
1105
19.8k
    if (icc_profile->buffer != NULL && icc_profile->hash_is_valid == false) {
1106
        /* Compute the hash code of the profile. */
1107
0
        gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode),
1108
0
                                icc_profile->buffer_size);
1109
0
        icc_profile->hash_is_valid = true;
1110
0
    }
1111
19.8k
    num_comps = icc_profile->num_comps;
1112
19.8k
    icc_profile->num_comps =
1113
19.8k
        gscms_get_input_channel_count(icc_profile->profile_handle,
1114
19.8k
            icc_profile->memory);
1115
19.8k
    num_comps_out = icc_profile->num_comps_out;
1116
19.8k
    icc_profile->num_comps_out =
1117
19.8k
        gscms_get_output_channel_count(icc_profile->profile_handle,
1118
19.8k
            icc_profile->memory);
1119
19.8k
    icc_profile->data_cs =
1120
19.8k
        gscms_get_profile_data_space(icc_profile->profile_handle,
1121
19.8k
            icc_profile->memory);
1122
19.8k
    if_debug0m(gs_debug_flag_icc,mem,"[icc] Setting ICC profile in Manager\n");
1123
19.8k
    switch(defaulttype) {
1124
16.3k
        case DEFAULT_GRAY:
1125
16.3k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default Gray\n");
1126
16.3k
            default_space = gsGRAY;
1127
16.3k
            break;
1128
2.76k
        case DEFAULT_RGB:
1129
2.76k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default RGB\n");
1130
2.76k
            default_space = gsRGB;
1131
2.76k
            break;
1132
555
        case DEFAULT_CMYK:
1133
555
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default CMYK\n");
1134
555
            default_space = gsCMYK;
1135
555
             break;
1136
0
        case NAMED_TYPE:
1137
0
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Named Color\n");
1138
0
            break;
1139
14
        case LAB_TYPE:
1140
14
            if_debug0m(gs_debug_flag_icc,mem,"[icc] CIELAB Profile\n");
1141
14
            break;
1142
0
        case DEVICEN_TYPE:
1143
0
            if_debug0m(gs_debug_flag_icc,mem,"[icc] DeviceN Profile\n");
1144
0
            break;
1145
0
        case DEFAULT_NONE:
1146
113
        default:
1147
113
            return 0;
1148
0
            break;
1149
19.8k
    }
1150
19.8k
    if_debug1m(gs_debug_flag_icc,mem,"[icc] name = %s\n", icc_profile->name);
1151
19.6k
    if_debug1m(gs_debug_flag_icc,mem,"[icc] num_comps = %d\n", icc_profile->num_comps);
1152
    /* Check that we have the proper color space for the ICC
1153
       profiles that can be externally set */
1154
19.6k
    if (default_space != gsUNDEFINED ||
1155
19.6k
        num_comps != icc_profile->num_comps ||
1156
19.6k
        num_comps_out != icc_profile->num_comps_out) {
1157
19.6k
        if (icc_profile->data_cs != default_space) {
1158
0
            return gs_rethrow(-1, "A default profile has an incorrect color space");
1159
0
        }
1160
19.6k
    }
1161
19.6k
    return 0;
1162
19.6k
}
1163
1164
/* This is used to get the profile handle given a file name  */
1165
cmm_profile_t*
1166
gsicc_get_profile_handle_file(const char* pname, int namelen, gs_memory_t *mem)
1167
342
{
1168
342
    cmm_profile_t *result;
1169
342
    stream* str;
1170
342
    int code;
1171
1172
    /* First see if we can get the stream. */
1173
342
    code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
1174
342
        mem->gs_lib_ctx->profiledir_len, &str);
1175
342
    if (code < 0 || str == NULL) {
1176
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1177
0
        return NULL;
1178
0
    }
1179
342
    result = gsicc_profile_new(str, mem, pname, namelen);
1180
342
    code = sfclose(str);
1181
342
    if (result == NULL) {
1182
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1183
0
        return NULL;
1184
0
    }
1185
342
    code = gsicc_init_profile_info(result);
1186
342
    if (code < 0) {
1187
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1188
0
        return NULL;
1189
0
    }
1190
342
    return result;
1191
342
}
1192
1193
/* Given that we already have a profile in a buffer (e.g. generated from a PS object)
1194
   this gets the handle and initializes the various member variables that we need */
1195
int
1196
gsicc_init_profile_info(cmm_profile_t *profile)
1197
342
{
1198
342
    int k;
1199
1200
    /* Get the profile handle */
1201
342
    profile->profile_handle =
1202
342
        gsicc_get_profile_handle_buffer(profile->buffer,
1203
342
                                        profile->buffer_size,
1204
342
                                        profile->memory);
1205
342
    if (profile->profile_handle == NULL)
1206
0
        return -1;
1207
1208
    /* Compute the hash code of the profile. */
1209
342
    gsicc_get_icc_buff_hash(profile->buffer, &(profile->hashcode),
1210
342
                            profile->buffer_size);
1211
342
    profile->hash_is_valid = true;
1212
342
    profile->default_match = DEFAULT_NONE;
1213
342
    profile->num_comps = gscms_get_input_channel_count(profile->profile_handle,
1214
342
        profile->memory);
1215
342
    profile->num_comps_out = gscms_get_output_channel_count(profile->profile_handle,
1216
342
        profile->memory);
1217
342
    profile->data_cs = gscms_get_profile_data_space(profile->profile_handle,
1218
342
        profile->memory);
1219
1220
    /* Initialize the range to default values */
1221
884
    for ( k = 0; k < profile->num_comps; k++) {
1222
542
        profile->Range.ranges[k].rmin = 0.0;
1223
542
        profile->Range.ranges[k].rmax = 1.0;
1224
542
    }
1225
342
    return 0;
1226
342
}
1227
1228
/* This is used to try to find the specified or default ICC profiles */
1229
/* This is where we would enhance the directory searching to use a   */
1230
/* list of paths separated by ':' (unix) or ';' Windows              */
1231
int
1232
gsicc_open_search(const char* pname, int namelen, gs_memory_t *mem_gc,
1233
                  const char* dirname, int dirlen, stream**strp)
1234
1.06M
{
1235
1.06M
    char *buffer;
1236
1.06M
    stream* str;
1237
1238
    /* Check if we need to prepend the file name  */
1239
1.06M
    if ( dirname != NULL) {
1240
        /* If this fails, we will still try the file by itself and with
1241
           %rom% since someone may have left a space some of the spaces
1242
           as our defaults, even if they defined the directory to use.
1243
           This will occur only after searching the defined directory.
1244
           A warning is noted.  */
1245
1.06M
        buffer = (char *) gs_alloc_bytes(mem_gc, namelen + dirlen + 1,
1246
1.06M
                                     "gsicc_open_search");
1247
1.06M
        if (buffer == NULL)
1248
0
            return_error(gs_error_VMerror);
1249
1.06M
        memcpy(buffer, dirname, dirlen);
1250
1.06M
        memcpy(buffer + dirlen, pname, namelen);
1251
        /* Just to make sure we were null terminated */
1252
1.06M
        buffer[namelen + dirlen] = '\0';
1253
1254
1.06M
        if (gs_check_file_permission(mem_gc, buffer, strlen(buffer), "r") >= 0) {
1255
1.06M
            str = sfopen(buffer, "r", mem_gc);
1256
1.06M
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1257
1.06M
            if (str != NULL) {
1258
1.06M
                *strp = str;
1259
1.06M
                return 0;
1260
1.06M
            }
1261
1.06M
        }
1262
0
        else {
1263
0
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1264
0
        }
1265
1.06M
    }
1266
1267
    /* First just try it like it is */
1268
0
    if (gs_check_file_permission(mem_gc, pname, namelen, "r") >= 0) {
1269
0
        char CFileName[gp_file_name_sizeof];
1270
1271
0
        if (namelen + 1 > gp_file_name_sizeof)
1272
0
            return_error(gs_error_ioerror);
1273
0
        memcpy(CFileName, pname, namelen);
1274
0
        CFileName[namelen] = 0x00;
1275
1276
0
        str = sfopen(CFileName, "r", mem_gc);
1277
0
        if (str != NULL) {
1278
0
            *strp = str;
1279
0
            return 0;
1280
0
        }
1281
0
    }
1282
1283
    /* If that fails, try %rom% */ /* FIXME: Not sure this is needed or correct */
1284
                                   /* A better approach might be to have built in defaults */
1285
0
    buffer = (char *) gs_alloc_bytes(mem_gc, 1 + namelen +
1286
0
                        strlen(DEFAULT_DIR_ICC),"gsicc_open_search");
1287
0
    if (buffer == NULL)
1288
0
        return_error(gs_error_VMerror);
1289
0
    strcpy(buffer, DEFAULT_DIR_ICC);
1290
0
    memcpy(buffer + strlen(DEFAULT_DIR_ICC), pname, namelen);
1291
    /* Just to make sure we were null terminated */
1292
0
    buffer[namelen + strlen(DEFAULT_DIR_ICC)] = '\0';
1293
0
    str = sfopen(buffer, "r", mem_gc);
1294
0
    gs_free_object(mem_gc, buffer, "gsicc_open_search");
1295
0
    if (str == NULL) {
1296
0
        gs_warn1("Could not find %s ",pname);
1297
0
    }
1298
0
    *strp = str;
1299
0
    return 0;
1300
0
}
1301
1302
/* Free source object icc array structure.  */
1303
static void
1304
rc_free_srcgtag_profile(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1305
0
{
1306
0
    cmm_srcgtag_profile_t *srcgtag_profile = (cmm_srcgtag_profile_t *)ptr_in;
1307
0
    int k;
1308
0
    gs_memory_t *mem_nongc =  srcgtag_profile->memory;
1309
1310
0
    if (srcgtag_profile->rc.ref_count <= 1 ) {
1311
        /* Decrement any profiles. */
1312
0
        for (k = 0; k < NUM_SOURCE_PROFILES; k++) {
1313
0
            if (srcgtag_profile->gray_profiles[k] != NULL) {
1314
0
                gsicc_adjust_profile_rc(srcgtag_profile->gray_profiles[k], -1,
1315
0
                    "rc_free_srcgtag_profile(gray)");
1316
0
            }
1317
0
            if (srcgtag_profile->rgb_profiles[k] != NULL) {
1318
0
                gsicc_adjust_profile_rc(srcgtag_profile->rgb_profiles[k], -1,
1319
0
                             "rc_free_srcgtag_profile(rgb)");
1320
0
            }
1321
0
            if (srcgtag_profile->cmyk_profiles[k] != NULL) {
1322
0
                gsicc_adjust_profile_rc(srcgtag_profile->cmyk_profiles[k], -1,
1323
0
                             "rc_free_srcgtag_profile(cmyk)");
1324
0
            }
1325
0
            if (srcgtag_profile->color_warp_profile != NULL) {
1326
0
                gsicc_adjust_profile_rc(srcgtag_profile->color_warp_profile, -1,
1327
0
                             "rc_free_srcgtag_profile(warp)");
1328
0
            }
1329
0
        }
1330
0
        gs_free_object(mem_nongc, srcgtag_profile->name, "rc_free_srcgtag_profile");
1331
0
        gs_free_object(mem_nongc, srcgtag_profile, "rc_free_srcgtag_profile");
1332
0
    }
1333
0
}
1334
1335
/* Allocate source object icc structure. */
1336
static cmm_srcgtag_profile_t*
1337
gsicc_new_srcgtag_profile(gs_memory_t *memory)
1338
0
{
1339
0
    cmm_srcgtag_profile_t *result;
1340
0
    int k;
1341
1342
0
    result = (cmm_srcgtag_profile_t *) gs_alloc_bytes(memory->non_gc_memory,
1343
0
                                            sizeof(cmm_srcgtag_profile_t),
1344
0
                                            "gsicc_new_srcgtag_profile");
1345
0
    if (result == NULL)
1346
0
        return NULL;
1347
0
    result->memory = memory->non_gc_memory;
1348
1349
0
    for (k = 0; k < NUM_SOURCE_PROFILES; k++) {
1350
0
        result->rgb_profiles[k] = NULL;
1351
0
        result->cmyk_profiles[k] = NULL;
1352
0
        result->gray_profiles[k] = NULL;
1353
0
        result->gray_rend_cond[k].black_point_comp = gsBPNOTSPECIFIED;
1354
0
        result->gray_rend_cond[k].rendering_intent = gsRINOTSPECIFIED;
1355
0
        result->gray_rend_cond[k].override_icc = false;
1356
0
        result->gray_rend_cond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1357
0
        result->gray_rend_cond[k].cmm = gsCMM_DEFAULT;
1358
0
        result->rgb_rend_cond[k].black_point_comp = gsBPNOTSPECIFIED;
1359
0
        result->rgb_rend_cond[k].rendering_intent = gsRINOTSPECIFIED;
1360
0
        result->rgb_rend_cond[k].override_icc = false;
1361
0
        result->rgb_rend_cond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1362
0
        result->rgb_rend_cond[k].cmm = gsCMM_DEFAULT;
1363
0
        result->cmyk_rend_cond[k].black_point_comp = gsBPNOTSPECIFIED;
1364
0
        result->cmyk_rend_cond[k].rendering_intent = gsRINOTSPECIFIED;
1365
0
        result->cmyk_rend_cond[k].override_icc = false;
1366
0
        result->cmyk_rend_cond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1367
0
        result->cmyk_rend_cond[k].cmm = gsCMM_DEFAULT;
1368
0
    }
1369
0
    result->color_warp_profile = NULL;
1370
0
    result->name = NULL;
1371
0
    result->name_length = 0;
1372
0
    rc_init_free(result, memory->non_gc_memory, 1, rc_free_srcgtag_profile);
1373
0
    return result;
1374
0
}
1375
1376
static void
1377
gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem)
1378
0
{
1379
0
    int k;
1380
0
    gsicc_colorname_t *curr_name, *next_name;
1381
1382
0
    curr_name = spotnames->head;
1383
0
    for (k = 0; k < spotnames->count; k++) {
1384
0
        next_name = curr_name->next;
1385
        /* Free the name */
1386
0
        gs_free_object(mem, curr_name->name, "gsicc_free_spotnames");
1387
        /* Free the name structure */
1388
0
        gs_free_object(mem, curr_name, "gsicc_free_spotnames");
1389
0
        curr_name = next_name;
1390
0
    }
1391
0
    if (spotnames->color_map != NULL) {
1392
0
        gs_free_object(mem, spotnames->color_map, "gsicc_free_spotnames");
1393
0
    }
1394
0
    if (spotnames->name_str != NULL) {
1395
0
        gs_free_object(mem, spotnames->name_str, "gsicc_free_spotnames");
1396
0
    }
1397
0
}
1398
1399
/* Free device icc array structure.  */
1400
static void
1401
rc_free_profile_array(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1402
201k
{
1403
201k
    cmm_dev_profile_t *icc_struct = (cmm_dev_profile_t *)ptr_in;
1404
201k
    int k;
1405
201k
    gs_memory_t *mem_nongc =  icc_struct->memory;
1406
1407
201k
    if (icc_struct->rc.ref_count <= 1 ) {
1408
        /* Decrement any profiles. */
1409
1.00M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1410
806k
            if (icc_struct->device_profile[k] != NULL) {
1411
190k
                if_debug1m(gs_debug_flag_icc, mem_nongc,
1412
190k
                           "[icc] Releasing device profile %d\n", k);
1413
190k
                gsicc_adjust_profile_rc(icc_struct->device_profile[k], -1,
1414
190k
                             "rc_free_profile_array");
1415
190k
            }
1416
806k
        }
1417
201k
        if (icc_struct->link_profile != NULL) {
1418
0
            if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing link profile\n");
1419
0
            gsicc_adjust_profile_rc(icc_struct->link_profile, -1, "rc_free_profile_array");
1420
0
        }
1421
201k
        if (icc_struct->proof_profile != NULL) {
1422
0
            if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing proof profile\n");
1423
0
            gsicc_adjust_profile_rc(icc_struct->proof_profile, -1, "rc_free_profile_array");
1424
0
        }
1425
201k
        if (icc_struct->oi_profile != NULL) {
1426
0
            if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing oi profile\n");
1427
0
            gsicc_adjust_profile_rc(icc_struct->oi_profile, -1, "rc_free_profile_array");
1428
0
        }
1429
201k
        if (icc_struct->postren_profile != NULL) {
1430
0
            if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing postren profile\n");
1431
0
            gsicc_adjust_profile_rc(icc_struct->postren_profile, -1, "rc_free_profile_array");
1432
0
        }
1433
201k
        if (icc_struct->blend_profile != NULL) {
1434
0
            if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing blend profile\n");
1435
0
            gsicc_adjust_profile_rc(icc_struct->blend_profile, -1, "rc_free_profile_array");
1436
0
        }
1437
201k
        if (icc_struct->spotnames != NULL) {
1438
0
            if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing spotnames\n");
1439
            /* Free the linked list in this object */
1440
0
            gsicc_free_spotnames(icc_struct->spotnames, mem_nongc);
1441
            /* Free the main object */
1442
0
            gs_free_object(mem_nongc, icc_struct->spotnames, "rc_free_profile_array");
1443
0
        }
1444
201k
        if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing device profile struct\n");
1445
201k
        gs_free_object(mem_nongc, icc_struct, "rc_free_profile_array");
1446
201k
    }
1447
201k
}
1448
1449
/* Allocate device icc structure. The actual profiles are in this structure */
1450
cmm_dev_profile_t*
1451
gsicc_new_device_profile_array(gx_device *dev)
1452
201k
{
1453
201k
    cmm_dev_profile_t *result;
1454
201k
    int k;
1455
201k
    gs_memory_t *memory = dev->memory;
1456
1457
201k
    if_debug0m(gs_debug_flag_icc,memory,"[icc] Allocating device profile struct\n");
1458
201k
    result = (cmm_dev_profile_t *) gs_alloc_bytes(memory->non_gc_memory,
1459
201k
                                            sizeof(cmm_dev_profile_t),
1460
201k
                                            "gsicc_new_device_profile_array");
1461
201k
    if (result == NULL)
1462
0
        return NULL;
1463
201k
    result->memory = memory->non_gc_memory;
1464
1465
1.00M
    for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1466
806k
        result->device_profile[k] = NULL;
1467
806k
        result->rendercond[k].rendering_intent = gsRINOTSPECIFIED;
1468
806k
        result->rendercond[k].black_point_comp = gsBPNOTSPECIFIED;
1469
806k
        result->rendercond[k].override_icc = false;
1470
806k
        result->rendercond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1471
806k
        result->rendercond[k].graphics_type_tag = GS_UNKNOWN_TAG;
1472
806k
        result->rendercond[k].cmm = gsCMM_DEFAULT;
1473
806k
    }
1474
201k
    result->proof_profile = NULL;
1475
201k
    result->link_profile = NULL;
1476
201k
    result->postren_profile = NULL;
1477
201k
    result->blend_profile = NULL;
1478
201k
    result->oi_profile = NULL;
1479
201k
    result->spotnames = NULL;
1480
201k
    result->devicegraytok = true;  /* Default is to map gray to pure K */
1481
201k
    result->graydetection = false;
1482
201k
    result->pageneutralcolor = false;
1483
201k
    result->usefastcolor = false;  /* Default is to not use fast color */
1484
201k
    result->blacktext = false;
1485
201k
    result->blackvector = false;
1486
201k
    result->blackthresholdL = 90.0F;
1487
201k
    result->blackthresholdC = 0.0F;
1488
201k
    result->prebandthreshold = true;
1489
201k
    result->supports_devn = false;
1490
201k
    result->overprint_control = gs_overprint_control_enable;  /* Default overprint if the device can */
1491
201k
    rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array);
1492
201k
    return result;
1493
201k
}
1494
1495
int
1496
gsicc_set_device_blackpreserve(gx_device *dev, gsicc_blackpreserve_t blackpreserve,
1497
                                gsicc_profile_types_t profile_type)
1498
316k
{
1499
316k
    int code;
1500
316k
    cmm_dev_profile_t *profile_struct;
1501
1502
    /* Although device methods should not be NULL, they are not completely filled in until
1503
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1504
     * happens, so we *must* make sure the method is not NULL before we use it.
1505
     */
1506
316k
    if (dev_proc(dev, get_profile) == NULL) {
1507
173k
        profile_struct = dev->icc_struct;
1508
173k
    } else {
1509
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1510
143k
        if (code < 0)
1511
0
            return code;
1512
143k
    }
1513
316k
    if (profile_struct ==  NULL)
1514
0
        return 0;
1515
316k
    profile_struct->rendercond[profile_type].preserve_black = blackpreserve;
1516
316k
    return 0;
1517
316k
}
1518
1519
int
1520
gsicc_set_device_profile_intent(gx_device *dev, gsicc_rendering_intents_t intent,
1521
                                gsicc_profile_types_t profile_type)
1522
316k
{
1523
316k
    int code;
1524
316k
    cmm_dev_profile_t *profile_struct;
1525
1526
    /* Although device methods should not be NULL, they are not completely filled in until
1527
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1528
     * happens, so we *must* make sure the method is not NULL before we use it.
1529
     */
1530
316k
    if (dev_proc(dev, get_profile) == NULL) {
1531
173k
        profile_struct = dev->icc_struct;
1532
173k
    } else {
1533
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1534
143k
        if (code < 0)
1535
0
            return code;
1536
143k
    }
1537
316k
    if (profile_struct ==  NULL)
1538
0
        return 0;
1539
316k
    profile_struct->rendercond[profile_type].rendering_intent = intent;
1540
316k
    return 0;
1541
316k
}
1542
1543
int
1544
gsicc_set_device_blackptcomp(gx_device *dev, gsicc_blackptcomp_t blackptcomp,
1545
                                gsicc_profile_types_t profile_type)
1546
316k
{
1547
316k
    int code = 0;
1548
316k
    cmm_dev_profile_t *profile_struct;
1549
1550
    /* Although device methods should not be NULL, they are not completely filled in until
1551
     * gx_device_fill_in_procs is called, and its possible for us to get here before this
1552
     * happens, so we *must* make sure the method is not NULL before we use it.
1553
     */
1554
316k
    if (dev_proc(dev, get_profile) == NULL) {
1555
173k
        profile_struct = dev->icc_struct;
1556
173k
    } else {
1557
143k
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1558
143k
    }
1559
316k
    if (profile_struct ==  NULL)
1560
0
        return 0;
1561
316k
    profile_struct->rendercond[profile_type].black_point_comp = blackptcomp;
1562
316k
    return code;
1563
316k
}
1564
1565
/* This is used to set up the equivalent cmyk colors for the spots that may
1566
   exist in an output DeviceN profile.  We do this by faking a new separation
1567
   space for each one */
1568
int
1569
gsicc_set_devicen_equiv_colors(gx_device *dev, const gs_gstate * pgs,
1570
                               cmm_profile_t *profile)
1571
0
{
1572
0
    gs_gstate temp_state = *((gs_gstate*)pgs);
1573
0
    gs_color_space *pcspace = gs_cspace_alloc(pgs->memory->non_gc_memory,
1574
0
                                              &gs_color_space_type_ICC);
1575
0
    if (pcspace == NULL)
1576
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for devn equiv colors");
1577
0
    pcspace->cmm_icc_profile_data = profile;
1578
0
    temp_state.color[0].color_space = pcspace;
1579
0
    return dev_proc(dev, update_spot_equivalent_colors)(dev, &temp_state, pcspace);
1580
0
}
1581
1582
0
#define DEFAULT_ICC_PROCESS "Cyan, Magenta, Yellow, Black,"
1583
0
#define DEFAULT_ICC_PROCESS_LENGTH 30
1584
#define DEFAULT_ICC_COLORANT_NAME "ICC_COLOR_"
1585
0
#define DEFAULT_ICC_COLORANT_LENGTH 12
1586
/* allow at most 16 colorants */
1587
/* This sets the colorants structure up in the device profile for when
1588
   we are dealing with DeviceN type output profiles.  Note
1589
   that this feature is only used with the tiffsep and psdcmyk devices.
1590
   If name_str is null it will use default names for the colorants */
1591
int
1592
gsicc_set_device_profile_colorants(gx_device *dev, char *name_str)
1593
0
{
1594
0
    int code;
1595
0
    cmm_dev_profile_t *profile_struct;
1596
0
    gsicc_colorname_t *name_entry;
1597
0
    gsicc_colorname_t **curr_entry;
1598
0
    gs_memory_t *mem;
1599
0
    char *temp_ptr, *last = NULL;
1600
0
    int done;
1601
0
    gsicc_namelist_t *spot_names;
1602
0
    char *pch;
1603
0
    int str_len;
1604
0
    int k;
1605
0
    bool free_str = false;
1606
1607
0
    code = dev_proc(dev, get_profile)((gx_device *)dev, &profile_struct);
1608
0
    if (profile_struct != NULL) {
1609
0
        if (name_str == NULL) {
1610
            /* Create a default name string that we can use */
1611
0
            int total_len;
1612
0
            int kk;
1613
0
            int num_comps = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
1614
0
            char temp_str[DEFAULT_ICC_COLORANT_LENGTH+2];
1615
1616
            /* If names are already set then we do not want to set default ones */
1617
0
            if (profile_struct->spotnames != NULL) {
1618
                /* Check if we have at least as many spot names
1619
                   as there are channels in the proFfile */
1620
0
                if (num_comps > profile_struct->spotnames->count) {
1621
0
                    gs_warn("ICC profile colorant names count insufficient");
1622
0
                    return_error(gs_error_rangecheck);
1623
0
                } else
1624
0
                    return 0;
1625
0
            }
1626
1627
0
            free_str = true;
1628
            /* Assume first 4 are CMYK */
1629
0
            total_len = ((DEFAULT_ICC_COLORANT_LENGTH + 1) * (num_comps-4)) +
1630
0
                        DEFAULT_ICC_PROCESS_LENGTH - 1;  /* -1 due to no comma at end */
1631
0
            name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1,
1632
0
                                               "gsicc_set_device_profile_colorants");
1633
0
            if (name_str == NULL)
1634
0
                return gs_throw(gs_error_VMerror, "Insufficient memory for colorant name");
1635
0
            gs_snprintf(name_str, total_len+1, DEFAULT_ICC_PROCESS);
1636
0
            for (kk = 0; kk < num_comps-5; kk++) {
1637
0
                gs_snprintf(temp_str,sizeof(temp_str),"ICC_COLOR_%d,",kk);
1638
0
                strcat(name_str,temp_str);
1639
0
            }
1640
            /* Last one no comma */
1641
0
            gs_snprintf(temp_str,sizeof(temp_str),"ICC_COLOR_%d",kk);
1642
0
            strcat(name_str,temp_str);
1643
0
        }
1644
0
        str_len = strlen(name_str);
1645
0
        if (profile_struct->spotnames != NULL &&
1646
0
            profile_struct->spotnames->name_str != NULL &&
1647
0
            strlen(profile_struct->spotnames->name_str) == str_len) {
1648
            /* Here we check if the names are the same */
1649
0
            if (strncmp(name_str, profile_struct->spotnames->name_str, str_len) == 0) {
1650
0
                if (free_str)
1651
0
                    gs_free_object(dev->memory, name_str,
1652
0
                                            "gsicc_set_device_profile_colorants");
1653
0
                return 0;
1654
0
            }
1655
0
        }
1656
0
        mem = dev->memory->non_gc_memory;
1657
        /* We need to free the existing one if there was one */
1658
0
        if (profile_struct->spotnames != NULL) {
1659
            /* Free the linked list in this object */
1660
0
            gsicc_free_spotnames(profile_struct->spotnames, mem);
1661
            /* Free the main object */
1662
0
            gs_free_object(mem, profile_struct->spotnames,
1663
0
                           "gsicc_set_device_profile_colorants");
1664
0
        }
1665
        /* Allocate structure for managing names */
1666
0
        spot_names = gsicc_new_namelist(mem);
1667
0
        if (spot_names == 0)
1668
0
            return gs_throw(gs_error_VMerror, "Insufficient memory for spot name");
1669
1670
0
        profile_struct->spotnames = spot_names;
1671
0
        spot_names->name_str = (char*) gs_alloc_bytes(mem, str_len+1,
1672
0
                                               "gsicc_set_device_profile_colorants");
1673
0
        if (spot_names->name_str == NULL)
1674
0
            return gs_throw(gs_error_VMerror, "Insufficient memory for spot name");
1675
0
        memcpy(spot_names->name_str, name_str, strlen(name_str));
1676
0
        spot_names->name_str[str_len] = 0;
1677
0
        curr_entry = &(spot_names->head);
1678
         /* Go ahead and tokenize now */
1679
0
        pch = gs_strtok(name_str, ",", &last);
1680
1681
0
        while (pch != NULL) {
1682
0
            if (spot_names->count == GS_CLIENT_COLOR_MAX_COMPONENTS)
1683
0
                return gs_throw(gs_error_rangecheck, "Too many spot names");
1684
1685
0
            temp_ptr = pch;
1686
0
            done = 0;
1687
            /* Remove any leading spaces */
1688
0
            while (!done) {
1689
0
                if (*temp_ptr == 0x20) {
1690
0
                    temp_ptr++;
1691
0
                } else {
1692
0
                    done = 1;
1693
0
                }
1694
0
            }
1695
            /* Allocate a new name object */
1696
0
            name_entry = gsicc_new_colorname(mem);
1697
0
            if (name_entry == NULL)
1698
0
                return gs_throw(gs_error_VMerror, "Insufficient memory for spot name");
1699
            /* Set our current entry to this one */
1700
0
            *curr_entry = name_entry;
1701
0
            spot_names->count += 1;
1702
0
            name_entry->length = strlen(temp_ptr);
1703
0
            name_entry->name = (char *) gs_alloc_bytes(mem, name_entry->length,
1704
0
                                        "gsicc_set_device_profile_colorants");
1705
0
            if (name_entry->name == NULL)
1706
0
                return gs_throw(gs_error_VMerror, "Insufficient memory for spot name");
1707
0
            memcpy(name_entry->name, temp_ptr, name_entry->length);
1708
            /* Get the next entry location */
1709
0
            curr_entry = &((*curr_entry)->next);
1710
0
            pch = gs_strtok(NULL, ",", &last);
1711
0
        }
1712
        /* Create the color map.  Query the device to find out where these
1713
           colorants are located.   It is possible that the device may
1714
           not be opened yet.  In which case, we need to make sure that
1715
           when it is opened that it checks this entry and gets itself
1716
           properly initialized if it is a separation device. */
1717
0
        spot_names->color_map =
1718
0
            (gs_devicen_color_map*) gs_alloc_bytes(mem,
1719
0
                                                   sizeof(gs_devicen_color_map),
1720
0
                                                   "gsicc_set_device_profile_colorants");
1721
0
        if (spot_names->color_map == NULL)
1722
0
            return gs_throw(gs_error_VMerror, "Insufficient memory for spot color map");
1723
0
        spot_names->color_map->num_colorants = spot_names->count;
1724
0
        spot_names->color_map->num_components = spot_names->count;
1725
1726
0
        name_entry = spot_names->head;
1727
0
        for (k = 0; k < spot_names->count; k++) {
1728
0
            int colorant_number = (*dev_proc(dev, get_color_comp_index))
1729
0
                    (dev, (const char *)name_entry->name, name_entry->length,
1730
0
                     SEPARATION_NAME);
1731
0
            name_entry = name_entry->next;
1732
0
            spot_names->color_map->color_map[k] = colorant_number;
1733
0
        }
1734
        /* We need to set the equivalent CMYK color for this colorant.  This is
1735
           done by faking out the update spot equivalent call with a special
1736
           gs_gstate and color space that makes it seem like the
1737
           spot color is a separation color space.  Unfortunately, we need the
1738
           graphic state to do this so we save it for later when we try to do
1739
           our first mapping.  We then use this flag to know if we did it yet */
1740
0
        spot_names->equiv_cmyk_set = false;
1741
0
        if (free_str)
1742
0
            gs_free_object(dev->memory, name_str,
1743
0
                           "gsicc_set_device_profile_colorants");
1744
0
    }
1745
0
    return code;
1746
0
}
1747
1748
/* This sets the device profiles. If the device does not have a defined
1749
   profile, then a default one is selected. */
1750
int
1751
gsicc_init_device_profile_struct(gx_device * dev,
1752
                                 char *profile_name,
1753
                                 gsicc_profile_types_t profile_type)
1754
9.85k
{
1755
9.85k
    int code;
1756
9.85k
    cmm_profile_t *curr_profile;
1757
9.85k
    cmm_dev_profile_t *profile_struct;
1758
1759
    /* See if the device has a profile structure.  If it does, then do a
1760
       check to see if the profile that we are trying to set is already
1761
       set and the same.  If it is not, then we need to free it and then
1762
       reset. */
1763
9.85k
    profile_struct = dev->icc_struct;
1764
9.85k
    if (profile_struct != NULL) {
1765
        /* Get the profile of interest */
1766
4.29k
        if (profile_type < gsPROOFPROFILE) {
1767
4.29k
            curr_profile = profile_struct->device_profile[profile_type];
1768
4.29k
        } else {
1769
            /* The proof, link profile or post render */
1770
0
            if (profile_type == gsPROOFPROFILE) {
1771
0
                curr_profile = profile_struct->proof_profile;
1772
0
            } else if (profile_type == gsLINKPROFILE) {
1773
0
                curr_profile = profile_struct->link_profile;
1774
0
            } else if (profile_type == gsPRPROFILE) {
1775
0
                curr_profile = profile_struct->postren_profile;
1776
0
            } else
1777
0
                curr_profile = profile_struct->blend_profile;
1778
1779
0
        }
1780
        /* See if we have the same profile in this location */
1781
4.29k
        if (curr_profile != NULL) {
1782
            /* There is something there now.  See if what we have coming in
1783
               is different and it is not the output intent.  In this  */
1784
4.29k
            if (profile_name != NULL && curr_profile->name != NULL) {
1785
4.29k
                if (strncmp(curr_profile->name, profile_name,
1786
4.29k
                            strlen(profile_name)) != 0 &&
1787
4.29k
                    strncmp(curr_profile->name, OI_PROFILE,
1788
0
                            strlen(curr_profile->name)) != 0) {
1789
                    /* A change in the profile.  rc decrement this one as it
1790
                       will be replaced */
1791
0
                    gsicc_adjust_profile_rc(curr_profile, -1, "gsicc_init_device_profile_struct");
1792
                    /* Icky - if the creation of the new profile fails, we end up with a dangling
1793
                       pointer, or a wrong reference count - so NULL the appropriate entry here
1794
                     */
1795
0
                    if (profile_type < gsPROOFPROFILE) {
1796
0
                        profile_struct->device_profile[profile_type] = NULL;
1797
0
                    } else {
1798
                        /* The proof, link profile or post render */
1799
0
                        if (profile_type == gsPROOFPROFILE) {
1800
0
                            profile_struct->proof_profile = NULL;
1801
0
                        } else if (profile_type == gsLINKPROFILE) {
1802
0
                            profile_struct->link_profile = NULL;
1803
0
                        } else if (profile_type == gsPRPROFILE) {
1804
0
                            profile_struct->postren_profile = NULL;
1805
0
                        } else
1806
0
                            profile_struct->blend_profile = NULL;
1807
1808
0
                    }
1809
1810
4.29k
                } else {
1811
                    /* Nothing to change.  It was either the same or is the
1812
                       output intent */
1813
4.29k
                    return 0;
1814
4.29k
                }
1815
4.29k
            }
1816
4.29k
        }
1817
5.55k
    } else {
1818
        /* We have no profile structure at all. Allocate the structure in
1819
           non-GC memory.  */
1820
5.55k
        dev->icc_struct = gsicc_new_device_profile_array(dev);
1821
5.55k
        profile_struct = dev->icc_struct;
1822
5.55k
        if (profile_struct == NULL)
1823
0
            return_error(gs_error_VMerror);
1824
5.55k
    }
1825
    /* Either use the incoming or a default */
1826
5.55k
    if (profile_name == NULL) {
1827
5.55k
        int has_tags = device_encodes_tags(dev);
1828
5.55k
        profile_name =
1829
5.55k
            (char *) gs_alloc_bytes(dev->memory,
1830
5.55k
                                    MAX_DEFAULT_ICC_LENGTH,
1831
5.55k
                                    "gsicc_init_device_profile_struct");
1832
5.55k
        if (profile_name == NULL)
1833
0
            return_error(gs_error_VMerror);
1834
5.55k
        switch(dev->color_info.num_components - has_tags) {
1835
5.55k
            case 1:
1836
5.55k
                strncpy(profile_name, DEFAULT_GRAY_ICC, strlen(DEFAULT_GRAY_ICC));
1837
5.55k
                profile_name[strlen(DEFAULT_GRAY_ICC)] = 0;
1838
5.55k
                break;
1839
0
            case 3:
1840
0
                strncpy(profile_name, DEFAULT_RGB_ICC, strlen(DEFAULT_RGB_ICC));
1841
0
                profile_name[strlen(DEFAULT_RGB_ICC)] = 0;
1842
0
                break;
1843
0
            case 4:
1844
0
                strncpy(profile_name, DEFAULT_CMYK_ICC, strlen(DEFAULT_CMYK_ICC));
1845
0
                profile_name[strlen(DEFAULT_CMYK_ICC)] = 0;
1846
0
                break;
1847
0
            default:
1848
0
                strncpy(profile_name, DEFAULT_CMYK_ICC, strlen(DEFAULT_CMYK_ICC));
1849
0
                profile_name[strlen(DEFAULT_CMYK_ICC)] = 0;
1850
0
                break;
1851
5.55k
        }
1852
        /* Go ahead and set the profile */
1853
5.55k
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1854
5.55k
                                        profile_type);
1855
5.55k
        gs_free_object(dev->memory, profile_name,
1856
5.55k
                       "gsicc_init_device_profile_struct");
1857
5.55k
        return code;
1858
5.55k
    } else {
1859
        /* Go ahead and set the profile */
1860
0
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1861
0
                                        profile_type);
1862
0
        return code;
1863
0
    }
1864
5.55k
}
1865
1866
/* This is used in getting a list of colorant names for the intepreters
1867
   device parameter list. */
1868
char* gsicc_get_dev_icccolorants(cmm_dev_profile_t *dev_profile)
1869
0
{
1870
0
    if (dev_profile == NULL || dev_profile->spotnames == NULL ||
1871
0
        dev_profile->spotnames->name_str == NULL)
1872
0
        return 0;
1873
0
    else
1874
0
        return dev_profile->spotnames->name_str;
1875
0
}
1876
1877
/* Check that the current state of the profiles is fine. Proof profile is of no
1878
   concern since it is doing a CIELAB to CIELAB mapping in the mashed up
1879
   transform. */
1880
static int
1881
gsicc_verify_device_profiles(gx_device * pdev)
1882
27.2k
{
1883
27.2k
    int k;
1884
27.2k
    cmm_dev_profile_t *dev_icc = pdev->icc_struct;
1885
27.2k
    bool check_components = true;
1886
27.2k
    bool can_postrender = false;
1887
27.2k
    bool objects = false;
1888
27.2k
    int has_tags = device_encodes_tags(pdev);
1889
27.2k
    int num_components = pdev->color_info.num_components - has_tags;
1890
1891
27.2k
    if (dev_proc(pdev, dev_spec_op) != NULL) {
1892
27.2k
        check_components = !(dev_proc(pdev, dev_spec_op)(pdev, gxdso_skip_icc_component_validation, NULL, 0));
1893
27.2k
        can_postrender = dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_iccpostrender, NULL, 0);
1894
27.2k
    }
1895
1896
27.2k
    if (dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE] == NULL)
1897
0
        return 0;
1898
1899
27.2k
    if (dev_icc->postren_profile != NULL && dev_icc->link_profile != NULL) {
1900
0
        return gs_rethrow(-1, "Post render profile not allowed with device link profile");
1901
0
    }
1902
1903
27.2k
    if (dev_icc->blend_profile != NULL) {
1904
0
        if (!(dev_icc->blend_profile->data_cs == gsGRAY ||
1905
0
            dev_icc->blend_profile->data_cs == gsRGB ||
1906
0
            dev_icc->blend_profile->data_cs == gsCMYK))
1907
0
            return gs_rethrow(-1, "Blending color space must be Gray, RGB or CMYK");
1908
0
    }
1909
1910
27.2k
    if (dev_icc->postren_profile != NULL) {
1911
0
        if (!can_postrender) {
1912
0
            return gs_rethrow(-1, "Post render profile not supported by device");
1913
0
        }
1914
0
        if (check_components) {
1915
0
            if (dev_icc->postren_profile->num_comps != num_components) {
1916
0
                return gs_rethrow(-1, "Post render profile does not match the device color model");
1917
0
            }
1918
0
            return 0;
1919
0
        }
1920
0
        return 0; /* An interesting case with sep device.  Need to do a bit of testing here */
1921
0
    }
1922
1923
108k
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
1924
81.6k
        if (dev_icc->device_profile[k] != NULL) {
1925
0
            objects = true;
1926
0
            break;
1927
0
        }
1928
81.6k
    }
1929
1930
27.2k
    if (dev_icc->link_profile == NULL) {
1931
27.2k
        if (!objects) {
1932
27.2k
            if (check_components && dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps !=
1933
21.6k
                num_components)
1934
0
                return gs_rethrow(-1, "Mismatch of ICC profiles and device color model");
1935
27.2k
            else
1936
27.2k
                return 0;  /* Currently sep devices have some leeway here */
1937
27.2k
        } else {
1938
0
            if (check_components) {
1939
0
                for (k = 1; k < NUM_DEVICE_PROFILES; k++)
1940
0
                    if (dev_icc->device_profile[k] != NULL) {
1941
0
                        if (dev_icc->device_profile[k]->num_comps != num_components)
1942
0
                            return gs_rethrow(-1, "Mismatch of object dependent ICC profiles and device color model");
1943
0
                    }
1944
0
            }
1945
0
            return 0;
1946
0
        }
1947
27.2k
    } else {
1948
        /* The input of the device link must match the output of the device
1949
           profile and the device link output must match the device color
1950
           model */
1951
0
        if (check_components && dev_icc->link_profile->num_comps_out !=
1952
0
            num_components) {
1953
0
            return gs_rethrow(-1, "Mismatch of device link profile and device color model");
1954
0
        }
1955
0
        if (check_components) {
1956
0
            for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1957
0
                if (dev_icc->device_profile[k] != NULL) {
1958
0
                    if (dev_icc->device_profile[k]->num_comps !=
1959
0
                        dev_icc->link_profile->num_comps) {
1960
0
                        return gs_rethrow(-1, "Mismatch of device link profile and device ICC profile");
1961
0
                    }
1962
0
                }
1963
0
            }
1964
0
        }
1965
0
        return 0;
1966
0
    }
1967
27.2k
}
1968
1969
/*  This computes the hash code for the device profile and assigns the profile
1970
    in the icc_struct member variable of the device.  This should
1971
    really occur only one time, but may occur twice if a color model is
1972
    specified or a nondefault profile is specified on the command line */
1973
int
1974
gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem,
1975
                         char *file_name, gsicc_profile_types_t pro_enum)
1976
27.2k
{
1977
27.2k
    cmm_profile_t *icc_profile;
1978
27.2k
    stream *str;
1979
27.2k
    int code;
1980
1981
27.2k
    if (file_name == NULL)
1982
0
        return 0;
1983
1984
    /* Check if device has a profile for this slot. Note that we already
1985
       decremented for any profile that we might be replacing
1986
       in gsicc_init_device_profile_struct */
1987
    /* Silent on failure if this is an output intent profile that
1988
     * could not be found.  Bug 695042.  Multi-threaded rendering
1989
     * set up will try to find the file for the profile during the set
1990
     * up via put/get params. but one does not exist.  The OI profile
1991
     * will be cloned after the put/get params */
1992
27.2k
    if (strncmp(file_name, OI_PROFILE, strlen(OI_PROFILE)) == 0)
1993
0
        return -1;
1994
1995
27.2k
    code = gsicc_open_search(file_name, strlen(file_name), mem,
1996
27.2k
                             mem->gs_lib_ctx->profiledir,
1997
27.2k
                             mem->gs_lib_ctx->profiledir_len, &str);
1998
27.2k
    if (code < 0)
1999
0
        return code;
2000
27.2k
    if (str == NULL)
2001
0
        return gs_rethrow(-1, "cannot find device profile");
2002
2003
27.2k
    icc_profile =
2004
27.2k
            gsicc_profile_new(str, mem, file_name, strlen(file_name));
2005
27.2k
    code = sfclose(str);
2006
27.2k
    if (icc_profile == NULL)
2007
0
        return gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
2008
2009
    /* Get the profile handle */
2010
27.2k
    icc_profile->profile_handle =
2011
27.2k
                gsicc_get_profile_handle_buffer(icc_profile->buffer,
2012
27.2k
                                                icc_profile->buffer_size,
2013
27.2k
                                                mem);
2014
27.2k
    if (icc_profile->profile_handle == NULL) {
2015
0
        rc_decrement(icc_profile, "gsicc_set_device_profile");
2016
0
        return_error(gs_error_unknownerror);
2017
0
    }
2018
2019
    /* Compute the hash code of the profile. Everything in the
2020
       ICC manager will have it's hash code precomputed */
2021
27.2k
    gsicc_get_icc_buff_hash(icc_profile->buffer,
2022
27.2k
                            &(icc_profile->hashcode),
2023
27.2k
                            icc_profile->buffer_size);
2024
27.2k
    icc_profile->hash_is_valid = true;
2025
2026
    /* Get the number of channels in the output profile */
2027
27.2k
    icc_profile->num_comps =
2028
27.2k
                gscms_get_input_channel_count(icc_profile->profile_handle,
2029
27.2k
                                              icc_profile->memory);
2030
27.2k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile has %d components\n",
2031
27.2k
               icc_profile->num_comps);
2032
27.2k
    icc_profile->num_comps_out =
2033
27.2k
                gscms_get_output_channel_count(icc_profile->profile_handle,
2034
27.2k
                                               icc_profile->memory);
2035
27.2k
    icc_profile->data_cs =
2036
27.2k
                gscms_get_profile_data_space(icc_profile->profile_handle,
2037
27.2k
                                             icc_profile->memory);
2038
2039
    /* We need to know if this is one of the "default" profiles or
2040
       if someone has externally set it.  The reason is that if there
2041
       is an output intent in the file, and someone wants to use the
2042
       output intent our handling of the output intent profile is
2043
       different depending upon if someone specified a particular
2044
       output profile */
2045
27.2k
    switch (icc_profile->num_comps) {
2046
16.3k
        case 1:
2047
16.3k
            if (strncmp(icc_profile->name, DEFAULT_GRAY_ICC,
2048
16.3k
                        strlen(icc_profile->name)) == 0) {
2049
16.3k
                icc_profile->default_match = DEFAULT_GRAY;
2050
16.3k
            }
2051
16.3k
            break;
2052
10.8k
        case 3:
2053
10.8k
            if (strncmp(icc_profile->name, DEFAULT_RGB_ICC,
2054
10.8k
                        strlen(icc_profile->name)) == 0) {
2055
10.8k
                icc_profile->default_match = DEFAULT_RGB;
2056
10.8k
            }
2057
10.8k
            break;
2058
0
        case 4:
2059
0
            if (strncmp(icc_profile->name, DEFAULT_CMYK_ICC,
2060
0
                        strlen(icc_profile->name)) == 0) {
2061
0
                icc_profile->default_match = DEFAULT_CMYK;
2062
0
            }
2063
0
            break;
2064
27.2k
    }
2065
2066
27.2k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n",
2067
27.2k
               icc_profile->data_cs);
2068
2069
    /* This is slightly silly, we have a device method for 'get_profile' we really ought to
2070
     * have one for 'set_profile' as well. In its absence, make sure we are setting the profile
2071
     * of the bottom level device.
2072
     */
2073
27.2k
    while(pdev->child)
2074
0
        pdev = pdev->child;
2075
2076
27.2k
    switch (pro_enum)
2077
27.2k
    {
2078
27.2k
        case gsDEFAULTPROFILE:
2079
27.2k
        case gsGRAPHICPROFILE:
2080
27.2k
        case gsIMAGEPROFILE:
2081
27.2k
        case gsTEXTPROFILE:
2082
27.2k
            if_debug1m(gs_debug_flag_icc, mem,
2083
27.2k
                       "[icc] Setting device profile %d\n", pro_enum);
2084
27.2k
            pdev->icc_struct->device_profile[pro_enum] = icc_profile;
2085
27.2k
            break;
2086
0
        case gsPROOFPROFILE:
2087
0
            if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting proof profile\n");
2088
0
            pdev->icc_struct->proof_profile = icc_profile;
2089
0
            break;
2090
0
        case gsLINKPROFILE:
2091
0
            if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting link profile\n");
2092
0
            pdev->icc_struct->link_profile = icc_profile;
2093
0
            break;
2094
0
        case gsPRPROFILE:
2095
0
            if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting postrender profile\n");
2096
0
            pdev->icc_struct->postren_profile = icc_profile;
2097
0
            break;
2098
0
        case gsBLENDPROFILE:
2099
0
            if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting blend profile\n");
2100
0
            pdev->icc_struct->blend_profile = icc_profile;
2101
0
            break;
2102
0
        default:
2103
0
        case gsOIPROFILE:
2104
            /* This never happens as output intent profile is set in zicc.c */
2105
0
            rc_decrement(icc_profile, "gsicc_set_device_profile");
2106
0
            return_error(gs_error_unknownerror);
2107
27.2k
    }
2108
2109
    /* Check that everything is OK with regard to the number of
2110
       components. */
2111
27.2k
    if (gsicc_verify_device_profiles(pdev) < 0)
2112
0
        return gs_rethrow(-1, "Error in device profiles");
2113
2114
27.2k
    if (icc_profile->num_comps != 1 &&
2115
27.2k
        icc_profile->num_comps != 3 &&
2116
27.2k
        icc_profile->num_comps != 4) {
2117
        /* NCLR Profile.  Set up default colorant names */
2118
0
        code = gsicc_set_device_profile_colorants(pdev, NULL);
2119
0
        if (code < 0)
2120
0
            return code;
2121
0
    }
2122
2123
27.2k
    return 0;
2124
27.2k
}
2125
2126
/* Set the icc profile in the gs_color_space object */
2127
int
2128
gsicc_set_gscs_profile(gs_color_space *pcs, cmm_profile_t *icc_profile,
2129
                       gs_memory_t * mem)
2130
53.8k
{
2131
53.8k
    if (pcs == NULL)
2132
0
        return -1;
2133
#if ICC_DUMP
2134
    if (icc_profile->buffer) {
2135
        dump_icc_buffer(mem,
2136
                        icc_profile->buffer_size, "set_gscs",
2137
                        icc_profile->buffer);
2138
        global_icc_index++;
2139
    }
2140
#endif
2141
2142
53.8k
    gsicc_adjust_profile_rc(icc_profile, 1, "gsicc_set_gscs_profile");
2143
53.8k
    if (pcs->cmm_icc_profile_data != NULL) {
2144
        /* There is already a profile set there */
2145
        /* free it and then set to the new one.  */
2146
        /* should we check the hash code and retain if the same
2147
           or place this job on the caller?  */
2148
0
        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gsicc_set_gscs_profile");
2149
0
    }
2150
53.8k
    pcs->cmm_icc_profile_data = icc_profile;
2151
53.8k
    return 0;
2152
53.8k
}
2153
2154
int
2155
gsicc_clone_profile(cmm_profile_t *source, cmm_profile_t **destination,
2156
                    gs_memory_t *memory)
2157
0
{
2158
0
    cmm_profile_t *des = gsicc_profile_new(NULL, memory, source->name,
2159
0
        source->name_length);
2160
2161
0
    if (des == NULL)
2162
0
        return gs_throw(gs_error_VMerror, "Profile clone failed");
2163
0
    des->buffer = gs_alloc_bytes(memory, source->buffer_size, "gsicc_clone_profile");
2164
0
    if (des->buffer == NULL) {
2165
0
        gsicc_adjust_profile_rc(des, -1, "gsicc_clone_profile");
2166
0
        return gs_throw(gs_error_VMerror, "Profile clone failed");
2167
0
    }
2168
0
    memcpy(des->buffer, source->buffer, source->buffer_size);
2169
0
    des->buffer_size = source->buffer_size;
2170
0
    gsicc_init_profile_info(des);
2171
0
    *destination = des;
2172
0
    return 0;
2173
0
}
2174
2175
cmm_profile_t *
2176
gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname,
2177
                  int namelen)
2178
1.26M
{
2179
1.26M
    cmm_profile_t *result;
2180
1.26M
    int code;
2181
1.26M
    char *nameptr = NULL;
2182
1.26M
    gs_memory_t *mem_nongc = memory->non_gc_memory;
2183
2184
1.26M
    result = (cmm_profile_t*) gs_alloc_bytes(mem_nongc, sizeof(cmm_profile_t),
2185
1.26M
                                    "gsicc_profile_new");
2186
1.26M
    if (result == NULL)
2187
0
        return result;
2188
1.26M
    memset(result, 0, GSICC_SERIALIZED_SIZE);
2189
1.26M
    if (namelen > 0) {
2190
1.06M
        nameptr = (char*) gs_alloc_bytes(mem_nongc, namelen+1,
2191
1.06M
                             "gsicc_profile_new");
2192
1.06M
        if (nameptr == NULL) {
2193
0
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2194
0
            return NULL;
2195
0
        }
2196
1.06M
        memcpy(nameptr, pname, namelen);
2197
1.06M
        nameptr[namelen] = '\0';
2198
1.06M
        result->name = nameptr;
2199
1.06M
    } else {
2200
198k
        result->name = NULL;
2201
198k
    }
2202
1.26M
    result->name_length = namelen;
2203
2204
    /* We may not have a stream if we are creating this
2205
       object from our own constructed buffer.  For
2206
       example if we are converting CalRGB to an ICC type */
2207
1.26M
    if ( s != NULL) {
2208
1.07M
        code = gsicc_load_profile_buffer(result, s, mem_nongc);
2209
1.07M
        if (code < 0) {
2210
127
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2211
127
            gs_free_object(mem_nongc, nameptr, "gsicc_profile_new");
2212
127
            return NULL;
2213
127
        }
2214
1.07M
    } else {
2215
197k
        result->buffer = NULL;
2216
197k
        result->buffer_size = 0;
2217
197k
    }
2218
1.26M
    rc_init_free(result, mem_nongc, 1, rc_free_icc_profile);
2219
1.26M
    result->profile_handle = NULL;
2220
1.26M
    result->spotnames = NULL;
2221
1.26M
    result->rend_is_valid = false;
2222
1.26M
    result->isdevlink = false;  /* only used for srcgtag profiles */
2223
1.26M
    result->dev = NULL;
2224
1.26M
    result->memory = mem_nongc;
2225
1.26M
    result->vers = ICCVERS_UNKNOWN;
2226
1.26M
    result->v2_data = NULL;
2227
1.26M
    result->v2_size = 0;
2228
1.26M
    result->release = gscms_release_profile; /* Default case */
2229
2230
1.26M
    result->lock = gx_monitor_label(gx_monitor_alloc(mem_nongc),
2231
1.26M
                                    "gsicc_manage");
2232
1.26M
    if (result->lock == NULL) {
2233
0
        gs_free_object(mem_nongc, result->buffer, "gsicc_load_profile");
2234
0
        gs_free_object(mem_nongc, result, "gsicc_profile_new");
2235
0
        gs_free_object(mem_nongc, nameptr, "gsicc_profile_new");
2236
0
        return NULL;
2237
0
    }
2238
1.26M
    if_debug1m(gs_debug_flag_icc, mem_nongc,
2239
1.26M
               "[icc] allocating ICC profile = "PRI_INTPTR"\n", (intptr_t)result);
2240
1.26M
    return result;
2241
1.26M
}
2242
2243
static void
2244
rc_free_icc_profile(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2245
1.26M
{
2246
1.26M
    cmm_profile_t *profile = (cmm_profile_t *)ptr_in;
2247
1.26M
    gs_memory_t *mem_nongc =  profile->memory;
2248
2249
1.26M
    if_debug2m(gs_debug_flag_icc, mem,
2250
1.26M
               "[icc] rc decrement profile = "PRI_INTPTR" rc = %ld\n",
2251
1.26M
               (intptr_t)ptr_in, profile->rc.ref_count);
2252
1.26M
    if (profile->rc.ref_count <= 1 ) {
2253
        /* Clear out the buffer if it is full */
2254
1.26M
        if (profile->buffer != NULL) {
2255
1.07M
            gs_free_object(mem_nongc, profile->buffer, "rc_free_icc_profile(buffer)");
2256
1.07M
            profile->buffer = NULL;
2257
1.07M
        }
2258
1.26M
        if_debug0m(gs_debug_flag_icc, mem, "[icc] profile freed\n");
2259
        /* Release this handle if it has been set */
2260
1.26M
        if (profile->profile_handle != NULL) {
2261
50.6k
            profile->release(profile->profile_handle, profile->memory);
2262
50.6k
            profile->profile_handle = NULL;
2263
50.6k
        }
2264
        /* Release the name if it has been set */
2265
1.26M
        if (profile->name != NULL) {
2266
1.06M
            gs_free_object(mem_nongc, profile->name,"rc_free_icc_profile(name)");
2267
1.06M
            profile->name = NULL;
2268
1.06M
            profile->name_length = 0;
2269
1.06M
        }
2270
1.26M
        profile->hash_is_valid = 0;
2271
1.26M
        if (profile->lock != NULL) {
2272
1.26M
            gx_monitor_free(profile->lock);
2273
1.26M
            profile->lock = NULL;
2274
1.26M
        }
2275
        /* If we had a DeviceN profile with names deallocate that now */
2276
1.26M
        if (profile->spotnames != NULL) {
2277
            /* Free the linked list in this object */
2278
0
            gsicc_free_spotnames(profile->spotnames, mem_nongc);
2279
            /* Free the main object */
2280
0
            gs_free_object(mem_nongc, profile->spotnames, "rc_free_icc_profile(spotnames)");
2281
0
        }
2282
        /* If we allocated a buffer to hold the v2 profile then free that */
2283
1.26M
        if (profile->v2_data != NULL) {
2284
0
            gs_free_object(mem_nongc, profile->v2_data, "rc_free_icc_profile(v2_data)");
2285
0
        }
2286
1.26M
        gs_free_object(mem_nongc, profile, "rc_free_icc_profile");
2287
1.26M
    }
2288
1.26M
}
2289
2290
/* We are just starting up.  We need to set the initial color space in the
2291
   graphic state at this time */
2292
int
2293
gsicc_init_gs_colors(gs_gstate *pgs)
2294
0
{
2295
0
    int             code = 0;
2296
0
    gs_color_space  *cs_old;
2297
0
    gs_color_space  *cs_new;
2298
0
    int k;
2299
2300
0
    if (pgs->in_cachedevice)
2301
0
        return_error(gs_error_undefined);
2302
2303
0
    for (k = 0; k < 2; k++) {
2304
        /* First do color space 0 */
2305
0
        cs_old = pgs->color[k].color_space;
2306
0
        cs_new = gs_cspace_new_DeviceGray(pgs->memory);
2307
0
        if (cs_new == NULL)
2308
0
            return_error(gs_error_VMerror);
2309
0
        rc_increment_cs(cs_new);
2310
0
        pgs->color[k].color_space = cs_new;
2311
0
        if ( (code = cs_new->type->install_cspace(cs_new, pgs)) < 0 ) {
2312
0
            pgs->color[k].color_space = cs_old;
2313
0
            rc_decrement_only_cs(cs_new, "gsicc_init_gs_colors");
2314
0
            return code;
2315
0
        } else {
2316
0
            rc_decrement_only_cs(cs_old, "gsicc_init_gs_colors");
2317
0
        }
2318
0
    }
2319
0
    return code;
2320
0
}
2321
2322
/* Only set those that have not already been set. */
2323
int
2324
gsicc_init_iccmanager(gs_gstate * pgs)
2325
265k
{
2326
265k
    int code = 0, k;
2327
265k
    const char *pname;
2328
265k
    int namelen;
2329
265k
    gsicc_manager_t *iccmanager = pgs->icc_manager;
2330
265k
    cmm_profile_t *profile;
2331
2332
1.32M
    for (k = 0; k < 4; k++) {
2333
1.06M
        pname = default_profile_params[k].path;
2334
1.06M
        namelen = strlen(pname);
2335
2336
1.06M
        switch(default_profile_params[k].default_type) {
2337
265k
            case DEFAULT_GRAY:
2338
265k
                profile = iccmanager->default_gray;
2339
265k
                break;
2340
265k
            case DEFAULT_RGB:
2341
265k
                profile = iccmanager->default_rgb;
2342
265k
                break;
2343
265k
            case DEFAULT_CMYK:
2344
265k
                 profile = iccmanager->default_cmyk;
2345
265k
                 break;
2346
265k
            default:
2347
265k
                profile = NULL;
2348
1.06M
        }
2349
1.06M
        if (profile == NULL)
2350
1.04M
            code = gsicc_set_profile(iccmanager, pname, namelen,
2351
1.04M
                                     default_profile_params[k].default_type);
2352
1.06M
        if (code < 0)
2353
0
            return gs_rethrow(code, "cannot find default icc profile");
2354
1.06M
    }
2355
#if CREATE_V2_DATA
2356
    /* Test bed for V2 creation from V4 */
2357
    for (int j = 2; j < 3; j++)
2358
    {
2359
        byte *data;
2360
        int size;
2361
2362
        switch (default_profile_params[j].default_type) {
2363
        case DEFAULT_GRAY:
2364
            profile = iccmanager->default_gray;
2365
            break;
2366
        case DEFAULT_RGB:
2367
            profile = iccmanager->default_rgb;
2368
            break;
2369
        case DEFAULT_CMYK:
2370
            profile = iccmanager->default_cmyk;
2371
            break;
2372
        default:
2373
            profile = NULL;
2374
        }
2375
        gsicc_initialize_default_profile(profile);
2376
        data = gsicc_create_getv2buffer(pgs, profile, &size);
2377
    }
2378
#endif
2379
265k
    return 0;
2380
265k
}
2381
2382
static void
2383
gsicc_manager_finalize(const gs_memory_t *memory, void * vptr)
2384
260k
{
2385
260k
    gsicc_manager_t *icc_man = (gsicc_manager_t *)vptr;
2386
2387
260k
    gsicc_manager_free_contents(icc_man, "gsicc_manager_finalize");
2388
260k
}
2389
2390
gsicc_manager_t *
2391
gsicc_manager_new(gs_memory_t *memory)
2392
260k
{
2393
260k
    gsicc_manager_t *result;
2394
2395
    /* Allocated in stable gc memory.  This done since the profiles
2396
       may be introduced late in the process. */
2397
260k
    memory = memory->stable_memory;
2398
260k
    result = gs_alloc_struct(memory, gsicc_manager_t, &st_gsicc_manager,
2399
260k
                             "gsicc_manager_new");
2400
260k
    if ( result == NULL )
2401
0
        return NULL;
2402
260k
    rc_init_free(result, memory, 1, rc_gsicc_manager_free);
2403
260k
    result->default_gray = NULL;
2404
260k
    result->default_rgb = NULL;
2405
260k
    result->default_cmyk = NULL;
2406
260k
    result->lab_profile = NULL;
2407
260k
    result->xyz_profile = NULL;
2408
260k
    result->graytok_profile = NULL;
2409
260k
    result->device_named = NULL;
2410
260k
    result->device_n = NULL;
2411
260k
    result->smask_profiles = NULL;
2412
260k
    result->memory = memory;
2413
260k
    result->srcgtag_profile = NULL;
2414
260k
    result->override_internal = false;
2415
260k
    return result;
2416
260k
}
2417
2418
static void gsicc_manager_free_contents(gsicc_manager_t *icc_manager,
2419
                                        client_name_t cname)
2420
260k
{
2421
260k
    int k;
2422
260k
    gsicc_devicen_entry_t *device_n, *device_n_next;
2423
2424
260k
    gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "gsicc_manager_free_contents");
2425
260k
    gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "gsicc_manager_free_contents");
2426
260k
    gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "gsicc_manager_free_contents");
2427
260k
    gsicc_adjust_profile_rc(icc_manager->device_named, -1, "gsicc_manager_free_contents");
2428
260k
    gsicc_adjust_profile_rc(icc_manager->lab_profile, -1, "gsicc_manager_free_contents");
2429
260k
    gsicc_adjust_profile_rc(icc_manager->graytok_profile, -1, "gsicc_manager_free_contents");
2430
260k
    rc_decrement(icc_manager->srcgtag_profile, "gsicc_manager_free_contents");
2431
2432
    /* Loop through the DeviceN profiles */
2433
260k
    if ( icc_manager->device_n != NULL) {
2434
0
        device_n = icc_manager->device_n->head;
2435
0
        for ( k = 0; k < icc_manager->device_n->count; k++) {
2436
0
            gsicc_adjust_profile_rc(device_n->iccprofile, -1, "gsicc_manager_free_contents");
2437
0
            device_n_next = device_n->next;
2438
0
            gs_free_object(icc_manager->memory, device_n, "gsicc_manager_free_contents");
2439
0
            device_n = device_n_next;
2440
0
        }
2441
0
        gs_free_object(icc_manager->memory, icc_manager->device_n,
2442
0
                       "gsicc_manager_free_contents");
2443
0
    }
2444
2445
    /* The soft mask profiles */
2446
260k
    if (icc_manager->smask_profiles != NULL) {
2447
394
        gs_free_object(icc_manager->smask_profiles->memory, icc_manager->smask_profiles, "gsicc_manager_free_contents");
2448
394
        icc_manager->smask_profiles = NULL;
2449
394
    }
2450
260k
}
2451
2452
static void
2453
rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2454
260k
{
2455
    /* Ending the manager.  Decrement the ref counts of the profiles
2456
       and then free the structure */
2457
260k
    gsicc_manager_t *icc_manager = (gsicc_manager_t * ) ptr_in;
2458
2459
260k
    assert(mem == icc_manager->memory);
2460
2461
260k
    gs_free_object(icc_manager->memory, icc_manager, "rc_gsicc_manager_free");
2462
260k
}
2463
2464
/* Allocates and loads the icc buffer from the stream. */
2465
static int
2466
gsicc_load_profile_buffer(cmm_profile_t *profile, stream *s,
2467
                          gs_memory_t *memory)
2468
1.07M
{
2469
1.07M
    int                     num_bytes,profile_size;
2470
1.07M
    unsigned char           *buffer_ptr;
2471
1.07M
    int                     code;
2472
2473
1.07M
    code = srewind(s);  /* Work around for issue with sfread return 0 bytes
2474
                        and not doing a retry if there is an issue.  This
2475
                        is a bug in the stream logic or strmio layer.  Occurs
2476
                        with smask_withicc.pdf on linux 64 bit system */
2477
1.07M
    if (code < 0)
2478
0
        return code;
2479
    /* Get the size from doing a seek to the end and then a rewind instead
2480
       of relying upon the profile size indicated in the header */
2481
1.07M
    code = sfseek(s,0,SEEK_END);
2482
1.07M
    if (code < 0)
2483
0
        return code;
2484
1.07M
    profile_size = sftell(s);
2485
1.07M
    code = srewind(s);
2486
1.07M
    if (code < 0)
2487
0
        return code;
2488
1.07M
    if (profile_size < ICC_HEADER_SIZE)
2489
127
        return_error(gs_error_VMerror);
2490
    /* Allocate the buffer, stuff with the profile */
2491
1.07M
   buffer_ptr = gs_alloc_bytes(memory, profile_size,
2492
1.07M
                                        "gsicc_load_profile");
2493
1.07M
   if (buffer_ptr == NULL)
2494
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer");
2495
1.07M
   num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s);
2496
1.07M
   if( num_bytes != profile_size) {
2497
0
       gs_free_object(memory, buffer_ptr, "gsicc_load_profile");
2498
0
       return -1;
2499
0
   }
2500
1.07M
   profile->buffer = buffer_ptr;
2501
1.07M
   profile->buffer_size = num_bytes;
2502
1.07M
   return 0;
2503
1.07M
}
2504
2505
/* Allocates and loads the named color structure from the stream. */
2506
static int
2507
gsicc_load_namedcolor_buffer(cmm_profile_t *profile, stream *s,
2508
                             gs_memory_t *memory)
2509
0
{
2510
0
    int                     num_bytes,profile_size;
2511
0
    unsigned char           *buffer_ptr;
2512
0
    int                     code;
2513
2514
0
    code = srewind(s);
2515
0
    if (code < 0)
2516
0
        return code;
2517
0
    code = sfseek(s,0,SEEK_END);
2518
0
    if (code < 0)
2519
0
        return code;
2520
0
    profile_size = sftell(s);
2521
0
    code = srewind(s);
2522
0
    if (code < 0)
2523
0
        return code;
2524
    /* Allocate the buffer, stuff with the profile */
2525
0
    buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size,
2526
0
                                "gsicc_load_profile");
2527
0
    if (buffer_ptr == NULL)
2528
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer");
2529
0
    num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s);
2530
0
    if( num_bytes != profile_size) {
2531
0
        gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_load_profile");
2532
0
        return -1;
2533
0
    }
2534
0
    profile->buffer = buffer_ptr;
2535
0
    profile->buffer_size = num_bytes;
2536
0
    return 0;
2537
0
}
2538
2539
/* Check if the embedded profile is the same as any of the default profiles */
2540
static void
2541
gsicc_set_default_cs_value(cmm_profile_t *picc_profile, gs_gstate *pgs)
2542
1.11k
{
2543
1.11k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
2544
1.11k
    int64_t hashcode = picc_profile->hashcode;
2545
2546
1.11k
    if ( picc_profile->default_match == DEFAULT_NONE ) {
2547
1.11k
        switch ( picc_profile->data_cs ) {
2548
433
            case gsGRAY:
2549
433
                if ( hashcode == icc_manager->default_gray->hashcode )
2550
0
                    picc_profile->default_match = DEFAULT_GRAY_s;
2551
433
                break;
2552
683
            case gsRGB:
2553
683
                if ( hashcode == icc_manager->default_rgb->hashcode )
2554
0
                    picc_profile->default_match = DEFAULT_RGB_s;
2555
683
                break;
2556
2
            case gsCMYK:
2557
2
                if ( hashcode == icc_manager->default_cmyk->hashcode )
2558
0
                    picc_profile->default_match = DEFAULT_CMYK_s;
2559
2
                break;
2560
0
            case gsCIELAB:
2561
0
                if ( hashcode == icc_manager->lab_profile->hashcode )
2562
0
                    picc_profile->default_match = LAB_TYPE_s;
2563
0
                break;
2564
0
            case gsCIEXYZ:
2565
0
                return;
2566
0
                break;
2567
0
            case gsNCHANNEL:
2568
0
                return;
2569
0
                break;
2570
0
            default:
2571
0
                return;
2572
1.11k
        }
2573
1.11k
    }
2574
1.11k
}
2575
2576
/* Initialize the hash code value */
2577
void
2578
gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_gstate *pgs)
2579
1.11k
{
2580
1.11k
    if ( !(picc_profile->hash_is_valid) ) {
2581
776
        gsicc_get_icc_buff_hash(picc_profile->buffer, &(picc_profile->hashcode),
2582
776
                                picc_profile->buffer_size);
2583
776
        picc_profile->hash_is_valid = true;
2584
776
    }
2585
1.11k
    gsicc_set_default_cs_value(picc_profile, pgs);
2586
1.11k
}
2587
2588
/* Interface code to get the profile handle for data
2589
   stored in the clist device */
2590
gcmmhprofile_t
2591
gsicc_get_profile_handle_clist(cmm_profile_t *picc_profile, gs_memory_t *memory)
2592
1.26k
{
2593
1.26k
    gcmmhprofile_t profile_handle = NULL;
2594
1.26k
    unsigned int profile_size;
2595
1.26k
    int size;
2596
1.26k
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) picc_profile->dev;
2597
1.26k
    unsigned char *buffer_ptr;
2598
1.26k
    int64_t position;
2599
1.26k
    gsicc_serialized_profile_t profile_header;
2600
1.26k
    int k;
2601
2602
1.26k
    if( pcrdev != NULL) {
2603
2604
        /* Check ICC table for hash code and get the whole size icc raw buffer
2605
           plus serialized header information */
2606
1.26k
        position = gsicc_search_icc_table(pcrdev->icc_table,
2607
1.26k
                                          picc_profile->hashcode, &size);
2608
1.26k
        if ( position < 0 )
2609
0
            return NULL;  /* Not found. */
2610
2611
        /* Get the ICC buffer.  We really want to avoid this transfer.
2612
           I need to write  an interface to the CMM to do this through
2613
           the clist ioprocs */
2614
        /* Allocate the buffer */
2615
1.26k
        profile_size = size - GSICC_SERIALIZED_SIZE;
2616
        /* Profile and its members are ALL in non-gc memory */
2617
1.26k
        buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size,
2618
1.26k
                                            "gsicc_get_profile_handle_clist");
2619
1.26k
        if (buffer_ptr == NULL)
2620
0
            return NULL;
2621
1.26k
        clist_read_chunk(pcrdev, position + GSICC_SERIALIZED_SIZE,
2622
1.26k
            profile_size, (unsigned char *) buffer_ptr);
2623
1.26k
        profile_handle = gscms_get_profile_handle_mem(buffer_ptr, profile_size, memory->non_gc_memory);
2624
1.26k
        if (profile_handle == NULL) {
2625
0
            gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_get_profile_handle_clist");
2626
0
            return NULL;
2627
0
        }
2628
        /* We also need to get some of the serialized information */
2629
1.26k
        clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2630
1.26k
                        (unsigned char *) (&profile_header));
2631
1.26k
        picc_profile->buffer = NULL;
2632
1.26k
        picc_profile->buffer_size = 0;
2633
1.26k
        picc_profile->data_cs = profile_header.data_cs;
2634
1.26k
        picc_profile->default_match = profile_header.default_match;
2635
1.26k
        picc_profile->hash_is_valid = profile_header.hash_is_valid;
2636
1.26k
        picc_profile->hashcode = profile_header.hashcode;
2637
1.26k
        picc_profile->islab = profile_header.islab;
2638
1.26k
        picc_profile->num_comps = profile_header.num_comps;
2639
1.26k
        picc_profile->rend_is_valid = profile_header.rend_is_valid;
2640
1.26k
        picc_profile->rend_cond = profile_header.rend_cond;
2641
1.26k
        picc_profile->isdevlink = profile_header.isdevlink;
2642
4.00k
        for ( k = 0; k < profile_header.num_comps; k++ ) {
2643
2.73k
            picc_profile->Range.ranges[k].rmax =
2644
2.73k
                profile_header.Range.ranges[k].rmax;
2645
2.73k
            picc_profile->Range.ranges[k].rmin =
2646
2.73k
                profile_header.Range.ranges[k].rmin;
2647
2.73k
        }
2648
1.26k
        gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_get_profile_handle_clist");
2649
1.26k
        return profile_handle;
2650
1.26k
     }
2651
0
     return NULL;
2652
1.26k
}
2653
2654
gcmmhprofile_t
2655
gsicc_get_profile_handle_buffer(unsigned char *buffer, int profile_size, gs_memory_t *memory)
2656
49.5k
{
2657
2658
49.5k
    gcmmhprofile_t profile_handle = NULL;
2659
2660
49.5k
     if( buffer != NULL) {
2661
49.5k
         if (profile_size < ICC_HEADER_SIZE) {
2662
0
             return 0;
2663
0
         }
2664
49.5k
         profile_handle = gscms_get_profile_handle_mem(buffer, profile_size, memory->non_gc_memory);
2665
49.5k
         return profile_handle;
2666
49.5k
     }
2667
0
     return 0;
2668
49.5k
}
2669
2670
 /*  If we have a profile for the color space already, then we use that.
2671
     If we do not have one then we will use data from
2672
     the ICC manager that is based upon the current color space. */
2673
 cmm_profile_t*
2674
 gsicc_get_gscs_profile(gs_color_space *gs_colorspace,
2675
                        gsicc_manager_t *icc_manager)
2676
0
 {
2677
0
     cmm_profile_t *profile = gs_colorspace->cmm_icc_profile_data;
2678
0
     gs_color_space_index color_space_index =
2679
0
            gs_color_space_get_index(gs_colorspace);
2680
0
     int code = 0;
2681
0
     bool islab;
2682
2683
0
     if (profile != NULL )
2684
0
        return profile;
2685
     /* else, return the default types */
2686
0
     switch( color_space_index ) {
2687
0
        case gs_color_space_index_DeviceGray:
2688
0
            return icc_manager->default_gray;
2689
0
            break;
2690
0
        case gs_color_space_index_DeviceRGB:
2691
0
            return icc_manager->default_rgb;
2692
0
            break;
2693
0
        case gs_color_space_index_DeviceCMYK:
2694
0
            return icc_manager->default_cmyk;
2695
0
            break;
2696
            /* Only used in 3x types */
2697
0
        case gs_color_space_index_DevicePixel:
2698
0
            return 0;
2699
0
            break;
2700
0
       case gs_color_space_index_DeviceN:
2701
            /* If we made it to here, then we will need to use the
2702
               alternate colorspace */
2703
0
            return 0;
2704
0
            break;
2705
0
       case gs_color_space_index_CIEDEFG:
2706
           /* For now just use default CMYK to avoid segfault.  MJV to fix */
2707
0
           gs_colorspace->cmm_icc_profile_data = icc_manager->default_cmyk;
2708
0
           gsicc_adjust_profile_rc(icc_manager->default_cmyk, 1, "gsicc_get_gscs_profile");
2709
0
           return gs_colorspace->cmm_icc_profile_data;
2710
           /* Need to convert to an ICC form */
2711
0
           break;
2712
0
        case gs_color_space_index_CIEDEF:
2713
           /* For now just use default RGB to avoid segfault.  MJV to fix */
2714
0
           gs_colorspace->cmm_icc_profile_data = icc_manager->default_rgb;
2715
0
           gsicc_adjust_profile_rc(icc_manager->default_rgb, 1, "gsicc_get_gscs_profile");
2716
0
           return gs_colorspace->cmm_icc_profile_data;
2717
           /* Need to convert to an ICC form */
2718
0
           break;
2719
0
        case gs_color_space_index_CIEABC:
2720
0
            gs_colorspace->cmm_icc_profile_data =
2721
0
                gsicc_profile_new(NULL, icc_manager->memory, NULL, 0);
2722
0
            if (gs_colorspace->cmm_icc_profile_data == NULL) {
2723
0
                gs_throw(gs_error_VMerror, "Creation of ICC profile for CIEABC failed");
2724
0
                return NULL;
2725
0
            }
2726
0
            code =
2727
0
                gsicc_create_fromabc(gs_colorspace,
2728
0
                        &(gs_colorspace->cmm_icc_profile_data->buffer),
2729
0
                        &(gs_colorspace->cmm_icc_profile_data->buffer_size),
2730
0
                        icc_manager->memory,
2731
0
                        &(gs_colorspace->params.abc->caches.DecodeABC.caches[0]),
2732
0
                        &(gs_colorspace->params.abc->common.caches.DecodeLMN[0]),
2733
0
                        &islab);
2734
0
            if (code < 0) {
2735
0
                gs_warn("Failed to create ICC profile from CIEABC");
2736
0
                gsicc_adjust_profile_rc(gs_colorspace->cmm_icc_profile_data, -1,
2737
0
                             "gsicc_get_gscs_profile");
2738
0
                return NULL;
2739
0
            }
2740
2741
0
            if (islab) {
2742
                /* Destroy the profile */
2743
0
                gsicc_adjust_profile_rc(gs_colorspace->cmm_icc_profile_data, -1,
2744
0
                             "gsicc_get_gscs_profile");
2745
                /* This may be an issue for pdfwrite */
2746
0
                return icc_manager->lab_profile;
2747
0
            }
2748
0
            gs_colorspace->cmm_icc_profile_data->default_match = CIE_ABC;
2749
0
            return gs_colorspace->cmm_icc_profile_data;
2750
0
            break;
2751
0
        case gs_color_space_index_CIEA:
2752
0
            gs_colorspace->cmm_icc_profile_data =
2753
0
                gsicc_profile_new(NULL, icc_manager->memory, NULL, 0);
2754
0
            if (gs_colorspace->cmm_icc_profile_data == NULL) {
2755
0
                gs_throw(gs_error_VMerror, "Creation of ICC profile for CIEA failed");
2756
0
                return NULL;
2757
0
            }
2758
0
            code =
2759
0
                gsicc_create_froma(gs_colorspace,
2760
0
                            &(gs_colorspace->cmm_icc_profile_data->buffer),
2761
0
                            &(gs_colorspace->cmm_icc_profile_data->buffer_size),
2762
0
                            icc_manager->memory,
2763
0
                            &(gs_colorspace->params.a->caches.DecodeA),
2764
0
                            &(gs_colorspace->params.a->common.caches.DecodeLMN[0]));
2765
0
            gs_colorspace->cmm_icc_profile_data->default_match = CIE_A;
2766
0
            return gs_colorspace->cmm_icc_profile_data;
2767
0
            break;
2768
0
        case gs_color_space_index_Separation:
2769
            /* Caller should use named color path */
2770
0
            return 0;
2771
0
            break;
2772
0
        case gs_color_space_index_Pattern:
2773
0
        case gs_color_space_index_Indexed:
2774
            /* Caller should use the base space for these */
2775
0
            return 0;
2776
0
            break;
2777
0
        case gs_color_space_index_ICC:
2778
            /* This should not occur, as the space
2779
               should have had a populated profile handle */
2780
0
            return 0;
2781
0
            break;
2782
0
     }
2783
0
    return 0;
2784
0
 }
2785
2786
static int64_t
2787
gsicc_search_icc_table(clist_icctable_t *icc_table, int64_t icc_hashcode, int *size)
2788
145k
{
2789
145k
    int tablesize = icc_table->tablesize, k;
2790
145k
    clist_icctable_entry_t *curr_entry;
2791
2792
145k
    curr_entry = icc_table->head;
2793
210k
    for (k = 0; k < tablesize; k++ ) {
2794
210k
        if ( curr_entry->serial_data.hashcode == icc_hashcode ) {
2795
145k
            *size = curr_entry->serial_data.size;
2796
145k
            return curr_entry->serial_data.file_position;
2797
145k
        }
2798
64.9k
        curr_entry = curr_entry->next;
2799
64.9k
    }
2800
2801
    /* Did not find it! */
2802
0
    *size = 0;
2803
0
    return -1;
2804
145k
}
2805
2806
/* This is used to get only the serial data from the clist.  We don't bother
2807
   with the whole profile until we actually need it.  It may be that the link
2808
   that we need is already in the link cache */
2809
cmm_profile_t*
2810
gsicc_read_serial_icc(gx_device *dev, int64_t icc_hashcode)
2811
144k
{
2812
144k
    cmm_profile_t *profile;
2813
144k
    int64_t position;
2814
144k
    int size;
2815
144k
    int code;
2816
144k
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) dev;
2817
2818
    /* Create a new ICC profile structure */
2819
144k
    profile = gsicc_profile_new(NULL, pcrdev->memory, NULL, 0);
2820
144k
    if (profile == NULL)
2821
0
        return NULL;
2822
2823
    /* Check ICC table for hash code and get the whole size icc raw buffer
2824
       plus serialized header information. Make sure the icc_table has
2825
       been intialized */
2826
144k
    if (pcrdev->icc_table == NULL) {
2827
0
        code = clist_read_icctable(pcrdev);
2828
0
        if (code<0)
2829
0
            return NULL;
2830
0
    }
2831
144k
    position = gsicc_search_icc_table(pcrdev->icc_table, icc_hashcode, &size);
2832
144k
    if ( position < 0 )
2833
0
        return NULL;
2834
2835
    /* Get the serialized portion of the ICC profile information */
2836
144k
    clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2837
144k
                    (unsigned char *) profile);
2838
144k
    return profile;
2839
144k
}
2840
2841
void
2842
gsicc_profile_serialize(gsicc_serialized_profile_t *profile_data,
2843
                        cmm_profile_t *icc_profile)
2844
2.01k
{
2845
2.01k
    if (icc_profile == NULL)
2846
0
        return;
2847
2.01k
    memcpy(profile_data, icc_profile, GSICC_SERIALIZED_SIZE);
2848
2.01k
}
2849
2850
/* Utility functions */
2851
2852
int
2853
gsicc_getsrc_channel_count(cmm_profile_t *icc_profile)
2854
0
{
2855
0
    return gscms_get_input_channel_count(icc_profile->profile_handle,
2856
0
        icc_profile->memory);
2857
0
}
2858
2859
void
2860
gsicc_extract_profile(gs_graphics_type_tag_t graphics_type_tag,
2861
                       cmm_dev_profile_t *profile_struct,
2862
                       cmm_profile_t **profile, gsicc_rendering_param_t *render_cond)
2863
25.7M
{
2864
25.7M
    switch (graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) {
2865
9.27M
        case GS_UNKNOWN_TAG:
2866
9.42M
        case GS_UNTOUCHED_TAG:
2867
9.42M
        default:
2868
9.42M
            (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2869
9.42M
            *render_cond = profile_struct->rendercond[GS_DEFAULT_DEVICE_PROFILE];
2870
9.42M
            break;
2871
14.0M
        case GS_VECTOR_TAG:
2872
14.0M
            *render_cond = profile_struct->rendercond[GS_VECTOR_DEVICE_PROFILE];
2873
14.0M
            if (profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE] != NULL) {
2874
0
                (*profile) = profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE];
2875
14.0M
            } else {
2876
14.0M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2877
14.0M
            }
2878
14.0M
            break;
2879
1.74M
        case GS_IMAGE_TAG:
2880
1.74M
            *render_cond = profile_struct->rendercond[GS_IMAGE_DEVICE_PROFILE];
2881
1.74M
            if (profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE] != NULL) {
2882
0
                (*profile) = profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE];
2883
1.74M
            } else {
2884
1.74M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2885
1.74M
            }
2886
1.74M
            break;
2887
573k
        case GS_TEXT_TAG:
2888
573k
            *render_cond = profile_struct->rendercond[GS_TEXT_DEVICE_PROFILE];
2889
573k
            if (profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE] != NULL) {
2890
0
                (*profile) = profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE];
2891
573k
            } else {
2892
573k
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2893
573k
            }
2894
573k
            break;
2895
25.7M
        }
2896
25.7M
}
2897
2898
/* internal ICC and rendering intent override control */
2899
void
2900
gs_setoverrideicc(gs_gstate *pgs, bool value)
2901
34.6k
{
2902
34.6k
    if (pgs->icc_manager != NULL) {
2903
34.6k
        pgs->icc_manager->override_internal = value;
2904
34.6k
    }
2905
34.6k
}
2906
bool
2907
gs_currentoverrideicc(const gs_gstate *pgs)
2908
55.4k
{
2909
55.4k
    if (pgs->icc_manager != NULL) {
2910
55.4k
        return pgs->icc_manager->override_internal;
2911
55.4k
    } else {
2912
0
        return false;
2913
0
    }
2914
55.4k
}
2915
2916
void
2917
gsicc_setrange_lab(cmm_profile_t *profile)
2918
0
{
2919
0
    profile->Range.ranges[0].rmin = 0.0;
2920
0
    profile->Range.ranges[0].rmax = 100.0;
2921
0
    profile->Range.ranges[1].rmin = -128.0;
2922
0
    profile->Range.ranges[1].rmax = 127.0;
2923
0
    profile->Range.ranges[2].rmin = -128.0;
2924
0
    profile->Range.ranges[2].rmax = 127.0;
2925
0
}
2926
2927
#if ICC_DUMP
2928
/* Debug dump of ICC buffer data */
2929
static void
2930
dump_icc_buffer(const gs_memory_t *mem, int buffersize, char filename[],byte *Buffer)
2931
{
2932
    char full_file_name[50];
2933
    gp_file *fid;
2934
2935
    gs_snprintf(full_file_name,sizeof(full_file_name),"%d)%s_debug.icc",global_icc_index,filename);
2936
    fid = gp_fopen(mem, full_file_name,"wb");
2937
    gp_fwrite(Buffer,sizeof(unsigned char),buffersize,fid);
2938
    gp_fclose(fid);
2939
}
2940
#endif
2941
2942
/* The following are for setting the system/user params */
2943
/* No default for the deviceN profile. */
2944
void
2945
gs_currentdevicenicc(const gs_gstate * pgs, gs_param_string * pval)
2946
43.3k
{
2947
43.3k
    static const char *const rfs = "";
2948
2949
    /*FIXME: This should return the entire list !!! */
2950
    /*       Just return the first one for now      */
2951
43.3k
    if (pgs->icc_manager->device_n == NULL) {
2952
43.3k
        pval->data = (const byte *) rfs;
2953
43.3k
        pval->persistent = true;
2954
43.3k
    } else {
2955
0
        pval->data =
2956
0
            (const byte *) (pgs->icc_manager->device_n->head->iccprofile->name);
2957
0
        pval->persistent = false;
2958
0
    }
2959
43.3k
    pval->size = strlen((const char *)pval->data);
2960
43.3k
}
2961
2962
int
2963
gs_setdevicenprofileicc(const gs_gstate * pgs, gs_param_string * pval)
2964
33.1k
{
2965
33.1k
    int code = 0;
2966
33.1k
    char *pname, *pstr, *pstrend, *last = NULL;
2967
33.1k
    int namelen = (pval->size)+1;
2968
33.1k
    gs_memory_t *mem = pgs->memory;
2969
2970
    /* Check if it was "NULL" */
2971
33.1k
    if (pval->size != 0) {
2972
        /* The DeviceN name can have multiple files
2973
           in it.  This way we can define all the
2974
           DeviceN color spaces with ICC profiles.
2975
           divide using , and ; delimeters as well as
2976
           remove leading and ending spaces (file names
2977
           can have internal spaces). */
2978
0
        pname = (char *)gs_alloc_bytes(mem, namelen,
2979
0
                                     "set_devicen_profile_icc");
2980
0
        if (pname == NULL)
2981
0
            return_error(gs_error_VMerror);
2982
0
        memcpy(pname,pval->data,namelen-1);
2983
0
        pname[namelen-1] = 0;
2984
0
        pstr = gs_strtok(pname, ",;", &last);
2985
0
        while (pstr != NULL) {
2986
0
            namelen = strlen(pstr);
2987
            /* Remove leading and trailing spaces from the name */
2988
0
            while ( namelen > 0 && pstr[0] == 0x20) {
2989
0
                pstr++;
2990
0
                namelen--;
2991
0
            }
2992
0
            namelen = strlen(pstr);
2993
0
            pstrend = &(pstr[namelen-1]);
2994
0
            while ( namelen > 0 && pstrend[0] == 0x20) {
2995
0
                pstrend--;
2996
0
                namelen--;
2997
0
            }
2998
0
            code = gsicc_set_profile(pgs->icc_manager, (const char*) pstr, namelen, DEVICEN_TYPE);
2999
0
            if (code < 0)
3000
0
                return gs_throw(code, "cannot find devicen icc profile");
3001
0
            pstr = gs_strtok(NULL, ",;", &last);
3002
0
        }
3003
0
        gs_free_object(mem, pname,
3004
0
        "set_devicen_profile_icc");
3005
0
        return code;
3006
0
    }
3007
33.1k
    return 0;
3008
33.1k
}
3009
3010
void
3011
gs_currentdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3012
43.3k
{
3013
43.3k
    static const char *const rfs = DEFAULT_GRAY_ICC;
3014
3015
43.3k
    if (pgs->icc_manager->default_gray == NULL) {
3016
21.6k
        pval->data = (const byte *) rfs;
3017
21.6k
        pval->persistent = true;
3018
21.6k
    } else {
3019
21.6k
        pval->data = (const byte *) (pgs->icc_manager->default_gray->name);
3020
21.6k
        pval->persistent = false;
3021
21.6k
    }
3022
43.3k
    pval->size = strlen((const char *)pval->data);
3023
43.3k
}
3024
3025
int
3026
gs_setdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3027
33.1k
{
3028
33.1k
    int code;
3029
33.1k
    char *pname;
3030
33.1k
    int namelen = (pval->size)+1;
3031
33.1k
    gs_memory_t *mem = pgs->memory;
3032
33.1k
    bool not_initialized;
3033
3034
    /* Detect if this is our first time in here.  If so, then we need to
3035
       reset up the default gray color spaces that are in the graphic state
3036
       to be ICC based.  It was not possible to do it until after we get
3037
       the profile */
3038
33.1k
    not_initialized = (pgs->icc_manager->default_gray == NULL);
3039
3040
33.1k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3041
33.1k
                             "set_default_gray_icc");
3042
33.1k
    if (pname == NULL)
3043
0
        return_error(gs_error_VMerror);
3044
33.1k
    memcpy(pname,pval->data,namelen-1);
3045
33.1k
    pname[namelen-1] = 0;
3046
33.1k
    code = gsicc_set_profile(pgs->icc_manager,
3047
33.1k
        (const char*) pname, namelen-1, DEFAULT_GRAY);
3048
33.1k
    gs_free_object(mem, pname,
3049
33.1k
        "set_default_gray_icc");
3050
33.1k
    if (code < 0)
3051
0
        return gs_throw(code, "cannot find default gray icc profile");
3052
    /* if this is our first time in here then we need to properly install the
3053
       color spaces that were initialized in the graphic state at this time */
3054
33.1k
    if (not_initialized) {
3055
0
        code = gsicc_init_gs_colors((gs_gstate*) pgs);
3056
0
    }
3057
33.1k
    if (code < 0)
3058
0
        return gs_throw(code, "error initializing gstate color spaces to icc");
3059
33.1k
    return code;
3060
33.1k
}
3061
3062
void
3063
gs_currenticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3064
43.3k
{
3065
43.3k
    static const char *const rfs = DEFAULT_DIR_ICC;   /* as good as any other */
3066
43.3k
    const gs_lib_ctx_t *lib_ctx = pgs->memory->gs_lib_ctx;
3067
3068
43.3k
    if (lib_ctx->profiledir == NULL) {
3069
0
        pval->data = (const byte *)rfs;
3070
0
        pval->size = strlen(rfs);
3071
0
        pval->persistent = true;
3072
43.3k
    } else {
3073
43.3k
        pval->data = (const byte *)(lib_ctx->profiledir);
3074
43.3k
        pval->size = lib_ctx->profiledir_len;
3075
43.3k
        pval->persistent = false;
3076
43.3k
    }
3077
43.3k
}
3078
3079
int
3080
gs_seticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3081
33.1k
{
3082
33.1k
    char *pname;
3083
33.1k
    int namelen = (pval->size)+1;
3084
33.1k
    gs_memory_t *mem = (gs_memory_t *)pgs->memory;
3085
3086
    /* Check if it was "NULL" */
3087
33.1k
    if (pval->size != 0 ) {
3088
33.1k
        pname = (char *)gs_alloc_bytes(mem, namelen,
3089
33.1k
                                       "gs_seticcdirectory");
3090
33.1k
        if (pname == NULL)
3091
0
            return gs_rethrow(gs_error_VMerror, "cannot allocate directory name");
3092
33.1k
        memcpy(pname,pval->data,namelen-1);
3093
33.1k
        pname[namelen-1] = 0;
3094
33.1k
        if (gs_lib_ctx_set_icc_directory(mem, (const char*) pname, namelen-1) < 0) {
3095
0
            gs_free_object(mem, pname, "gs_seticcdirectory");
3096
0
            return -1;
3097
0
        }
3098
33.1k
        gs_free_object(mem, pname, "gs_seticcdirectory");
3099
33.1k
    }
3100
33.1k
    return 0;
3101
33.1k
}
3102
3103
void
3104
gs_currentsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3105
43.3k
{
3106
43.3k
    if (pgs->icc_manager->srcgtag_profile == NULL) {
3107
43.3k
        pval->data = NULL;
3108
43.3k
        pval->size = 0;
3109
43.3k
        pval->persistent = true;
3110
43.3k
    } else {
3111
0
        pval->data = (byte *)pgs->icc_manager->srcgtag_profile->name;
3112
0
        pval->size = pgs->icc_manager->srcgtag_profile->name_length;
3113
0
        pval->persistent = false;
3114
0
    }
3115
43.3k
}
3116
3117
int
3118
gs_setsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3119
33.1k
{
3120
33.1k
    int code;
3121
33.1k
    char *pname;
3122
33.1k
    int namelen = (pval->size)+1;
3123
33.1k
    gs_memory_t *mem = pgs->memory;
3124
3125
33.1k
    if (pval->size == 0) return 0;
3126
0
    pname = (char *)gs_alloc_bytes(mem, namelen, "set_srcgtag_icc");
3127
0
    if (pname == NULL)
3128
0
        return_error(gs_error_VMerror);
3129
0
    memcpy(pname,pval->data,namelen-1);
3130
0
    pname[namelen-1] = 0;
3131
0
    code = gsicc_set_srcgtag_struct(pgs->icc_manager, (const char*) pname,
3132
0
                                   namelen);
3133
0
    gs_free_object(mem, pname, "set_srcgtag_icc");
3134
0
    if (code < 0)
3135
0
        return gs_rethrow(code, "cannot find srctag file");
3136
0
    return code;
3137
0
}
3138
3139
void
3140
gs_currentdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval)
3141
43.3k
{
3142
43.3k
    static const char *const rfs = DEFAULT_RGB_ICC;
3143
3144
43.3k
    if (pgs->icc_manager->default_rgb == NULL) {
3145
21.6k
        pval->data = (const byte *) rfs;
3146
21.6k
        pval->persistent = true;
3147
21.6k
    } else {
3148
21.6k
        pval->data = (const byte *) (pgs->icc_manager->default_rgb->name);
3149
21.6k
        pval->persistent = false;
3150
21.6k
    }
3151
43.3k
    pval->size = strlen((const char *)pval->data);
3152
43.3k
}
3153
3154
int
3155
gs_setdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval)
3156
33.1k
{
3157
33.1k
    int code;
3158
33.1k
    char *pname;
3159
33.1k
    int namelen = (pval->size)+1;
3160
33.1k
    gs_memory_t *mem = pgs->memory;
3161
3162
33.1k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3163
33.1k
                             "set_default_rgb_icc");
3164
33.1k
    if (pname == NULL)
3165
0
        return_error(gs_error_VMerror);
3166
33.1k
    memcpy(pname,pval->data,namelen-1);
3167
33.1k
    pname[namelen-1] = 0;
3168
33.1k
    code = gsicc_set_profile(pgs->icc_manager,
3169
33.1k
        (const char*) pname, namelen-1, DEFAULT_RGB);
3170
33.1k
    gs_free_object(mem, pname,
3171
33.1k
        "set_default_rgb_icc");
3172
33.1k
    if (code < 0)
3173
0
        return gs_rethrow(code, "cannot find default rgb icc profile");
3174
33.1k
    return code;
3175
33.1k
}
3176
3177
void
3178
gs_currentnamedicc(const gs_gstate * pgs, gs_param_string * pval)
3179
43.3k
{
3180
43.3k
    static const char *const rfs = "";
3181
3182
43.3k
    if (pgs->icc_manager->device_named == NULL) {
3183
43.3k
        pval->data = (const byte *) rfs;
3184
43.3k
        pval->persistent = true;
3185
43.3k
    } else {
3186
0
        pval->data = (const byte *) (pgs->icc_manager->device_named->name);
3187
0
        pval->persistent = false;
3188
0
    }
3189
43.3k
    pval->size = strlen((const char *)pval->data);
3190
43.3k
}
3191
3192
int
3193
gs_setnamedprofileicc(const gs_gstate * pgs, gs_param_string * pval)
3194
33.1k
{
3195
33.1k
    int code;
3196
33.1k
    char* pname;
3197
33.1k
    int namelen = (pval->size)+1;
3198
33.1k
    gs_memory_t *mem = pgs->memory;
3199
3200
    /* Check if it was "NULL" */
3201
33.1k
    if (pval->size != 0) {
3202
0
        pname = (char *)gs_alloc_bytes(mem, namelen,
3203
0
                                 "set_named_profile_icc");
3204
0
        if (pname == NULL)
3205
0
            return_error(gs_error_VMerror);
3206
0
        memcpy(pname,pval->data,namelen-1);
3207
0
        pname[namelen-1] = 0;
3208
0
        code = gsicc_set_profile(pgs->icc_manager,
3209
0
            (const char*) pname, namelen-1, NAMED_TYPE);
3210
0
        gs_free_object(mem, pname,
3211
0
                "set_named_profile_icc");
3212
0
        if (code < 0)
3213
0
            return gs_rethrow(code, "cannot find named color icc profile");
3214
0
        return code;
3215
0
    }
3216
33.1k
    return 0;
3217
33.1k
}
3218
3219
void
3220
gs_currentdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3221
43.3k
{
3222
43.3k
    static const char *const rfs = DEFAULT_CMYK_ICC;
3223
3224
43.3k
    if (pgs->icc_manager->default_cmyk == NULL) {
3225
21.6k
        pval->data = (const byte *) rfs;
3226
21.6k
        pval->persistent = true;
3227
21.6k
    } else {
3228
21.6k
        pval->data = (const byte *) (pgs->icc_manager->default_cmyk->name);
3229
21.6k
        pval->persistent = false;
3230
21.6k
    }
3231
43.3k
    pval->size = strlen((const char *)pval->data);
3232
43.3k
}
3233
3234
int
3235
gs_setdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3236
33.1k
{
3237
33.1k
    int code;
3238
33.1k
    char* pname;
3239
33.1k
    int namelen = (pval->size)+1;
3240
33.1k
    gs_memory_t *mem = pgs->memory;
3241
3242
33.1k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3243
33.1k
                             "set_default_cmyk_icc");
3244
33.1k
    if (pname == NULL)
3245
0
        return_error(gs_error_VMerror);
3246
33.1k
    memcpy(pname,pval->data,namelen-1);
3247
33.1k
    pname[namelen-1] = 0;
3248
33.1k
    code = gsicc_set_profile(pgs->icc_manager,
3249
33.1k
        (const char*) pname, namelen-1, DEFAULT_CMYK);
3250
33.1k
    gs_free_object(mem, pname,
3251
33.1k
                "set_default_cmyk_icc");
3252
33.1k
    if (code < 0)
3253
0
        return gs_throw(code, "cannot find default cmyk icc profile");
3254
33.1k
    return code;
3255
33.1k
}
3256
3257
void
3258
gs_currentlabicc(const gs_gstate * pgs, gs_param_string * pval)
3259
43.3k
{
3260
43.3k
    static const char *const rfs = LAB_ICC;
3261
3262
43.3k
    pval->data = (const byte *)( (pgs->icc_manager->lab_profile == NULL) ?
3263
21.6k
                        rfs : pgs->icc_manager->lab_profile->name);
3264
43.3k
    pval->size = strlen((const char *)pval->data);
3265
43.3k
    pval->persistent = true;
3266
43.3k
}
3267
3268
int
3269
gs_setlabicc(const gs_gstate * pgs, gs_param_string * pval)
3270
33.1k
{
3271
33.1k
    int code;
3272
33.1k
    char* pname;
3273
33.1k
    int namelen = (pval->size)+1;
3274
33.1k
    gs_memory_t *mem = pgs->memory;
3275
3276
33.1k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3277
33.1k
                             "set_lab_icc");
3278
33.1k
    if (pname == NULL)
3279
0
        return_error(gs_error_VMerror);
3280
33.1k
    memcpy(pname,pval->data,namelen-1);
3281
33.1k
    pname[namelen-1] = 0;
3282
33.1k
    code = gsicc_set_profile(pgs->icc_manager,
3283
33.1k
        (const char*) pname, namelen-1, LAB_TYPE);
3284
33.1k
    gs_free_object(mem, pname,
3285
33.1k
                "set_lab_icc");
3286
33.1k
    if (code < 0)
3287
0
        return gs_throw(code, "cannot find default lab icc profile");
3288
33.1k
    return code;
3289
33.1k
}