1 #ifndef XICC_H 2 #define XICC_H 3 /* 4 * International Color Consortium color transform expanded support 5 * 6 * Author: Graeme W. Gill 7 * Date: 28/6/00 8 * Version: 1.00 9 * 10 * Copyright 2000, 2011 Graeme W. Gill 11 * All rights reserved. 12 * This material is licenced under the GNU AFFERO GENERAL PUB LICENSE Version 3 :- 13 * see the License.txt file for licencing details. 14 * 15 * Based on the old iccXfm class. 16 */ 17 18 /* 19 * This library expands the icclib functionality, 20 * particularly in creating and exercising color transforms. 21 * 22 * For the moment, this support is concentrated around the 23 * Lut and Matrix subsets of the ICC profile tranforms. 24 * 25 * It is intended to allow color transformation, storage and retrieval 26 * of ICC profiles, while permitting inititialization from scattered 27 * data, reversing of the transform, and specific manipulations of 28 * the internal processing elements. 29 * 30 * This class bases much of it's functionality on that of the 31 * underlying icclib icmLuBase. 32 */ 33 34 #include "icc.h" /* icclib ICC definitions */ 35 #include "cgats.h" /* CGAT format */ 36 #include "rspl.h" /* rspllib thin plate spline definitions */ 37 #include "gamut.h" /* gamut definitions */ 38 #include "xutils.h" /* Utility functions */ 39 #include "xcam.h" /* CAM definitions */ 40 #include "xspect.h" /* Spectral conversion object */ 41 #include "xcolorants.h" /* Known colorants support */ 42 #include "insttypes.h" /* Instrument type support */ 43 #include "mpp.h" /* model printer profile support */ 44 #include "moncurve.h" /* monotonic curve support */ 45 /* (more at the end) */ 46 47 #define XICC_USE_HK 1 /* [Set] Set to 1 to use Helmholtz-Kohlraush in all CAM conversions */ 48 #define XICC_NEUTRAL_CMYK_BLACK /* Use neutral axis black, else use K direction black. */ 49 #define XICC_BLACK_POINT_TOLL 0.5 /* Tollerance of CMYK black point location */ 50 #define XICC_BLACK_FIND_ABERR_WEIGHT 10.0 /* Weight of ab error against min L in BP */ 51 52 /* ------------------------------------------------------------------------------ */ 53 54 /* The "effective" PCS colorspace is the one specified by the PCS override, and */ 55 /* visible in the overal profile conversion. The "native" PCS colorspace is the one */ 56 /* that the underlying tags actually represent, and the PCS that the individual */ 57 /* stages within each profile type handle (unless the ICX_MERGED flag is set, in which */ 58 /* case the clut == native PCS appears to be the effective one). The conversion between */ 59 /* the native and effective PCS is generally done in the to/from_abs() conversions. */ 60 61 /* ------------------------------------------------------------------------------ */ 62 63 /* Pseudo intents, valid as parameter to xicc get_luobj(): */ 64 65 /* Default Color Appearance Space, based on absolute colorimetric */ 66 #define icxAppearance ((icRenderingIntent)994) 67 68 /* Represents icAbsoluteColorimetric, converted to Color Appearance space */ 69 #define icxAbsAppearance ((icRenderingIntent)995) /* Fixed D50 white point */ 70 71 /* Special Color Appearance Space, based on "absolute" perceptual */ 72 #define icxPerceptualAppearance ((icRenderingIntent)996) 73 74 /* Default Color Appearance Space, based on "absolute" saturation */ 75 #define icxSaturationAppearance ((icRenderingIntent)997) 76 77 /* These two are for completeness, they are unlikely to be useful: */ 78 /* Special Color Appearance Space, based on "absolute" perceptual */ 79 #define icxAbsPerceptualAppearance ((icRenderingIntent)998) 80 81 /* Default Color Appearance Space, based on "absolute" saturation */ 82 #define icxAbsSaturationAppearance ((icRenderingIntent)999) 83 84 85 /* Pseudo PCS colospace returned as PCS for intent icxAppearanceJab */ 86 #define icxSigJabData ((icColorSpaceSignature) icmMakeTag('J','a','b',' ')) 87 88 /* Pseudo PCS colospace returned as PCS for intent icxAppearanceJCh */ 89 #define icxSigJChData ((icColorSpaceSignature) icmMakeTag('J','C','h',' ')) 90 91 /* Pseudo PCS colospace returned as PCS */ 92 #define icxSigLChData ((icColorSpaceSignature) icmMakeTag('L','C','h',' ')) 93 94 /* Return a string description of the given enumeration value */ 95 const char *icx2str(icmEnumType etype, int enumval); 96 97 98 /* ------------------------------------------------------------------------------ */ 99 100 /* A 3x3 matrix model */ 101 struct _icxMatrixModel { 102 void *imp; /* Opaque implementation */ 103 104 icc *picc; /* ICC profile used to set cone space matrix, NULL for Bradford. */ 105 int isLab; /* Convert lookup to Lab */ 106 107 void (*force) (struct _icxMatrixModel *p, double *targ, double *in); 108 void (*lookup) (struct _icxMatrixModel *p, double *out, double *in); 109 void (*del) (struct _icxMatrixModel *p); 110 111 }; typedef struct _icxMatrixModel icxMatrixModel; 112 113 /* Create a matrix model of a set of points, and return an object to lookup */ 114 /* points from the model. Return NULL on error. */ 115 icxMatrixModel *new_MatrixModel( 116 icc *picc, /* ICC profile used to set cone space matrix, NULL for Bradford. */ 117 int verb, /* NZ if verbose */ 118 int nodp, /* Number of points */ 119 cow *ipoints, /* Array of input points in XYZ space */ 120 int isLab, /* nz if data points are Lab */ 121 int quality, /* Quality metric, 0..3 (-1 == 2 orders only) */ 122 int isLinear, /* NZ if pure linear, gamma = 1.0 */ 123 int isGamma, /* NZ if gamma rather than shaper */ 124 int isShTRC, /* NZ if shared TRCs */ 125 int shape0gam, /* NZ if zero'th order shaper should be gamma function */ 126 int clipbw, /* Prevent white > 1 and -ve black */ 127 int clipprims, /* Prevent primaries going -ve */ 128 double smooth, /* Smoothing factor (nominal 1.0) */ 129 double scale /* Amount to scale device values */ 130 ); 131 132 /* ------------------------------------------------------------------------------ */ 133 /* Basic class keeps extra state for an icc, and provides the */ 134 /* expanded set of methods. */ 135 136 /* Black generation rule */ 137 /* The rule is all in terms of device K and L* values */ 138 typedef enum { 139 icxKvalue = 0, /* K is specified as output K target by PCS auxiliary */ 140 icxKlocus = 1, /* K is specified as proportion of K locus by PCS auxiliary */ 141 icxKluma5 = 2, /* K is specified as locus by 5 parameters as a function of L */ 142 icxKluma5k = 3, /* K is specified as K value by 5 parameters as a function of L */ 143 icxKl5l = 4, /* K is specified as locus by 2x5 parameters as a function of L and K locus aux */ 144 icxKl5lk = 5 /* K is specified as K value by 2x5 parameters as a function of L and K value aux */ 145 } icxKrule; 146 147 /* Curve parameters */ 148 typedef struct { 149 double Ksmth; /* K smoothing filter extent */ 150 double Kstle; /* K start level at white end (0.0 - 1.0)*/ 151 double Kstpo; /* K start point as prop. of L locus (0.0 - 1.0) */ 152 double Kenpo; /* K end point as prop. of L locus (0.0 - 1.0) */ 153 double Kenle; /* K end level at Black end (0.0 - 1.0) */ 154 double Kshap; /* K transition shape, 0.0-1.0 concave, 1.0-2.0 convex */ 155 double Kskew; /* K transition shape skew, 1.0 = even */ 156 } icxInkCurve; 157 158 /* Default black generation smoothing value */ 159 #define ICXINKDEFSMTH 0.09 /* Transition window of +/- ICXINKDEFSMTH */ 160 #define ICXINKDEFSKEW 2.0 /* Curve shape skew (matches typical device behaviour) */ 161 162 /* Structure to convey inking details */ 163 typedef struct { 164 double tlimit; /* Total ink limit, > 0.0 to < inputChan, < 0.0 == off */ 165 double klimit; /* Black limit, > 0.0 to < 1.0, < 0.0 == off */ 166 icxKrule k_rule; /* type of K generation rule */ 167 int KonlyLmin; /* Use K only black Locus Lmin */ 168 icxInkCurve c; /* K curve, or locus minimum curve */ 169 icxInkCurve x; /* locus maximum curve if icxKl5l */ 170 } icxInk; 171 172 /* Structure to convey inverse lookup clip handling details */ 173 struct _icxClip { 174 int nearclip; /* Flag - use near clipping not vector */ 175 int LabLike; /* Flag It's an Lab like colorspace */ 176 int fdi; /* Dimentionality of clip vector */ 177 struct _icxCuspMap *cm; /* Cusp map for computing vector (if !NULL) */ 178 double ocent[MXDO]; /* Default center of clut output gamut used if cm == NULL */ 179 }; typedef struct _icxClip icxClip; 180 181 /* Structure to convey viewing conditions */ 182 typedef struct { 183 ViewingCondition Ev;/* Enumerated Viewing Condition */ 184 double Wxyz[3]; /* Reference/Adapted White XYZ (Y range 0.0 .. 1.0) */ 185 double La; /* Adapting/Surround Luminance cd/m^2 */ 186 double Yb; /* Relative Luminance of Background to reference white */ 187 double Lv; /* Luminance of white in the Image/Scene/Viewing field (cd/m^2) */ 188 /* Ignored if Ev is set to other than vc_none */ 189 double Yf; /* Flare as a fraction of the reference white (Y range 0.0 .. 1.0) */ 190 double Yg; /* Glare as a fraction of the adapting/surround (Y range 0.0 .. 1.0) */ 191 double Gxyz[3]; /* The Glare white coordinates (ie the Ambient color) */ 192 /* will be taken from Wxyz if Gxyz <= 0.0 */ 193 double hkscale; /* [1.0] HK scaling factor */ 194 char *desc; /* Possible description of this VC */ 195 } icxViewCond; 196 197 #define XICC_DEFAULT_GLARE 5 /* Default glare in % */ 198 199 /* Method of black point adaptation */ 200 typedef enum { 201 gmm_BPadpt = 0, /* Adapt source black point to destination */ 202 gmm_noBPadpt = 1, /* Don't adapt black point to destination */ 203 gmm_bendBP = 2, /* Don't adapt black point, bend it to dest. at end */ 204 gmm_clipBP = 3 /* Don't adapt black point, clip it to dest. at end */ 205 } icx_BPmap; 206 207 /* Structure to convey gamut mapping intent */ 208 typedef struct { 209 int usecas; /* 0x0 Use relative Lab space */ 210 /* 0x1 Use Absolute Lab Space */ 211 /* 0x2 Use Color Appearance Space */ 212 /* 0x3 Use Absolute Color Appearance Space */ 213 /* 0x102 Use Color Appearance Space with luminence scaling */ 214 int usemap; /* NZ if Gamut mapping should be used, else clip */ 215 double greymf; /* Grey axis hue matching factor, 0.0 - 1.0 */ 216 double glumwcpf; /* Grey axis luminance white compression factor, 0.0 - 1.0 */ 217 double glumwexf; /* Grey axis luminance white expansion factor, 0.0 - 1.0 */ 218 double glumbcpf; /* Grey axis luminance black compression factor, 0.0 - 1.0 */ 219 double glumbexf; /* Grey axis luminance black expansion factor, 0.0 - 1.0 */ 220 double glumknf; /* Grey axis luminance knee factor, 0.0 - 1.0 */ 221 icx_BPmap bph; /* Method of black point adapation */ 222 double gamcpf; /* Gamut compression factor, 0.0 - 1.0 */ 223 double gamexf; /* Gamut expansion factor, 0.0 - 1.0 */ 224 double gamcknf; /* Gamut compression knee factor, 0.0 - 1.0 */ 225 double gamxknf; /* Gamut expansion knee factor, 0.0 - 1.0 */ 226 double gampwf; /* Gamut Perceptual Map weighting factor, 0.0 - 1.0 */ 227 double gamlpwf; /* Gamut Lightness preserving perceptual Map whtg. factor, 0.0 - 1.0 */ 228 double gamswf; /* Gamut Saturation Map weighting factor, 0.0 - 1.0 */ 229 double satenh; /* Saturation enhancement value, 0.0 - Inf */ 230 double hkscale; /* [1.0] Optional HK scaling factor */ 231 char *as; /* Alias string (option name) */ 232 char *desc; /* Possible description of this VC */ 233 icRenderingIntent icci; /* Closest ICC intent */ 234 } icxGMappingIntent; 235 236 struct _xicc { 237 /* Private: */ 238 icc *pp; /* ICC profile we expand */ 239 240 struct _xcal *cal; /* Optional device cal, NULL if none */ 241 int nodel_cal; /* Flag, nz if cal was provided externally and shouldn't be deleted */ 242 243 /* Public: */ 244 void (*del)(struct _xicc *p); 245 246 /* "use" flags */ 247 #define ICX_CLIP_VECTOR 0x0000 /* If clipping is needed, clip in vector direction (default) */ 248 #define ICX_CLIP_NEAREST 0x0010 /* If clipping is needed, clip to nearest */ 249 #define ICX_MERGE_CLUT 0x0020 /* Merge the output() and out_abs() into the clut(), */ 250 /* for improved performance on reading, and */ 251 /* clipping in effective output space on inverse lookup. */ 252 /* Reduces accuracy noticably though. */ 253 /* Output output() and out_abs() become NOPs */ 254 #define ICX_CAM_CLIP 0x0100 /* Use CAM space during invfwd clipping lookup, */ 255 /* irrespective of the native or effective PCS. */ 256 /* Ignored if MERGE_CLUT is set or vector clip is used. */ 257 /* May halve the inverse lookup performance! */ 258 #define ICX_INT_SEPARATE 0x0400 /* Handle 4 dimensional devices with fixed inking rules */ 259 /* with an optimised internal separation pass, rather */ 260 /* than a point by point inverse locus lookup . */ 261 /* NOT IMPLEMENTED YET */ 262 #define ICX_FAST_SETUP 0x0800 /* Improve initial setup speed at the cost of throughput */ 263 #define ICX_VERBOSE 0x8000 /* Turn on verboseness during creation */ 264 265 /* Returm a lookup object from the icc */ 266 struct _icxLuBase * (*get_luobj) (struct _xicc *p, 267 int flags, /* clip, merge flags */ 268 icmLookupFunc func, /* Functionality */ 269 icRenderingIntent intent,/* Intent */ 270 icColorSpaceSignature pcsor, /* PCS override (0 = def) */ 271 icmLookupOrder order, /* Search Order */ 272 icxViewCond *vc, /* Viewing Condition - only */ 273 /* used if pcsor == CIECAM. */ 274 /* or ICX_CAM_CLIP flag. */ 275 icxInk *ink); /* inking details (NULL = def) */ 276 277 278 /* Set a xluobj and icc table from scattered data */ 279 /* Return appropriate lookup object */ 280 /* NULL on error, check errc+err for reason */ 281 /* "create" flags */ 282 #define ICX_SET_WHITE 0x00010000 /* find, set and make relative to the white point */ 283 #define ICX_SET_WHITE_US 0x00030000 /* find, set and make relative to the white point hue, */ 284 /* but not scale to W L value, to avoid input clipping */ 285 #define ICX_SET_WHITE_C 0x00050000 /* find, set and make relative to the white point hue, */ 286 /* and clip any cLUT values over D50 to D50 */ 287 #define ICX_SET_BLACK 0x00080000 /* find and set the black point */ 288 #define ICX_WRITE_WBL 0x00100000 /* Matrix: write White, Black & Luminance tags */ 289 #define ICX_CLIP_WB 0x00200000 /* Clip white and black to be < 1 and > 0 respectively */ 290 #define ICX_CLIP_PRIMS 0x00400000 /* Clip matrix primaries to be > 0 */ 291 #define ICX_NO_IN_SHP_LUTS 0x00800000 /* Lut/Mtx: Don't create input (Device) shaper curves. */ 292 #define ICX_NO_IN_POS_LUTS 0x01000000 /* LuLut: Don't create input (Device) postion curves. */ 293 #define ICX_NO_OUT_LUTS 0x02000000 /* LuLut: Don't create output (PCS) curves. */ 294 //#define ICX_2PASSSMTH 0x04000000 /* If LuLut: Use Gaussian smoothing */ 295 //#define ICX_EXTRA_FIT 0x08000000 /* If LuLut: Counteract scat data point errors. */ 296 /* And ICX_VERBOSE Turn on verboseness during creation */ 297 struct _icxLuBase * (*set_luobj) (struct _xicc *p, 298 icmLookupFunc func, /* Functionality to set */ 299 icRenderingIntent intent, /* Intent to set */ 300 icmLookupOrder order, /* Search Order */ 301 int flags, /* white/black point flags */ 302 int no, /* Total Number of points */ 303 int nobw, /* Number of points to look */ 304 /* for white & black patches in */ 305 cow *points, /* Array of input points */ 306 icxMatrixModel *skm, /* Optional skeleton model */ 307 double dispLuminance, /* > 0.0 if display luminance */ 308 /* value and is known */ 309 double wpscale, /* > 0.0 if input white pt is */ 310 /* is to be scaled */ 311 // double *bpo, /* != NULL black point override */ 312 double smooth, /* RSPL smoothing factor, */ 313 /* -ve if raw */ 314 double avgdev, /* Avge Dev. of points */ 315 double demph, /* cLut dark emphasis factor */ 316 icxViewCond *vc, /* Viewing Condition - only */ 317 /* used if pcsor == CIECAM. */ 318 /* or ICX_CAM_CLIP flag. */ 319 icxInk *ink, /* inking details */ 320 struct _xcal *cal, /* Optional cal Will override any */ 321 /* existing, not deltd with xicc. */ 322 int quality); /* Quality metric, 0..3 */ 323 324 325 /* Return the devices viewing conditions. */ 326 /* Return value 0 if it is well defined */ 327 /* Return value 1 if it is a guess */ 328 /* Return value 2 if it is not possible/appropriate */ 329 int (*get_viewcond)(struct _xicc *p, icxViewCond *vc); 330 331 char err[512]; /* Error message */ 332 int errc; /* Error code */ 333 }; typedef struct _xicc xicc; 334 335 /* ~~~~~ */ 336 /* Might be good to add a slow but very precise vector and closest "clip to gamut" */ 337 /* function for use in setting white and black points. Use this in profile. */ 338 339 xicc *new_xicc(icc *picc); 340 341 /* ------------------------------------------------------------------------------ */ 342 /* Expanded lookup object support */ 343 #define XLU_BASE_MEMBERS \ 344 /* Private: */ \ 345 int trace; /* Optional run time tracing flag */ \ 346 struct _xicc *pp; /* Pointer to XICC we're a part of */ \ 347 icmLuBase *plu; /* Pointer to icm Lu we are expanding */ \ 348 int flags; /* Flags passed to get_luobj */ \ 349 icmLookupFunc func; /* Function passed to get_luobj */ \ 350 icRenderingIntent intent; /* Effective/External Intent */ \ 351 /* "in" and "out" are in reference to */ \ 352 /* the requested lookup direction. */ \ 353 icColorSpaceSignature ins; /* Effective/External Clr space of input */ \ 354 icColorSpaceSignature outs; /* Effective/External Clr space of output */\ 355 icColorSpaceSignature pcs; /* Effective/External PCS */ \ 356 icColorSpaceSignature natis; /* Native input Clr space */ \ 357 icColorSpaceSignature natos; /* Native output Clr space */ \ 358 icColorSpaceSignature natpcs; /* Native PCS Clr space */ \ 359 int inputChan; /* Num of input channels */ \ 360 int outputChan; /* Num of output channels */ \ 361 double ninmin[MXDI]; /* icc Native Input color space minimum */ \ 362 double ninmax[MXDI]; /* icc Native Input color space maximum */ \ 363 double noutmin[MXDO]; /* icc Native Output color space minimum */ \ 364 double noutmax[MXDO]; /* icc Native Output color space maximum */ \ 365 double inmin[MXDI]; /* icx Effective Input color space minimum */ \ 366 double inmax[MXDI]; /* icx Effective Input color space maximum */ \ 367 double outmin[MXDO]; /* icx Effective Output color space minimum */ \ 368 double outmax[MXDO]; /* icx Effective Output color space maximum */ \ 369 icxViewCond vc; /* Viewing Condition for CIECAM97s */ \ 370 icxcam *cam; /* CAM conversion */ \ 371 \ 372 /* Attributes inhereted by ixcLu's */ \ 373 int noisluts; /* Flag - If LuLut: Don't create input (Device) shaper curves. */ \ 374 int noipluts; /* Flag - If LuLut: Don't create input (Device) position curves. */ \ 375 int nooluts; /* Flag - If LuLut: Don't create output (PCS) curves. */ \ 376 int nearclip; /* Flag - If clipping occurs, return the nearest solution, */ \ 377 int mergeclut; /* Flag - If LuLut: Merge output() and out_abs() into clut(). */ \ 378 int camclip; /* Flag - If LuLut: Use CIECAM for clut reverse lookup clipping */ \ 379 int intsep; /* Flag - If LuLut: Do internal separation for 4d device */ \ 380 int fastsetup; /* Flag - If LuLut: Do fast setup at cost of slower throughput */ \ 381 \ 382 /* Public: */ \ 383 void (*del)(struct _icxLuBase *p); \ 384 \ 385 /* Return Internal native colorspaces */ \ 386 void (*lutspaces) (struct _icxLuBase *p, icColorSpaceSignature *ins, int *inn, \ 387 icColorSpaceSignature *outs, int *outn, \ 388 icColorSpaceSignature *pcs); \ 389 \ 390 /* External effective colorspaces */ \ 391 void (*spaces) (struct _icxLuBase *p, icColorSpaceSignature *ins, int *inn, \ 392 icColorSpaceSignature *outs, int *outn, \ 393 icmLuAlgType *alg, icRenderingIntent *intt, \ 394 icmLookupFunc *fnc, icColorSpaceSignature *pcs); \ 395 \ 396 /* Get the Native input space and output space ranges */ \ 397 void (*get_native_ranges) (struct _icxLuBase *p, \ 398 double *inmin, double *inmax, /* Maximum range of inspace values */ \ 399 double *outmin, double *outmax); /* Maximum range of outspace values */ \ 400 \ 401 \ 402 /* Get the Effective input space and output space ranges */ \ 403 void (*get_ranges) (struct _icxLuBase *p, \ 404 double *inmin, double *inmax, /* Maximum range of inspace values */ \ 405 double *outmin, double *outmax); /* Maximum range of outspace values */ \ 406 \ 407 \ 408 /* Return the media white and black points */ \ 409 /* in the effective PCS colorspace. */ \ 410 /* (ie. these will be relative values for relative intent etc.) */ \ 411 void (*efv_wh_bk_points)(struct _icxLuBase *p, double *wht, double *blk, double *kblk); \ 412 \ 413 /* Translate color values through profile */ \ 414 /* 0 = success */ \ 415 /* 1 = warning: clipping occured */ \ 416 /* 2 = fatal: other error */ \ 417 \ 418 /* (Note that clipping is not a reliable means of detecting out of gamut in the */ \ 419 /* lookup(bwd) call for clut based profiles, but is for inv_lookup() calls.) */ \ 420 \ 421 int (*lookup) (struct _icxLuBase *p, double *out, double *in); \ 422 /* Requested conversion */ \ 423 int (*inv_lookup) (struct _icxLuBase *p, double *out, double *in); \ 424 /* Inverse conversion */ \ 425 \ 426 /* Given an xicc lookup object, returm a gamut object. */ \ 427 /* Note that the Effective PCS must be Lab or Jab */ \ 428 /* A icxLuLut type must be icmFwd or icmBwd, */ \ 429 /* and for icmFwd, the ink limit (if supplied) */ \ 430 /* will be applied. */ \ 431 /* Return NULL on error, check xicc errc+err for reason */ \ 432 gamut * (*get_gamut) (struct _icxLuBase *plu, /* xicc lookup object */ \ 433 double detail); /* gamut detail level, 0.0 = def */ \ 434 \ 435 /* Given an xicc lookup object, return an icxCuspMap object. */ \ 436 /* Note that the PCS must be Lab or Jab. */ \ 437 /* An icxLuLut type must be icmFwd, and the ink limit (if supplied) */ \ 438 /* will be applied. */ \ 439 /* Return NULL on error, check errc+err for reason */ \ 440 struct _icxCuspMap *(*get_cuspmap)(struct _icxLuBase *p, int res); \ 441 \ 442 /* The following two functions expose the relative colorimetric native ICC PCS */ \ 443 /* <--> absolute/CAM space transform, so that CAM based gamut compression */ \ 444 /* can be applied in creating the ICC Lut tabls in profout.c. */ \ 445 \ 446 /* Given a native ICC relative XYZ or Lab PCS value, convert in the fwd */ \ 447 /* direction into the nominated Effective output PCS (ie. Absolute, Jab etc.) */ \ 448 void (*fwd_relpcs_outpcs) (struct _icxLuBase *p, icColorSpaceSignature is, \ 449 double *out, double *in); \ 450 \ 451 /* Given a nominated Effective output PCS (ie. Absolute, Jab etc.), convert it */ \ 452 /* in the bwd direction into a native ICC relative XYZ or Lab PCS value */ \ 453 void (*bwd_outpcs_relpcs) (struct _icxLuBase *p, icColorSpaceSignature os, \ 454 double *out, double *in); \ 455 \ 456 457 458 /* Base xlookup object */ 459 struct _icxLuBase { 460 XLU_BASE_MEMBERS 461 }; typedef struct _icxLuBase icxLuBase; 462 463 /* Monochrome Fwd & Bwd type object */ 464 struct _icxLuMono { 465 XLU_BASE_MEMBERS 466 467 /* Overall lookups */ 468 int (*fwd_lookup) (struct _icxLuBase *p, double *out, double *in); 469 int (*bwd_lookup) (struct _icxLuBase *p, double *out, double *in); 470 471 /* Components of Device to PCS lookup */ 472 int (*fwd_curve) (struct _icxLuMono *p, double *out, double *in); 473 int (*fwd_map) (struct _icxLuMono *p, double *out, double *in); 474 int (*fwd_abs) (struct _icxLuMono *p, double *out, double *in); 475 476 /* Components of PCS to Device lookup */ 477 int (*bwd_abs) (struct _icxLuMono *p, double *out, double *in); 478 int (*bwd_map) (struct _icxLuMono *p, double *out, double *in); 479 int (*bwd_curve) (struct _icxLuMono *p, double *out, double *in); 480 481 }; typedef struct _icxLuMono icxLuMono; 482 483 /* 3D Matrix Fwd & Bwd type object */ 484 struct _icxLuMatrix { 485 XLU_BASE_MEMBERS 486 487 /* Overall lookups */ 488 int (*fwd_lookup) (struct _icxLuBase *p, double *out, double *in); 489 int (*bwd_lookup) (struct _icxLuBase *p, double *out, double *in); 490 491 /* Components of Device to PCS lookup */ 492 int (*fwd_curve) (struct _icxLuMatrix *p, double *out, double *in); 493 int (*fwd_matrix) (struct _icxLuMatrix *p, double *out, double *in); 494 int (*fwd_abs) (struct _icxLuMatrix *p, double *out, double *in); 495 496 /* Components of PCS to Device lookup */ 497 int (*bwd_abs) (struct _icxLuMatrix *p, double *out, double *in); 498 int (*bwd_matrix) (struct _icxLuMatrix *p, double *out, double *in); 499 int (*bwd_curve) (struct _icxLuMatrix *p, double *out, double *in); 500 501 }; typedef struct _icxLuMatrix icxLuMatrix; 502 503 /* Multi-D. Lut type object */ 504 struct _icxLuLut { 505 XLU_BASE_MEMBERS 506 507 /* private: */ 508 icmLut *lut; /* ICC Lut that is being used */ 509 rspl *inputTable[MXDI]; /* The input lookups */ 510 rspl *clutTable; /* The multi dimention lookup */ 511 rspl *cclutTable; /* Alternate multi dimention lookup in CAM space */ 512 rspl *outputTable[MXDO]; /* The output lookups */ 513 514 /* Inverted RSPLs used to speed ink limit calculation */ 515 /* input' -> input */ 516 rspl *revinputTable[MXDI]; 517 518 /* In/Out lookup flags used for rspl init. callback */ 519 int iol_out; /* Non-zero if output lookup */ 520 int iol_ch; /* Channel */ 521 522 /* In/Out inversion support */ 523 double inputClipc[MXDI]; /* The input lookups clip center */ 524 double outputClipc[MXDO]; /* The output lookups clip center */ 525 526 /* clut inversion support */ 527 double icent[MXDI]; /* center of input gamut */ 528 double licent[MXDI]; /* last icent value used */ 529 530 icxClip clip; /* Clip setup information */ 531 532 int kch; /* Black ink channel if discovered */ 533 /* -1 if not known or applicable */ 534 /* (Only set by icxLu_comp_bk_point()) */ 535 icxInk ink; /* inking details */ 536 double Lmin, Lmax; /* L min/max for inking rule */ 537 538 /* Auxiliary parameter flags, non-zero for inputs that will be */ 539 /* used as auxiliary parameters the rspl input */ 540 /* dimensionality exceeds the output dimension (i.e. CMYK->Lab) */ 541 int auxm[MXDI]; 542 543 /* Auxiliar linearization function - NULL if none */ 544 /* Only the used auxiliary chanels need be calculated. */ 545 /* ~~ not implimented yet ~~~ */ 546 // void (*auxlinf)(void *auxlinf_ctx, double inout[MXDI]); 547 548 /* Opaque context for auxlin */ 549 // void *auxlinf_ctx; 550 551 /* Temporary icm fwd abs XYZ LuLut used for setting up icx clut */ 552 icmLuBase *absxyzlu; 553 554 /* Optional function to compute the input chanel */ 555 /* sum from the raw rspl input values. NULL if not used. */ 556 /* Use this to take account of any transformation beyond */ 557 /* the input space, or 6 color masquerading as 4 etc. */ 558 double (*limitf)(void *limitf_ctx, float in[MXDI]); /* ~~ not implimented yet */ 559 560 /* Opaque context for limitf */ 561 void *limitf_ctx; 562 563 /* Input space sum limit. Points with a limitf() over */ 564 /* this number will not be considered in gamut. Valid if gt 0 */ 565 double slimit; 566 567 /* public: */ 568 569 /* Note that black inking rules are always defined and provided */ 570 /* in dev[] and pcs[] space, even for component functions */ 571 /* (ie. the implementation of the inking rule deals with */ 572 /* the dev<->dev' and pcs<->pcs' conversions) */ 573 574 /* Requested direction component lookup */ 575 int (*in_abs) (struct _icxLuLut *p, double *out, double *in); 576 int (*matrix) (struct _icxLuLut *p, double *out, double *in); 577 int (*input) (struct _icxLuLut *p, double *out, double *in); 578 int (*clut) (struct _icxLuLut *p, double *out, double *in); 579 int (*clut_aux)(struct _icxLuLut *p, double *out, double *olimit, 580 double *auxv, double *in); 581 int (*output) (struct _icxLuLut *p, double *out, double *in); 582 int (*out_abs) (struct _icxLuLut *p, double *out, double *in); 583 584 /* Inverse direction component lookup (in reverse order) */ 585 int (*inv_out_abs) (struct _icxLuLut *p, double *out, double *in); 586 int (*inv_output) (struct _icxLuLut *p, double *out, double *in); 587 int (*inv_clut) (struct _icxLuLut *p, double *out, double *in); 588 int (*inv_clut_aux)(struct _icxLuLut *p, double *out, double *auxv, 589 double *auxr, double *auxt, double *clipd, double *in); 590 int (*inv_input) (struct _icxLuLut *p, double *out, double *in); 591 int (*inv_matrix) (struct _icxLuLut *p, double *out, double *in); 592 int (*inv_in_abs) (struct _icxLuLut *p, double *out, double *in); 593 594 /* Get locus information for a clut (see xlut.c for details) */ 595 int (*clut_locus) (struct _icxLuLut *p, double *locus, double *out, double *in); 596 597 /* Get various types of information about the LuLut */ 598 void (*get_info) (struct _icxLuLut *p, icmLut **lutp, 599 icmXYZNumber *pcswhtp, icmXYZNumber *whitep, 600 icmXYZNumber *blackp); 601 602 /* Get the matrix contents */ 603 void (*get_matrix) (struct _icxLuLut *p, double m[3][3]); 604 605 }; typedef struct _icxLuLut icxLuLut; 606 607 /* ------------------------------------------------------------------------------ */ 608 /* Utility declarations and functions */ 609 610 /* Utility that mirrors get_luobj intent handling: */ 611 /* return nz if the intent implies Jab space */ 612 int xiccIsIntentJab(icRenderingIntent intent); 613 614 /* Profile Creation Suplimental Information structure */ 615 struct _profxinf { 616 icmSig manufacturer; /* Device manufacturer ICC Sig, 0 for default */ 617 char *deviceMfgDesc; /* Manufacturer text description, NULL for none */ 618 619 icmSig model; /* Device model ICC Sig, 0 for default */ 620 char *modelDesc; /* Model text description, NULL for none */ 621 622 icmSig creator; /* Profile creator ICC Sig, 0 for default */ 623 624 char *profDesc; /* Text profile description, NULL for default */ 625 626 char *copyright; /* Copyrigh text, NULL for default */ 627 628 /* Attribute flags */ 629 int transparency; /* NZ for Trasparency, else Reflective */ 630 int matte; /* NZ for Matte, else Glossy */ 631 int negative; /* NZ for Negative, else Positive */ 632 int blackandwhite; /* NZ for BlackAndWhite, else Color */ 633 634 /* Default intent */ 635 icRenderingIntent default_ri; /* Default rendering intent */ 636 637 /* Other stuff ICC ?? */ 638 639 }; typedef struct _profxinf profxinf; 640 641 /* Set an icc's Lut tables, and take care of auxiliary continuity problems. */ 642 /* Only useful if there are auxiliary device output chanels to be set. */ 643 int icxLut_set_tables_auxfix( 644 icmLut *p, /* Pointer to icmLut object */ 645 void *cbctx, /* Opaque callback context pointer value */ 646 icColorSpaceSignature insig, /* Input color space */ 647 icColorSpaceSignature outsig, /* Output color space */ 648 void (*infunc)(void *cbctx, double *out, double *in), 649 /* Input transfer function, inspace->inspace' (NULL = default) */ 650 double *inmin, double *inmax, /* Maximum range of inspace' values */ 651 /* (NULL = default) */ 652 void (*clutfunc)(void *cbntx, double *out, double *aux, double *auxr, double *pcs, double *in), 653 /* inspace' -> outspace' transfer function, also */ 654 /* return the internal target PCS and the (packed) auxiliary locus */ 655 /* range as [min0, max0, min1, max1...], and the actual auxiliary */ 656 /* target used. */ 657 void (*clutpcsfunc)(void *cbntx, double *out, double *aux, double *pcs), 658 /* Internal PCS + actual aux_target -> outspace' transfer function */ 659 void (*clutipcsfunc)(void *cbntx, double *pcs, double *olimit, double *auxv, double *in), 660 /* outspace' -> Internal PCS + auxv check function */ 661 double *clutmin, double *clutmax, /* Maximum range of outspace' values */ 662 /* (NULL = default) */ 663 void (*outfunc)(void *cbntx, double *out, double *in) 664 /* Output transfer function, outspace'->outspace (NULL = deflt) */ 665 ); 666 667 668 /* Return an enumerated viewing condition */ 669 /* Return enumeration if OK, -999 if there is no such enumeration. */ 670 /* xicc may be NULL if just the description is wanted, */ 671 /* or an explicit white point is provided. */ 672 int xicc_enum_viewcond( 673 xicc *p, /* Expanded profile to get white point (May be NULL if desc NZ) */ 674 icxViewCond *vc, /* Viewing parameters to return, May be NULL if desc is nz */ 675 int no, /* Enumeration to return, -1 for default, -2 for none */ 676 char *as, /* String alias to number, NULL if none */ 677 int desc, /* NZ - Just return a description of this enumeration in vc */ 678 double *wp /* Provide XYZ white point if xicc is NULL */ 679 ); 680 681 /* Debug: dump a Viewing Condition to standard out */ 682 void xicc_dump_viewcond(icxViewCond *vc); 683 684 /* Debug: dump an Inking setup to standard out */ 685 void xicc_dump_inking(icxInk *ik); 686 687 /* Return enumerated gamut mapping intents */ 688 /* Return 0 if OK, 1 if there is no such enumeration. */ 689 /* Note the following fixed numbers meanings: */ 690 #define icxNoGMIntent -1 691 #define icxDefaultGMIntent -2 692 #define icxAbsoluteGMIntent -3 693 #define icxRelativeGMIntent -4 694 #define icxPerceptualGMIntent -5 695 #define icxSaturationGMIntent -6 696 #define icxIllegalGMIntent -999 697 int xicc_enum_gmapintent(icxGMappingIntent *gmi, int no, char *as); 698 void xicc_dump_gmi(icxGMappingIntent *gmi); 699 700 /* - - - - - - - - - - */ 701 /* Utility functions: */ 702 703 /* Given an open icc profile, */ 704 /* guess which channel is the black. */ 705 /* Return -1 if there is no black channel or it can't be guessed */ 706 int icxGuessBlackChan(icc *p); 707 708 /* Given an icc profile, try and create an xcal */ 709 /* Return NULL on error or no cal */ 710 struct _xcal *xiccReadCalTag(icc *p); 711 712 /* A callback that uses an xcal, that can be used with icc get_tac */ 713 void xiccCalCallback(void *cntx, double *out, double *in); 714 715 /* Given an xicc icc profile, estmate the total ink limit and black ink limit. */ 716 void icxGetLimits(xicc *p, double *tlimit, double *klimit); 717 718 /* Using the above function, set default total and black ink values */ 719 void icxDefaultLimits(xicc *p, double *tlout, double tlin, double *klout, double klin); 720 721 /* Given a calibrated total ink limit and an xcal, return the */ 722 /* equivalent underlying (pre-calibration) total ink limit. */ 723 /* This is the maximum equivalent, that makes sure that */ 724 /* the calibrated limit is met or exceeded. */ 725 double icxMaxUnderlyingLimit(struct _xcal *cal, double ilimit); 726 727 /* - - - - - - - - - - */ 728 729 /* Utility function - compute the clip vector direction. */ 730 /* return NULL if vector clip isn't used. */ 731 double *icxClipVector( 732 icxClip *p, /* Clipping setup information */ 733 double *in, /* Target point */ 734 double *cdirv, /* Returned clip vector */ 735 int safe /* Flag - return safe vector */ 736 ); 737 738 /* - - - - - - - - - - */ 739 740 /* CIE XYZ to perceptual Lab with partial derivatives. */ 741 void icxdXYZ2Lab(icmXYZNumber *w, double *out, double dout[3][3], double *in); 742 743 /* Return the normal Delta E squared, given two Lab values, */ 744 /* including partial derivatives. */ 745 double icxdLabDEsq(double dout[2][3], double *Lab0, double *Lab1); 746 747 /* Return the CIE94 Delta E color difference measure, squared */ 748 /* including partial derivatives. */ 749 double icxdCIE94sq(double dout[2][3], double Lab0[3], double Lab1[3]); 750 751 /* Return the normal Delta E given two Lab values, */ 752 /* including partial derivatives. */ 753 double icxdLabDE(double dout[2][3], double *Lab0, double *Lab1); 754 755 /* Return the CIE94 Delta E color difference measure */ 756 /* including partial derivatives. */ 757 double icxdCIE94(double dout[2][3], double Lab0[3], double Lab1[3]); 758 759 /* - - - - - - - - - - */ 760 /* Power like function, based on Graphics Gems adjustment curve. */ 761 /* Avoids "toe" problem of pure power. */ 762 /* Adjusted so that "power" 2 and 0.5 agree with real power at 0.5 */ 763 double icx_powlike(double vv, double pp); 764 765 /* Compute the necessary aproximate power, to transform */ 766 /* the given value from src to dst. They are assumed to be */ 767 /* in the range 0.0 .. 1.0 */ 768 double icx_powlike_needed(double src, double dst); 769 770 /* - - - - - - - - - - */ 771 772 /* Transfer function */ 773 double icxTransFunc( 774 double *v, /* Pointer to first parameter */ 775 int luord, /* Number of parameters */ 776 double vv /* Source of value */ 777 ); 778 779 /* Inverse Transfer function */ 780 double icxInvTransFunc( 781 double *v, /* Pointer to first parameter */ 782 int luord, /* Number of parameters */ 783 double vv /* Source of value */ 784 ); 785 786 /* Transfer function with scaling */ 787 double icxSTransFunc( 788 double *v, /* Pointer to first parameter */ 789 int luord, /* Number of parameters */ 790 double vv, /* Source of value */ 791 double min, /* Scale values */ 792 double max 793 ); 794 795 /* Inverse Transfer function with scaling */ 796 double icxInvSTransFunc( 797 double *v, /* Pointer to first parameter */ 798 int luord, /* Number of parameters */ 799 double vv, /* Source of value */ 800 double min, /* Scale values */ 801 double max 802 ); 803 804 /* Transfer function with partial derivative */ 805 /* with respect to the parameters. */ 806 double icxdpTransFunc( 807 double *v, /* Pointer to first parameter */ 808 double *dv, /* Return derivative wrt each parameter [luord] */ 809 int luord, /* Number of parameters */ 810 double vv /* Source of value */ 811 ); 812 813 /* Transfer function with scaling and */ 814 /* partial derivative with respect to the parameters. */ 815 double icxdpSTransFunc( 816 double *v, /* Pointer to first parameter */ 817 double *dv, /* Return derivative wrt each parameter [luord] */ 818 int luord, /* Number of parameters */ 819 double vv, /* Source of value */ 820 double min, /* Scale values */ 821 double max 822 ); 823 824 /* Transfer function with partial derivative */ 825 /* with respect to the input value. */ 826 double icxdiTransFunc( 827 double *v, /* Pointer to first parameter */ 828 double *pdv, /* Return derivative wrt source value [1] */ 829 int luord, /* Number of parameters */ 830 double vv /* Source of value */ 831 ); 832 833 /* Transfer function with scaling and */ 834 /* partial derivative with respect to the input value. */ 835 double icxdiSTransFunc( 836 double *v, /* Pointer to first parameter */ 837 double *pdv, /* Return derivative wrt source value [1] */ 838 int luord, /* Number of parameters */ 839 double vv, /* Source of value */ 840 double min, /* Scale values */ 841 double max 842 ); 843 844 /* Transfer function with partial derivative */ 845 /* with respect to the parameters and the input value. */ 846 double icxdpdiTransFunc( 847 double *v, /* Pointer to first parameter */ 848 double *dv, /* Return derivative wrt each parameter [luord] */ 849 double *pdin, /* Return derivative wrt source value [1] */ 850 int luord, /* Number of parameters */ 851 double vv /* Source of value */ 852 ); 853 854 /* Transfer function with scaling and */ 855 /* partial derivative with respect to the */ 856 /* parameters and the input value. */ 857 double icxdpdiSTransFunc( 858 double *v, /* Pointer to first parameter */ 859 double *dv, /* Return derivative wrt each parameter [luord] */ 860 double *pdin, /* Return derivative wrt source value [1] */ 861 int luord, /* Number of parameters */ 862 double vv, /* Source of value */ 863 double min, /* Scale values */ 864 double max 865 ); 866 867 /* Should add/move the spectro/moncurve stuff in here, */ 868 /* since it has offset and scaling. */ 869 870 /* - - - - - - - - - - */ 871 /* Multi-plane interpolation - uses base + di slope values. */ 872 /* Parameters are assumed to be fdi groups of di + 1 parameters. */ 873 void icxPlaneInterp( 874 double *v, /* Pointer to first parameter [fdi * (di + 1)] */ 875 int fdi, /* Number of output channels */ 876 int di, /* Number of input channels */ 877 double *out, /* Resulting fdi values */ 878 double *in /* Input di values */ 879 ); 880 881 /* Matrix cube interpolation. with partial derivative */ 882 /* with respect to the input and parameters. */ 883 void icxdpdiPlaneInterp( 884 double *v, /* Pointer to first parameter value [fdi * (di + 1)] */ 885 double *dv, /* Return [1 + di] deriv. wrt each parameter v */ 886 double *din, /* Return [fdi * di] deriv. wrt each input value */ 887 int fdi, /* Number of output channels */ 888 int di, /* Number of input channels */ 889 double *out, /* Resulting fdi values */ 890 double *in /* Input di values */ 891 ); 892 893 /* - - - - - - - - - - */ 894 895 /* Matrix cube interpolation - interpolate between 2^di output corner values. */ 896 /* Parameters are assumed to be fdi groups of 2^di parameters. */ 897 void icxCubeInterp( 898 double *v, /* Pointer to first parameter */ 899 int fdi, /* Number of output channels */ 900 int di, /* Number of input channels */ 901 double *out, /* Resulting fdi values */ 902 double *in /* Input di values */ 903 ); 904 905 /* Matrix cube interpolation. with partial derivative */ 906 /* with respect to the input and parameters. */ 907 void icxdpdiCubeInterp( 908 double *v, /* Pointer to first parameter value */ 909 double *dv, /* Return [fdi * 2^di] deriv wrt each parameter v */ 910 double *din, /* Return [fdi * di] deriv wrt each input value */ 911 int fdi, /* Number of output channels */ 912 int di, /* Number of input channels */ 913 double *out, /* Resulting fdi values */ 914 double *in /* Input di values */ 915 ); 916 917 /* - - - - - - - - - - */ 918 919 /* 3x3 matrix in 1D array multiplication */ 920 void icxMulBy3x3Parm( 921 double out[3], /* Return input multiplied by matrix */ 922 double mat[9], /* Matrix organised in [slow][fast] order */ 923 double in[3] /* Input values */ 924 ); 925 926 /* 3x3 matrix in 1D array multiplication, with partial derivatives */ 927 /* with respect to just the input. */ 928 void icxdpdiiMulBy3x3Parm( 929 double out[3], /* Return input multiplied by matrix */ 930 double din[3][3], /* Return deriv for each [output] with respect to [input] */ 931 double mat[9], /* Matrix organised in [slow][fast] order */ 932 double in[3] /* Input values */ 933 ); 934 935 /* 3x3 matrix in 1D array multiplication, with partial derivatives */ 936 /* with respect to the input and parameters. */ 937 void icxdpdiMulBy3x3Parm( 938 double out[3], /* Return input multiplied by matrix */ 939 double dv[3][9], /* Return deriv for each [output] with respect to [param] */ 940 double din[3][3], /* Return deriv for each [output] with respect to [input] */ 941 double mat[9], /* Matrix organised in [slow][fast] order */ 942 double in[3] /* Input values */ 943 ); 944 945 /* - - - - - - - - - - */ 946 947 /* Cusp map - used for vector clipping in Lab like spaces */ 948 struct _icxCuspMap { 949 double Lmax[3]; /* Maximum L* value found */ 950 double Lmin[3]; /* Minimum L* value found */ 951 int res; /* Resolution of hue map */ 952 double *L; /* L* value of cusp at hue angle */ 953 double *C; /* C* value of cusp at hue angle */ 954 955 /* Expand cusp map with given point */ 956 void (*expand)(struct _icxCuspMap *p, double lab[3]); 957 958 /* Return the corresponding cusp location, given the source point */ 959 void (*getCusp)(struct _icxCuspMap *p,double cuspLCh[3], double srcLab[3]); 960 961 /* We're done with CuspMap */ 962 void (*del)(struct _icxCuspMap *p); 963 964 }; typedef struct _icxCuspMap icxCuspMap; 965 966 967 /* - - - - - - - - - - */ 968 969 #include "xcal.h" 970 971 #endif /* XICC_H */ 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007