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
13.5M
#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
1.55M
{
119
1.55M
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
120
121
1.55M
    ctx->icc_color_accuracy = level;
122
1.55M
}
123
124
uint
125
gsicc_currentcoloraccuracy(gs_memory_t *mem)
126
1.55M
{
127
1.55M
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
128
129
1.55M
    return ctx->icc_color_accuracy;
130
1.55M
}
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
2.80k
{
145
2.80k
    if (icc_profile == NULL || icc_profile->buffer == NULL)
146
0
        return -1;
147
148
2.80k
    *major = icc_profile->buffer[8];
149
2.80k
    *minor = icc_profile->buffer[9];
150
151
2.80k
    return 0;
152
2.80k
}
153
154
void
155
gsicc_set_icc_range(cmm_profile_t **icc_profile)
156
13.5M
{
157
13.5M
    int num_comp = (*icc_profile)->num_comps;
158
13.5M
    int k;
159
160
50.8M
    for ( k = 0; k < num_comp; k++) {
161
37.2M
        (*icc_profile)->Range.ranges[k].rmin = 0.0;
162
37.2M
        (*icc_profile)->Range.ranges[k].rmax = 1.0;
163
37.2M
    }
164
13.5M
}
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
66.1k
{
171
66.1k
    stream *str;
172
66.1k
    int code;
173
66.1k
    cmm_profile_t *icc_profile;
174
175
66.1k
    if (icc_manager == NULL) {
176
0
        code = gsicc_open_search(pname, namelen, mem, NULL, 0, &str);
177
66.1k
    } else {
178
66.1k
        code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
179
66.1k
                                 mem->gs_lib_ctx->profiledir_len, &str);
180
66.1k
    }
181
66.1k
    if (code < 0 || str == NULL)
182
0
        return NULL;
183
66.1k
    icc_profile = gsicc_profile_new(str, mem, pname, namelen);
184
66.1k
    code = sfclose(str);
185
66.1k
    if (icc_profile == NULL)
186
0
        return NULL;
187
    /* Get the profile handle */
188
66.1k
    icc_profile->profile_handle =
189
66.1k
            gsicc_get_profile_handle_buffer(icc_profile->buffer,
190
66.1k
                                            icc_profile->buffer_size,
191
66.1k
                                            mem);
192
66.1k
    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
66.1k
    gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode),
199
66.1k
                            icc_profile->buffer_size);
200
66.1k
    icc_profile->hash_is_valid = true;
201
66.1k
    icc_profile->num_comps =
202
66.1k
            gscms_get_input_channel_count(icc_profile->profile_handle, icc_profile->memory);
203
66.1k
    icc_profile->num_comps_out =
204
66.1k
            gscms_get_output_channel_count(icc_profile->profile_handle, icc_profile->memory);
205
66.1k
    icc_profile->data_cs =
206
66.1k
            gscms_get_profile_data_space(icc_profile->profile_handle, icc_profile->memory);
207
66.1k
    gsicc_set_icc_range(&icc_profile);
208
66.1k
    return icc_profile;
209
66.1k
}
210
211
static void
212
gsicc_smask_finalize(const gs_memory_t *memory, void * vptr)
213
60.0k
{
214
60.0k
    gsicc_smask_t *iccsmask = (gsicc_smask_t *)vptr;
215
216
60.0k
    gsicc_adjust_profile_rc(iccsmask->smask_gray, -1,
217
60.0k
        "gsicc_smask_finalize");
218
60.0k
    gsicc_adjust_profile_rc(iccsmask->smask_rgb, -1,
219
60.0k
        "gsicc_smask_finalize");
220
60.0k
    gsicc_adjust_profile_rc(iccsmask->smask_cmyk, -1,
221
60.0k
        "gsicc_smask_finalize");
222
60.0k
}
223
224
gsicc_smask_t*
225
gsicc_new_iccsmask(gs_memory_t *memory)
226
60.0k
{
227
60.0k
    gsicc_smask_t *result;
228
229
60.0k
    result = (gsicc_smask_t *) gs_alloc_struct(memory, gsicc_smask_t, &st_gsicc_smask, "gsicc_new_iccsmask");
230
60.0k
    if (result != NULL) {
231
60.0k
        result->smask_gray = NULL;
232
60.0k
        result->smask_rgb = NULL;
233
60.0k
        result->smask_cmyk = NULL;
234
60.0k
        result->memory = memory;
235
60.0k
        result->swapped = false;
236
60.0k
    }
237
60.0k
    return result;
238
60.0k
}
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
17.6k
{
245
17.6k
    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
17.6k
    icc_manager->smask_profiles = gsicc_new_iccsmask(stable_mem);
250
17.6k
    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
17.6k
    if ((icc_manager->smask_profiles->smask_gray =
254
17.6k
        gsicc_set_iccsmaskprofile(SMASK_GRAY_ICC, strlen(SMASK_GRAY_ICC),
255
17.6k
        icc_manager, stable_mem) ) == NULL)
256
0
        goto error;
257
17.6k
    if ((icc_manager->smask_profiles->smask_rgb =
258
17.6k
        gsicc_set_iccsmaskprofile(SMASK_RGB_ICC, strlen(SMASK_RGB_ICC),
259
17.6k
        icc_manager, stable_mem)) == NULL)
260
0
        goto error;
261
17.6k
    if ((icc_manager->smask_profiles->smask_cmyk =
262
17.6k
        gsicc_set_iccsmaskprofile(SMASK_CMYK_ICC, strlen(SMASK_CMYK_ICC),
263
17.6k
        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
17.6k
    icc_manager->smask_profiles->smask_gray->default_match = DEFAULT_GRAY;
270
17.6k
    icc_manager->smask_profiles->smask_rgb->default_match = DEFAULT_RGB;
271
17.6k
    icc_manager->smask_profiles->smask_cmyk->default_match = DEFAULT_CMYK;
272
17.6k
    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
17.6k
}
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
2.35M
{
496
2.35M
    switch (profile_data->default_match) {
497
580k
        case DEFAULT_GRAY:
498
580k
            return gs_color_space_index_DeviceGray;
499
1.20M
        case DEFAULT_RGB:
500
1.20M
            return gs_color_space_index_DeviceRGB;
501
192k
        case DEFAULT_CMYK:
502
192k
            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
377k
        default:
512
377k
            return gs_color_space_index_ICC;
513
2.35M
    }
514
2.35M
}
515
516
int
517
gsicc_use_fast_color(cmm_profile_t* profile_data)
518
197M
{
519
197M
    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
1.18M
    case LAB_TYPE:
525
1.18M
    case NAMED_TYPE:
526
1.18M
    case DEVICEN_TYPE:
527
1.18M
        return 0;
528
195M
    default:
529
195M
        return profile_data->num_comps;
530
197M
    }
531
197M
}
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
471k
{
549
471k
    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
471k
        default:
556
471k
            return false;
557
471k
    }
558
471k
}
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
90.8M
{
569
90.8M
    if (profile_data != NULL) {
570
84.4M
        gx_monitor_enter(profile_data->lock);
571
84.4M
        if (profile_data->rc.ref_count == 1 && delta < 0) {
572
14.7M
            profile_data->rc.ref_count = 0;   /* while locked */
573
14.7M
            gx_monitor_leave(profile_data->lock);
574
14.7M
            rc_free_struct(profile_data, name_str);
575
69.7M
        } else {
576
69.7M
            rc_adjust(profile_data, delta, name_str);
577
69.7M
            gx_monitor_leave(profile_data->lock);
578
69.7M
        }
579
84.4M
    }
580
90.8M
}
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
13
{
632
13
    return gscms_get_device_class(icc_profile->profile_handle, icc_profile->memory);
633
13
}
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
14.6M
{
898
14.6M
    cmm_profile_t *icc_profile;
899
14.6M
    cmm_profile_t **manager_default_profile = NULL; /* quite compiler */
900
14.6M
    stream *str;
901
14.6M
    gs_memory_t *mem_gc = icc_manager->memory;
902
14.6M
    int code;
903
14.6M
    int k;
904
14.6M
    int num_comps = 0;
905
14.6M
    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
14.6M
    default_space = gsUNDEFINED;
913
14.6M
    if (icc_manager->smask_profiles !=NULL &&
914
14.6M
        icc_manager->smask_profiles->swapped == true) {
915
0
            return 0;
916
14.6M
    } else {
917
14.6M
        switch(defaulttype) {
918
3.63M
            case DEFAULT_GRAY:
919
3.63M
                manager_default_profile = &(icc_manager->default_gray);
920
3.63M
                default_space = gsGRAY;
921
3.63M
                num_comps = 1;
922
3.63M
                break;
923
3.63M
            case DEFAULT_RGB:
924
3.63M
                manager_default_profile = &(icc_manager->default_rgb);
925
3.63M
                default_space = gsRGB;
926
3.63M
                num_comps = 3;
927
3.63M
                break;
928
3.63M
            case DEFAULT_CMYK:
929
3.63M
                 manager_default_profile = &(icc_manager->default_cmyk);
930
3.63M
                 default_space = gsCMYK;
931
3.63M
                 num_comps = 4;
932
3.63M
                 break;
933
0
            case NAMED_TYPE:
934
0
                 manager_default_profile = &(icc_manager->device_named);
935
0
                 default_space = gsNAMED;
936
0
                 break;
937
3.73M
            case LAB_TYPE:
938
3.73M
                 manager_default_profile = &(icc_manager->lab_profile);
939
3.73M
                 num_comps = 3;
940
3.73M
                 default_space = gsCIELAB;
941
3.73M
                 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
14.6M
        }
951
14.6M
    }
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
14.6M
    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
2.25M
        icc_profile = *manager_default_profile;
963
2.25M
        if ( namelen == icc_profile->name_length ) {
964
2.25M
            if( memcmp(pname, icc_profile->name, namelen) == 0)
965
2.25M
                return 0;
966
2.25M
        }
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
12.3M
    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
12.3M
    code = gsicc_open_search(pname, namelen, mem_gc, mem_gc->gs_lib_ctx->profiledir,
1017
12.3M
                             mem_gc->gs_lib_ctx->profiledir_len, &str);
1018
12.3M
    if (code < 0)
1019
0
        return code;
1020
12.3M
    if (str != NULL) {
1021
12.3M
        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
12.3M
        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
12.3M
        code = sfclose(str);
1050
12.3M
        if (icc_profile == NULL) {
1051
0
            return gs_throw1(-1, "problems with profile %s",pname);
1052
0
        }
1053
12.3M
         *manager_default_profile = icc_profile;
1054
12.3M
        icc_profile->default_match = defaulttype;
1055
12.3M
        if (defaulttype == LAB_TYPE)
1056
3.09M
            icc_profile->islab = true;
1057
12.3M
        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
12.3M
        } 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
12.3M
            icc_profile->num_comps = num_comps;
1072
12.3M
            icc_profile->num_comps_out = 3;
1073
12.3M
            gsicc_set_icc_range(&icc_profile);
1074
12.3M
            icc_profile->data_cs = default_space;
1075
12.3M
        }
1076
12.3M
        return 0;
1077
12.3M
    }
1078
0
    return -1;
1079
12.3M
}
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
291k
{
1089
291k
    gsicc_profile_t defaulttype = icc_profile->default_match;
1090
291k
    gsicc_colorbuffer_t default_space = gsUNDEFINED;
1091
291k
    int num_comps, num_comps_out;
1092
291k
    gs_memory_t *mem = icc_profile->memory;
1093
1094
    /* Get the profile handle if it is not already set */
1095
291k
    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
291k
    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
291k
    num_comps = icc_profile->num_comps;
1112
291k
    icc_profile->num_comps =
1113
291k
        gscms_get_input_channel_count(icc_profile->profile_handle,
1114
291k
            icc_profile->memory);
1115
291k
    num_comps_out = icc_profile->num_comps_out;
1116
291k
    icc_profile->num_comps_out =
1117
291k
        gscms_get_output_channel_count(icc_profile->profile_handle,
1118
291k
            icc_profile->memory);
1119
291k
    icc_profile->data_cs =
1120
291k
        gscms_get_profile_data_space(icc_profile->profile_handle,
1121
291k
            icc_profile->memory);
1122
291k
    if_debug0m(gs_debug_flag_icc,mem,"[icc] Setting ICC profile in Manager\n");
1123
291k
    switch(defaulttype) {
1124
252k
        case DEFAULT_GRAY:
1125
252k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default Gray\n");
1126
252k
            default_space = gsGRAY;
1127
252k
            break;
1128
28.7k
        case DEFAULT_RGB:
1129
28.7k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default RGB\n");
1130
28.7k
            default_space = gsRGB;
1131
28.7k
            break;
1132
7.42k
        case DEFAULT_CMYK:
1133
7.42k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default CMYK\n");
1134
7.42k
            default_space = gsCMYK;
1135
7.42k
             break;
1136
0
        case NAMED_TYPE:
1137
0
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Named Color\n");
1138
0
            break;
1139
447
        case LAB_TYPE:
1140
447
            if_debug0m(gs_debug_flag_icc,mem,"[icc] CIELAB Profile\n");
1141
447
            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
2.16k
        default:
1147
2.16k
            return 0;
1148
0
            break;
1149
291k
    }
1150
291k
    if_debug1m(gs_debug_flag_icc,mem,"[icc] name = %s\n", icc_profile->name);
1151
289k
    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
289k
    if (default_space != gsUNDEFINED ||
1155
289k
        num_comps != icc_profile->num_comps ||
1156
289k
        num_comps_out != icc_profile->num_comps_out) {
1157
288k
        if (icc_profile->data_cs != default_space) {
1158
0
            return gs_rethrow(-1, "A default profile has an incorrect color space");
1159
0
        }
1160
288k
    }
1161
289k
    return 0;
1162
289k
}
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
4.95k
{
1168
4.95k
    cmm_profile_t *result;
1169
4.95k
    stream* str;
1170
4.95k
    int code;
1171
1172
    /* First see if we can get the stream. */
1173
4.95k
    code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
1174
4.95k
        mem->gs_lib_ctx->profiledir_len, &str);
1175
4.95k
    if (code < 0 || str == NULL) {
1176
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1177
0
        return NULL;
1178
0
    }
1179
4.95k
    result = gsicc_profile_new(str, mem, pname, namelen);
1180
4.95k
    code = sfclose(str);
1181
4.95k
    if (result == NULL) {
1182
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1183
0
        return NULL;
1184
0
    }
1185
4.95k
    code = gsicc_init_profile_info(result);
1186
4.95k
    if (code < 0) {
1187
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1188
0
        return NULL;
1189
0
    }
1190
4.95k
    return result;
1191
4.95k
}
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
4.95k
{
1198
4.95k
    int k;
1199
1200
    /* Get the profile handle */
1201
4.95k
    profile->profile_handle =
1202
4.95k
        gsicc_get_profile_handle_buffer(profile->buffer,
1203
4.95k
                                        profile->buffer_size,
1204
4.95k
                                        profile->memory);
1205
4.95k
    if (profile->profile_handle == NULL)
1206
0
        return -1;
1207
1208
    /* Compute the hash code of the profile. */
1209
4.95k
    gsicc_get_icc_buff_hash(profile->buffer, &(profile->hashcode),
1210
4.95k
                            profile->buffer_size);
1211
4.95k
    profile->hash_is_valid = true;
1212
4.95k
    profile->default_match = DEFAULT_NONE;
1213
4.95k
    profile->num_comps = gscms_get_input_channel_count(profile->profile_handle,
1214
4.95k
        profile->memory);
1215
4.95k
    profile->num_comps_out = gscms_get_output_channel_count(profile->profile_handle,
1216
4.95k
        profile->memory);
1217
4.95k
    profile->data_cs = gscms_get_profile_data_space(profile->profile_handle,
1218
4.95k
        profile->memory);
1219
1220
    /* Initialize the range to default values */
1221
11.7k
    for ( k = 0; k < profile->num_comps; k++) {
1222
6.76k
        profile->Range.ranges[k].rmin = 0.0;
1223
6.76k
        profile->Range.ranges[k].rmax = 1.0;
1224
6.76k
    }
1225
4.95k
    return 0;
1226
4.95k
}
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
12.7M
{
1235
12.7M
    char *buffer;
1236
12.7M
    stream* str;
1237
1238
    /* Check if we need to prepend the file name  */
1239
12.7M
    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
12.7M
        buffer = (char *) gs_alloc_bytes(mem_gc, namelen + dirlen + 1,
1246
12.7M
                                     "gsicc_open_search");
1247
12.7M
        if (buffer == NULL)
1248
0
            return_error(gs_error_VMerror);
1249
12.7M
        memcpy(buffer, dirname, dirlen);
1250
12.7M
        memcpy(buffer + dirlen, pname, namelen);
1251
        /* Just to make sure we were null terminated */
1252
12.7M
        buffer[namelen + dirlen] = '\0';
1253
1254
12.7M
        if (gs_check_file_permission(mem_gc, buffer, strlen(buffer), "r") >= 0) {
1255
12.7M
            str = sfopen(buffer, "r", mem_gc);
1256
12.7M
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1257
12.7M
            if (str != NULL) {
1258
12.7M
                *strp = str;
1259
12.7M
                return 0;
1260
12.7M
            }
1261
12.7M
        }
1262
0
        else {
1263
0
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1264
0
        }
1265
12.7M
    }
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
2.01M
{
1403
2.01M
    cmm_dev_profile_t *icc_struct = (cmm_dev_profile_t *)ptr_in;
1404
2.01M
    int k;
1405
2.01M
    gs_memory_t *mem_nongc =  icc_struct->memory;
1406
1407
2.01M
    if (icc_struct->rc.ref_count <= 1 ) {
1408
        /* Decrement any profiles. */
1409
10.0M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1410
8.07M
            if (icc_struct->device_profile[k] != NULL) {
1411
1.90M
                if_debug1m(gs_debug_flag_icc, mem_nongc,
1412
1.90M
                           "[icc] Releasing device profile %d\n", k);
1413
1.90M
                gsicc_adjust_profile_rc(icc_struct->device_profile[k], -1,
1414
1.90M
                             "rc_free_profile_array");
1415
1.90M
            }
1416
8.07M
        }
1417
2.01M
        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
2.01M
        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
2.01M
        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
2.01M
        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
2.01M
        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
2.01M
        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
2.01M
        if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing device profile struct\n");
1445
2.01M
        gs_free_object(mem_nongc, icc_struct, "rc_free_profile_array");
1446
2.01M
    }
1447
2.01M
}
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
2.01M
{
1453
2.01M
    cmm_dev_profile_t *result;
1454
2.01M
    int k;
1455
2.01M
    gs_memory_t *memory = dev->memory;
1456
1457
2.01M
    if_debug0m(gs_debug_flag_icc,memory,"[icc] Allocating device profile struct\n");
1458
2.01M
    result = (cmm_dev_profile_t *) gs_alloc_bytes(memory->non_gc_memory,
1459
2.01M
                                            sizeof(cmm_dev_profile_t),
1460
2.01M
                                            "gsicc_new_device_profile_array");
1461
2.01M
    if (result == NULL)
1462
0
        return NULL;
1463
2.01M
    result->memory = memory->non_gc_memory;
1464
1465
10.0M
    for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1466
8.07M
        result->device_profile[k] = NULL;
1467
8.07M
        result->rendercond[k].rendering_intent = gsRINOTSPECIFIED;
1468
8.07M
        result->rendercond[k].black_point_comp = gsBPNOTSPECIFIED;
1469
8.07M
        result->rendercond[k].override_icc = false;
1470
8.07M
        result->rendercond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1471
8.07M
        result->rendercond[k].graphics_type_tag = GS_UNKNOWN_TAG;
1472
8.07M
        result->rendercond[k].cmm = gsCMM_DEFAULT;
1473
8.07M
    }
1474
2.01M
    result->proof_profile = NULL;
1475
2.01M
    result->link_profile = NULL;
1476
2.01M
    result->postren_profile = NULL;
1477
2.01M
    result->blend_profile = NULL;
1478
2.01M
    result->oi_profile = NULL;
1479
2.01M
    result->spotnames = NULL;
1480
2.01M
    result->devicegraytok = true;  /* Default is to map gray to pure K */
1481
2.01M
    result->graydetection = false;
1482
2.01M
    result->pageneutralcolor = false;
1483
2.01M
    result->usefastcolor = false;  /* Default is to not use fast color */
1484
2.01M
    result->blacktext = false;
1485
2.01M
    result->blackvector = false;
1486
2.01M
    result->blackthresholdL = 90.0F;
1487
2.01M
    result->blackthresholdC = 0.0F;
1488
2.01M
    result->prebandthreshold = true;
1489
2.01M
    result->supports_devn = false;
1490
2.01M
    result->overprint_control = gs_overprint_control_enable;  /* Default overprint if the device can */
1491
2.01M
    rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array);
1492
2.01M
    return result;
1493
2.01M
}
1494
1495
int
1496
gsicc_set_device_blackpreserve(gx_device *dev, gsicc_blackpreserve_t blackpreserve,
1497
                                gsicc_profile_types_t profile_type)
1498
6.22M
{
1499
6.22M
    int code;
1500
6.22M
    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
6.22M
    if (dev_proc(dev, get_profile) == NULL) {
1507
2.22M
        profile_struct = dev->icc_struct;
1508
4.00M
    } else {
1509
4.00M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1510
4.00M
        if (code < 0)
1511
0
            return code;
1512
4.00M
    }
1513
6.22M
    if (profile_struct ==  NULL)
1514
0
        return 0;
1515
6.22M
    profile_struct->rendercond[profile_type].preserve_black = blackpreserve;
1516
6.22M
    return 0;
1517
6.22M
}
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
6.22M
{
1523
6.22M
    int code;
1524
6.22M
    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
6.22M
    if (dev_proc(dev, get_profile) == NULL) {
1531
2.22M
        profile_struct = dev->icc_struct;
1532
4.00M
    } else {
1533
4.00M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1534
4.00M
        if (code < 0)
1535
0
            return code;
1536
4.00M
    }
1537
6.22M
    if (profile_struct ==  NULL)
1538
0
        return 0;
1539
6.22M
    profile_struct->rendercond[profile_type].rendering_intent = intent;
1540
6.22M
    return 0;
1541
6.22M
}
1542
1543
int
1544
gsicc_set_device_blackptcomp(gx_device *dev, gsicc_blackptcomp_t blackptcomp,
1545
                                gsicc_profile_types_t profile_type)
1546
6.22M
{
1547
6.22M
    int code = 0;
1548
6.22M
    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
6.22M
    if (dev_proc(dev, get_profile) == NULL) {
1555
2.22M
        profile_struct = dev->icc_struct;
1556
4.00M
    } else {
1557
4.00M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1558
4.00M
    }
1559
6.22M
    if (profile_struct ==  NULL)
1560
0
        return 0;
1561
6.22M
    profile_struct->rendercond[profile_type].black_point_comp = blackptcomp;
1562
6.22M
    return code;
1563
6.22M
}
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
317k
{
1755
317k
    int code;
1756
317k
    cmm_profile_t *curr_profile;
1757
317k
    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
317k
    profile_struct = dev->icc_struct;
1764
317k
    if (profile_struct != NULL) {
1765
        /* Get the profile of interest */
1766
190k
        if (profile_type < gsPROOFPROFILE) {
1767
190k
            curr_profile = profile_struct->device_profile[profile_type];
1768
190k
        } 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
190k
        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
68.1k
            if (profile_name != NULL && curr_profile->name != NULL) {
1785
68.1k
                if (strncmp(curr_profile->name, profile_name,
1786
68.1k
                            strlen(profile_name)) != 0 &&
1787
68.1k
                    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
68.1k
                } else {
1811
                    /* Nothing to change.  It was either the same or is the
1812
                       output intent */
1813
68.1k
                    return 0;
1814
68.1k
                }
1815
68.1k
            }
1816
68.1k
        }
1817
190k
    } else {
1818
        /* We have no profile structure at all. Allocate the structure in
1819
           non-GC memory.  */
1820
126k
        dev->icc_struct = gsicc_new_device_profile_array(dev);
1821
126k
        profile_struct = dev->icc_struct;
1822
126k
        if (profile_struct == NULL)
1823
0
            return_error(gs_error_VMerror);
1824
126k
    }
1825
    /* Either use the incoming or a default */
1826
249k
    if (profile_name == NULL) {
1827
220k
        int has_tags = device_encodes_tags(dev);
1828
220k
        profile_name =
1829
220k
            (char *) gs_alloc_bytes(dev->memory,
1830
220k
                                    MAX_DEFAULT_ICC_LENGTH,
1831
220k
                                    "gsicc_init_device_profile_struct");
1832
220k
        if (profile_name == NULL)
1833
0
            return_error(gs_error_VMerror);
1834
220k
        switch(dev->color_info.num_components - has_tags) {
1835
131k
            case 1:
1836
131k
                strncpy(profile_name, DEFAULT_GRAY_ICC, strlen(DEFAULT_GRAY_ICC));
1837
131k
                profile_name[strlen(DEFAULT_GRAY_ICC)] = 0;
1838
131k
                break;
1839
79.0k
            case 3:
1840
79.0k
                strncpy(profile_name, DEFAULT_RGB_ICC, strlen(DEFAULT_RGB_ICC));
1841
79.0k
                profile_name[strlen(DEFAULT_RGB_ICC)] = 0;
1842
79.0k
                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
10.6k
            default:
1848
10.6k
                strncpy(profile_name, DEFAULT_CMYK_ICC, strlen(DEFAULT_CMYK_ICC));
1849
10.6k
                profile_name[strlen(DEFAULT_CMYK_ICC)] = 0;
1850
10.6k
                break;
1851
220k
        }
1852
        /* Go ahead and set the profile */
1853
220k
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1854
220k
                                        profile_type);
1855
220k
        gs_free_object(dev->memory, profile_name,
1856
220k
                       "gsicc_init_device_profile_struct");
1857
220k
        return code;
1858
220k
    } else {
1859
        /* Go ahead and set the profile */
1860
28.1k
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1861
28.1k
                                        profile_type);
1862
28.1k
        return code;
1863
28.1k
    }
1864
249k
}
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
321k
{
1883
321k
    int k;
1884
321k
    cmm_dev_profile_t *dev_icc = pdev->icc_struct;
1885
321k
    bool check_components = true;
1886
321k
    bool can_postrender = false;
1887
321k
    bool objects = false;
1888
321k
    int has_tags = device_encodes_tags(pdev);
1889
321k
    int num_components = pdev->color_info.num_components - has_tags;
1890
1891
321k
    if (dev_proc(pdev, dev_spec_op) != NULL) {
1892
321k
        check_components = !(dev_proc(pdev, dev_spec_op)(pdev, gxdso_skip_icc_component_validation, NULL, 0));
1893
321k
        can_postrender = dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_iccpostrender, NULL, 0);
1894
321k
    }
1895
1896
321k
    if (dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE] == NULL)
1897
0
        return 0;
1898
1899
321k
    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
321k
    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
321k
    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
1.28M
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
1924
963k
        if (dev_icc->device_profile[k] != NULL) {
1925
0
            objects = true;
1926
0
            break;
1927
0
        }
1928
963k
    }
1929
1930
321k
    if (dev_icc->link_profile == NULL) {
1931
321k
        if (!objects) {
1932
321k
            if (check_components && dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps !=
1933
147k
                num_components)
1934
12
                return gs_rethrow(-1, "Mismatch of ICC profiles and device color model");
1935
321k
            else
1936
321k
                return 0;  /* Currently sep devices have some leeway here */
1937
321k
        } 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
321k
    } 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
321k
}
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
321k
{
1977
321k
    cmm_profile_t *icc_profile;
1978
321k
    stream *str;
1979
321k
    int code;
1980
1981
321k
    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
321k
    if (strncmp(file_name, OI_PROFILE, strlen(OI_PROFILE)) == 0)
1993
0
        return -1;
1994
1995
321k
    code = gsicc_open_search(file_name, strlen(file_name), mem,
1996
321k
                             mem->gs_lib_ctx->profiledir,
1997
321k
                             mem->gs_lib_ctx->profiledir_len, &str);
1998
321k
    if (code < 0)
1999
0
        return code;
2000
321k
    if (str == NULL)
2001
0
        return gs_rethrow(-1, "cannot find device profile");
2002
2003
321k
    icc_profile =
2004
321k
            gsicc_profile_new(str, mem, file_name, strlen(file_name));
2005
321k
    code = sfclose(str);
2006
321k
    if (icc_profile == NULL)
2007
0
        return gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
2008
2009
    /* Get the profile handle */
2010
321k
    icc_profile->profile_handle =
2011
321k
                gsicc_get_profile_handle_buffer(icc_profile->buffer,
2012
321k
                                                icc_profile->buffer_size,
2013
321k
                                                mem);
2014
321k
    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
321k
    gsicc_get_icc_buff_hash(icc_profile->buffer,
2022
321k
                            &(icc_profile->hashcode),
2023
321k
                            icc_profile->buffer_size);
2024
321k
    icc_profile->hash_is_valid = true;
2025
2026
    /* Get the number of channels in the output profile */
2027
321k
    icc_profile->num_comps =
2028
321k
                gscms_get_input_channel_count(icc_profile->profile_handle,
2029
321k
                                              icc_profile->memory);
2030
321k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile has %d components\n",
2031
321k
               icc_profile->num_comps);
2032
321k
    icc_profile->num_comps_out =
2033
321k
                gscms_get_output_channel_count(icc_profile->profile_handle,
2034
321k
                                               icc_profile->memory);
2035
321k
    icc_profile->data_cs =
2036
321k
                gscms_get_profile_data_space(icc_profile->profile_handle,
2037
321k
                                             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
321k
    switch (icc_profile->num_comps) {
2046
169k
        case 1:
2047
169k
            if (strncmp(icc_profile->name, DEFAULT_GRAY_ICC,
2048
169k
                        strlen(icc_profile->name)) == 0) {
2049
169k
                icc_profile->default_match = DEFAULT_GRAY;
2050
169k
            }
2051
169k
            break;
2052
138k
        case 3:
2053
138k
            if (strncmp(icc_profile->name, DEFAULT_RGB_ICC,
2054
138k
                        strlen(icc_profile->name)) == 0) {
2055
138k
                icc_profile->default_match = DEFAULT_RGB;
2056
138k
            }
2057
138k
            break;
2058
13.1k
        case 4:
2059
13.1k
            if (strncmp(icc_profile->name, DEFAULT_CMYK_ICC,
2060
13.1k
                        strlen(icc_profile->name)) == 0) {
2061
13.1k
                icc_profile->default_match = DEFAULT_CMYK;
2062
13.1k
            }
2063
13.1k
            break;
2064
321k
    }
2065
2066
321k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n",
2067
321k
               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
321k
    while(pdev->child)
2074
0
        pdev = pdev->child;
2075
2076
321k
    switch (pro_enum)
2077
321k
    {
2078
321k
        case gsDEFAULTPROFILE:
2079
321k
        case gsGRAPHICPROFILE:
2080
321k
        case gsIMAGEPROFILE:
2081
321k
        case gsTEXTPROFILE:
2082
321k
            if_debug1m(gs_debug_flag_icc, mem,
2083
321k
                       "[icc] Setting device profile %d\n", pro_enum);
2084
321k
            pdev->icc_struct->device_profile[pro_enum] = icc_profile;
2085
321k
            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
321k
    }
2108
2109
    /* Check that everything is OK with regard to the number of
2110
       components. */
2111
321k
    if (gsicc_verify_device_profiles(pdev) < 0)
2112
12
        return gs_rethrow(-1, "Error in device profiles");
2113
2114
321k
    if (icc_profile->num_comps != 1 &&
2115
321k
        icc_profile->num_comps != 3 &&
2116
321k
        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
321k
    return 0;
2124
321k
}
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
604k
{
2131
604k
    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
604k
    gsicc_adjust_profile_rc(icc_profile, 1, "gsicc_set_gscs_profile");
2143
604k
    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
604k
    pcs->cmm_icc_profile_data = icc_profile;
2151
604k
    return 0;
2152
604k
}
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
14.7M
{
2179
14.7M
    cmm_profile_t *result;
2180
14.7M
    int code;
2181
14.7M
    char *nameptr = NULL;
2182
14.7M
    gs_memory_t *mem_nongc = memory->non_gc_memory;
2183
2184
14.7M
    result = (cmm_profile_t*) gs_alloc_bytes(mem_nongc, sizeof(cmm_profile_t),
2185
14.7M
                                    "gsicc_profile_new");
2186
14.7M
    if (result == NULL)
2187
0
        return result;
2188
14.7M
    memset(result, 0, GSICC_SERIALIZED_SIZE);
2189
14.7M
    if (namelen > 0) {
2190
12.7M
        nameptr = (char*) gs_alloc_bytes(mem_nongc, namelen+1,
2191
12.7M
                             "gsicc_profile_new");
2192
12.7M
        if (nameptr == NULL) {
2193
0
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2194
0
            return NULL;
2195
0
        }
2196
12.7M
        memcpy(nameptr, pname, namelen);
2197
12.7M
        nameptr[namelen] = '\0';
2198
12.7M
        result->name = nameptr;
2199
12.7M
    } else {
2200
1.97M
        result->name = NULL;
2201
1.97M
    }
2202
14.7M
    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
14.7M
    if ( s != NULL) {
2208
12.8M
        code = gsicc_load_profile_buffer(result, s, mem_nongc);
2209
12.8M
        if (code < 0) {
2210
6.17k
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2211
6.17k
            gs_free_object(mem_nongc, nameptr, "gsicc_profile_new");
2212
6.17k
            return NULL;
2213
6.17k
        }
2214
12.8M
    } else {
2215
1.95M
        result->buffer = NULL;
2216
1.95M
        result->buffer_size = 0;
2217
1.95M
    }
2218
14.7M
    rc_init_free(result, mem_nongc, 1, rc_free_icc_profile);
2219
14.7M
    result->profile_handle = NULL;
2220
14.7M
    result->spotnames = NULL;
2221
14.7M
    result->rend_is_valid = false;
2222
14.7M
    result->isdevlink = false;  /* only used for srcgtag profiles */
2223
14.7M
    result->dev = NULL;
2224
14.7M
    result->memory = mem_nongc;
2225
14.7M
    result->vers = ICCVERS_UNKNOWN;
2226
14.7M
    result->v2_data = NULL;
2227
14.7M
    result->v2_size = 0;
2228
14.7M
    result->release = gscms_release_profile; /* Default case */
2229
2230
14.7M
    result->lock = gx_monitor_label(gx_monitor_alloc(mem_nongc),
2231
14.7M
                                    "gsicc_manage");
2232
14.7M
    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
14.7M
    if_debug1m(gs_debug_flag_icc, mem_nongc,
2239
14.7M
               "[icc] allocating ICC profile = "PRI_INTPTR"\n", (intptr_t)result);
2240
14.7M
    return result;
2241
14.7M
}
2242
2243
static void
2244
rc_free_icc_profile(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2245
14.7M
{
2246
14.7M
    cmm_profile_t *profile = (cmm_profile_t *)ptr_in;
2247
14.7M
    gs_memory_t *mem_nongc =  profile->memory;
2248
2249
14.7M
    if_debug2m(gs_debug_flag_icc, mem,
2250
14.7M
               "[icc] rc decrement profile = "PRI_INTPTR" rc = %ld\n",
2251
14.7M
               (intptr_t)ptr_in, profile->rc.ref_count);
2252
14.7M
    if (profile->rc.ref_count <= 1 ) {
2253
        /* Clear out the buffer if it is full */
2254
14.7M
        if (profile->buffer != NULL) {
2255
12.8M
            gs_free_object(mem_nongc, profile->buffer, "rc_free_icc_profile(buffer)");
2256
12.8M
            profile->buffer = NULL;
2257
12.8M
        }
2258
14.7M
        if_debug0m(gs_debug_flag_icc, mem, "[icc] profile freed\n");
2259
        /* Release this handle if it has been set */
2260
14.7M
        if (profile->profile_handle != NULL) {
2261
716k
            profile->release(profile->profile_handle, profile->memory);
2262
716k
            profile->profile_handle = NULL;
2263
716k
        }
2264
        /* Release the name if it has been set */
2265
14.7M
        if (profile->name != NULL) {
2266
12.7M
            gs_free_object(mem_nongc, profile->name,"rc_free_icc_profile(name)");
2267
12.7M
            profile->name = NULL;
2268
12.7M
            profile->name_length = 0;
2269
12.7M
        }
2270
14.7M
        profile->hash_is_valid = 0;
2271
14.7M
        if (profile->lock != NULL) {
2272
14.7M
            gx_monitor_free(profile->lock);
2273
14.7M
            profile->lock = NULL;
2274
14.7M
        }
2275
        /* If we had a DeviceN profile with names deallocate that now */
2276
14.7M
        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
14.7M
        if (profile->v2_data != NULL) {
2284
0
            gs_free_object(mem_nongc, profile->v2_data, "rc_free_icc_profile(v2_data)");
2285
0
        }
2286
14.7M
        gs_free_object(mem_nongc, profile, "rc_free_icc_profile");
2287
14.7M
    }
2288
14.7M
}
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
3.18M
{
2326
3.18M
    int code = 0, k;
2327
3.18M
    const char *pname;
2328
3.18M
    int namelen;
2329
3.18M
    gsicc_manager_t *iccmanager = pgs->icc_manager;
2330
3.18M
    cmm_profile_t *profile;
2331
2332
15.9M
    for (k = 0; k < 4; k++) {
2333
12.7M
        pname = default_profile_params[k].path;
2334
12.7M
        namelen = strlen(pname);
2335
2336
12.7M
        switch(default_profile_params[k].default_type) {
2337
3.18M
            case DEFAULT_GRAY:
2338
3.18M
                profile = iccmanager->default_gray;
2339
3.18M
                break;
2340
3.18M
            case DEFAULT_RGB:
2341
3.18M
                profile = iccmanager->default_rgb;
2342
3.18M
                break;
2343
3.18M
            case DEFAULT_CMYK:
2344
3.18M
                 profile = iccmanager->default_cmyk;
2345
3.18M
                 break;
2346
3.18M
            default:
2347
3.18M
                profile = NULL;
2348
12.7M
        }
2349
12.7M
        if (profile == NULL)
2350
12.4M
            code = gsicc_set_profile(iccmanager, pname, namelen,
2351
12.4M
                                     default_profile_params[k].default_type);
2352
12.7M
        if (code < 0)
2353
0
            return gs_rethrow(code, "cannot find default icc profile");
2354
12.7M
    }
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
3.18M
    return 0;
2380
3.18M
}
2381
2382
static void
2383
gsicc_manager_finalize(const gs_memory_t *memory, void * vptr)
2384
3.09M
{
2385
3.09M
    gsicc_manager_t *icc_man = (gsicc_manager_t *)vptr;
2386
2387
3.09M
    gsicc_manager_free_contents(icc_man, "gsicc_manager_finalize");
2388
3.09M
}
2389
2390
gsicc_manager_t *
2391
gsicc_manager_new(gs_memory_t *memory)
2392
3.09M
{
2393
3.09M
    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
3.09M
    memory = memory->stable_memory;
2398
3.09M
    result = gs_alloc_struct(memory, gsicc_manager_t, &st_gsicc_manager,
2399
3.09M
                             "gsicc_manager_new");
2400
3.09M
    if ( result == NULL )
2401
0
        return NULL;
2402
3.09M
    rc_init_free(result, memory, 1, rc_gsicc_manager_free);
2403
3.09M
    result->default_gray = NULL;
2404
3.09M
    result->default_rgb = NULL;
2405
3.09M
    result->default_cmyk = NULL;
2406
3.09M
    result->lab_profile = NULL;
2407
3.09M
    result->xyz_profile = NULL;
2408
3.09M
    result->graytok_profile = NULL;
2409
3.09M
    result->device_named = NULL;
2410
3.09M
    result->device_n = NULL;
2411
3.09M
    result->smask_profiles = NULL;
2412
3.09M
    result->memory = memory;
2413
3.09M
    result->srcgtag_profile = NULL;
2414
3.09M
    result->override_internal = false;
2415
3.09M
    return result;
2416
3.09M
}
2417
2418
static void gsicc_manager_free_contents(gsicc_manager_t *icc_manager,
2419
                                        client_name_t cname)
2420
3.09M
{
2421
3.09M
    int k;
2422
3.09M
    gsicc_devicen_entry_t *device_n, *device_n_next;
2423
2424
3.09M
    gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "gsicc_manager_free_contents");
2425
3.09M
    gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "gsicc_manager_free_contents");
2426
3.09M
    gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "gsicc_manager_free_contents");
2427
3.09M
    gsicc_adjust_profile_rc(icc_manager->device_named, -1, "gsicc_manager_free_contents");
2428
3.09M
    gsicc_adjust_profile_rc(icc_manager->lab_profile, -1, "gsicc_manager_free_contents");
2429
3.09M
    gsicc_adjust_profile_rc(icc_manager->graytok_profile, -1, "gsicc_manager_free_contents");
2430
3.09M
    rc_decrement(icc_manager->srcgtag_profile, "gsicc_manager_free_contents");
2431
2432
    /* Loop through the DeviceN profiles */
2433
3.09M
    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
3.09M
    if (icc_manager->smask_profiles != NULL) {
2447
17.6k
        gs_free_object(icc_manager->smask_profiles->memory, icc_manager->smask_profiles, "gsicc_manager_free_contents");
2448
17.6k
        icc_manager->smask_profiles = NULL;
2449
17.6k
    }
2450
3.09M
}
2451
2452
static void
2453
rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2454
3.09M
{
2455
    /* Ending the manager.  Decrement the ref counts of the profiles
2456
       and then free the structure */
2457
3.09M
    gsicc_manager_t *icc_manager = (gsicc_manager_t * ) ptr_in;
2458
2459
3.09M
    assert(mem == icc_manager->memory);
2460
2461
3.09M
    gs_free_object(icc_manager->memory, icc_manager, "rc_gsicc_manager_free");
2462
3.09M
}
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
12.8M
{
2469
12.8M
    int                     num_bytes,profile_size;
2470
12.8M
    unsigned char           *buffer_ptr;
2471
12.8M
    int                     code;
2472
2473
12.8M
    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
12.8M
    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
12.8M
    code = sfseek(s,0,SEEK_END);
2482
12.8M
    if (code < 0)
2483
0
        return code;
2484
12.8M
    profile_size = sftell(s);
2485
12.8M
    code = srewind(s);
2486
12.8M
    if (code < 0)
2487
0
        return code;
2488
12.8M
    if (profile_size < ICC_HEADER_SIZE)
2489
6.17k
        return_error(gs_error_VMerror);
2490
    /* Allocate the buffer, stuff with the profile */
2491
12.7M
   buffer_ptr = gs_alloc_bytes(memory, profile_size,
2492
12.7M
                                        "gsicc_load_profile");
2493
12.7M
   if (buffer_ptr == NULL)
2494
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer");
2495
12.7M
   num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s);
2496
12.7M
   if( num_bytes != profile_size) {
2497
0
       gs_free_object(memory, buffer_ptr, "gsicc_load_profile");
2498
0
       return -1;
2499
0
   }
2500
12.7M
   profile->buffer = buffer_ptr;
2501
12.7M
   profile->buffer_size = num_bytes;
2502
12.7M
   return 0;
2503
12.7M
}
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
23.6k
{
2543
23.6k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
2544
23.6k
    int64_t hashcode = picc_profile->hashcode;
2545
2546
23.6k
    if ( picc_profile->default_match == DEFAULT_NONE ) {
2547
23.6k
        switch ( picc_profile->data_cs ) {
2548
9.14k
            case gsGRAY:
2549
9.14k
                if ( hashcode == icc_manager->default_gray->hashcode )
2550
0
                    picc_profile->default_match = DEFAULT_GRAY_s;
2551
9.14k
                break;
2552
14.5k
            case gsRGB:
2553
14.5k
                if ( hashcode == icc_manager->default_rgb->hashcode )
2554
0
                    picc_profile->default_match = DEFAULT_RGB_s;
2555
14.5k
                break;
2556
19
            case gsCMYK:
2557
19
                if ( hashcode == icc_manager->default_cmyk->hashcode )
2558
0
                    picc_profile->default_match = DEFAULT_CMYK_s;
2559
19
                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
23.6k
        }
2573
23.6k
    }
2574
23.6k
}
2575
2576
/* Initialize the hash code value */
2577
void
2578
gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_gstate *pgs)
2579
23.6k
{
2580
23.6k
    if ( !(picc_profile->hash_is_valid) ) {
2581
18.7k
        gsicc_get_icc_buff_hash(picc_profile->buffer, &(picc_profile->hashcode),
2582
18.7k
                                picc_profile->buffer_size);
2583
18.7k
        picc_profile->hash_is_valid = true;
2584
18.7k
    }
2585
23.6k
    gsicc_set_default_cs_value(picc_profile, pgs);
2586
23.6k
}
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
13.9k
{
2593
13.9k
    gcmmhprofile_t profile_handle = NULL;
2594
13.9k
    unsigned int profile_size;
2595
13.9k
    int size;
2596
13.9k
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) picc_profile->dev;
2597
13.9k
    unsigned char *buffer_ptr;
2598
13.9k
    int64_t position;
2599
13.9k
    gsicc_serialized_profile_t profile_header;
2600
13.9k
    int k;
2601
2602
13.9k
    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
13.9k
        position = gsicc_search_icc_table(pcrdev->icc_table,
2607
13.9k
                                          picc_profile->hashcode, &size);
2608
13.9k
        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
13.9k
        profile_size = size - GSICC_SERIALIZED_SIZE;
2616
        /* Profile and its members are ALL in non-gc memory */
2617
13.9k
        buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size,
2618
13.9k
                                            "gsicc_get_profile_handle_clist");
2619
13.9k
        if (buffer_ptr == NULL)
2620
0
            return NULL;
2621
13.9k
        clist_read_chunk(pcrdev, position + GSICC_SERIALIZED_SIZE,
2622
13.9k
            profile_size, (unsigned char *) buffer_ptr);
2623
13.9k
        profile_handle = gscms_get_profile_handle_mem(buffer_ptr, profile_size, memory->non_gc_memory);
2624
13.9k
        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
13.9k
        clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2630
13.9k
                        (unsigned char *) (&profile_header));
2631
13.9k
        picc_profile->buffer = NULL;
2632
13.9k
        picc_profile->buffer_size = 0;
2633
13.9k
        picc_profile->data_cs = profile_header.data_cs;
2634
13.9k
        picc_profile->default_match = profile_header.default_match;
2635
13.9k
        picc_profile->hash_is_valid = profile_header.hash_is_valid;
2636
13.9k
        picc_profile->hashcode = profile_header.hashcode;
2637
13.9k
        picc_profile->islab = profile_header.islab;
2638
13.9k
        picc_profile->num_comps = profile_header.num_comps;
2639
13.9k
        picc_profile->rend_is_valid = profile_header.rend_is_valid;
2640
13.9k
        picc_profile->rend_cond = profile_header.rend_cond;
2641
13.9k
        picc_profile->isdevlink = profile_header.isdevlink;
2642
46.3k
        for ( k = 0; k < profile_header.num_comps; k++ ) {
2643
32.3k
            picc_profile->Range.ranges[k].rmax =
2644
32.3k
                profile_header.Range.ranges[k].rmax;
2645
32.3k
            picc_profile->Range.ranges[k].rmin =
2646
32.3k
                profile_header.Range.ranges[k].rmin;
2647
32.3k
        }
2648
13.9k
        gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_get_profile_handle_clist");
2649
13.9k
        return profile_handle;
2650
13.9k
     }
2651
0
     return NULL;
2652
13.9k
}
2653
2654
gcmmhprofile_t
2655
gsicc_get_profile_handle_buffer(unsigned char *buffer, int profile_size, gs_memory_t *memory)
2656
706k
{
2657
2658
706k
    gcmmhprofile_t profile_handle = NULL;
2659
2660
706k
     if( buffer != NULL) {
2661
706k
         if (profile_size < ICC_HEADER_SIZE) {
2662
0
             return 0;
2663
0
         }
2664
706k
         profile_handle = gscms_get_profile_handle_mem(buffer, profile_size, memory->non_gc_memory);
2665
706k
         return profile_handle;
2666
706k
     }
2667
0
     return 0;
2668
706k
}
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
1.38M
{
2789
1.38M
    int tablesize = icc_table->tablesize, k;
2790
1.38M
    clist_icctable_entry_t *curr_entry;
2791
2792
1.38M
    curr_entry = icc_table->head;
2793
1.93M
    for (k = 0; k < tablesize; k++ ) {
2794
1.93M
        if ( curr_entry->serial_data.hashcode == icc_hashcode ) {
2795
1.38M
            *size = curr_entry->serial_data.size;
2796
1.38M
            return curr_entry->serial_data.file_position;
2797
1.38M
        }
2798
553k
        curr_entry = curr_entry->next;
2799
553k
    }
2800
2801
    /* Did not find it! */
2802
0
    *size = 0;
2803
0
    return -1;
2804
1.38M
}
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
1.37M
{
2812
1.37M
    cmm_profile_t *profile;
2813
1.37M
    int64_t position;
2814
1.37M
    int size;
2815
1.37M
    int code;
2816
1.37M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) dev;
2817
2818
    /* Create a new ICC profile structure */
2819
1.37M
    profile = gsicc_profile_new(NULL, pcrdev->memory, NULL, 0);
2820
1.37M
    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
1.37M
    if (pcrdev->icc_table == NULL) {
2827
0
        code = clist_read_icctable(pcrdev);
2828
0
        if (code<0)
2829
0
            return NULL;
2830
0
    }
2831
1.37M
    position = gsicc_search_icc_table(pcrdev->icc_table, icc_hashcode, &size);
2832
1.37M
    if ( position < 0 )
2833
0
        return NULL;
2834
2835
    /* Get the serialized portion of the ICC profile information */
2836
1.37M
    clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2837
1.37M
                    (unsigned char *) profile);
2838
1.37M
    return profile;
2839
1.37M
}
2840
2841
void
2842
gsicc_profile_serialize(gsicc_serialized_profile_t *profile_data,
2843
                        cmm_profile_t *icc_profile)
2844
18.7k
{
2845
18.7k
    if (icc_profile == NULL)
2846
0
        return;
2847
18.7k
    memcpy(profile_data, icc_profile, GSICC_SERIALIZED_SIZE);
2848
18.7k
}
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
290M
{
2864
290M
    switch (graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) {
2865
90.5M
        case GS_UNKNOWN_TAG:
2866
93.9M
        case GS_UNTOUCHED_TAG:
2867
93.9M
        default:
2868
93.9M
            (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2869
93.9M
            *render_cond = profile_struct->rendercond[GS_DEFAULT_DEVICE_PROFILE];
2870
93.9M
            break;
2871
106M
        case GS_VECTOR_TAG:
2872
106M
            *render_cond = profile_struct->rendercond[GS_VECTOR_DEVICE_PROFILE];
2873
106M
            if (profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE] != NULL) {
2874
0
                (*profile) = profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE];
2875
106M
            } else {
2876
106M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2877
106M
            }
2878
106M
            break;
2879
86.3M
        case GS_IMAGE_TAG:
2880
86.3M
            *render_cond = profile_struct->rendercond[GS_IMAGE_DEVICE_PROFILE];
2881
86.3M
            if (profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE] != NULL) {
2882
0
                (*profile) = profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE];
2883
86.3M
            } else {
2884
86.3M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2885
86.3M
            }
2886
86.3M
            break;
2887
3.46M
        case GS_TEXT_TAG:
2888
3.46M
            *render_cond = profile_struct->rendercond[GS_TEXT_DEVICE_PROFILE];
2889
3.46M
            if (profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE] != NULL) {
2890
0
                (*profile) = profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE];
2891
3.46M
            } else {
2892
3.46M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2893
3.46M
            }
2894
3.46M
            break;
2895
290M
        }
2896
290M
}
2897
2898
/* internal ICC and rendering intent override control */
2899
void
2900
gs_setoverrideicc(gs_gstate *pgs, bool value)
2901
560k
{
2902
560k
    if (pgs->icc_manager != NULL) {
2903
560k
        pgs->icc_manager->override_internal = value;
2904
560k
    }
2905
560k
}
2906
bool
2907
gs_currentoverrideicc(const gs_gstate *pgs)
2908
868k
{
2909
868k
    if (pgs->icc_manager != NULL) {
2910
868k
        return pgs->icc_manager->override_internal;
2911
868k
    } else {
2912
0
        return false;
2913
0
    }
2914
868k
}
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
639k
{
2947
639k
    static const char *const rfs = "";
2948
2949
    /*FIXME: This should return the entire list !!! */
2950
    /*       Just return the first one for now      */
2951
639k
    if (pgs->icc_manager->device_n == NULL) {
2952
639k
        pval->data = (const byte *) rfs;
2953
639k
        pval->persistent = true;
2954
639k
    } 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
639k
    pval->size = strlen((const char *)pval->data);
2960
639k
}
2961
2962
int
2963
gs_setdevicenprofileicc(const gs_gstate * pgs, gs_param_string * pval)
2964
541k
{
2965
541k
    int code = 0;
2966
541k
    char *pname, *pstr, *pstrend, *last = NULL;
2967
541k
    int namelen = (pval->size)+1;
2968
541k
    gs_memory_t *mem = pgs->memory;
2969
2970
    /* Check if it was "NULL" */
2971
541k
    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
541k
    return 0;
3008
541k
}
3009
3010
void
3011
gs_currentdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3012
639k
{
3013
639k
    static const char *const rfs = DEFAULT_GRAY_ICC;
3014
3015
639k
    if (pgs->icc_manager->default_gray == NULL) {
3016
319k
        pval->data = (const byte *) rfs;
3017
319k
        pval->persistent = true;
3018
319k
    } else {
3019
319k
        pval->data = (const byte *) (pgs->icc_manager->default_gray->name);
3020
319k
        pval->persistent = false;
3021
319k
    }
3022
639k
    pval->size = strlen((const char *)pval->data);
3023
639k
}
3024
3025
int
3026
gs_setdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3027
541k
{
3028
541k
    int code;
3029
541k
    char *pname;
3030
541k
    int namelen = (pval->size)+1;
3031
541k
    gs_memory_t *mem = pgs->memory;
3032
541k
    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
541k
    not_initialized = (pgs->icc_manager->default_gray == NULL);
3039
3040
541k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3041
541k
                             "set_default_gray_icc");
3042
541k
    if (pname == NULL)
3043
0
        return_error(gs_error_VMerror);
3044
541k
    memcpy(pname,pval->data,namelen-1);
3045
541k
    pname[namelen-1] = 0;
3046
541k
    code = gsicc_set_profile(pgs->icc_manager,
3047
541k
        (const char*) pname, namelen-1, DEFAULT_GRAY);
3048
541k
    gs_free_object(mem, pname,
3049
541k
        "set_default_gray_icc");
3050
541k
    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
541k
    if (not_initialized) {
3055
0
        code = gsicc_init_gs_colors((gs_gstate*) pgs);
3056
0
    }
3057
541k
    if (code < 0)
3058
0
        return gs_throw(code, "error initializing gstate color spaces to icc");
3059
541k
    return code;
3060
541k
}
3061
3062
void
3063
gs_currenticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3064
639k
{
3065
639k
    static const char *const rfs = DEFAULT_DIR_ICC;   /* as good as any other */
3066
639k
    const gs_lib_ctx_t *lib_ctx = pgs->memory->gs_lib_ctx;
3067
3068
639k
    if (lib_ctx->profiledir == NULL) {
3069
0
        pval->data = (const byte *)rfs;
3070
0
        pval->size = strlen(rfs);
3071
0
        pval->persistent = true;
3072
639k
    } else {
3073
639k
        pval->data = (const byte *)(lib_ctx->profiledir);
3074
639k
        pval->size = lib_ctx->profiledir_len;
3075
639k
        pval->persistent = false;
3076
639k
    }
3077
639k
}
3078
3079
int
3080
gs_seticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3081
541k
{
3082
541k
    char *pname;
3083
541k
    int namelen = (pval->size)+1;
3084
541k
    gs_memory_t *mem = (gs_memory_t *)pgs->memory;
3085
3086
    /* Check if it was "NULL" */
3087
541k
    if (pval->size != 0 ) {
3088
541k
        pname = (char *)gs_alloc_bytes(mem, namelen,
3089
541k
                                       "gs_seticcdirectory");
3090
541k
        if (pname == NULL)
3091
0
            return gs_rethrow(gs_error_VMerror, "cannot allocate directory name");
3092
541k
        memcpy(pname,pval->data,namelen-1);
3093
541k
        pname[namelen-1] = 0;
3094
541k
        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
541k
        gs_free_object(mem, pname, "gs_seticcdirectory");
3099
541k
    }
3100
541k
    return 0;
3101
541k
}
3102
3103
void
3104
gs_currentsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3105
639k
{
3106
639k
    if (pgs->icc_manager->srcgtag_profile == NULL) {
3107
639k
        pval->data = NULL;
3108
639k
        pval->size = 0;
3109
639k
        pval->persistent = true;
3110
639k
    } 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
639k
}
3116
3117
int
3118
gs_setsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3119
541k
{
3120
541k
    int code;
3121
541k
    char *pname;
3122
541k
    int namelen = (pval->size)+1;
3123
541k
    gs_memory_t *mem = pgs->memory;
3124
3125
541k
    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
639k
{
3142
639k
    static const char *const rfs = DEFAULT_RGB_ICC;
3143
3144
639k
    if (pgs->icc_manager->default_rgb == NULL) {
3145
319k
        pval->data = (const byte *) rfs;
3146
319k
        pval->persistent = true;
3147
319k
    } else {
3148
319k
        pval->data = (const byte *) (pgs->icc_manager->default_rgb->name);
3149
319k
        pval->persistent = false;
3150
319k
    }
3151
639k
    pval->size = strlen((const char *)pval->data);
3152
639k
}
3153
3154
int
3155
gs_setdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval)
3156
541k
{
3157
541k
    int code;
3158
541k
    char *pname;
3159
541k
    int namelen = (pval->size)+1;
3160
541k
    gs_memory_t *mem = pgs->memory;
3161
3162
541k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3163
541k
                             "set_default_rgb_icc");
3164
541k
    if (pname == NULL)
3165
0
        return_error(gs_error_VMerror);
3166
541k
    memcpy(pname,pval->data,namelen-1);
3167
541k
    pname[namelen-1] = 0;
3168
541k
    code = gsicc_set_profile(pgs->icc_manager,
3169
541k
        (const char*) pname, namelen-1, DEFAULT_RGB);
3170
541k
    gs_free_object(mem, pname,
3171
541k
        "set_default_rgb_icc");
3172
541k
    if (code < 0)
3173
0
        return gs_rethrow(code, "cannot find default rgb icc profile");
3174
541k
    return code;
3175
541k
}
3176
3177
void
3178
gs_currentnamedicc(const gs_gstate * pgs, gs_param_string * pval)
3179
639k
{
3180
639k
    static const char *const rfs = "";
3181
3182
639k
    if (pgs->icc_manager->device_named == NULL) {
3183
639k
        pval->data = (const byte *) rfs;
3184
639k
        pval->persistent = true;
3185
639k
    } else {
3186
0
        pval->data = (const byte *) (pgs->icc_manager->device_named->name);
3187
0
        pval->persistent = false;
3188
0
    }
3189
639k
    pval->size = strlen((const char *)pval->data);
3190
639k
}
3191
3192
int
3193
gs_setnamedprofileicc(const gs_gstate * pgs, gs_param_string * pval)
3194
541k
{
3195
541k
    int code;
3196
541k
    char* pname;
3197
541k
    int namelen = (pval->size)+1;
3198
541k
    gs_memory_t *mem = pgs->memory;
3199
3200
    /* Check if it was "NULL" */
3201
541k
    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
541k
    return 0;
3217
541k
}
3218
3219
void
3220
gs_currentdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3221
639k
{
3222
639k
    static const char *const rfs = DEFAULT_CMYK_ICC;
3223
3224
639k
    if (pgs->icc_manager->default_cmyk == NULL) {
3225
319k
        pval->data = (const byte *) rfs;
3226
319k
        pval->persistent = true;
3227
319k
    } else {
3228
319k
        pval->data = (const byte *) (pgs->icc_manager->default_cmyk->name);
3229
319k
        pval->persistent = false;
3230
319k
    }
3231
639k
    pval->size = strlen((const char *)pval->data);
3232
639k
}
3233
3234
int
3235
gs_setdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3236
541k
{
3237
541k
    int code;
3238
541k
    char* pname;
3239
541k
    int namelen = (pval->size)+1;
3240
541k
    gs_memory_t *mem = pgs->memory;
3241
3242
541k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3243
541k
                             "set_default_cmyk_icc");
3244
541k
    if (pname == NULL)
3245
0
        return_error(gs_error_VMerror);
3246
541k
    memcpy(pname,pval->data,namelen-1);
3247
541k
    pname[namelen-1] = 0;
3248
541k
    code = gsicc_set_profile(pgs->icc_manager,
3249
541k
        (const char*) pname, namelen-1, DEFAULT_CMYK);
3250
541k
    gs_free_object(mem, pname,
3251
541k
                "set_default_cmyk_icc");
3252
541k
    if (code < 0)
3253
0
        return gs_throw(code, "cannot find default cmyk icc profile");
3254
541k
    return code;
3255
541k
}
3256
3257
void
3258
gs_currentlabicc(const gs_gstate * pgs, gs_param_string * pval)
3259
639k
{
3260
639k
    static const char *const rfs = LAB_ICC;
3261
3262
639k
    pval->data = (const byte *)( (pgs->icc_manager->lab_profile == NULL) ?
3263
319k
                        rfs : pgs->icc_manager->lab_profile->name);
3264
639k
    pval->size = strlen((const char *)pval->data);
3265
639k
    pval->persistent = true;
3266
639k
}
3267
3268
int
3269
gs_setlabicc(const gs_gstate * pgs, gs_param_string * pval)
3270
541k
{
3271
541k
    int code;
3272
541k
    char* pname;
3273
541k
    int namelen = (pval->size)+1;
3274
541k
    gs_memory_t *mem = pgs->memory;
3275
3276
541k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3277
541k
                             "set_lab_icc");
3278
541k
    if (pname == NULL)
3279
0
        return_error(gs_error_VMerror);
3280
541k
    memcpy(pname,pval->data,namelen-1);
3281
541k
    pname[namelen-1] = 0;
3282
541k
    code = gsicc_set_profile(pgs->icc_manager,
3283
541k
        (const char*) pname, namelen-1, LAB_TYPE);
3284
541k
    gs_free_object(mem, pname,
3285
541k
                "set_lab_icc");
3286
541k
    if (code < 0)
3287
0
        return gs_throw(code, "cannot find default lab icc profile");
3288
541k
    return code;
3289
541k
}