293 lines
9.9 KiB
C
293 lines
9.9 KiB
C
#ifndef MPP_H
|
|
#define MPP_H
|
|
|
|
/*
|
|
* Argyll Color Management System
|
|
* Model Printer Profile object.
|
|
*
|
|
* Author: Graeme W. Gill
|
|
* Date: 24/2/2002
|
|
*
|
|
* Copyright 2002 Graeme W. Gill
|
|
* All rights reserved.
|
|
* This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
|
|
* see the License.txt file for licencing details.
|
|
*
|
|
*/
|
|
|
|
/* This version (based on mpp_x1) has n * 2^(n-1) shape params, */
|
|
/* used for linear interpolation of the shaping correction. */
|
|
|
|
/*
|
|
* This object provides a model based printer forward profile
|
|
* functionality, to support forward profiling and optimised
|
|
* separation of printing devices with more than 4 inks.
|
|
*/
|
|
|
|
/* ------------------------------------------------------------------------------ */
|
|
|
|
#define MPP_MXINKS 8 /* Would like to be ICX_MXINKS but need more dynamic allocation */
|
|
#define MPP_MXTCORD 20 /* Maximum shaper harmonic orders to use */
|
|
#define MPP_MXCCOMB (1 << MPP_MXINKS) /* Maximum number of primary combinations */
|
|
#define MPP_MXPARMS (MPP_MXINKS * MPP_MXTCORD + (MPP_MXINKS * MPP_MXCCOMB/2) + MPP_MXCCOMB)
|
|
/* Maximum total parameters for a band */
|
|
#define MPP_MXBANDS 61 /* Maximum number of spectral bands (enought for 10nm) */
|
|
|
|
/* A test patch value */
|
|
typedef struct {
|
|
/* public: */
|
|
double *nv; /* [MPP_MXINKS] Device values */
|
|
double *band; /* [3+MPP_MXBANDS]; Target XYZ & Spectral reflectance values */
|
|
|
|
/* private: */
|
|
double w; /* Weight for this pass */
|
|
double *lband; /* [3+MPP_MXBANDS]; L* scale Target XYZ & Spectral reflectance values */
|
|
double Lab[3]; /* Target Lab value */
|
|
double tpcnv, tpcnv1; /* Intermediate values for band oba without channel och */
|
|
double *tcnv; /* [MPP_MXINKS] Transfer curve corrected device values */
|
|
double *scnv; /* [MPP_MXINKS] Ideal shape correction values for device input */
|
|
double *pcnv; /* [MPP_MXCCOMB] Primary combination values (pre or post shape) */
|
|
double *fcnv; /* [MPP_MXINKS * MPP_MXCCOMB/2] shape interpolation weights for och */
|
|
double cXYZ[3]; /* Current model XYZ value */
|
|
double err; /* Delta E squared */
|
|
} mppcol;
|
|
|
|
struct _mpp {
|
|
|
|
/* Public: */
|
|
int version; /* 1 */
|
|
|
|
void (*del)(struct _mpp *p);
|
|
|
|
|
|
/* Create the mpp from scattered data points */
|
|
/* Returns nz on error */
|
|
int (*create) (struct _mpp *p,
|
|
int verb, /* Vebosity level, 0 = none */
|
|
int quality, /* Profile quality, 0..3 */
|
|
int display, /* non-zero if display device */
|
|
double limit, /* Total ink limit (not %) (if not display) */
|
|
inkmask imask, /* Inkmask describing device colorspace */
|
|
int spec_n, /* Number of spectral bands, 0 if not valid */
|
|
double spec_wl_short, /* First reading wavelength in nm (shortest) */
|
|
double spec_wl_long, /* Last reading wavelength in nm (longest) */
|
|
double norm, /* Normalising scale value */
|
|
instType itype, /* Spectral instrument type (if not display) */
|
|
int no, /* Number of points */
|
|
mppcol *points); /* Array of input points */
|
|
|
|
int (*write_mpp)(struct _mpp *p, char *filename, int lab); /* write to a CGATS .mpp file */
|
|
int (*read_mpp)(struct _mpp *p, char *filename); /* read from a CGATS .mpp file */
|
|
|
|
/* Get various types of information about the mpp */
|
|
void (*get_info) (struct _mpp *p,
|
|
inkmask *imask, /* Inkmask, describing device colorspace */
|
|
int *nodchan, /* Number of device channels */
|
|
double *limit, /* Total ink limit (0.0 .. devchan) */
|
|
int *spec_n, /* Number of spectral bands, 0 if none */
|
|
double *spec_wl_short,/* First reading wavelength in nm (shortest) */
|
|
double *spec_wl_long, /* Last reading wavelength in nm (longest) */
|
|
instType *itype, /* Instrument type */
|
|
int *display); /* NZ if display type */
|
|
|
|
/* Set an illuminant and observer to use spectral model */
|
|
/* for CIE lookup with optional FWA. Set both to default for XYZ mpp model. */
|
|
/* Return 0 on OK, 1 on spectral not supported */
|
|
/* If the model is for a display, the illuminant will be ignored. */
|
|
int (*set_ilob) (struct _mpp *p,
|
|
icxIllumeType ilType, /* Illuminant type (icxIT_default for none) */
|
|
xspect *custIllum, /* Custom illuminant (NULL for none) */
|
|
icxObserverType obType, /* Observer type (icxOT_default for none) */
|
|
xspect custObserver[3], /* Custom observer (NULL for none) */
|
|
icColorSpaceSignature rcs, /* Return color space, icSigXYZData or icSigLabData */
|
|
int use_fwa /* NZ to involke FWA. */
|
|
);
|
|
|
|
/* Get the white and black points for this profile (default XYZ) */
|
|
void (*get_wb) (struct _mpp *p,
|
|
double *white,
|
|
double *black,
|
|
double *kblack);
|
|
|
|
|
|
/* Lookup an XYZ or Lab color (default XYZ) */
|
|
/* [will use spectral and FWA if configured] */
|
|
void (*lookup) (struct _mpp *p,
|
|
double *out, /* Returned XYZ or Lab */
|
|
double *in); /* Input device values */
|
|
|
|
/* Lookup an XYZ or Lab color with its partial derivative. */
|
|
/* [will ignore spectral and FWA even if configured] */
|
|
void (*dlookup)(struct _mpp *p,
|
|
double *out, /* Return the XYZ or Lab */
|
|
double **dout, /* Return the partial derivative dout[3][n] */
|
|
double *dev);
|
|
|
|
/* Lookup an XYZ value. (never FWA corrected) */
|
|
void (*lookup_xyz) (struct _mpp *p,
|
|
double *out, /* Returned XYZ value */
|
|
double *in); /* Input device values */
|
|
|
|
/* Lookup a spectral value. (never FWA corrected) */
|
|
void (*lookup_spec) (struct _mpp *p,
|
|
xspect *out, /* Returned spectral value */
|
|
double *in); /* Input device values */
|
|
|
|
/* Return a gamut object, return NULL on error */
|
|
gamut *(*get_gamut)(struct _mpp *p, double detail); /* detail level 0.0 = default */
|
|
|
|
/* Private: */
|
|
int verb; /* Verbose */
|
|
|
|
/* General model information */
|
|
int display; /* Non-zero if display profile rather than output */
|
|
inkmask imask; /* Inkmask describing device space */
|
|
double limit; /* Total ink limit (If output device) */
|
|
int spec_n; /* Number of spectral bands, 0 if not valid */
|
|
double spec_wl_short; /* First reading wavelength in nm (shortest) */
|
|
double spec_wl_long; /* Last reading wavelength in nm (longest) */
|
|
double norm; /* Normalising scale value (will be 1.0) */
|
|
instType itype; /* Spectral instrument type (If output device) */
|
|
mppcol white, black; /* White and black points */
|
|
mppcol kblack; /* K only black point */
|
|
|
|
/* Foward model parameters */
|
|
int n; /* Number of chanels */
|
|
int nn; /* Number of primary combinations = 1 << n */
|
|
int nnn2; /* Total shape combinations (= no of pairs?) = n * nn/2 */
|
|
|
|
int cord; /* Device transfer curve order (must be 1 <= cord <= MPP_MXTCORD) */
|
|
double tc[MPP_MXINKS][3+MPP_MXBANDS][MPP_MXTCORD]; /* Device transfer curve parameters */
|
|
int useshape; /* Flag, NZ if shape parameters are being used */
|
|
double ***shape; /* [MPP_MXINKS][MPP_MXCCOMB][3+MPP_MXBANDS] Extra shaping parameters */
|
|
double pc[MPP_MXCCOMB][3+MPP_MXBANDS]; /* Primary overlay combinations color values */
|
|
|
|
/* Model housekeeping */
|
|
/* Translate sparse shape color combo to compacted parameters and back */
|
|
int f2c[MPP_MXINKS][MPP_MXCCOMB]; /* Full to Compact */
|
|
struct { int ink; int comb; } c2f[MPP_MXINKS * MPP_MXCCOMB/2]; /* Compact to Full */
|
|
|
|
/* Optimisation state */
|
|
mppcol *otp; /* Optimisation test point */
|
|
int oit, ott; /* Optimisation itteration and total itterations */
|
|
int och; /* Optimisation device channel 0..n-1 */
|
|
int oba; /* Optimisation band, 0..2 are XYZ, 3..spec_n+3 are spectral */
|
|
double lpca[MPP_MXCCOMB][MPP_MXBANDS]; /* Primary combinations anchor L* band values */
|
|
int nodp; /* Number of device data points */
|
|
mppcol *cols; /* List of test points */
|
|
double spmax; /* Maximum spectral value of any sample and band */
|
|
|
|
/* Lookup */
|
|
icColorSpaceSignature pcs; /* PCS to return, XYZ, Lab */
|
|
xsp2cie *spc; /* Spectral to CIE converter (NULL if using XYZ model) */
|
|
|
|
/* Houskeeping */
|
|
icmErr e; /* Error code & message */
|
|
|
|
}; typedef struct _mpp mpp;
|
|
|
|
/* Create a new, uninitialised mpp */
|
|
mpp *new_mpp(void);
|
|
|
|
|
|
/* - - - - - - - - - - - - - */
|
|
/* mppcol utility functions */
|
|
/* Allocate the data portion of an mppcol */
|
|
/* Return NZ if malloc error */
|
|
int new_mppcol(
|
|
mppcol *p, /* mppcol to allocate */
|
|
int n, /* Number of inks */
|
|
int nb /* Number of spectral bands */
|
|
);
|
|
|
|
/* Free the data allocation of an mppcol */
|
|
void del_mppcol(
|
|
mppcol *p, /* mppcol to free */
|
|
int n, /* Number of inks */
|
|
int nb /* Number of spectral bands */
|
|
);
|
|
|
|
/* Copy the contents of one mppcol to another */
|
|
void copy_mppcol(
|
|
mppcol *d, /* Destination */
|
|
mppcol *s, /* Source */
|
|
int n, /* Number of inks */
|
|
int nb /* Number of spectral bands */
|
|
);
|
|
|
|
/* Allocate an array of mppcol, */
|
|
/* Return NULL if malloc error */
|
|
mppcol *new_mppcols(
|
|
int no, /* Number in array */
|
|
int n, /* Number of inks */
|
|
int nb /* Number of spectral bands */
|
|
);
|
|
|
|
/* Free an array of mppcol */
|
|
void del_mppcols(
|
|
mppcol *p, /* mppcol array to be free'd */
|
|
int no, /* Number in array */
|
|
int n, /* Number of inks */
|
|
int nb /* Number of spectral bands */
|
|
);
|
|
|
|
/* ================================ */
|
|
|
|
#ifdef COMMPLUS /* Commercial+ */
|
|
|
|
/* A channel change */
|
|
typedef struct {
|
|
inkmask im; /* Identity of ink */
|
|
int add; /* nz to add, z to delete */
|
|
xspect sp; /* If not NULL, spectra of colorant to add */
|
|
double Lab[3]; /* or if L > 0.0, L*a*b* of colorant to add */
|
|
double mix[MPP_MXINKS]; /* or mix of input profile colorants (can be < 0.0 and > 1.0) */
|
|
} mppchch;
|
|
|
|
/* Create a modified mpp */
|
|
mpp *mpp_modify(
|
|
mppchch *chl, /* List of changes */
|
|
int nil, /* Number in list */
|
|
mpp *p /* mpp2 to use as base */
|
|
);
|
|
|
|
#endif /* COMMPLUS Commercial+ */
|
|
|
|
#endif /* MPP_H */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|