summaryrefslogtreecommitdiff
path: root/gs/src/gscspace.h
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gscspace.h')
-rw-r--r--gs/src/gscspace.h448
1 files changed, 315 insertions, 133 deletions
diff --git a/gs/src/gscspace.h b/gs/src/gscspace.h
index 32c30196b..01b3f0bf5 100644
--- a/gs/src/gscspace.h
+++ b/gs/src/gscspace.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996 Aladdin Enterprises. All rights reserved.
+/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
This file is part of Aladdin Ghostscript.
@@ -16,174 +16,356 @@
all copies.
*/
-/* gscspace.h */
+/*Id: gscspace.h */
/* Client interface to color spaces */
#ifndef gscspace_INCLUDED
# define gscspace_INCLUDED
+#include "gsmemory.h"
+
+/*
+ * The handling of color spaces in the graphic library is somewhat
+ * awkward because of historical artifacts.
+ *
+ * The PostScript Level 1 (DeviceGray/RGB) color spaces, and the "Level
+ * 1 1/2" DeviceCMYK space, have no associated parameters. Therefore,
+ * they can be represented as simple objects (just a pointer to a type
+ * vector containing procedures and parameters). This was the original
+ * design.
+ *
+ * PostScript Level 2 and LanguageLevel 3 add two new kinds of color spaces:
+ * color spaces with parameters (CIEBased and DevicePixel spaces), and
+ * compound color spaces (Indexed, Separation, Pattern, and DeviceN spaces),
+ * which parameters that include specifying an alternate or underlying color
+ * space. To handle these spaces, we extended the original design to store
+ * scalar parameters (i.e., parameters other than the complex color
+ * transformation data for CIEBased spaces, the lookup table for Indexed
+ * spaces, and the list of component names for DeviceN spaces) in-line in
+ * the color space object. For compound spaces, this requires storing a
+ * color space in-line inside another color space, which is clearly
+ * impossible. Therefore, we defined a generality hierarchy for color
+ * spaces:
+ *
+ * - Base spaces (DeviceGray/RGB/CMYK/Pixel and CIEBased),
+ * whose parameters (if any) don't include other color spaces.
+ *
+ * - Paint spaces (base spaces + Indexed, Separation, and DeviceN),
+ * which may have a base space as the alternate or underlying space.
+ *
+ * - General spaces (paint spaces + Pattern), which may have a
+ * paint space as the underlying space.
+ *
+ * With this approach, a general space can include a paint space stored
+ * in-line, and a paint space (either in its own right or as the underlying
+ * space of a Pattern space) can include a base space in-line.
+ *
+ * Note that because general, paint, and base spaces are (necessarily) of
+ * different sizes, assigning (copying the top object of) color spaces must
+ * take into account the actual size of the color space being assigned. In
+ * principle, this also requires checking that the source object will
+ * actually fit into the destination. Currently we rely on the caller to
+ * ensure that this is the case; in fact, the current API (gs_cspace_init
+ * and gs_cspace_assign) doesn't even provide enough information to make the
+ * check.
+ *
+ * In retrospect, we might have gotten a simpler design without significant
+ * performance loss by always referencing underlying and alternate spaces
+ * through a pointer; however, at this point, the cost and risk of changing
+ * to such a design are too high.
+ *
+ * There are two aspects to memory management for color spaces: managing
+ * the color space objects themselves, and managing the non-scalar
+ * parameters that they reference (if any).
+ *
+ * - Color space objects per se have no special management properties:
+ * they can be allocated on the stack or on the heap, and freed by
+ * scope exit, explicit deallocation, or garbage collection.
+ *
+ * - Separately allocated (non-scalar) color space parameters are
+ * managed by reference counting. Currently we do this for the
+ * CIEBased spaces, and for the first-level parameters of Indexed and
+ * Separation spaces: clients must deal with deallocating the other
+ * parameter structures mentioned above, including the Indexed lookup
+ * table if any. This is clearly not a good situation, but we don't
+ * envision fixing it any time soon.
+ *
+ * Here is the information associated with the various color space
+ * structures. Note that DevicePixel, DeviceN, and the ability to use
+ * Separation or DeviceN spaces as the base space of an Indexed space
+ * are LanguageLevel 3 additions.
+ *
+ * For base spaces:
+ *
+ * Space Space parameters Color parameters
+ * ----- ---------------- ----------------
+ * DeviceGray (none) 1 real [0-1]
+ * DeviceRGB (none) 3 reals [0-1]
+ * DeviceCMYK (none) 4 reals [0-1]
+ * DevicePixel depth 1 int [up to depth bits]
+ * CIEBasedDEFG dictionary 4 reals
+ * CIEBasedDEF dictionary 3 reals
+ * CIEBasedABC dictionary 3 reals
+ * CIEBasedA dictionary 1 real
+ *
+ * For non-base paint spaces (alt_space and base_space are base spaces):
+ *
+ * Space Space parameters Color parameters
+ * ----- ---------------- ----------------
+ * Indexed base_space, hival, lookup 1 int [0-hival]
+ * Separation name, alt_space, tint_xform 1 real [0-1]
+ * DeviceN names, alt_space, tint_xform N reals
+ *
+ * For non-paint spaces (base_space is a paint space -- should be named
+ * paint_space!):
+ *
+ * Space Space parameters Color parameters
+ * ----- ---------------- ----------------
+ * Pattern colored: (none) dictionary
+ * uncolored: base_space dictionary + base space params
+ */
+
/* Color space type indices */
typedef enum {
- /* Supported in all configurations */
- gs_color_space_index_DeviceGray = 0,
- gs_color_space_index_DeviceRGB,
- /* Supported in extended Level 1, and in Level 2 */
- gs_color_space_index_DeviceCMYK,
- /* Supported in Level 2 only */
- /* DEC C truncates identifiers at 32 characters, so.... */
- gs_color_space_index_CIEDEFG,
- gs_color_space_index_CIEDEF,
- gs_color_space_index_CIEABC,
- gs_color_space_index_CIEA,
- gs_color_space_index_Separation,
- gs_color_space_index_Indexed,
- gs_color_space_index_Pattern
+
+ /* Supported in all configurations */
+ gs_color_space_index_DeviceGray = 0,
+ gs_color_space_index_DeviceRGB,
+
+ /* Supported in extended Level 1, and in Level 2 and above */
+ gs_color_space_index_DeviceCMYK,
+
+ /* Supported in LanguageLevel 3 only */
+ gs_color_space_index_DevicePixel,
+ gs_color_space_index_DeviceN,
+
+ /* Supported in Level 2 and above only */
+ /* DEC C truncates identifiers at 32 characters, so.... */
+ gs_color_space_index_CIEDEFG,
+ gs_color_space_index_CIEDEF,
+ gs_color_space_index_CIEABC,
+ gs_color_space_index_CIEA,
+ gs_color_space_index_Separation,
+ gs_color_space_index_Indexed,
+ gs_color_space_index_Pattern
} gs_color_space_index;
-/* Define the abstract type for color space objects. */
-#ifndef gs_color_space_DEFINED
-# define gs_color_space_DEFINED
-typedef struct gs_color_space_s gs_color_space;
-#endif
+/* Define an abstract type for color space types (method structures). */
+typedef struct gs_color_space_type_s gs_color_space_type;
/*
- * We preallocate instances of the 3 device color spaces, and provide
- * procedures that return them (to avoid upsetting compilers that don't
- * allow extern pointers to abstract types). Note that
- * gs_color_space_DeviceCMYK() may return NULL if CMYK color support is not
- * included in this configuration.
+ * The common part of all color spaces. This structure now includes a memory
+ * structure pointer, so that it may be released without providing this
+ * information separately. (type is a pointer to the structure of methods.)
+ *
+ * Note that all color space structures consist of the basic information and
+ * a union containing some additional information. The macro operand is that
+ * union.
*/
-extern const gs_color_space *gs_color_space_DeviceGray(P0());
-extern const gs_color_space *gs_color_space_DeviceRGB(P0());
-extern const gs_color_space *gs_color_space_DeviceCMYK(P0());
+#define gs_cspace_common(param_union) \
+ const gs_color_space_type * type; \
+ gs_memory_t * pmem; \
+ union { \
+ param_union; \
+ } params
/*
- * Color spaces are complicated because different spaces involve
- * different kinds of parameters, as follows:
-
-Space Space parameters Color parameters
------ ---------------- ----------------
-DeviceGray (none) 1 real [0-1]
-DeviceRGB (none) 3 reals [0-1]
-DeviceCMYK (none) 4 reals [0-1]
-CIEBasedDEFG dictionary 4 reals
-CIEBasedDEF dictionary 3 reals
-CIEBasedABC dictionary 3 reals
-CIEBasedA dictionary 1 real
-Separation name, alt_space, tint_xform 1 real [0-1]
-Indexed base_space, hival, lookup 1 int [0-hival]
-Pattern colored: (none) dictionary
- uncolored: base_space dictionary + base space params
-
-Space Underlying or alternate space
------ -----------------------------
-Separation Device, CIE
-Indexed Device, CIE
-Pattern Device, CIE, Separation, Indexed
-
- * Logically speaking, each color space type should be a different
- * structure type at the allocator level. This would potentially require
- * either reference counting or garbage collector for color spaces, but that
- * is probably better than the current design, which uses fixed-size color
- * space objects and a second level of type discrimination.
+ * Parameters for base color spaces. Of the base color spaces, only
+ * DevicePixel and CIE spaces have parameters: see gscie.h for the structure
+ * definitions for CIE space parameters.
*/
+typedef struct gs_device_pixel_params_s {
+ int depth;
+} gs_device_pixel_params;
+typedef struct gs_cie_a_s gs_cie_a;
+typedef struct gs_cie_abc_s gs_cie_abc;
+typedef struct gs_cie_def_s gs_cie_def;
+typedef struct gs_cie_defg_s gs_cie_defg;
+
+#define gs_base_cspace_params \
+ gs_device_pixel_params pixel; \
+ gs_cie_defg * defg; \
+ gs_cie_def * def; \
+ gs_cie_abc * abc; \
+ gs_cie_a * a
-/* Define abstract structure types for color space parameters. */
-typedef struct gs_cie_defg_s gs_cie_defg;
-typedef struct gs_cie_def_s gs_cie_def;
-typedef struct gs_cie_abc_s gs_cie_abc;
-typedef struct gs_cie_a_s gs_cie_a;
-typedef struct gs_separation_params_s gs_separation_params;
-typedef struct gs_indexed_params_s gs_indexed_params;
-
-/* Define an abstract type for color space types. */
-typedef struct gs_color_space_type_s gs_color_space_type;
-
-/* ---------------- Color spaces per se ---------------- */
-
- /* Base color spaces (Device and CIE) */
-
-/*typedef struct gs_cie_defg_s gs_cie_defg;*/
-/*typedef struct gs_cie_def_s gs_cie_def;*/
-/*typedef struct gs_cie_abc_s gs_cie_abc;*/
-/*typedef struct gs_cie_a_s gs_cie_a;*/
-#define gs_base_cspace_params\
- gs_cie_defg *defg;\
- gs_cie_def *def;\
- gs_cie_abc *abc;\
- gs_cie_a *a
typedef struct gs_base_color_space_s {
- const gs_color_space_type _ds *type;
- union {
- gs_base_cspace_params;
- } params;
+ gs_cspace_common(gs_base_cspace_params);
} gs_base_color_space;
+#define gs_base_color_space_size sizeof(gs_base_color_space)
- /* Paint (non-pattern) color spaces (base + Separation + Indexed) */
+/*
+ * Non-base "paint" color spaces: Index, Separation, and DeviceN
+ * spaces. These include a base color space (known as the alternative color
+ * space in the case of Separation and DeviceN spaces).
+ *
+ * Note that for indexed color spaces, hival is the highest support index,
+ * which is one less than the number of entries in the palette (as defined
+ * in PostScript).
+ */
+typedef ulong gs_separation_name; /* BOGUS */
+typedef struct gs_indexed_map_s gs_indexed_map;
-typedef ulong gs_separation_name; /* BOGUS */
+typedef struct gs_indexed_params_s {
+ gs_base_color_space base_space;
+ int hival; /* num_entries - 1 */
+ union {
+ gs_const_string table; /* size is implicit */
+ gs_indexed_map * map;
+ } lookup;
+ bool use_proc; /* 0 = use table, 1 = use proc & map */
+} gs_indexed_params;
-typedef struct gs_indexed_map_s gs_indexed_map;
-/*typedef struct gs_separation_params_s gs_separation_params;*/
-struct gs_separation_params_s {
- gs_separation_name sname;
- gs_base_color_space alt_space;
- gs_indexed_map *map;
-};
-/*typedef struct gs_indexed_params_s gs_indexed_params;*/
-struct gs_indexed_params_s {
- gs_base_color_space base_space;
- int hival;
- union {
- gs_const_string table; /* size is implicit */
- gs_indexed_map *map;
- } lookup;
- bool use_proc; /* 0 = use table, 1 = use proc & map */
+typedef struct gs_separation_params_s {
+ gs_separation_name sname;
+ gs_base_color_space alt_space;
+ gs_indexed_map * map;
+} gs_separation_params;
+
+typedef struct gs_device_n_params_s gs_device_n_params;
+struct gs_device_n_params_s {
+ gs_separation_name * names;
+ uint num_components;
+ gs_base_color_space alt_space;
+ int (* tint_transform)
+ (P4(const gs_device_n_params *params, const float *in, float *out,
+ void *data));
+ void * tint_transform_data;
};
-#define gs_paint_cspace_params\
- gs_base_cspace_params;\
- gs_separation_params separation;\
- gs_indexed_params indexed
+
+#define gs_paint_cspace_params \
+ gs_base_cspace_params; \
+ gs_indexed_params indexed; \
+ gs_separation_params separation; \
+ gs_device_n_params device_n
+
typedef struct gs_paint_color_space_s {
- const gs_color_space_type _ds *type;
- union {
- gs_paint_cspace_params;
- } params;
+ gs_cspace_common(gs_paint_cspace_params);
} gs_paint_color_space;
+#define gs_paint_color_space_size sizeof(gs_paint_color_space)
- /* General color spaces (including patterns) */
-
+/*
+ * Pattern parameter set. This may contain an instances of a paintable
+ * color space. The boolean indicates if this is the case.
+ */
typedef struct gs_pattern_params_s {
- bool has_base_space;
- gs_paint_color_space base_space;
+ bool has_base_space;
+ gs_paint_color_space base_space;
} gs_pattern_params;
+
+/*
+ * Fully general color spaces.
+ */
struct gs_color_space_s {
- const gs_color_space_type _ds *type;
- union {
- gs_paint_cspace_params;
- gs_pattern_params pattern;
- } params;
+ gs_cspace_common(
+ gs_paint_cspace_params;
+ gs_pattern_params pattern
+ );
};
+#define gs_pattern_color_space_size sizeof(gs_color_space)
+
+/*
+ * Define the abstract type for color space objects.
+ */
+#ifndef gs_color_space_DEFINED
+# define gs_color_space_DEFINED
+typedef struct gs_color_space_s gs_color_space;
+#endif
+
/*extern_st(st_color_space);*/ /* in gxcspace.h */
-#define public_st_color_space() /* in gscolor.c */\
- gs_public_st_composite(st_color_space, gs_color_space,\
- "gs_color_space", color_space_enum_ptrs, color_space_reloc_ptrs)
+#define public_st_color_space() /* in gscspace.c */ \
+ gs_public_st_composite( st_color_space, \
+ gs_color_space, \
+ "gs_color_space", \
+ color_space_enum_ptrs, \
+ color_space_reloc_ptrs \
+ )
+
#define st_color_space_max_ptrs 2 /* 1 base + 1 indexed */
/* ---------------- Procedures ---------------- */
+/* ------ Create/copy/destroy ------ */
+
+/*
+ * Note that many of the constructors take no parameters, and the
+ * remainder take only a few (CIE color spaces constructures take a
+ * client data pointer as an operand, the composite color space (Separation,
+ * Indexed, and Pattern) constructurs take the base space as an operand,
+ * and the Indexed color space constructors have a few additiona operands).
+ * This is done to conserve memory. If initialization values for all the
+ * color space parameters were provided to the constructors, these values
+ * would need to have some fairly generic format. Different clients gather
+ * this data in different forms, so they would need to allocate memory to
+ * convert it to the generic form, only to immediately release this memory
+ * once the construction is complete.
+ *
+ * The alternative approach employed here is to provide a number of access
+ * methods (macros) that return pointers to individual fields of the
+ * various color space structures. This requires exporting only fairly simple
+ * data structures, and so does not violate modularity too severely.
+ *
+ * NB: Of necessity, the macros provide access to modifiable structures. If
+ * these structures are modified after the color space object is first
+ * initialized, unpredictable and, most likely, undesirable results will
+ * occur.
+ *
+ * The constructors will return an integer, which is 0 on success and an
+ * error code on failure (gs_error_VMerror or gs_error_rangecheck).
+ */
+
+extern int
+ gs_cspace_build_DeviceGray(P2(gs_color_space **ppcspace, gs_memory_t *pmem)),
+ gs_cspace_build_DeviceRGB(P2(gs_color_space **ppcspace, gs_memory_t *pmem)),
+ gs_cspace_build_DeviceCMYK(P2(gs_color_space **ppcspace, gs_memory_t *pmem));
+
+/*
+ * We preallocate instances of the 3 device color spaces, and provide
+ * procedures that return them. Note that gs_cspace_DeviceCMYK() is
+ * defined even if CMYK color support is not included in this configuration.
+ */
+#ifndef gs_imager_state_DEFINED
+# define gs_imager_state_DEFINED
+typedef struct gs_imager_state_s gs_imager_state;
+#endif
+extern const gs_color_space *
+ gs_cspace_DeviceGray(P1(const gs_imager_state *pis));
+extern const gs_color_space *
+ gs_cspace_DeviceRGB(P1(const gs_imager_state *pis));
+extern const gs_color_space *
+ gs_cspace_DeviceCMYK(P1(const gs_imager_state *pis));
+
+/* Copy a color space into one newly allocated by the caller. */
+void gs_cspace_init_from(P2(gs_color_space *pcsto,
+ const gs_color_space *pcsfrom));
+
+/* Assign a color space into a previously initialized one. */
+void cs_cspace_assign(P2(gs_color_space *pdest, const gs_color_space *psrc));
+
+/* Prepare to free a color space. */
+void gs_cspace_release(P1(gs_color_space *pcs));
+
+/* ------ Accessors ------ */
+
/* Get the index of a color space. */
-gs_color_space_index gs_color_space_get_index(P1(const gs_color_space *));
+extern gs_color_space_index gs_color_space_get_index(P1(
+ const gs_color_space *
+));
/* Get the number of components in a color space. */
-int gs_color_space_num_components(P1(const gs_color_space *));
-
-/* Get the base space of an Indexed color space. */
-/* We have to redefine this because the VAX VMS C compiler (but not */
-/* the preprocessor!) limits identifiers to 31 characters. */
-#define gs_color_space_indexed_base_space(pcs)\
- gs_color_space_indexed_base(pcs)
-const gs_color_space *
- gs_color_space_indexed_base_space(P1(const gs_color_space *));
+extern int gs_color_space_num_components(P1( const gs_color_space * ));
+
+/*
+ * Get the base space of an Indexed or uncolored Pattern color space, or the
+ * alternate space of a Separation or DeviceN space. Return NULL if the
+ * color space does not have a base/alternative color space.
+ */
+extern const gs_color_space * gs_cspace_base_space(
+ const gs_color_space * pcspace
+);
+
+/* backwards compatibility */
+#define gs_color_space_indexed_base_space(pcspace)\
+ gs_cspace_base_space(pcspace)
#endif /* gscspace_INCLUDED */