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