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