1 /* Copyright (C) 2003 Artifex Software Inc, artofcode llc. 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 /* $Id: gxhldevc.c,v 1.4 2005/05/31 10:56:57 igor Exp $ */
17 /* High level device color save/compare procedures */
18
19 /*
20 * See comments at the start of gxhldevc.h for more explanation of the
21 * purpose and operation of these procedures.
22 */
23 #include "gx.h"
24 #include "gzstate.h"
25 #include "gscspace.h"
26 #include "gxcspace.h"
27 #include "gxhldevc.h"
28 #include "memory_.h"
29 #include "gxpcolor.h"
30 #include "gsptype2.h"
31
32 /*
33 * Initiailze a high level saved color to null
34 */
gx_hld_saved_color_init(gx_hl_saved_color * psc)35 void gx_hld_saved_color_init(gx_hl_saved_color * psc)
36 {
37 gx_device_color temp_devc;
38
39 memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
40 psc->color_space_id = psc->pattern_id = gs_no_id;
41 color_set_null(&temp_devc);
42 temp_devc.type->save_dc(&temp_devc, &(psc->saved_dev_color));
43 }
44
45 /*
46 * Get graphics state pointer (from imager state pointer)
47 */
gx_hld_get_gstate_ptr(const gs_imager_state * pis)48 const gs_state * gx_hld_get_gstate_ptr(const gs_imager_state * pis)
49 {
50 extern_st(st_gs_state); /* only for testing */
51
52 /* Check to verify the structure type is really st_gs_state */
53 if (pis == NULL || gs_object_type(pis->memory, pis) != &st_gs_state)
54 return NULL;
55
56 return (const gs_state *) pis;
57 }
58
59 /*
60 * Save the device color information including the color space id and
61 * client color data (if available).
62 *
63 * More description in src/gxhldevc.h
64 */
65 bool
gx_hld_save_color(const gs_imager_state * pis,const gx_device_color * pdevc,gx_hl_saved_color * psc)66 gx_hld_save_color(const gs_imager_state * pis, const gx_device_color * pdevc,
67 gx_hl_saved_color * psc)
68 {
69 const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
70 memset(psc, 0, sizeof(*psc)); /* clear the entire structure */
71
72 if (pdevc == NULL) {
73 /* No device color given, should not happen */
74 gx_hld_saved_color_init(psc); /* revert to unknown color */
75 return false;
76 } else if (pgs == NULL) {
77 /* No color space, simply save device color specific info */
78 psc->color_space_id = psc->pattern_id = gs_no_id;
79 pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
80 return false;
81 } else {
82 /*
83 * Have color space, save id, ccolor, & device color specific info.
84 * Also save the high level colors since two gx_color_index values
85 * may be the same but for differing high level colors (due to the
86 * usual lower resolution of the gx_color_index values.
87 */
88 const gs_color_space * pcs = pgs->color_space;
89 int i = gs_color_space_num_components(pcs);
90
91 psc->color_space_id = pcs->id;
92 pdevc->type->save_dc(pdevc, &(psc->saved_dev_color));
93 i = any_abs(i);
94 for (i--; i >= 0; i--)
95 psc->ccolor.paint.values[i] = pdevc->ccolor.paint.values[i];
96
97 /* Save the pattern id - if present */
98 if ((pdevc->type == gx_dc_type_pattern
99 || pdevc->type == gx_dc_type_pattern2) && pdevc->ccolor_valid)
100 psc->pattern_id = pdevc->ccolor.pattern->pattern_id;
101 else
102 psc->pattern_id = gs_no_id;
103 return true;
104 }
105 }
106
107 /*
108 * Compare two saved colors to check if match. Note this routine assumes
109 * unused parts of the saved color have been zeroed. See gx_hld_save_color()
110 * for what is actually being compared.
111 */
gx_hld_saved_color_equal(const gx_hl_saved_color * psc1,const gx_hl_saved_color * psc2)112 bool gx_hld_saved_color_equal(const gx_hl_saved_color * psc1,
113 const gx_hl_saved_color * psc2)
114 {
115 return (memcmp(psc1, psc2, sizeof(*psc1)) == 0);
116 }
117
118 /*
119 * Check whether two saved colors have same color space.
120 */
gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,const gx_hl_saved_color * psc2)121 bool gx_hld_saved_color_same_cspace(const gx_hl_saved_color * psc1,
122 const gx_hl_saved_color * psc2)
123 {
124 if (psc1->color_space_id != psc2->color_space_id)
125 return false;
126 if (psc1->pattern_id != psc2->pattern_id)
127 return false;
128 if (psc1->ccolor_valid != psc2->ccolor_valid)
129 return false;
130 if (psc1->color_space_id != psc2->color_space_id)
131 return false;
132 return true;
133 }
134
135 /*
136 * Check if a high level color is availavble.
137 */
138 bool
gx_hld_is_hl_color_available(const gs_imager_state * pis,const gx_device_color * pdevc)139 gx_hld_is_hl_color_available(const gs_imager_state * pis,
140 const gx_device_color * pdevc)
141 {
142 const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
143
144 if (pgs != NULL && pdevc != NULL && pdevc->ccolor_valid)
145 return true;
146 return false;
147 }
148
149 /*
150 * Get pointers to the current color space and client color.
151 *
152 * More description in src/gxhldevc.h
153 */
154 gx_hld_get_color_space_and_ccolor_status
gx_hld_get_color_space_and_ccolor(const gs_imager_state * pis,const gx_device_color * pdevc,const gs_color_space ** ppcs,const gs_client_color ** ppcc)155 gx_hld_get_color_space_and_ccolor(const gs_imager_state * pis,
156 const gx_device_color * pdevc, const gs_color_space ** ppcs,
157 const gs_client_color ** ppcc)
158 {
159 /* Check if the current color space was used to build the device color */
160 if (gx_hld_is_hl_color_available(pis, pdevc)) {
161 const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
162 const gs_color_space * pcs = pgs->color_space;
163
164 *ppcs = pcs;
165 *ppcc = &(pdevc->ccolor);
166 if (pdevc->type == gx_dc_type_pattern
167 || pdevc->type == &gx_dc_pure_masked
168 || pdevc->type == gx_dc_type_pattern2)
169 return pattern_color_sapce;
170 else {
171 return non_pattern_color_space;
172 }
173 }
174 /* No color space */
175 *ppcs = NULL;
176 *ppcc = NULL;
177 return use_process_color;
178 }
179
180 /*
181 * Get the number of components in the current color space.
182 *
183 * More description in src/gxhldevc.h
184 */
185 int
gx_hld_get_number_color_components(const gs_imager_state * pis)186 gx_hld_get_number_color_components(const gs_imager_state * pis)
187 {
188 const gs_state * pgs = gx_hld_get_gstate_ptr(pis);
189
190 if (pgs != NULL) {
191 const gs_color_space * pcs = pgs->color_space;
192 int n = gs_color_space_num_components(pcs);
193
194 return (n >= 0 ? n : -n - 1);
195 } else
196 return -1;
197 }
198
199 /*
200 * Get the requested high level color value.
201 *
202 * More description in src/gxhldevc.h
203 */
204 gx_hld_get_color_component_status
gx_hld_get_color_component(const gs_imager_state * pis,const gx_device_color * pdevc,int comp_num,float * output)205 gx_hld_get_color_component(const gs_imager_state * pis,
206 const gx_device_color * pdevc,
207 int comp_num, float * output)
208 {
209 if (pdevc != NULL && pdevc->ccolor_valid) {
210 int ncomp = gx_hld_get_number_color_components(pis);
211
212 if (ncomp < 0)
213 return invalid_color_info;
214 if (comp_num < 0 || comp_num >= ncomp)
215 return invalid_component_requested;
216 *output = pdevc->ccolor.paint.values[comp_num];
217 return valid_result;
218 }
219 return invalid_color_info;
220 }
221
222