Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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 */