Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gsicc_manage.c
Line
Count
Source
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
16.5M
#define ICC_HEADER_SIZE 128
46
#define CREATE_V2_DATA 0
47
48
#if ICC_DUMP
49
unsigned int global_icc_index = 0;
50
#endif
51
52
/* Needed for gsicc_set_devicen_equiv_colors. */
53
extern const gs_color_space_type gs_color_space_type_ICC;
54
55
/* Static prototypes */
56
57
static void gsicc_set_default_cs_value(cmm_profile_t *picc_profile,
58
                                       gs_gstate *pgs);
59
static gsicc_namelist_t* gsicc_new_namelist(gs_memory_t *memory);
60
static gsicc_colorname_t* gsicc_new_colorname(gs_memory_t *memory);
61
static gsicc_namelist_t* gsicc_get_spotnames(gcmmhprofile_t profile,
62
                                             gs_memory_t *memory);
63
static void gsicc_manager_free_contents(gsicc_manager_t *icc_man,
64
                                        client_name_t cname);
65
66
static void rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in,
67
                                  client_name_t cname);
68
static void rc_free_icc_profile(gs_memory_t * mem, void *ptr_in,
69
                                client_name_t cname);
70
static int gsicc_load_profile_buffer(cmm_profile_t *profile, stream *s,
71
                                     gs_memory_t *memory);
72
static int64_t gsicc_search_icc_table(clist_icctable_t *icc_table,
73
                                      int64_t icc_hashcode, int *size);
74
static int gsicc_load_namedcolor_buffer(cmm_profile_t *profile, stream *s,
75
                          gs_memory_t *memory);
76
static cmm_srcgtag_profile_t* gsicc_new_srcgtag_profile(gs_memory_t *memory);
77
static void gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem);
78
79
static void
80
gsicc_manager_finalize(const gs_memory_t *memory, void * vptr);
81
82
static void
83
gsicc_smask_finalize(const gs_memory_t *memory, void * vptr);
84
85
/* profile data structure */
86
/* profile_handle should NOT be garbage collected since it is allocated by the external CMS */
87
gs_private_st_ptrs2(st_gsicc_colorname, gsicc_colorname_t, "gsicc_colorname",
88
                    gsicc_colorname_enum_ptrs, gsicc_colorname_reloc_ptrs, name, next);
89
90
gs_private_st_ptrs2_final(st_gsicc_manager, gsicc_manager_t, "gsicc_manager",
91
                    gsicc_manager_enum_ptrs, gsicc_manager_profile_reloc_ptrs,
92
                    gsicc_manager_finalize, smask_profiles, device_n);
93
94
gs_private_st_simple_final(st_gsicc_smask, gsicc_smask_t, "gsicc_smask", gsicc_smask_finalize);
95
96
gs_private_st_ptrs2(st_gsicc_devicen, gsicc_devicen_t, "gsicc_devicen",
97
                gsicc_devicen_enum_ptrs, gsicc_devicen_reloc_ptrs, head, final);
98
99
gs_private_st_ptrs1(st_gsicc_devicen_entry, gsicc_devicen_entry_t,
100
                    "gsicc_devicen_entry", gsicc_devicen_entry_enum_ptrs,
101
                    gsicc_devicen_entry_reloc_ptrs, next);
102
103
typedef struct default_profile_def_s {
104
    const char *path;
105
    gsicc_profile_t default_type;
106
} default_profile_def_t;
107
108
static default_profile_def_t default_profile_params[] =
109
{
110
    {DEFAULT_GRAY_ICC, DEFAULT_GRAY},
111
    {DEFAULT_RGB_ICC, DEFAULT_RGB},
112
    {DEFAULT_CMYK_ICC, DEFAULT_CMYK},
113
    {LAB_ICC, LAB_TYPE}
114
};
115
116
void
117
gsicc_setcoloraccuracy(gs_memory_t *mem, uint level)
118
1.85M
{
119
1.85M
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
120
121
1.85M
    ctx->icc_color_accuracy = level;
122
1.85M
}
123
124
uint
125
gsicc_currentcoloraccuracy(gs_memory_t *mem)
126
1.85M
{
127
1.85M
    gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem);
128
129
1.85M
    return ctx->icc_color_accuracy;
130
1.85M
}
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.00k
{
145
4.00k
    if (icc_profile == NULL || icc_profile->buffer == NULL)
146
0
        return -1;
147
148
4.00k
    *major = icc_profile->buffer[8];
149
4.00k
    *minor = icc_profile->buffer[9];
150
151
4.00k
    return 0;
152
4.00k
}
153
154
void
155
gsicc_set_icc_range(cmm_profile_t **icc_profile)
156
16.5M
{
157
16.5M
    int num_comp = (*icc_profile)->num_comps;
158
16.5M
    int k;
159
160
62.1M
    for ( k = 0; k < num_comp; k++) {
161
45.5M
        (*icc_profile)->Range.ranges[k].rmin = 0.0;
162
45.5M
        (*icc_profile)->Range.ranges[k].rmax = 1.0;
163
45.5M
    }
164
16.5M
}
165
166
cmm_profile_t*
167
gsicc_set_iccsmaskprofile(const char *pname,
168
                          int namelen, gsicc_manager_t *icc_manager,
169
                          gs_memory_t *mem)
170
123k
{
171
123k
    stream *str;
172
123k
    int code;
173
123k
    cmm_profile_t *icc_profile;
174
175
123k
    if (icc_manager == NULL) {
176
0
        code = gsicc_open_search(pname, namelen, mem, NULL, 0, &str);
177
123k
    } else {
178
123k
        code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
179
123k
                                 mem->gs_lib_ctx->profiledir_len, &str);
180
123k
    }
181
123k
    if (code < 0 || str == NULL)
182
0
        return NULL;
183
123k
    icc_profile = gsicc_profile_new(str, mem, pname, namelen);
184
123k
    code = sfclose(str);
185
123k
    if (icc_profile == NULL)
186
0
        return NULL;
187
    /* Get the profile handle */
188
123k
    icc_profile->profile_handle =
189
123k
            gsicc_get_profile_handle_buffer(icc_profile->buffer,
190
123k
                                            icc_profile->buffer_size,
191
123k
                                            mem);
192
123k
    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
123k
    gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode),
199
123k
                            icc_profile->buffer_size);
200
123k
    icc_profile->hash_is_valid = true;
201
123k
    icc_profile->num_comps =
202
123k
            gscms_get_input_channel_count(icc_profile->profile_handle, icc_profile->memory);
203
123k
    icc_profile->num_comps_out =
204
123k
            gscms_get_output_channel_count(icc_profile->profile_handle, icc_profile->memory);
205
123k
    icc_profile->data_cs =
206
123k
            gscms_get_profile_data_space(icc_profile->profile_handle, icc_profile->memory);
207
123k
    gsicc_set_icc_range(&icc_profile);
208
123k
    return icc_profile;
209
123k
}
210
211
static void
212
gsicc_smask_finalize(const gs_memory_t *memory, void * vptr)
213
89.0k
{
214
89.0k
    gsicc_smask_t *iccsmask = (gsicc_smask_t *)vptr;
215
216
89.0k
    gsicc_adjust_profile_rc(iccsmask->smask_gray, -1,
217
89.0k
        "gsicc_smask_finalize");
218
89.0k
    gsicc_adjust_profile_rc(iccsmask->smask_rgb, -1,
219
89.0k
        "gsicc_smask_finalize");
220
89.0k
    gsicc_adjust_profile_rc(iccsmask->smask_cmyk, -1,
221
89.0k
        "gsicc_smask_finalize");
222
89.0k
}
223
224
gsicc_smask_t*
225
gsicc_new_iccsmask(gs_memory_t *memory)
226
89.0k
{
227
89.0k
    gsicc_smask_t *result;
228
229
89.0k
    result = (gsicc_smask_t *) gs_alloc_struct(memory, gsicc_smask_t, &st_gsicc_smask, "gsicc_new_iccsmask");
230
89.0k
    if (result != NULL) {
231
89.0k
        result->smask_gray = NULL;
232
89.0k
        result->smask_rgb = NULL;
233
89.0k
        result->smask_cmyk = NULL;
234
89.0k
        result->memory = memory;
235
89.0k
        result->swapped = false;
236
89.0k
    }
237
89.0k
    return result;
238
89.0k
}
239
240
/* Allocate a new structure to hold the profiles that contains the profiles
241
   used when we are in a softmask group */
242
int
243
gsicc_initialize_iccsmask(gsicc_manager_t *icc_manager)
244
32.4k
{
245
32.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
32.4k
    icc_manager->smask_profiles = gsicc_new_iccsmask(stable_mem);
250
32.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
32.4k
    if ((icc_manager->smask_profiles->smask_gray =
254
32.4k
        gsicc_set_iccsmaskprofile(SMASK_GRAY_ICC, strlen(SMASK_GRAY_ICC),
255
32.4k
        icc_manager, stable_mem) ) == NULL)
256
0
        goto error;
257
32.4k
    if ((icc_manager->smask_profiles->smask_rgb =
258
32.4k
        gsicc_set_iccsmaskprofile(SMASK_RGB_ICC, strlen(SMASK_RGB_ICC),
259
32.4k
        icc_manager, stable_mem)) == NULL)
260
0
        goto error;
261
32.4k
    if ((icc_manager->smask_profiles->smask_cmyk =
262
32.4k
        gsicc_set_iccsmaskprofile(SMASK_CMYK_ICC, strlen(SMASK_CMYK_ICC),
263
32.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
32.4k
    icc_manager->smask_profiles->smask_gray->default_match = DEFAULT_GRAY;
270
32.4k
    icc_manager->smask_profiles->smask_rgb->default_match = DEFAULT_RGB;
271
32.4k
    icc_manager->smask_profiles->smask_cmyk->default_match = DEFAULT_CMYK;
272
32.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
32.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
2.26M
{
496
2.26M
    switch (profile_data->default_match) {
497
486k
        case DEFAULT_GRAY:
498
486k
            return gs_color_space_index_DeviceGray;
499
1.13M
        case DEFAULT_RGB:
500
1.13M
            return gs_color_space_index_DeviceRGB;
501
262k
        case DEFAULT_CMYK:
502
262k
            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
381k
        default:
512
381k
            return gs_color_space_index_ICC;
513
2.26M
    }
514
2.26M
}
515
516
int
517
gsicc_use_fast_color(cmm_profile_t* profile_data)
518
250M
{
519
250M
    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
774k
    case LAB_TYPE:
525
774k
    case NAMED_TYPE:
526
774k
    case DEVICEN_TYPE:
527
774k
        return 0;
528
249M
    default:
529
249M
        return profile_data->num_comps;
530
250M
    }
531
250M
}
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
619k
{
549
619k
    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
619k
        default:
556
619k
            return false;
557
619k
    }
558
619k
}
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
118M
{
569
118M
    if (profile_data != NULL) {
570
111M
        gx_monitor_enter(profile_data->lock);
571
111M
        if (profile_data->rc.ref_count == 1 && delta < 0) {
572
18.3M
            profile_data->rc.ref_count = 0;   /* while locked */
573
18.3M
            gx_monitor_leave(profile_data->lock);
574
18.3M
            rc_free_struct(profile_data, name_str);
575
92.8M
        } else {
576
92.8M
            rc_adjust(profile_data, delta, name_str);
577
92.8M
            gx_monitor_leave(profile_data->lock);
578
92.8M
        }
579
111M
    }
580
118M
}
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
37
{
632
37
    return gscms_get_device_class(icc_profile->profile_handle, icc_profile->memory);
633
37
}
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
17.8M
{
899
17.8M
    cmm_profile_t *icc_profile;
900
17.8M
    cmm_profile_t **manager_default_profile = NULL; /* quite compiler */
901
17.8M
    stream *str;
902
17.8M
    gs_memory_t *mem_gc = icc_manager->memory;
903
17.8M
    int code;
904
17.8M
    int k;
905
17.8M
    int num_comps = 0;
906
17.8M
    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
17.8M
    default_space = gsUNDEFINED;
914
17.8M
    if (icc_manager->smask_profiles !=NULL &&
915
413k
        icc_manager->smask_profiles->swapped == true) {
916
0
            return 0;
917
17.8M
    } else {
918
17.8M
        switch(defaulttype) {
919
4.42M
            case DEFAULT_GRAY:
920
4.42M
                manager_default_profile = &(icc_manager->default_gray);
921
4.42M
                default_space = gsGRAY;
922
4.42M
                num_comps = 1;
923
4.42M
                break;
924
4.42M
            case DEFAULT_RGB:
925
4.42M
                manager_default_profile = &(icc_manager->default_rgb);
926
4.42M
                default_space = gsRGB;
927
4.42M
                num_comps = 3;
928
4.42M
                break;
929
4.42M
            case DEFAULT_CMYK:
930
4.42M
                 manager_default_profile = &(icc_manager->default_cmyk);
931
4.42M
                 default_space = gsCMYK;
932
4.42M
                 num_comps = 4;
933
4.42M
                 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.53M
            case LAB_TYPE:
939
4.53M
                 manager_default_profile = &(icc_manager->lab_profile);
940
4.53M
                 num_comps = 3;
941
4.53M
                 default_space = gsCIELAB;
942
4.53M
                 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
17.8M
        }
952
17.8M
    }
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
17.8M
    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.75M
        icc_profile = *manager_default_profile;
964
2.75M
        if ( namelen == icc_profile->name_length ) {
965
2.75M
            if( memcmp(pname, icc_profile->name, namelen) == 0)
966
2.75M
                return 0;
967
2.75M
        }
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
15.0M
    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
15.0M
    code = gsicc_open_search(pname, namelen, mem_gc, mem_gc->gs_lib_ctx->profiledir,
1018
15.0M
                             mem_gc->gs_lib_ctx->profiledir_len, &str);
1019
15.0M
    if (code < 0)
1020
0
        return code;
1021
15.0M
    if (str != NULL) {
1022
15.0M
        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
15.0M
        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
15.0M
        code = sfclose(str);
1051
15.0M
        if (icc_profile == NULL) {
1052
0
            return gs_throw1(-1, "problems with profile %s",pname);
1053
0
        }
1054
15.0M
         *manager_default_profile = icc_profile;
1055
15.0M
        icc_profile->default_match = defaulttype;
1056
15.0M
        if (defaulttype == LAB_TYPE)
1057
3.76M
            icc_profile->islab = true;
1058
15.0M
        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
15.0M
        } 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
15.0M
            icc_profile->num_comps = num_comps;
1073
15.0M
            icc_profile->num_comps_out = 3;
1074
15.0M
            gsicc_set_icc_range(&icc_profile);
1075
15.0M
            icc_profile->data_cs = default_space;
1076
15.0M
        }
1077
15.0M
        return 0;
1078
15.0M
    }
1079
0
    return -1;
1080
15.0M
}
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
364k
{
1090
364k
    gsicc_profile_t defaulttype = icc_profile->default_match;
1091
364k
    gsicc_colorbuffer_t default_space = gsUNDEFINED;
1092
364k
    int num_comps, num_comps_out;
1093
364k
    gs_memory_t *mem = icc_profile->memory;
1094
1095
    /* Get the profile handle if it is not already set */
1096
364k
    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
364k
    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
364k
    num_comps = icc_profile->num_comps;
1113
364k
    icc_profile->num_comps =
1114
364k
        gscms_get_input_channel_count(icc_profile->profile_handle,
1115
364k
            icc_profile->memory);
1116
364k
    num_comps_out = icc_profile->num_comps_out;
1117
364k
    icc_profile->num_comps_out =
1118
364k
        gscms_get_output_channel_count(icc_profile->profile_handle,
1119
364k
            icc_profile->memory);
1120
364k
    icc_profile->data_cs =
1121
364k
        gscms_get_profile_data_space(icc_profile->profile_handle,
1122
364k
            icc_profile->memory);
1123
364k
    if_debug0m(gs_debug_flag_icc,mem,"[icc] Setting ICC profile in Manager\n");
1124
364k
    switch(defaulttype) {
1125
307k
        case DEFAULT_GRAY:
1126
307k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default Gray\n");
1127
307k
            default_space = gsGRAY;
1128
307k
            break;
1129
40.2k
        case DEFAULT_RGB:
1130
40.2k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default RGB\n");
1131
40.2k
            default_space = gsRGB;
1132
40.2k
            break;
1133
11.7k
        case DEFAULT_CMYK:
1134
11.7k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Default CMYK\n");
1135
11.7k
            default_space = gsCMYK;
1136
11.7k
             break;
1137
0
        case NAMED_TYPE:
1138
0
            if_debug0m(gs_debug_flag_icc,mem,"[icc] Named Color\n");
1139
0
            break;
1140
1.08k
        case LAB_TYPE:
1141
1.08k
            if_debug0m(gs_debug_flag_icc,mem,"[icc] CIELAB Profile\n");
1142
1.08k
            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.43k
        default:
1148
3.43k
            return 0;
1149
0
            break;
1150
364k
    }
1151
364k
    if_debug1m(gs_debug_flag_icc,mem,"[icc] name = %s\n", icc_profile->name);
1152
361k
    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
361k
    if (default_space != gsUNDEFINED ||
1156
1.08k
        num_comps != icc_profile->num_comps ||
1157
359k
        num_comps_out != icc_profile->num_comps_out) {
1158
359k
        if (icc_profile->data_cs != default_space) {
1159
0
            return gs_rethrow(-1, "A default profile has an incorrect color space");
1160
0
        }
1161
359k
    }
1162
361k
    return 0;
1163
361k
}
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.57k
{
1169
5.57k
    cmm_profile_t *result;
1170
5.57k
    stream* str;
1171
5.57k
    int code;
1172
1173
    /* First see if we can get the stream. */
1174
5.57k
    code = gsicc_open_search(pname, namelen, mem, mem->gs_lib_ctx->profiledir,
1175
5.57k
        mem->gs_lib_ctx->profiledir_len, &str);
1176
5.57k
    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.57k
    result = gsicc_profile_new(str, mem, pname, namelen);
1181
5.57k
    code = sfclose(str);
1182
5.57k
    if (result == NULL) {
1183
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1184
0
        return NULL;
1185
0
    }
1186
5.57k
    code = gsicc_init_profile_info(result);
1187
5.57k
    if (code < 0) {
1188
0
        gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
1189
0
        return NULL;
1190
0
    }
1191
5.57k
    return result;
1192
5.57k
}
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.57k
{
1199
5.57k
    int k;
1200
1201
    /* Get the profile handle */
1202
5.57k
    profile->profile_handle =
1203
5.57k
        gsicc_get_profile_handle_buffer(profile->buffer,
1204
5.57k
                                        profile->buffer_size,
1205
5.57k
                                        profile->memory);
1206
5.57k
    if (profile->profile_handle == NULL)
1207
0
        return -1;
1208
1209
    /* Compute the hash code of the profile. */
1210
5.57k
    gsicc_get_icc_buff_hash(profile->buffer, &(profile->hashcode),
1211
5.57k
                            profile->buffer_size);
1212
5.57k
    profile->hash_is_valid = true;
1213
5.57k
    profile->default_match = DEFAULT_NONE;
1214
5.57k
    profile->num_comps = gscms_get_input_channel_count(profile->profile_handle,
1215
5.57k
        profile->memory);
1216
5.57k
    profile->num_comps_out = gscms_get_output_channel_count(profile->profile_handle,
1217
5.57k
        profile->memory);
1218
5.57k
    profile->data_cs = gscms_get_profile_data_space(profile->profile_handle,
1219
5.57k
        profile->memory);
1220
1221
    /* Initialize the range to default values */
1222
12.4k
    for ( k = 0; k < profile->num_comps; k++) {
1223
6.91k
        profile->Range.ranges[k].rmin = 0.0;
1224
6.91k
        profile->Range.ranges[k].rmax = 1.0;
1225
6.91k
    }
1226
5.57k
    return 0;
1227
5.57k
}
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
15.5M
{
1236
15.5M
    char *buffer;
1237
15.5M
    stream* str;
1238
1239
    /* Check if we need to prepend the file name  */
1240
15.5M
    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
15.5M
        buffer = (char *) gs_alloc_bytes(mem_gc, namelen + dirlen + 1,
1247
15.5M
                                     "gsicc_open_search");
1248
15.5M
        if (buffer == NULL)
1249
0
            return_error(gs_error_VMerror);
1250
15.5M
        memcpy(buffer, dirname, dirlen);
1251
15.5M
        memcpy(buffer + dirlen, pname, namelen);
1252
        /* Just to make sure we were null terminated */
1253
15.5M
        buffer[namelen + dirlen] = '\0';
1254
1255
15.5M
        if (gs_check_file_permission(mem_gc, buffer, strlen(buffer), "r") >= 0) {
1256
15.5M
            str = sfopen(buffer, "r", mem_gc);
1257
15.5M
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1258
15.5M
            if (str != NULL) {
1259
15.5M
                *strp = str;
1260
15.5M
                return 0;
1261
15.5M
            }
1262
15.5M
        }
1263
0
        else {
1264
0
            gs_free_object(mem_gc, buffer, "gsicc_open_search");
1265
0
        }
1266
15.5M
    }
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.51M
{
1404
2.51M
    cmm_dev_profile_t *icc_struct = (cmm_dev_profile_t *)ptr_in;
1405
2.51M
    int k;
1406
2.51M
    gs_memory_t *mem_nongc =  icc_struct->memory;
1407
1408
2.51M
    if (icc_struct->rc.ref_count <= 1 ) {
1409
        /* Decrement any profiles. */
1410
12.5M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1411
10.0M
            if (icc_struct->device_profile[k] != NULL) {
1412
2.36M
                if_debug1m(gs_debug_flag_icc, mem_nongc,
1413
2.36M
                           "[icc] Releasing device profile %d\n", k);
1414
2.36M
                gsicc_adjust_profile_rc(icc_struct->device_profile[k], -1,
1415
2.36M
                             "rc_free_profile_array");
1416
2.36M
            }
1417
10.0M
        }
1418
2.51M
        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.51M
        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.51M
        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.51M
        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.51M
        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.51M
        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.51M
        if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing device profile struct\n");
1446
2.51M
        gs_free_object(mem_nongc, icc_struct, "rc_free_profile_array");
1447
2.51M
    }
1448
2.51M
}
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.51M
{
1454
2.51M
    cmm_dev_profile_t *result;
1455
2.51M
    int k;
1456
2.51M
    gs_memory_t *memory = dev->memory;
1457
1458
2.51M
    if_debug0m(gs_debug_flag_icc,memory,"[icc] Allocating device profile struct\n");
1459
2.51M
    result = (cmm_dev_profile_t *) gs_alloc_bytes(memory->non_gc_memory,
1460
2.51M
                                            sizeof(cmm_dev_profile_t),
1461
2.51M
                                            "gsicc_new_device_profile_array");
1462
2.51M
    if (result == NULL)
1463
0
        return NULL;
1464
2.51M
    result->memory = memory->non_gc_memory;
1465
1466
12.5M
    for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
1467
10.0M
        result->device_profile[k] = NULL;
1468
10.0M
        result->rendercond[k].rendering_intent = gsRINOTSPECIFIED;
1469
10.0M
        result->rendercond[k].black_point_comp = gsBPNOTSPECIFIED;
1470
10.0M
        result->rendercond[k].override_icc = false;
1471
10.0M
        result->rendercond[k].preserve_black = gsBKPRESNOTSPECIFIED;
1472
10.0M
        result->rendercond[k].graphics_type_tag = GS_UNKNOWN_TAG;
1473
10.0M
        result->rendercond[k].cmm = gsCMM_DEFAULT;
1474
10.0M
    }
1475
2.51M
    result->proof_profile = NULL;
1476
2.51M
    result->link_profile = NULL;
1477
2.51M
    result->postren_profile = NULL;
1478
2.51M
    result->blend_profile = NULL;
1479
2.51M
    result->oi_profile = NULL;
1480
2.51M
    result->spotnames = NULL;
1481
2.51M
    result->devicegraytok = true;  /* Default is to map gray to pure K */
1482
2.51M
    result->graydetection = false;
1483
2.51M
    result->pageneutralcolor = false;
1484
2.51M
    result->usefastcolor = false;  /* Default is to not use fast color */
1485
2.51M
    result->blacktext = false;
1486
2.51M
    result->blackvector = false;
1487
2.51M
    result->blackthresholdL = 90.0F;
1488
2.51M
    result->blackthresholdC = 0.0F;
1489
2.51M
    result->prebandthreshold = true;
1490
2.51M
    result->supports_devn = false;
1491
2.51M
    result->overprint_control = gs_overprint_control_enable;  /* Default overprint if the device can */
1492
2.51M
    rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array);
1493
2.51M
    return result;
1494
2.51M
}
1495
1496
int
1497
gsicc_set_device_blackpreserve(gx_device *dev, gsicc_blackpreserve_t blackpreserve,
1498
                                gsicc_profile_types_t profile_type)
1499
7.41M
{
1500
7.41M
    int code;
1501
7.41M
    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.41M
    if (dev_proc(dev, get_profile) == NULL) {
1508
2.76M
        profile_struct = dev->icc_struct;
1509
4.64M
    } else {
1510
4.64M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1511
4.64M
        if (code < 0)
1512
0
            return code;
1513
4.64M
    }
1514
7.41M
    if (profile_struct ==  NULL)
1515
0
        return 0;
1516
7.41M
    profile_struct->rendercond[profile_type].preserve_black = blackpreserve;
1517
7.41M
    return 0;
1518
7.41M
}
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.41M
{
1524
7.41M
    int code;
1525
7.41M
    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.41M
    if (dev_proc(dev, get_profile) == NULL) {
1532
2.76M
        profile_struct = dev->icc_struct;
1533
4.64M
    } else {
1534
4.64M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1535
4.64M
        if (code < 0)
1536
0
            return code;
1537
4.64M
    }
1538
7.41M
    if (profile_struct ==  NULL)
1539
0
        return 0;
1540
7.41M
    profile_struct->rendercond[profile_type].rendering_intent = intent;
1541
7.41M
    return 0;
1542
7.41M
}
1543
1544
int
1545
gsicc_set_device_blackptcomp(gx_device *dev, gsicc_blackptcomp_t blackptcomp,
1546
                                gsicc_profile_types_t profile_type)
1547
7.41M
{
1548
7.41M
    int code = 0;
1549
7.41M
    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.41M
    if (dev_proc(dev, get_profile) == NULL) {
1556
2.76M
        profile_struct = dev->icc_struct;
1557
4.64M
    } else {
1558
4.64M
        code = dev_proc(dev, get_profile)(dev,  &profile_struct);
1559
4.64M
    }
1560
7.41M
    if (profile_struct ==  NULL)
1561
0
        return 0;
1562
7.41M
    profile_struct->rendercond[profile_type].black_point_comp = blackptcomp;
1563
7.41M
    return code;
1564
7.41M
}
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
392k
{
1756
392k
    int code;
1757
392k
    cmm_profile_t *curr_profile;
1758
392k
    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
392k
    profile_struct = dev->icc_struct;
1765
392k
    if (profile_struct != NULL) {
1766
        /* Get the profile of interest */
1767
243k
        if (profile_type < gsPROOFPROFILE) {
1768
243k
            curr_profile = profile_struct->device_profile[profile_type];
1769
243k
        } 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
243k
        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
93.6k
            if (profile_name != NULL && curr_profile->name != NULL) {
1786
93.6k
                if (strncmp(curr_profile->name, profile_name,
1787
93.6k
                            strlen(profile_name)) != 0 &&
1788
0
                    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
93.6k
                } else {
1812
                    /* Nothing to change.  It was either the same or is the
1813
                       output intent */
1814
93.6k
                    return 0;
1815
93.6k
                }
1816
93.6k
            }
1817
93.6k
        }
1818
243k
    } else {
1819
        /* We have no profile structure at all. Allocate the structure in
1820
           non-GC memory.  */
1821
148k
        dev->icc_struct = gsicc_new_device_profile_array(dev);
1822
148k
        profile_struct = dev->icc_struct;
1823
148k
        if (profile_struct == NULL)
1824
0
            return_error(gs_error_VMerror);
1825
148k
    }
1826
    /* Either use the incoming or a default */
1827
298k
    if (profile_name == NULL) {
1828
272k
        int has_tags = device_encodes_tags(dev);
1829
272k
        profile_name =
1830
272k
            (char *) gs_alloc_bytes(dev->memory,
1831
272k
                                    MAX_DEFAULT_ICC_LENGTH,
1832
272k
                                    "gsicc_init_device_profile_struct");
1833
272k
        if (profile_name == NULL)
1834
0
            return_error(gs_error_VMerror);
1835
272k
        switch(dev->color_info.num_components - has_tags) {
1836
160k
            case 1:
1837
160k
                strncpy(profile_name, DEFAULT_GRAY_ICC, strlen(DEFAULT_GRAY_ICC));
1838
160k
                profile_name[strlen(DEFAULT_GRAY_ICC)] = 0;
1839
160k
                break;
1840
87.8k
            case 3:
1841
87.8k
                strncpy(profile_name, DEFAULT_RGB_ICC, strlen(DEFAULT_RGB_ICC));
1842
87.8k
                profile_name[strlen(DEFAULT_RGB_ICC)] = 0;
1843
87.8k
                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
23.7k
            default:
1849
23.7k
                strncpy(profile_name, DEFAULT_CMYK_ICC, strlen(DEFAULT_CMYK_ICC));
1850
23.7k
                profile_name[strlen(DEFAULT_CMYK_ICC)] = 0;
1851
23.7k
                break;
1852
272k
        }
1853
        /* Go ahead and set the profile */
1854
272k
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1855
272k
                                        profile_type);
1856
272k
        gs_free_object(dev->memory, profile_name,
1857
272k
                       "gsicc_init_device_profile_struct");
1858
272k
        return code;
1859
272k
    } else {
1860
        /* Go ahead and set the profile */
1861
26.5k
        code = gsicc_set_device_profile(dev, dev->memory, profile_name,
1862
26.5k
                                        profile_type);
1863
26.5k
        return code;
1864
26.5k
    }
1865
298k
}
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
380k
{
1884
380k
    int k;
1885
380k
    cmm_dev_profile_t *dev_icc = pdev->icc_struct;
1886
380k
    bool check_components = true;
1887
380k
    bool can_postrender = false;
1888
380k
    bool objects = false;
1889
380k
    int has_tags = device_encodes_tags(pdev);
1890
380k
    int num_components = pdev->color_info.num_components - has_tags;
1891
1892
380k
    if (dev_proc(pdev, dev_spec_op) != NULL) {
1893
380k
        check_components = !(dev_proc(pdev, dev_spec_op)(pdev, gxdso_skip_icc_component_validation, NULL, 0));
1894
380k
        can_postrender = dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_iccpostrender, NULL, 0);
1895
380k
    }
1896
1897
380k
    if (dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE] == NULL)
1898
0
        return 0;
1899
1900
380k
    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
380k
    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
380k
    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.52M
    for (k = 1; k < NUM_DEVICE_PROFILES; k++) {
1925
1.14M
        if (dev_icc->device_profile[k] != NULL) {
1926
0
            objects = true;
1927
0
            break;
1928
0
        }
1929
1.14M
    }
1930
1931
380k
    if (dev_icc->link_profile == NULL) {
1932
380k
        if (!objects) {
1933
380k
            if (check_components && dev_icc->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps !=
1934
175k
                num_components)
1935
18
                return gs_rethrow(-1, "Mismatch of ICC profiles and device color model");
1936
380k
            else
1937
380k
                return 0;  /* Currently sep devices have some leeway here */
1938
380k
        } 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
380k
    } 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
380k
}
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
380k
{
1978
380k
    cmm_profile_t *icc_profile;
1979
380k
    stream *str;
1980
380k
    int code;
1981
1982
380k
    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
380k
    if (strncmp(file_name, OI_PROFILE, strlen(OI_PROFILE)) == 0)
1994
0
        return -1;
1995
1996
380k
    code = gsicc_open_search(file_name, strlen(file_name), mem,
1997
380k
                             mem->gs_lib_ctx->profiledir,
1998
380k
                             mem->gs_lib_ctx->profiledir_len, &str);
1999
380k
    if (code < 0)
2000
0
        return code;
2001
380k
    if (str == NULL)
2002
0
        return gs_rethrow(-1, "cannot find device profile");
2003
2004
380k
    icc_profile =
2005
380k
            gsicc_profile_new(str, mem, file_name, strlen(file_name));
2006
380k
    code = sfclose(str);
2007
380k
    if (icc_profile == NULL)
2008
0
        return gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
2009
2010
    /* Get the profile handle */
2011
380k
    icc_profile->profile_handle =
2012
380k
                gsicc_get_profile_handle_buffer(icc_profile->buffer,
2013
380k
                                                icc_profile->buffer_size,
2014
380k
                                                mem);
2015
380k
    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
380k
    gsicc_get_icc_buff_hash(icc_profile->buffer,
2023
380k
                            &(icc_profile->hashcode),
2024
380k
                            icc_profile->buffer_size);
2025
380k
    icc_profile->hash_is_valid = true;
2026
2027
    /* Get the number of channels in the output profile */
2028
380k
    icc_profile->num_comps =
2029
380k
                gscms_get_input_channel_count(icc_profile->profile_handle,
2030
380k
                                              icc_profile->memory);
2031
380k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile has %d components\n",
2032
380k
               icc_profile->num_comps);
2033
380k
    icc_profile->num_comps_out =
2034
380k
                gscms_get_output_channel_count(icc_profile->profile_handle,
2035
380k
                                               icc_profile->memory);
2036
380k
    icc_profile->data_cs =
2037
380k
                gscms_get_profile_data_space(icc_profile->profile_handle,
2038
380k
                                             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
380k
    switch (icc_profile->num_comps) {
2047
203k
        case 1:
2048
203k
            if (strncmp(icc_profile->name, DEFAULT_GRAY_ICC,
2049
203k
                        strlen(icc_profile->name)) == 0) {
2050
203k
                icc_profile->default_match = DEFAULT_GRAY;
2051
203k
            }
2052
203k
            break;
2053
150k
        case 3:
2054
150k
            if (strncmp(icc_profile->name, DEFAULT_RGB_ICC,
2055
150k
                        strlen(icc_profile->name)) == 0) {
2056
150k
                icc_profile->default_match = DEFAULT_RGB;
2057
150k
            }
2058
150k
            break;
2059
26.3k
        case 4:
2060
26.3k
            if (strncmp(icc_profile->name, DEFAULT_CMYK_ICC,
2061
26.3k
                        strlen(icc_profile->name)) == 0) {
2062
26.3k
                icc_profile->default_match = DEFAULT_CMYK;
2063
26.3k
            }
2064
26.3k
            break;
2065
380k
    }
2066
2067
380k
    if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n",
2068
380k
               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
380k
    while(pdev->child)
2075
0
        pdev = pdev->child;
2076
2077
380k
    switch (pro_enum)
2078
380k
    {
2079
380k
        case gsDEFAULTPROFILE:
2080
380k
        case gsGRAPHICPROFILE:
2081
380k
        case gsIMAGEPROFILE:
2082
380k
        case gsTEXTPROFILE:
2083
380k
            if_debug1m(gs_debug_flag_icc, mem,
2084
380k
                       "[icc] Setting device profile %d\n", pro_enum);
2085
380k
            pdev->icc_struct->device_profile[pro_enum] = icc_profile;
2086
380k
            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
380k
    }
2109
2110
    /* Check that everything is OK with regard to the number of
2111
       components. */
2112
380k
    if (gsicc_verify_device_profiles(pdev) < 0)
2113
18
        return gs_rethrow(-1, "Error in device profiles");
2114
2115
380k
    if (icc_profile->num_comps != 1 &&
2116
177k
        icc_profile->num_comps != 3 &&
2117
26.3k
        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
380k
    return 0;
2125
380k
}
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
839k
{
2132
839k
    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
839k
    gsicc_adjust_profile_rc(icc_profile, 1, "gsicc_set_gscs_profile");
2144
839k
    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
839k
    pcs->cmm_icc_profile_data = icc_profile;
2152
839k
    return 0;
2153
839k
}
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
18.3M
{
2180
18.3M
    cmm_profile_t *result;
2181
18.3M
    int code;
2182
18.3M
    char *nameptr = NULL;
2183
18.3M
    gs_memory_t *mem_nongc = memory->non_gc_memory;
2184
2185
18.3M
    result = (cmm_profile_t*) gs_alloc_bytes(mem_nongc, sizeof(cmm_profile_t),
2186
18.3M
                                    "gsicc_profile_new");
2187
18.3M
    if (result == NULL)
2188
0
        return result;
2189
18.3M
    memset(result, 0, GSICC_SERIALIZED_SIZE);
2190
18.3M
    if (namelen > 0) {
2191
15.5M
        nameptr = (char*) gs_alloc_bytes(mem_nongc, namelen+1,
2192
15.5M
                             "gsicc_profile_new");
2193
15.5M
        if (nameptr == NULL) {
2194
0
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2195
0
            return NULL;
2196
0
        }
2197
15.5M
        memcpy(nameptr, pname, namelen);
2198
15.5M
        nameptr[namelen] = '\0';
2199
15.5M
        result->name = nameptr;
2200
15.5M
    } else {
2201
2.76M
        result->name = NULL;
2202
2.76M
    }
2203
18.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
18.3M
    if ( s != NULL) {
2209
15.6M
        code = gsicc_load_profile_buffer(result, s, mem_nongc);
2210
15.6M
        if (code < 0) {
2211
8.09k
            gs_free_object(mem_nongc, result, "gsicc_profile_new");
2212
8.09k
            gs_free_object(mem_nongc, nameptr, "gsicc_profile_new");
2213
8.09k
            return NULL;
2214
8.09k
        }
2215
15.6M
    } else {
2216
2.72M
        result->buffer = NULL;
2217
2.72M
        result->buffer_size = 0;
2218
2.72M
    }
2219
18.3M
    rc_init_free(result, mem_nongc, 1, rc_free_icc_profile);
2220
18.3M
    result->profile_handle = NULL;
2221
18.3M
    result->spotnames = NULL;
2222
18.3M
    result->rend_is_valid = false;
2223
18.3M
    result->isdevlink = false;  /* only used for srcgtag profiles */
2224
18.3M
    result->dev = NULL;
2225
18.3M
    result->memory = mem_nongc;
2226
18.3M
    result->vers = ICCVERS_UNKNOWN;
2227
18.3M
    result->v2_data = NULL;
2228
18.3M
    result->v2_size = 0;
2229
18.3M
    result->release = gscms_release_profile; /* Default case */
2230
2231
18.3M
    result->lock = gx_monitor_label(gx_monitor_alloc(mem_nongc),
2232
18.3M
                                    "gsicc_manage");
2233
18.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
18.3M
    if_debug1m(gs_debug_flag_icc, mem_nongc,
2240
18.3M
               "[icc] allocating ICC profile = "PRI_INTPTR"\n", (intptr_t)result);
2241
18.3M
    return result;
2242
18.3M
}
2243
2244
static void
2245
rc_free_icc_profile(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2246
18.3M
{
2247
18.3M
    cmm_profile_t *profile = (cmm_profile_t *)ptr_in;
2248
18.3M
    gs_memory_t *mem_nongc =  profile->memory;
2249
2250
18.3M
    if_debug2m(gs_debug_flag_icc, mem,
2251
18.3M
               "[icc] rc decrement profile = "PRI_INTPTR" rc = %ld\n",
2252
18.3M
               (intptr_t)ptr_in, profile->rc.ref_count);
2253
18.3M
    if (profile->rc.ref_count <= 1 ) {
2254
        /* Clear out the buffer if it is full */
2255
18.3M
        if (profile->buffer != NULL) {
2256
15.6M
            gs_free_object(mem_nongc, profile->buffer, "rc_free_icc_profile(buffer)");
2257
15.6M
            profile->buffer = NULL;
2258
15.6M
        }
2259
18.3M
        if_debug0m(gs_debug_flag_icc, mem, "[icc] profile freed\n");
2260
        /* Release this handle if it has been set */
2261
18.3M
        if (profile->profile_handle != NULL) {
2262
919k
            profile->release(profile->profile_handle, profile->memory);
2263
919k
            profile->profile_handle = NULL;
2264
919k
        }
2265
        /* Release the name if it has been set */
2266
18.3M
        if (profile->name != NULL) {
2267
15.5M
            gs_free_object(mem_nongc, profile->name,"rc_free_icc_profile(name)");
2268
15.5M
            profile->name = NULL;
2269
15.5M
            profile->name_length = 0;
2270
15.5M
        }
2271
18.3M
        profile->hash_is_valid = 0;
2272
18.3M
        if (profile->lock != NULL) {
2273
18.3M
            gx_monitor_free(profile->lock);
2274
18.3M
            profile->lock = NULL;
2275
18.3M
        }
2276
        /* If we had a DeviceN profile with names deallocate that now */
2277
18.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
18.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
18.3M
        gs_free_object(mem_nongc, profile, "rc_free_icc_profile");
2288
18.3M
    }
2289
18.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.88M
{
2327
3.88M
    int code = 0, k;
2328
3.88M
    const char *pname;
2329
3.88M
    int namelen;
2330
3.88M
    gsicc_manager_t *iccmanager = pgs->icc_manager;
2331
3.88M
    cmm_profile_t *profile;
2332
2333
19.4M
    for (k = 0; k < 4; k++) {
2334
15.5M
        pname = default_profile_params[k].path;
2335
15.5M
        namelen = strlen(pname);
2336
2337
15.5M
        switch(default_profile_params[k].default_type) {
2338
3.88M
            case DEFAULT_GRAY:
2339
3.88M
                profile = iccmanager->default_gray;
2340
3.88M
                break;
2341
3.88M
            case DEFAULT_RGB:
2342
3.88M
                profile = iccmanager->default_rgb;
2343
3.88M
                break;
2344
3.88M
            case DEFAULT_CMYK:
2345
3.88M
                 profile = iccmanager->default_cmyk;
2346
3.88M
                 break;
2347
3.88M
            default:
2348
3.88M
                profile = NULL;
2349
15.5M
        }
2350
15.5M
        if (profile == NULL)
2351
15.1M
            code = gsicc_set_profile(iccmanager, pname, namelen,
2352
15.1M
                                     default_profile_params[k].default_type);
2353
15.5M
        if (code < 0)
2354
0
            return gs_rethrow(code, "cannot find default icc profile");
2355
15.5M
    }
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.88M
    return 0;
2381
3.88M
}
2382
2383
static void
2384
gsicc_manager_finalize(const gs_memory_t *memory, void * vptr)
2385
3.76M
{
2386
3.76M
    gsicc_manager_t *icc_man = (gsicc_manager_t *)vptr;
2387
2388
3.76M
    gsicc_manager_free_contents(icc_man, "gsicc_manager_finalize");
2389
3.76M
}
2390
2391
gsicc_manager_t *
2392
gsicc_manager_new(gs_memory_t *memory)
2393
3.76M
{
2394
3.76M
    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.76M
    memory = memory->stable_memory;
2399
3.76M
    result = gs_alloc_struct(memory, gsicc_manager_t, &st_gsicc_manager,
2400
3.76M
                             "gsicc_manager_new");
2401
3.76M
    if ( result == NULL )
2402
0
        return NULL;
2403
3.76M
    rc_init_free(result, memory, 1, rc_gsicc_manager_free);
2404
3.76M
    result->default_gray = NULL;
2405
3.76M
    result->default_rgb = NULL;
2406
3.76M
    result->default_cmyk = NULL;
2407
3.76M
    result->lab_profile = NULL;
2408
3.76M
    result->xyz_profile = NULL;
2409
3.76M
    result->graytok_profile = NULL;
2410
3.76M
    result->device_named = NULL;
2411
3.76M
    result->device_n = NULL;
2412
3.76M
    result->smask_profiles = NULL;
2413
3.76M
    result->memory = memory;
2414
3.76M
    result->srcgtag_profile = NULL;
2415
3.76M
    result->override_internal = false;
2416
3.76M
    return result;
2417
3.76M
}
2418
2419
static void gsicc_manager_free_contents(gsicc_manager_t *icc_manager,
2420
                                        client_name_t cname)
2421
3.76M
{
2422
3.76M
    int k;
2423
3.76M
    gsicc_devicen_entry_t *device_n, *device_n_next;
2424
2425
3.76M
    gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "gsicc_manager_free_contents");
2426
3.76M
    gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "gsicc_manager_free_contents");
2427
3.76M
    gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "gsicc_manager_free_contents");
2428
3.76M
    gsicc_adjust_profile_rc(icc_manager->device_named, -1, "gsicc_manager_free_contents");
2429
3.76M
    gsicc_adjust_profile_rc(icc_manager->lab_profile, -1, "gsicc_manager_free_contents");
2430
3.76M
    gsicc_adjust_profile_rc(icc_manager->graytok_profile, -1, "gsicc_manager_free_contents");
2431
3.76M
    rc_decrement(icc_manager->srcgtag_profile, "gsicc_manager_free_contents");
2432
2433
    /* Loop through the DeviceN profiles */
2434
3.76M
    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.76M
    if (icc_manager->smask_profiles != NULL) {
2448
32.4k
        gs_free_object(icc_manager->smask_profiles->memory, icc_manager->smask_profiles, "gsicc_manager_free_contents");
2449
32.4k
        icc_manager->smask_profiles = NULL;
2450
32.4k
    }
2451
3.76M
}
2452
2453
static void
2454
rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2455
3.76M
{
2456
    /* Ending the manager.  Decrement the ref counts of the profiles
2457
       and then free the structure */
2458
3.76M
    gsicc_manager_t *icc_manager = (gsicc_manager_t * ) ptr_in;
2459
2460
3.76M
    assert(mem == icc_manager->memory);
2461
2462
3.76M
    gs_free_object(icc_manager->memory, icc_manager, "rc_gsicc_manager_free");
2463
3.76M
}
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
15.6M
{
2470
15.6M
    int                     num_bytes,profile_size;
2471
15.6M
    unsigned char           *buffer_ptr;
2472
15.6M
    int                     code;
2473
2474
15.6M
    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
15.6M
    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
15.6M
    code = sfseek(s,0,SEEK_END);
2483
15.6M
    if (code < 0)
2484
0
        return code;
2485
15.6M
    profile_size = sftell(s);
2486
15.6M
    code = srewind(s);
2487
15.6M
    if (code < 0)
2488
0
        return code;
2489
15.6M
    if (profile_size < ICC_HEADER_SIZE)
2490
8.09k
        return_error(gs_error_VMerror);
2491
    /* Allocate the buffer, stuff with the profile */
2492
15.6M
   buffer_ptr = gs_alloc_bytes(memory, profile_size,
2493
15.6M
                                        "gsicc_load_profile");
2494
15.6M
   if (buffer_ptr == NULL)
2495
0
        return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer");
2496
15.6M
   num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s);
2497
15.6M
   if( num_bytes != profile_size) {
2498
0
       gs_free_object(memory, buffer_ptr, "gsicc_load_profile");
2499
0
       return -1;
2500
0
   }
2501
15.6M
   profile->buffer = buffer_ptr;
2502
15.6M
   profile->buffer_size = num_bytes;
2503
15.6M
   return 0;
2504
15.6M
}
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
31.3k
{
2544
31.3k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
2545
31.3k
    int64_t hashcode = picc_profile->hashcode;
2546
2547
31.3k
    if ( picc_profile->default_match == DEFAULT_NONE ) {
2548
31.3k
        switch ( picc_profile->data_cs ) {
2549
11.8k
            case gsGRAY:
2550
11.8k
                if ( hashcode == icc_manager->default_gray->hashcode )
2551
0
                    picc_profile->default_match = DEFAULT_GRAY_s;
2552
11.8k
                break;
2553
19.4k
            case gsRGB:
2554
19.4k
                if ( hashcode == icc_manager->default_rgb->hashcode )
2555
0
                    picc_profile->default_match = DEFAULT_RGB_s;
2556
19.4k
                break;
2557
38
            case gsCMYK:
2558
38
                if ( hashcode == icc_manager->default_cmyk->hashcode )
2559
0
                    picc_profile->default_match = DEFAULT_CMYK_s;
2560
38
                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
31.3k
        }
2574
31.3k
    }
2575
31.3k
}
2576
2577
/* Initialize the hash code value */
2578
void
2579
gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_gstate *pgs)
2580
31.3k
{
2581
31.3k
    if ( !(picc_profile->hash_is_valid) ) {
2582
25.7k
        gsicc_get_icc_buff_hash(picc_profile->buffer, &(picc_profile->hashcode),
2583
25.7k
                                picc_profile->buffer_size);
2584
25.7k
        picc_profile->hash_is_valid = true;
2585
25.7k
    }
2586
31.3k
    gsicc_set_default_cs_value(picc_profile, pgs);
2587
31.3k
}
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
18.9k
{
2594
18.9k
    gcmmhprofile_t profile_handle = NULL;
2595
18.9k
    unsigned int profile_size;
2596
18.9k
    int size;
2597
18.9k
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) picc_profile->dev;
2598
18.9k
    unsigned char *buffer_ptr;
2599
18.9k
    int64_t position;
2600
18.9k
    gsicc_serialized_profile_t profile_header;
2601
18.9k
    int k;
2602
2603
18.9k
    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
18.9k
        position = gsicc_search_icc_table(pcrdev->icc_table,
2608
18.9k
                                          picc_profile->hashcode, &size);
2609
18.9k
        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
18.9k
        profile_size = size - GSICC_SERIALIZED_SIZE;
2617
        /* Profile and its members are ALL in non-gc memory */
2618
18.9k
        buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size,
2619
18.9k
                                            "gsicc_get_profile_handle_clist");
2620
18.9k
        if (buffer_ptr == NULL)
2621
0
            return NULL;
2622
18.9k
        clist_read_chunk(pcrdev, position + GSICC_SERIALIZED_SIZE,
2623
18.9k
            profile_size, (unsigned char *) buffer_ptr);
2624
18.9k
        profile_handle = gscms_get_profile_handle_mem(buffer_ptr, profile_size, memory->non_gc_memory);
2625
18.9k
        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
18.9k
        clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2631
18.9k
                        (unsigned char *) (&profile_header));
2632
18.9k
        picc_profile->buffer = NULL;
2633
18.9k
        picc_profile->buffer_size = 0;
2634
18.9k
        picc_profile->data_cs = profile_header.data_cs;
2635
18.9k
        picc_profile->default_match = profile_header.default_match;
2636
18.9k
        picc_profile->hash_is_valid = profile_header.hash_is_valid;
2637
18.9k
        picc_profile->hashcode = profile_header.hashcode;
2638
18.9k
        picc_profile->islab = profile_header.islab;
2639
18.9k
        picc_profile->num_comps = profile_header.num_comps;
2640
18.9k
        picc_profile->rend_is_valid = profile_header.rend_is_valid;
2641
18.9k
        picc_profile->rend_cond = profile_header.rend_cond;
2642
18.9k
        picc_profile->isdevlink = profile_header.isdevlink;
2643
63.2k
        for ( k = 0; k < profile_header.num_comps; k++ ) {
2644
44.2k
            picc_profile->Range.ranges[k].rmax =
2645
44.2k
                profile_header.Range.ranges[k].rmax;
2646
44.2k
            picc_profile->Range.ranges[k].rmin =
2647
44.2k
                profile_header.Range.ranges[k].rmin;
2648
44.2k
        }
2649
18.9k
        gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_get_profile_handle_clist");
2650
18.9k
        return profile_handle;
2651
18.9k
     }
2652
0
     return NULL;
2653
18.9k
}
2654
2655
gcmmhprofile_t
2656
gsicc_get_profile_handle_buffer(unsigned char *buffer, int profile_size, gs_memory_t *memory)
2657
905k
{
2658
2659
905k
    gcmmhprofile_t profile_handle = NULL;
2660
2661
905k
     if( buffer != NULL) {
2662
905k
         if (profile_size < ICC_HEADER_SIZE) {
2663
0
             return 0;
2664
0
         }
2665
905k
         profile_handle = gscms_get_profile_handle_mem(buffer, profile_size, memory->non_gc_memory);
2666
905k
         return profile_handle;
2667
905k
     }
2668
0
     return 0;
2669
905k
}
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.93M
{
2790
1.93M
    int tablesize = icc_table->tablesize, k;
2791
1.93M
    clist_icctable_entry_t *curr_entry;
2792
2793
1.93M
    curr_entry = icc_table->head;
2794
2.73M
    for (k = 0; k < tablesize; k++ ) {
2795
2.73M
        if ( curr_entry->serial_data.hashcode == icc_hashcode ) {
2796
1.93M
            *size = curr_entry->serial_data.size;
2797
1.93M
            return curr_entry->serial_data.file_position;
2798
1.93M
        }
2799
800k
        curr_entry = curr_entry->next;
2800
800k
    }
2801
2802
    /* Did not find it! */
2803
0
    *size = 0;
2804
0
    return -1;
2805
1.93M
}
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.91M
{
2813
1.91M
    cmm_profile_t *profile;
2814
1.91M
    int64_t position;
2815
1.91M
    int size;
2816
1.91M
    int code;
2817
1.91M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader*) dev;
2818
2819
    /* Create a new ICC profile structure */
2820
1.91M
    profile = gsicc_profile_new(NULL, pcrdev->memory, NULL, 0);
2821
1.91M
    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.91M
    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.91M
    position = gsicc_search_icc_table(pcrdev->icc_table, icc_hashcode, &size);
2833
1.91M
    if ( position < 0 )
2834
0
        return NULL;
2835
2836
    /* Get the serialized portion of the ICC profile information */
2837
1.91M
    clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE,
2838
1.91M
                    (unsigned char *) profile);
2839
1.91M
    return profile;
2840
1.91M
}
2841
2842
void
2843
gsicc_profile_serialize(gsicc_serialized_profile_t *profile_data,
2844
                        cmm_profile_t *icc_profile)
2845
25.3k
{
2846
25.3k
    if (icc_profile == NULL)
2847
0
        return;
2848
25.3k
    memcpy(profile_data, icc_profile, GSICC_SERIALIZED_SIZE);
2849
25.3k
}
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
383M
{
2865
383M
    switch (graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) {
2866
128M
        case GS_UNKNOWN_TAG:
2867
132M
        case GS_UNTOUCHED_TAG:
2868
132M
        default:
2869
132M
            (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2870
132M
            *render_cond = profile_struct->rendercond[GS_DEFAULT_DEVICE_PROFILE];
2871
132M
            break;
2872
138M
        case GS_VECTOR_TAG:
2873
138M
            *render_cond = profile_struct->rendercond[GS_VECTOR_DEVICE_PROFILE];
2874
138M
            if (profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE] != NULL) {
2875
0
                (*profile) = profile_struct->device_profile[GS_VECTOR_DEVICE_PROFILE];
2876
138M
            } else {
2877
138M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2878
138M
            }
2879
138M
            break;
2880
109M
        case GS_IMAGE_TAG:
2881
109M
            *render_cond = profile_struct->rendercond[GS_IMAGE_DEVICE_PROFILE];
2882
109M
            if (profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE] != NULL) {
2883
0
                (*profile) = profile_struct->device_profile[GS_IMAGE_DEVICE_PROFILE];
2884
109M
            } else {
2885
109M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2886
109M
            }
2887
109M
            break;
2888
4.17M
        case GS_TEXT_TAG:
2889
4.17M
            *render_cond = profile_struct->rendercond[GS_TEXT_DEVICE_PROFILE];
2890
4.17M
            if (profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE] != NULL) {
2891
0
                (*profile) = profile_struct->device_profile[GS_TEXT_DEVICE_PROFILE];
2892
4.17M
            } else {
2893
4.17M
                (*profile) = profile_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2894
4.17M
            }
2895
4.17M
            break;
2896
383M
        }
2897
383M
}
2898
2899
/* internal ICC and rendering intent override control */
2900
void
2901
gs_setoverrideicc(gs_gstate *pgs, bool value)
2902
685k
{
2903
685k
    if (pgs->icc_manager != NULL) {
2904
685k
        pgs->icc_manager->override_internal = value;
2905
685k
    }
2906
685k
}
2907
bool
2908
gs_currentoverrideicc(const gs_gstate *pgs)
2909
1.05M
{
2910
1.05M
    if (pgs->icc_manager != NULL) {
2911
1.05M
        return pgs->icc_manager->override_internal;
2912
1.05M
    } else {
2913
0
        return false;
2914
0
    }
2915
1.05M
}
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
770k
{
2948
770k
    static const char *const rfs = "";
2949
2950
    /*FIXME: This should return the entire list !!! */
2951
    /*       Just return the first one for now      */
2952
770k
    if (pgs->icc_manager->device_n == NULL) {
2953
770k
        pval->data = (const byte *) rfs;
2954
770k
        pval->persistent = true;
2955
770k
    } 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
770k
    pval->size = strlen((const char *)pval->data);
2961
770k
}
2962
2963
int
2964
gs_setdevicenprofileicc(const gs_gstate * pgs, gs_param_string * pval)
2965
658k
{
2966
658k
    int code = 0;
2967
658k
    char *pname, *pstr, *pstrend, *last = NULL;
2968
658k
    int namelen = (pval->size)+1;
2969
658k
    gs_memory_t *mem = pgs->memory;
2970
2971
    /* Check if it was "NULL" */
2972
658k
    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
658k
    return 0;
3009
658k
}
3010
3011
void
3012
gs_currentdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3013
770k
{
3014
770k
    static const char *const rfs = DEFAULT_GRAY_ICC;
3015
3016
770k
    if (pgs->icc_manager->default_gray == NULL) {
3017
385k
        pval->data = (const byte *) rfs;
3018
385k
        pval->persistent = true;
3019
385k
    } else {
3020
385k
        pval->data = (const byte *) (pgs->icc_manager->default_gray->name);
3021
385k
        pval->persistent = false;
3022
385k
    }
3023
770k
    pval->size = strlen((const char *)pval->data);
3024
770k
}
3025
3026
int
3027
gs_setdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval)
3028
658k
{
3029
658k
    int code;
3030
658k
    char *pname;
3031
658k
    int namelen = (pval->size)+1;
3032
658k
    gs_memory_t *mem = pgs->memory;
3033
658k
    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
658k
    not_initialized = (pgs->icc_manager->default_gray == NULL);
3040
3041
658k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3042
658k
                             "set_default_gray_icc");
3043
658k
    if (pname == NULL)
3044
0
        return_error(gs_error_VMerror);
3045
658k
    memcpy(pname,pval->data,namelen-1);
3046
658k
    pname[namelen-1] = 0;
3047
658k
    code = gsicc_set_profile(pgs->icc_manager,
3048
658k
        (const char*) pname, namelen-1, DEFAULT_GRAY);
3049
658k
    gs_free_object(mem, pname,
3050
658k
        "set_default_gray_icc");
3051
658k
    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
658k
    if (not_initialized) {
3056
0
        code = gsicc_init_gs_colors((gs_gstate*) pgs);
3057
0
    }
3058
658k
    if (code < 0)
3059
0
        return gs_throw(code, "error initializing gstate color spaces to icc");
3060
658k
    return code;
3061
658k
}
3062
3063
void
3064
gs_currenticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3065
770k
{
3066
770k
    static const char *const rfs = DEFAULT_DIR_ICC;   /* as good as any other */
3067
770k
    const gs_lib_ctx_t *lib_ctx = pgs->memory->gs_lib_ctx;
3068
3069
770k
    if (lib_ctx->profiledir == NULL) {
3070
0
        pval->data = (const byte *)rfs;
3071
0
        pval->size = strlen(rfs);
3072
0
        pval->persistent = true;
3073
770k
    } else {
3074
770k
        pval->data = (const byte *)(lib_ctx->profiledir);
3075
770k
        pval->size = lib_ctx->profiledir_len;
3076
770k
        pval->persistent = false;
3077
770k
    }
3078
770k
}
3079
3080
int
3081
gs_seticcdirectory(const gs_gstate * pgs, gs_param_string * pval)
3082
658k
{
3083
658k
    char *pname;
3084
658k
    int namelen = (pval->size)+1;
3085
658k
    gs_memory_t *mem = (gs_memory_t *)pgs->memory;
3086
3087
    /* Check if it was "NULL" */
3088
658k
    if (pval->size != 0 ) {
3089
658k
        pname = (char *)gs_alloc_bytes(mem, namelen,
3090
658k
                                       "gs_seticcdirectory");
3091
658k
        if (pname == NULL)
3092
0
            return gs_rethrow(gs_error_VMerror, "cannot allocate directory name");
3093
658k
        memcpy(pname,pval->data,namelen-1);
3094
658k
        pname[namelen-1] = 0;
3095
658k
        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
658k
        gs_free_object(mem, pname, "gs_seticcdirectory");
3100
658k
    }
3101
658k
    return 0;
3102
658k
}
3103
3104
void
3105
gs_currentsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3106
770k
{
3107
770k
    if (pgs->icc_manager->srcgtag_profile == NULL) {
3108
770k
        pval->data = NULL;
3109
770k
        pval->size = 0;
3110
770k
        pval->persistent = true;
3111
770k
    } 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
770k
}
3117
3118
int
3119
gs_setsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval)
3120
658k
{
3121
658k
    int code;
3122
658k
    char *pname;
3123
658k
    int namelen = (pval->size)+1;
3124
658k
    gs_memory_t *mem = pgs->memory;
3125
3126
658k
    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
770k
{
3143
770k
    static const char *const rfs = DEFAULT_RGB_ICC;
3144
3145
770k
    if (pgs->icc_manager->default_rgb == NULL) {
3146
385k
        pval->data = (const byte *) rfs;
3147
385k
        pval->persistent = true;
3148
385k
    } else {
3149
385k
        pval->data = (const byte *) (pgs->icc_manager->default_rgb->name);
3150
385k
        pval->persistent = false;
3151
385k
    }
3152
770k
    pval->size = strlen((const char *)pval->data);
3153
770k
}
3154
3155
int
3156
gs_setdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval)
3157
658k
{
3158
658k
    int code;
3159
658k
    char *pname;
3160
658k
    int namelen = (pval->size)+1;
3161
658k
    gs_memory_t *mem = pgs->memory;
3162
3163
658k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3164
658k
                             "set_default_rgb_icc");
3165
658k
    if (pname == NULL)
3166
0
        return_error(gs_error_VMerror);
3167
658k
    memcpy(pname,pval->data,namelen-1);
3168
658k
    pname[namelen-1] = 0;
3169
658k
    code = gsicc_set_profile(pgs->icc_manager,
3170
658k
        (const char*) pname, namelen-1, DEFAULT_RGB);
3171
658k
    gs_free_object(mem, pname,
3172
658k
        "set_default_rgb_icc");
3173
658k
    if (code < 0)
3174
0
        return gs_rethrow(code, "cannot find default rgb icc profile");
3175
658k
    return code;
3176
658k
}
3177
3178
void
3179
gs_currentnamedicc(const gs_gstate * pgs, gs_param_string * pval)
3180
770k
{
3181
770k
    static const char *const rfs = "";
3182
3183
770k
    if (pgs->icc_manager->device_named == NULL) {
3184
770k
        pval->data = (const byte *) rfs;
3185
770k
        pval->persistent = true;
3186
770k
    } else {
3187
0
        pval->data = (const byte *) (pgs->icc_manager->device_named->name);
3188
0
        pval->persistent = false;
3189
0
    }
3190
770k
    pval->size = strlen((const char *)pval->data);
3191
770k
}
3192
3193
int
3194
gs_setnamedprofileicc(const gs_gstate * pgs, gs_param_string * pval)
3195
658k
{
3196
658k
    int code;
3197
658k
    char* pname;
3198
658k
    int namelen = (pval->size)+1;
3199
658k
    gs_memory_t *mem = pgs->memory;
3200
3201
    /* Check if it was "NULL" */
3202
658k
    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
658k
    return 0;
3218
658k
}
3219
3220
void
3221
gs_currentdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3222
770k
{
3223
770k
    static const char *const rfs = DEFAULT_CMYK_ICC;
3224
3225
770k
    if (pgs->icc_manager->default_cmyk == NULL) {
3226
385k
        pval->data = (const byte *) rfs;
3227
385k
        pval->persistent = true;
3228
385k
    } else {
3229
385k
        pval->data = (const byte *) (pgs->icc_manager->default_cmyk->name);
3230
385k
        pval->persistent = false;
3231
385k
    }
3232
770k
    pval->size = strlen((const char *)pval->data);
3233
770k
}
3234
3235
int
3236
gs_setdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval)
3237
658k
{
3238
658k
    int code;
3239
658k
    char* pname;
3240
658k
    int namelen = (pval->size)+1;
3241
658k
    gs_memory_t *mem = pgs->memory;
3242
3243
658k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3244
658k
                             "set_default_cmyk_icc");
3245
658k
    if (pname == NULL)
3246
0
        return_error(gs_error_VMerror);
3247
658k
    memcpy(pname,pval->data,namelen-1);
3248
658k
    pname[namelen-1] = 0;
3249
658k
    code = gsicc_set_profile(pgs->icc_manager,
3250
658k
        (const char*) pname, namelen-1, DEFAULT_CMYK);
3251
658k
    gs_free_object(mem, pname,
3252
658k
                "set_default_cmyk_icc");
3253
658k
    if (code < 0)
3254
0
        return gs_throw(code, "cannot find default cmyk icc profile");
3255
658k
    return code;
3256
658k
}
3257
3258
void
3259
gs_currentlabicc(const gs_gstate * pgs, gs_param_string * pval)
3260
770k
{
3261
770k
    static const char *const rfs = LAB_ICC;
3262
3263
770k
    pval->data = (const byte *)( (pgs->icc_manager->lab_profile == NULL) ?
3264
385k
                        rfs : pgs->icc_manager->lab_profile->name);
3265
770k
    pval->size = strlen((const char *)pval->data);
3266
770k
    pval->persistent = true;
3267
770k
}
3268
3269
int
3270
gs_setlabicc(const gs_gstate * pgs, gs_param_string * pval)
3271
658k
{
3272
658k
    int code;
3273
658k
    char* pname;
3274
658k
    int namelen = (pval->size)+1;
3275
658k
    gs_memory_t *mem = pgs->memory;
3276
3277
658k
    pname = (char *)gs_alloc_bytes(mem, namelen,
3278
658k
                             "set_lab_icc");
3279
658k
    if (pname == NULL)
3280
0
        return_error(gs_error_VMerror);
3281
658k
    memcpy(pname,pval->data,namelen-1);
3282
658k
    pname[namelen-1] = 0;
3283
658k
    code = gsicc_set_profile(pgs->icc_manager,
3284
658k
        (const char*) pname, namelen-1, LAB_TYPE);
3285
658k
    gs_free_object(mem, pname,
3286
658k
                "set_lab_icc");
3287
658k
    if (code < 0)
3288
0
        return gs_throw(code, "cannot find default lab icc profile");
3289
658k
    return code;
3290
658k
}