1 /* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /*  Data type definitions when using the gscms  */
18 
19 #ifndef gscms_INCLUDED
20 #  define gscms_INCLUDED
21 
22 #include "std.h"
23 #include "stdpre.h"
24 #include "gstypes.h"
25 #include "gscspace.h"      /* for gs_color_space */
26 #include "gsdevice.h"     /* Need to carry pointer to clist reader */
27 #include "gxsync.h"       /* for semaphore and monitors */
28 #include "stdint_.h"
29 
30 #define ICC_MAX_CHANNELS 15
31 #define NUM_DEVICE_PROFILES 4
32 #define NUM_SOURCE_PROFILES 3
33 
34 /* Define the preferred size of the output by the CMS */
35 /* This can be different than the size of gx_color_value
36    which can range between 8 and 16.  Here we can only
37    have 8 or 16 bits */
38 
39 typedef unsigned short icc_output_type;
40 
41 #define icc_byte_count sizeof(icc_output_type)
42 #define icc_bits_count (icc_byte_count * 8)
43 #define icc_max_color_value ((gx_color_value)((1L << icc_bits_count) - 1))
44 #define icc_value_to_byte(cv)\
45   ((cv) >> (icc_bits_count - 8))
46 #define icc_value_from_byte(cb)\
47   (((cb) << (icc_bits_count - 8)) + ((cb) >> (16 - icc_bits_count)))
48 
49 typedef struct gs_range_icc_s {
50     gs_range_t ranges[ICC_MAX_CHANNELS];
51 } gs_range_icc_t;  /* ICC profile input could be up to 15 bands */
52 
53 /* This object is used only for device post processing CM.  It and its objects
54    must be allocated in non-gc memory. */
55 
56 #ifndef cmm_profile_DEFINED
57 typedef struct cmm_profile_s cmm_profile_t;
58 #define cmm_profile_DEFINED
59 #endif
60 
61 typedef struct gsicc_device_cm_s {
62     cmm_profile_t *gray_profile;
63     cmm_profile_t *rgb_profile;
64     cmm_profile_t *cmyk_profile;
65     cmm_profile_t *device_link_profile;
66     gs_memory_t *memory;
67 } gsicc_device_cm_t;
68 
69 /*  The buffer description.  We handle a variety of different types */
70 typedef enum {
71     gsUNDEFINED = 0,
72     gsGRAY,
73     gsRGB,
74     gsCMYK,
75     gsNCHANNEL,
76     gsCIEXYZ,
77     gsCIELAB,
78     gsNAMED
79 } gsicc_colorbuffer_t;
80 
81 typedef struct gsicc_bufferdesc_s {
82     unsigned char num_chan;
83     unsigned char bytes_per_chan;
84     bool has_alpha;
85     bool alpha_first;
86     bool little_endian;
87     bool is_planar;
88     int plane_stride;
89     int row_stride;
90     int num_rows;
91     int pixels_per_row;
92 } gsicc_bufferdesc_t;
93 
94 /* Mapping procedures to allow easy vectoring depending upon if we are using
95    the CMM or doing "dumb" color transforms */
96 typedef void (*gscms_trans_color_proc_t) (gx_device * dev, gsicc_link_t *icclink,
97                                           void *inputcolor, void *outputcolor,
98                                           int num_bytes);
99 
100 typedef void (*gscms_trans_buffer_proc_t) (gx_device * dev, gsicc_link_t *icclink,
101                                            gsicc_bufferdesc_t *input_buff_desc,
102                                            gsicc_bufferdesc_t *output_buff_desc,
103                                            void *inputbuffer, void *outputbuffer);
104 
105 typedef void (*gscms_link_free_proc_t) (gsicc_link_t *icclink);
106 
107 typedef struct gscms_procs_s {
108     gscms_trans_buffer_proc_t map_buffer;
109     gscms_trans_color_proc_t  map_color;
110     gscms_link_free_proc_t free_link;
111 } gscms_procs_t;
112 
113 /* Enumerate the ICC rendering intents */
114 typedef enum {
115     gsPERCEPTUAL = 0,
116     gsRELATIVECOLORIMETRIC,
117     gsSATURATION,
118     gsABSOLUTECOLORIMETRIC,
119     gsPERCEPTUAL_OR,            /* These are needed for keeping track  */
120     gsRELATIVECOLORIMETRIC_OR,  /* of when the source ri is going to */
121     gsSATURATION_OR,            /* override the destination profile intent */
122     gsABSOLUTECOLORIMETRIC_OR   /* in particular through the clist */
123 } gsicc_rendering_intents_t;
124 
125 #define gsRI_OVERRIDE 0x4
126 #define gsRI_MASK 0x3;
127 
128 /* Enumerate the types of profiles */
129 typedef enum {
130     gsDEFAULTPROFILE = 0,
131     gsGRAPHICPROFILE,
132     gsIMAGEPROFILE,
133     gsTEXTPROFILE,
134     gsPROOFPROFILE,
135     gsLINKPROFILE,
136     gsOIPROFILE
137 } gsicc_profile_types_t;
138 
139 typedef enum {
140     gsSRC_GRAPPRO = 0,
141     gsSRC_IMAGPRO,
142     gsSRC_TEXTPRO,
143 } gsicc_profile_srctypes_t;
144 
145 /* Source profiles for different objects.  only CMYK and RGB */
146 typedef struct cmm_srcgtag_profile_s {
147         cmm_profile_t  *rgb_profiles[NUM_SOURCE_PROFILES];
148         gsicc_rendering_intents_t rgb_intent[NUM_SOURCE_PROFILES];
149         cmm_profile_t  *cmyk_profiles[NUM_SOURCE_PROFILES];
150         gsicc_rendering_intents_t cmyk_intent[NUM_SOURCE_PROFILES];
151         cmm_profile_t  *color_warp_profile;
152         gs_memory_t *memory;
153         int name_length;            /* Length of file name */
154         char *name;                 /* Name of file name where this is found */
155         rc_header rc;
156 } cmm_srcgtag_profile_t;
157 
158 /* Destination profiles for different objects */
159 typedef struct cmm_dev_profile_s {
160         cmm_profile_t  *device_profile[NUM_DEVICE_PROFILES];
161         cmm_profile_t  *proof_profile;
162         cmm_profile_t  *link_profile;
163         cmm_profile_t  *oi_profile;  /* output intent profile */
164         gsicc_rendering_intents_t intent[NUM_DEVICE_PROFILES];
165         bool devicegraytok;        /* Used for forcing gray to pure black */
166         bool usefastcolor;         /* Used when we want to use no cm */
167         bool supports_devn;        /* If the target handles devn colors */
168         gs_memory_t *memory;
169         rc_header rc;
170 } cmm_dev_profile_t;
171 
172 /*  Doing this an an enum type for now.  There is alot going on with respect
173  *  to this and V2 versus V4 profiles
174  */
175 
176 typedef enum {
177     BP_ON = 0,
178     BP_OFF,
179 } gsicc_black_point_comp_t;
180 
181 /*  Used so that we can specify if we want to link with Device input color spaces
182     during the link creation process. For the DeviceN case, the DeviceN profile
183     must match the DeviceN profile in colorant order and number of colorants.
184     Also, used to indicate if the profile matches one of the default profiles in
185     the icc manager.  This is useful for reducing clist size since we will encode
186     this value instead of the ICC profile.
187 */
188 
189 typedef enum {
190     DEFAULT_NONE,   /* A profile that was actually embedded in a doc */
191     DEFAULT_GRAY,   /* The default DeviceGray profile */
192     DEFAULT_RGB,    /* The default DeviceRGB profile */
193     DEFAULT_CMYK,   /* The default DeviceCMYK profile */
194     NAMED_TYPE,     /* The named color profile */
195     LAB_TYPE,       /* The CIELAB profile */
196     DEVICEN_TYPE,   /* A special device N profile */
197     DEFAULT_GRAY_s, /* Same as default but a source profile from document */
198     DEFAULT_RGB_s,  /* Same as default but a source profile from document */
199     DEFAULT_CMYK_s, /* Same as default but a source profile from document */
200     LAB_TYPE_s,     /* Same as our default CIELAB but a source profile from doc */
201     CAL_GRAY,       /* Generated from PDF cal gray object */
202     CAL_RGB,        /* Generated from PDF cal rgb object */
203     CIE_A,          /* Generated from PS CIEA definition */
204     CIE_ABC,        /* Generated from PS CIEABC definition */
205     CIE_DEF,        /* Generated from PS CIEDEF definition */
206     CIE_DEFG,       /* Generated from PS CIEDEFG definition */
207     CIE_CRD        /* Generated from PS CRD definition */
208 } gsicc_profile_t;
209 
210 #define gsicc_serial_data\
211     unsigned char num_comps;		/* number of device dependent values */\
212     unsigned char num_comps_out;	/* usually 3 but could be more if device link type */\
213     bool islab;				/* Needed since we want to detect this to avoid */\
214                                         /*  expensive decode on LAB images.  Is true */\
215                                         /* if PDF color space is \Lab */\
216     gsicc_profile_t default_match;	/* Used for detecting a match to a default space */\
217     gsicc_colorbuffer_t data_cs;	/* The data color space of the profile (not the PCS) */\
218     gs_range_icc_t Range;\
219     int64_t hashcode;			/* A hash code for the icc profile */\
220     bool hash_is_valid;			/* Is the code valid? */\
221     int devicen_permute[ICC_MAX_CHANNELS];	/* Permutation vector for deviceN laydown order */\
222     bool devicen_permute_needed;		/* Check if we need to permute the DeviceN values */\
223     int buffer_size			/* size of ICC profile buffer */
224 
225 /* A subset of the profile information which is used when writing and reading
226  * out to the c-list
227  */
228 typedef struct gsicc_serialized_profile_s {
229     gsicc_serial_data;
230 } gsicc_serialized_profile_t;
231 
232 typedef struct gsicc_colorname_s gsicc_colorname_t;
233 
234 struct gsicc_colorname_s {
235     char *name;
236     int length;
237     gsicc_colorname_t *next;
238 };
239 
240 typedef struct gsicc_namelist_s gsicc_namelist_t;
241 
242 struct gsicc_namelist_s {
243     int count;
244     gsicc_colorname_t *head;
245 };
246 
247 /* A structure for holding profile information.  A member variable
248  * of the ghostscript color structure.   The item is reference counted.
249  */
250 struct cmm_profile_s {
251     gsicc_serial_data;
252     byte *buffer;               /* A buffer with ICC profile content */
253     gx_device *dev;             /* A pointer to the clist device in which the ICC data may be contained */
254     gsicc_namelist_t *spotnames;  /* Only used with NCLR ICC input profiles with named color tag */
255     void *profile_handle;       /* The profile handle */
256     rc_header rc;               /* Reference count.  So we know when to free */
257     int name_length;            /* Length of file name */
258     char *name;                 /* Name of file name (if there is one) where profile is found.
259                                  * If it was embedded in the stream, there will not be a file
260                                  * name.  This is primarily here for the system profiles, and
261                                  * so that we avoid resetting them everytime the user params
262                                  * are reloaded. */
263     gs_memory_t *memory;        /* In case we have some in non-gc and some in gc memory */
264     gx_monitor_t *lock;		/* handle for the monitor */
265 };
266 
267 #ifndef cmm_profile_DEFINED
268 typedef struct cmm_profile_s cmm_profile_t;
269 #define cmm_profile_DEFINED
270 #endif
271 
272 /* A linked list structure for storing profiles in a table in which we
273    can store and refer to from the clist and also when creating icc profiles
274    from ps object.  Right now it is not clear to me if we really need a
275    cache in the traditional sense or a list since I believe the number of entries will
276    in general be very small (i.e. there will not be at MOST more than 2 to 3 internal
277    ICC profiles in a file).  The default GRAY, RGB, and CMYK profiles are not
278    stored here but are maintained in the ICC manager.  This is for profiles
279    that are in the content and for profiles we generate from PS and PDF CIE (NonICC)
280    color spaces.
281  */
282 typedef struct gsicc_profile_entry_s gsicc_profile_entry_t;
283 
284 struct gsicc_profile_entry_s {
285     gs_color_space *color_space;     /* The color space with the profile */
286     gsicc_profile_entry_t *next;    /* next CS */
287     int64_t key;                    /* Key based off dictionary location */
288 };
289 
290 /* ProfileList. The size of the list is limited by max_memory_size.
291    Profiles are added if there is sufficient memory. */
292 typedef struct gsicc_profile_cache_s {
293     gsicc_profile_entry_t *head;
294     int num_entries;
295     rc_header rc;
296     gs_memory_t *memory;
297 } gsicc_profile_cache_t;
298 
299 /*  These are the types that we can potentially have linked together by the CMS.
300  *  If the CMS does not have understanding of PS color space types, then we
301  *  will need to convert them to an ICC type. */
302 typedef enum {
303     DEVICETYPE,
304     ICCTYPE,
305     CRDTYPE,
306     CIEATYPE,
307     CIEABCTYPE,
308     CIEDEFTYPE,
309     CIEDEFGTYPE
310 } gs_colortype_t;
311 
312 /* The link object. */
313 
314 #ifndef gsicc_link_DEFINED
315 typedef struct gsicc_link_s gsicc_link_t;
316 #  define gsicc_link_DEFINED
317 #endif
318 
319 typedef struct gsicc_hashlink_s {
320     int64_t link_hashcode;
321     int64_t src_hash;
322     int64_t des_hash;
323     int64_t rend_hash;
324 } gsicc_hashlink_t;
325 
326 struct gsicc_link_s {
327     void *link_handle;
328     void *contextptr;
329     gscms_procs_t procs;
330     gsicc_hashlink_t hashcode;
331     struct gsicc_link_cache_s *icc_link_cache;
332     int ref_count;
333     gsicc_link_t *next;
334     gx_semaphore_t *wait;		/* semaphore used by waiting threads */
335     int num_waiting;
336     bool includes_softproof;
337     bool includes_devlink;
338     bool is_identity;  /* Used for noting that this is an identity profile */
339     bool valid;		/* true once link is completely built and usable */
340 };
341 
342 /* ICC Cache. The size of the cache is limited by max_memory_size.
343  * Links are added if there is sufficient memory and if the number
344  * of links does not exceed a (soft) limit.
345  */
346 
347 typedef struct gsicc_link_cache_s {
348     gsicc_link_t *head;
349     int num_links;
350     rc_header rc;
351     gs_memory_t *memory;
352     gx_monitor_t *lock;		/* handle for the monitor */
353     gx_semaphore_t *wait;	/* somebody needs a link cache slot */
354     int num_waiting;		/* number of threads waiting */
355 } gsicc_link_cache_t;
356 
357 /* A linked list structure to keep DeviceN ICC profiles
358  * that the user wishes to use to achieve accurate rendering
359  * with DeviceN (typically non CMYK or CMYK + spot) colors.
360  * The ICC profiles used for this will require a special
361  * private tag in the ICC profile that defines the colorant
362  * names and they must match those in the DeviceN color
363  * space.  Note this is not to say that DeviceN color
364  * management can only be achieved with ICC profiles.  If
365  * a customer has a proprietary mixing model for inks, they
366  * will be able to hook in their method in the location
367  * in the code where the DeviceN colors are processed.  If
368  * there is no ICC color management of the DeviceN colors
369  * and the DeviceN colors are NOT the native colors
370  * for the device, then the colors will be transformed to
371  * the alternate CS using the alternate tint transform
372  */
373 
374 typedef struct gsicc_devicen_entry_s gsicc_devicen_entry_t;
375 
376 struct gsicc_devicen_entry_s {
377     cmm_profile_t *iccprofile;
378     gsicc_devicen_entry_t *next;
379 };
380 
381 typedef struct gsicc_devicen_s gsicc_devicen_t;
382 
383 struct gsicc_devicen_s {
384     gsicc_devicen_entry_t *head;
385     gsicc_devicen_entry_t *final;
386     int count;
387 };
388 
389 /* Had to add bool so that we know if things were swapped.
390    The reason is that if we are in a swapped state and
391    there is a vmreclaim we then end up sending the user
392    params again and we will find that there is a mismatch */
393 typedef struct gsicc_smask_s {
394     cmm_profile_t *smask_gray;
395     cmm_profile_t *smask_rgb;
396     cmm_profile_t *smask_cmyk;
397     gs_memory_t *memory;
398     bool swapped;
399 } gsicc_smask_t;
400 
401 /* The manager object */
402 
403 typedef struct gsicc_manager_s {
404     cmm_profile_t *device_named;    /* The named color profile for the device */
405     cmm_profile_t *default_gray;    /* Default gray profile for device gray */
406     cmm_profile_t *default_rgb;     /* Default RGB profile for device RGB */
407     cmm_profile_t *default_cmyk;    /* Default CMYK profile for device CMKY */
408     cmm_profile_t *lab_profile;     /* Colorspace type ICC profile from LAB to LAB */
409     cmm_profile_t *graytok_profile; /* A specialized profile for mapping gray to K */
410     gsicc_devicen_t *device_n;      /* A linked list of profiles used for DeviceN support */
411     gsicc_smask_t *smask_profiles;  /* Profiles used when we are in a softmask group */
412     bool override_internal;         /* Set via the user params */
413     bool override_ri;               /* Override rend intent. Set via the user params */
414     cmm_srcgtag_profile_t *srcgtag_profile;
415     gs_memory_t *memory;
416     rc_header rc;
417 } gsicc_manager_t;
418 
419 /* --------------- graphical object tags ------------ */
420 
421 /* The default is "unknown" which has value 0 and by default devices don't encode tags */
422 typedef enum {
423     GS_UNKNOWN_TAG = 0x0,
424     GS_TEXT_TAG = 0x1,
425     GS_IMAGE_TAG = 0x2,
426     GS_PATH_TAG = 0x4,
427     GS_UNTOUCHED_TAG = 0x8,
428     GS_DEVICE_ENCODES_TAGS = 0x80
429 } gs_graphics_type_tag_t;
430 
431 typedef struct gsicc_rendering_param_s {
432     gsicc_rendering_intents_t rendering_intent;
433     gs_graphics_type_tag_t    graphics_type_tag;
434     gsicc_black_point_comp_t  black_point_comp;
435 } gsicc_rendering_param_t;
436 
437 #endif /* ifndef gscms_INCLUDED */
438