Coverage Report

Created: 2026-09-14 07:34

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