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