Coverage Report

Created: 2025-08-28 07:06

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