Coverage Report

Created: 2025-12-31 07:31

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