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 /*  Data type definitions when using the gscms  */
17 
18 #ifndef gscms_INCLUDED
19 #  define gscms_INCLUDED
20 
21 #include "std.h"
22 #include "gstypes.h"
23 #include "gscspace.h"      /* for gs_color_space */
24 #include "gsdevice.h"     /* Need to carry pointer to clist reader */
25 #include "gxsync.h"       /* for monitors */
26 #include "stdint_.h"
27 
28 #define ICC_MAX_CHANNELS 15
29 #define NUM_DEVICE_PROFILES 4
30 #define NUM_SOURCE_PROFILES 3
31 
32 #define AB_NEUTRAL_8 5
33 #define AB_NEUTRAL_16 5
34 
35 #define DEV_NEUTRAL_8 5
36 #define DEV_NEUTRAL_16 5
37 
38 /* Define the preferred size of the output by the CMS */
39 /* This can be different than the size of gx_color_value
40    which can range between 8 and 16.  Here we can only
41    have 8 or 16 bits */
42 
43 typedef unsigned short icc_output_type;
44 
45 #define icc_byte_count sizeof(icc_output_type)
46 #define icc_bits_count (icc_byte_count * 8)
47 #define icc_max_color_value ((gx_color_value)((1L << icc_bits_count) - 1))
48 #define icc_value_to_byte(cv)\
49   ((cv) >> (icc_bits_count - 8))
50 #define icc_value_from_byte(cb)\
51   (((cb) << (icc_bits_count - 8)) + ((cb) >> (16 - icc_bits_count)))
52 
53 typedef struct gs_range_icc_s {
54     gs_range_t ranges[ICC_MAX_CHANNELS];
55 } gs_range_icc_t;  /* ICC profile input could be up to 15 bands */
56 
57 /* This object is used only for device post processing CM.  It and its objects
58    must be allocated in non-gc memory. */
59 
60 typedef struct gsicc_device_cm_s {
61     cmm_profile_t *gray_profile;
62     cmm_profile_t *rgb_profile;
63     cmm_profile_t *cmyk_profile;
64     cmm_profile_t *device_link_profile;
65     gs_memory_t *memory;
66 } gsicc_device_cm_t;
67 
68 /*  The buffer description.  We handle a variety of different types */
69 typedef enum {
70     gsUNDEFINED = 0,
71     gsGRAY,
72     gsRGB,
73     gsCMYK,
74     gsNCHANNEL,
75     gsCIEXYZ,
76     gsCIELAB,
77     gsNAMED
78 } gsicc_colorbuffer_t;
79 
80 typedef struct gsicc_bufferdesc_s {
81     unsigned char num_chan;
82     unsigned char bytes_per_chan;
83     bool has_alpha;
84     bool alpha_first;
85     bool little_endian;
86     bool is_planar;
87     int plane_stride;
88     int row_stride;
89     int num_rows;
90     int pixels_per_row;
91 } gsicc_bufferdesc_t;
92 
93 /* Mapping procedures to allow easy vectoring depending upon if we are using
94    the CMM or doing "dumb" color transforms */
95 typedef int (*gscms_trans_color_proc_t) (gx_device * dev, gsicc_link_t *icclink,
96                                          void *inputcolor, void *outputcolor,
97                                          int num_bytes);
98 
99 typedef int (*gscms_trans_buffer_proc_t) (gx_device * dev, gsicc_link_t *icclink,
100                                           gsicc_bufferdesc_t *input_buff_desc,
101                                           gsicc_bufferdesc_t *output_buff_desc,
102                                           void *inputbuffer, void *outputbuffer);
103 
104 typedef void (*gscms_link_free_proc_t) (gsicc_link_t *icclink);
105 
106 typedef bool (*gscms_monitor_proc_t) (void *inputcolor, int num_bytes);
107 
108 typedef struct gscms_procs_s {
109     gscms_trans_buffer_proc_t map_buffer;
110     gscms_trans_color_proc_t  map_color;
111     gscms_link_free_proc_t free_link;
112     gscms_monitor_proc_t is_color;
113 } gscms_procs_t;
114 
115 /* Allow different methods for releasing the opaque profile contents */
116 typedef void(*gscms_free_profile_proc_t) (void *profile_handle, gs_memory_t *memory);
117 
118 /* Enumerate the ICC rendering intents and other parameters.  A note on
119    these.  0-3 are for different values.   4-7 are for Override cases
120    where we are trying to override some value specified in the document.
121    8 is reserved for not specified.  This is used in the case were we
122    can specify multiple rendering values for the sources and wish to just
123    use default or document values for a particular value.  For example,
124    we may want for RGB Graphics to specify a Rendering Intent but not
125    a black point compensation. */
126 typedef enum {
127     gsPERCEPTUAL = 0,
128     gsRELATIVECOLORIMETRIC,
129     gsSATURATION,
130     gsABSOLUTECOLORIMETRIC,
131     gsPERCEPTUAL_OR,            /* These are needed for keeping track  */
132     gsRELATIVECOLORIMETRIC_OR,  /* of when the source ri is going to */
133     gsSATURATION_OR,            /* override the destination profile intent */
134     gsABSOLUTECOLORIMETRIC_OR,  /* in particular through the clist */
135     gsRINOTSPECIFIED = 8,       /* Used to ignore value when source based setting */
136 
137     /* Stop modern C shrinking this enum to a byte */
138     gsicc_rendering_intent__FORCE_SIZE= 0x10000
139 } gsicc_rendering_intents_t;
140 
141 /* We make an enumerated type in case someone wants to add different types
142    of black point compensation.  Like lcms provides the option for. If
143    any are added, be sure to add in the regular and the source overide
144    option. Also not that we have at most 4 options due to gsBP_OVERRIDE  */
145 typedef enum {
146     gsBLACKPTCOMP_OFF = 0,
147     gsBLACKPTCOMP_ON,
148     gsBLACKPTCOMP_OFF_OR = 4, /* These are needed for keeping track of the  */
149     gsBLACKPTCOMP_ON_OR,      /* source blackpt is to overide dest. setting */
150     gsBPNOTSPECIFIED = 8,    /* Used to ignore value when source based setting */
151 
152     /* Stop modern C shrinking this enum to a byte */
153     gsicc_blackptcomp__FORCE_SIZE= 0x10000
154 } gsicc_blackptcomp_t;
155 
156 /* This is used mainly for when the sourcegtag option specifies us to use no
157    color management or a replacement color management CMM */
158 typedef enum {
159     gsCMM_DEFAULT = 0,
160     gsCMM_NONE,
161     gsCMM_REPLACE
162 } gsicc_cmm_t;
163 
164 /* Since this is not specified by the source document we don't need to worry
165    about override values */
166 typedef enum {
167     gsBLACKPRESERVE_OFF = 0,
168     gsBLACKPRESERVE_KONLY,
169     gsBLACKPRESERVE_KPLANE,
170     gsBKPRESNOTSPECIFIED = 8,   /* Used to ignore value when source based setting */
171 
172     /* Stop modern C shrinking this enum to a byte */
173     gsicc_blackpreserve__FORCE_SIZE= 0x10000
174 } gsicc_blackpreserve_t;
175 
176 #define gsRI_OVERRIDE 0x4
177 #define gsBP_OVERRIDE 0x4
178 #define gsKP_OVERRIDE 0x4
179 #define gsRI_MASK 0x3;
180 #define gsBP_MASK 0x3;
181 #define gsKP_MASK 0x3;
182 
183 /* Enumerate the types of profiles */
184 typedef enum {
185     gsDEFAULTPROFILE = 0,
186     gsGRAPHICPROFILE,
187     gsIMAGEPROFILE,
188     gsTEXTPROFILE,
189     gsPROOFPROFILE,
190     gsLINKPROFILE,
191     gsOIPROFILE,
192     gsPRPROFILE,
193     gsBLENDPROFILE
194 } gsicc_profile_types_t;
195 
196 typedef enum {
197     gsSRC_GRAPPRO = 0,
198     gsSRC_IMAGPRO,
199     gsSRC_TEXTPRO,
200 } gsicc_profile_srctypes_t;
201 
202 /* --------------- graphical object tags ------------ */
203 
204 /* The default is "unknown" which has value 0 and by default devices don't encode tags */
205 typedef enum {
206     GS_UNTOUCHED_TAG = 0x0,	/* UNTOUCHED *must* be 0 -- transparency code relies on this */
207     GS_TEXT_TAG = 0x1,
208     GS_IMAGE_TAG = 0x2,
209     GS_PATH_TAG = 0x4,
210     GS_UNKNOWN_TAG = 0x40,
211     GS_DEVICE_ENCODES_TAGS = 0x80
212 } gs_graphics_type_tag_t;
213 
214 /* Source profile graphic tag rendering conditions */
215 typedef struct gsicc_rendering_param_s {
216     gsicc_rendering_intents_t rendering_intent;   /* Standard rendering intent */
217     gsicc_blackptcomp_t black_point_comp;         /* Black point compensation */
218     gsicc_blackpreserve_t preserve_black;         /* preserve K plane in CMYK2CMYK */
219     gs_graphics_type_tag_t graphics_type_tag;     /* Some CMM may want this */
220     gsicc_cmm_t cmm;                              /* which cmm? (used only with sourcetag) */
221     bool override_icc;                            /* Override source ICC (used only with sourcetag) */
222 } gsicc_rendering_param_t;
223 
224 /* Source profiles for different objects.  only CMYK and RGB */
225 typedef struct cmm_srcgtag_profile_s {
226     cmm_profile_t  *rgb_profiles[NUM_SOURCE_PROFILES];
227     gsicc_rendering_param_t rgb_rend_cond[NUM_SOURCE_PROFILES];
228     cmm_profile_t  *cmyk_profiles[NUM_SOURCE_PROFILES];
229     gsicc_rendering_param_t cmyk_rend_cond[NUM_SOURCE_PROFILES];
230     cmm_profile_t  *gray_profiles[NUM_SOURCE_PROFILES];
231     gsicc_rendering_param_t gray_rend_cond[NUM_SOURCE_PROFILES];
232     cmm_profile_t  *color_warp_profile;
233     gs_memory_t *memory;
234     int name_length;            /* Length of file name */
235     char *name;                 /* Name of file name where this is found */
236     rc_header rc;
237 } cmm_srcgtag_profile_t;
238 
239 typedef struct gsicc_colorname_s gsicc_colorname_t;
240 
241 struct gsicc_colorname_s {
242     char *name;
243     int length;
244     gsicc_colorname_t *next;
245 };
246 
247 typedef struct gsicc_namelist_s gsicc_namelist_t;
248 
249 typedef struct gs_devicen_color_map_s gs_devicen_color_map;
250 
251 struct gsicc_namelist_s {
252     int count;
253     gsicc_colorname_t *head;
254     char *name_str;
255     gs_devicen_color_map *color_map;
256     bool equiv_cmyk_set;   /* So that we make sure the equiv cmyk values are set */
257                            /* This can't be done at the time this structure
258                               is set up since we need the device and the graphic
259                               state for this, but instead is done when we
260                               do our first mapping */
261 };
262 
263 /* Destination profiles for different objects */
264 struct cmm_dev_profile_s {
265         cmm_profile_t  *device_profile[NUM_DEVICE_PROFILES];
266         cmm_profile_t  *proof_profile;
267         cmm_profile_t  *link_profile;
268         cmm_profile_t  *oi_profile;  /* output intent profile */
269         cmm_profile_t  *blend_profile; /* blending color space */
270         cmm_profile_t  *postren_profile;  /* Profile for use by devices post render */
271         gsicc_rendering_param_t rendercond[NUM_DEVICE_PROFILES];
272         bool devicegraytok;        /* Used for forcing gray to pure black */
273         bool graydetection;        /* Device param for monitoring for gray only page */
274         bool pageneutralcolor;      /* Only valid if graydetection true */
275         bool usefastcolor;         /* Used when we want to use no cm */
276         bool supports_devn;        /* If the target handles devn colors */
277         bool sim_overprint;     /* Indicates we want to do overprint blending */
278         gsicc_namelist_t *spotnames;  /* If our device profiles are devn */
279         bool prebandthreshold;     /* Used to indicate use of HT pre-clist */
280         gs_memory_t *memory;
281         rc_header rc;
282 };
283 
284 /*  Used so that we can specify if we want to link with Device input color spaces
285     during the link creation process. For the DeviceN case, the DeviceN profile
286     must match the DeviceN profile in colorant order and number of colorants.
287     Also, used to indicate if the profile matches one of the default profiles in
288     the icc manager.  This is useful for reducing clist size since we will encode
289     this value instead of the ICC profile.
290 */
291 typedef enum {
292     DEFAULT_NONE,   /* A profile that was actually embedded in a doc */
293     DEFAULT_GRAY,   /* The default DeviceGray profile */
294     DEFAULT_RGB,    /* The default DeviceRGB profile */
295     DEFAULT_CMYK,   /* The default DeviceCMYK profile */
296     NAMED_TYPE,     /* The named color profile */
297     LAB_TYPE,       /* The CIELAB profile */
298     DEVICEN_TYPE,   /* A special device N profile */
299     DEFAULT_GRAY_s, /* Same as default but a source profile from document */
300     DEFAULT_RGB_s,  /* Same as default but a source profile from document */
301     DEFAULT_CMYK_s, /* Same as default but a source profile from document */
302     LAB_TYPE_s,     /* Same as our default CIELAB but a source profile from doc */
303     CAL_GRAY,       /* Generated from PDF cal gray object */
304     CAL_RGB,        /* Generated from PDF cal rgb object */
305     CIE_A,          /* Generated from PS CIEA definition */
306     CIE_ABC,        /* Generated from PS CIEABC definition */
307     CIE_DEF,        /* Generated from PS CIEDEF definition */
308     CIE_DEFG,       /* Generated from PS CIEDEFG definition */
309     CIE_CRD        /* Generated from PS CRD definition */
310 } gsicc_profile_t;
311 
312 typedef enum {
313     ICCVERS_UNKNOWN,
314     ICCVERS_2,
315     ICCVERS_NOT2
316 } gsicc_version_t;
317 
318 #define gsicc_serial_data\
319     unsigned char num_comps;		/* number of device dependent values */\
320     unsigned char num_comps_out;	/* usually 3 but could be more if device link type */\
321     bool islab;				/* Needed since we want to detect this to avoid */\
322                                         /*  expensive decode on LAB images.  Is true */\
323                                         /* if PDF color space is \Lab */\
324     bool isdevlink;                  /* is this a device link profile */\
325     gsicc_profile_t default_match;	/* Used for detecting a match to a default space */\
326     gsicc_colorbuffer_t data_cs;	/* The data color space of the profile (not the PCS) */\
327     gs_range_icc_t Range;\
328     int64_t hashcode;			/* A hash code for the icc profile */\
329     bool hash_is_valid;			/* Is the code valid? */\
330     int devicen_permute[ICC_MAX_CHANNELS];	/* Permutation vector for deviceN laydown order */\
331     bool devicen_permute_needed;		/* Check if we need to permute the DeviceN values */\
332     int buffer_size;		/* size of ICC profile buffer */\
333     bool rend_is_valid;                 /* Needed for cond/profile coupling during */\
334     gsicc_rendering_param_t rend_cond   /* clist playback when rendering images */
335 
336 /* A subset of the profile information which is used when writing and reading
337  * out to the c-list
338  */
339 typedef struct gsicc_serialized_profile_s {
340     gsicc_serial_data;
341 } gsicc_serialized_profile_t;
342 
343 /* A structure for holding profile information.  A member variable
344  * of the ghostscript color structure.   The item is reference counted.
345  */
346 struct cmm_profile_s {
347     gsicc_serial_data;
348     byte *buffer;                       /* A buffer with ICC profile content */
349     gx_device *dev;                     /* A pointer to the clist device in which the ICC data may be contained */
350     gsicc_namelist_t *spotnames;        /* Used for profiles that have non-standard colorants */
351     void *profile_handle;               /* The profile handle */
352     rc_header rc;                       /* Reference count.  So we know when to free */
353     int name_length;                    /* Length of file name */
354     char *name;                         /* Name of file name (if there is one) where profile is found.
355                                          * If it was embedded in the stream, there will not be a file
356                                          * name.  This is primarily here for the system profiles, and
357                                          * so that we avoid resetting them everytime the user params
358                                          * are reloaded. */
359     gsicc_version_t vers;               /* Is this profile V2 */
360     byte *v2_data;                      /* V2 data that is equivalent to this profile. Used for PDF-A1 support */
361     int v2_size;                        /* Number of bytes in v2_data */
362     gs_memory_t *memory;                /* In case we have some in non-gc and some in gc memory */
363     gx_monitor_t *lock;                 /* handle for the monitor */
364     gscms_free_profile_proc_t release;  /* Release the profile handle at CMM */
365 };
366 
367 /* The above definition is plagued with an offset issue.  Probably should
368    do away with gsicc_serialized_profile_t type */
369 #ifndef offsetof
370 #define offsetof(st, member) \
371    ((char *)&(((st *)(NULL))->member) - (char *)(NULL))
372 #endif
373 #define GSICC_SERIALIZED_SIZE offsetof(cmm_profile_t, buffer)
374 
375 /* A linked list structure for storing profiles in a table in which we
376    can store and refer to from the clist and also when creating icc profiles
377    from ps object.  Right now it is not clear to me if we really need a
378    cache in the traditional sense or a list since I believe the number of entries will
379    in general be very small (i.e. there will not be at MOST more than 2 to 3 internal
380    ICC profiles in a file).  The default GRAY, RGB, and CMYK profiles are not
381    stored here but are maintained in the ICC manager.  This is for profiles
382    that are in the content and for profiles we generate from PS and PDF CIE (NonICC)
383    color spaces.
384  */
385 typedef struct gsicc_profile_entry_s gsicc_profile_entry_t;
386 
387 struct gsicc_profile_entry_s {
388     gs_color_space *color_space;     /* The color space with the profile */
389     gsicc_profile_entry_t *next;     /* next CS */
390     uint64_t key;                    /* Key based off dictionary location */
391 };
392 
393 /* ProfileList. The size of the list is limited by max_memory_size.
394    Profiles are added if there is sufficient memory. */
395 typedef struct gsicc_profile_cache_s {
396     gsicc_profile_entry_t *head;
397     int num_entries;
398     rc_header rc;
399     gs_memory_t *memory;
400 } gsicc_profile_cache_t;
401 
402 /*  These are the types that we can potentially have linked together by the CMS.
403  *  If the CMS does not have understanding of PS color space types, then we
404  *  will need to convert them to an ICC type. */
405 typedef enum {
406     DEVICETYPE,
407     ICCTYPE,
408     CRDTYPE,
409     CIEATYPE,
410     CIEABCTYPE,
411     CIEDEFTYPE,
412     CIEDEFGTYPE
413 } gs_colortype_t;
414 
415 /* The link object. */
416 
417 typedef struct gsicc_hashlink_s {
418     int64_t link_hashcode;
419     int64_t src_hash;
420     int64_t des_hash;
421     int64_t rend_hash;
422 } gsicc_hashlink_t;
423 
424 struct gsicc_link_s {
425     void *link_handle;		/* the CMS decides what this is */
426     gs_memory_t *memory;
427     gscms_procs_t procs;
428     gsicc_hashlink_t hashcode;
429     struct gsicc_link_cache_s *icc_link_cache;
430     int ref_count;
431     gsicc_link_t *next;
432     gx_monitor_t *lock;		/* lock used while changing contents */
433     bool includes_softproof;
434     bool includes_devlink;
435     bool is_identity;  /* Used for noting that this is an identity profile */
436     bool valid;		/* true once link is completely built and usable */
437     bool is_monitored;
438     gscms_procs_t orig_procs;  /* procs to use after monitoring */
439     gsicc_colorbuffer_t data_cs; /* needed for begin_monitor after end_monitor */
440     int num_input;  /* Need so we can monitor properly */
441     int num_output; /* Need so we can monitor properly */
442 };
443 
444 /* ICC Cache. The size of the cache is limited by max_memory_size.
445  * Links are added if there is sufficient memory and if the number
446  * of links does not exceed a (soft) limit.
447  */
448 
449 typedef struct gsicc_link_cache_s {
450     gsicc_link_t *head;
451     int num_links;
452     rc_header rc;
453     gs_memory_t *memory;
454     gx_monitor_t *lock;		/* handle for the monitor */
455     bool cache_full;		/* flag that some thread needs a cache slot */
456     gx_semaphore_t *full_wait;	/* semaphore for waiting when the cache is full */
457 } gsicc_link_cache_t;
458 
459 /* A linked list structure to keep DeviceN ICC profiles
460  * that the user wishes to use to achieve accurate rendering
461  * with DeviceN (typically non CMYK or CMYK + spot) colors.
462  * The ICC profiles used for this will require a special
463  * private tag in the ICC profile that defines the colorant
464  * names and they must match those in the DeviceN color
465  * space.  Note this is not to say that DeviceN color
466  * management can only be achieved with ICC profiles.  If
467  * a customer has a proprietary mixing model for inks, they
468  * will be able to hook in their method in the location
469  * in the code where the DeviceN colors are processed.  If
470  * there is no ICC color management of the DeviceN colors
471  * and the DeviceN colors are NOT the native colors
472  * for the device, then the colors will be transformed to
473  * the alternate CS using the alternate tint transform
474  */
475 
476 typedef struct gsicc_devicen_entry_s gsicc_devicen_entry_t;
477 
478 struct gsicc_devicen_entry_s {
479     cmm_profile_t *iccprofile;
480     gsicc_devicen_entry_t *next;
481 };
482 
483 typedef struct gsicc_devicen_s gsicc_devicen_t;
484 
485 struct gsicc_devicen_s {
486     gsicc_devicen_entry_t *head;
487     gsicc_devicen_entry_t *final;
488     int count;
489 };
490 
491 /* Had to add bool so that we know if things were swapped.
492    The reason is that if we are in a swapped state and
493    there is a vmreclaim we then end up sending the user
494    params again and we will find that there is a mismatch */
495 typedef struct gsicc_smask_s {
496     cmm_profile_t *smask_gray;
497     cmm_profile_t *smask_rgb;
498     cmm_profile_t *smask_cmyk;
499     gs_memory_t *memory;
500     bool swapped;
501 } gsicc_smask_t;
502 
503 /* The manager object */
504 
505 typedef struct gsicc_manager_s {
506     cmm_profile_t *device_named;    /* The named color profile for the device */
507     cmm_profile_t *default_gray;    /* Default gray profile for device gray */
508     cmm_profile_t *default_rgb;     /* Default RGB profile for device RGB */
509     cmm_profile_t *default_cmyk;    /* Default CMYK profile for device CMKY */
510     cmm_profile_t *lab_profile;     /* Colorspace type ICC profile from LAB to LAB */
511     cmm_profile_t *xyz_profile;     /* RGB based proflie that hands back CIEXYZ values */
512     cmm_profile_t *graytok_profile; /* A specialized profile for mapping gray to K */
513     gsicc_devicen_t *device_n;      /* A linked list of profiles used for DeviceN support */
514     gsicc_smask_t *smask_profiles;  /* Profiles used when we are in a softmask group */
515     bool override_internal;         /* Set via the user params */
516     cmm_srcgtag_profile_t *srcgtag_profile;
517     gs_memory_t *memory;
518     rc_header rc;
519 } gsicc_manager_t;
520 
521 #endif /* ifndef gscms_INCLUDED */
522