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