1 /* Copyright (C) 1999, 2000 Aladdin Enterprises. 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
17 /* $Id: gsistate.c,v 1.12 2005/08/30 06:38:44 igor Exp $ */
18 /* Imager state housekeeping */
19 #include "gx.h"
20 #include "gserrors.h"
21 #include "gscspace.h"
22 #include "gscie.h"
23 #include "gsstruct.h"
24 #include "gsutil.h" /* for gs_next_ids */
25 #include "gxbitmap.h"
26 #include "gxcmap.h"
27 #include "gxdht.h"
28 #include "gxistate.h"
29 #include "gzht.h"
30 #include "gzline.h"
31 #include "gxfmap.h"
32
33 /******************************************************************************
34 * See gsstate.c for a discussion of graphics/imager state memory management. *
35 ******************************************************************************/
36
37 /* Imported values */
38 /* The following should include a 'const', but for some reason */
39 /* the Watcom compiler won't accept it, even though it happily accepts */
40 /* the same construct everywhere else. */
41 extern /*const*/ gx_color_map_procs *const cmap_procs_default;
42
43 /* GC procedures for gx_line_params */
44 private
45 ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0;
46 case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ?
47 NULL : plp->dash.pattern));
48 ENUM_PTRS_END
RELOC_PTRS_WITH(line_params_reloc_ptrs,gx_line_params * plp)49 private RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp)
50 {
51 if (plp->dash.pattern_size)
52 RELOC_VAR(plp->dash.pattern);
53 } RELOC_PTRS_END
54 private_st_line_params();
55
56 /*
57 * GC procedures for gs_imager_state
58 *
59 * See comments in gixstate.h before the definition of gs_cr_state_do_rc and
60 * st_cr_state_num_ptrs for an explanation about why the effective_transfer
61 * pointers are handled in this manner.
62 */
63 public_st_imager_state();
64 private
65 ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
66 ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
67 ENUM_PTR(0, gs_imager_state, client_data);
68 ENUM_PTR(1, gs_imager_state, opacity.mask);
69 ENUM_PTR(2, gs_imager_state, shape.mask);
70 ENUM_PTR(3, gs_imager_state, transparency_stack);
71 #define E1(i,elt) ENUM_PTR(i+4,gs_imager_state,elt);
gs_cr_state_do_ptrs(E1)72 gs_cr_state_do_ptrs(E1)
73 #undef E1
74 ENUM_PTRS_END
75 private RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
76 {
77 RELOC_SUPER(gs_imager_state, st_line_params, line_params);
78 RELOC_PTR(gs_imager_state, client_data);
79 RELOC_PTR(gs_imager_state, opacity.mask);
80 RELOC_PTR(gs_imager_state, shape.mask);
81 RELOC_PTR(gs_imager_state, transparency_stack);
82 #define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
83 gs_cr_state_do_ptrs(R1)
84 #undef R1
85 {
86 int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1;
87
88 for (; i >= 0; i--)
89 RELOC_PTR(gs_imager_state, effective_transfer[i]);
90 }
91 } RELOC_PTRS_END
92
93
94 /* Initialize an imager state, other than the parts covered by */
95 /* gs_imager_state_initial. */
96 int
gs_imager_state_initialize(gs_imager_state * pis,gs_memory_t * mem)97 gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
98 {
99 int i;
100 pis->memory = mem;
101 pis->client_data = 0;
102 pis->opacity.mask = 0;
103 pis->shape.mask = 0;
104 pis->transparency_stack = 0;
105 /* Color rendering state */
106 pis->halftone = 0;
107 {
108 int i;
109
110 for (i = 0; i < gs_color_select_count; ++i)
111 pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
112 }
113 pis->dev_ht = 0;
114 pis->cie_render = 0;
115 pis->black_generation = 0;
116 pis->undercolor_removal = 0;
117 /* Allocate an initial transfer map. */
118 rc_alloc_struct_n(pis->set_transfer.gray,
119 gx_transfer_map, &st_transfer_map,
120 mem, return_error(gs_error_VMerror),
121 "gs_imager_state_init(transfer)", 1);
122 pis->set_transfer.gray->proc = gs_identity_transfer;
123 pis->set_transfer.gray->id = gs_next_ids(pis->memory, 1);
124 pis->set_transfer.gray->values[0] = frac_0;
125 pis->set_transfer.red =
126 pis->set_transfer.green =
127 pis->set_transfer.blue = NULL;
128 for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
129 pis->effective_transfer[i] = pis->set_transfer.gray;
130 pis->cie_joint_caches = NULL;
131 pis->cmap_procs = cmap_procs_default;
132 pis->pattern_cache = NULL;
133 pis->have_pattern_streams = false;
134 return 0;
135 }
136
137 /*
138 * Make a temporary copy of a gs_imager_state. Note that this does not
139 * do all the necessary reference counting, etc. However, it does
140 * clear out the transparency stack in the destination.
141 */
142 gs_imager_state *
gs_imager_state_copy(const gs_imager_state * pis,gs_memory_t * mem)143 gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem)
144 {
145 gs_imager_state *pis_copy =
146 gs_alloc_struct(mem, gs_imager_state, &st_imager_state,
147 "gs_imager_state_copy");
148
149 if (pis_copy) {
150 *pis_copy = *pis;
151 pis_copy->transparency_stack = 0;
152 }
153 return pis_copy;
154 }
155
156 /* Increment reference counts to note that an imager state has been copied. */
157 void
gs_imager_state_copied(gs_imager_state * pis)158 gs_imager_state_copied(gs_imager_state * pis)
159 {
160 rc_increment(pis->opacity.mask);
161 rc_increment(pis->shape.mask);
162 rc_increment(pis->halftone);
163 rc_increment(pis->dev_ht);
164 rc_increment(pis->cie_render);
165 rc_increment(pis->black_generation);
166 rc_increment(pis->undercolor_removal);
167 rc_increment(pis->set_transfer.gray);
168 rc_increment(pis->set_transfer.red);
169 rc_increment(pis->set_transfer.green);
170 rc_increment(pis->set_transfer.blue);
171 rc_increment(pis->cie_joint_caches);
172 }
173
174 /* Adjust reference counts before assigning one imager state to another. */
175 void
gs_imager_state_pre_assign(gs_imager_state * pto,const gs_imager_state * pfrom)176 gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
177 {
178 const char *const cname = "gs_imager_state_pre_assign";
179
180 #define RCCOPY(element)\
181 rc_pre_assign(pto->element, pfrom->element, cname)
182
183 RCCOPY(cie_joint_caches);
184 RCCOPY(set_transfer.blue);
185 RCCOPY(set_transfer.green);
186 RCCOPY(set_transfer.red);
187 RCCOPY(set_transfer.gray);
188 RCCOPY(undercolor_removal);
189 RCCOPY(black_generation);
190 RCCOPY(cie_render);
191 RCCOPY(dev_ht);
192 RCCOPY(halftone);
193 RCCOPY(shape.mask);
194 RCCOPY(opacity.mask);
195 #undef RCCOPY
196 }
197
198 /* Release an imager state. */
199 void
gs_imager_state_release(gs_imager_state * pis)200 gs_imager_state_release(gs_imager_state * pis)
201 {
202 const char *const cname = "gs_imager_state_release";
203 gx_device_halftone *pdht = pis->dev_ht;
204
205 #define RCDECR(element)\
206 rc_decrement(pis->element, cname)
207
208 RCDECR(cie_joint_caches);
209 RCDECR(set_transfer.gray);
210 RCDECR(set_transfer.blue);
211 RCDECR(set_transfer.green);
212 RCDECR(set_transfer.red);
213 RCDECR(undercolor_removal);
214 RCDECR(black_generation);
215 RCDECR(cie_render);
216 /*
217 * If we're going to free the device halftone, make sure we free the
218 * dependent structures as well.
219 */
220 if (pdht != 0 && pdht->rc.ref_count == 1) {
221 gx_device_halftone_release(pdht, pdht->rc.memory);
222 }
223 RCDECR(dev_ht);
224 RCDECR(halftone);
225 RCDECR(shape.mask);
226 RCDECR(opacity.mask);
227 #undef RCDECR
228 }
229