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