Coverage Report

Created: 2026-08-08 08:00

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