From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- icc/icc.h | 1992 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1992 insertions(+) create mode 100644 icc/icc.h (limited to 'icc/icc.h') diff --git a/icc/icc.h b/icc/icc.h new file mode 100644 index 0000000..7c3a65b --- /dev/null +++ b/icc/icc.h @@ -0,0 +1,1992 @@ +#ifndef ICC_H +#define ICC_H + +/* + * International Color Consortium Format Library (icclib) + * + * Author: Graeme W. Gill + * Date: 1999/11/29 + * Version: 2.15 + * + * Copyright 1997 - 2012 Graeme W. Gill + * + * This material is licensed with an "MIT" free use license:- + * see the License.txt file in this directory for licensing details. + */ + +/* We can get some subtle errors if certain headers aren't included */ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/* Version of icclib release */ + +#define ICCLIB_VERSION 0x020016 +#define ICCLIB_VERSION_STR "2.16" + +#undef ENABLE_V4 /* V4 is not fully implemented */ + +/* + * Note XYZ scaling to 1.0, not 100.0 + */ + +#undef ICC_DEBUG_MALLOC /* Turns on partial support for filename and linenumber capture */ + +/* 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 + +/* =========================================================== */ +/* Platform specific primitive defines. */ +/* This really needs checking for each different platform. */ +/* Using C99 and MSC covers a lot of cases, */ +/* and the fallback default is pretty reliable with modern compilers and machines. */ + +/* Note that the code assume that int is at least 32 bits, */ +/* and avoid using long as it is uncertain whether this is */ +/* the same size as an int or larger, opening the scope */ +/* for oveflow errors. */ + +#if UINT_MAX < 0xffffffff +# error "icclib: integer size is too small, must be at least 32 bit" +#endif + +#ifndef ORD32 /* If not defined elsewhere */ + +#if (__STDC_VERSION__ >= 199901L) /* C99 */ + +#include + +#define INR8 int8_t /* 8 bit signed */ +#define INR16 int16_t /* 16 bit signed */ +#define INR32 int32_t /* 32 bit signed */ +#define INR64 int64_t /* 64 bit signed - not used in icclib */ +#define ORD8 uint8_t /* 8 bit unsigned */ +#define ORD16 uint16_t /* 16 bit unsigned */ +#define ORD32 uint32_t /* 32 bit unsigned */ +#define ORD64 uint64_t /* 64 bit unsigned - not used in icclib */ + +#define PNTR intptr_t + +/* printf format precision specifier */ +#define PF64PREC "ll" + +/* Constant precision specifier */ +#define CF64PREC "LL" + +#else /* !__STDC_VERSION__ */ +#ifdef _MSC_VER + +#define INR8 __int8 /* 8 bit signed */ +#define INR16 __int16 /* 16 bit signed */ +#define INR32 __int32 /* 32 bit signed */ +#define INR64 __int64 /* 64 bit signed - not used in icclib */ +#define ORD8 unsigned __int8 /* 8 bit unsigned */ +#define ORD16 unsigned __int16 /* 16 bit unsigned */ +#define ORD32 unsigned __int32 /* 32 bit unsigned */ +#define ORD64 unsigned __int64 /* 64 bit unsigned - not used in icclib */ + +#define PNTR UINT_PTR + +#define vsnprintf _vsnprintf + +/* printf format precision specifier */ +#define PF64PREC "I64" + +/* Constant precision specifier */ +#define CF64PREC "LL" + +#else /* !_MSC_VER */ + +/* The following works on a lot of modern systems, including */ +/* LP64 model 64 bit modes */ + +#define INR8 signed char /* 8 bit signed */ +#define INR16 signed short /* 16 bit signed */ +#define INR32 signed int /* 32 bit signed */ +#define ORD8 unsigned char /* 8 bit unsigned */ +#define ORD16 unsigned short /* 16 bit unsigned */ +#define ORD32 unsigned int /* 32 bit unsigned */ + +#ifdef __GNUC__ +#define INR64 long long /* 64 bit signed - not used in icclib */ +#define ORD64 unsigned long long /* 64 bit unsigned - not used in icclib */ + +/* printf format precision specifier */ +#define PF64PREC "ll" + +#endif + +#define PNTR unsigned long + +#endif /* !_MSC_VER */ +#endif /* !__STDC_VERSION__ */ +#endif /* !defined(ORD32) */ + +/* =========================================================== */ +#include "iccV42.h" /* ICC Version 4.2 definitions. */ + +/* Note that the prefix icm is used for the native Machine */ +/* equivalents of the ICC binary file structures, and other icclib */ +/* specific definitions. */ + +/* ---------------------------------------------- */ +/* System interface objects. The defaults can be replaced */ +/* for adaption to different system environments */ + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Heap allocator class interface definition */ +#ifdef ICC_DEBUG_MALLOC + +#define ICM_ALLOC_BASE \ + /* Public: */ \ + \ + void *(*dmalloc) (struct _icmAlloc *p, size_t size, char *file, int line); \ + void *(*dcalloc) (struct _icmAlloc *p, size_t num, size_t size, char *file, int line); \ + void *(*drealloc)(struct _icmAlloc *p, void *ptr, size_t size, char *file, int line); \ + void (*dfree) (struct _icmAlloc *p, void *ptr, char *file, int line); \ + \ + /* we're done with the allocator object */ \ + void (*del)(struct _icmAlloc *p); \ + +#ifdef _ICC_C_ /* only inside icc.c */ +#define malloc( p, size ) dmalloc( p, size, __FILE__, __LINE__ ) +#define calloc( p, num, size ) dcalloc( p, num, size, __FILE__, __LINE__ ) +#define realloc( p, ptr, size ) drealloc( p, ptr, size, __FILE__, __LINE__ ) +#define free( p, ptr ) dfree( p, ptr , __FILE__, __LINE__ ) +#endif /* _ICC_C */ + +#else /* !ICC_DEBUG_MALLOC */ + +/* 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); \ + +#endif /* !ICC_DEBUG_MALLOC */ + +/* 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); + +/* File access class interface definition */ +#define ICM_FILE_BASE \ + /* Public: */ \ + \ + /* Get the size of the file (Typically valid after read only) */ \ + size_t (*get_size) (struct _icmFile *p); \ + \ + /* Set current position to offset. Return 0 on success, nz on failure. */ \ + int (*seek) (struct _icmFile *p, unsigned 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); \ + \ + /* printf to the file */ \ + int (*gprintf)(struct _icmFile *p, const char *format, ...); \ + \ + /* flush all write data out to secondary storage. Return nz on failure. */ \ + int (*flush)(struct _icmFile *p); \ + \ + /* Return the memory buffer. Error if not icmFileMem */ \ + int (*get_buf)(struct _icmFile *p, unsigned char **buf, size_t *len); \ + \ + /* 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; + + +/* - - - - - - - - - - - - - - - - - - - - - */ + +/* These are avalailable if SEPARATE_STD is not defined: */ + +/* Implementation of file access class based on standard file I/O */ +struct _icmFileStd { + ICM_FILE_BASE + + /* Private: */ + icmAlloc *al; /* Heap allocator */ + int del_al; /* NZ if heap allocator should be deleted */ + FILE *fp; + int doclose; /* nz if free should close */ + + /* Private: */ + size_t size; /* Size of the file (For read) */ + +}; 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); + +/* Create given a file name with allocator */ +icmFile *new_icmFileStd_name_a(char *name, char *mode, icmAlloc *al); + +/* Create given a (binary) FILE* and allocator */ +icmFile *new_icmFileStd_fp_a(FILE *fp, icmAlloc *al); + + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Implementation of file access class based on a memory image */ +/* The buffer is assumed to be allocated with the given heap allocator */ +/* Pass base = NULL, length = 0 for no initial buffer */ + +struct _icmFileMem { + ICM_FILE_BASE + + /* Private: */ + icmAlloc *al; /* Heap allocator */ + int del_al; /* NZ if heap allocator should be deleted */ + int del_buf; /* NZ if memory file buffer should be deleted */ + unsigned char *start, *cur, *end, *aend; + +}; typedef struct _icmFileMem icmFileMem; + +/* Create a memory image file access class with given allocator */ +/* The buffer is not delete with the object. */ +icmFile *new_icmFileMem_a(void *base, size_t length, icmAlloc *al); + +/* Create a memory image file access class with given allocator */ +/* and delete buffer when icmFile is deleted. */ +icmFile *new_icmFileMem_ad(void *base, size_t length, icmAlloc *al); + +/* This is avalailable if SEPARATE_STD is not defined: */ + +/* Create a memory image file access class */ +icmFile *new_icmFileMem(void *base, size_t length); + +/* Create a memory image file access class */ +/* and delete buffer when icmFile is deleted. */ +icmFile *new_icmFileMem_d(void *base, size_t length); + +/* --------------------------------- */ +/* 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 */ + +/* Non-standard Color Space Signatures - will be incompatible outside icclib! */ + +/* A monochrome CIE L* space */ +#define icmSigLData ((icColorSpaceSignature) icmMakeTag('L',' ',' ',' ')) + +/* A monochrome CIE Y space */ +#define icmSigYData ((icColorSpaceSignature) icmMakeTag('Y',' ',' ',' ')) + + +/* Pseudo Color Space Signatures - just used within icclib */ + +/* Pseudo PCS colospace of profile */ +#define icmSigPCSData ((icColorSpaceSignature) icmMakeTag('P','C','S',' ')) + +/* Pseudo PCS colospace to signal 8 bit Lab */ +#define icmSigLab8Data ((icColorSpaceSignature) icmMakeTag('L','a','b','8')) + +/* Pseudo PCS colospace to signal V2 16 bit Lab */ +#define icmSigLabV2Data ((icColorSpaceSignature) icmMakeTag('L','a','b','2')) + +/* Pseudo PCS colospace to signal V4 16 bit Lab */ +#define icmSigLabV4Data ((icColorSpaceSignature) icmMakeTag('L','a','b','4')) + +/* Pseudo PCS colospace to signal 8 bit L */ +#define icmSigL8Data ((icColorSpaceSignature) icmMakeTag('L',' ',' ','8')) + +/* Pseudo PCS colospace to signal V2 16 bit L */ +#define icmSigLV2Data ((icColorSpaceSignature) icmMakeTag('L',' ',' ','2')) + +/* Pseudo PCS colospace to signal V4 16 bit L */ +#define icmSigLV4Data ((icColorSpaceSignature) icmMakeTag('L',' ',' ','4')) + +/* Non-standard Platform Signature */ +#define icmSig_nix ((icPlatformSignature) icmMakeTag('*','n','i','x')) + + +/* Alias for icSigColorantTableType found in LOGO profiles (Byte swapped clrt !) */ +#define icmSigAltColorantTableType ((icTagTypeSignature)icmMakeTag('t','r','l','c')) + +/* Tag Type signature, used to handle any tag that */ +/* isn't handled with a specific type object. */ +/* Also used in manufacturer & model header fields */ +/* Old: #define icmSigUnknownType ((icTagTypeSignature)icmMakeTag('?','?','?','?')) */ +#define icmSigUnknownType ((icTagTypeSignature) 0) + + +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 int len, unsigned int of); \ + int (*write)(struct _icmBase *p, unsigned int of); \ + void (*del)(struct _icmBase *p); \ + \ + /* Public: */ \ + void (*dump)(struct _icmBase *p, icmFile *op, int verb); \ + int (*allocate)(struct _icmBase *p); + +/* Base tag element data object */ +struct _icmBase { + ICM_BASE_MEMBERS +}; typedef struct _icmBase icmBase; + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Tag type to hold an unknown tag type, */ +/* so that it can be read and copied. */ +struct _icmUnknown { + ICM_BASE_MEMBERS + + /* Private: */ + unsigned int _size; /* size of data currently allocated */ + + /* Public: */ + icTagTypeSignature uttype; /* The unknown tag type signature */ + unsigned int size; /* Allocated and used size of the array */ + unsigned char *data; /* tag data */ +}; typedef struct _icmUnknown icmUnknown; + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* UInt8 Array */ +struct _icmUInt8Array { + ICM_BASE_MEMBERS + + /* Private: */ + unsigned int _size; /* Size currently allocated */ + + /* Public: */ + unsigned int 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 int 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 int 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 int 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 int 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 int 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 int 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 */ + int rsize; /* Number of reverse lists */ + unsigned 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 int 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 int 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 */ + icmDataASCII = 0, /* ASCII data */ + icmDataBin = 1 /* Binary data */ +} icmDataStyle; + +struct _icmData { + ICM_BASE_MEMBERS + + /* Private: */ + unsigned int _size; /* Size currently allocated */ + + /* Public: */ + icmDataStyle flag; /* Style of data */ + unsigned int 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 int size; /* Allocated and used size of data, 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 int 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 int 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 int 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 int numPlatforms; /* num of platforms and allocated array size */ + icmPlatformEntry *data; /* Array of pointers to platform entry data */ +}; typedef struct _icmDeviceSettings icmDeviceSettings; + +#endif /* NEW */ + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* optimised simplex Lut lookup axis flipping structure */ +typedef struct { + double fth; /* Flip threshold */ + char bthff; /* Below threshold flip flag value */ + char athff; /* Above threshold flip flag value */ +} sx_flip_info; + +/* Set method flags */ +#define ICM_CLUT_SET_EXACT 0x0000 /* Set clut node values exactly from callback */ +#define ICM_CLUT_SET_APXLS 0x0001 /* Set clut node values to aproximate least squares fit */ + +#define ICM_CLUT_SET_FILTER 0x0002 /* Post filter values (icmSetMultiLutTables() only) */ + + +/* lut */ +struct _icmLut { + ICM_BASE_MEMBERS + + /* Private: */ + /* Cache appropriate normalization routines */ + int dinc[MAX_CHAN]; /* Dimensional increment through clut (in doubles) */ + int dcube[1 << MAX_CHAN]; /* Hyper cube offsets (in doubles) */ + icmRevTable rit[MAX_CHAN]; /* Reverse input table information */ + icmRevTable rot[MAX_CHAN]; /* Reverse output table information */ + sx_flip_info finfo[MAX_CHAN]; /* Optimised simplex flip 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 */ + + /* Optimised simplex orientation information. oso_ffa is NZ if valid. */ + /* Only valid if inputChan > 1 && clutPoints > 1 */ + /* oso_ff[01] will be NULL if not valid */ + unsigned short *oso_ffa; /* Flip flags for inputChan-1 dimensions, organised */ + /* [inputChan 0, 0..cp-2]..[inputChan ic-2, 0..cp-2] */ + unsigned short *oso_ffb; /* Flip flags for dimemension inputChan-1, organised */ + /* [0..cp-2] */ + int odinc[MAX_CHAN]; /* Dimensional increment through oso_ffa */ + + /* 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 a Lut tables contents */ + int (*set_tables) ( + struct _icmLut *p, /* Pointer to Lut object */ + int flags, /* Setting flags */ + 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; + +/* Helper function to set multiple Lut tables simultaneously. */ +/* Note that these tables all have to be compatible in */ +/* having the same configuration and resolutions, and the */ +/* same per channel input and output curves. */ +/* Set errc and return error number in underlying icc */ +/* Note that clutfunc in[] value has "index under". */ +/* If ICM_CLUT_SET_FILTER is set, the per grid node filtering radius */ +/* is returned in clutfunc out[-1], out[-2] etc for each table */ +int icmSetMultiLutTables( + int ntables, /* Number of tables to be set, 1..n */ + struct _icmLut **p, /* Pointer to Lut object */ + int flags, /* Setting flags */ + 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) */ + /* Will be called ntables times each input grid value */ + double *inmin, double *inmax, /* Maximum range of inspace' values */ + /* (NULL = default) */ + void (*clutfunc)(void *cbntx, double *out, double *in), + /* inspace' -> outspace[ntables]' transfer function */ + /* will be called once for each input' grid value, and */ + /* ntables output values should be written consecutively */ + /* to out[]. */ + 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) */ + /* Will be called ntables times on each output value */ +); + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* 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; + +#ifdef NEW +/* - - - - - - - - - - - - - - - - - - - - - */ +/* MultiLocalizedUnicode */ + +struct _icmMultiLocalizedUnicode { + ICM_BASE_MEMBERS + + /* Private: */ + ~~~999 + + /* Public: */ + ~~~999 + +}; typedef struct _icmMultiLocalizedUnicode icmMultiLocalizedUnicode; + +#endif /* NEW */ + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* 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; + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* Colorant table */ +/* (Contribution from Piet Vandenborre, derived from NamedColor) */ + +/* Structure that holds colorant table data */ +typedef struct { + struct _icc *icp; /* Pointer to ICC we're a part of */ + char name[32]; /* Name for colorant */ + double pcsCoords[3]; /* PCS coords of colorant */ +} icmColorantTableVal; + +struct _icmColorantTable { + ICM_BASE_MEMBERS + + /* Private: */ + unsigned int _count; /* Count currently allocated */ + + /* Public: */ + unsigned int count; /* Count of colorants */ + icmColorantTableVal *data; /* Array of [count] colorants */ +}; typedef struct _icmColorantTable icmColorantTable; + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* textDescription */ +struct _icmTextDescription { + ICM_BASE_MEMBERS + + /* Private: */ + unsigned int _size; /* Size currently allocated */ + unsigned int 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 int size; /* Allocated and used size of desc, inc null */ + char *desc; /* ascii string (null terminated) */ + + unsigned int ucLangCode; /* UniCode language code */ + unsigned int ucSize; /* Allocated and used size of ucDesc in wchars, inc null */ + ORD16 *ucDesc; /* The UniCode description (null terminated) */ + + /* See */ + ORD16 scCode; /* ScriptCode code */ + unsigned int 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; + +#ifdef NEW +/* - - - - - - - - - - - - - - - - - - - - - */ +/* ResponseCurveSet16 */ + +struct _icmResponseCurveSet16 { + ICM_BASE_MEMBERS + + /* Private: */ + ~~~999 + + /* Public: */ + ~~~999 + +}; typedef struct _icmResponseCurveSet16 icmResponseCurveSet16; + +#endif /* NEW */ + +/* - - - - - - - - - - - - - - - - - - - - - */ +/* 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 int _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 int 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 int _ppsize; /* Currently allocated size */ + unsigned int _crdsize[4]; /* Currently allocated sizes */ + + /* Public: */ + unsigned int ppsize; /* Postscript product name size (including null) */ + char *ppname; /* Postscript product name (null terminated) */ + unsigned int 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 (vcgt) */ +struct _icmVideoCardGammaTable { + unsigned short channels; /* No of gamma channels (1 or 3) */ + unsigned short entryCount; /* 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 { + unsigned short channels; /* No of gamma channels (always 3) */ + 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; + +typedef enum { + icmVideoCardGammaTableType = 0, + icmVideoCardGammaFormulaType = 1 +} icmVideoCardGammaTagType; + +struct _icmVideoCardGamma { + ICM_BASE_MEMBERS + icmVideoCardGammaTagType tagType; /* eg. table or formula, use above enum */ + union { + icmVideoCardGammaTable table; + icmVideoCardGammaFormula formula; + } u; + + double (*lookup)(struct _icmVideoCardGamma *p, int chan, double iv); /* Read a value */ + +}; typedef struct _icmVideoCardGamma icmVideoCardGamma; + +/* ------------------------------------------------- */ +/* The Profile header */ +struct _icmHeader { + + /* Private: */ + unsigned int (*get_size)(struct _icmHeader *p); + int (*read)(struct _icmHeader *p, unsigned int len, unsigned int of); + int (*write)(struct _icmHeader *p, unsigned int of, int doid); + 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, icmFile *op, int verb); + + /* Values that must be set before writing */ + icProfileClassSignature deviceClass; /* Type of profile */ + icColorSpaceSignature colorSpace; /* Clr space of data (Cannonical input space) */ + icColorSpaceSignature pcs; /* PCS: XYZ or Lab (Cannonical output space) */ + icRenderingIntent renderingIntent;/* Rendering intent */ + + /* Values that should be set before writing */ + icmSig manufacturer; /* Dev manufacturer */ + icmSig model; /* Dev model */ + icmUint64 attributes; /* Device attributes */ + 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 */ + /* Default is majv = 2, alternate value is 4 */ + icmDateTimeNumber date; /* Creation Date */ + icPlatformSignature platform; /* Primary Platform */ + icmXYZNumber illuminant; /* Profile illuminant */ + + /* Values that are created automatically */ + unsigned char id[16]; /* MD5 fingerprint value, lsB to msB */ + +}; typedef struct _icmHeader icmHeader; + +/* ---------------------------------------------------------- */ +/* Objects for accessing lookup functions. */ +/* Note that 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. */ +/* The conversion between the native and effective PCS is done in the to/from_abs() */ +/* conversions. */ + +/* 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 */ + icmNamedType = 5 /* Named color data */ +} icmLuAlgType; + +/* Lookup class members common to named and non-named color types */ +#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 (externaly visible) intent */ \ + icmLookupFunc function; /* Functionality being used */ \ + icmLookupOrder order; /* Conversion representation search Order */ \ + icmXYZNumber pcswht, whitePoint, blackPoint; /* White and black point info (absolute 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 */ \ + 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, \ + icColorSpaceSignature *pcs); \ + \ + /* External effecive colorspaces */ \ + void (*spaces) (struct _icmLuBase *p, icColorSpaceSignature *ins, int *inn, \ + icColorSpaceSignature *outs, int *outn, \ + icmLuAlgType *alg, icRenderingIntent *intt, \ + icmLookupFunc *fnc, icColorSpaceSignature *pcs, \ + icmLookupOrder *ord); \ + \ + /* Relative to Absolute for this WP in XYZ */ \ + void (*XYZ_Rel2Abs)(struct _icmLuBase *p, double *xyzout, double *xyzin); \ + \ + /* Absolute to Relative for this WP in XYZ */ \ + void (*XYZ_Abs2Rel)(struct _icmLuBase *p, double *xyzout, double *xyzin); \ + + +/* Non-algorithm specific lookup class. Used as base class of algorithm specific class. */ +#define LU_ICM_NN_BASE_MEMBERS \ + LU_ICM_BASE_MEMBERS \ + \ + /* Public: */ \ + \ + /* Get the native input space and output space ranges */ \ + /* This is an accurate number of what the underlying profile can hold. */ \ + void (*get_lutranges) (struct _icmLuBase *p, \ + double *inmin, double *inmax, /* Range of inspace values */ \ + double *outmin, double *outmax); /* Range of outspace values */ \ + \ + /* Get the effective input space and output space ranges */ \ + /* This may not be accurate when the effective type is different to the native type */ \ + void (*get_ranges) (struct _icmLuBase *p, \ + double *inmin, double *inmax, /* Range of inspace values */ \ + double *outmin, double *outmax); /* Range of outspace values */ \ + \ + /* Initialise the white and black points from the ICC tags */ \ + /* and the corresponding absolute<->relative conversion matrices */ \ + /* Return nz on error */ \ + int (*init_wh_bk)(struct _icmLuBase *p); \ + \ + /* Get the LU white and black points in absolute XYZ space. */ \ + /* 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 _icmLuBase *p, double *wht, double *blk); \ + \ + /* Get the LU 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 _icmLuBase *p, double *wht, double *blk); \ + \ + /* Translate color values through profile in effective in and out colorspaces, */ \ + /* return values: */ \ + /* 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. */ \ + int (*lookup) (struct _icmLuBase *p, double *out, double *in); \ + \ + \ + /* Alternate to above, splits color conversion into three steps. */ \ + /* Colorspace of _in and _out and _core are the effective in and out */ \ + /* colorspaces. Note that setting colorspace overrides will probably. */ \ + /* force _in and/or _out to be dumy (unity) transforms. */ \ + \ + /* Per channel input lookup (may be unity): */ \ + int (*lookup_in) (struct _icmLuBase *p, double *out, double *in); \ + \ + /* Intra channel conversion: */ \ + int (*lookup_core) (struct _icmLuBase *p, double *out, double *in); \ + \ + /* Per channel output lookup (may be unity): */ \ + int (*lookup_out) (struct _icmLuBase *p, double *out, double *in); \ + \ + /* Inverse versions of above - partially implemented */ \ + /* Inverse per channel input lookup (may be unity): */ \ + int (*lookup_inv_in) (struct _icmLuBase *p, double *out, double *in); \ + \ + + +/* Base lookup object */ +struct _icmLuBase { + LU_ICM_NN_BASE_MEMBERS +}; typedef struct _icmLuBase icmLuBase; + + +/* Algorithm specific lookup classes */ + +/* Monochrome Fwd & Bwd type object */ +struct _icmLuMono { + LU_ICM_NN_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_NN_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_NN_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, in reverse order */ + /* 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 */ + /* (Note that there's no reason why white/black point info */ + /* isn't being made available for other Lu types) */ + void (*get_info) (struct _icmLuLut *p, icmLut **lutp, + icmXYZNumber *pcswhtp, icmXYZNumber *whitep, + icmXYZNumber *blackp); + + /* Get the matrix contents */ + void (*get_matrix) (struct _icmLuLut *p, double m[3][3]); + +}; typedef struct _icmLuLut icmLuLut; + +/* Named colors lookup object */ +struct _icmLuNamed { + LU_ICM_BASE_MEMBERS + + /* Private: */ + + /* Public: */ + + /* Get various types of information about the Named lookup */ + void (*get_info) (struct _icmLuLut *p, + icmXYZNumber *pcswhtp, icmXYZNumber *whitep, + icmXYZNumber *blackp, + int *maxnamesize, + int *num_colors, char *prefix, char *suffix); + + + /* Lookup a name that includes prefix and suffix */ + int (*fullname_lookup) (struct _icmLuNamed *p, double *pcs, double *dev, char *in); + + /* Lookup a name that doesn't include prefix and suffix */ + int (*name_lookup) (struct _icmLuNamed *p, double *pcs, double *dev, char *in); + + /* Fill in a list with the nout closest named colors to the pcs target */ + int (*pcs_lookup) (struct _icmLuNamed *p, char **out, int nout, double *in); + + /* Fill in a list with the nout closest named colors to the device target */ + int (*dev_lookup) (struct _icmLuNamed *p, char **out, int nout, double *in); + +}; typedef struct _icmLuNamed icmLuNamed; + +/* ---------------------------------------------------------- */ +/* 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 (not including padding) */ + unsigned int pad; /* Padding in bytes */ + icmBase *objp; /* In memory data structure */ +} icmTag; + +/* Pseudo enumerations valid as parameter to get_luobj(): */ + +/* Special purpose Perceptual intent */ +#define icmAbsolutePerceptual ((icRenderingIntent)97) + +/* Special purpose Saturation intent */ +#define icmAbsoluteSaturation ((icRenderingIntent)98) + +/* To be specified where an intent is not appropriate */ +#define icmDefaultIntent ((icRenderingIntent)99) + +/* Pseudo PCS colospace used to indicate the native PCS */ +#define icmSigDefaultData ((icColorSpaceSignature) 0x0) + +/* Pseudo colospace used to indicate a named colorspace */ +#define icmSigNamedData ((icColorSpaceSignature) 0x1) + + +/* Arguments to set a non-default creation version */ +typedef enum { + icmVersionDefault = 0, /* Version 2.2.0 is default */ + icmVersion2_3 = 1, /* Version 2.3.0 - Chromaticity Tag */ + icmVersion2_4 = 2, /* Version 2.4.0 - Display etc. have intents */ + icmVersion4_1 = 3, /* Version 4.1.0 - General V4 features */ +} icmICCVersion; + +/* The ICC object */ +struct _icc { + /* Public: */ + icmFile *(*get_rfp)(struct _icc *p); /* Return the current read fp (if any) */ + int (*set_version)(struct _icc *p, icmICCVersion ver); + /* For creation, use ICC V4 etc. */ + unsigned int (*get_size)(struct _icc *p); /* Return total size needed, 0 = err. */ + int (*read)(struct _icc *p, icmFile *fp, unsigned int of); /* Returns error code */ + int (*read_x)(struct _icc *p, icmFile *fp, unsigned int of, int take_fp); + int (*write)(struct _icc *p, icmFile *fp, unsigned int of);/* Returns error code */ + int (*write_x)(struct _icc *p, icmFile *fp, unsigned int of, int take_fp); + void (*dump)(struct _icc *p, icmFile *op, int verb); /* Dump whole icc */ + void (*del)(struct _icc *p); /* Free whole icc */ + int (*find_tag)(struct _icc *p, icTagSignature sig); + /* Returns 0 if found, 1 if found but not readable, 2 of not found */ + icmBase * (*read_tag)(struct _icc *p, icTagSignature sig); + /* Returns pointer to object */ + icmBase * (*read_tag_any)(struct _icc *p, icTagSignature sig); + /* Returns pointer to object, but may be icmSigUnknownType! */ + 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 */ + int (*check_id)(struct _icc *p, ORD8 *id); /* Returns 0 if ID is OK, 1 if not present etc. */ + double (*get_tac)(struct _icc *p, double *chmax, /* Returns total ink limit and channel maximums */ + void (*calfunc)(void *cntx, double *out, double *in), void *cntx); /* optional cal. lookup */ + + /* Get a particular color conversion function */ + icmLuBase * (*get_luobj) (struct _icc *p, + icmLookupFunc func, /* Functionality */ + icRenderingIntent intent, /* Intent */ + icColorSpaceSignature pcsor, /* PCS override (0 = def) */ + icmLookupOrder order); /* Search Order */ + /* Return appropriate lookup object */ + /* NULL on error, check errc+err for reason */ + + /* Low level - load specific cLUT conversion */ + icmLuBase * (*new_clutluobj)(struct _icc *p, + icTagSignature ttag, /* Target Lut tag */ + icColorSpaceSignature inSpace, /* Native Input color space */ + icColorSpaceSignature outSpace, /* Native Output color space */ + icColorSpaceSignature pcs, /* Native PCS (from header) */ + icColorSpaceSignature e_inSpace, /* Override Inpt color space */ + icColorSpaceSignature e_outSpace, /* Override Outpt color space */ + icColorSpaceSignature e_pcs, /* Override PCS */ + icRenderingIntent intent, /* Rendering intent (For abs.) */ + icmLookupFunc func); /* For icmLuSpaces() */ + /* 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 */ + int warnc; /* Warning code */ + + /* Private: ? */ + icmAlloc *al; /* Heap allocator */ + int del_al; /* NZ if heap allocator should be deleted */ + icmFile *fp; /* File associated with object */ + int del_fp; /* NZ if File should be deleted */ + unsigned int of; /* Offset of the profile within the file */ + unsigned int count; /* Num tags in the profile */ + icmTag *data; /* The tagTable and tagData */ + icmICCVersion ver; /* Version class, see icmICCVersion enum */ + + }; typedef struct _icc icc; + +/* ========================================================== */ +/* Utility structures and declarations */ + +/* Type of primitives that can be read or written */ +typedef enum { + icmUInt8Number, + icmUInt16Number, + icmUInt32Number, + icmUInt64Number, + icmU8Fixed8Number, + icmU16Fixed16Number, + icmSInt8Number, + icmSInt16Number, + icmSInt32Number, + icmSInt64Number, + icmS15Fixed16Number, + icmDCS8Number, + icmDCS16Number, + icmPCSNumber, /* 16 bit PCS of profile */ + icmPCSXYZNumber, /* 16 bit XYZ */ + icmPCSLab8Number, /* 8 bit Lab */ + icmPCSLabNumber, /* 16 bit Lab of profile */ + icmPCSLabV2Number, /* 16 bit Lab Version 2 */ + icmPCSLabV4Number /* 16 bit Lab Version 4 */ +} icmPrimType; + +/* Structure to hold pseudo-hilbert counter info */ +struct _psh { + int di; /* Dimensionality */ + unsigned int res; /* Resolution per coordinate */ + unsigned int bits; /* Bits per coordinate */ + unsigned int ix; /* Current binary index */ + unsigned int tmask; /* Total 2^n count mask */ + unsigned int 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, + icmProfileClassSignature, + icmPlatformSignature, + icmMeasurementFlare, + icmMeasurementGeometry, + icmRenderingIntent, + icmTransformLookupFunc, + icmSpotShape, + icmStandardObserver, + icmIlluminant, + icmLuAlg +} icmEnumType; + + +/* A helper object that computes MD5 checksums */ +struct _icmMD5 { + /* Private: */ +// icc *icp; /* ICC we're part of */ + icmAlloc *al; /* Heap allocator */ + int fin; /* Flag, nz if final has been called */ + ORD32 sum[4]; /* Current/final checksum */ + unsigned int tlen; /* Total length added in bytes */ + ORD8 buf[64]; /* Partial buffer */ + + /* Public: */ + void (*reset)(struct _icmMD5 *p); /* Reset the checksum */ + void (*add)(struct _icmMD5 *p, ORD8 *buf, unsigned int len); /* Add some bytes */ + void (*get)(struct _icmMD5 *p, ORD8 chsum[16]); /* Finalise and get the checksum */ + void (*del)(struct _icmMD5 *p); /* We're done with the object */ + +}; typedef struct _icmMD5 icmMD5; + +/* Create a new MD5 checksumming object, with a reset checksum value */ +/* Return it or NULL if there is an error */ +icmMD5 *new_icmMD5(icmAlloc *al); + + +/* Implementation of file access class to compute an MD5 checksum */ +struct _icmFileMD5 { + ICM_FILE_BASE + int (*get_errc)(struct _icmFile *p); /* Check if there was an error */ + + /* Private: */ + icmAlloc *al; /* Heap allocator */ + icmMD5 *md5; /* MD5 object */ + unsigned int of; /* Current offset */ + int errc; /* Error code, 0 for OK */ + + /* Private: */ + size_t size; /* Size of the file (For read) */ + +}; typedef struct _icmFileMD5 icmFileMD5; + +/* Create a dumy file access class with allocator */ +icmFile *new_icmFileMD5_a(icmMD5 *md5, icmAlloc *al); + + +/* ========================================================== */ +/* Public function declarations */ +/* Create an empty object. Return null on error */ +extern ICCLIB_API icc *new_icc_a(icmAlloc *al); /* With allocator class */ + +/* If SEPARATE_STD not defined: */ +extern ICCLIB_API icc *new_icc(void); /* Default allocator */ + +/* - - - - - - - - - - - - - */ +/* Some useful utilities: */ + +/* Default ICC profile file extension string */ + +#if defined (UNIX) || defined(__APPLE__) +#define ICC_FILE_EXT ".icc" +#define ICC_FILE_EXT_ND "icc" +#else +#define ICC_FILE_EXT ".icm" +#define ICC_FILE_EXT_ND "icm" +#endif + +/* Read a given primitive type. Return non-zero on error */ +extern ICCLIB_API int read_Primitive(icc *icpp, icmPrimType ptype, void *prim, char *p); + +/* Write a given primitive type. Return non-zero on error */ +extern ICCLIB_API int write_Primitive(icc *icp, icmPrimType ptype, char *p, void *prim); + +/* Return a string that represents a tag */ +extern ICCLIB_API char *tag2str(int tag); + +/* Return a tag created from a string */ +extern ICCLIB_API unsigned int str2tag(const char *str); + +/* Utility to define a non-standard tag, arguments are 4 character constants */ +#define icmMakeTag(A,B,C,D) \ + ( (((ORD32)(ORD8)(A)) << 24) \ + | (((ORD32)(ORD8)(B)) << 16) \ + | (((ORD32)(ORD8)(C)) << 8) \ + | ((ORD32)(ORD8)(D)) ) + +/* Return a string description of the given enumeration value */ +extern ICCLIB_API const char *icm2str(icmEnumType etype, int enumval); + +/* Return the number of channels for the given color space. Return 0 if unknown. */ +extern ICCLIB_API unsigned int icmCSSig2nchan(icColorSpaceSignature sig); + +/* Return the individual channel names and number of channels give a colorspace signature. */ +/* Return 0 if it is not a colorspace that itself defines particular channels, */ +/* 1 if it is a colorant based colorspace, and 2 if it is not a colorant based space */ +extern ICCLIB_API unsigned int icmCSSig2chanNames( icColorSpaceSignature sig, char *cvals[]); + + +/* 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) + +/* Simple macro to transfer an XYZ number to an XYZ number */ +#define icmXYZ2XYZ(d_xyz, s_xyz) ((d_xyz).X = (s_xyz).X, (d_xyz).Y = (s_xyz).Y, \ + (d_xyz).Z = (s_xyz).Z) + +/* Simple macro to transfer an 3array to 3array */ +/* Hmm. Same as icmCpy3 */ +#define icmAry2Ary(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \ + (d_ary)[2] = (s_ary)[2]) + +/* CIE Y (range 0 .. 1) to perceptual CIE 1976 L* (range 0 .. 100) */ +double icmY2L(double val); + +/* Perceptual CIE 1976 L* (range 0 .. 100) to CIE Y (range 0 .. 1) */ +double icmL2Y(double val); + +/* 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); + +/* LCh to Lab */ +extern ICCLIB_API void icmLCh2Lab(double *out, double *in); + +/* Lab to LCh */ +extern ICCLIB_API void icmLab2LCh(double *out, double *in); + +/* XYZ to Yxy */ +extern ICCLIB_API void icmXYZ2Yxy(double *out, double *in); + +/* Yxy to XYZ */ +extern ICCLIB_API void icmYxy2XYZ(double *out, double *in); + +/* CIE XYZ to perceptual Luv */ +extern ICCLIB_API void icmXYZ2Luv(icmXYZNumber *w, double *out, double *in); + +/* Perceptual Luv to CIE XYZ */ +extern ICCLIB_API void icmLuv2XYZ(icmXYZNumber *w, double *out, double *in); + + +/* NOTE :- none of the following seven have been protected */ +/* against arithmmetic issues (ie. for black) */ + +/* CIE XYZ to perceptual CIE 1976 UCS diagram Yu'v'*/ +/* (Yu'v' is a better chromaticity space than Yxy) */ +extern ICCLIB_API void icmXYZ21976UCS(double *out, double *in); + +/* Perceptual CIE 1976 UCS diagram Yu'v' to CIE XYZ */ +extern ICCLIB_API void icm1976UCS2XYZ(double *out, double *in); + +/* CIE XYZ to perceptual CIE 1960 UCS */ +/* (This was obsoleted by the 1976UCS, but is still used */ +/* in computing color temperatures.) */ +extern ICCLIB_API void icmXYZ21960UCS(double *out, double *in); + +/* Perceptual CIE 1960 UCS to CIE XYZ */ +extern ICCLIB_API void icm1960UCS2XYZ(double *out, double *in); + +/* CIE XYZ to perceptual CIE 1964 WUV (U*V*W*) */ +/* (This is obsolete but still used in computing CRI) */ +extern ICCLIB_API void icmXYZ21964WUV(icmXYZNumber *w, double *out, double *in); + +/* Perceptual CIE 1964 WUV (U*V*W*) to CIE XYZ */ +extern ICCLIB_API void icm1964WUV2XYZ(icmXYZNumber *w, double *out, double *in); + +/* CIE CIE1960 UCS to perceptual CIE 1964 WUV (U*V*W*) */ +extern ICCLIB_API void icm1960UCS21964WUV(icmXYZNumber *w, double *out, double *in); + + +/* The standard D50 illuminant value */ +extern icmXYZNumber icmD50; +extern icmXYZNumber icmD50_100; /* Scaled to 100 */ +double icmD50_ary3[3]; /* As an array */ +double icmD50_100_ary3[3]; /* Scaled to 100 as an array */ + +/* The standard D65 illuminant value */ +extern icmXYZNumber icmD65; +extern icmXYZNumber icmD65_100; /* Scaled to 100 */ +double icmD65_ary3[3]; /* As an array */ +double icmD65_100_ary3[3]; /* Scaled to 100 as an array */ + +/* The default black value */ +extern icmXYZNumber icmBlack; + + +/* Initialise a pseudo-hilbert grid counter, return total usable count. */ +extern ICCLIB_API unsigned psh_init(psh *p, int di, unsigned int 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[]); + + +/* RGB primaries to device to RGB->XYZ transform matrix */ +/* Return non-zero if matrix would be singular */ +int icmRGBprim2matrix( + icmXYZNumber white, /* White point */ + icmXYZNumber red, /* Red colorant */ + icmXYZNumber green, /* Green colorant */ + icmXYZNumber blue, /* Blue colorant */ + double mat[3][3] /* Destination matrix */ +); + +/* Chromatic Adaption transform utility */ +/* Return a 3x3 chromatic adaption matrix */ +/* Use icmMulBy3x3(dst, mat, src) */ + +#define ICM_CAM_BRADFORD 0x0001 /* Use Bradford sharpened response space */ +#define ICM_CAM_MULMATRIX 0x0002 /* Transform the given 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 */ +); + +/* - - - - - - - - - - - - - - */ +/* Set a 3 vector */ +#define icmSet3(d_ary, s_val) ((d_ary)[0] = (s_val), (d_ary)[1] = (s_val), \ + (d_ary)[2] = (s_val)) + +/* Copy a 3 vector */ +#define icmCpy3(d_ary, s_ary) ((d_ary)[0] = (s_ary)[0], (d_ary)[1] = (s_ary)[1], \ + (d_ary)[2] = (s_ary)[2]) + +/* Clamp a 3 vector to be +ve */ +void icmClamp3(double out[3], double in[3]); + +/* Add two 3 vectors */ +void icmAdd3(double out[3], double in1[3], double in2[3]); + +#define ICMADD3(o, i, j) ((o)[0] = (i)[0] + (j)[0], (o)[1] = (i)[1] + (j)[1], (o)[2] = (i)[2] + (j)[2]) + +/* Subtract two 3 vectors, out = in1 - in2 */ +void icmSub3(double out[3], double in1[3], double in2[3]); + +#define ICMSUB3(o, i, j) ((o)[0] = (i)[0] - (j)[0], (o)[1] = (i)[1] - (j)[1], (o)[2] = (i)[2] - (j)[2]) + +/* Compute the dot product of two 3 vectors */ +double icmDot3(double in1[3], double in2[3]); + +#define ICMDOT3(o, i, j) ((o) = (i)[0] * (j)[0] + (i)[1] * (j)[1] + (i)[2] * (j)[2]) + +/* Compute the cross product of two 3D vectors, out = in1 x in2 */ +void icmCross3(double out[3], double in1[3], double in2[3]); + +/* Compute the norm squared (length squared) of a 3 vector */ +double icmNorm3sq(double in[3]); + +#define ICMNORM3SQ(i) ((i)[0] * (i)[0] + (i)[1] * (i)[1] + (i)[2] * (i)[2]) + +/* Compute the norm (length) of a 3 vector */ +double icmNorm3(double in[3]); + +#define ICMNORM3(i) sqrt((i)[0] * (i)[0] + (i)[1] * (i)[1] + (i)[2] * (i)[2]) + +/* Scale a 3 vector by the given ratio */ +void icmScale3(double out[3], double in[3], double rat); + +/* Compute a blend between in0 and in1 */ +void icmBlend3(double out[3], double in0[3], double in1[3], double bf); + +#define ICMSCALE3(o, i, j) ((o)[0] = (i)[0] * (j), (o)[1] = (i)[1] * (j), (o)[2] = (i)[2] * (j)) + +/* Normalise a 3 vector to the given length. Return nz if not normalisable */ +int icmNormalize3(double out[3], double in[3], double len); + +/* Compute the norm squared (length squared) of a vector defined by two points */ +double icmNorm33sq(double in1[3], double in0[3]); + +/* Compute the norm (length) of of a vector defined by two points */ +double icmNorm33(double in1[3], double in0[3]); + +/* Scale a two point vector by the given ratio. in0[] is the origin. */ +void icmScale33(double out[3], double in1[3], double in0[3], double rat); + +/* Normalise a two point vector to the given length. */ +/* The new location of in1[] is returned in out[], in0[] is the origin. */ +/* Return nz if not normalisable */ +int icmNormalize33(double out[3], double in1[3], double in0[3], double len); + + +/* Set a 3x3 matrix to unity */ +void icmSetUnity3x3(double mat[3][3]); + +/* Copy a 3x3 transform matrix */ +void icmCpy3x3(double out[3][3], double mat[3][3]); + +/* Scale each element of a 3x3 transform matrix */ +void icmScale3x3(double dst[3][3], double src[3][3], double scale); + +/* Multiply 3 vector by 3x3 transform matrix */ +/* Organization is mat[out][in] */ +void icmMulBy3x3(double out[3], double mat[3][3], double in[3]); + +/* Add one 3x3 to another */ +/* dst = src1 + src2 */ +void icmAdd3x3(double dst[3][3], double src1[3][3], double src2[3][3]); + +/* Tensor product. Multiply two 3 vectors to form a 3x3 matrix */ +/* src1[] forms the colums, and src2[] forms the rows in the result */ +void icmTensMul3(double dst[3][3], double src1[3], double src2[3]); + +/* Multiply one 3x3 with another */ +/* dst = src * dst */ +void icmMul3x3(double dst[3][3], double src[3][3]); + +/* Multiply one 3x3 with another #2 */ +/* dst = src1 * src2 */ +void icmMul3x3_2(double dst[3][3], double src1[3][3], double src2[3][3]); + +/* Compute the determinant of a 3x3 matrix */ +double icmDet3x3(double in[3][3]); + +/* Invert a 3x3 transform matrix. Return 1 if error. */ +int icmInverse3x3(double out[3][3], double in[3][3]); + +/* Transpose a 3x3 matrix */ +void icmTranspose3x3(double out[3][3], double in[3][3]); + +/* Given two 3D points, create a matrix that rotates */ +/* and scales one onto the other about the origin 0,0,0. */ +/* Use icmMulBy3x3() to apply this to other points */ +void icmRotMat(double mat[3][3], double src[3], double targ[3]); + +/* Copy a 3x4 transform matrix */ +void icmCpy3x4(double out[3][4], double mat[3][4]); + +/* Multiply 3 array by 3x4 transform matrix */ +void icmMul3By3x4(double out[3], double mat[3][4], double in[3]); + +/* Given two 3D vectors, create a matrix that translates, */ +/* rotates and scales one onto the other. */ +/* Use icmMul3By3x4 to apply this to other points */ +void icmVecRotMat(double m[3][4], double s1[3], double s0[3], double t1[3], double t0[3]); + + +/* Compute the intersection of a vector and a plane */ +/* return nz if there is no intersection */ +int icmVecPlaneIsect(double isect[3], double pl_const, double pl_norm[3], double ve_1[3], double ve_0[3]); + +/* Compute the closest points between two lines a and b. */ +/* Return closest points and parameter values if not NULL. */ +/* Return nz if they are paralel. */ +int icmLineLineClosest(double ca[3], double cb[3], double *pa, double *pb, + double la0[3], double la1[3], double lb0[3], double lb1[3]); + +/* Given 3 3D points, compute a plane equation. */ +/* The normal will be right handed given the order of the points */ +/* The plane equation will be the 3 normal components and the constant. */ +/* Return nz if any points are cooincident or co-linear */ +int icmPlaneEqn3(double eq[4], double p0[3], double p1[3], double p2[3]); + +/* Given a 3D point and a plane equation, return the signed */ +/* distance from the plane */ +double icmPlaneDist3(double eq[4], double p[3]); + +/* - - - - - - - - - - - - - - - - - - - - - - - */ + +/* Multiply 2 array by 2x2 transform matrix */ +void icmMulBy2x2(double out[2], double mat[2][2], double in[2]); + +/* - - - - - - - - - - - - - - - - - - - - - - - */ + +/* Return the normal Delta E given two Lab values */ +extern ICCLIB_API double icmLabDE(double *in0, double *in1); + +/* Return the normal Delta E squared, given two Lab values */ +extern ICCLIB_API double icmLabDEsq(double *in0, double *in1); + +/* Return the normal Delta E given two XYZ values */ +extern ICCLIB_API double icmXYZLabDE(icmXYZNumber *w, double *in0, double *in1); + + +/* Return the CIE94 Delta E color difference measure for two Lab values */ +extern ICCLIB_API double icmCIE94(double *in0, double *in1); + +/* Return the CIE94 Delta E color difference measure squared, for two Lab values */ +extern ICCLIB_API double icmCIE94sq(double *in0, double *in1); + +/* Return the CIE94 Delta E color difference measure for two XYZ values */ +extern ICCLIB_API double icmXYZCIE94(icmXYZNumber *w, double *in0, double *in1); + + +/* Return the CIEDE2000 Delta E color difference measure for two Lab values */ +extern ICCLIB_API double icmCIE2K(double *in0, double *in1); + +/* Return the CIEDE2000 Delta E color difference measure squared, for two Lab values */ +extern ICCLIB_API double icmCIE2Ksq(double *in0, double *in1); + +/* Return the CIEDE2000 Delta E color difference measure for two XYZ values */ +extern ICCLIB_API double icmXYZCIE2K(icmXYZNumber *w, double *in0, double *in1); + +/* - - - - - - - - - - - - - - - - - - - - - - - */ +/* Clip Lab, while maintaining hue angle. */ +/* Return nz if clipping occured */ +int icmClipLab(double out[3], double in[3]); + +/* Clip XYZ, while maintaining hue angle */ +/* Return nz if clipping occured */ +int icmClipXYZ(double out[3], double in[3]); + +/* - - - - - - - - - - - - - - - - - - - - - - - */ +/* Print an int vector to a string. */ +/* Returned static buffer is re-used every 5 calls. */ +char *icmPiv(int di, int *p); + +/* Print a double color vector to a string. */ +/* Returned static buffer is re-used every 5 calls. */ +char *icmPdv(int di, double *p); + +/* Print a float color vector to a string. */ +/* Returned static buffer is re-used every 5 calls. */ +char *icmPfv(int di, float *p); + +/* Print an 0..1 range XYZ as a D50 Lab string */ +/* Returned static buffer is re-used every 5 calls. */ +char *icmPLab(double *p); + +/* ---------------------------------------------------------- */ + +#ifdef __cplusplus + } +#endif + +#endif /* ICC_H */ + -- cgit v1.2.3