Coverage Report

Created: 2025-06-24 07:01

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