Coverage Report

Created: 2026-04-01 07:17

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