1 /* Copyright (C) 1992, 1995, 1997, 1998, 1999 artofcode LLC.  All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify it
4   under the terms of the GNU General Public License as published by the
5   Free Software Foundation; either version 2 of the License, or (at your
6   option) any later version.
7 
8   This program is distributed in the hope that it will be useful, but
9   WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   General Public License for more details.
12 
13   You should have received a copy of the GNU General Public License along
14   with this program; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16 
17 */
18 
19 /*$Id: gscie.h,v 1.3.2.1.2.1 2003/01/17 00:49:02 giles Exp $ */
20 /* Structures for CIE color algorithms */
21 /* (requires gscspace.h, gscolor2.h) */
22 
23 #ifndef gscie_INCLUDED
24 #  define gscie_INCLUDED
25 
26 #include "gconfigv.h"		/* for USE_FPU */
27 #include "gsrefct.h"
28 #include "gsstype.h"		/* for extern_st */
29 #include "gxctable.h"
30 
31 /* ---------------- Configuration parameters ---------------- */
32 
33 /* Define the size of the Encode/Decode/Transform procedure value caches. */
34 /* With the current design, these caches must all have the same size. */
35 #ifndef CIE_LOG2_CACHE_SIZE
36 #  define CIE_LOG2_CACHE_SIZE 9
37 #endif
38 
39 /* Define whether to use fixed- or floating-point values in the caches. */
40 /*#define CIE_CACHE_USE_FIXED */
41 #if USE_FPU < 0
42 #  define CIE_CACHE_USE_FIXED
43 #endif
44 
45 /* If we are using fixed-point values, define the number of fraction bits. */
46 #define CIE_FIXED_FRACTION_BITS 12
47 
48 /* Define whether to interpolate between cached values. */
49 #define CIE_CACHE_INTERPOLATE
50 
51 /* Define whether to interpolate at all intermediate lookup steps. */
52 /* This is computationally expensive and doesn't seem to improve */
53 /* the accuracy of the result. */
54 /*#define CIE_INTERPOLATE_INTERMEDIATE */
55 
56 /* Define whether to interpolate in the RenderTable. */
57 /* This is computationally very expensive, so it is normally disabled. */
58 #define CIE_RENDER_TABLE_INTERPOLATE
59 
60 /* ------ Derived values ------ */
61 
62 /* from CIE_LOG2_CACHE_SIZE */
63 #define gx_cie_log2_cache_size CIE_LOG2_CACHE_SIZE
64 #define gx_cie_cache_size (1 << gx_cie_log2_cache_size)
65 
66 /* From CIE_FIXED_FRACTION_BITS 12 */
67 #ifndef CIE_FIXED_FRACTION_BITS
68 /* Take as many bits as we can without having to multiply in two pieces. */
69 #  define CIE_FIXED_FRACTION_BITS\
70      ((arch_sizeof_long * 8 - gx_cie_log2_cache_size) / 2 - 1)
71 #endif
72 
73 /* From CIE_RENDER_TABLE_INTERPOLATE */
74 #ifdef CIE_RENDER_TABLE_INTERPOLATE
75 #  define CIE_CACHE_INTERPOLATE
76 #endif
77 
78 #define float_lshift(v, nb) ((v) * (1L << (nb)))
79 #define float_rshift(v, nb) ((v) * (1.0 / (1L << (nb))))
80 
81 #ifdef CIE_CACHE_INTERPOLATE
82 /* We have to have room for both a cache index and the interpolation bits */
83 /* in a positive int (i.e., leaving 1 bit for the sign), plus a little slop. */
84 /* The values for interpolation are cie_cached_values by default. */
85 #  define _cie_interpolate_bits\
86      min(arch_sizeof_int * 8 - gx_cie_log2_cache_size - 2, 10)
87 #  define _cix(i) ((i) >> _cie_interpolate_bits)
88 #  define _cif(i) ((int)(i) & ((1 << _cie_interpolate_bits) - 1))
89 #  define cie_interpolate_between(v0, v1, i)\
90      ((v0) + cie_cached_rshift(((v1) - (v0)) * _cif(i) +\
91 			        (1 << (_cie_interpolate_bits - 1)),\
92 			       _cie_interpolate_bits))
93 #  define cie_interpolate(p, i)\
94      cie_interpolate_between((p)[_cix(i)], (p)[_cix(i) + 1], i)
95 #  define cie_interpolate_fracs(p, i)\
96      ((p)[_cix(i)] +\
97       (frac)arith_rshift((long)((p)[_cix(i) + 1] - (p)[_cix(i)]) * _cif(i), _cie_interpolate_bits))
98 #else
99 #  define _cie_interpolate_bits 0
100 #  define cie_interpolate_between(v0, v1, i) (v0)
101 #  define cie_interpolate(p, i) ((p)[i])
102 #  define cie_interpolate_fracs(p, i) ((p)[i])
103 #endif
104 
105 #ifdef CIE_CACHE_USE_FIXED
106 typedef long cie_cached_value;
107 
108 #  define _cie_fixed_shift CIE_FIXED_FRACTION_BITS
109 #  define float2cie_cached(v)\
110      ((cie_cached_value)float_lshift(v, _cie_fixed_shift))
111 #  define cie_cached2float(v)\
112      float_rshift(v, _cie_fixed_shift)
113 #  define cie_cached2int(v, fbits)\
114      arith_rshift(v, _cie_fixed_shift - (fbits))
115 /* We are multiplying two cie_cached_values to produce a result that */
116 /* lies between 0 and gx_cie_cache_size - 1.  If the intermediate result */
117 /* might overflow, compute it in pieces (being a little sloppy). */
118 #  define _cie_product_excess_bits\
119      (_cie_fixed_shift * 2 + gx_cie_log2_cache_size - (arch_sizeof_long * 8 - 1))
120 #  define cie_cached_product2int(v, factor, fbits)\
121      (_cie_product_excess_bits > 0 ?\
122       arith_rshift( (v) * arith_rshift(factor, _cie_product_excess_bits) +\
123 		    arith_rshift(v, _cie_product_excess_bits) *\
124 		     ((factor) & ((1 << _cie_product_excess_bits) - 1)),\
125 		    _cie_fixed_shift * 2 - _cie_product_excess_bits - (fbits)) :\
126       arith_rshift((v) * (factor), _cie_fixed_shift * 2 - (fbits)))
127 #  define cie_cached_rshift(v, n) arith_rshift(v, n)
128 #else
129 typedef float cie_cached_value;
130 #  define float2cie_cached(v) (v)
131 #  define cie_cached2float(v) (v)
132 #  define cie_cached2int(v, fbits)\
133      ((int)float_lshift(v, fbits))
134 #  define cie_cached_product2int(v, factor, fbits)\
135      ((int)float_lshift((v) * (factor), fbits))
136 #  define cie_cached_rshift(v, n) float_rshift(v, n)
137 #endif
138 
139 /* ---------------- Structures ---------------- */
140 
141 #ifndef gs_cie_render_DEFINED
142 #  define gs_cie_render_DEFINED
143 typedef struct gs_cie_render_s gs_cie_render;
144 #endif
145 
146 /* ------ Common definitions ------ */
147 
148 /*
149  * For the purposes of the CIE routines, we consider that all the vectors
150  * are column vectors, that the matrices are specified in column order
151  * (e.g., the matrix
152  *      [ A B C ]
153  *      [ D E F ]
154  *      [ G H I ]
155  * is represented as [A D G B E H C F I]), and that to transform a vector
156  * V by a matrix M, we compute M * V to produce another column vector.
157  * Note in particular that in order to produce a matrix M that is
158  * equivalent to transforming by M1 and then by M2, we must compute
159  * M = M2 * M1.
160  */
161 
162 /* A 3-element vector. */
163 typedef struct gs_vector3_s {
164     float u, v, w;
165 } gs_vector3;
166 
167 /* A 3x3 matrix, stored in column order. */
168 typedef struct gs_matrix3_s {
169     gs_vector3 cu, cv, cw;
170     bool is_identity;
171 } gs_matrix3;
172 
173 /* 3- and 4-element vectors of ranges. */
174 typedef struct gs_range_s {
175     float rmin, rmax;
176 } gs_range;
177 typedef struct gs_range3_s {
178     gs_range ranges[3];
179 } gs_range3;
180 typedef struct gs_range4_s {
181     gs_range ranges[4];
182 } gs_range4;
183 
184 /* Client-supplied transformation procedures. */
185 typedef struct gs_cie_common_s gs_cie_common;
186 typedef struct gs_cie_wbsd_s gs_cie_wbsd;
187 
188 typedef float (*gs_cie_a_proc) (P2(floatp, const gs_cie_a *));
189 
190 typedef float (*gs_cie_abc_proc) (P2(floatp, const gs_cie_abc *));
191 typedef struct gs_cie_abc_proc3_s {
192     gs_cie_abc_proc procs[3];
193 } gs_cie_abc_proc3;
194 
195 typedef float (*gs_cie_def_proc) (P2(floatp, const gs_cie_def *));
196 typedef struct gs_cie_def_proc3_s {
197     gs_cie_def_proc procs[3];
198 } gs_cie_def_proc3;
199 
200 typedef float (*gs_cie_defg_proc) (P2(floatp, const gs_cie_defg *));
201 typedef struct gs_cie_defg_proc4_s {
202     gs_cie_defg_proc procs[4];
203 } gs_cie_defg_proc4;
204 
205 typedef float (*gs_cie_common_proc) (P2(floatp, const gs_cie_common *));
206 typedef struct gs_cie_common_proc3_s {
207     gs_cie_common_proc procs[3];
208 } gs_cie_common_proc3;
209 
210 typedef float (*gs_cie_render_proc) (P2(floatp, const gs_cie_render *));
211 typedef struct gs_cie_render_proc3_s {
212     gs_cie_render_proc procs[3];
213 } gs_cie_render_proc3;
214 
215 /*
216  * The TransformPQR procedure depends on both the color space and the
217  * CRD, so we can't simply pass it through the band list as a table of
218  * sampled values, even though such a table exists as part of an
219  * internal cache.  Instead, we use two different approaches.  The
220  * graphics library knows that the cache must be reloaded whenever the
221  * color space or CRD changes, so we can simply transmit the cached
222  * values through the band list whenever this occurs.  However, this
223  * still leaves the issue of how to represent the procedure in the CRD
224  * per se: such a representation is required in order for
225  * currentcolorrendering and setcolorrendering to work.  For this
226  * purpose, we provide a procedure name and procedure data, which
227  * drivers can supply with their default CRDs; the driver must also be
228  * prepared to map the procedure name back to an actual set of
229  * procedures.
230  *
231  * To simplify the driver-provided CRD machinery, we define TransformPQR as
232  * a single procedure taking an integer that specifies the component number,
233  * rather than an array of procedures.  Note that if proc_name != 0,
234  * proc is irrelevant -- the driver will provide it by looking up proc_name.
235  * For this reason, the last argument of TransformPQR must be writable.
236  * Note also that since TransformPQR can fail (if the driver doesn't
237  * recognize the proc_name), it must return a failure code.
238  */
239 typedef int (*gs_cie_transform_proc)(P5(int, floatp, const gs_cie_wbsd *,
240 					gs_cie_render *, float *));
241 typedef struct gs_cie_transform_proc3_s {
242     gs_cie_transform_proc proc;
243     const char *proc_name;
244     gs_const_string proc_data;
245     const char *driver_name;	/* for mapping proc_name back to procs */
246 } gs_cie_transform_proc3;
247 
248 typedef frac(*gs_cie_render_table_proc) (P2(byte, const gs_cie_render *));
249 typedef struct gs_cie_render_table_procs_s {
250     gs_cie_render_table_proc procs[4];
251 } gs_cie_render_table_procs;
252 
253 /* CIE white and black points. */
254 typedef struct gs_cie_wb_s {
255     gs_vector3 WhitePoint;
256     gs_vector3 BlackPoint;
257 } gs_cie_wb;
258 
259 /* ------ Caches ------ */
260 
261 /*
262  * Given that all the client-supplied procedures involved in CIE color
263  * mapping and rendering are monotonic, and given that we can determine
264  * the minimum and maximum input values for them, we can cache their values.
265  * This takes quite a lot of space, but eliminates the need for callbacks
266  * deep in the graphics code (particularly the image operator).
267  *
268  * The procedures, and how we determine their domains, are as follows:
269 
270  Stage          Name            Domain determination
271  -----          ----            --------------------
272  pre-decode     DecodeDEF       RangeDEF
273  pre-decode     DecodeDEFG      RangeDEFG
274  color space    DecodeA         RangeA
275  color space    DecodeABC       RangeABC
276  color space    DecodeLMN       RangeLMN
277  rendering      TransformPQR    RangePQR
278  (but depends on color space White/BlackPoints)
279  rendering      EncodeLMN       RangePQR transformed by the inverse of
280 				MatrixPQR and then by MatrixLMN
281  rendering      EncodeABC       RangeLMN transformed by MatrixABC
282  rendering      RenderTable.T   [0..1]*m
283 
284  * Note that we can mostly cache the results of the color space procedures
285  * without knowing the color rendering parameters, and vice versa,
286  * because of the range parameters supplied in the dictionaries.
287  * Unfortunately, TransformPQR is an exception.
288  */
289 /*
290  * The index into a cache is (value - base) * factor, where
291  * factor is computed as (cie_cache_size - 1) / (rmax - rmin).
292  */
293 /*
294  * We have two kinds of caches: ordinary caches, where each value is
295  * a scalar, and vector caches, where each value is a gs_cached_vector3.
296  * The latter allow us to pre-multiply the values by one column of
297  * a gs_matrix3, avoiding multiplications at lookup time.
298  *
299  * If the function being cached is simply a linear transformation,
300  * f(x) = scale * x + origin, then we can fold it into a following or
301  * preceding matrix.
302  */
303 typedef struct cie_linear_params_s {
304     bool is_linear;
305     float scale, origin;
306 } cie_linear_params_t;
307 typedef struct cie_cache_params_s {
308     bool is_identity;		/* must come first */
309     float base, factor;
310     cie_linear_params_t linear;	/* only used in vector_cache.floats? */
311 } cie_cache_params;
312 typedef struct cie_cache_floats_s {
313     cie_cache_params params;
314     float values[gx_cie_cache_size];
315 } cie_cache_floats;
316 typedef struct cie_cache_fracs_s {
317     cie_cache_params params;
318     frac values[gx_cie_cache_size];
319 } cie_cache_fracs;
320 typedef struct cie_cache_ints_s {
321     cie_cache_params params;
322     int values[gx_cie_cache_size];
323 } cie_cache_ints;
324 typedef union gx_cie_scalar_cache_s {
325     cie_cache_floats floats;
326     cie_cache_fracs fracs;
327     cie_cache_ints ints;
328 } gx_cie_scalar_cache;
329 
330 typedef struct cie_cached_vector3_s {
331     cie_cached_value u, v, w;
332 } cie_cached_vector3;
333 typedef struct cie_vector_cache_params_s {
334     cie_cached_value base, factor, limit;
335 } cie_vector_cache_params;
336 typedef struct cie_cache_vectors_s {
337     cie_vector_cache_params params;
338     cie_cached_vector3 values[gx_cie_cache_size];
339 } cie_cache_vectors;
340 typedef struct gx_cie_vector_cache_s {
341     cie_cache_floats floats;
342     cie_cache_vectors vecs;
343 } gx_cie_vector_cache;
344 
345 /* ------ Color space dictionaries ------ */
346 
347 /* Elements common to all CIE color space dictionaries. */
348 struct gs_cie_common_s {
349     int (*install_cspace)(P2(const gs_color_space *, gs_state *));
350     void *client_data;
351     gs_range3 RangeLMN;
352     gs_cie_common_proc3 DecodeLMN;
353     gs_matrix3 MatrixLMN;
354     gs_cie_wb points;
355     /* Following are computed when structure is initialized. */
356     struct {
357 	gx_cie_scalar_cache DecodeLMN[3];
358     } caches;
359 };
360 
361 /* st_cie_common and st_cie_common_elements_t are exported for gsicc.c */
362 #define public_st_cie_common()     /* in gscscie.c */\
363   gs_public_st_ptrs1(st_cie_common, gs_cie_common, "gs_cie_common",\
364 		      cie_common_enum_ptrs, cie_common_reloc_ptrs, client_data)
365 
366 /* extern_st(st_cie_common); */ /* in gxcie.h */
367 
368 #define gs_cie_common_elements\
369 	gs_cie_common common;		/* must be first */\
370 	rc_header rc
371 typedef struct gs_cie_common_elements_s {
372     gs_cie_common_elements;
373 } gs_cie_common_elements_t;
374 
375 #define public_st_cie_common_elements() /* in gscscie.c */ \
376   gs_public_st_suffix_add0_local( st_cie_common_elements_t,\
377 				  gs_cie_common_elements_t,\
378 				  "gs_cie_common_elements_t",\
379 				  cie_common_enum_ptrs,\
380 				  cie_common_reloc_ptrs,\
381 				  st_cie_common)
382 
383 /* extern_st(st_cie_common_elements_t); */ /* in gxcie.h */
384 
385 /* A CIEBasedA dictionary. */
386 struct gs_cie_a_s {
387     gs_cie_common_elements;	/* must be first */
388     gs_range RangeA;
389     gs_cie_a_proc DecodeA;
390     gs_vector3 MatrixA;
391     /* Following are computed when structure is initialized. */
392     struct {
393 	gx_cie_vector_cache DecodeA;	/* mult. by MatrixA */
394     } caches;
395 };
396 
397 #define private_st_cie_a()	/* in gscscie.c */\
398   gs_private_st_suffix_add0_local(st_cie_a, gs_cie_a, "gs_cie_a",\
399 				  cie_common_enum_ptrs,\
400 				  cie_common_reloc_ptrs,\
401 				  st_cie_common_elements_t)
402 
403 /* Common elements for CIEBasedABC, DEF, and DEFG dictionaries. */
404 #define gs_cie_abc_elements\
405 	gs_cie_common_elements;		/* must be first */\
406 	gs_range3 RangeABC;\
407 	gs_cie_abc_proc3 DecodeABC;\
408 	gs_matrix3 MatrixABC;\
409 		/* Following are computed when structure is initialized. */\
410 	struct {\
411 		bool skipABC;\
412 		gx_cie_vector_cache DecodeABC[3];  /* mult. by MatrixABC */\
413 	} caches
414 
415 /* A CIEBasedABC dictionary. */
416 struct gs_cie_abc_s {
417     gs_cie_abc_elements;
418 };
419 
420 #define private_st_cie_abc()	/* in gscscie.c */\
421   gs_private_st_suffix_add0_local(st_cie_abc, gs_cie_abc, "gs_cie_abc",\
422 				  cie_common_enum_ptrs, cie_common_reloc_ptrs,\
423 				  st_cie_common_elements_t)
424 
425 /* A CIEBasedDEF dictionary. */
426 struct gs_cie_def_s {
427     gs_cie_abc_elements;	/* must be first */
428     gs_range3 RangeDEF;
429     gs_cie_def_proc3 DecodeDEF;
430     gs_range3 RangeHIJ;
431     gx_color_lookup_table Table;	/* [NH][NI * NJ * 3] */
432     struct {
433 	gx_cie_scalar_cache DecodeDEF[3];
434     } caches_def;
435 };
436 
437 #define private_st_cie_def()	/* in gscscie.c */\
438   gs_private_st_suffix_add1(st_cie_def, gs_cie_def, "gs_cie_def",\
439                             cie_def_enum_ptrs, cie_def_reloc_ptrs,\
440                             st_cie_abc, Table.table)
441 
442 /* A CIEBasedDEFG dictionary. */
443 struct gs_cie_defg_s {
444     gs_cie_abc_elements;
445     gs_range4 RangeDEFG;
446     gs_cie_defg_proc4 DecodeDEFG;
447     gs_range4 RangeHIJK;
448     gx_color_lookup_table Table;	/* [NH * NI][NJ * NK * 3] */
449     struct {
450 	gx_cie_scalar_cache DecodeDEFG[4];
451     } caches_defg;
452 };
453 
454 #define private_st_cie_defg()	/* in gscscie.c */\
455   gs_private_st_suffix_add1(st_cie_defg, gs_cie_defg, "gs_cie_defg",\
456 			    cie_defg_enum_ptrs, cie_defg_reloc_ptrs,\
457 			    st_cie_abc, Table.table)
458 
459 /*
460  * Default values for components.  Note that for some components, there are
461  * two sets of default procedures: _default (identity procedures) and
462  * _from_cache (procedures that just return the cached values).
463  */
464 extern const gs_range3 Range3_default;
465 extern const gs_range4 Range4_default;
466 extern const gs_cie_defg_proc4 DecodeDEFG_default;
467 extern const gs_cie_defg_proc4 DecodeDEFG_from_cache;
468 extern const gs_cie_def_proc3 DecodeDEF_default;
469 extern const gs_cie_def_proc3 DecodeDEF_from_cache;
470 extern const gs_cie_abc_proc3 DecodeABC_default;
471 extern const gs_cie_abc_proc3 DecodeABC_from_cache;
472 extern const gs_cie_common_proc3 DecodeLMN_default;
473 extern const gs_cie_common_proc3 DecodeLMN_from_cache;
474 extern const gs_matrix3 Matrix3_default;
475 extern const gs_range RangeA_default;
476 extern const gs_cie_a_proc DecodeA_default;
477 extern const gs_cie_a_proc DecodeA_from_cache;
478 extern const gs_vector3 MatrixA_default;
479 extern const gs_vector3 BlackPoint_default;
480 extern const gs_cie_render_proc3 Encode_default;
481 extern const gs_cie_render_proc3 EncodeLMN_from_cache;
482 extern const gs_cie_render_proc3 EncodeABC_from_cache;
483 extern const gs_cie_transform_proc3 TransformPQR_default;
484 extern const gs_cie_transform_proc3 TransformPQR_from_cache;
485 extern const gs_cie_transform_proc TransformPQR_lookup_proc_name;
486 extern const gs_cie_render_table_procs RenderTableT_default;
487 extern const gs_cie_render_table_procs RenderTableT_from_cache;
488 
489 /* ------ Rendering dictionaries ------ */
490 
491 struct gs_cie_wbsd_s {
492     struct {
493 	gs_vector3 xyz, pqr;
494     } ws, bs, wd, bd;
495 };
496 typedef struct gs_cie_render_table_s {
497     /*
498      * If lookup.table == 0, the other members (of both lookup and T) are
499      * not set.  If not 0, lookup.table points to an array of
500      * st_const_string_elements.
501      */
502     gx_color_lookup_table lookup;
503     gs_cie_render_table_procs T;
504 } gs_cie_render_table_t;
505 typedef enum {
506     CIE_RENDER_STATUS_BUILT,
507     CIE_RENDER_STATUS_INITED,
508     CIE_RENDER_STATUS_SAMPLED,
509     CIE_RENDER_STATUS_COMPLETED
510 } cie_render_status_t;
511 
512 typedef struct gx_cie_float_fixed_cache_s {
513     cie_cache_floats floats;
514     union if_ {
515 	cie_cache_fracs fracs;
516 	cie_cache_ints ints;
517     } fixeds;
518 } gx_cie_float_fixed_cache;
519 
520 /* The main dictionary */
521 struct gs_cie_render_s {
522     cie_render_status_t status;
523     rc_header rc;
524     gs_id id;
525     void *client_data;
526     gs_cie_wb points;
527     gs_matrix3 MatrixPQR;
528     gs_range3 RangePQR;
529     gs_cie_transform_proc3 TransformPQR;
530     gs_matrix3 MatrixLMN;
531     gs_cie_render_proc3 EncodeLMN;
532     gs_range3 RangeLMN;
533     gs_matrix3 MatrixABC;
534     gs_cie_render_proc3 EncodeABC;
535     gs_range3 RangeABC;
536     gs_cie_render_table_t RenderTable;
537     /* Following are computed when structure is initialized. */
538     gs_range3 DomainLMN;
539     gs_range3 DomainABC;
540     gs_matrix3 MatrixABCEncode;
541     cie_cached_value EncodeABC_base[3];
542     gs_matrix3 MatrixPQR_inverse_LMN;
543     gs_vector3 wdpqr, bdpqr;
544     struct {
545 	gx_cie_vector_cache EncodeLMN[3];	/* mult. by M'ABCEncode */
546 	gx_cie_float_fixed_cache EncodeABC[3];
547 	gx_cie_scalar_cache RenderTableT[4];
548 	bool RenderTableT_is_identity;
549     } caches;
550 };
551 
552 /* The CRD type is public only for a type test in zcrd.c. */
553 extern_st(st_cie_render1);
554 #define public_st_cie_render1()	/* in gscrd.c */\
555   gs_public_st_composite(st_cie_render1, gs_cie_render, "gs_cie_render",\
556 			 cie_render1_enum_ptrs, cie_render1_reloc_ptrs)
557 
558 /* ------ Joint caches ------ */
559 
560 /* This cache depends on both the color space and the rendering */
561 /* dictionary -- see above. */
562 typedef enum {
563     CIE_JC_STATUS_BUILT,
564     CIE_JC_STATUS_INITED,
565     CIE_JC_STATUS_COMPLETED
566 } cie_joint_caches_status_t;
567 
568 typedef struct gx_cie_joint_caches_s {
569     /*
570      * The first 4 members are the "key" in the cache.  They behave as
571      * follows:
572      *
573      *    If id_status = COMPLETED, the cache is valid with respect to the
574      *    color space and CRD identified by cspace_id and render_id.
575      *
576      *    If status = COMPLETED, then id_status = COMPLETED also, and for
577      *    every gstate pgs that references this cache, pgs->color_space->id =
578      *    cspace_id and pgs->cie_render->id = render_id; hence the cache is
579      *    valid with respect to that gstate.
580      *
581      * This invariant is maintained because the PostScript CRD-setting
582      * operators, the library's CRD-setting procedure, and the library's
583      * procedures for setting CIE color spaces all unshare the joint caches
584      * and set status in the new copy to something other than COMPLETED.
585      *
586      * The only reason for id_status is that certain client code often
587      * resets the CRD and/or color space and then sets it back to its
588      * original value, and we want to detect that and not invalidate the
589      * caches.  If it weren't for that, setcolorspace and setcolorrendering
590      * could simply invalidate the caches.
591      */
592     gs_id cspace_id;
593     gs_id render_id;
594     cie_joint_caches_status_t id_status;
595     cie_joint_caches_status_t status;
596     rc_header rc;
597     bool skipDecodeABC;
598     bool skipDecodeLMN;
599     gx_cie_vector_cache DecodeLMN[3];	/* mult. by dLMN_PQR */
600     gs_cie_wbsd points_sd;
601     bool skipPQR;
602     gx_cie_vector_cache TransformPQR[3];	/* mult. by PQR_inverse_LMN */
603     bool skipEncodeLMN;
604 } gx_cie_joint_caches;
605 
606 #define private_st_joint_caches() /* in gscie.c */\
607   gs_private_st_simple(st_joint_caches, gx_cie_joint_caches,\
608     "gx_cie_joint_caches")
609 
610 /* ------ Internal procedures ------ */
611 
612 typedef struct gs_for_loop_params_s {
613     double init, step, limit;
614 } gs_for_loop_params;
615 void gs_cie_cache_init(P4(cie_cache_params *, gs_for_loop_params *,
616 			  const gs_range *, client_name_t));
617 void gs_cie_cache_to_fracs(P2(const cie_cache_floats *, cie_cache_fracs *));
618 void gs_cie_defg_complete(P1(gs_cie_defg *));
619 void gs_cie_def_complete(P1(gs_cie_def *));
620 void gs_cie_abc_complete(P1(gs_cie_abc *));
621 void gs_cie_a_complete(P1(gs_cie_a *));
622 gx_cie_joint_caches *gx_currentciecaches(P1(gs_state *));
623 const gs_cie_common *gs_cie_cs_common(P1(const gs_state *));
624 int gs_cie_cs_complete(P2(gs_state *, bool));
625 int gs_cie_jc_complete(P2(const gs_imager_state *, const gs_color_space *pcs));
626 float gs_cie_cached_value(P2(floatp, const cie_cache_floats *));
627 
628 #define CIE_CLAMP_INDEX(index)\
629   index = (index < 0 ? 0 :\
630 	   index >= gx_cie_cache_size ? gx_cie_cache_size - 1 : index)
631 
632 /*
633  * Compute the source and destination WhitePoint and BlackPoint for
634  * the TransformPQR procedure.
635  */
636 int gs_cie_compute_points_sd(P3(gx_cie_joint_caches *pjc,
637 				const gs_cie_common * pcie,
638 				const gs_cie_render * pcrd));
639 
640 /*
641  * Compute the derived values in a CRD that don't involve the cached
642  * procedure values, moving the CRD from "built" to "inited" status.
643  * If the CRD is already in "inited" or a later status, do nothing.
644  */
645 int gs_cie_render_init(P1(gs_cie_render *));
646 
647 /*
648  * Sample the EncodeLMN, EncodeABC, and RenderTableT CRD procedures, and
649  * load the caches, moving the CRD from "inited" to "sampled" status.
650  * If the CRD is already in "sampled" or a later status, do nothing;
651  * otherwise, if the CRD is not in "inited" status, return an error.
652  */
653 int gs_cie_render_sample(P1(gs_cie_render *));
654 
655 /*
656  * Finish preparing a CRD for installation, by restricting and/or
657  * transforming the cached procedure values, moving the CRD from "sampled"
658  * to "completed" status.  If the CRD is already in "completed" status, do
659  * nothing; otherwise, if the CRD is not in "sampled" status, return an
660  * error.
661  */
662 int gs_cie_render_complete(P1(gs_cie_render *));
663 
664 /* ---------------- Procedures ---------------- */
665 
666 /* ------ Constructors ------ */
667 
668 /*
669  * Note that these procedures take a client_data pointer as an operand. The
670  * client is responsible for allocating and deleting this object; the
671  * color space machinery does not take ownership of it.
672  *
673  * Note that these procedures set the reference count of the (large)
674  * parameter structures to 1, not 0.  gs_setcolorspace will increment
675  * the reference count again, so unless you want the parameter structures
676  * to stay allocated permanently (or until a garbage collection),
677  * you should call cs_adjust_count(pcspace, -1).  THIS IS A BUG IN THE API.
678  */
679 extern int
680     gs_cspace_build_CIEA(P3(gs_color_space ** ppcspace, void *client_data,
681 			    gs_memory_t * pmem)),
682     gs_cspace_build_CIEABC(P3(gs_color_space ** ppcspace, void *client_data,
683 			      gs_memory_t * pmem)),
684     gs_cspace_build_CIEDEF(P3(gs_color_space ** ppcspace, void *client_data,
685 			      gs_memory_t * pmem)),
686     gs_cspace_build_CIEDEFG(P3(gs_color_space ** ppcspace, void *client_data,
687 			       gs_memory_t * pmem));
688 
689 /* ------ Accessors ------ */
690 
691 /*
692  * Note that the accessors depend heavily on "puns" between the variants
693  * of pcspace->params.{a,abc,def,defg}.
694  */
695 
696 /* Generic CIE based color space parameters */
697 #define gs_cie_RangeLMN(pcspace)  (&(pcspace)->params.a->common.RangeLMN)
698 #define gs_cie_DecodeLMN(pcspace) (&(pcspace)->params.a->common.DecodeLMN)
699 #define gs_cie_MatrixLMN(pcspace) (&(pcspace)->params.a->common.MatrixLMN)
700 #define gs_cie_WhitePoint(pcspace)\
701   ((pcspace)->params.a->common.points.WhitePoint)
702 #define gs_cie_BlackPoint(pcspace)\
703   ((pcspace)->params.a->common.points.BlackPoint)
704 
705 /* CIEBasedA color space */
706 #define gs_cie_a_RangeA(pcspace)      (&(pcspace)->params.a->RangeA)
707 #define gs_cie_a_DecodeA(pcspace)     (&(pcspace)->params.a->DecodeA)
708 #define gs_cie_a_MatrixA(pcspace)     (&(pcspace)->params.a->MatrixA)
709 #define gs_cie_a_RangeA(pcspace)      (&(pcspace)->params.a->RangeA)
710 
711 /* CIEBasedABC color space */
712 /* Note that these also work for CIEBasedDEF[G] spaces. */
713 #define gs_cie_abc_RangeABC(pcspace)    (&(pcspace)->params.abc->RangeABC)
714 #define gs_cie_abc_DecodeABC(pcspace)   (&(pcspace)->params.abc->DecodeABC)
715 #define gs_cie_abc_MatrixABC(pcspace)   (&(pcspace)->params.abc->MatrixABC)
716 
717 /* CIDBasedDEF color space */
718 #define gs_cie_def_RangeDEF(pcspace)    (&(pcspace)->params.def->RangeDEF)
719 #define gs_cie_def_DecodeDEF(pcspace)   (&(pcspace)->params.def->DecodeDEF)
720 #define gs_cie_def_RangeHIJ(pcspace)    (&(pcspace)->params.def->RangeHIJ)
721 
722 /* CIDBasedDEFG color space */
723 #define gs_cie_defg_RangeDEFG(pcspace)  (&(pcspace)->params.defg->RangeDEFG)
724 #define gs_cie_defg_DecodeDEFG(pcspace) (&(pcspace)->params.defg->DecodeDEFG)
725 #define gs_cie_defg_RangeHIJK(pcspace)  (&(pcspace)->params.defg->RangeHIJK)
726 
727 /*
728  * The following routine is provided so as to avoid explicitly exporting the
729  * CIEBasedDEF[G] color lookup table structure. It is doubtful any
730  * high-level clients will ever need to get this information.
731  *
732  * The caller must make sure the number of dimensions and strings provided
733  * are the number expected given the number of components in the color space.
734  * The procedure gs_color_space_num_components is available for this purpose.
735  *
736  * For a 3 component color space (CIEBasedDEF), ptable points to an array of
737  * pdims[0] gs_const_string structures, each of which is of length
738  * 3 * pdims[1] * pdims[2].
739  *
740  * For a 4 component color space (CIEBasedDEFG), ptable points to an array of
741  * pdims[0] * pdims[1] strings, each of which is of length
742  * 3 * pdims[2] * pdims[3].
743  *
744  * NB: the caller is responsible for deallocating the color table data
745  *     when no longer needed.  */
746 extern int
747     gs_cie_defx_set_lookup_table(P3(gs_color_space * pcspace, int *pdims,
748 				    const gs_const_string * ptable));
749 
750 #endif /* gscie_INCLUDED */
751