Files
2026-08-20 20:28:40 +01:00

1038 lines
43 KiB
C

#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 icmLuSpace.
*/
#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 */
#ifdef COMMPLUS
#include "mpp2.h" /* model printer profile #2 support */
#endif
#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(): */
/* (The 'Abs' versions set the view conditions white point and flare to D50, */
/* to allow matching side-by side apperance.) */
/* 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);
/* ------------------------------------------------------------------------------ */
/* icx error codes */
#define ICX_ERR_OK 0 /* No error */
#define ICX_ERR_MALLOC 0x10000 /* A malloc failed. (errm could be NULL) */
#define ICX_ERR_BAD_PCS 0x10001 /* set_icxLuMatrix got PCS != XYZ */
#define ICX_ERR_BAD_DEV 0x10002 /* set_icxLuMatrix got dev != RGB or CMY */
#define ICX_ERR_NO_WP 0x10003 /* set_* couldn't find white point */
#define ICX_ERR_XFIT_FAIL 0x1000a /* set_* failed to create xfit object */
#define ICX_ERR_XFIT_FIT_FAIL 0x1000b /* set_* xfit fitting failed */
/* ------------------------------------------------------------------------------ */
/* 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. */
/* A selector for profile creation type */
typedef enum {
icxTCT_V2V2 = 0 /* V2 profile with V2 transforms */
} icxTransformCreateType;
/* 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; /* Dimensionality 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;
#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, loaded from ICC 'targ', NULL if none */
/* Public: */
void (*del)(struct _xicc *p);
/* If the given cal is not NULL, override or set the xicc cal. */
/* (This takes a reference) */
void (*set_cal_curves)(struct _xicc *p,
struct _xcal *cal
);
/* Return the currently set cal */
/* (It's up to the caller to take a reference if they need to) */
void (*get_cal_curves)(struct _xicc *p,
struct _xcal **cal
);
/* "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 e.c+e.m 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: 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_SINGLE_INTENT 0x08000000 /* Create A2B0 from scattered data rather than A2B1 */
//#define ICX_2PASSSMTH 0x10000000 /* If LuLut: Use Gaussian smoothing REMOVE */
//#define ICX_EXTRA_FIT 0x20000000 /* If LuLut: Counteract scat data point errors. REMOVE */
/* And ICX_VERBOSE Turn on verboseness during creation */
// int (*get_viewcond)(struct _xicc *p, icxViewCond *vc); /* Development code */
icmErr e; /* Error code & message */
}; 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);
/* ------------------------------------------------------------------------------ */
/*
int set_icxLuMono() goes here...
*/
/* Create icxLuMatrix and undelying tone reproduction curves and */
/* colorant tags from the supplied scattered data points. */
/* The scattered data is assumed to map Device -> native PCS (ie. dir = Fwd) */
/* Set error code and message in icco on error. */
/* Return the error code */
int set_icxLuMatrix(
icc *icco,
int flags, /* "create" flags */
icxTransformCreateType icctype, /* Profile creation type */
int nodp, /* Number of points */
int nodpbw, /* Number of points to look for white & black patches in */
cow *ipoints, /* Array of input points in XYZ space */
icxMatrixModel *skm, /* Optional skeleton model (not used here) */
double dispLuminance, /* > 0.0 if display luminance value and is known */
double wpscale, /* > 0.0 if input white point is to be scaled */
int quality, /* Quality metric, 0..3 */
double smooth, /* Curve smoothing, nominally 1.0 */
int isShTRC, /* Matrix - NZ if shared TRCs */
int isGamma, /* Matrix - NZ if gamma rather than shaper */
int isLinear, /* Matrix - NZ if pure linear, gamma = 1.0 */
int inputEnt, /* Num of in-table entries */
int inv_inputEnt /* Num of inverse in-table entries */
);
/* Create icxLuLut and underlying fwd Lut from scattered data */
/* The scattered data is assumed to map Device -> native PCS */
int set_icxLuLut(
icc *icco,
int flags, /* "create" ICX flags etc. */
icxTransformCreateType icctype, /* Profile creation type */
int nodp, /* Number of data points */
int nodpbw, /* Number of data points to look for white & black patches in */
cow *ipoints, /* Array of input points (Lab or XYZ normalized to 1.0) */
icxMatrixModel *skm, /* Optional skeleton model (used for input profiles) */
double dispLuminance, /* > 0.0 if display luminance value and is known */
double wpscale, /* > 0.0 if white point is to be scaled */
double smooth, /* RSPL smoothing factor, -ve if raw */
double avgdev, /* reading Average Deviation as a prop. of the input range */
double demph, /* dark emphasis factor for cLUT grid res. */
icxViewCond *vc, /* Viewing Condition (NULL if not using CAM) */
icxInk *ink, /* inking details (NULL for default) */
struct _xcal *cal, /* Optional cal (NULL for none) */
int quality, /* Quality metric, 0..3 */
int ires, /* Num of in-table entries */
int gres[MXDI], /* RSPL/CLUT resolution */
int ores /* Num of out-table entries */
);
/* ------------------------------------------------------------------------------ */
/* What type of icxLu we are */
typedef enum {
icxLuMonoType = 0,
icxLuMatrixType = 1, /* K is specified as output K target by PCS auxiliary */
icxLuLutType = 2 /* K is specified as output K target by PCS auxiliary */
} icxLuType;
# define XLU_XFIT_FLAGS
/* Expanded lookup object support */
#define XLU_BASE_MEMBERS \
/* Private: */ \
icxLuType lutype; /* Full type of object */ \
int trace; /* Optional run time tracing flag */ \
struct _xicc *pp; /* Pointer to XICC we're a part of */ \
icmLuSpace *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 */ \
XLU_XFIT_FLAGS \
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 e.c+e.m 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 e.c+e.m 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
int dir;
/* 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
int dir;
/* 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: */
rspl *clutTable; /* The multi dimension lookup */
rspl *cclutTable; /* Alternate multi dimension lookup in CAM space */
/* 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 */
/* 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 implemented 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 */
icmLuSpace *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 implemented 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);
}; 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 */
char *chartarget; /* CharTaret text, NULL for none */
/* 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;
/* 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 = use *as */
char *as, /* String alias to number, NULL if none */
int desc, /* NZ - Just return a description and index 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 from 'targ' tag .ti3 data. */
/* Return NULL on error or no cal */
struct _xcal *xiccReadCalTag(icc *p);
/* xiccCalCallback context */
typedef struct {
struct _xcal *cal;
} icxCalCBctx;
/* A callback that uses an xcal, that can be used with icc get_tac */
void xiccCalCallback(icxCalCBctx *cntx, double *out, double *in);
/* xiccCalCallback cast to void functiion */
#define xiccCalCallback_void ((void (*)(void *, double *, double *))xiccCalCallback)
/* Given an xicc icc profile, estmate the total ink limit and black ink limit. */
/* final raw limits are returned if cal tables are present in the 'targ' .ti3 */
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 final raw total ink limit and an xcal, return the */
/* equivalent linearized (underlying) total ink limit. */
/* This is the maximum equivalent, that makes sure that */
/* the final raw 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 */