summaryrefslogtreecommitdiff
path: root/xicc/xcolorants.h
blob: 804fea5aec1e17a833af78a90a80b63870463b89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#ifndef XCOLORANTS_H
#define XCOLORANTS_H
/* 
 * International Color Consortium color transform expanded support
 * Known colorant definitions.
 */

/*
 * Author:  Graeme W. Gill
 * Date:    24/2/2002
 * Version: 1.00
 *
 * Copyright 2002 Graeme W. Gill
 * All rights reserved.
 * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
 * see the License.txt file for licencing details.
 *
 */

/* Some standard defines for known generic ink colors */

/*
   Note that we don't handle the issue of an arbitrary ink order,
   and we are only partially coping with multi-ink ICC profiles
   mapping to xcolorants and back. This is supported by mapping
   inkmask to ICC ColorantTable names and back (if needed),
   or by guessing colorants to match profile (icx_icc_cv_to_colorant_comb()).

   default xcolorant order matches the concrete ICC order, but
   ICC icSigXXcolorData could be in any order, and xcolorants
   currently doesn't handle it.

   One way of encapsulating things would be to change inkmask to:

	struct {
		unsigned int attr;							// Attributes (ie. Additive)
		unsigned int mask[(ICX_MXINKS + 31)/32];	// Ink masks
		int inks[MAX_CHAN];							// icx_ink_table[] index
	} inkmask;

   Then add appropriate macros & functions to replace current bit mask logic.

   Would it be easier to make all Argyll internal handling conform
   to the standard xcolorants order, and translate in the ICC file I/O ?
   MPP and .ti? files are assumed/made to conform to xcolorants order.
   
   Another change would be to make xcolorants an object,
   with dynamic colorant and colorant combination values.
   These would be initialised to defaults, but could then
   be added to at run time, to support import/export to
   other color data formats, and coping with arbitrary raster
   files etc.

   Handling the "colorant" of non-device type color channels
   is also a challenge (ie., Lab, Hsv etc.)

 */ 

/* Maximum number of simultanious inks allowed for */
#define ICX_MXINKS 31

/* Note that new inks need to be added to icx_ink_table[] in xcolorants.c ! */

/* The type of the inkmask (allow for expansion) */
typedef unsigned int inkmask;

/* The ink mask enumeration */
#define ICX_ADDITIVE          0x80000000	/* Special flag indicating addive colorants */
#define ICX_INVERTED          0x40000000	/* Special flag indicating actual device is */
											/* the inverse of the perported additive/subtractive */
#define ICX_CYAN              0x00000001
#define ICX_MAGENTA           0x00000002
#define ICX_YELLOW            0x00000004
#define ICX_BLACK             0x00000008
#define ICX_ORANGE            0x00000010
#define ICX_RED               0x00000020
#define ICX_GREEN             0x00000040
#define ICX_BLUE              0x00000080
#define ICX_WHITE             0x00000100
#define ICX_LIGHT_CYAN        0x00010000
#define ICX_LIGHT_MAGENTA     0x00020000
#define ICX_LIGHT_YELLOW      0x00040000
#define ICX_LIGHT_BLACK       0x00080000
#define ICX_MEDIUM_CYAN       0x00100000
#define ICX_MEDIUM_MAGENTA    0x00200000
#define ICX_MEDIUM_YELLOW     0x00400000
#define ICX_MEDIUM_BLACK      0x00800000
#define ICX_LIGHT_LIGHT_BLACK 0x01000000

/* Character representation */
#define ICX_C_CYAN              "C"
#define ICX_C_MAGENTA           "M"
#define ICX_C_YELLOW            "Y"
#define ICX_C_BLACK             "K"
#define ICX_C_ORANGE            "O"
#define ICX_C_RED               "R"
#define ICX_C_GREEN             "G"
#define ICX_C_BLUE              "B"
#define ICX_C_WHITE             "W"
#define ICX_C_LIGHT_CYAN        "c"
#define ICX_C_LIGHT_MAGENTA     "m"
#define ICX_C_LIGHT_YELLOW      "y"
#define ICX_C_LIGHT_BLACK       "k"
#define ICX_C_MEDIUM_CYAN       "2c"
#define ICX_C_MEDIUM_MAGENTA    "2m"
#define ICX_C_MEDIUM_YELLOW     "2y"
#define ICX_C_MEDIUM_BLACK      "2k"
#define ICX_C_LIGHT_LIGHT_BLACK "1k"

/* Everyday String representation (max 31 chars) */
#define ICX_S_CYAN              "Cyan"
#define ICX_S_MAGENTA           "Magenta"
#define ICX_S_YELLOW            "Yellow"
#define ICX_S_BLACK             "Black"
#define ICX_S_ORANGE            "Orange"
#define ICX_S_RED               "Red"
#define ICX_S_GREEN             "Green"
#define ICX_S_BLUE              "Blue"
#define ICX_S_WHITE             "White"
#define ICX_S_LIGHT_CYAN        "Light Cyan"
#define ICX_S_LIGHT_MAGENTA     "Light Magenta"
#define ICX_S_LIGHT_YELLOW      "Light Yellow"
#define ICX_S_LIGHT_BLACK       "Light Black"
#define ICX_S_MEDIUM_CYAN       "Medium Cyan"
#define ICX_S_MEDIUM_MAGENTA    "Medium Magenta"
#define ICX_S_MEDIUM_YELLOW     "Medium Yellow"
#define ICX_S_MEDIUM_BLACK      "Medium Black"
#define ICX_S_LIGHT_LIGHT_BLACK "Light Light Black"

/* Postscript string representation */
#define ICX_PS_CYAN              "Cyan"
#define ICX_PS_MAGENTA           "Magenta"
#define ICX_PS_YELLOW            "Yellow"
#define ICX_PS_BLACK             "Black"
#define ICX_PS_ORANGE            "Orange"
#define ICX_PS_RED               "Red"
#define ICX_PS_GREEN             "Green"
#define ICX_PS_BLUE              "Blue"
#define ICX_PS_WHITE             "White"
#define ICX_PS_LIGHT_CYAN        "LightCyan"
#define ICX_PS_LIGHT_MAGENTA     "LightMagenta"
#define ICX_PS_LIGHT_YELLOW      "LightYellow"
#define ICX_PS_LIGHT_BLACK       "LightBlack"
#define ICX_PS_MEDIUM_CYAN       "MediumCyan"
#define ICX_PS_MEDIUM_MAGENTA    "MediumMagenta"
#define ICX_PS_MEDIUM_YELLOW     "MediumYellow"
#define ICX_PS_MEDIUM_BLACK      "MediumBlack"
#define ICX_PS_LIGHT_LIGHT_BLACK "LightLightBlack"

/* Common colorant combinations */
#define ICX_W						/* Video style "grey" */ \
	(ICX_ADDITIVE | ICX_WHITE)

#define ICX_RGB						/* Classic video RGB */ \
	(ICX_ADDITIVE | ICX_RED | ICX_GREEN | ICX_BLUE)

#define ICX_K						/* Printer style "grey" */ \
	(ICX_BLACK)

#define ICX_CMY						/* Classic printing CMY */ \
	(ICX_CYAN | ICX_MAGENTA | ICX_YELLOW)

#define ICX_IRGB					/* Fake printer RGB (== Inverted CMY) */ \
	(ICX_ADDITIVE | ICX_INVERTED | ICX_RED | ICX_GREEN | ICX_BLUE)

#define ICX_CMYK					/* Classic printing CMYK */ \
	(ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK)

#define ICX_CMYKcm					/* Your bog standard "6 color" printers */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_LIGHT_CYAN | ICX_LIGHT_MAGENTA)

#define ICX_CMYKcmk					/* A more unusual "7 color" printer */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_LIGHT_CYAN | ICX_LIGHT_MAGENTA | ICX_LIGHT_BLACK)

#define ICX_CMYKcmk1k				/* A more unusual "8 color" printer */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_LIGHT_CYAN | ICX_LIGHT_MAGENTA | ICX_LIGHT_BLACK \
	 | ICX_LIGHT_LIGHT_BLACK)

#define ICX_CMYKOG					/* A "hexachrome" style extended gamut printer */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_ORANGE | ICX_GREEN)

#define ICX_CMYKOGB					/* A "hexachrome" _ Blue style extended gamut printer */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_ORANGE | ICX_GREEN | ICX_BLUE)

#define ICX_CMYKRB					/* A 6 color printer with red and blue. */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_RED | ICX_BLUE)

#define ICX_CMYKRGB					/* A 7 color printer with RGB */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_RED | ICX_GREEN | ICX_BLUE)

#define ICX_CMYKOGcm				/* An 8 color extended gamut printer */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_ORANGE | ICX_GREEN | ICX_LIGHT_CYAN | ICX_LIGHT_MAGENTA)

#define ICX_CMYKcm2c2m				/* An 8 color printer that wishes it had variable dot size */ \
	(  ICX_CYAN | ICX_MAGENTA | ICX_YELLOW | ICX_BLACK \
	 | ICX_LIGHT_CYAN | ICX_LIGHT_MAGENTA | ICX_MEDIUM_CYAN | ICX_MEDIUM_MAGENTA)

/* ------------------------------------------ */

/* Given an ink combination mask, return the number of recognised inks in it */
int icx_noofinks(inkmask mask);

/* Given an ink combination mask, return the 1-2 character based string */
/* If winv is nz, include ICX_INVERTED indicator if set */
/* Return NULL on error. free() after use */
char *icx_inkmask2char(inkmask mask, int winv);

/* Given the 1-2 character based string, return the ink combination mask */
/* Note that ICX_ADDITIVE will be guessed */
/* Return 0 if unrecognised character in string */
inkmask icx_char2inkmask(char *chstring); 

/* Given an ink combination mask that may contain light inks, */
/* return the corresponding ink mask without light inks. */
/* Return 0 if ink combination not recognised. */
inkmask icx_ink2primary_ink(inkmask mask);


/* Given an ink combination mask and a single ink mask, */
/* return the index number for that ink. */
/* Return -1 if mask1 not in mask */
int icx_ink2index(inkmask mask, inkmask mask1);

/* Given an ink combination mask and a index number, */
/* return the single ink mask. */
/* Return 0 if there are no inks at that index */
inkmask icx_index2ink(inkmask mask, int ixno);


/* Given a single ink mask, */
/* return its string representation */
char *icx_ink2string(inkmask mask); 

/* Given a single ink mask, */
/* return its 1-2 character representation */
char *icx_ink2char(inkmask mask); 

/* Given a single ink mask, */
/* return its Postscript string representation */
char *icx_ink2psstring(inkmask mask); 


/* Return an enumerated single colorant description */
/* Return 0 if no such enumeration, single colorant mask if there is */
inkmask icx_enum_colorant(int no, char **desc);

/* Return an enumerated colorant combination inkmask and description */
/* Return 0 if no such enumeration, colorant combination mask if there is */
inkmask icx_enum_colorant_comb(int no, char **desc);


/* Given an colorant combination mask, */
/* check if it matches the given ICC colorspace signature. */ 
/* return NZ if it does. */
int icx_colorant_comb_match_icc(inkmask mask, icColorSpaceSignature sig);

#ifndef SALONEINSTLIB

/* Given an ICC colorspace signature, return the appropriate */
/* colorant combination mask. Return 0 if ambiguous signature. */
inkmask icx_icc_to_colorant_comb(icColorSpaceSignature sig, icProfileClassSignature deviceClass);

/* Given an ICC colorspace signature, and a matching list */
/* of the D50 L*a*b* colors of the colorants, return the best matching */
/* colorant combination mask. Return 0 if not applicable to colorspace. */
inkmask icx_icc_cv_to_colorant_comb(icColorSpaceSignature sig, icProfileClassSignature deviceClass,
                                    double cvals[][3]);

/* Given an colorant combination mask */
/* return the primary matching ICC colorspace signature. */ 
/* return 0 if there is no match */
icColorSpaceSignature icx_colorant_comb_to_icc(inkmask mask);

#endif /* !SALONEINSTLIB */

/* --------------------------------------------------------- */
/* An aproximate device colorant model object lookup object: */

struct _icxColorantLu {
/* Public: */
	void (*del)(struct _icxColorantLu *s);	/* We're done with it */

	/* Conversions */
	void (*dev_to_XYZ)(struct _icxColorantLu *s, double *out, double *in);	/* Absolute */
	void (*dev_to_rLab)(struct _icxColorantLu *s, double *out, double *in);	/* Relative */

/* Private: */
	inkmask mask;				/* Colorant mask for this instance */
	int di;						/* Dimensionality */
	int whix, bkix;				/* White and Black Indexes into icx_inkTable[] */
	icmXYZNumber wp;			/* White point XYZ value */
	int iix[ICX_MXINKS];		/* Device Indexes into icx_inkTable[] */
	double Ynorm;				/* Y normalisation factor for Additive */
}; typedef struct _icxColorantLu icxColorantLu;

/* Create a icxColorantLu conversion object */
icxColorantLu *new_icxColorantLu(inkmask mask);

#endif /* XCOLORANTS_H */