221 lines
9.8 KiB
C
221 lines
9.8 KiB
C
/* ================================================= */
|
|
/* icmPe transform declarations */
|
|
/* This is #included in icc.h */
|
|
|
|
typedef enum { /* Lab version encoding */
|
|
icmEncV2 = 0, /* ICC V2 */
|
|
icmEncProf = 2 /* Same as icc header version */
|
|
} icmEncLabVer;
|
|
|
|
typedef enum { /* Lab version representation */
|
|
icmEncNbit = 0, /* 32 bit float or 16.16 */
|
|
icmEnc8bit = 1, /* 8 bit */
|
|
icmEnc16bit = 2 /* 16 bit */
|
|
} icmEncBytes;
|
|
|
|
/* Given a full range colorspace sig, return a default value ranges. */
|
|
/* Return NZ if range is not 0.0 - 1.0 */
|
|
int icmGetDefaultFullRange(
|
|
struct _icc *icp,
|
|
double *min, double *max, /* Return range */
|
|
icColorSpaceSignature sig /* Full range colorspace sig */
|
|
);
|
|
|
|
/* Clip the given PCS value to be within the 16 bit encodable range */
|
|
/* Return nz if clipped */
|
|
static int icmClipPCS16(
|
|
struct _icc *icp,
|
|
double out[3],
|
|
double in[3],
|
|
icColorSpaceSignature encSpace,
|
|
icmEncLabVer ver /* 0 = V2, 2 same as profile */
|
|
);
|
|
|
|
/* A structure for returning information about a colorspace */
|
|
typedef struct {
|
|
icColorSpaceSignature sig; /* Signature */
|
|
int nch; /* Number of channels */
|
|
double min[MAX_CHAN]; /* Nominal range of each channel */
|
|
double max[MAX_CHAN];
|
|
} icmCSInfo;
|
|
|
|
/* Lookup class members common to named and non-named color types */
|
|
#define LU4_ICM_BASE_MEMBERS(TCLASS) \
|
|
\
|
|
/* Private: */ \
|
|
icmLu4Type ttype; /* The type of object */ \
|
|
struct _icc *icp; /* Pointer to ICC we're a part of */ \
|
|
icTagSignature sourceTag; /* The transform source tag */ \
|
|
icRenderingIntent intent; /* Effective (externaly visible) intent */ \
|
|
icmLookupFunc function; /* Functionality being used */ \
|
|
icmLookupOrder order; /* Conversion representation search Order */ \
|
|
icmPeOp op; /* lookup op */ \
|
|
int can_bwd; /* nz if lookup_bwd will work */ \
|
|
icmXYZNumber pcswht; /* PCS White, i.e. D50 (abs. XYZ) */ \
|
|
icmXYZNumber whitePoint, blackPoint;/* Profile White and black point (abs. XYZ) */ \
|
|
int blackisassumed; /* nz if black point tag is missing from profile */ \
|
|
double toAbs[3][3]; /* Matrix to convert from relative to absolute */ \
|
|
double fromAbs[3][3]; /* Matrix to convert from absolute to relative */ \
|
|
icmCSInfo ini; /* Native Clr space of input info. */ \
|
|
icmCSInfo outi; /* Native Clr space of output info. */ \
|
|
icmCSInfo pcsi; /* Native PCS info. */ \
|
|
icmCSInfo e_ini; /* Effective Clr space of input info. */ \
|
|
icmCSInfo e_outi; /* Effective Clr space of output info. */ \
|
|
icmCSInfo e_pcsi; /* Effective PCS info. */ \
|
|
/* Hmm. Do we need in/out/e_ abs intent flags ? */ \
|
|
\
|
|
/* Public: */ \
|
|
\
|
|
void (*del)(TCLASS *p); \
|
|
\
|
|
/* Initialise the white and black points from the ICC tags, */ \
|
|
/* and the corresponding absolute<->relative conversion matrices. */ \
|
|
/* (Called on init, and after white & black set during creation.) */ \
|
|
/* Return nz on error */ \
|
|
\
|
|
int (*init_wh_bk)(TCLASS *p); \
|
|
\
|
|
/* External effecive colorspaces and other lookup information */ \
|
|
void (*spaces) (TCLASS *p, icmCSInfo *ini, icmCSInfo *outi, icmCSInfo *pcsi, \
|
|
icTagSignature *srctag, icRenderingIntent *intt, \
|
|
icmLookupFunc *fnc, icmLookupOrder *ord, \
|
|
icmPeOp *op, int *can_bwd); \
|
|
\
|
|
/* Internal native colorspaces: */ \
|
|
void (*native_spaces) (TCLASS *p, icmCSInfo *ini, icmCSInfo *outi, icmCSInfo *pcsi);\
|
|
\
|
|
/* Relative to Absolute for this WP in XYZ */ \
|
|
void (*XYZ_Rel2Abs)(TCLASS *p, double *xyzout, double *xyzin); \
|
|
\
|
|
/* Absolute to Relative for this WP in XYZ */ \
|
|
void (*XYZ_Abs2Rel)(TCLASS *p, double *xyzout, double *xyzin); \
|
|
|
|
|
|
/* Base lookup object */
|
|
struct _icmLu4Base {
|
|
LU4_ICM_BASE_MEMBERS(struct _icmLu4Base)
|
|
}; // typedef struct _icmLu4Base icmLu4Base;
|
|
|
|
|
|
/* Colorspace lookup class (not named color) */
|
|
struct _icmLu4Space {
|
|
LU4_ICM_BASE_MEMBERS(struct _icmLu4Space)
|
|
|
|
/* Private: */
|
|
|
|
/* Note that these icmPeContainers will all be flat - */
|
|
/* i.e. there will be no sub-icmPeSeq's, only icmPeInverter's */
|
|
|
|
/* single stage transform */
|
|
icmPeContainer *lookup; /* Overall transform */
|
|
|
|
/* 3 stage transforms */
|
|
icmPeContainer *input; /* Per channel pre-transforms */
|
|
icmPeContainer *core3; /* Core transform that may change no. channels */
|
|
icmPeContainer *output; /* Per channel post-transforms */
|
|
|
|
/* 5 stage transforms */
|
|
icmPeContainer *input_fmt; /* PCS and abs. conversion */
|
|
icmPeContainer *input_pch; /* Per channel pre-transforms */
|
|
icmPeContainer *core5; /* Core transform that may change no. channels */
|
|
icmPeContainer *output_pch; /* Per channel post-transforms */
|
|
icmPeContainer *output_fmt; /* PCS and abs. conversion */
|
|
/* Public: */
|
|
|
|
/* Get the LU PCS white, white and black points in absolute XYZ space. */
|
|
/* PCS will be the profile header PCS white point. */
|
|
/* Return nz if the black point is being assumed to be 0,0,0 rather */
|
|
/* than being from the tag. */
|
|
int (*wh_bk_points)(struct _icmLu4Space *p, double *pcs, double *wht, double *blk);
|
|
|
|
/* Get the LU PCS white, white and black points in LU PCS space, converted to XYZ. */
|
|
/* (ie. white and black will be relative if LU is relative intent etc.) */
|
|
/* Return nz if the black point is being assumed to be 0,0,0 rather */
|
|
/* than being from the tag. */
|
|
int (*lu_wh_bk_points)(struct _icmLu4Space *p, double *pcs, double *wht, double *blk);
|
|
|
|
/* Overall transforms */
|
|
icmPe_lurv (*lookup_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*lookup_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
|
|
/* 3 stage transforms are fmt&per-channel + core + per-channel&fmt: */
|
|
|
|
/* 3 stage components of fwd lookup */
|
|
icmPe_lurv (*input_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*core3_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*output_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
|
|
/* 3 stage cComponents of bwd lookup */
|
|
icmPe_lurv (*output_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*core3_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*input_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
|
|
|
|
/* 5 stage transforms are fmt + per-channel + core + per-channel + fmt: */
|
|
|
|
/* 5 stage sub-components of input_fwd and output_fwd lookup */
|
|
icmPe_lurv (*input_fmt_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*input_pch_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*core5_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*output_pch_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*output_fmt_fwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
|
|
/* 5 stage sub-components of input_bwd and output_bwd lookup */
|
|
icmPe_lurv (*output_fmt_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*output_pch_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*core5_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*input_pch_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
icmPe_lurv (*input_fmt_bwd) (struct _icmLu4Space *p, double *out, double *in);
|
|
|
|
/* Lookup information */
|
|
|
|
/* Find the largest per channel input lut resolution. */
|
|
/* res may be NULL */
|
|
/* Returns 0 if there is no per channel lut in the input sequence. */
|
|
unsigned int (*max_in_res)(struct _icmLu4Space *p, int res[MAX_CHAN]);
|
|
|
|
/* Find the largest cLUT clutPoints[] value. */
|
|
/* res may be NULL */
|
|
/* Returns 0 if there is no cLut transform in the sequence. */
|
|
unsigned int (*max_clut_res)(struct _icmLu4Space *p, int res[MAX_CHAN]);
|
|
|
|
/* Find the largest per channel output lut resolution. */
|
|
/* res may be NULL */
|
|
/* Returns 0 if there is no per channel lut in the output sequence. */
|
|
unsigned int (*max_out_res)(struct _icmLu4Space *p, int res[MAX_CHAN]);
|
|
|
|
/* Determine if the per channel input or output is likely to be */
|
|
/* in a linear light space. We do this by seeing if the first */
|
|
/* non-per channel or format element is a matrix or matrix like */
|
|
/* element, and if the PCS is XYZ. This is not totally reliable, but */
|
|
/* should work for simple matrix device profiles. */
|
|
/* Return nz if true */
|
|
/* dir should be 0 if for if we are interested in the input characteristic, */
|
|
/* and nz if we are interested in the output characteristic. */
|
|
/* (We assume that the icmPeContainer is flattened) */
|
|
int (*linear_light_inout)(struct _icmLu4Space *p, int dir);
|
|
|
|
/* Return a pointer to the last icmPeLut in the lookup_fwd and */
|
|
/* a Seq containing the transforms from the output of the Lut */
|
|
/* Return NULL if no icmPeLut */
|
|
/* Delete both objects when done */
|
|
icmPeClut *(*get_lut)(
|
|
struct _icmLu4Space *p,
|
|
icmPeContainer **ptail /* If not NULL return tail process, NULL if none */
|
|
);
|
|
|
|
/* Return total ink limit and channel maximums. */
|
|
/* return -1.0 if this lu doesn't have an icmPeClut in it. */
|
|
double (*get_tac)(
|
|
struct _icmLu4Space *p,
|
|
double *chmax, /* device return channel maximums. May be NULL */
|
|
void (*calfunc)(void *cntx, double *out, double *in), /* Optional calibration func. */
|
|
void *cntx
|
|
);
|
|
|
|
}; // typedef struct _icmLu4Space icmLu4Space;
|
|
|
|
/* Fake up alg from icmLu4 attributes */
|
|
icmLuAlgType icmSynthAlgType(icmLuBase *p);
|
|
|