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