/src/ghostpdl/base/gsgstate.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 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., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* gs_gstate housekeeping */ |
18 | | #include "gx.h" |
19 | | #include "gserrors.h" |
20 | | #include "gscspace.h" |
21 | | #include "gscie.h" |
22 | | #include "gsstruct.h" |
23 | | #include "gsutil.h" /* for gs_next_ids */ |
24 | | #include "gxbitmap.h" |
25 | | #include "gxcmap.h" |
26 | | #include "gxdht.h" |
27 | | #include "gxgstate.h" |
28 | | #include "gzht.h" |
29 | | #include "gzline.h" |
30 | | #include "gxfmap.h" |
31 | | #include "gsicc_cache.h" |
32 | | #include "gsicc_manage.h" |
33 | | #include "gsicc_profilecache.h" |
34 | | |
35 | | /****************************************************************************** |
36 | | * See gsstate.c for a discussion of graphics state memory management. * |
37 | | ******************************************************************************/ |
38 | | |
39 | | /* Imported values */ |
40 | | /* The following should include a 'const', but for some reason */ |
41 | | /* the Watcom compiler won't accept it, even though it happily accepts */ |
42 | | /* the same construct everywhere else. */ |
43 | | extern /*const*/ gx_color_map_procs *const cmap_procs_default; |
44 | | |
45 | | /* GC procedures for gx_line_params */ |
46 | | static |
47 | 26.2M | ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0; |
48 | 13.1M | case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ? |
49 | 26.2M | NULL : plp->dash.pattern)); |
50 | 26.2M | ENUM_PTRS_END |
51 | 13.1M | static RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp) |
52 | 13.1M | { |
53 | 13.1M | if (plp->dash.pattern_size) |
54 | 13.1M | RELOC_VAR(plp->dash.pattern); |
55 | 13.1M | } RELOC_PTRS_END |
56 | | private_st_line_params(); |
57 | | |
58 | | /* |
59 | | * GC procedures for gs_gstate |
60 | | * |
61 | | * See comments in gixstate.h before the definition of gs_cr_state_do_rc and |
62 | | * st_cr_state_num_ptrs for an explanation about why the effective_transfer |
63 | | * pointers are handled in this manner. |
64 | | */ |
65 | | public_st_gs_gstate(); |
66 | | static |
67 | 537M | ENUM_PTRS_WITH(gs_gstate_enum_ptrs, gs_gstate *gisvptr) |
68 | 26.2M | ENUM_SUPER(gs_gstate, st_line_params, line_params, st_gs_gstate_num_ptrs - st_line_params_num_ptrs); |
69 | 275M | #define e1(i,elt) ENUM_PTR(i,gs_gstate,elt); |
70 | 275M | gs_gstate_do_ptrs(e1) |
71 | 0 | #undef e1 |
72 | 223M | #define E1(i,elt) ENUM_PTR(i + gs_gstate_num_ptrs,gs_gstate,elt); |
73 | 223M | gs_cr_state_do_ptrs(E1) |
74 | 0 | #undef E1 |
75 | 13.1M | case (gs_gstate_num_ptrs + st_cr_state_num_ptrs): /* handle device specially */ |
76 | 13.1M | ENUM_RETURN(gx_device_enum_ptr(gisvptr->device)); |
77 | 537M | ENUM_PTRS_END |
78 | | |
79 | 13.1M | static RELOC_PTRS_WITH(gs_gstate_reloc_ptrs, gs_gstate *gisvptr) |
80 | 13.1M | { |
81 | 13.1M | RELOC_SUPER(gs_gstate, st_line_params, line_params); |
82 | 275M | #define r1(i,elt) RELOC_PTR(gs_gstate,elt); |
83 | 275M | gs_gstate_do_ptrs(r1) |
84 | 13.1M | #undef r1 |
85 | 223M | #define R1(i,elt) RELOC_PTR(gs_gstate,elt); |
86 | 223M | gs_cr_state_do_ptrs(R1) |
87 | 13.1M | #undef R1 |
88 | | |
89 | 13.1M | gisvptr->device = gx_device_reloc_ptr(gisvptr->device, gcst); |
90 | 13.1M | { |
91 | 13.1M | int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1; |
92 | | |
93 | 852M | for (; i >= 0; i--) |
94 | 839M | RELOC_PTR(gs_gstate, effective_transfer[i]); |
95 | 13.1M | } |
96 | 13.1M | } RELOC_PTRS_END |
97 | | |
98 | | /* Initialize an gs_gstate, other than the parts covered by */ |
99 | | /* GS_STATE_INIT_VALUES(). */ |
100 | | int |
101 | | gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) |
102 | 3.26M | { |
103 | 3.26M | int i; |
104 | 3.26M | pgs->memory = mem; |
105 | 3.26M | pgs->client_data = 0; |
106 | 3.26M | pgs->trans_device = 0; |
107 | | /* Color rendering state */ |
108 | 3.26M | pgs->halftone = 0; |
109 | 3.26M | { |
110 | 3.26M | int i; |
111 | | |
112 | 9.78M | for (i = 0; i < gs_color_select_count; ++i) |
113 | 6.52M | pgs->screen_phase[i].x = pgs->screen_phase[i].y = 0; |
114 | 3.26M | } |
115 | 16.3M | for (i=0; i < HT_OBJTYPE_COUNT; i++) |
116 | 13.0M | pgs->dev_ht[i] = NULL; |
117 | 3.26M | pgs->cie_render = 0; |
118 | 3.26M | pgs->cie_to_xyz = false; |
119 | 3.26M | pgs->black_generation = 0; |
120 | 3.26M | pgs->undercolor_removal = 0; |
121 | | /* Allocate an initial transfer map. */ |
122 | 3.26M | rc_alloc_struct_n(pgs->set_transfer.gray, |
123 | 3.26M | gx_transfer_map, &st_transfer_map, |
124 | 3.26M | mem, return_error(gs_error_VMerror), |
125 | 3.26M | "gs_gstate_init(transfer)", 1); |
126 | 3.26M | pgs->set_transfer.gray->proc = gs_identity_transfer; |
127 | 3.26M | pgs->set_transfer.gray->id = gs_next_ids(pgs->memory, 1); |
128 | 3.26M | pgs->set_transfer.gray->values[0] = frac_0; |
129 | 3.26M | pgs->set_transfer.red = |
130 | 3.26M | pgs->set_transfer.green = |
131 | 3.26M | pgs->set_transfer.blue = NULL; |
132 | 212M | for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) |
133 | 208M | pgs->effective_transfer[i] = pgs->set_transfer.gray; |
134 | 3.26M | pgs->cie_joint_caches = NULL; |
135 | 3.26M | pgs->cie_joint_caches_alt = NULL; |
136 | 3.26M | pgs->cmap_procs = cmap_procs_default; |
137 | 3.26M | pgs->pattern_cache = NULL; |
138 | 3.26M | pgs->have_pattern_streams = false; |
139 | 3.26M | pgs->devicergb_cs = gs_cspace_new_DeviceRGB(mem); |
140 | 3.26M | pgs->devicecmyk_cs = gs_cspace_new_DeviceCMYK(mem); |
141 | 3.26M | if (pgs->devicergb_cs == NULL || pgs->devicecmyk_cs == NULL) |
142 | 0 | return_error(gs_error_VMerror); |
143 | 3.26M | pgs->icc_link_cache = gsicc_cache_new(pgs->memory); |
144 | 3.26M | if (pgs->icc_link_cache == NULL) |
145 | 0 | return_error(gs_error_VMerror); |
146 | 3.26M | pgs->icc_manager = gsicc_manager_new(pgs->memory); |
147 | 3.26M | if (pgs->icc_manager == NULL) |
148 | 0 | return_error(gs_error_VMerror); |
149 | 3.26M | pgs->icc_profile_cache = gsicc_profilecache_new(pgs->memory); |
150 | 3.26M | if (pgs->icc_profile_cache == NULL) |
151 | 0 | return_error(gs_error_VMerror); |
152 | 3.26M | pgs->black_textvec_state = NULL; |
153 | | #if ENABLE_CUSTOM_COLOR_CALLBACK |
154 | | pgs->custom_color_callback = INIT_CUSTOM_COLOR_PTR; |
155 | | #endif |
156 | 3.26M | return 0; |
157 | 3.26M | } |
158 | | |
159 | | /* Increment reference counts to note that an gs_gstate has been copied. */ |
160 | | void |
161 | | gs_gstate_copied(gs_gstate * pgs) |
162 | 59.7M | { |
163 | 59.7M | int i; |
164 | | |
165 | 59.7M | rc_increment(pgs->halftone); |
166 | 298M | for (i=0; i < HT_OBJTYPE_COUNT; i++) |
167 | 238M | rc_increment(pgs->dev_ht[i]); |
168 | 59.7M | rc_increment(pgs->cie_render); |
169 | 59.7M | rc_increment(pgs->black_generation); |
170 | 59.7M | rc_increment(pgs->undercolor_removal); |
171 | 59.7M | rc_increment(pgs->set_transfer.gray); |
172 | 59.7M | rc_increment(pgs->set_transfer.red); |
173 | 59.7M | rc_increment(pgs->set_transfer.green); |
174 | 59.7M | rc_increment(pgs->set_transfer.blue); |
175 | 59.7M | rc_increment(pgs->cie_joint_caches); |
176 | 59.7M | rc_increment(pgs->cie_joint_caches_alt); |
177 | 59.7M | rc_increment(pgs->devicergb_cs); |
178 | 59.7M | rc_increment(pgs->devicecmyk_cs); |
179 | 59.7M | rc_increment(pgs->icc_link_cache); |
180 | 59.7M | rc_increment(pgs->icc_profile_cache); |
181 | 59.7M | rc_increment(pgs->icc_manager); |
182 | 59.7M | rc_increment(pgs->black_textvec_state); |
183 | 59.7M | } |
184 | | |
185 | | /* Adjust reference counts before assigning one gs_gstate to another. */ |
186 | | void |
187 | | gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) |
188 | 60.2k | { |
189 | 60.2k | const char *const cname = "gs_gstate_pre_assign"; |
190 | 60.2k | int i; |
191 | | |
192 | 60.2k | #define RCCOPY(element)\ |
193 | 1.02M | rc_pre_assign(pto->element, pfrom->element, cname) |
194 | | |
195 | 60.2k | RCCOPY(cie_joint_caches); |
196 | 60.2k | RCCOPY(cie_joint_caches_alt); |
197 | 60.2k | RCCOPY(set_transfer.blue); |
198 | 60.2k | RCCOPY(set_transfer.green); |
199 | 60.2k | RCCOPY(set_transfer.red); |
200 | 60.2k | RCCOPY(set_transfer.gray); |
201 | 60.2k | RCCOPY(undercolor_removal); |
202 | 60.2k | RCCOPY(black_generation); |
203 | 60.2k | RCCOPY(cie_render); |
204 | 301k | for (i=0; i < HT_OBJTYPE_COUNT; i++) |
205 | 240k | RCCOPY(dev_ht[i]); |
206 | 60.2k | RCCOPY(halftone); |
207 | 60.2k | RCCOPY(devicergb_cs); |
208 | 60.2k | RCCOPY(devicecmyk_cs); |
209 | 60.2k | RCCOPY(icc_link_cache); |
210 | 60.2k | RCCOPY(icc_profile_cache); |
211 | 60.2k | RCCOPY(icc_manager); |
212 | 60.2k | RCCOPY(black_textvec_state); |
213 | 60.2k | #undef RCCOPY |
214 | 60.2k | } |
215 | | |
216 | | /* Release a gs_gstate. */ |
217 | | void |
218 | | gs_gstate_release(gs_gstate * pgs) |
219 | 122M | { |
220 | 122M | const char *const cname = "gs_gstate_release"; |
221 | 122M | gx_device_halftone *pdht; |
222 | 122M | int i; |
223 | | |
224 | 122M | #define RCDECR(element)\ |
225 | 2.32G | rc_decrement(pgs->element, cname);\ |
226 | 2.32G | pgs->element = NULL /* prevent subsequent decrements from this gs_gstate */ |
227 | | |
228 | 122M | RCDECR(cie_joint_caches); |
229 | 122M | RCDECR(set_transfer.gray); |
230 | 122M | RCDECR(set_transfer.blue); |
231 | 122M | RCDECR(set_transfer.green); |
232 | 122M | RCDECR(set_transfer.red); |
233 | 122M | RCDECR(undercolor_removal); |
234 | 122M | RCDECR(black_generation); |
235 | 122M | RCDECR(cie_render); |
236 | | /* |
237 | | * If we're going to free a device halftone, make sure we free the |
238 | | * dependent structures as well. |
239 | | */ |
240 | 613M | for (i=0; i < HT_OBJTYPE_COUNT; i++) { |
241 | 490M | pdht = pgs->dev_ht[i]; |
242 | 490M | if (pdht != NULL && pdht->rc.ref_count == 1) { |
243 | 1.28M | gx_device_halftone_release(pdht, pdht->rc.memory); |
244 | 1.28M | } |
245 | 490M | RCDECR(dev_ht[i]); |
246 | 490M | } |
247 | 122M | RCDECR(halftone); |
248 | 122M | RCDECR(devicergb_cs); |
249 | 122M | RCDECR(devicecmyk_cs); |
250 | 122M | RCDECR(icc_link_cache); |
251 | 122M | RCDECR(icc_profile_cache); |
252 | 122M | RCDECR(icc_manager); |
253 | 122M | RCDECR(black_textvec_state); |
254 | 122M | #undef RCDECR |
255 | 122M | } |