Coverage Report

Created: 2022-10-31 07:00

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