xref: /plan9/sys/src/cmd/gs/src/gscspace.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 2000 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: gscspace.h,v 1.14 2004/08/04 19:36:12 stefan Exp $ */
18 /* Client interface to color spaces */
19 
20 #ifndef gscspace_INCLUDED
21 #  define gscspace_INCLUDED
22 
23 #include "gsmemory.h"
24 #include "gsiparam.h"
25 
26 /*
27  * The handling of color spaces in the graphic library is somewhat
28  * awkward because of historical artifacts.
29  *
30  * The PostScript Level 1 (DeviceGray/RGB) color spaces, and the "Level
31  * 1 1/2" DeviceCMYK space, have no associated parameters.  Therefore,
32  * they can be represented as simple objects (just a pointer to a type
33  * vector containing procedures and parameters).  This was the original
34  * design.
35  *
36  * PostScript Level 2 and LanguageLevel 3 add two new kinds of color spaces:
37  * color spaces with parameters (CIEBased and DevicePixel spaces),  and
38  * compound color spaces (Indexed, Separation, Pattern, and DeviceN spaces),
39  * with parameters that include a specification of an alternative or
40  * underlying color space.  To handle these spaces, we extended the original
41  * design to store in-line certain scalar parameters (i.e., parameters other
42  * than the complex color transformation data for CIEBased spaces, the lookup
43  * table for Indexed spaces, and the list of component names for DeviceN
44  * spaces) in the color space object.  For compound spaces, this requires
45  * storing a color space in-line inside another color space, which is clearly
46  * impossible.  Therefore, we defined a generality hierarchy for color spaces:
47  *
48  *      - Base spaces (DeviceGray/RGB/CMYK/Pixel, CIEBased), whose
49  *      whose parameters (if any) don't include other color spaces.
50  *
51  *	- Direct spaces (base spaces + Separation and DeviceN), which
52  *      may have a base space as an alternative space.
53  *
54  *      - Paint spaces (direct spaces + Indexed), which may have a direct
55  *      space as the underlying space
56  *
57  *      - General spaces (paint spaces + Pattern), which may have a
58  *      paint space as the underlying space.
59  *
60  * With this approach, a general space can include a paint space stored
61  * in-line; a paint space (either in its own right or as the underlying
62  * space of a Pattern space) can include a direct space in-line; and a
63  * direct space can include a base space in-line.
64  *
65  * The introduction of ICCBased color spaces in PDF 1.3 wrecked havoc on
66  * this hierarchy. ICCBased color spaces contain alternative color spaces,
67  * which may be paint spaces. On the other hand, ICCBased spaces may be
68  * use as alternative or underlying color spaces in direct and paint
69  * spaces.
70  *
71  * The proper solution to this problem would be to reference alternative and
72  * underlying color spaces via a pointer. The cost and risk of that approach
73  * is, however, larger than is warranted just by the addition of ICCBased
74  * color spaces. Another alternative is to allow just base color spaces to
75  * include an alternative color space via a pointer. That would require two
76  * separate mechanisms for dealing with alternative color spaces, which
77  * seems messy and may well cause problems in the future.
78  *
79  * Examination of some PDF files indicates that ICCBased color spaces are
80  * routinely used as alternative spaces for Separation or Device color
81  * spaces, but essentially never make use of alternative color spaces other
82  * than the device-specific spaces. To support this usage, the approach
83  * taken here splits previous base color space class into "small"  and
84  * "regular" base color spaces. Small base color spaces include all of
85  * those color spaces that previously were considered base spaces. Regular
86  * base spaces add the ICCBased color spaces to this set. To maintain
87  * compatibility with the existing code base, regular base spaces make use
88  * of the gs_base_color_space type name.
89  *
90  * Note that because general, paint, direct, regular base, and small base
91  * spaces are (necessarily) of different sizes, assigning (copying the top
92  * object of) color spaces must take into account the actual size of the
93  * color space being assigned.  In principle, this also requires checking
94  * that the source object will actually fit into the destination.  Currently
95  * we rely on the caller to ensure that this is the case; in fact, the
96  * current API (gs_cspace_init and gs_cspace_assign) doesn't even provide
97  * enough information to make the check.
98  *
99  * In retrospect, we might have gotten a simpler design without significant
100  * performance loss by always referencing underlying and alternate spaces
101  * through a pointer; however, at this point, the cost and risk of changing
102  * to such a design are too high.
103  *
104  * There are two aspects to memory management for color spaces: managing
105  * the color space objects themselves, and managing the non-scalar
106  * parameters that they reference (if any).
107  *
108  *      - Color space objects per se have no special management properties:
109  *      they can be allocated on the stack or on the heap, and freed by
110  *      scope exit, explicit deallocation, or garbage collection.
111  *
112  *      - Separately allocated (non-scalar) color space parameters are
113  *      managed by reference counting.  Currently we do this for the
114  *      CIEBased spaces, and for the first-level parameters of Indexed and
115  *      Separation spaces: clients must deal with deallocating the other
116  *      parameter structures mentioned above, including the Indexed lookup
117  *      table if any. This is clearly not a good situation, but we don't
118  *      envision fixing it any time soon.
119  *
120  * Here is the information associated with the various color space
121  * structures.  Note that DevicePixel, DeviceN, and the ability to use
122  * Separation or DeviceN spaces as the base space of an Indexed space
123  * are LanguageLevel 3 additions.  Unfortunately, the terminology for the
124  * different levels of generality is confusing and inconsistent for
125  * historical reasons.
126  *
127  * For base spaces:
128  *
129  * Space        Space parameters                Color parameters
130  * -----        ----------------                ----------------
131  * DeviceGray   (none)                          1 real [0-1]
132  * DeviceRGB    (none)                          3 reals [0-1]
133  * DeviceCMYK   (none)                          4 reals [0-1]
134  * DevicePixel  depth                           1 int [up to depth bits]
135  * CIEBasedDEFG dictionary                      4 reals
136  * CIEBasedDEF  dictionary                      3 reals
137  * CIEBasedABC  dictionary                      3 reals
138  * CIEBasedA    dictionary                      1 real
139  *
140  * For non-base direct spaces:
141  *
142  * Space        Space parameters                Color parameters
143  * -----        ----------------                ----------------
144  *
145  * Separation   name, alt_space, tint_xform     1 real [0-1]
146  * DeviceN      names, alt_space, tint_xform    N reals
147  *
148  * For non-direct paint spaces:
149  *
150  * Space        Space parameters                Color parameters
151  * -----        ----------------                ----------------
152  * Indexed      base_space, hival, lookup       1 int [0-hival]
153  * ICCBased     dictionary, alt_space           1, 3, or 4 reals
154  *
155  * For non-paint spaces:
156  *
157  * Space        Space parameters                Color parameters
158  * -----        ----------------                ----------------
159  * Pattern      colored: (none)                 dictionary
160  *              uncolored: base_space dictionary + base space params
161  */
162 
163 /*
164  * Define color space type indices.  NOTE: PostScript code (gs_res.ps,
165  * gs_ll3.ps) and the color space substitution code (gscssub.[hc] and its
166  * clients) assumes values 0-2 for DeviceGray/RGB/CMYK respectively.
167  */
168 typedef enum {
169 
170     /* Supported in all configurations */
171     gs_color_space_index_DeviceGray = 0,
172     gs_color_space_index_DeviceRGB,
173 
174     /* Supported in extended Level 1, and in Level 2 and above */
175     gs_color_space_index_DeviceCMYK,
176 
177     /* Supported in LanguageLevel 3 only */
178     gs_color_space_index_DevicePixel,
179     gs_color_space_index_DeviceN,
180 
181     /* Supported in Level 2 and above only */
182     /* DEC C truncates identifiers at 32 characters, so.... */
183     gs_color_space_index_CIEDEFG,
184     gs_color_space_index_CIEDEF,
185     gs_color_space_index_CIEABC,
186     gs_color_space_index_CIEA,
187     gs_color_space_index_Separation,
188     gs_color_space_index_Indexed,
189     gs_color_space_index_Pattern,
190 
191     /* Supported in PDF 1.3 and later only */
192     gs_color_space_index_CIEICC
193 
194 } gs_color_space_index;
195 
196 /* We define the names only for debugging printout. */
197 #define GS_COLOR_SPACE_TYPE_NAMES\
198   "DeviceGray", "DeviceRGB", "DeviceCMYK", "DevicePixel", "DeviceN",\
199   "ICCBased", "CIEBasedDEFG", "CIEBasedDEF", "CIEBasedABC", "CIEBasedA",\
200   "Separation", "Indexed", "Pattern"
201 
202 /* Define an abstract type for color space types (method structures). */
203 typedef struct gs_color_space_type_s gs_color_space_type;
204 
205 /*
206  * The common part of all color spaces. This structure now includes a memory
207  * structure pointer, so that it may be released without providing this
208  * information separately. (type is a pointer to the structure of methods.)
209  *
210  * Note that all color space structures consist of the basic information and
211  * a union containing some additional information. The macro operand is that
212  * union.
213  */
214 #define gs_cspace_common(param_union)   \
215     const gs_color_space_type * type;   \
216     gs_memory_t *               pmem;   \
217     gs_id                       id;     \
218     union {                             \
219 	param_union;                    \
220     }                           params
221 
222 /*
223  * Parameters for "small" base color spaces. Of the small base color spaces,
224  * only DevicePixel and CIE spaces have parameters: see gscie.h for the
225  * structure definitions for CIE space parameters.
226  */
227 typedef struct gs_device_pixel_params_s {
228     int depth;
229 } gs_device_pixel_params;
230 typedef struct gs_cie_a_s gs_cie_a;
231 typedef struct gs_cie_abc_s gs_cie_abc;
232 typedef struct gs_cie_def_s gs_cie_def;
233 typedef struct gs_cie_defg_s gs_cie_defg;
234 
235 #define gs_small_base_cspace_params     \
236     gs_device_pixel_params   pixel;     \
237     gs_cie_defg *            defg;      \
238     gs_cie_def *             def;       \
239     gs_cie_abc *             abc;       \
240     gs_cie_a *               a
241 
242 typedef struct gs_small_base_color_space_s {
243     gs_cspace_common(gs_small_base_cspace_params);
244 } gs_small_base_color_space;
245 
246 #define gs_small_base_color_space_size sizeof(gs_small_base_color_space)
247 
248 /*
249  * "Regular" base color spaces include all of the small base color space and
250  * the ICCBased color space, which includes a small base color space as an
251  * alternative color space. See gsicc.h for the structure definition of
252  * gs_cie_icc_s.
253  */
254 typedef struct gs_cie_icc_s gs_cie_icc;
255 
256 typedef struct gs_cieicc_params_s {
257     gs_cie_icc *                picc_info;
258     gs_small_base_color_space   alt_space;
259 } gs_icc_params;
260 
261 #define gs_base_cspace_params   \
262     gs_small_base_cspace_params;\
263     gs_icc_params   icc
264 
265 typedef struct gs_base_color_space_s {
266     gs_cspace_common(gs_base_cspace_params);
267 } gs_base_color_space;
268 
269 #define gs_base_color_space_size sizeof(gs_base_color_space)
270 
271 #ifndef gs_device_n_map_DEFINED
272 #  define gs_device_n_map_DEFINED
273 typedef struct gs_device_n_map_s gs_device_n_map;
274 #endif
275 
276 /*
277  * Non-base direct color spaces: Separation and DeviceN.
278  * These include a base alternative color space.
279  */
280 typedef ulong gs_separation_name;	/* BOGUS */
281 
282 /*
283  * Define callback function for graphics library to ask
284  * interpreter about character string representation of
285  * component names.  This is used for comparison of component
286  * names with similar objects like ProcessColorModel colorant
287  * names.
288  */
289 typedef int (gs_callback_func_get_colorname_string)
290      (const gs_memory_t *mem, gs_separation_name colorname, unsigned char **ppstr, unsigned int *plen);
291 
292 typedef enum { SEP_NONE, SEP_ALL, SEP_OTHER } separation_type;
293 
294 typedef struct gs_separation_params_s {
295     gs_separation_name sep_name;
296     gs_base_color_space alt_space;
297     gs_device_n_map *map;
298     separation_type sep_type;
299     bool use_alt_cspace;
300     gs_callback_func_get_colorname_string *get_colorname_string;
301 } gs_separation_params;
302 
303 typedef struct gs_device_n_params_s {
304     gs_separation_name *names;
305     uint num_components;
306     gs_base_color_space alt_space;
307     gs_device_n_map *map;
308     bool use_alt_cspace;
309     gs_callback_func_get_colorname_string *get_colorname_string;
310 } gs_device_n_params;
311 
312 #define gs_direct_cspace_params         \
313     gs_base_cspace_params;              \
314     gs_separation_params separation;    \
315     gs_device_n_params device_n
316 
317 typedef struct gs_direct_color_space_s {
318     gs_cspace_common(gs_direct_cspace_params);
319 } gs_direct_color_space;
320 
321 #define gs_direct_color_space_size sizeof(gs_direct_color_space)
322 
323 /*
324  * Non-direct paint space: Indexed space.
325  *
326  * Note that for indexed color spaces, hival is the highest support index,
327  * which is one less than the number of entries in the palette (as defined
328  * in PostScript).
329  */
330 
331 typedef struct gs_indexed_map_s gs_indexed_map;
332 
333 typedef struct gs_indexed_params_s {
334     gs_direct_color_space base_space;
335     int hival;			/* num_entries - 1 */
336     union {
337 	gs_const_string table;	/* size is implicit */
338 	gs_indexed_map *map;
339     } lookup;
340     bool use_proc;		/* 0 = use table, 1 = use proc & map */
341 } gs_indexed_params;
342 
343 #define gs_paint_cspace_params          \
344     gs_direct_cspace_params;            \
345     gs_indexed_params indexed
346 
347 typedef struct gs_paint_color_space_s {
348     gs_cspace_common(gs_paint_cspace_params);
349 } gs_paint_color_space;
350 
351 #define gs_paint_color_space_size sizeof(gs_paint_color_space)
352 
353 /*
354  * Pattern parameter set. This may contain an instances of a paintable
355  * color space. The boolean indicates if this is the case.
356  */
357 typedef struct gs_pattern_params_s {
358     bool has_base_space;
359     gs_paint_color_space base_space;
360 } gs_pattern_params;
361 
362 /*
363  * Fully general color spaces.
364  */
365 struct gs_color_space_s {
366     gs_cspace_common(
367 	gs_paint_cspace_params;
368 	gs_pattern_params pattern
369     );
370 };
371 
372 #define gs_pattern_color_space_size sizeof(gs_color_space)
373 
374 /*
375  * Define the abstract type for color space objects.
376  */
377 #ifndef gs_color_space_DEFINED
378 #  define gs_color_space_DEFINED
379 typedef struct gs_color_space_s gs_color_space;
380 #endif
381 
382 					/*extern_st(st_color_space); *//* in gxcspace.h */
383 #define public_st_color_space()	/* in gscspace.c */  \
384     gs_public_st_composite( st_color_space,         \
385                             gs_color_space,         \
386                             "gs_color_space",       \
387                             color_space_enum_ptrs,  \
388                             color_space_reloc_ptrs  \
389                             )
390 
391 #define st_color_space_max_ptrs 2	/* 1 base + 1 indexed */
392 
393 /* ---------------- Procedures ---------------- */
394 
395 /* ------ Create/copy/destroy ------ */
396 
397 /*
398  * Note that many of the constructors take no parameters, and the
399  * remainder take only a few (CIE color spaces constructures take a
400  * client data pointer as an operand, the composite color space (Separation,
401  * Indexed, and Pattern) constructurs take the base space as an operand,
402  * and the Indexed color space constructors have a few additiona operands).
403  * This is done to conserve memory. If initialization values for all the
404  * color space parameters were provided to the constructors, these values
405  * would need to have some fairly generic format. Different clients gather
406  * this data in different forms, so they would need to allocate memory to
407  * convert it to the generic form, only to immediately release this memory
408  * once the construction is complete.
409  *
410  * The alternative approach employed here is to provide a number of access
411  * methods (macros) that return pointers to individual fields of the
412  * various color space structures. This requires exporting only fairly simple
413  * data structures, and so does not violate modularity too severely.
414  *
415  * NB: Of necessity, the macros provide access to modifiable structures. If
416  *     these structures are modified after the color space object is first
417  *     initialized, unpredictable and, most likely, undesirable results will
418  *     occur.
419  *
420  * The constructors return an integer, 0 on success and an
421  * error code on failure (gs_error_VMerror or gs_error_rangecheck).
422  *
423  * In parallel with the constructors, we provide initializers that assume
424  * the client has allocated the color space object (perhaps on the stack)
425  * and takes responsibility for freeing it.
426  */
427 
428 extern int
429     gs_cspace_init_DeviceGray(const gs_memory_t *mem, gs_color_space *pcs),
430     gs_cspace_build_DeviceGray(gs_color_space ** ppcspace,
431 				  gs_memory_t * pmem),
432     gs_cspace_init_DeviceRGB(const gs_memory_t *mem, gs_color_space *pcs),
433     gs_cspace_build_DeviceRGB(gs_color_space ** ppcspace,
434                               gs_memory_t * pmem),
435     gs_cspace_init_DeviceCMYK(const gs_memory_t *mem, gs_color_space *pcs),
436     gs_cspace_build_DeviceCMYK(gs_color_space ** ppcspace,
437                                gs_memory_t * pmem);
438 
439 /* Copy a color space into one newly allocated by the caller. */
440 void gs_cspace_init_from(gs_color_space * pcsto,
441 			 const gs_color_space * pcsfrom);
442 
443 /* Assign a color space into a previously initialized one. */
444 void gs_cspace_assign(gs_color_space * pdest, const gs_color_space * psrc);
445 
446 /* Prepare to free a color space. */
447 void gs_cspace_release(gs_color_space * pcs);
448 
449 /* ------ Accessors ------ */
450 
451 /* Get the index of a color space. */
452 gs_color_space_index gs_color_space_get_index(const gs_color_space *);
453 
454 /* Get the number of components in a color space. */
455 int gs_color_space_num_components(const gs_color_space *);
456 
457 /*
458  * Test whether two color spaces are equal.  Note that this test is
459  * conservative: if it returns true, the color spaces are definitely
460  * equal, while if it returns false, they might still be equivalent.
461  */
462 bool gs_color_space_equal(const gs_color_space *pcs1,
463 			  const gs_color_space *pcs2);
464 
465 /* Restrict a color to its legal range. */
466 #ifndef gs_client_color_DEFINED
467 #  define gs_client_color_DEFINED
468 typedef struct gs_client_color_s gs_client_color;
469 #endif
470 void gs_color_space_restrict_color(gs_client_color *, const gs_color_space *);
471 
472 /*
473  * Get the base space of an Indexed or uncolored Pattern color space, or the
474  * alternate space of a Separation or DeviceN space.  Return NULL if the
475  * color space does not have a base/alternative color space.
476  */
477 const gs_color_space *gs_cspace_base_space(const gs_color_space * pcspace);
478 
479 /* backwards compatibility */
480 #define gs_color_space_indexed_base_space(pcspace)\
481     gs_cspace_base_space(pcspace)
482 
483 #endif /* gscspace_INCLUDED */
484