1 #ifndef ICC_H
2 #define ICC_H
3 /*
4  * International Color Consortium Format Library (icclib)
5  *
6  * Author:  Graeme W. Gill
7  * Date:    99/11/29
8  * Version: 2.01
9  *
10  * Copyright 1997, 1998, 1999, 2000, 2001 Graeme W. Gill
11  * Please refer to Licence.txt file for details.
12  */
13 
14 
15 /* We can get some subtle errors if certain headers aren't included */
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <fcntl.h>
20 #include <math.h>
21 #include <time.h>
22 #include <sys/types.h>
23 
24 /*
25  *  Note XYZ scaling to 1.0, not 100.0
26  */
27 
28 
29 /* Make allowance for shared library use */
30 #ifdef ICCLIB_SHARED		/* Compiling or Using shared library version */
31 # ifdef ICCLIB_EXPORTS		/* Compiling shared library */
32 #  ifdef NT
33 #   define ICCLIB_API __declspec(dllexport)
34 #  endif /* NT */
35 # else						/* Using shared library */
36 #  ifdef NT
37 #   define ICCLIB_API __declspec(dllimport)
38 #   ifdef ICCLIB_DEBUG
39 #    pragma comment (lib, "icclibd.lib")
40 #   else
41 #    pragma comment (lib, "icclib.lib")
42 #   endif	/* DEBUG */
43 #  endif /* NT */
44 # endif
45 #else						/* Using static library */
46 # define ICCLIB_API	/* empty */
47 #endif
48 
49 
50 #ifdef __cplusplus
51 	extern "C" {
52 #endif
53 
54 
55 /* ---------------------------------------------- */
56 /* Platform specific defines */
57 /* It is assumed that the native machine size is 32 bits */
58 #ifndef INR8
59 #define INR8   signed char		/* 8 bit signed */
60 #endif
61 #ifndef INR16
62 #define INR16  signed short		/* 16 bit signed */
63 #endif
64 #ifndef INR32
65 #define INR32  signed long		/* 32 bit signed */
66 #endif
67 #ifndef ORD8
68 #define ORD8   unsigned char	/* 8 bit unsigned */
69 #endif
70 #ifndef ORD16
71 #define ORD16  unsigned short	/* 16 bit unsigned */
72 #endif
73 #ifndef ORD32
74 #define ORD32  unsigned long	/* 32 bit unsigned */
75 #endif
76 
77 #include "icc9809.h"	/* Standard ICC definitions, version ICC.1:1998-09 with mods noted. */
78 
79 /* Note that the prefix icm is used for the native Machine */
80 /* equivalents of the file structures defined in icc34.h */
81 
82 /* ---------------------------------------------- */
83 /* System interface objects. The defaults can be replaced */
84 /* for adaption to different system environments */
85 
86 /* File access class interface definition */
87 #define ICM_FILE_BASE																		\
88 	/* Public: */																			\
89 																							\
90 	/* Set current position to offset. Return 0 on success, nz on failure. */				\
91 	int    (*seek) (struct _icmFile *p, long int offset);									\
92 																							\
93 	/* Read count items of size length. Return number of items successfully read. */ 		\
94 	size_t (*read) (struct _icmFile *p, void *buffer, size_t size, size_t count);			\
95 																							\
96 	/* write count items of size length. Return number of items successfully written. */ 	\
97 	size_t (*write)(struct _icmFile *p, void *buffer, size_t size, size_t count);			\
98 																							\
99 	/* flush all write data out to secondary storage. Return nz on failure. */				\
100 	int (*flush)(struct _icmFile *p);														\
101 																							\
102 	/* we're done with the file object, return nz on failure */								\
103 	int (*del)(struct _icmFile *p);															\
104 
105 
106 /* Common file interface class */
107 struct _icmFile {
108 	ICM_FILE_BASE
109 }; typedef struct _icmFile icmFile;
110 
111 
112 /* - - - - - - - - - - - - - - - - - - - - -  */
113 
114 /* Implementation of file access class based on standard file I/O */
115 struct _icmFileStd {
116 	ICM_FILE_BASE
117 
118 	/* Private: */
119 	FILE *fp;
120 	int   doclose;		/* nz if free should close */
121 }; typedef struct _icmFileStd icmFileStd;
122 
123 /* Create given a file name */
124 icmFile *new_icmFileStd_name(char *name, char *mode);
125 
126 /* Create given a (binary) FILE* */
127 icmFile *new_icmFileStd_fp(FILE *fp);
128 
129 
130 
131 /* - - - - - - - - - - - - - - - - - - - - -  */
132 /* Implementation of file access class based on a memory image */
133 struct _icmFileMem {
134 	ICM_FILE_BASE
135 
136 	/* Private: */
137 	unsigned char *start, *cur, *end;
138 
139 }; typedef struct _icmFileMem icmFileMem;
140 
141 /* Create a memory image file access class */
142 icmFile *new_icmFileMem(void *base, size_t length);
143 
144 
145 /* - - - - - - - - - - - - - - - - - - - - -  */
146 /* Heap allocator class interface definition */
147 #define ICM_ALLOC_BASE																		\
148 	/* Public: */																			\
149 																							\
150 	void *(*malloc) (struct _icmAlloc *p, size_t size);										\
151 	void *(*calloc) (struct _icmAlloc *p, size_t num, size_t size);							\
152 	void *(*realloc)(struct _icmAlloc *p, void *ptr, size_t size);							\
153 	void  (*free)   (struct _icmAlloc *p, void *ptr);										\
154 																							\
155 	/* we're done with the allocator object */												\
156 	void (*del)(struct _icmAlloc *p);														\
157 
158 /* Common heap allocator interface class */
159 struct _icmAlloc {
160 	ICM_ALLOC_BASE
161 }; typedef struct _icmAlloc icmAlloc;
162 
163 /* - - - - - - - - - - - - - - - - - - - - -  */
164 
165 /* Implementation of heap class based on standard system malloc */
166 struct _icmAllocStd {
167 	ICM_ALLOC_BASE
168 }; typedef struct _icmAllocStd icmAllocStd;
169 
170 /* Create a standard alloc object */
171 icmAlloc *new_icmAllocStd(void);
172 
173 
174 /* --------------------------------- */
175 /* Assumed constants                 */
176 
177 #define MAX_CHAN 15		/* Maximum number of color channels */
178 
179 /* --------------------------------- */
180 /* tag and other compound structures */
181 
182 typedef int icmSig;	/* Otherwise un-enumerated 4 byte signature */
183 
184 typedef struct {
185 	ORD32 l;			/* High and low components of signed 64 bit */
186 	INR32 h;
187 } icmInt64;
188 
189 typedef struct {
190 	ORD32 l,h;			/* High and low components of unsigned 64 bit */
191 } icmUint64;
192 
193 /* XYZ Number */
194 typedef struct {
195     double  X;
196     double  Y;
197     double  Z;
198 } icmXYZNumber;
199 
200 /* Response 16 number */
201 typedef struct {
202 	double	       deviceValue;	/* The device value in range 0.0 - 1.0 */
203 	double	       measurement;	/* The reading value */
204 } icmResponse16Number;
205 
206 /*
207  *  read and write method error codes:
208  *  0 = sucess
209  *  1 = file format/logistical error
210  *  2 = system error
211  */
212 
213 #define ICM_BASE_MEMBERS																\
214 	/* Private: */																		\
215 	icTagTypeSignature  ttype;		/* The tag type signature */						\
216 	struct _icc    *icp;			/* Pointer to ICC we're a part of */				\
217 	int	           touched;			/* Flag for write bookeeping */						\
218     int            refcount;		/* Reference count for sharing */					\
219 	unsigned int   (*get_size)(struct _icmBase *p);										\
220 	int            (*read)(struct _icmBase *p, unsigned long len, unsigned long of);	\
221 	int            (*write)(struct _icmBase *p, unsigned long of);						\
222 	void           (*del)(struct _icmBase *p);											\
223 																						\
224 	/* Public: */																		\
225 	void           (*dump)(struct _icmBase *p, FILE *op, int verb);						\
226 	int            (*allocate)(struct _icmBase *p);
227 
228 /* Base tag element data object */
229 struct _icmBase {
230 	ICM_BASE_MEMBERS
231 }; typedef struct _icmBase icmBase;
232 
233 /* UInt8 Array */
234 struct _icmUInt8Array {
235 	ICM_BASE_MEMBERS
236 
237 	/* Private: */
238 	unsigned int   _size;		/* Size currently allocated */
239 
240 	/* Public: */
241 	unsigned long	size;		/* Allocated and used size of the array */
242     unsigned int   *data;		/* Pointer to array of data */
243 }; typedef struct _icmUInt8Array icmUInt8Array;
244 
245 /* uInt16 Array */
246 struct _icmUInt16Array {
247 	ICM_BASE_MEMBERS
248 
249 	/* Private: */
250 	unsigned int   _size;		/* Size currently allocated */
251 
252 	/* Public: */
253 	unsigned long	size;		/* Allocated and used size of the array */
254     unsigned int	*data;		/* Pointer to array of data */
255 }; typedef struct _icmUInt16Array icmUInt16Array;
256 
257 /* uInt32 Array */
258 struct _icmUInt32Array {
259 	ICM_BASE_MEMBERS
260 
261 	/* Private: */
262 	unsigned int   _size;		/* Size currently allocated */
263 
264 	/* Public: */
265 	unsigned long	size;		/* Allocated and used size of the array */
266     unsigned int	*data;		/* Pointer to array of data */
267 }; typedef struct _icmUInt32Array icmUInt32Array;
268 
269 /* UInt64 Array */
270 struct _icmUInt64Array {
271 	ICM_BASE_MEMBERS
272 
273 	/* Private: */
274 	unsigned int   _size;		/* Size currently allocated */
275 
276 	/* Public: */
277 	unsigned long	size;		/* Allocated and used size of the array */
278     icmUint64		*data;		/* Pointer to array of hight data */
279 }; typedef struct _icmUInt64Array icmUInt64Array;
280 
281 /* u16Fixed16 Array */
282 struct _icmU16Fixed16Array {
283 	ICM_BASE_MEMBERS
284 
285 	/* Private: */
286 	unsigned int   _size;		/* Size currently allocated */
287 
288 	/* Public: */
289 	unsigned long	size;		/* Allocated and used size of the array */
290     double			*data;		/* Pointer to array of hight data */
291 }; typedef struct _icmU16Fixed16Array icmU16Fixed16Array;
292 
293 /* s15Fixed16 Array */
294 struct _icmS15Fixed16Array {
295 	ICM_BASE_MEMBERS
296 
297 	/* Private: */
298 	unsigned int   _size;		/* Size currently allocated */
299 
300 	/* Public: */
301 	unsigned long	size;		/* Allocated and used size of the array */
302     double			*data;		/* Pointer to array of hight data */
303 }; typedef struct _icmS15Fixed16Array icmS15Fixed16Array;
304 
305 /* XYZ Array */
306 struct _icmXYZArray {
307 	ICM_BASE_MEMBERS
308 
309 	/* Private: */
310 	unsigned int   _size;		/* Size currently allocated */
311 
312 	/* Public: */
313 	unsigned long	size;		/* Allocated and used size of the array */
314     icmXYZNumber	*data;		/* Pointer to array of data */
315 }; typedef struct _icmXYZArray icmXYZArray;
316 
317 /* Curve */
318 typedef enum {
319     icmCurveUndef           = -1, /* Undefined curve */
320     icmCurveLin             = 0,  /* Linear transfer curve */
321     icmCurveGamma           = 1,  /* Gamma power transfer curve */
322     icmCurveSpec            = 2   /* Specified curve */
323 } icmCurveStyle;
324 
325 /* Curve reverse lookup information */
326 typedef struct {
327 	int inited;				/* Flag */
328 	double rmin, rmax;		/* Range of reverse grid */
329 	double qscale;			/* Quantising scale factor */
330 	long rsize;				/* Number of reverse lists */
331 	int **rlists;			/* Array of list of fwd values that may contain output value */
332 							/* Offset 0 = allocated size */
333 							/* Offset 1 = next free index */
334 							/* Offset 2 = first fwd index */
335 	unsigned long size;		/* Copy of forward table size */
336 	double       *data;		/* Copy of forward table data */
337 } icmRevTable;
338 
339 struct _icmCurve {
340 	ICM_BASE_MEMBERS
341 
342 	/* Private: */
343 	unsigned int   _size;		/* Size currently allocated */
344 	icmRevTable  rt;			/* Reverse table information */
345 
346 	/* Public: */
347     icmCurveStyle   flag;		/* Style of curve */
348 	unsigned long	size;		/* Allocated and used size of the array */
349     double         *data;  		/* Curve data scaled to range 0.0 - 1.0 */
350 								/* or data[0] = gamma value */
351 	/* Translate a value through the curve, return warning flags */
352 	int (*lookup_fwd) (struct _icmCurve *p, double *out, double *in);	/* Forwards */
353 	int (*lookup_bwd) (struct _icmCurve *p, double *out, double *in);	/* Backwards */
354 
355 }; typedef struct _icmCurve icmCurve;
356 
357 /* Data */
358 typedef enum {
359     icmDataUndef           = -1, /* Undefined data curve */
360     icmDataASCII           = 0,  /* ASCII data curve */
361     icmDataBin             = 1   /* Binary data */
362 } icmDataStyle;
363 
364 struct _icmData {
365 	ICM_BASE_MEMBERS
366 
367 	/* Private: */
368 	unsigned int   _size;		/* Size currently allocated */
369 
370 	/* Public: */
371     icmDataStyle	flag;		/* Style of data */
372 	unsigned long	size;		/* Allocated and used size of the array (inc ascii null) */
373     unsigned char	*data;  	/* data or string, NULL if size == 0 */
374 }; typedef struct _icmData icmData;
375 
376 /* text */
377 struct _icmText {
378 	ICM_BASE_MEMBERS
379 
380 	/* Private: */
381 	unsigned int   _size;		/* Size currently allocated */
382 
383 	/* Public: */
384 	unsigned long	 size;		/* Allocated and used size of desc, inc null */
385 	char             *data;		/* ascii string (null terminated), NULL if size==0 */
386 }; typedef struct _icmText icmText;
387 
388 /* The base date time number */
389 struct _icmDateTimeNumber {
390 	ICM_BASE_MEMBERS
391 
392 	/* Public: */
393     unsigned int      year;
394     unsigned int      month;
395     unsigned int      day;
396     unsigned int      hours;
397     unsigned int      minutes;
398     unsigned int      seconds;
399 }; typedef struct _icmDateTimeNumber icmDateTimeNumber;
400 
401 #ifdef NEW
402 / * DeviceSettings */
403 
404 /*
405    I think this all works like this:
406 
407 Valid setting = (   (platform == platform1 and platform1.valid)
408                  or (platform == platform2 and platform2.valid)
409                  or ...
410                 )
411 
412 where
413 	platformN.valid = (   platformN.combination1.valid
414 	                   or platformN.combination2.valid
415 	                   or ...
416 	                  )
417 
418 where
419 	platformN.combinationM.valid = (    platformN.combinationM.settingstruct1.valid
420 	                                and platformN.combinationM.settingstruct2.valid
421 	                                and ...
422 	                               )
423 
424 where
425 	platformN.combinationM.settingstructP.valid = (   platformN.combinationM.settingstructP.setting1.valid
426 	                                               or platformN.combinationM.settingstructP.setting2.valid
427 	                                               or ...
428 	                                              )
429 
430  */
431 
432 /* The Settings Structure holds an array of settings of a particular type */
433 struct _icmSettingStruct {
434 	ICM_BASE_MEMBERS
435 
436 	/* Private: */
437 	unsigned int   _num;				/* Size currently allocated */
438 
439 	/* Public: */
440 	icSettingsSig       settingSig;		/* Setting identification */
441 	unsigned long       numSettings; 	/* number of setting values */
442 	union {								/* Setting values - type depends on Sig */
443 		icUInt64Number      *resolution;
444 		icDeviceMedia       *media;
445 		icDeviceDither      *halftone;
446 	}
447 }; typedef struct _icmSettingStruct icmSettingStruct;
448 
449 /* A Setting Combination holds all arrays of different setting types */
450 struct _icmSettingComb {
451 	/* Private: */
452 	unsigned int   _num;			/* number currently allocated */
453 
454 	/* Public: */
455 	unsigned long       numStructs;   /* num of setting structures */
456 	icmSettingStruct    *data;
457 }; typedef struct _icmSettingComb icmSettingComb;
458 
459 /* A Platform Entry holds all setting combinations */
460 struct _icmPlatformEntry {
461 	/* Private: */
462 	unsigned int   _num;			/* number currently allocated */
463 
464 	/* Public: */
465 	icPlatformSignature platform;
466 	unsigned long       numCombinations;    /* num of settings and allocated array size */
467 	icmSettingComb      *data;
468 }; typedef struct _icmPlatformEntry icmPlatformEntry;
469 
470 /* The Device Settings holds all platform settings */
471 struct _icmDeviceSettings {
472 	/* Private: */
473 	unsigned int   _num;			/* number currently allocated */
474 
475 	/* Public: */
476 	unsigned long       numPlatforms;	/* num of platforms and allocated array size */
477 	icmPlatformEntry    *data;			/* Array of pointers to platform entry data */
478 }; typedef struct _icmDeviceSettings icmDeviceSettings;
479 
480 #endif /* NEW */
481 
482 /* lut */
483 struct _icmLut {
484 	ICM_BASE_MEMBERS
485 
486 	/* Private: */
487 	/* Cache appropriate normalization routines */
488 	int dinc[MAX_CHAN];				/* Dimensional increment through clut */
489 	int dcube[1 << MAX_CHAN];		/* Hyper cube offsets */
490 	icmRevTable  rit;				/* Reverse input table information */
491 	icmRevTable  rot;				/* Reverse output table information */
492 
493 	unsigned int inputTable_size;	/* size allocated to input table */
494 	unsigned int clutTable_size;	/* size allocated to clut table */
495 	unsigned int outputTable_size;	/* size allocated to output table */
496 
497 	/* return the minimum and maximum values of the given channel in the clut */
498 	void (*min_max) (struct _icmLut *pp, double *minv, double *maxv, int chan);
499 
500 	/* Translate color values through 3x3 matrix, input tables only, multi-dimensional lut, */
501 	/* or output tables, */
502 	int (*lookup_matrix)  (struct _icmLut *pp, double *out, double *in);
503 	int (*lookup_input)   (struct _icmLut *pp, double *out, double *in);
504 	int (*lookup_clut_nl) (struct _icmLut *pp, double *out, double *in);
505 	int (*lookup_clut_sx) (struct _icmLut *pp, double *out, double *in);
506 	int (*lookup_output)  (struct _icmLut *pp, double *out, double *in);
507 
508 	/* Public: */
509 
510 	/* return non zero if matrix is non-unity */
511 	int (*nu_matrix) (struct _icmLut *pp);
512 
513     unsigned int	inputChan;      /* Num of input channels */
514     unsigned int	outputChan;     /* Num of output channels */
515     unsigned int	clutPoints;     /* Num of grid points */
516     unsigned int	inputEnt;       /* Num of in-table entries (must be 256 for Lut8) */
517     unsigned int	outputEnt;      /* Num of out-table entries (must be 256 for Lut8) */
518     double			e[3][3];		/* 3 * 3 array */
519 	double	        *inputTable;	/* The in-table: [inputChan * inputEnt] */
520 	double	        *clutTable;		/* The clut: [(clutPoints ^ inputChan) * outputChan] */
521 	double	        *outputTable;	/* The out-table: [outputChan * outputEnt] */
522 	/* inputTable  is organized [inputChan 0..ic-1][inputEnt 0..ie-1] */
523 	/* clutTable   is organized [inputChan 0, 0..cp-1]..[inputChan ic-1, 0..cp-1]
524 	                                                                [outputChan 0..oc-1] */
525 	/* outputTable is organized [outputChan 0..oc-1][outputEnt 0..oe-1] */
526 
527 	/* Helper function to setup the three tables contents */
528 	int (*set_tables) (
529 		struct _icmLut *p,						/* Pointer to Lut object */
530 		void   *cbctx,							/* Opaque callback context pointer value */
531 		icColorSpaceSignature insig, 			/* Input color space */
532 		icColorSpaceSignature outsig, 			/* Output color space */
533 		void (*infunc)(void *cbctx, double *out, double *in),
534 								/* Input transfer function, inspace->inspace' (NULL = default) */
535 		double *inmin, double *inmax,			/* Maximum range of inspace' values */
536 												/* (NULL = default) */
537 		void (*clutfunc)(void *cbntx, double *out, double *in),
538 								/* inspace' -> outspace' transfer function */
539 		double *clutmin, double *clutmax,		/* Maximum range of outspace' values */
540 												/* (NULL = default) */
541 		void (*outfunc)(void *cbntx, double *out, double *in));
542 								/* Output transfer function, outspace'->outspace (NULL = deflt) */
543 
544 }; typedef struct _icmLut icmLut;
545 
546 /* Measurement Data */
547 struct _icmMeasurement {
548 	ICM_BASE_MEMBERS
549 
550 	/* Public: */
551     icStandardObserver           observer;       /* Standard observer */
552     icmXYZNumber                 backing;        /* XYZ for backing */
553     icMeasurementGeometry        geometry;       /* Meas. geometry */
554     double                       flare;          /* Measurement flare */
555     icIlluminant                 illuminant;     /* Illuminant */
556 }; typedef struct _icmMeasurement icmMeasurement;
557 
558 /* Named color */
559 
560 /* Structure that holds each named color data */
561 typedef struct {
562 	struct _icc      *icp;				/* Pointer to ICC we're a part of */
563 	char              root[32];			/* Root name for color */
564 	double            pcsCoords[3];		/* icmNC2: PCS coords of color */
565 	double            deviceCoords[MAX_CHAN];	/* Dev coords of color */
566 } icmNamedColorVal;
567 
568 struct _icmNamedColor {
569 	ICM_BASE_MEMBERS
570 
571 	/* Private: */
572 	unsigned int      _count;			/* Count currently allocated */
573 
574 	/* Public: */
575     unsigned int      vendorFlag;		/* Bottom 16 bits for IC use */
576     unsigned int      count;			/* Count of named colors */
577     unsigned int      nDeviceCoords;	/* Num of device coordinates */
578     char              prefix[32];		/* Prefix for each color name (null terminated) */
579     char              suffix[32];		/* Suffix for each color name (null terminated) */
580     icmNamedColorVal  *data;			/* Array of [count] color values */
581 }; typedef struct _icmNamedColor icmNamedColor;
582 
583 /* textDescription */
584 struct _icmTextDescription {
585 	ICM_BASE_MEMBERS
586 
587 	/* Private: */
588 	unsigned long  _size;			/* Size currently allocated */
589 	unsigned long  uc_size;			/* uc Size currently allocated */
590 	int            (*core_read)(struct _icmTextDescription *p, char **bpp, char *end);
591 	int            (*core_write)(struct _icmTextDescription *p, char **bpp);
592 
593 	/* Public: */
594 	unsigned long	  size;			/* Allocated and used size of desc, inc null */
595 	char              *desc;		/* ascii string (null terminated) */
596 
597 	unsigned int      ucLangCode;	/* UniCode language code */
598 	unsigned long	  ucSize;		/* Allocated and used size of ucDesc in wchars, inc null */
599 	ORD16             *ucDesc;		/* The UniCode description (null terminated) */
600 
601 	ORD16             scCode;		/* ScriptCode code */
602 	unsigned long	  scSize;		/* Used size of scDesc in bytes, inc null */
603 	ORD8              scDesc[67];	/* ScriptCode Description (null terminated, max 67) */
604 }; typedef struct _icmTextDescription icmTextDescription;
605 
606 /* Profile sequence structure */
607 struct _icmDescStruct {
608 	/* Private: */
609 	struct _icc      *icp;				/* Pointer to ICC we're a part of */
610 
611 	/* Public: */
612 	int             (*allocate)(struct _icmDescStruct *p);	/* Allocate method */
613     icmSig            deviceMfg;		/* Dev Manufacturer */
614     unsigned int      deviceModel;		/* Dev Model */
615     icmUint64         attributes;		/* Dev attributes */
616     icTechnologySignature technology;	/* Technology sig */
617 	icmTextDescription device;			/* Manufacturer text (sub structure) */
618 	icmTextDescription model;			/* Model text (sub structure) */
619 }; typedef struct _icmDescStruct icmDescStruct;
620 
621 /* Profile sequence description */
622 struct _icmProfileSequenceDesc {
623 	ICM_BASE_MEMBERS
624 
625 	/* Private: */
626 	unsigned int	 _count;			/* number currently allocated */
627 
628 	/* Public: */
629     unsigned int      count;			/* Number of descriptions */
630 	icmDescStruct     *data;			/* array of [count] descriptions */
631 }; typedef struct _icmProfileSequenceDesc icmProfileSequenceDesc;
632 
633 /* signature (only ever used for technology ??) */
634 struct _icmSignature {
635 	ICM_BASE_MEMBERS
636 
637 	/* Public: */
638     icTechnologySignature sig;	/* Signature */
639 }; typedef struct _icmSignature icmSignature;
640 
641 /* Per channel Screening Data */
642 typedef struct {
643 	/* Public: */
644     double            frequency;		/* Frequency */
645     double            angle;			/* Screen angle */
646     icSpotShape       spotShape;		/* Spot Shape encodings below */
647 } icmScreeningData;
648 
649 struct _icmScreening {
650 	ICM_BASE_MEMBERS
651 
652 	/* Private: */
653 	unsigned int   _channels;			/* number currently allocated */
654 
655 	/* Public: */
656     unsigned int      screeningFlag;	/* Screening flag */
657     unsigned int      channels;			/* Number of channels */
658     icmScreeningData  *data;			/* Array of screening data */
659 }; typedef struct _icmScreening icmScreening;
660 
661 /* Under color removal, black generation */
662 struct _icmUcrBg {
663 	ICM_BASE_MEMBERS
664 
665 	/* Private: */
666     unsigned int      UCR_count;		/* Currently allocated UCR count */
667     unsigned int      BG_count;			/* Currently allocated BG count */
668 	unsigned long	  _size;			/* Currently allocated string size */
669 
670 	/* Public: */
671     unsigned int      UCRcount;			/* Undercolor Removal Curve length */
672     double           *UCRcurve;		    /* The array of UCR curve values, 0.0 - 1.0 */
673 										/* or 0.0 - 100 % if count = 1 */
674     unsigned int      BGcount;			/* Black generation Curve length */
675     double           *BGcurve;			/* The array of BG curve values, 0.0 - 1.0 */
676 										/* or 0.0 - 100 % if count = 1 */
677 	unsigned long	  size;				/* Allocated and used size of desc, inc null */
678 	char              *string;			/* UcrBg description (null terminated) */
679 }; typedef struct _icmUcrBg icmUcrBg;
680 
681 /* viewingConditionsType */
682 struct _icmViewingConditions {
683 	ICM_BASE_MEMBERS
684 
685 	/* Public: */
686     icmXYZNumber    illuminant;		/* In candelas per sq. meter */
687     icmXYZNumber    surround;		/* In candelas per sq. meter */
688     icIlluminant    stdIlluminant;	/* See icIlluminant defines */
689 }; typedef struct _icmViewingConditions icmViewingConditions;
690 
691 /* Postscript Color Rendering Dictionary names type */
692 struct _icmCrdInfo {
693 	ICM_BASE_MEMBERS
694 	/* Private: */
695     unsigned long    _ppsize;		/* Currently allocated size */
696 	unsigned long    _crdsize[4];	/* Currently allocated sizes */
697 
698 	/* Public: */
699     unsigned long    ppsize;		/* Postscript product name size (including null) */
700     char            *ppname;		/* Postscript product name (null terminated) */
701 	unsigned long    crdsize[4];	/* Rendering intent 0-3 CRD names sizes (icluding null) */
702 	char            *crdname[4];	/* Rendering intent 0-3 CRD names (null terminated) */
703 }; typedef struct _icmCrdInfo icmCrdInfo;
704 
705 
706 /* Apple ColorSync 2.5 video card gamma type */
707 struct _icmVideoCardGammaTable {
708 	unsigned short   channels;		/* # of gamma channels (1 or 3) */
709 	unsigned short   entryCount; 	/* 1-based number of entries per channel */
710 	unsigned short   entrySize;		/* size in bytes of each entry */
711 	void            *data;			/* variable size data */
712 }; typedef struct _icmVideoCardGammaTable icmVideoCardGammaTable;
713 
714 struct _icmVideoCardGammaFormula {
715 	double           redGamma;		/* must be > 0.0 */
716 	double           redMin;		/* must be > 0.0 and < 1.0 */
717 	double           redMax;		/* must be > 0.0 and < 1.0 */
718 	double           greenGamma;   	/* must be > 0.0 */
719 	double           greenMin;		/* must be > 0.0 and < 1.0 */
720 	double           greenMax;		/* must be > 0.0 and < 1.0 */
721 	double           blueGamma;		/* must be > 0.0 */
722 	double           blueMin;		/* must be > 0.0 and < 1.0 */
723 	double           blueMax;		/* must be > 0.0 and < 1.0 */
724 }; typedef struct _icmVideoCardGammaFormula icmVideoCardGammaFormula;
725 
726 enum {
727 	icmVideoCardGammaTableType = 0,
728 	icmVideoCardGammaFormulaType = 1
729 };
730 
731 struct _icmVideoCardGamma {
732 	ICM_BASE_MEMBERS
733 	unsigned long                tagType;		/* eg. table or formula, use above enum */
734 	union {
735 		icmVideoCardGammaTable   table;
736 		icmVideoCardGammaFormula formula;
737 	} u;
738 }; typedef struct _icmVideoCardGamma icmVideoCardGamma;
739 
740 /* ------------------------------------------------- */
741 /* The Profile header */
742 struct _icmHeader {
743 	/* Private: */
744 	unsigned int           (*get_size)(struct _icmHeader *p);
745 	int                    (*read)(struct _icmHeader *p, unsigned long len, unsigned long of);
746 	int                    (*write)(struct _icmHeader *p, unsigned long of);
747 	void                   (*del)(struct _icmHeader *p);
748 	struct _icc            *icp;			/* Pointer to ICC we're a part of */
749     unsigned int            size;			/* Profile size in bytes */
750 
751 	/* public: */
752 	void                   (*dump)(struct _icmHeader *p, FILE *op, int verb);
753 
754 	/* Values that must be set before writing */
755     icProfileClassSignature deviceClass;	/* Type of profile */
756     icColorSpaceSignature   colorSpace;		/* Clr space of data */
757     icColorSpaceSignature   pcs;			/* PCS: XYZ or Lab */
758     icRenderingIntent       renderingIntent;/* Rendering intent */
759 
760 	/* Values that should be set before writing */
761     icmSig                  manufacturer;	/* Dev manufacturer */
762     icmSig		            model;			/* Dev model */
763     icmUint64               attributes;		/* Device attributes.l */
764     unsigned int            flags;			/* Various bits */
765 
766 	/* Values that may optionally be set before writing */
767     /* icmUint64            attributes;		   Device attributes.h (see above) */
768     icmSig                  creator;		/* Profile creator */
769 
770 	/* Values that are not normally set, since they have defaults */
771     icmSig                  cmmId;			/* CMM for profile */
772     int            			majv, minv, bfv;/* Format version - major, minor, bug fix */
773     icmDateTimeNumber       date;			/* Creation Date */
774     icPlatformSignature     platform;		/* Primary Platform */
775     icmXYZNumber            illuminant;		/* Profile illuminant */
776 
777 }; typedef struct _icmHeader icmHeader;
778 
779 /* ---------------------------------------------------------- */
780 /* Objects for accessing lookup functions */
781 
782 /* Public: Parameter to get_luobj function */
783 typedef enum {
784     icmFwd           = 0,  /* Device to PCS, or Device 1 to Last Device */
785     icmBwd           = 1,  /* PCS to Device, or Last Device to Device */
786     icmGamut         = 2,  /* PCS Gamut check */
787     icmPreview       = 3   /* PCS to PCS preview */
788 } icmLookupFunc;
789 
790 /* Public: Parameter to get_luobj function */
791 typedef enum {
792     icmLuOrdNorm     = 0,  /* Normal profile preference: Lut, matrix, monochrome */
793     icmLuOrdRev      = 1   /* Reverse profile preference: monochrome, matrix, monochrome */
794 } icmLookupOrder;
795 
796 /* Public: Lookup algorithm object type */
797 typedef enum {
798     icmMonoFwdType       = 0,	/* Monochrome, Forward */
799     icmMonoBwdType       = 1,	/* Monochrome, Backward */
800     icmMatrixFwdType     = 2,	/* Matrix, Forward */
801     icmMatrixBwdType     = 3,	/* Matrix, Backward */
802     icmLutType           = 4	/* Multi-dimensional Lookup Table */
803 } icmLuAlgType;
804 
805 #define LU_ICM_BASE_MEMBERS																	\
806 	/* Private: */																		\
807 	icmLuAlgType   ttype;		    	/* The object tag */							\
808 	struct _icc    *icp;				/* Pointer to ICC we're a part of */			\
809 	icRenderingIntent intent;			/* Effective intent */							\
810 	icmLookupFunc function;				/* Functionality being used */					\
811 	icmXYZNumber pcswht, whitePoint, blackPoint;	/* White and black point info */	\
812 	double toAbs[3][3];					/* Matrix to convert from relative to absolute */ \
813 	double fromAbs[3][3];				/* Matrix to convert from absolute to relative */ \
814     icColorSpaceSignature inSpace;		/* Native Clr space of input */					\
815     icColorSpaceSignature outSpace;		/* Native Clr space of output */				\
816 	icColorSpaceSignature pcs;			/* Native PCS */								\
817     icColorSpaceSignature e_inSpace;	/* Effective Clr space of input */				\
818     icColorSpaceSignature e_outSpace;	/* Effective Clr space of output */				\
819 	icColorSpaceSignature e_pcs;		/* Effective PCS */								\
820 																						\
821 	/* Public: */																		\
822 	void           (*del)(struct _icmLuBase *p);										\
823 	                            /* Internal native colorspaces */     							\
824 	void           (*lutspaces) (struct _icmLuBase *p, icColorSpaceSignature *ins, int *inn,	\
825 	                                                   icColorSpaceSignature *outs, int *outn);	\
826 	                                                                                        \
827 	                         /* External effecive colorspaces */							\
828 	void           (*spaces) (struct _icmLuBase *p, icColorSpaceSignature *ins, int *inn,	\
829 	                                 icColorSpaceSignature *outs, int *outn,				\
830 	                                 icmLuAlgType *alg, icRenderingIntent *intt, 			\
831 	                                 icmLookupFunc *fnc, icColorSpaceSignature *pcs); 		\
832 																							\
833 	/* Get the effective input space and output space ranges */								\
834 	void (*get_ranges) (struct _icmLuBase *p,												\
835 		double *inmin, double *inmax,		/* Maximum range of inspace values */			\
836 		double *outmin, double *outmax);	/* Maximum range of outspace values */			\
837 																							\
838 	void           (*wh_bk_points)(struct _icmLuBase *p, icmXYZNumber *wht, icmXYZNumber *blk);	\
839 	int            (*lookup) (struct _icmLuBase *p, double *out, double *in);
840 
841 	/* Translate color values through profile */
842 	/* 0 = success */
843 	/* 1 = warning: clipping occured */
844 	/* 2 = fatal: other error */
845 
846 /* Base lookup object */
847 struct _icmLuBase {
848 	LU_ICM_BASE_MEMBERS
849 }; typedef struct _icmLuBase icmLuBase;
850 
851 /* Monochrome  Fwd & Bwd type object */
852 struct _icmLuMono {
853 	LU_ICM_BASE_MEMBERS
854 	icmCurve    *grayCurve;
855 
856 	/* Overall lookups */
857 	int (*fwd_lookup) (struct _icmLuBase *p, double *out, double *in);
858 	int (*bwd_lookup) (struct _icmLuBase *p, double *out, double *in);
859 
860 	/* Components of lookup */
861 	int (*fwd_curve) (struct _icmLuMono *p, double *out, double *in);
862 	int (*fwd_map)   (struct _icmLuMono *p, double *out, double *in);
863 	int (*fwd_abs)   (struct _icmLuMono *p, double *out, double *in);
864 	int (*bwd_abs)   (struct _icmLuMono *p, double *out, double *in);
865 	int (*bwd_map)   (struct _icmLuMono *p, double *out, double *in);
866 	int (*bwd_curve) (struct _icmLuMono *p, double *out, double *in);
867 
868 }; typedef struct _icmLuMono icmLuMono;
869 
870 /* 3D Matrix Fwd & Bwd type object */
871 struct _icmLuMatrix {
872 	LU_ICM_BASE_MEMBERS
873 	icmCurve    *redCurve, *greenCurve, *blueCurve;
874 	icmXYZArray *redColrnt, *greenColrnt, *blueColrnt;
875     double		mx[3][3];	/* 3 * 3 conversion matrix */
876     double		bmx[3][3];	/* 3 * 3 backwards conversion matrix */
877 
878 	/* Overall lookups */
879 	int (*fwd_lookup) (struct _icmLuBase *p, double *out, double *in);
880 	int (*bwd_lookup) (struct _icmLuBase *p, double *out, double *in);
881 
882 	/* Components of lookup */
883 	int (*fwd_curve)  (struct _icmLuMatrix *p, double *out, double *in);
884 	int (*fwd_matrix) (struct _icmLuMatrix *p, double *out, double *in);
885 	int (*fwd_abs)    (struct _icmLuMatrix *p, double *out, double *in);
886 	int (*bwd_abs)    (struct _icmLuMatrix *p, double *out, double *in);
887 	int (*bwd_matrix) (struct _icmLuMatrix *p, double *out, double *in);
888 	int (*bwd_curve)  (struct _icmLuMatrix *p, double *out, double *in);
889 
890 }; typedef struct _icmLuMatrix icmLuMatrix;
891 
892 /* Multi-D. Lut type object */
893 struct _icmLuLut {
894 	LU_ICM_BASE_MEMBERS
895 
896 	/* private: */
897 	icmLut *lut;								/* Lut to use */
898 	int    usematrix;							/* non-zero if matrix should be used */
899     double imx[3][3];							/* 3 * 3 inverse conversion matrix */
900 	int    imx_valid;							/* Inverse matrix is valid */
901 	void (*in_normf)(double *out, double *in);	/* Lut input data normalizing function */
902 	void (*in_denormf)(double *out, double *in);/* Lut input data de-normalizing function */
903 	void (*out_normf)(double *out, double *in);	/* Lut output data normalizing function */
904 	void (*out_denormf)(double *out, double *in);/* Lut output de-normalizing function */
905 	void (*e_in_denormf)(double *out, double *in);/* Effective input de-normalizing function */
906 	void (*e_out_denormf)(double *out, double *in);/* Effecive output de-normalizing function */
907 	/* function chosen out of lut->lookup_clut_sx and lut->lookup_clut_nl to imp. clut() */
908 	int (*lookup_clut) (struct _icmLut *pp, double *out, double *in);	/* clut function */
909 
910 	/* public: */
911 
912 	/* Components of lookup */
913 	int (*in_abs)  (struct _icmLuLut *p, double *out, double *in);	/* Should be in icmLut ? */
914 	int (*matrix)  (struct _icmLuLut *p, double *out, double *in);
915 	int (*input)   (struct _icmLuLut *p, double *out, double *in);
916 	int (*clut)    (struct _icmLuLut *p, double *out, double *in);
917 	int (*output)  (struct _icmLuLut *p, double *out, double *in);
918 	int (*out_abs) (struct _icmLuLut *p, double *out, double *in);	/* Should be in icmLut ? */
919 
920 	/* Some inverse components */
921 	/* Should be in icmLut ??? */
922 	int (*inv_out_abs) (struct _icmLuLut *p, double *out, double *in);
923 	int (*inv_output)  (struct _icmLuLut *p, double *out, double *in);
924 	/* inv_clut is beyond scope of icclib. See argyll for solution! */
925 	int (*inv_input)   (struct _icmLuLut *p, double *out, double *in);
926 	int (*inv_matrix)  (struct _icmLuLut *p, double *out, double *in);
927 	int (*inv_in_abs)  (struct _icmLuLut *p, double *out, double *in);
928 
929 	/* Get various types of information about the LuLut */
930 	void (*get_info) (struct _icmLuLut *p, icmLut **lutp,
931 	                 icmXYZNumber *pcswhtp, icmXYZNumber *whitep,
932 	                 icmXYZNumber *blackp);
933 
934 	/* Get the native input space and output space ranges */
935 	void (*get_lutranges) (struct _icmLuLut *p,
936 		double *inmin, double *inmax,		/* Maximum range of inspace values */
937 		double *outmin, double *outmax);	/* Maximum range of outspace values */
938 
939 	/* Get the matrix contents */
940 	void (*get_matrix) (struct _icmLuLut *p, double m[3][3]);
941 
942 }; typedef struct _icmLuLut icmLuLut;
943 
944 /* ---------------------------------------------------------- */
945 /* A tag */
946 typedef struct {
947     icTagSignature      sig;			/* The tag signature */
948 	icTagTypeSignature  ttype;			/* The tag type signature */
949     unsigned int        offset;			/* File offset to start header */
950     unsigned int        size;			/* Size in bytes */
951 	icmBase            *objp;			/* In memory data structure */
952 } icmTag;
953 
954 /* Pseudo enumerations valid as parameter to get_luobj(): */
955 
956 /* To be specified where an intent is not appropriate */
957 #define icmDefaultIntent ((icRenderingIntent)98)
958 
959 /* Pseudo PCS colospace used to indicate the native PCS */
960 #define icmSigDefaultData ((icColorSpaceSignature) 0x0)
961 
962 
963 /* The ICC object */
964 struct _icc {
965 	/* Public: */
966 	unsigned int (*get_size)(struct _icc *p);				/* Return total size needed, 0 = err. */
967 	int          (*read)(struct _icc *p, icmFile *fp, unsigned long of);	/* Returns error code */
968 	int          (*write)(struct _icc *p, icmFile *fp, unsigned long of);/* Returns error code */
969 	void         (*dump)(struct _icc *p, FILE *op, int verb);	/* Dump whole icc */
970 	void         (*del)(struct _icc *p);						/* Free whole icc */
971 	int          (*find_tag)(struct _icc *p, icTagSignature sig);
972 															/* Returns 1 if found, 2 readable */
973 	icmBase *    (*read_tag)(struct _icc *p, icTagSignature sig);
974 															/* Returns pointer to object */
975 	icmBase *    (*add_tag)(struct _icc *p, icTagSignature sig, icTagTypeSignature ttype);
976 															/* Returns pointer to object */
977 	int          (*rename_tag)(struct _icc *p, icTagSignature sig, icTagSignature sigNew);
978 															/* Rename and existing tag */
979 	icmBase *    (*link_tag)(struct _icc *p, icTagSignature sig, icTagSignature ex_sig);
980 															/* Returns pointer to object */
981 	int          (*unread_tag)(struct _icc *p, icTagSignature sig);
982 														/* Unread a tag (free on refcount == 0 */
983 	int          (*read_all_tags)(struct _icc *p); /* Read all the tags, non-zero on error. */
984 
985 	int          (*delete_tag)(struct _icc *p, icTagSignature sig);
986 															/* Returns 0 if deleted OK */
987 	icmLuBase *  (*get_luobj) (struct _icc *p,
988                                      icmLookupFunc func,			/* Functionality */
989 	                                 icRenderingIntent intent,		/* Intent */
990 	                                 icColorSpaceSignature pcsor,	/* PCS overide (0 = def) */
991 	                                 icmLookupOrder order);			/* Search Order */
992 	                                 /* Return appropriate lookup object */
993 	                                 /* NULL on error, check errc+err for reason */
994 
995 
996     icmHeader       *header;			/* The header */
997 	char             err[512];			/* Error message */
998 	int              errc;				/* Error code */
999 
1000 	/* Private: ? */
1001 	icmAlloc        *al;				/* Heap allocator */
1002 	int              del_al;			/* NZ if heap allocator should be deleted */
1003 	icmFile         *fp;				/* File associated with object */
1004 	unsigned long    of;				/* Offset of the profile within the file */
1005     unsigned int     count;				/* Num tags in the profile */
1006     icmTag          *data;    			/* The tagTable and tagData */
1007 
1008 	}; typedef struct _icc icc;
1009 
1010 /* ========================================================== */
1011 /* Utility structures and declarations */
1012 
1013 /* Structure to hold pseudo-hilbert counter info */
1014 struct _psh {
1015 	int      di;	/* Dimensionality */
1016 	unsigned res;	/* Resolution per coordinate */
1017 	unsigned bits;	/* Bits per coordinate */
1018 	unsigned ix;	/* Current binary index */
1019 	unsigned tmask;	/* Total 2^n count mask */
1020 	unsigned count;	/* Usable count */
1021 }; typedef struct _psh psh;
1022 
1023 /* Type of encoding to be returned as a string */
1024 typedef enum {
1025     icmScreenEncodings,
1026     icmDeviceAttributes,
1027 	icmProfileHeaderFlags,
1028 	icmAsciiOrBinaryData,
1029 	icmTagSignature,
1030 	icmTechnologySignature,
1031 	icmTypeSignature,
1032 	icmColorSpaceSignature,
1033 	icmProfileClassSignaure,
1034 	icmPlatformSignature,
1035 	icmMeasurementFlare,
1036 	icmMeasurementGeometry,
1037 	icmRenderingIntent,
1038 	icmSpotShape,
1039 	icmStandardObserver,
1040 	icmIlluminant,
1041 	icmLuAlg
1042 } icmEnumType;
1043 
1044 /* ========================================================== */
1045 /* Public function declarations */
1046 /* Create an empty object. Return null on error */
1047 extern ICCLIB_API icc *new_icc(void);				/* Default allocator */
1048 extern ICCLIB_API icc *new_icc_a(icmAlloc *al);		/* With allocator class */
1049 
1050 /* - - - - - - - - - - - - - */
1051 /* Some useful utilities: */
1052 
1053 /* Return a string that represents a tag */
1054 extern ICCLIB_API char *tag2str(int tag);
1055 
1056 /* Return a tag created from a string */
1057 extern ICCLIB_API int str2tag(const char *str);
1058 
1059 /* Return a string description of the given enumeration value */
1060 extern ICCLIB_API const char *icm2str(icmEnumType etype, int enumval);
1061 
1062 /* CIE XYZ to perceptual Lab */
1063 extern ICCLIB_API void icmXYZ2Lab(icmXYZNumber *w, double *out, double *in);
1064 
1065 /* Perceptual Lab to CIE XYZ */
1066 extern ICCLIB_API void icmLab2XYZ(icmXYZNumber *w, double *out, double *in);
1067 
1068 /* The standard D50 illuminant value */
1069 extern ICCLIB_API icmXYZNumber icmD50;
1070 
1071 /* The standard D65 illuminant value */
1072 extern ICCLIB_API icmXYZNumber icmD65;
1073 
1074 /* The default black value */
1075 extern ICCLIB_API icmXYZNumber icmBlack;
1076 
1077 /* Initialise a pseudo-hilbert grid counter, return total usable count. */
1078 extern ICCLIB_API unsigned psh_init(psh *p, int di, unsigned res, int co[]);
1079 
1080 /* Reset the counter */
1081 extern ICCLIB_API void psh_reset(psh *p);
1082 
1083 /* Increment pseudo-hilbert coordinates */
1084 /* Return non-zero if count rolls over to 0 */
1085 extern ICCLIB_API int psh_inc(psh *p, int co[]);
1086 
1087 /* Chromatic Adaption transform utility */
1088 /* Return a 3x3 chromatic adaption matrix */
1089 void icmChromAdaptMatrix(
1090 	int flags,				/* Flags as defined below */
1091 	icmXYZNumber d_wp,		/* Destination white point */
1092 	icmXYZNumber s_wp,		/* Source white point */
1093 	double mat[3][3]		/* Destination matrix */
1094 );
1095 
1096 #define ICM_CAM_BRADFORD	0x0001	/* Use Bradford sharpened response space */
1097 #define ICM_CAM_MULMATRIX	0x0002	/* Transform the given matrix */
1098 
1099 /* Return the normal Delta E given two Lab values */
1100 extern ICCLIB_API double icmLabDE(double *in1, double *in2);
1101 
1102 /* Return the normal Delta E squared, given two Lab values */
1103 extern ICCLIB_API double icmLabDEsq(double *in1, double *in2);
1104 
1105 /* Return the CIE94 Delta E color difference measure for two Lab values */
1106 extern ICCLIB_API double icmCIE94(double *in1, double *in2);
1107 
1108 /* Return the CIE94 Delta E color difference measure squared, for two Lab values */
1109 extern ICCLIB_API double icmCIE94sq(double *in1, double *in2);
1110 
1111 /* Simple macro to transfer an array to an XYZ number */
1112 #define icmAry2XYZ(xyz, ary) ((xyz).X = (ary)[0], (xyz).Y = (ary)[1], (xyz).Z = (ary)[2])
1113 
1114 /* And the reverse */
1115 #define icmXYZ2Ary(ary, xyz) ((ary)[0] = (xyz).X, (ary)[1] = (xyz).Y, (ary)[2] = (xyz).Z)
1116 
1117 /* ---------------------------------------------------------- */
1118 
1119 #ifdef __cplusplus
1120 	}
1121 #endif
1122 
1123 #endif /* ICC_H */
1124 
1125