Coverage Report

Created: 2026-07-24 07:44

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