Coverage Report

Created: 2026-02-14 07:09

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