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