#ifndef ICC_H #define ICC_H /* * International Color Consortium Format Library (icclib) * * Author: Graeme W. Gill * Date: 99/11/29 * Version: 2.01 * * Copyright 1997, 1998, 1999, 2000, 2001 Graeme W. Gill * Please refer to Licence.txt file for details. */ /* We can get some subtle errors if certain headers aren't included */ #include #include #include #include #include #include #include /* * Note XYZ scaling to 1.0, not 100.0 */ /* Make allowance for shared library use */ #ifdef ICCLIB_SHARED /* Compiling or Using shared library version */ # ifdef ICCLIB_EXPORTS /* Compiling shared library */ # ifdef NT # define ICCLIB_API __declspec(dllexport) # endif /* NT */ # else /* Using shared library */ # ifdef NT # define ICCLIB_API __declspec(dllimport) # ifdef ICCLIB_DEBUG # pragma comment (lib, "icclibd.lib") # else # pragma comment (lib, "icclib.lib") # endif /* DEBUG */ # endif /* NT */ # endif #else /* Using static library */ # define ICCLIB_API /* empty */ #endif #ifdef __cplusplus extern "C" { #endif /* ---------------------------------------------- */ /* Platform specific defines */ /* It is assumed that the native machine size is 32 bits */ #ifndef INR8 #define INR8 signed char /* 8 bit signed */ #endif #ifndef INR16 #define INR16 signed short /* 16 bit signed */ #endif #ifndef INR32 #define INR32 signed long /* 32 bit signed */ #endif #ifndef ORD8 #define ORD8 unsigned char /* 8 bit unsigned */ #endif #ifndef ORD16 #define ORD16 unsigned short /* 16 bit unsigned */ #endif #ifndef ORD32 #define ORD32 unsigned long /* 32 bit unsigned */ #endif #include "icc9809.h" /* Standard ICC definitions, version ICC.1:1998-09 with mods noted. */ /* Note that the prefix icm is used for the native Machine */ /* equivalents of the file structures defined in icc34.h */ /* ---------------------------------------------- */ /* System interface objects. The defaults can be replaced */ /* for adaption to different system environments */ /* File access class interface definition */ #define ICM_FILE_BASE \ /* Public: */ \ \ /* Set current position to offset. Return 0 on success, nz on failure. */ \ int (*seek) (struct _icmFile *p, long int offset); \ \ /* Read count items of size length. Return number of items successfully read. */ \ size_t (*read) (struct _icmFile *p, void *buffer, size_t size, size_t count); \ \ /* write count items of size length. Return number of items successfully written. */ \ size_t (*write)(struct _icmFile *p, void *buffer, size_t size, size_t count); \ \ /* flush all write data out to secondary storage. Return nz on failure. */ \ int (*flush)(struct _icmFile *p); \ \ /* we're done with the file object, return nz on failure */ \ int (*del)(struct _icmFile *p); \ /* Common file interface class */ struct _icmFile { ICM_FILE_BASE }; typedef struct _icmFile icmFile; /* - - - - - - - - - - - - - - - - - - - - - */ /* Implementation of file access class based on standard file I/O */ struct _icmFileStd { ICM_FILE_BASE /* Private: */ FILE *fp; int doclose; /* nz if free should close */ }; typedef struct _icmFileStd icmFileStd; /* Create given a file name */ icmFile *new_icmFileStd_name(char *name, char *mode); /* Create given a (binary) FILE* */ icmFile *new_icmFileStd_fp(FILE *fp); /* - - - - - - - - - - - - - - - - - - - - - */ /* Implementation of file access class based on a memory image */ struct _icmFileMem { ICM_FILE_BASE /* Private: */ unsigned char *start, *cur, *end; }; typedef struct _icmFileMem icmFileMem; /* Create a memory image file access class */ icmFile *new_icmFileMem(void *base, size_t length); /* - - - - - - - - - - - - - - - - - - - - - */ /* Heap allocator class interface definition */ #define ICM_ALLOC_BASE \ /* Public: */ \ \ void *(*malloc) (struct _icmAlloc *p, size_t size); \ void *(*calloc) (struct _icmAlloc *p, size_t num, size_t size); \ void *(*realloc)(struct _icmAlloc *p, void *ptr, size_t size); \ void (*free) (struct _icmAlloc *p, void *ptr); \ \ /* we're done with the allocator object */ \ void (*del)(struct _icmAlloc *p); \ /* Common heap allocator interface class */ struct _icmAlloc { ICM_ALLOC_BASE }; typedef struct _icmAlloc icmAlloc; /* - - - - - - - - - - - - - - - - - - - - - */ /* Implementation of heap class based on standard system malloc */ struct _icmAllocStd { ICM_ALLOC_BASE }; typedef struct _icmAllocStd icmAllocStd; /* Create a standard alloc object */ icmAlloc *new_icmAllocStd(void); /* --------------------------------- */ /* Assumed constants */ #define MAX_CHAN 15 /* Maximum number of color channels */ /* --------------------------------- */ /* tag and other compound structures */ typedef int icmSig; /* Otherwise un-enumerated 4 byte signature */ typedef struct { ORD32 l; /* High and low components of signed 64 bit */ INR32 h; } icmInt64; typedef struct { ORD32 l,h; /* High and low components of unsigned 64 bit */ } icmUint64; /* XYZ Number */ typedef struct { double X; double Y; double Z; } icmXYZNumber; /* Response 16 number */ typedef struct { double deviceValue; /* The device value in range 0.0 - 1.0 */ double measurement; /* The reading value */ } icmResponse16Number; /* * read and write method error codes: * 0 = sucess * 1 = file format/logistical error * 2 = system error */ #define ICM_BASE_MEMBERS \ /* Private: */ \ icTagTypeSignature ttype; /* The tag type signature */ \ struct _icc *icp; /* Pointer to ICC we're a part of */ \ int touched; /* Flag for write bookeeping */ \ int refcount; /* Reference count for sharing */ \ unsigned int (*get_size)(struct _icmBase *p); \ int (*read)(struct _icmBase *p, unsigned long len, unsigned long of); \ int (*write)(struct _icmBase *p, unsigned long of); \ void (*del)(struct _icmBase *p); \ \ /* Public: */ \ void (*dump)(struct _icmBase *p, FILE *op, int verb); \ int (*allocate)(struct _icmBase *p); /* Base tag element data object */ struct _icmBase { ICM_BASE_MEMBERS }; typedef struct _icmBase icmBase; /* UInt8 Array */ struct _icmUInt8Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ unsigned int *data; /* Pointer to array of data */ }; typedef struct _icmUInt8Array icmUInt8Array; /* uInt16 Array */ struct _icmUInt16Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ unsigned int *data; /* Pointer to array of data */ }; typedef struct _icmUInt16Array icmUInt16Array; /* uInt32 Array */ struct _icmUInt32Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ unsigned int *data; /* Pointer to array of data */ }; typedef struct _icmUInt32Array icmUInt32Array; /* UInt64 Array */ struct _icmUInt64Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ icmUint64 *data; /* Pointer to array of hight data */ }; typedef struct _icmUInt64Array icmUInt64Array; /* u16Fixed16 Array */ struct _icmU16Fixed16Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ double *data; /* Pointer to array of hight data */ }; typedef struct _icmU16Fixed16Array icmU16Fixed16Array; /* s15Fixed16 Array */ struct _icmS15Fixed16Array { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ double *data; /* Pointer to array of hight data */ }; typedef struct _icmS15Fixed16Array icmS15Fixed16Array; /* XYZ Array */ struct _icmXYZArray { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of the array */ icmXYZNumber *data; /* Pointer to array of data */ }; typedef struct _icmXYZArray icmXYZArray; /* Curve */ typedef enum { icmCurveUndef = -1, /* Undefined curve */ icmCurveLin = 0, /* Linear transfer curve */ icmCurveGamma = 1, /* Gamma power transfer curve */ icmCurveSpec = 2 /* Specified curve */ } icmCurveStyle; /* Curve reverse lookup information */ typedef struct { int inited; /* Flag */ double rmin, rmax; /* Range of reverse grid */ double qscale; /* Quantising scale factor */ long rsize; /* Number of reverse lists */ int **rlists; /* Array of list of fwd values that may contain output value */ /* Offset 0 = allocated size */ /* Offset 1 = next free index */ /* Offset 2 = first fwd index */ unsigned long size; /* Copy of forward table size */ double *data; /* Copy of forward table data */ } icmRevTable; struct _icmCurve { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ icmRevTable rt; /* Reverse table information */ /* Public: */ icmCurveStyle flag; /* Style of curve */ unsigned long size; /* Allocated and used size of the array */ double *data; /* Curve data scaled to range 0.0 - 1.0 */ /* or data[0] = gamma value */ /* Translate a value through the curve, return warning flags */ int (*lookup_fwd) (struct _icmCurve *p, double *out, double *in); /* Forwards */ int (*lookup_bwd) (struct _icmCurve *p, double *out, double *in); /* Backwards */ }; typedef struct _icmCurve icmCurve; /* Data */ typedef enum { icmDataUndef = -1, /* Undefined data curve */ icmDataASCII = 0, /* ASCII data curve */ icmDataBin = 1 /* Binary data */ } icmDataStyle; struct _icmData { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ icmDataStyle flag; /* Style of data */ unsigned long size; /* Allocated and used size of the array (inc ascii null) */ unsigned char *data; /* data or string, NULL if size == 0 */ }; typedef struct _icmData icmData; /* text */ struct _icmText { ICM_BASE_MEMBERS /* Private: */ unsigned int _size; /* Size currently allocated */ /* Public: */ unsigned long size; /* Allocated and used size of desc, inc null */ char *data; /* ascii string (null terminated), NULL if size==0 */ }; typedef struct _icmText icmText; /* The base date time number */ struct _icmDateTimeNumber { ICM_BASE_MEMBERS /* Public: */ unsigned int year; unsigned int month; unsigned int day; unsigned int hours; unsigned int minutes; unsigned int seconds; }; typedef struct _icmDateTimeNumber icmDateTimeNumber; #ifdef NEW / * DeviceSettings */ /* I think this all works like this: Valid setting = ( (platform == platform1 and platform1.valid) or (platform == platform2 and platform2.valid) or ... ) where platformN.valid = ( platformN.combination1.valid or platformN.combination2.valid or ... ) where platformN.combinationM.valid = ( platformN.combinationM.settingstruct1.valid and platformN.combinationM.settingstruct2.valid and ... ) where platformN.combinationM.settingstructP.valid = ( platformN.combinationM.settingstructP.setting1.valid or platformN.combinationM.settingstructP.setting2.valid or ... ) */ /* The Settings Structure holds an array of settings of a particular type */ struct _icmSettingStruct { ICM_BASE_MEMBERS /* Private: */ unsigned int _num; /* Size currently allocated */ /* Public: */ icSettingsSig settingSig; /* Setting identification */ unsigned long numSettings; /* number of setting values */ union { /* Setting values - type depends on Sig */ icUInt64Number *resolution; icDeviceMedia *media; icDeviceDither *halftone; } }; typedef struct _icmSettingStruct icmSettingStruct; /* A Setting Combination holds all arrays of different setting types */ struct _icmSettingComb { /* Private: */ unsigned int _num; /* number currently allocated */ /* Public: */ unsigned long numStructs; /* num of setting structures */ icmSettingStruct *data; }; typedef struct _icmSettingComb icmSettingComb; /* A Platform Entry holds all setting combinations */ struct _icmPlatformEntry { /* Private: */ unsigned int _num; /* number currently allocated */ /* Public: */ icPlatformSignature platform; unsigned long numCombinations; /* num of settings and allocated array size */ icmSettingComb *data; }; typedef struct _icmPlatformEntry icmPlatformEntry; /* The Device Settings holds all platform settings */ struct _icmDeviceSettings { /* Private: */ unsigned int _num; /* number currently allocated */ /* Public: */ unsigned long numPlatforms; /* num of platforms and allocated array size */ icmPlatformEntry *data; /* Array of pointers to platform entry data */ }; typedef struct _icmDeviceSettings icmDeviceSettings; #endif /* NEW */ /* lut */ struct _icmLut { ICM_BASE_MEMBERS /* Private: */ /* Cache appropriate normalization routines */ int dinc[MAX_CHAN]; /* Dimensional increment through clut */ int dcube[1 << MAX_CHAN]; /* Hyper cube offsets */ icmRevTable rit; /* Reverse input table information */ icmRevTable rot; /* Reverse output table information */ unsigned int inputTable_size; /* size allocated to input table */ unsigned int clutTable_size; /* size allocated to clut table */ unsigned int outputTable_size; /* size allocated to output table */ /* return the minimum and maximum values of the given channel in the clut */ void (*min_max) (struct _icmLut *pp, double *minv, double *maxv, int chan); /* Translate color values through 3x3 matrix, input tables only, multi-dimensional lut, */ /* or output tables, */ int (*lookup_matrix) (struct _icmLut *pp, double *out, double *in); int (*lookup_input) (struct _icmLut *pp, double *out, double *in); int (*lookup_clut_nl) (struct _icmLut *pp, double *out, double *in); int (*lookup_clut_sx) (struct _icmLut *pp, double *out, double *in); int (*lookup_output) (struct _icmLut *pp, double *out, double *in); /* Public: */ /* return non zero if matrix is non-unity */ int (*nu_matrix) (struct _icmLut *pp); unsigned int inputChan; /* Num of input channels */ unsigned int outputChan; /* Num of output channels */ unsigned int clutPoints; /* Num of grid points */ unsigned int inputEnt; /* Num of in-table entries (must be 256 for Lut8) */ unsigned int outputEnt; /* Num of out-table entries (must be 256 for Lut8) */ double e[3][3]; /* 3 * 3 array */ double *inputTable; /* The in-table: [inputChan * inputEnt] */ double *clutTable; /* The clut: [(clutPoints ^ inputChan) * outputChan] */ double *outputTable; /* The out-table: [outputChan * outputEnt] */ /* inputTable is organized [inputChan 0..ic-1][inputEnt 0..ie-1] */ /* clutTable is organized [inputChan 0, 0..cp-1]..[inputChan ic-1, 0..cp-1] [outputChan 0..oc-1] */ /* outputTable is organized [outputChan 0..oc-1][outputEnt 0..oe-1] */ /* Helper function to setup the three tables contents */ int (*set_tables) ( struct _icmLut *p, /* Pointer to Lut 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 *in), /* inspace' -> outspace' transfer 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) */ }; typedef struct _icmLut icmLut; /* Measurement Data */ struct _icmMeasurement { ICM_BASE_MEMBERS /* Public: */ icStandardObserver observer; /* Standard observer */ icmXYZNumber backing; /* XYZ for backing */ icMeasurementGeometry geometry; /* Meas. geometry */ double flare; /* Measurement flare */ icIlluminant illuminant; /* Illuminant */ }; typedef struct _icmMeasurement icmMeasurement; /* Named color */ /* Structure that holds each named color data */ typedef struct { struct _icc *icp; /* Pointer to ICC we're a part of */ char root[32]; /* Root name for color */ double pcsCoords[3]; /* icmNC2: PCS coords of color */ double deviceCoords[MAX_CHAN]; /* Dev coords of color */ } icmNamedColorVal; struct _icmNamedColor { ICM_BASE_MEMBERS /* Private: */ unsigned int _count; /* Count currently allocated */ /* Public: */ unsigned int vendorFlag; /* Bottom 16 bits for IC use */ unsigned int count; /* Count of named colors */ unsigned int nDeviceCoords; /* Num of device coordinates */ char prefix[32]; /* Prefix for each color name (null terminated) */ char suffix[32]; /* Suffix for each color name (null terminated) */ icmNamedColorVal *data; /* Array of [count] color values */ }; typedef struct _icmNamedColor icmNamedColor; /* textDescription */ struct _icmTextDescription { ICM_BASE_MEMBERS /* Private: */ unsigned long _size; /* Size currently allocated */ unsigned long uc_size; /* uc Size currently allocated */ int (*core_read)(struct _icmTextDescription *p, char **bpp, char *end); int (*core_write)(struct _icmTextDescription *p, char **bpp); /* Public: */ unsigned long size; /* Allocated and used size of desc, inc null */ char *desc; /* ascii string (null terminated) */ unsigned int ucLangCode; /* UniCode language code */ unsigned long ucSize; /* Allocated and used size of ucDesc in wchars, inc null */ ORD16 *ucDesc; /* The UniCode description (null terminated) */ ORD16 scCode; /* ScriptCode code */ unsigned long scSize; /* Used size of scDesc in bytes, inc null */ ORD8 scDesc[67]; /* ScriptCode Description (null terminated, max 67) */ }; typedef struct _icmTextDescription icmTextDescription; /* Profile sequence structure */ struct _icmDescStruct { /* Private: */ struct _icc *icp; /* Pointer to ICC we're a part of */ /* Public: */ int (*allocate)(struct _icmDescStruct *p); /* Allocate method */ icmSig deviceMfg; /* Dev Manufacturer */ unsigned int deviceModel; /* Dev Model */ icmUint64 attributes; /* Dev attributes */ icTechnologySignature technology; /* Technology sig */ icmTextDescription device; /* Manufacturer text (sub structure) */ icmTextDescription model; /* Model text (sub structure) */ }; typedef struct _icmDescStruct icmDescStruct; /* Profile sequence description */ struct _icmProfileSequenceDesc { ICM_BASE_MEMBERS /* Private: */ unsigned int _count; /* number currently allocated */ /* Public: */ unsigned int count; /* Number of descriptions */ icmDescStruct *data; /* array of [count] descriptions */ }; typedef struct _icmProfileSequenceDesc icmProfileSequenceDesc; /* signature (only ever used for technology ??) */ struct _icmSignature { ICM_BASE_MEMBERS /* Public: */ icTechnologySignature sig; /* Signature */ }; typedef struct _icmSignature icmSignature; /* Per channel Screening Data */ typedef struct { /* Public: */ double frequency; /* Frequency */ double angle; /* Screen angle */ icSpotShape spotShape; /* Spot Shape encodings below */ } icmScreeningData; struct _icmScreening { ICM_BASE_MEMBERS /* Private: */ unsigned int _channels; /* number currently allocated */ /* Public: */ unsigned int screeningFlag; /* Screening flag */ unsigned int channels; /* Number of channels */ icmScreeningData *data; /* Array of screening data */ }; typedef struct _icmScreening icmScreening; /* Under color removal, black generation */ struct _icmUcrBg { ICM_BASE_MEMBERS /* Private: */ unsigned int UCR_count; /* Currently allocated UCR count */ unsigned int BG_count; /* Currently allocated BG count */ unsigned long _size; /* Currently allocated string size */ /* Public: */ unsigned int UCRcount; /* Undercolor Removal Curve length */ double *UCRcurve; /* The array of UCR curve values, 0.0 - 1.0 */ /* or 0.0 - 100 % if count = 1 */ unsigned int BGcount; /* Black generation Curve length */ double *BGcurve; /* The array of BG curve values, 0.0 - 1.0 */ /* or 0.0 - 100 % if count = 1 */ unsigned long size; /* Allocated and used size of desc, inc null */ char *string; /* UcrBg description (null terminated) */ }; typedef struct _icmUcrBg icmUcrBg; /* viewingConditionsType */ struct _icmViewingConditions { ICM_BASE_MEMBERS /* Public: */ icmXYZNumber illuminant; /* In candelas per sq. meter */ icmXYZNumber surround; /* In candelas per sq. meter */ icIlluminant stdIlluminant; /* See icIlluminant defines */ }; typedef struct _icmViewingConditions icmViewingConditions; /* Postscript Color Rendering Dictionary names type */ struct _icmCrdInfo { ICM_BASE_MEMBERS /* Private: */ unsigned long _ppsize; /* Currently allocated size */ unsigned long _crdsize[4]; /* Currently allocated sizes */ /* Public: */ unsigned long ppsize; /* Postscript product name size (including null) */ char *ppname; /* Postscript product name (null terminated) */ unsigned long crdsize[4]; /* Rendering intent 0-3 CRD names sizes (icluding null) */ char *crdname[4]; /* Rendering intent 0-3 CRD names (null terminated) */ }; typedef struct _icmCrdInfo icmCrdInfo; /* Apple ColorSync 2.5 video card gamma type */ struct _icmVideoCardGammaTable { unsigned short channels; /* # of gamma channels (1 or 3) */ unsigned short entryCount; /* 1-based number of entries per channel */ unsigned short entrySize; /* size in bytes of each entry */ void *data; /* variable size data */ }; typedef struct _icmVideoCardGammaTable icmVideoCardGammaTable; struct _icmVideoCardGammaFormula { double redGamma; /* must be > 0.0 */ double redMin; /* must be > 0.0 and < 1.0 */ double redMax; /* must be > 0.0 and < 1.0 */ double greenGamma; /* must be > 0.0 */ double greenMin; /* must be > 0.0 and < 1.0 */ double greenMax; /* must be > 0.0 and < 1.0 */ double blueGamma; /* must be > 0.0 */ double blueMin; /* must be > 0.0 and < 1.0 */ double blueMax; /* must be > 0.0 and < 1.0 */ }; typedef struct _icmVideoCardGammaFormula icmVideoCardGammaFormula; enum { icmVideoCardGammaTableType = 0, icmVideoCardGammaFormulaType = 1 }; struct _icmVideoCardGamma { ICM_BASE_MEMBERS unsigned long tagType; /* eg. table or formula, use above enum */ union { icmVideoCardGammaTable table; icmVideoCardGammaFormula formula; } u; }; typedef struct _icmVideoCardGamma icmVideoCardGamma; /* ------------------------------------------------- */ /* The Profile header */ struct _icmHeader { /* Private: */ unsigned int (*get_size)(struct _icmHeader *p); int (*read)(struct _icmHeader *p, unsigned long len, unsigned long of); int (*write)(struct _icmHeader *p, unsigned long of); void (*del)(struct _icmHeader *p); struct _icc *icp; /* Pointer to ICC we're a part of */ unsigned int size; /* Profile size in bytes */ /* public: */ void (*dump)(struct _icmHeader *p, FILE *op, int verb); /* Values that must be set before writing */ icProfileClassSignature deviceClass; /* Type of profile */ icColorSpaceSignature colorSpace; /* Clr space of data */ icColorSpaceSignature pcs; /* PCS: XYZ or Lab */ icRenderingIntent renderingIntent;/* Rendering intent */ /* Values that should be set before writing */ icmSig manufacturer; /* Dev manufacturer */ icmSig model; /* Dev model */ icmUint64 attributes; /* Device attributes.l */ unsigned int flags; /* Various bits */ /* Values that may optionally be set before writing */ /* icmUint64 attributes; Device attributes.h (see above) */ icmSig creator; /* Profile creator */ /* Values that are not normally set, since they have defaults */ icmSig cmmId; /* CMM for profile */ int majv, minv, bfv;/* Format version - major, minor, bug fix */ icmDateTimeNumber date; /* Creation Date */ icPlatformSignature platform; /* Primary Platform */ icmXYZNumber illuminant; /* Profile illuminant */ }; typedef struct _icmHeader icmHeader; /* ---------------------------------------------------------- */ /* Objects for accessing lookup functions */ /* Public: Parameter to get_luobj function */ typedef enum { icmFwd = 0, /* Device to PCS, or Device 1 to Last Device */ icmBwd = 1, /* PCS to Device, or Last Device to Device */ icmGamut = 2, /* PCS Gamut check */ icmPreview = 3 /* PCS to PCS preview */ } icmLookupFunc; /* Public: Parameter to get_luobj function */ typedef enum { icmLuOrdNorm = 0, /* Normal profile preference: Lut, matrix, monochrome */ icmLuOrdRev = 1 /* Reverse profile preference: monochrome, matrix, monochrome */ } icmLookupOrder; /* Public: Lookup algorithm object type */ typedef enum { icmMonoFwdType = 0, /* Monochrome, Forward */ icmMonoBwdType = 1, /* Monochrome, Backward */ icmMatrixFwdType = 2, /* Matrix, Forward */ icmMatrixBwdType = 3, /* Matrix, Backward */ icmLutType = 4 /* Multi-dimensional Lookup Table */ } icmLuAlgType; #define LU_ICM_BASE_MEMBERS \ /* Private: */ \ icmLuAlgType ttype; /* The object tag */ \ struct _icc *icp; /* Pointer to ICC we're a part of */ \ icRenderingIntent intent; /* Effective intent */ \ icmLookupFunc function; /* Functionality being used */ \ icmXYZNumber pcswht, whitePoint, blackPoint; /* White and black point info */ \ double toAbs[3][3]; /* Matrix to convert from relative to absolute */ \ double fromAbs[3][3]; /* Matrix to convert from absolute to relative */ \ icColorSpaceSignature inSpace; /* Native Clr space of input */ \ icColorSpaceSignature outSpace; /* Native Clr space of output */ \ icColorSpaceSignature pcs; /* Native PCS */ \ icColorSpaceSignature e_inSpace; /* Effective Clr space of input */ \ icColorSpaceSignature e_outSpace; /* Effective Clr space of output */ \ icColorSpaceSignature e_pcs; /* Effective PCS */ \ \ /* Public: */ \ void (*del)(struct _icmLuBase *p); \ /* Internal native colorspaces */ \ void (*lutspaces) (struct _icmLuBase *p, icColorSpaceSignature *ins, int *inn, \ icColorSpaceSignature *outs, int *outn); \ \ /* External effecive colorspaces */ \ void (*spaces) (struct _icmLuBase *p, icColorSpaceSignature *ins, int *inn, \ icColorSpaceSignature *outs, int *outn, \ icmLuAlgType *alg, icRenderingIntent *intt, \ icmLookupFunc *fnc, icColorSpaceSignature *pcs); \ \ /* Get the effective input space and output space ranges */ \ void (*get_ranges) (struct _icmLuBase *p, \ double *inmin, double *inmax, /* Maximum range of inspace values */ \ double *outmin, double *outmax); /* Maximum range of outspace values */ \ \ void (*wh_bk_points)(struct _icmLuBase *p, icmXYZNumber *wht, icmXYZNumber *blk); \ int (*lookup) (struct _icmLuBase *p, double *out, double *in); /* Translate color values through profile */ /* 0 = success */ /* 1 = warning: clipping occured */ /* 2 = fatal: other error */ /* Base lookup object */ struct _icmLuBase { LU_ICM_BASE_MEMBERS }; typedef struct _icmLuBase icmLuBase; /* Monochrome Fwd & Bwd type object */ struct _icmLuMono { LU_ICM_BASE_MEMBERS icmCurve *grayCurve; /* Overall lookups */ int (*fwd_lookup) (struct _icmLuBase *p, double *out, double *in); int (*bwd_lookup) (struct _icmLuBase *p, double *out, double *in); /* Components of lookup */ int (*fwd_curve) (struct _icmLuMono *p, double *out, double *in); int (*fwd_map) (struct _icmLuMono *p, double *out, double *in); int (*fwd_abs) (struct _icmLuMono *p, double *out, double *in); int (*bwd_abs) (struct _icmLuMono *p, double *out, double *in); int (*bwd_map) (struct _icmLuMono *p, double *out, double *in); int (*bwd_curve) (struct _icmLuMono *p, double *out, double *in); }; typedef struct _icmLuMono icmLuMono; /* 3D Matrix Fwd & Bwd type object */ struct _icmLuMatrix { LU_ICM_BASE_MEMBERS icmCurve *redCurve, *greenCurve, *blueCurve; icmXYZArray *redColrnt, *greenColrnt, *blueColrnt; double mx[3][3]; /* 3 * 3 conversion matrix */ double bmx[3][3]; /* 3 * 3 backwards conversion matrix */ /* Overall lookups */ int (*fwd_lookup) (struct _icmLuBase *p, double *out, double *in); int (*bwd_lookup) (struct _icmLuBase *p, double *out, double *in); /* Components of lookup */ int (*fwd_curve) (struct _icmLuMatrix *p, double *out, double *in); int (*fwd_matrix) (struct _icmLuMatrix *p, double *out, double *in); int (*fwd_abs) (struct _icmLuMatrix *p, double *out, double *in); int (*bwd_abs) (struct _icmLuMatrix *p, double *out, double *in); int (*bwd_matrix) (struct _icmLuMatrix *p, double *out, double *in); int (*bwd_curve) (struct _icmLuMatrix *p, double *out, double *in); }; typedef struct _icmLuMatrix icmLuMatrix; /* Multi-D. Lut type object */ struct _icmLuLut { LU_ICM_BASE_MEMBERS /* private: */ icmLut *lut; /* Lut to use */ int usematrix; /* non-zero if matrix should be used */ double imx[3][3]; /* 3 * 3 inverse conversion matrix */ int imx_valid; /* Inverse matrix is valid */ void (*in_normf)(double *out, double *in); /* Lut input data normalizing function */ void (*in_denormf)(double *out, double *in);/* Lut input data de-normalizing function */ void (*out_normf)(double *out, double *in); /* Lut output data normalizing function */ void (*out_denormf)(double *out, double *in);/* Lut output de-normalizing function */ void (*e_in_denormf)(double *out, double *in);/* Effective input de-normalizing function */ void (*e_out_denormf)(double *out, double *in);/* Effecive output de-normalizing function */ /* function chosen out of lut->lookup_clut_sx and lut->lookup_clut_nl to imp. clut() */ int (*lookup_clut) (struct _icmLut *pp, double *out, double *in); /* clut function */ /* public: */ /* Components of lookup */ int (*in_abs) (struct _icmLuLut *p, double *out, double *in); /* Should be in icmLut ? */ int (*matrix) (struct _icmLuLut *p, double *out, double *in); int (*input) (struct _icmLuLut *p, double *out, double *in); int (*clut) (struct _icmLuLut *p, double *out, double *in); int (*output) (struct _icmLuLut *p, double *out, double *in); int (*out_abs) (struct _icmLuLut *p, double *out, double *in); /* Should be in icmLut ? */ /* Some inverse components */ /* Should be in icmLut ??? */ int (*inv_out_abs) (struct _icmLuLut *p, double *out, double *in); int (*inv_output) (struct _icmLuLut *p, double *out, double *in); /* inv_clut is beyond scope of icclib. See argyll for solution! */ int (*inv_input) (struct _icmLuLut *p, double *out, double *in); int (*inv_matrix) (struct _icmLuLut *p, double *out, double *in); int (*inv_in_abs) (struct _icmLuLut *p, double *out, double *in); /* Get various types of information about the LuLut */ void (*get_info) (struct _icmLuLut *p, icmLut **lutp, icmXYZNumber *pcswhtp, icmXYZNumber *whitep, icmXYZNumber *blackp); /* Get the native input space and output space ranges */ void (*get_lutranges) (struct _icmLuLut *p, double *inmin, double *inmax, /* Maximum range of inspace values */ double *outmin, double *outmax); /* Maximum range of outspace values */ /* Get the matrix contents */ void (*get_matrix) (struct _icmLuLut *p, double m[3][3]); }; typedef struct _icmLuLut icmLuLut; /* ---------------------------------------------------------- */ /* A tag */ typedef struct { icTagSignature sig; /* The tag signature */ icTagTypeSignature ttype; /* The tag type signature */ unsigned int offset; /* File offset to start header */ unsigned int size; /* Size in bytes */ icmBase *objp; /* In memory data structure */ } icmTag; /* Pseudo enumerations valid as parameter to get_luobj(): */ /* To be specified where an intent is not appropriate */ #define icmDefaultIntent ((icRenderingIntent)98) /* Pseudo PCS colospace used to indicate the native PCS */ #define icmSigDefaultData ((icColorSpaceSignature) 0x0) /* The ICC object */ struct _icc { /* Public: */ unsigned int (*get_size)(struct _icc *p); /* Return total size needed, 0 = err. */ int (*read)(struct _icc *p, icmFile *fp, unsigned long of); /* Returns error code */ int (*write)(struct _icc *p, icmFile *fp, unsigned long of);/* Returns error code */ void (*dump)(struct _icc *p, FILE *op, int verb); /* Dump whole icc */ void (*del)(struct _icc *p); /* Free whole icc */ int (*find_tag)(struct _icc *p, icTagSignature sig); /* Returns 1 if found, 2 readable */ icmBase * (*read_tag)(struct _icc *p, icTagSignature sig); /* Returns pointer to object */ icmBase * (*add_tag)(struct _icc *p, icTagSignature sig, icTagTypeSignature ttype); /* Returns pointer to object */ int (*rename_tag)(struct _icc *p, icTagSignature sig, icTagSignature sigNew); /* Rename and existing tag */ icmBase * (*link_tag)(struct _icc *p, icTagSignature sig, icTagSignature ex_sig); /* Returns pointer to object */ int (*unread_tag)(struct _icc *p, icTagSignature sig); /* Unread a tag (free on refcount == 0 */ int (*read_all_tags)(struct _icc *p); /* Read all the tags, non-zero on error. */ int (*delete_tag)(struct _icc *p, icTagSignature sig); /* Returns 0 if deleted OK */ icmLuBase * (*get_luobj) (struct _icc *p, icmLookupFunc func, /* Functionality */ icRenderingIntent intent, /* Intent */ icColorSpaceSignature pcsor, /* PCS overide (0 = def) */ icmLookupOrder order); /* Search Order */ /* Return appropriate lookup object */ /* NULL on error, check errc+err for reason */ icmHeader *header; /* The header */ char err[512]; /* Error message */ int errc; /* Error code */ /* Private: ? */ icmAlloc *al; /* Heap allocator */ int del_al; /* NZ if heap allocator should be deleted */ icmFile *fp; /* File associated with object */ unsigned long of; /* Offset of the profile within the file */ unsigned int count; /* Num tags in the profile */ icmTag *data; /* The tagTable and tagData */ }; typedef struct _icc icc; /* ========================================================== */ /* Utility structures and declarations */ /* Structure to hold pseudo-hilbert counter info */ struct _psh { int di; /* Dimensionality */ unsigned res; /* Resolution per coordinate */ unsigned bits; /* Bits per coordinate */ unsigned ix; /* Current binary index */ unsigned tmask; /* Total 2^n count mask */ unsigned count; /* Usable count */ }; typedef struct _psh psh; /* Type of encoding to be returned as a string */ typedef enum { icmScreenEncodings, icmDeviceAttributes, icmProfileHeaderFlags, icmAsciiOrBinaryData, icmTagSignature, icmTechnologySignature, icmTypeSignature, icmColorSpaceSignature, icmProfileClassSignaure, icmPlatformSignature, icmMeasurementFlare, icmMeasurementGeometry, icmRenderingIntent, icmSpotShape, icmStandardObserver, icmIlluminant, icmLuAlg } icmEnumType; /* ========================================================== */ /* Public function declarations */ /* Create an empty object. Return null on error */ extern ICCLIB_API icc *new_icc(void); /* Default allocator */ extern ICCLIB_API icc *new_icc_a(icmAlloc *al); /* With allocator class */ /* - - - - - - - - - - - - - */ /* Some useful utilities: */ /* Return a string that represents a tag */ extern ICCLIB_API char *tag2str(int tag); /* Return a tag created from a string */ extern ICCLIB_API int str2tag(const char *str); /* Return a string description of the given enumeration value */ extern ICCLIB_API const char *icm2str(icmEnumType etype, int enumval); /* CIE XYZ to perceptual Lab */ extern ICCLIB_API void icmXYZ2Lab(icmXYZNumber *w, double *out, double *in); /* Perceptual Lab to CIE XYZ */ extern ICCLIB_API void icmLab2XYZ(icmXYZNumber *w, double *out, double *in); /* The standard D50 illuminant value */ extern ICCLIB_API icmXYZNumber icmD50; /* The standard D65 illuminant value */ extern ICCLIB_API icmXYZNumber icmD65; /* The default black value */ extern ICCLIB_API icmXYZNumber icmBlack; /* Initialise a pseudo-hilbert grid counter, return total usable count. */ extern ICCLIB_API unsigned psh_init(psh *p, int di, unsigned res, int co[]); /* Reset the counter */ extern ICCLIB_API void psh_reset(psh *p); /* Increment pseudo-hilbert coordinates */ /* Return non-zero if count rolls over to 0 */ extern ICCLIB_API int psh_inc(psh *p, int co[]); /* Chromatic Adaption transform utility */ /* Return a 3x3 chromatic adaption matrix */ void icmChromAdaptMatrix( int flags, /* Flags as defined below */ icmXYZNumber d_wp, /* Destination white point */ icmXYZNumber s_wp, /* Source white point */ double mat[3][3] /* Destination matrix */ ); #define ICM_CAM_BRADFORD 0x0001 /* Use Bradford sharpened response space */ #define ICM_CAM_MULMATRIX 0x0002 /* Transform the given matrix */ /* Return the normal Delta E given two Lab values */ extern ICCLIB_API double icmLabDE(double *in1, double *in2); /* Return the normal Delta E squared, given two Lab values */ extern ICCLIB_API double icmLabDEsq(double *in1, double *in2); /* Return the CIE94 Delta E color difference measure for two Lab values */ extern ICCLIB_API double icmCIE94(double *in1, double *in2); /* Return the CIE94 Delta E color difference measure squared, for two Lab values */ extern ICCLIB_API double icmCIE94sq(double *in1, double *in2); /* Simple macro to transfer an array to an XYZ number */ #define icmAry2XYZ(xyz, ary) ((xyz).X = (ary)[0], (xyz).Y = (ary)[1], (xyz).Z = (ary)[2]) /* And the reverse */ #define icmXYZ2Ary(ary, xyz) ((ary)[0] = (xyz).X, (ary)[1] = (xyz).Y, (ary)[2] = (xyz).Z) /* ---------------------------------------------------------- */ #ifdef __cplusplus } #endif #endif /* ICC_H */