Coverage Report

Created: 2026-04-09 07:06

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