1 /* Copyright (C) 2001-2012 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.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Color mapping procedures */
18 /* Requires gxdcolor.h. */
19 
20 #ifndef gxcmap_INCLUDED
21 #  define gxcmap_INCLUDED
22 
23 #include "gscsel.h"
24 #include "gxfmap.h"
25 #include "gscspace.h"
26 
27 #ifndef gx_device_DEFINED
28 #  define gx_device_DEFINED
29 typedef struct gx_device_s gx_device;
30 #endif
31 #ifndef gx_device_color_DEFINED
32 #  define gx_device_color_DEFINED
33 typedef struct gx_device_color_s gx_device_color;
34 #endif
35 
36 /* Procedures for rendering colors specified by fractions. */
37 
38 #define cmap_proc_gray(proc)\
39   void proc(frac, gx_device_color *, const gs_imager_state *,\
40             gx_device *, gs_color_select_t)
41 #define cmap_proc_rgb(proc)\
42   void proc(frac, frac, frac, gx_device_color *, const gs_imager_state *,\
43             gx_device *, gs_color_select_t)
44 #define cmap_proc_cmyk(proc)\
45   void proc(frac, frac, frac, frac, gx_device_color *,\
46             const gs_imager_state *, gx_device *, gs_color_select_t,\
47             const gs_color_space *)
48 #define cmap_proc_rgb_alpha(proc)\
49   void proc(frac, frac, frac, frac, gx_device_color *,\
50                const gs_imager_state *, gx_device *, gs_color_select_t)
51 #define cmap_proc_separation(proc)\
52   void proc(frac, gx_device_color *, const gs_imager_state *,\
53                gx_device *, gs_color_select_t)
54 #define cmap_proc_devicen(proc)\
55   void proc(const frac *, gx_device_color *, const gs_imager_state *, \
56                gx_device *, gs_color_select_t)
57 #define cmap_proc_is_halftoned(proc)\
58   bool proc(const gs_imager_state *, gx_device *)
59 
60 /*
61  * List of mapping functions from the standard color spaces to the
62  * device color model. Any unused component will be mapped to 0.
63  */
64 #define cm_map_proc_gray(proc) \
65     void proc (gx_device * dev, frac gray, \
66               frac * out)
67 
68 #define cm_map_proc_rgb(proc) \
69     void proc (gx_device * dev, \
70               const gs_imager_state *pis, \
71               frac r, frac g, frac b, \
72               frac * out)
73 
74 #define cm_map_proc_cmyk(proc) \
75     void proc (gx_device * dev, \
76               frac c, frac m, frac y, frac k, \
77               frac * out)
78 
79 /*
80  * The following procedures come from the device.  It they are
81  * specified then  they are used to convert from the given
82  * color space to the device's color model.  Otherwise the
83  * standard conversions are used.  The procedures must be defined
84  * for a DeviceN color model
85  *
86  * Because of a bug in the Watcom C compiler, we have to split the
87  * struct from the typedef.
88  */
89 struct gx_cm_color_map_procs_s {
90     cm_map_proc_gray((*map_gray));
91     cm_map_proc_rgb((*map_rgb));
92     cm_map_proc_cmyk((*map_cmyk));
93 };
94 
95 typedef struct gx_cm_color_map_procs_s  gx_cm_color_map_procs;
96 
97 /*
98  * Make some routine global for use in the forwarding device.
99  */
100 cm_map_proc_gray(gray_cs_to_gray_cm);
101 cm_map_proc_rgb(rgb_cs_to_rgb_cm);
102 cm_map_proc_cmyk(cmyk_cs_to_cmyk_cm);
103 
104 /*
105  * Color mapping may now be device specific, so the color space
106  * to color model mapping is separated from other maps, such as
107  * applying the current transfer function or halftone.
108  *
109  * The routine pointed to by get_cmap_procs (a field in the image
110  * state; see gxistate.h) should initialize the cm_color_map_procs
111  * pointer, using the get_color_mapping_procs method of the device.
112  *
113  * Because of a bug in the Watcom C compiler, we have to split the
114  * struct from the typedef.
115  */
116 struct gx_color_map_procs_s {
117     cmap_proc_gray((*map_gray));
118     cmap_proc_rgb((*map_rgb));
119     cmap_proc_cmyk((*map_cmyk));
120     cmap_proc_rgb_alpha((*map_rgb_alpha));
121     cmap_proc_separation((*map_separation));
122     cmap_proc_devicen((*map_devicen));
123     cmap_proc_is_halftoned((*is_halftoned));
124 };
125 typedef struct gx_color_map_procs_s gx_color_map_procs;
126 
127 /*
128  * Determine the color mapping procedures for a device.  Even though this
129  * does not currently use information from the imager state, it must be
130  * a virtual procedure of the state for internal reasons.
131  */
132 const gx_color_map_procs *
133     gx_get_cmap_procs(const gs_imager_state *, const gx_device *);
134 const gx_color_map_procs *
135     gx_default_get_cmap_procs(const gs_imager_state *, const gx_device *);
136 
137 /*
138  * Set the color mapping procedures in the graphics state.  This is
139  * currently only needed when switching devices, but might be used more
140  * often in the future.
141  */
142 void gx_set_cmap_procs(gs_imager_state *, const gx_device *);
143 
144 /* Remap a concrete (frac) gray, RGB or CMYK color. */
145 /* These cannot fail, and do not return a value. */
146 #define gx_remap_concrete_gray(cgray, pdc, pis, dev, select)\
147   ((pis)->cmap_procs->map_gray)(cgray, pdc, pis, dev, select)
148 #define gx_remap_concrete_rgb(cr, cg, cb, pdc, pis, dev, select)\
149   ((pis)->cmap_procs->map_rgb)(cr, cg, cb, pdc, pis, dev, select)
150 #define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pis, dev, select, pcs)\
151   ((pis)->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pis, dev, select, pcs)
152 #define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pis, dev, select)\
153   ((pis)->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pis, dev, select)
154 #define gx_remap_concrete_separation(pcc, pdc, pis, dev, select)\
155   ((pis)->cmap_procs->map_separation)(pcc, pdc, pis, dev, select)
156 #define gx_remap_concrete_devicen(pcc, pdc, pis, dev, select)\
157   ((pis)->cmap_procs->map_devicen)(pcc, pdc, pis, dev, select)
158 
159 /* Map a color */
160 #include "gxcindex.h"
161 #include "gxcvalue.h"
162 
163 /*
164  * These are the default routines for converting a color space into
165  * a list of device colorants.
166  */
167 extern cm_map_proc_gray(gx_default_gray_cs_to_gray_cm);
168 extern cm_map_proc_rgb(gx_default_rgb_cs_to_gray_cm);
169 extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_gray_cm);
170 
171 extern cm_map_proc_gray(gx_default_gray_cs_to_rgb_cm);
172 extern cm_map_proc_rgb(gx_default_rgb_cs_to_rgb_cm);
173 extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_rgb_cm);
174 
175 extern cm_map_proc_gray(gx_default_gray_cs_to_cmyk_cm);
176 extern cm_map_proc_rgb(gx_default_rgb_cs_to_cmyk_cm);
177 extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_cmyk_cm);
178 
179 extern cm_map_proc_gray(gx_default_gray_cs_to_cmyk_cm);
180 extern cm_map_proc_rgb(gx_default_rgb_cs_to_cmyk_cm);
181 extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_cmyk_cm);
182 
183 extern cm_map_proc_gray(gx_error_gray_cs_to_cmyk_cm);
184 extern cm_map_proc_rgb(gx_error_rgb_cs_to_cmyk_cm);
185 extern cm_map_proc_cmyk(gx_error_cmyk_cs_to_cmyk_cm);
186 
187 /*
188   Get the mapping procedures appropriate for the currently set
189   color model.
190  */
191 #define dev_t_proc_get_color_mapping_procs(proc, dev_t) \
192     const gx_cm_color_map_procs * (proc)(const dev_t * dev)
193 
194 #define dev_proc_get_color_mapping_procs(proc) \
195     dev_t_proc_get_color_mapping_procs(proc, gx_device)
196 
197 /*
198   Define the options for the component_type parameter to get_color_comp_index
199   routines.  Note:  This information is currently being used by the routines
200   for identifying when they are being given a separation name.  Some devices
201   automaticaly add separations to the device's components if the separation
202   is not previously known and there is room in the device.
203 */
204 #define NO_COMP_NAME_TYPE	0
205 #define SEPARATION_NAME		1
206 
207 /*
208   Convert a color component name into a colorant index.
209 */
210 #define dev_t_proc_get_color_comp_index(proc, dev_t) \
211     int (proc)(dev_t * dev, const char * pname, int name_size, int component_type)
212 
213 #define dev_proc_get_color_comp_index(proc) \
214     dev_t_proc_get_color_comp_index(proc, gx_device)
215 
216 /*
217   Map a color into the device's color model.
218 */
219 #define dev_t_proc_encode_color(proc, dev_t) \
220     gx_color_index (proc)(dev_t * dev, const gx_color_value colors[])
221 
222 #define dev_proc_encode_color(proc) \
223     dev_t_proc_encode_color(proc, gx_device)
224 
225 /*
226   Map a color index from the device's current color model into a list of
227   colorant values.
228 */
229 #define dev_t_proc_decode_color(proc, dev_t) \
230     int (proc)(dev_t * dev, gx_color_index cindex, gx_color_value colors[])
231 
232 #define dev_proc_decode_color(proc) \
233     dev_t_proc_decode_color(proc, gx_device)
234 
235 /*
236  * These are the default routines for translating a color component
237  * name into the device colorant index.
238  */
239 dev_proc_get_color_comp_index(gx_error_get_color_comp_index);
240 dev_proc_get_color_comp_index(gx_default_DevGray_get_color_comp_index);
241 dev_proc_get_color_comp_index(gx_default_DevRGB_get_color_comp_index);
242 dev_proc_get_color_comp_index(gx_default_DevCMYK_get_color_comp_index);
243 dev_proc_get_color_comp_index(gx_default_DevRGBK_get_color_comp_index);
244 
245 /*
246  * These are the default routines for getting the color space conversion
247  * routines.
248  */
249 dev_proc_get_color_mapping_procs(gx_error_get_color_mapping_procs);
250 dev_proc_get_color_mapping_procs(gx_default_DevGray_get_color_mapping_procs);
251 dev_proc_get_color_mapping_procs(gx_default_DevRGB_get_color_mapping_procs);
252 dev_proc_get_color_mapping_procs(gx_default_DevCMYK_get_color_mapping_procs);
253 dev_proc_get_color_mapping_procs(gx_default_DevRGBK_get_color_mapping_procs);
254 
255 /*
256  * These are the default routines for converting a colorant value list
257  * into a gx_color_index.
258  */
259 dev_proc_encode_color(gx_error_encode_color);
260 dev_proc_encode_color(gx_default_encode_color);
261 
262 /*
263  * These are the default routines for converting a colorant value list
264  * into a gx_color_index.
265  */
266 dev_proc_encode_color(gx_default_gray_fast_encode);
267 dev_proc_encode_color(gx_default_gray_encode);
268 
269 /*
270  * This is the default encode_color routine for grayscale devices
271  * that provide a map_rgb_color procedure, but don't themselves
272  * provide encode_color.
273  */
274 dev_proc_encode_color(gx_backwards_compatible_gray_encode);
275 
276 /*
277  * These are the default routines for converting a gx_color_index into
278  * a list of device colorant values
279  */
280 dev_proc_decode_color(gx_error_decode_color);
281 dev_proc_decode_color(gx_default_decode_color);
282 
283 /*
284  * convert a float paint value to a fractional value with clamping to
285  * [0,1]
286  */
287 frac gx_unit_frac(float fvalue);
288 /* Determine if the device is using the standard color mapping procs.  In
289    such a case, we can make use of the faster icc color conversions for
290    images */
291 bool gx_device_uses_std_cmap_procs(gx_device * dev,
292                                    const gs_imager_state * pis);
293 bool fwd_uses_fwd_cmap_procs(gx_device * dev);
294 const gx_cm_color_map_procs* fwd_get_target_cmap_procs(gx_device * dev);
295 void cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc,
296      const gs_imager_state * pis, gx_device * dev, bool has_transfer,
297      bool has_halftone, gs_color_select_t select);
298 void cmap_transfer(gx_color_value *pconc, const gs_imager_state * pis,
299                    gx_device * dev);
300 void cmap_transfer_plane(gx_color_value *pconc, const gs_imager_state *pis,
301                     gx_device *dev, int plane);
302 #endif /* gxcmap_INCLUDED */
303