/src/ghostpdl/base/gsht.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2024 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 | | /* setscreen operator for Ghostscript library */ |
18 | | #include "memory_.h" |
19 | | #include "string_.h" |
20 | | #include "assert_.h" |
21 | | #include <stdlib.h> /* for qsort */ |
22 | | #include "gx.h" |
23 | | #include "gserrors.h" |
24 | | #include "gsstruct.h" |
25 | | #include "gsutil.h" /* for gs_next_ids */ |
26 | | #include "gxarith.h" /* for igcd */ |
27 | | #include "gzstate.h" |
28 | | #include "gxdevice.h" /* for gzht.h */ |
29 | | #include "gzht.h" |
30 | | #include "gxfmap.h" /* For effective transfer usage in threshold */ |
31 | | #include "gp.h" |
32 | | |
33 | | #define DUMP_SCREENS 0 |
34 | | |
35 | | /* Forward declarations */ |
36 | | void gx_set_effective_transfer(gs_gstate *); |
37 | | |
38 | | /* Structure types */ |
39 | | public_st_ht_order(); |
40 | | private_st_ht_order_component(); |
41 | | public_st_ht_order_comp_element(); |
42 | | public_st_halftone(); |
43 | | public_st_device_halftone(); |
44 | | |
45 | | /* GC procedures */ |
46 | | |
47 | | static |
48 | 18.4M | ENUM_PTRS_WITH(ht_order_enum_ptrs, gx_ht_order *porder) return 0; |
49 | 3.93M | case 0: ENUM_RETURN((porder->data_memory ? porder->levels : 0)); |
50 | 3.93M | case 1: ENUM_RETURN((porder->data_memory ? porder->bit_data : 0)); |
51 | 3.93M | case 2: ENUM_RETURN(porder->cache); |
52 | 3.93M | case 3: ENUM_RETURN(porder->transfer); |
53 | 18.4M | ENUM_PTRS_END |
54 | | static |
55 | 3.93M | RELOC_PTRS_WITH(ht_order_reloc_ptrs, gx_ht_order *porder) |
56 | 3.93M | { |
57 | 3.93M | if (porder->data_memory) { |
58 | 3.44M | RELOC_VAR(porder->levels); |
59 | 3.44M | RELOC_VAR(porder->bit_data); |
60 | 3.44M | } |
61 | 3.93M | RELOC_VAR(porder->cache); |
62 | 3.93M | RELOC_VAR(porder->transfer); |
63 | 3.93M | } |
64 | 3.93M | RELOC_PTRS_END |
65 | | |
66 | | static |
67 | 490k | ENUM_PTRS_WITH(halftone_enum_ptrs, gs_halftone *hptr) return 0; |
68 | 490k | case 0: |
69 | 490k | switch (hptr->type) |
70 | 490k | { |
71 | 0 | case ht_type_spot: |
72 | 0 | ENUM_RETURN((hptr->params.spot.transfer == 0 ? |
73 | 0 | hptr->params.spot.transfer_closure.data : |
74 | 0 | 0)); |
75 | 0 | case ht_type_threshold: |
76 | 0 | ENUM_RETURN_CONST_STRING_PTR(gs_halftone, params.threshold.thresholds); |
77 | 0 | case ht_type_threshold2: |
78 | 0 | return ENUM_CONST_BYTESTRING(&hptr->params.threshold2.thresholds); |
79 | 0 | case ht_type_client_order: |
80 | 0 | ENUM_RETURN(hptr->params.client_order.client_data); |
81 | 0 | case ht_type_multiple: |
82 | 0 | case ht_type_multiple_colorscreen: |
83 | 0 | ENUM_RETURN(hptr->params.multiple.components); |
84 | 0 | case ht_type_none: |
85 | 258k | case ht_type_screen: |
86 | 490k | case ht_type_colorscreen: |
87 | 490k | return 0; |
88 | 490k | } |
89 | | /* fall through */ |
90 | 0 | case 1: |
91 | 0 | switch (hptr->type) { |
92 | 0 | case ht_type_threshold: |
93 | 0 | ENUM_RETURN((hptr->params.threshold.transfer == 0 ? |
94 | 0 | hptr->params.threshold.transfer_closure.data : |
95 | 0 | 0)); |
96 | 0 | case ht_type_threshold2: |
97 | 0 | ENUM_RETURN(hptr->params.threshold2.transfer_closure.data); |
98 | 0 | case ht_type_client_order: |
99 | 0 | ENUM_RETURN(hptr->params.client_order.transfer_closure.data); |
100 | 0 | default: |
101 | 0 | return 0; |
102 | 0 | } |
103 | 490k | ENUM_PTRS_END |
104 | | |
105 | 488k | static RELOC_PTRS_WITH(halftone_reloc_ptrs, gs_halftone *hptr) |
106 | 488k | { |
107 | 488k | switch (hptr->type) { |
108 | 0 | case ht_type_spot: |
109 | 0 | if (hptr->params.spot.transfer == 0) |
110 | 0 | RELOC_PTR(gs_halftone, params.spot.transfer_closure.data); |
111 | 0 | break; |
112 | 0 | case ht_type_threshold: |
113 | 0 | RELOC_CONST_STRING_PTR(gs_halftone, params.threshold.thresholds); |
114 | 0 | if (hptr->params.threshold.transfer == 0) |
115 | 0 | RELOC_PTR(gs_halftone, params.threshold.transfer_closure.data); |
116 | 0 | break; |
117 | 0 | case ht_type_threshold2: |
118 | 0 | RELOC_CONST_BYTESTRING_VAR(hptr->params.threshold2.thresholds); |
119 | 0 | RELOC_OBJ_VAR(hptr->params.threshold2.transfer_closure.data); |
120 | 0 | break; |
121 | 0 | case ht_type_client_order: |
122 | 0 | RELOC_PTR(gs_halftone, params.client_order.client_data); |
123 | 0 | RELOC_PTR(gs_halftone, params.client_order.transfer_closure.data); |
124 | 0 | break; |
125 | 0 | case ht_type_multiple: |
126 | 0 | case ht_type_multiple_colorscreen: |
127 | 0 | RELOC_PTR(gs_halftone, params.multiple.components); |
128 | 0 | break; |
129 | 0 | case ht_type_none: |
130 | 257k | case ht_type_screen: |
131 | 488k | case ht_type_colorscreen: |
132 | 488k | break; |
133 | 488k | } |
134 | 488k | } |
135 | 488k | RELOC_PTRS_END |
136 | | |
137 | | /* setscreen */ |
138 | | int |
139 | | gs_setscreen(gs_gstate * pgs, gs_screen_halftone * phsp) |
140 | 0 | { |
141 | 0 | gs_screen_enum senum; |
142 | 0 | int code = gx_ht_process_screen(&senum, pgs, phsp, |
143 | 0 | gs_currentaccuratescreens(pgs->memory)); |
144 | |
|
145 | 0 | if (code < 0) |
146 | 0 | return code; |
147 | 0 | return gs_screen_install(&senum); |
148 | 0 | } |
149 | | |
150 | | /* currentscreen */ |
151 | | int |
152 | | gs_currentscreen(const gs_gstate * pgs, gs_screen_halftone * phsp) |
153 | 0 | { |
154 | 0 | switch (pgs->halftone->type) { |
155 | 0 | case ht_type_screen: |
156 | 0 | *phsp = pgs->halftone->params.screen; |
157 | 0 | return 0; |
158 | 0 | case ht_type_colorscreen: |
159 | 0 | *phsp = pgs->halftone->params.colorscreen.screens.colored.gray; |
160 | 0 | return 0; |
161 | 0 | default: |
162 | 0 | return_error(gs_error_undefined); |
163 | 0 | } |
164 | 0 | } |
165 | | |
166 | | /* .currentscreenlevels */ |
167 | | int |
168 | | gs_currentscreenlevels(const gs_gstate * pgs) |
169 | 0 | { |
170 | 0 | int gi = 0; |
171 | |
|
172 | 0 | if (pgs->device != NULL) |
173 | 0 | gi = pgs->device->color_info.gray_index; |
174 | 0 | if (gi != GX_CINFO_COMP_NO_INDEX) |
175 | 0 | return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[gi].corder.num_levels; |
176 | 0 | else |
177 | 0 | return pgs->dev_ht[HT_OBJTYPE_DEFAULT]->components[0].corder.num_levels; |
178 | 0 | } |
179 | | |
180 | | /* .setscreenphase */ |
181 | | int |
182 | | gx_gstate_setscreenphase(gs_gstate * pgs, int x, int y, |
183 | | gs_color_select_t select) |
184 | 43.9M | { |
185 | 43.9M | if (select == gs_color_select_all) { |
186 | 14.6M | int i; |
187 | | |
188 | 43.8M | for (i = 0; i < gs_color_select_count; ++i) |
189 | 29.2M | gx_gstate_setscreenphase(pgs, x, y, (gs_color_select_t) i); |
190 | 14.6M | return 0; |
191 | 29.3M | } else if ((int)select < 0 || (int)select >= gs_color_select_count) |
192 | 0 | return_error(gs_error_rangecheck); |
193 | 29.3M | pgs->screen_phase[select].x = x; |
194 | 29.3M | pgs->screen_phase[select].y = y; |
195 | 29.3M | return 0; |
196 | 43.9M | } |
197 | | int |
198 | | gs_setscreenphase(gs_gstate * pgs, int x, int y, gs_color_select_t select) |
199 | 0 | { |
200 | 0 | int code = gx_gstate_setscreenphase(pgs, x, y, |
201 | 0 | select); |
202 | | |
203 | | /* |
204 | | * If we're only setting the source phase, we don't need to do |
205 | | * unset_dev_color, because the source phase doesn't affect painting |
206 | | * with the current color. |
207 | | */ |
208 | 0 | if (code >= 0 && (select == gs_color_select_texture || |
209 | 0 | select == gs_color_select_all) |
210 | 0 | ) |
211 | 0 | gx_unset_dev_color(pgs); |
212 | 0 | return code; |
213 | 0 | } |
214 | | |
215 | | int |
216 | | gs_currentscreenphase_pgs(const gs_gstate * pgs, gs_int_point * pphase, |
217 | | gs_color_select_t select) |
218 | 14.3M | { |
219 | 14.3M | if ((int)select < 0 || (int)select >= gs_color_select_count) |
220 | 0 | return_error(gs_error_rangecheck); |
221 | 14.3M | *pphase = pgs->screen_phase[select]; |
222 | 14.3M | return 0; |
223 | 14.3M | } |
224 | | |
225 | | /* .currentscreenphase */ |
226 | | int |
227 | | gs_currentscreenphase(const gs_gstate * pgs, gs_int_point * pphase, |
228 | | gs_color_select_t select) |
229 | 14.3M | { |
230 | 14.3M | return gs_currentscreenphase_pgs((const gs_gstate *)pgs, pphase, select); |
231 | 14.3M | } |
232 | | |
233 | | /* currenthalftone */ |
234 | | int |
235 | | gs_currenthalftone(gs_gstate * pgs, gs_halftone * pht) |
236 | 162k | { |
237 | 162k | *pht = *pgs->halftone; |
238 | 162k | return 0; |
239 | 162k | } |
240 | | |
241 | | /* ------ Internal routines ------ */ |
242 | | |
243 | | /* Process one screen plane. */ |
244 | | int |
245 | | gx_ht_process_screen_memory(gs_screen_enum * penum, gs_gstate * pgs, |
246 | | gs_screen_halftone * phsp, bool accurate, gs_memory_t * mem) |
247 | 1.30M | { |
248 | 1.30M | gs_point pt; |
249 | 1.30M | int code = gs_screen_init_memory(penum, pgs, phsp, accurate, mem); |
250 | | |
251 | 1.30M | if (code < 0) |
252 | 0 | return code; |
253 | 23.5M | while ((code = gs_screen_currentpoint(penum, &pt)) == 0) |
254 | 22.2M | if ((code = gs_screen_next(penum, (*phsp->spot_function) (pt.x, pt.y))) < 0) |
255 | 0 | return code; |
256 | 1.30M | return 0; |
257 | 1.30M | } |
258 | | |
259 | | /* |
260 | | * Internal procedure to allocate and initialize either an internally |
261 | | * generated or a client-defined halftone order. For spot halftones, |
262 | | * the client is responsible for calling gx_compute_cell_values. |
263 | | */ |
264 | | int |
265 | | gx_ht_alloc_ht_order(gx_ht_order * porder, uint width, uint height, |
266 | | uint num_levels, uint num_bits, uint strip_shift, |
267 | | const gx_ht_order_procs_t *procs, gs_memory_t * mem) |
268 | 8.92M | { |
269 | 8.92M | porder->threshold = NULL; |
270 | 8.92M | porder->width = width; |
271 | 8.92M | porder->height = height; |
272 | 8.92M | porder->raster = bitmap_raster(width); |
273 | 8.92M | porder->shift = strip_shift; |
274 | 8.92M | porder->orig_height = porder->height; |
275 | 8.92M | porder->orig_shift = porder->shift; |
276 | 8.92M | porder->full_height = ht_order_full_height(porder); |
277 | 8.92M | porder->num_levels = num_levels; |
278 | 8.92M | porder->num_bits = num_bits; |
279 | 8.92M | porder->procs = procs; |
280 | 8.92M | porder->data_memory = mem; |
281 | | |
282 | 8.92M | if (num_levels > 0) { |
283 | 8.92M | porder->levels = |
284 | 8.92M | (uint *)gs_alloc_byte_array(mem, porder->num_levels, sizeof(uint), |
285 | 8.92M | "alloc_ht_order_data(levels)"); |
286 | 8.92M | if (porder->levels == 0) |
287 | 0 | return_error(gs_error_VMerror); |
288 | 8.92M | memset(porder->levels, 0, sizeof(uint) * porder->num_levels); |
289 | 8.92M | } else |
290 | 0 | porder->levels = 0; |
291 | | |
292 | 8.92M | if (num_bits > 0) { |
293 | 8.92M | porder->bit_data = |
294 | 8.92M | gs_alloc_byte_array(mem, porder->num_bits, |
295 | 8.92M | porder->procs->bit_data_elt_size, |
296 | 8.92M | "alloc_ht_order_data(bit_data)"); |
297 | 8.92M | if (porder->bit_data == 0) { |
298 | 0 | gs_free_object(mem, porder->levels, "alloc_ht_order_data(levels)"); |
299 | 0 | porder->levels = 0; |
300 | 0 | return_error(gs_error_VMerror); |
301 | 0 | } |
302 | 8.92M | } else |
303 | 0 | porder->bit_data = 0; |
304 | | |
305 | 8.92M | porder->cache = 0; |
306 | 8.92M | porder->transfer = 0; |
307 | 8.92M | return 0; |
308 | 8.92M | } |
309 | | |
310 | | /* |
311 | | * Procedure to copy a halftone order. |
312 | | */ |
313 | | static int |
314 | | gx_ht_copy_ht_order(gx_ht_order * pdest, gx_ht_order * psrc, gs_memory_t * mem) |
315 | 4.87M | { |
316 | 4.87M | int code; |
317 | | |
318 | 4.87M | *pdest = *psrc; |
319 | | |
320 | 4.87M | code = gx_ht_alloc_ht_order(pdest, psrc->width, psrc->height, |
321 | 4.87M | psrc->num_levels, psrc->num_bits, psrc->shift, |
322 | 4.87M | psrc->procs, mem); |
323 | 4.87M | if (code < 0) |
324 | 0 | return code; |
325 | 4.87M | if (pdest->levels != NULL) |
326 | 4.87M | memcpy(pdest->levels, psrc->levels, psrc->num_levels * sizeof(uint)); |
327 | 4.87M | if (pdest->bit_data != NULL) |
328 | 4.87M | memcpy(pdest->bit_data, psrc->bit_data, |
329 | 4.87M | (size_t)psrc->num_bits * psrc->procs->bit_data_elt_size); |
330 | 4.87M | pdest->transfer = psrc->transfer; |
331 | 4.87M | rc_increment(pdest->transfer); |
332 | 4.87M | return 0; |
333 | 4.87M | } |
334 | | |
335 | | /* |
336 | | * Set the destination component to match the source component, and |
337 | | * "assume ownership" of all of the refrernced data structures. |
338 | | */ |
339 | | static void |
340 | | gx_ht_move_ht_order(gx_ht_order * pdest, gx_ht_order * psrc) |
341 | 0 | { |
342 | 0 | uint width = psrc->width, height = psrc->height, shift = psrc->shift; |
343 | |
|
344 | 0 | pdest->params = psrc->params; |
345 | 0 | pdest->width = width; |
346 | 0 | pdest->height = height; |
347 | 0 | pdest->raster = bitmap_raster(width); |
348 | 0 | pdest->shift = shift; |
349 | 0 | pdest->orig_height = height; |
350 | 0 | pdest->orig_shift = shift; |
351 | 0 | pdest->full_height = ht_order_full_height(pdest); |
352 | 0 | pdest->num_levels = psrc->num_levels; |
353 | 0 | pdest->num_bits = psrc->num_bits; |
354 | 0 | pdest->procs = psrc->procs; |
355 | 0 | pdest->data_memory = psrc->data_memory; |
356 | 0 | pdest->levels = psrc->levels; |
357 | 0 | pdest->bit_data = psrc->bit_data; |
358 | 0 | pdest->cache = psrc->cache; /* should be 0 */ |
359 | 0 | pdest->transfer = psrc->transfer; |
360 | 0 | } |
361 | | |
362 | | /* Allocate and initialize the contents of a halftone order. */ |
363 | | /* The client must have set the defining values in porder->params. */ |
364 | | int |
365 | | gx_ht_alloc_order(gx_ht_order * porder, uint width, uint height, |
366 | | uint strip_shift, uint num_levels, gs_memory_t * mem) |
367 | 1.64M | { |
368 | 1.64M | gx_ht_order order; |
369 | 1.64M | int code; |
370 | | |
371 | 1.64M | order = *porder; |
372 | 1.64M | gx_compute_cell_values(&order.params); |
373 | 1.64M | code = gx_ht_alloc_ht_order(&order, width, height, num_levels, |
374 | 1.64M | width * height, strip_shift, |
375 | 1.64M | &ht_order_procs_default, mem); |
376 | 1.64M | if (code < 0) |
377 | 0 | return code; |
378 | 1.64M | *porder = order; |
379 | 1.64M | return 0; |
380 | 1.64M | } |
381 | | |
382 | | /* |
383 | | * Allocate and initialize a threshold order, which may use the short |
384 | | * representation. |
385 | | */ |
386 | | int |
387 | | gx_ht_alloc_threshold_order(gx_ht_order * porder, uint width, uint height, |
388 | | uint num_levels, gs_memory_t * mem) |
389 | 0 | { |
390 | 0 | gx_ht_order order; |
391 | |
|
392 | 0 | unsigned long num_bits = bitmap_raster(width) * (unsigned long)8 * height; |
393 | 0 | const gx_ht_order_procs_t *procs; |
394 | 0 | int code; |
395 | |
|
396 | 0 | if (num_bits <= 2000) |
397 | 0 | procs = &ht_order_procs_default; |
398 | 0 | else if (num_bits <= max_ushort + 1) /* We can index 0 to 65535 so a size of 65536 (max_ushort + 1) is OK */ |
399 | 0 | procs = &ht_order_procs_short; |
400 | 0 | else if (num_bits <= max_uint) |
401 | 0 | procs = &ht_order_procs_uint; |
402 | 0 | else |
403 | 0 | return_error(gs_error_VMerror); /* At this point in history, this is way too large of a screen */ |
404 | | |
405 | 0 | order = *porder; |
406 | 0 | gx_compute_cell_values(&order.params); |
407 | 0 | code = gx_ht_alloc_ht_order(&order, width, height, num_levels, |
408 | 0 | width * height, 0, procs, mem); |
409 | 0 | if (code < 0) |
410 | 0 | return code; |
411 | 0 | *porder = order; |
412 | 0 | return 0; |
413 | 0 | } |
414 | | |
415 | | /* Allocate and initialize the contents of a client-defined halftone order. */ |
416 | | int |
417 | | gx_ht_alloc_client_order(gx_ht_order * porder, uint width, uint height, |
418 | | uint num_levels, uint num_bits, gs_memory_t * mem) |
419 | 0 | { |
420 | 0 | gx_ht_order order; |
421 | 0 | int code; |
422 | |
|
423 | 0 | order = *porder; |
424 | 0 | order.params.M = width, order.params.N = 0; |
425 | 0 | order.params.R = 1; |
426 | 0 | order.params.M1 = height, order.params.N1 = 0; |
427 | 0 | order.params.R1 = 1; |
428 | 0 | gx_compute_cell_values(&order.params); |
429 | 0 | code = gx_ht_alloc_ht_order(&order, width, height, num_levels, |
430 | 0 | num_bits, 0, &ht_order_procs_default, mem); |
431 | 0 | if (code < 0) |
432 | 0 | return code; |
433 | 0 | *porder = order; |
434 | 0 | return 0; |
435 | 0 | } |
436 | | |
437 | | /* Compare keys ("masks", actually sample values) for qsort. */ |
438 | | static int |
439 | | compare_samples(const void *p1, const void *p2) |
440 | 150M | { |
441 | 150M | ht_sample_t m1 = ((const gx_ht_bit *)p1)->mask; |
442 | 150M | ht_sample_t m2 = ((const gx_ht_bit *)p2)->mask; |
443 | | |
444 | | /* force qsort() to be determinstic even if two masks are the same */ |
445 | 150M | if (m1==m2) { |
446 | 14.7M | m1=((const gx_ht_bit *)p1)->offset; |
447 | 14.7M | m2=((const gx_ht_bit *)p2)->offset; |
448 | 14.7M | } |
449 | | |
450 | 150M | return (m1 < m2 ? -1 : m1 > m2 ? 1 : 0); |
451 | 150M | } |
452 | | /* Sort the halftone order by sample value. */ |
453 | | void |
454 | | gx_sort_ht_order(gx_ht_bit * recs, uint N) |
455 | 2.96M | { |
456 | 2.96M | int i; |
457 | | |
458 | | /* Tag each sample with its index, for sorting. */ |
459 | 54.5M | for (i = 0; i < N; i++) |
460 | 51.6M | recs[i].offset = i; |
461 | 2.96M | qsort((void *)recs, N, sizeof(*recs), compare_samples); |
462 | | #ifdef DEBUG |
463 | | if (gs_debug_c('H')) { |
464 | | uint i; |
465 | | |
466 | | dlputs("[H]Sorted samples:\n"); |
467 | | for (i = 0; i < N; i++) |
468 | | dlprintf3("%5u: %5u: %u\n", |
469 | | i, recs[i].offset, recs[i].mask); |
470 | | } |
471 | | #endif |
472 | 2.96M | } |
473 | | |
474 | | /* |
475 | | * Construct the halftone order from a sampled spot function. Only width x |
476 | | * strip samples have been filled in; we must replicate the resulting sorted |
477 | | * order vertically, shifting it by shift each time. See gxdht.h regarding |
478 | | * the invariants that must be restored. |
479 | | */ |
480 | | void |
481 | | gx_ht_construct_spot_order(gx_ht_order * porder) |
482 | 2.96M | { |
483 | 2.96M | uint width = porder->width; |
484 | 2.96M | uint num_levels = porder->num_levels; /* = width x strip */ |
485 | 2.96M | uint strip = num_levels / width; |
486 | 2.96M | gx_ht_bit *bits = (gx_ht_bit *)porder->bit_data; |
487 | 2.96M | uint *levels = porder->levels; |
488 | 2.96M | uint shift = porder->orig_shift; |
489 | 2.96M | uint full_height = porder->full_height; |
490 | 2.96M | uint num_bits = porder->num_bits; |
491 | 2.96M | uint copies = num_bits / (width * strip); |
492 | 2.96M | gx_ht_bit *bp = bits + num_bits - 1; |
493 | 2.96M | uint i; |
494 | | |
495 | 2.96M | gx_sort_ht_order(bits, num_levels); |
496 | 2.96M | if_debug5('h', |
497 | 2.96M | "[h]spot order: num_levels=%u w=%u h=%u strip=%u shift=%u\n", |
498 | 2.96M | num_levels, width, porder->orig_height, strip, shift); |
499 | | /* Fill in the levels array, replicating the bits vertically */ |
500 | | /* if needed. */ |
501 | 54.5M | for (i = num_levels; i > 0;) { |
502 | 51.6M | uint offset = bits[--i].offset; |
503 | 51.6M | uint x = offset % width; |
504 | 51.6M | uint hy = offset - x; |
505 | 51.6M | uint k; |
506 | | |
507 | 51.6M | levels[i] = i * copies; |
508 | 476M | for (k = 0; k < copies; |
509 | 425M | k++, bp--, hy += num_levels, x = (x + width - shift) % width |
510 | 51.6M | ) |
511 | 425M | bp->offset = hy + x; |
512 | 51.6M | } |
513 | | /* If we have a complete halftone, restore the invariant. */ |
514 | 2.96M | if (num_bits == width * full_height) { |
515 | 2.96M | porder->height = full_height; |
516 | 2.96M | porder->shift = 0; |
517 | 2.96M | } |
518 | 2.96M | gx_ht_construct_bits(porder); |
519 | 2.96M | } |
520 | | |
521 | | /* Construct a single offset/mask. */ |
522 | | void |
523 | | gx_ht_construct_bit(gx_ht_bit * bit, int width, int bit_num) |
524 | 425M | { |
525 | 425M | uint padding = bitmap_raster(width) * 8 - width; |
526 | 425M | int pix = bit_num; |
527 | 425M | ht_mask_t mask; |
528 | 425M | byte *pb; |
529 | | |
530 | 425M | pix += pix / width * padding; |
531 | 425M | bit->offset = (pix >> 3) & -size_of(mask); |
532 | 425M | mask = (ht_mask_t) 1 << (~pix & (ht_mask_bits - 1)); |
533 | | /* Replicate the mask bits. */ |
534 | 425M | pix = ht_mask_bits - width; |
535 | 642M | while ((pix -= width) >= 0) |
536 | 217M | mask |= mask >> width; |
537 | | /* Store the mask, reversing bytes if necessary. */ |
538 | 425M | bit->mask = 0; |
539 | 425M | for (pb = (byte *) & bit->mask + (sizeof(mask) - 1); |
540 | 1.90G | mask != 0; |
541 | 1.47G | mask >>= 8, pb-- |
542 | 425M | ) |
543 | 1.47G | *pb = (byte) mask; |
544 | 425M | } |
545 | | |
546 | | /* Construct offset/masks from the whitening order. */ |
547 | | /* porder->bits[i].offset contains the index of the bit position */ |
548 | | /* that is i'th in the whitening order. */ |
549 | | void |
550 | | gx_ht_construct_bits(gx_ht_order * porder) |
551 | 2.96M | { |
552 | 2.96M | uint i; |
553 | 2.96M | gx_ht_bit *phb; |
554 | | |
555 | 2.96M | for (i = 0, phb = (gx_ht_bit *)porder->bit_data; |
556 | 428M | i < porder->num_bits; |
557 | 425M | i++, phb++) |
558 | 425M | gx_ht_construct_bit(phb, porder->width, phb->offset); |
559 | | #ifdef DEBUG |
560 | | if (gs_debug_c('H')) { |
561 | | dmlprintf1(porder->data_memory, "[H]Halftone order bits "PRI_INTPTR":\n", (intptr_t)porder->bit_data); |
562 | | for (i = 0, phb = (gx_ht_bit *)porder->bit_data; |
563 | | i < porder->num_bits; |
564 | | i++, phb++) |
565 | | dmlprintf3(porder->data_memory, "%4d: %u:0x%lx\n", i, phb->offset, |
566 | | (ulong) phb->mask); |
567 | | } |
568 | | #endif |
569 | 2.96M | } |
570 | | |
571 | | /* Release a gx_device_halftone by freeing its components. */ |
572 | | /* (Don't free the gx_device_halftone itself.) */ |
573 | | void |
574 | | gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache) |
575 | 10.5M | { |
576 | | /* "free cache" is a proxy for "differs from default" */ |
577 | 10.5M | if (free_cache) { |
578 | 5.85M | if (porder->cache != NULL) |
579 | 4.87M | gx_ht_free_cache(mem, porder->cache); |
580 | 5.85M | } |
581 | 10.5M | porder->cache = 0; |
582 | 10.5M | rc_decrement(porder->transfer, "gx_ht_order_release(transfer)"); |
583 | 10.5M | porder->transfer = 0; |
584 | 10.5M | if (porder->data_memory != NULL) { |
585 | 8.92M | gs_free_object(porder->data_memory, porder->bit_data, |
586 | 8.92M | "gx_ht_order_release(bit_data)"); |
587 | 8.92M | gs_free_object(porder->data_memory, porder->levels, |
588 | 8.92M | "gx_ht_order_release(levels)"); |
589 | 8.92M | if (porder->threshold != NULL) { |
590 | 148k | gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, |
591 | 148k | "gx_ht_order_release(threshold)"); |
592 | 148k | } |
593 | 8.92M | } |
594 | 10.5M | porder->threshold = 0; |
595 | 10.5M | porder->levels = 0; |
596 | 10.5M | porder->bit_data = 0; |
597 | 10.5M | } |
598 | | |
599 | | void |
600 | | gx_device_halftone_release(gx_device_halftone * pdht, gs_memory_t * mem) |
601 | 2.27M | { |
602 | 2.27M | if (pdht->components) { |
603 | 1.94M | int i; |
604 | | |
605 | | /* One of the components might be the same as the default */ |
606 | | /* order, so check that we don't free it twice. */ |
607 | 8.13M | for (i = 0; i < pdht->num_comp; ++i) |
608 | 6.18M | if (pdht->components[i].corder.bit_data != |
609 | 6.18M | pdht->order.bit_data |
610 | 6.18M | ) { /* Currently, all orders except the default one */ |
611 | | /* own their caches. */ |
612 | 5.85M | gx_ht_order_release(&pdht->components[i].corder, mem, true); |
613 | 5.85M | } |
614 | 1.94M | gs_free_object(mem, pdht->components, |
615 | 1.94M | "gx_dev_ht_release(components)"); |
616 | 1.94M | pdht->components = 0; |
617 | 1.94M | pdht->num_comp = 0; |
618 | 1.94M | } |
619 | 2.27M | gx_ht_order_release(&pdht->order, mem, false); |
620 | 2.27M | } |
621 | | |
622 | | /* |
623 | | * This routine will take a color name (defined by a ptr and size) and |
624 | | * check if this is a valid colorant name for the current device. If |
625 | | * so then the device's colorant number is returned. |
626 | | * |
627 | | * Two other checks are also made. If the name is "Default" then a value |
628 | | * of GX_DEVICE_COLOR_MAX_COMPONENTS is returned. This is done to |
629 | | * simplify the handling of default halftones. Note: The device also |
630 | | * uses GX_DEVICE_COLOR_MAX_COMPONENTS to indicate colorants which are |
631 | | * known but not being used due to the SeparationOrder parameter. In this |
632 | | * case we return -1 since the colorant is not currently being used by the |
633 | | * device. |
634 | | * |
635 | | * If the halftone type is colorscreen or multiple colorscreen, then we |
636 | | * also check for Red/Cyan, Green/Magenta, Blue/Yellow, and Gray/Black |
637 | | * component name pairs. This is done since the setcolorscreen and |
638 | | * sethalftone types 2 and 4 imply the dual name sets. |
639 | | * |
640 | | * A negative value is returned if the color name is not found. |
641 | | */ |
642 | | int |
643 | | gs_color_name_component_number(gx_device * dev, const char * pname, |
644 | | int name_size, int halftonetype) |
645 | 1.32M | { |
646 | 1.32M | int num_colorant; |
647 | | |
648 | 1.32M | #define check_colorant_name(dev, name) \ |
649 | 1.32M | ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_COMP_NAME_TYPE_HT)) |
650 | | |
651 | 1.32M | #define check_colorant_name_length(dev, name, length) \ |
652 | 1.32M | ((*dev_proc(dev, get_color_comp_index)) (dev, name, length, NO_COMP_NAME_TYPE_HT)) |
653 | | |
654 | 1.32M | #define check_name(str, pname, length) \ |
655 | 2.87M | ((strlen(str) == length) && (strncmp(pname, str, length) == 0)) |
656 | | |
657 | | /* |
658 | | * Check if this is a device colorant. |
659 | | */ |
660 | 1.32M | num_colorant = check_colorant_name_length(dev, pname, name_size); |
661 | 1.32M | if (num_colorant >= 0) { |
662 | | /* |
663 | | * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the |
664 | | * colorant is logically present in the device but not being used |
665 | | * because a SeparationOrder parameter is specified. Since we are |
666 | | * using this value to indicate 'Default', we use -1 to indicate |
667 | | * that the colorant is not really being used. |
668 | | */ |
669 | 485k | if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) |
670 | 0 | num_colorant = -1; |
671 | 485k | return num_colorant; |
672 | 485k | } |
673 | | |
674 | | /* |
675 | | * Check if this is the default component |
676 | | */ |
677 | 840k | if (check_name("Default", pname, name_size)) |
678 | 19.2k | return GX_DEVICE_COLOR_MAX_COMPONENTS; |
679 | | |
680 | | /* Halftones set by setcolorscreen, and (we think) */ |
681 | | /* Type 2 and Type 4 halftones, are supposed to work */ |
682 | | /* for both RGB and CMYK, so we need a special check here. */ |
683 | 821k | if (halftonetype == ht_type_colorscreen || |
684 | 821k | halftonetype == ht_type_multiple_colorscreen) { |
685 | 821k | if (check_name("Red", pname, name_size)) |
686 | 209k | num_colorant = check_colorant_name(dev, "Cyan"); |
687 | 612k | else if (check_name("Green", pname, name_size)) |
688 | 209k | num_colorant = check_colorant_name(dev, "Magenta"); |
689 | 403k | else if (check_name("Blue", pname, name_size)) |
690 | 209k | num_colorant = check_colorant_name(dev, "Yellow"); |
691 | 193k | else if (check_name("Gray", pname, name_size)) |
692 | 193k | num_colorant = check_colorant_name(dev, "Black"); |
693 | | /* |
694 | | * The device will return GX_DEVICE_COLOR_MAX_COMPONENTS if the |
695 | | * colorant is logically present in the device but not being used |
696 | | * because a SeparationOrder parameter is specified. Since we are |
697 | | * using this value to indicate 'Default', we use -1 to indicate |
698 | | * that the colorant is not really being used. |
699 | | */ |
700 | 821k | if (num_colorant == GX_DEVICE_COLOR_MAX_COMPONENTS) |
701 | 0 | num_colorant = -1; |
702 | | |
703 | 821k | #undef check_colorant_name |
704 | 821k | #undef check_colorant_name_length |
705 | 821k | #undef check_name |
706 | | |
707 | 821k | } |
708 | 821k | return num_colorant; |
709 | 840k | } |
710 | | |
711 | | /* |
712 | | * See gs_color_name_component_number for main description. |
713 | | * |
714 | | * This version converts a name index value into a string and size and |
715 | | * then call gs_color_name_component_number. |
716 | | */ |
717 | | int |
718 | | gs_cname_to_colorant_number(gs_gstate * pgs, byte * pname, uint name_size, |
719 | | int halftonetype) |
720 | 19.2k | { |
721 | 19.2k | gx_device * dev = pgs->device; |
722 | | |
723 | 19.2k | return gs_color_name_component_number(dev, (char *)pname, name_size, |
724 | 19.2k | halftonetype); |
725 | 19.2k | } |
726 | | |
727 | | /* |
728 | | * Install a device halftone into the gs_gstate. |
729 | | * |
730 | | * To allow halftones to be shared between graphic states, the |
731 | | * gs_gstate contains a pointer to a device halftone structure. Thus, when |
732 | | * we say a halftone is "in" the gs_gstate, we are only claiming |
733 | | * that the halftone pointer in the gs_gstate points to that halftone. |
734 | | * |
735 | | * Though the operand halftone uses the same structure as the halftone |
736 | | * "in" the gs_gstate, not all of its fields are filled in, and the |
737 | | * organization of components differs. Specifically, the following fields |
738 | | * are not filled in: |
739 | | * |
740 | | * rc The operand device halftone has only a transient existence, |
741 | | * its reference count information is not initialized. In many |
742 | | * cases, the operand device halftone structure is allocated |
743 | | * on the stack by clients. |
744 | | * |
745 | | * id A halftone is not considered to have an identity until it |
746 | | * is installed in the gs_gstate. This is a design error |
747 | | * which reflects the PostScript origins of this code. In |
748 | | * PostScript, it is impossible to check if two halftone |
749 | | * specifications (sets of operands to setscreen/setcolorscreen |
750 | | * or halftone dictionaries) are the same. Hence, the only way |
751 | | * a halftone could be identified was by the graphic state in |
752 | | * which it was included. In PCL it is possible to directly |
753 | | * identify a halftone specification, but currently there is |
754 | | * no way to use this knowledge in the graphic library. |
755 | | * |
756 | | * (An altogether more reasonable approach would be to apply |
757 | | * id's to halftone orders.) |
758 | | * |
759 | | * type This is filled in by the type operand. It is used by |
760 | | * PostScript's currentscreen/currentcolorscreen operators to |
761 | | * determine if a sampling procedure or a halftone dictionary |
762 | | * should be pushed onto the stack. More importantly, it is |
763 | | * also used to determine if specific halftone components can |
764 | | * be used for either the additive or subtractive version of |
765 | | * that component in the process color model. For example, a |
766 | | * RedThreshold in a HalftoneType 4 dictionary can be applied |
767 | | * to either the component "Red" or the component "Cyan", but |
768 | | * the value of the key "Red" in a HalftoneType 5 dictionary |
769 | | * can only be used for a "Red" component (not a "Cyan" |
770 | | * component). |
771 | | * |
772 | | * num_comp For the operand halftone, this is the number of halftone |
773 | | * components included in the specification. For the device |
774 | | * halftone in the gs_gstate, this is always the same as |
775 | | * the number of color model components (see num_dev_comp). |
776 | | * |
777 | | * num_dev_comp The number of components in the device process color model |
778 | | * when the operand halftone was created. With some compositor |
779 | | * devices (for example PDF 1.4) we can have differences in the |
780 | | * process color model of the compositor versus the output device. |
781 | | * These compositor devices do not halftone. |
782 | | * |
783 | | * components For the operand halftone, this field is non-null only if |
784 | | * multiple halftones are provided. In that case, the size |
785 | | * of the array pointed is the same as the number of |
786 | | * components provided. One of these components will usually |
787 | | * be the same as that identified by the "order" field. |
788 | | * |
789 | | * For the device halftone in the gs_gstate, this field is |
790 | | * always non-null, and the size of the array pointed to will |
791 | | * be the same as the number of components in the process |
792 | | * color model. |
793 | | * |
794 | | * lcm_width, These fields provide the least common multiple of the |
795 | | * lcm_height halftone dimensions of the individual component orders. |
796 | | * They represent the dimensions of the smallest tile that |
797 | | * repeats for all color components (this is of interest |
798 | | * because Ghostscript uses a "chunky" raster format for all |
799 | | * drawing procedures). These fields cannot be set in the |
800 | | * operand device halftone as we do not yet know which of |
801 | | * the halftone components will actually be used. |
802 | | * |
803 | | * Conversely, the "order" field is significant only in the operand device |
804 | | * halftone. There it represents the default halftone component, which will |
805 | | * be used for all device color components for which a named halftone is |
806 | | * not available. It is ignored (filled with 0's) in the device halftone |
807 | | * in the gs_gstate. |
808 | | * |
809 | | * The ordering of entries and the set of fields initialized in the |
810 | | * components array also vary between the operand device halftone and |
811 | | * the device halftone in the gs_gstate. |
812 | | * |
813 | | * If the components array is present in the operand device halftone, the |
814 | | * cname field in each entry of the array will contain a name index |
815 | | * identifying the colorant name, and the comp_number field will provide the |
816 | | * index of the corresponding component in the process color model. The |
817 | | * order of entries in the components array is essentially arbitrary, |
818 | | * but in some common cases will reflect the order in which the halftone |
819 | | * specification is provided. By convention, if no explicit default order |
820 | | * is provided (i.e.: via a HalftoneType 5 dictionary), the first |
821 | | * entry of the array will be the same as the "order" (default) field. |
822 | | * |
823 | | * For the device halftone in the gs_gstate, the components array is |
824 | | * always present, but the cname and comp_number fields of individual |
825 | | * entries are ignored. The order of the entries in the array always |
826 | | * matches the order of components in the device color model. |
827 | | * |
828 | | * The distinction between the operand device halftone and the one in |
829 | | * the graphic state extends even to the individual fields of the |
830 | | * gx_ht_order structure incorporated in the order field of the halftone |
831 | | * and the corder field of the elements of the components array. The |
832 | | * fields of this structure that are handled differently in the operand |
833 | | * and gs_gstate device halftones are: |
834 | | * |
835 | | * params Provides a set of parameters that are required for |
836 | | * converting a halftone specification to a single |
837 | | * component order. This field is used only in the |
838 | | * operand device halftone; it is not set in the device |
839 | | * halftone in the gs_gstate. |
840 | | * |
841 | | * orig_height, The height and shift values of the halftone cell, |
842 | | * orig_shift prior to any replication. These fields are currently |
843 | | * unused, and will always be the same as the height |
844 | | * and width fields in the device halftone in the |
845 | | * gs_gstate. |
846 | | * |
847 | | * full_height The height of the smallest replicated tile whose shift |
848 | | * value is 0. This is calculated as part of the |
849 | | * installation process; it may be set in the operand |
850 | | * device halftone, but its value is ignored. |
851 | | * |
852 | | * |
853 | | * data_memory Points to the memory structure used to allocate the |
854 | | * levels and bit_data arrays. The handling of this field |
855 | | * is a bit complicated. For orders that are "taken over" |
856 | | * by the installation process, this field will have the |
857 | | * same value in the operand device halftone and the |
858 | | * device halftone in the gs_gstate. For halftones |
859 | | * that are copied by the installation process, this |
860 | | * field will have the same value as the memory field in |
861 | | * the gs_gstate (the two are usually the same). |
862 | | * |
863 | | * cache Pointer to a cache of tiles representing various |
864 | | * levels of the halftone. This may or may not be |
865 | | * provided in the operand device halftone (in principle |
866 | | * this should always be a null pointer in the operand |
867 | | * device halftone, but this is not the manner in which |
868 | | * the cache was handled historically). |
869 | | * |
870 | | * screen_params This structure contains transformation information |
871 | | * that is required when reading the sample data for a |
872 | | * screen. It is no longer required once the halftone |
873 | | * order has been constructed. |
874 | | * |
875 | | * In addition to what is noted above, this procedure is made somewhat |
876 | | * more complex than expected due to memory management considerations. To |
877 | | * clarify this, it is necessary to consider the properties of the pieces |
878 | | * that constitute a device halftone. |
879 | | * |
880 | | * The gx_device_halftone structure itself is shareable and uses |
881 | | * reference counts. |
882 | | * |
883 | | * The gx_ht_order_component array (components array entry) is in |
884 | | * principle shareable, though it does not provide any reference |
885 | | * counting mechanism. Hence any sharing needs to be done with |
886 | | * caution. |
887 | | * |
888 | | * Individual component orders are not shareable, as they are part of |
889 | | * the gx_ht_order_commponent structure (a major design error). |
890 | | * |
891 | | * The levels, bit_data, and cache structures referenced by the |
892 | | * gx_ht_order structure are in principle shareable, but they also do |
893 | | * not provide any reference counting mechanism. Traditionally, one set |
894 | | * of two component orders could share these structures, using the |
895 | | * halftone's "order" field and various scattered bits of special case |
896 | | * code. This practice has been ended because it did not extend to |
897 | | * sharing amongst more than two components. |
898 | | * |
899 | | * The gx_transfer_map structure referenced by the gx_ht_order structure |
900 | | * is shareable, and uses reference counts. Traditionally this structure |
901 | | * was not shared, but this is no longer the case. |
902 | | * |
903 | | * As noted, the rc field of the operand halftone is not initialized, so |
904 | | * this procedure cannot simply take ownership of the operand device |
905 | | * halftone structure (i.e.: an ostensibly shareable structure is not |
906 | | * shareable). Hence, this procedure will always create a new copy of the |
907 | | * gx_device_halftone structure, either by allocating a new structure or |
908 | | * re-using the structure already referenced by the gs_gstate. This |
909 | | * feature must be retained, as in several cases the calling code will |
910 | | * allocate the operand device halftone structure on the stack. |
911 | | * |
912 | | * Traditionally, this procedure took ownership of all of the structures |
913 | | * referenced by the operand device halftone structure. This implied |
914 | | * that all structures referenced by the gx_device_halftone structure |
915 | | * needed to be allocated on the heap, and should not be released once |
916 | | * the call to gx_gstate_dev_ht_install completes. |
917 | | * |
918 | | * There were two problems with this approach: |
919 | | * |
920 | | * 1. In the event of an error, the calling code most likely would have |
921 | | * to release referenced components, as the gs_gstate had not yet |
922 | | * take ownership of them. In many cases, the code did not do this. |
923 | | * |
924 | | * 2. When the structures referenced by a single order needed to be |
925 | | * shared amongst more than one component, there was no easy way to |
926 | | * discover this sharing when the gs_gstate's device halftone |
927 | | * subsequently needed to be released. Hence, objects would be |
928 | | * released multiple times. |
929 | | * |
930 | | * Subsequently, the code in this routine was changed to copy most of |
931 | | * the referenced structures (everything except the transfer functions). |
932 | | * Unfortunately, the calling code was not changed, which caused memory |
933 | | * leaks. |
934 | | * |
935 | | * The approach now taken uses a mixture of the two approaches. |
936 | | * Ownership to structures referenced by the operand device halftone is |
937 | | * assumed by the device halftone in the gs_gstate where this is |
938 | | * possible. In these cases, the corresponding references are removed in |
939 | | * the operand device halftone (hence, this operand is no longer |
940 | | * qualified as const). When a structure is required but ownership cannot |
941 | | * be assumed, a copy is made and the reference in the operand device |
942 | | * halftone is left undisturbed. The calling code has also been modified |
943 | | * to release any remaining referenced structures when this routine |
944 | | * returns, whether or not an error is indicated. |
945 | | */ |
946 | | int |
947 | | gx_gstate_dev_ht_install( |
948 | | gs_gstate * pgs, |
949 | | gx_device_halftone * pdht, |
950 | | gs_halftone_type type, |
951 | | const gx_device * dev, |
952 | | gs_HT_objtype_t objtype ) |
953 | 1.62M | { |
954 | 1.62M | gx_device_halftone dht; |
955 | 1.62M | int num_comps = pdht->num_dev_comp; |
956 | 1.62M | int i, code = 0; |
957 | 1.62M | bool used_default = false; |
958 | 1.62M | int lcm_width = 1, lcm_height = 1; |
959 | 1.62M | bool mem_diff = pdht->rc.memory != pgs->memory; |
960 | 1.62M | uint w, h; |
961 | 1.62M | int dw, dh; |
962 | | |
963 | 1.62M | assert(objtype < HT_OBJTYPE_COUNT); |
964 | | |
965 | | /* construct the new device halftone structure */ |
966 | 1.62M | memset(&dht.order, 0, sizeof(dht.order)); |
967 | | /* the rc field is filled in later */ |
968 | 1.62M | dht.id = gs_next_ids(pgs->memory, 1); |
969 | 1.62M | dht.type = type; |
970 | 1.62M | dht.components = gs_alloc_struct_array( |
971 | 1.62M | pgs->memory, |
972 | 1.62M | num_comps, |
973 | 1.62M | gx_ht_order_component, |
974 | 1.62M | &st_ht_order_component_element, |
975 | 1.62M | "gx_gstate_dev_ht_install(components)" ); |
976 | 1.62M | if (dht.components == NULL) |
977 | 0 | return_error(gs_error_VMerror); |
978 | 1.62M | dht.num_comp = dht.num_dev_comp = num_comps; |
979 | | /* lcm_width, lcm_height are filled in later */ |
980 | | |
981 | | /* initialize the components array */ |
982 | 1.62M | memset(dht.components, 0, num_comps * sizeof(dht.components[0])); |
983 | 6.49M | for (i = 0; i < num_comps; i++) |
984 | 4.87M | dht.components[i].comp_number = -1; |
985 | | |
986 | | /* |
987 | | * Duplicate any of the non-default components, but do not create copies |
988 | | * of the levels or bit_data arrays. If all goes according to plan, the |
989 | | * gs_gstate's device halftone will assume ownership of these arrays |
990 | | * by clearing the corresponding pointers in the operand halftone's |
991 | | * orders. |
992 | | */ |
993 | 1.62M | if (pdht->components != NULL) { |
994 | 1.29M | int input_ncomps = pdht->num_comp; |
995 | | |
996 | 5.00M | for (i = 0; i < input_ncomps && code >= 0; i++) { |
997 | 3.71M | gx_ht_order_component * p_s_comp = &pdht->components[i]; |
998 | 3.71M | gx_ht_order * p_s_order = &p_s_comp->corder; |
999 | 3.71M | int comp_num = p_s_comp->comp_number; |
1000 | | |
1001 | 3.71M | if (comp_num >= 0 && comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS && |
1002 | 3.71M | comp_num < dht.num_comp) { |
1003 | 3.16M | gx_ht_order * p_d_order = &dht.components[comp_num].corder; |
1004 | | |
1005 | | /* indicate that this order has been filled in */ |
1006 | 3.16M | dht.components[comp_num].comp_number = comp_num; |
1007 | | |
1008 | | /* |
1009 | | * The component can be used only if it is from the |
1010 | | * proper memory |
1011 | | */ |
1012 | 3.16M | if (mem_diff) |
1013 | 3.16M | code = gx_ht_copy_ht_order( p_d_order, |
1014 | 3.16M | p_s_order, |
1015 | 3.16M | pgs->memory ); |
1016 | 0 | else { |
1017 | | /* check if this is also the default component */ |
1018 | 0 | used_default = used_default || |
1019 | 0 | p_s_order->bit_data == pdht->order.bit_data; |
1020 | |
|
1021 | 0 | gx_ht_move_ht_order(p_d_order, p_s_order); |
1022 | 0 | } |
1023 | 3.16M | } |
1024 | 3.71M | } |
1025 | 1.29M | } |
1026 | | |
1027 | | /* |
1028 | | * Copy the default order to any remaining components. |
1029 | | */ |
1030 | | |
1031 | 6.49M | for (i = 0; i < num_comps && code >= 0; i++) { |
1032 | 4.87M | gx_ht_order *porder = &dht.components[i].corder; |
1033 | | |
1034 | 4.87M | if (dht.components[i].comp_number != i) { |
1035 | | /* Previously this code would 'move' the default order from pdht to the |
1036 | | * dht component here, if we hadn't already done so, and would NULL out the default |
1037 | | * order in pdht to prevent it being freed when we released the halftone. |
1038 | | * However this didn't account for the possibility that one or more of the components |
1039 | | * of dht was already sharing the default order of the halftone. See gx_device_halftone_release |
1040 | | * which carefully checks to see if the default order is used by any component, in |
1041 | | * order to avoid double freeing it. |
1042 | | * We could do that check here, but the tiny benefit in not copying the data would |
1043 | | * probably be lost by the checks, so lets just always *copy* the default order if we need to. |
1044 | | */ |
1045 | 1.71M | code = gx_ht_copy_ht_order(porder, &pdht->order, pgs->memory); |
1046 | 1.71M | dht.components[i].comp_number = i; |
1047 | 1.71M | } |
1048 | | |
1049 | 4.87M | w = porder->width; |
1050 | 4.87M | h = porder->full_height; |
1051 | 4.87M | dw = igcd(lcm_width, w); |
1052 | 4.87M | dh = igcd(lcm_height, h); |
1053 | | |
1054 | 4.87M | lcm_width /= dw; |
1055 | 4.87M | lcm_height /= dh; |
1056 | 4.87M | lcm_width = (w > max_int / lcm_width ? max_int : lcm_width * w); |
1057 | 4.87M | lcm_height = (h > max_int / lcm_height ? max_int : lcm_height * h); |
1058 | | |
1059 | 4.87M | if (porder->cache == 0) { |
1060 | 4.87M | uint tile_bytes, num_tiles, slots_wanted, rep_raster, rep_count; |
1061 | 4.87M | gx_ht_cache * pcache; |
1062 | | |
1063 | 4.87M | tile_bytes = porder->raster |
1064 | 4.87M | * (porder->num_bits / porder->width); |
1065 | 4.87M | num_tiles = 1 + gx_ht_cache_default_bits_size() / tile_bytes; |
1066 | | /* |
1067 | | * Limit num_tiles to a reasonable number allowing for width repition. |
1068 | | * The most we need is one cache slot per bit. |
1069 | | * This prevents allocations of large cache bits that will never |
1070 | | * be used. See rep_count limit in gxht.c |
1071 | | */ |
1072 | 4.87M | slots_wanted = 1 + ( porder->width * porder->height ); |
1073 | 4.87M | rep_raster = ((num_tiles*tile_bytes) / porder->height / |
1074 | 4.87M | slots_wanted) & ~(align_bitmap_mod - 1); |
1075 | 4.87M | rep_count = rep_raster * 8 / porder->width; |
1076 | 4.87M | if (rep_count > sizeof(ulong) * 8 && (num_tiles > |
1077 | 4.87M | 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count) )) |
1078 | 4.87M | num_tiles = 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count); |
1079 | 4.87M | pcache = gx_ht_alloc_cache( pgs->memory, num_tiles, |
1080 | 4.87M | tile_bytes * num_tiles ); |
1081 | 4.87M | if (pcache == NULL) |
1082 | 0 | code = gs_error_VMerror; |
1083 | 4.87M | else { |
1084 | 4.87M | porder->cache = pcache; |
1085 | 4.87M | gx_ht_init_cache(pgs->memory, pcache, porder); |
1086 | 4.87M | } |
1087 | 4.87M | } |
1088 | 4.87M | } |
1089 | 1.62M | dht.lcm_width = lcm_width; |
1090 | 1.62M | dht.lcm_height = lcm_height; |
1091 | | |
1092 | | /* |
1093 | | * If everything is OK so far, allocate a unique copy of the device |
1094 | | * halftone reference by the gs_gstate. |
1095 | | * |
1096 | | * This code requires a special check for the case in which the |
1097 | | * deivce halftone referenced by the gs_gstate is already unique. |
1098 | | * In this case, we must explicitly release just the components array |
1099 | | * (and any structures it refers to) of the existing halftone. This |
1100 | | * cannot be done automatically, as the rc_unshare_struct macro only |
1101 | | * ensures that a unique instance of the top-level structure is |
1102 | | * created, not that any substructure references are updated. |
1103 | | * |
1104 | | * Though this is scheduled to be changed, for the time being the |
1105 | | * command list renderer may invoke this code with pdht == psi->dev_ht |
1106 | | * (in which case we know pgs->dev_ht.rc.ref_count == 1). Special |
1107 | | * handling is required in that case, to avoid releasing structures |
1108 | | * we still need. |
1109 | | */ |
1110 | 1.62M | if (code >= 0) { |
1111 | 1.62M | gx_device_halftone **ppgsdht; |
1112 | 1.62M | rc_header tmp_rc; |
1113 | | |
1114 | | /* The pgsdht corresponds to the one we will be installing according to 'objtype' */ |
1115 | 1.62M | ppgsdht = &(pgs->dev_ht[objtype]); |
1116 | 1.62M | if (*ppgsdht != NULL && (*ppgsdht)->rc.ref_count == 1) { |
1117 | 339k | if (pdht != *ppgsdht) |
1118 | 339k | gx_device_halftone_release(*ppgsdht, (*ppgsdht)->rc.memory); |
1119 | 1.28M | } else { |
1120 | 1.28M | rc_unshare_struct( *ppgsdht, |
1121 | 1.28M | gx_device_halftone, |
1122 | 1.28M | &st_device_halftone, |
1123 | 1.28M | pgs->memory, |
1124 | 1.28M | BEGIN code = gs_error_VMerror; goto err; END, |
1125 | 1.28M | "gx_gstate_dev_ht_install" ); |
1126 | 1.28M | } |
1127 | | |
1128 | | /* |
1129 | | * Everything worked. "Assume ownership" of the appropriate |
1130 | | * portions of the source device halftone by clearing the |
1131 | | * associated references. Since we might have |
1132 | | * pdht == pgs->dev_ht[], this must done before updating pgs->dev_ht[]. |
1133 | | * |
1134 | | * If the default order has been used for a device component, and |
1135 | | * any of the source component orders share their levels or bit_data |
1136 | | * arrays with the default order, clear the pointers in those orders |
1137 | | * now. This is necessary because the default order's pointers will |
1138 | | * be cleared immediately below, so subsequently it will not be |
1139 | | * possible to tell if that this information is being shared. |
1140 | | */ |
1141 | 1.62M | if (pdht->components != NULL && !mem_diff) { |
1142 | 0 | int input_ncomps = pdht->num_comp; |
1143 | |
|
1144 | 0 | for (i = 0; i < input_ncomps; i++) { |
1145 | 0 | gx_ht_order_component * p_s_comp = &pdht->components[i]; |
1146 | 0 | gx_ht_order * p_s_order = &p_s_comp->corder; |
1147 | 0 | int comp_num = p_s_comp->comp_number; |
1148 | |
|
1149 | 0 | if ( comp_num >= 0 && |
1150 | 0 | comp_num < GX_DEVICE_COLOR_MAX_COMPONENTS ) { |
1151 | 0 | memset(p_s_order, 0, sizeof(*p_s_order)); |
1152 | 0 | } else if ( comp_num == GX_DEVICE_COLOR_MAX_COMPONENTS && |
1153 | 0 | used_default ) |
1154 | 0 | memset(p_s_order, 0, sizeof(*p_s_order)); |
1155 | 0 | } |
1156 | 0 | } |
1157 | 1.62M | if (used_default && !mem_diff) { |
1158 | 0 | memset(&pdht->order, 0, sizeof(pdht->order)); |
1159 | 0 | } |
1160 | | |
1161 | 1.62M | tmp_rc = (*ppgsdht)->rc; |
1162 | 1.62M | **ppgsdht = dht; |
1163 | 1.62M | (*ppgsdht)->rc = tmp_rc; |
1164 | | |
1165 | | /* update the effective transfer function array */ |
1166 | 1.62M | gx_gstate_set_effective_xfer(pgs); |
1167 | | |
1168 | 1.62M | return 0; |
1169 | 1.62M | } |
1170 | | |
1171 | | /* something went amiss; release all copied components */ |
1172 | 0 | err: |
1173 | 0 | for (i = 0; i < num_comps; i++) { |
1174 | 0 | gx_ht_order_component * pcomp = &dht.components[i]; |
1175 | 0 | gx_ht_order * porder = &pcomp->corder; |
1176 | |
|
1177 | 0 | if (pcomp->comp_number == -1) { |
1178 | 0 | gx_ht_order_release(porder, pgs->memory, true); |
1179 | 0 | } |
1180 | 0 | else if (porder->cache != NULL) { |
1181 | 0 | gx_ht_free_cache(pgs->memory, porder->cache); |
1182 | 0 | porder->cache = NULL; |
1183 | 0 | } |
1184 | 0 | } |
1185 | 0 | gs_free_object(pgs->memory, dht.components, "gx_gstate_dev_ht_install"); |
1186 | |
|
1187 | 0 | return code; |
1188 | 1.62M | } |
1189 | | |
1190 | | /* |
1191 | | * Copy the dev_ht[HT_OBJTYPE_DEFAULT] to the dev_ht[] for the specified object type. |
1192 | | */ |
1193 | | int |
1194 | | gx_gstate_dev_ht_copy_to_objtype(gs_gstate *pgs, gs_HT_objtype_t objtype) |
1195 | 0 | { |
1196 | 0 | gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; /* the current dev_ht */ |
1197 | |
|
1198 | 0 | if (objtype >= HT_OBJTYPE_COUNT) { |
1199 | 0 | return_error(gs_error_undefined); |
1200 | 0 | } |
1201 | 0 | rc_increment(pdht); |
1202 | 0 | pgs->dev_ht[objtype] = pdht; |
1203 | 0 | return 0; |
1204 | 0 | } |
1205 | | |
1206 | | /* |
1207 | | * Install a new halftone in the graphics state. Note that we copy the top |
1208 | | * level of the gs_halftone and the gx_device_halftone, and take ownership |
1209 | | * of any substructures. |
1210 | | */ |
1211 | | int |
1212 | | gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, |
1213 | | gx_device_halftone * pdht) |
1214 | 637k | { |
1215 | 637k | gs_memory_t *mem = pht->rc.memory; |
1216 | 637k | gs_halftone *old_ht = pgs->halftone; |
1217 | 637k | gs_halftone *new_ht; |
1218 | 637k | int code; |
1219 | | |
1220 | 637k | pdht->num_dev_comp = pgs->device->color_info.num_components; |
1221 | 637k | if (old_ht != NULL && old_ht->rc.memory == mem && |
1222 | 637k | old_ht->rc.ref_count == 1 |
1223 | 637k | ) |
1224 | 311k | new_ht = old_ht; |
1225 | 325k | else |
1226 | 637k | rc_alloc_struct_1(new_ht, gs_halftone, &st_halftone, |
1227 | 637k | mem, return_error(gs_error_VMerror), |
1228 | 637k | "gx_ht_install(new halftone)"); |
1229 | 637k | code = gx_gstate_dev_ht_install(pgs, |
1230 | 637k | pdht, pht->type, gs_currentdevice_inline(pgs), |
1231 | 637k | pht->objtype); |
1232 | 637k | if (code < 0) { |
1233 | 0 | if (new_ht != old_ht) |
1234 | 0 | gs_free_object(mem, new_ht, "gx_ht_install(new halftone)"); |
1235 | 0 | return code; |
1236 | 0 | } |
1237 | | |
1238 | | /* |
1239 | | * Discard any unused components and the components array of the |
1240 | | * operand device halftone |
1241 | | */ |
1242 | 637k | gx_device_halftone_release(pdht, pdht->rc.memory); |
1243 | | |
1244 | 637k | if (new_ht != old_ht) |
1245 | 637k | rc_decrement(old_ht, "gx_ht_install(old halftone)"); |
1246 | 637k | { |
1247 | 637k | rc_header rc; |
1248 | | |
1249 | 637k | rc = new_ht->rc; |
1250 | 637k | *new_ht = *pht; |
1251 | 637k | new_ht->rc = rc; |
1252 | 637k | } |
1253 | 637k | pgs->halftone = new_ht; |
1254 | 637k | gx_unset_both_dev_colors(pgs); |
1255 | 637k | return 0; |
1256 | 637k | } |
1257 | | |
1258 | | /* |
1259 | | * This macro will determine the colorant number of a given color name. |
1260 | | * A value of -1 indicates that the name is not valid. |
1261 | | */ |
1262 | | #define check_colorant_name(name, dev) \ |
1263 | | ((*dev_proc(dev, get_color_comp_index)) (dev, name, strlen(name), NO_NAME_TYPE)) |
1264 | | |
1265 | | /* Reestablish the effective transfer functions, taking into account */ |
1266 | | /* any overrides from halftone dictionaries. */ |
1267 | | void |
1268 | | gx_gstate_set_effective_xfer(gs_gstate * pgs) |
1269 | 9.98M | { |
1270 | 9.98M | gx_device_halftone *pdht = pgs->dev_ht[HT_OBJTYPE_DEFAULT]; |
1271 | 9.98M | gx_transfer_map *pmap; |
1272 | 9.98M | gx_ht_order *porder; |
1273 | 9.98M | int i, component_num, non_id_count; |
1274 | | |
1275 | 9.98M | non_id_count = (pgs->set_transfer.gray->proc == &gs_identity_transfer) ? 0 : GX_DEVICE_COLOR_MAX_COMPONENTS; |
1276 | 648M | for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) |
1277 | 638M | pgs->effective_transfer[i] = pgs->set_transfer.gray; /* default */ |
1278 | | |
1279 | | /* Check if we have a transfer functions from setcolortransfer */ |
1280 | 9.98M | if (pgs->set_transfer.red) { |
1281 | 826 | component_num = pgs->set_transfer.red_component_num; |
1282 | 826 | if (component_num >= 0) { |
1283 | 800 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1284 | 800 | non_id_count--; |
1285 | 800 | pgs->effective_transfer[component_num] = pgs->set_transfer.red; |
1286 | 800 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1287 | 800 | non_id_count++; |
1288 | 800 | } |
1289 | 826 | } |
1290 | 9.98M | if (pgs->set_transfer.green) { |
1291 | 584 | component_num = pgs->set_transfer.green_component_num; |
1292 | 584 | if (component_num >= 0) { |
1293 | 558 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1294 | 558 | non_id_count--; |
1295 | 558 | pgs->effective_transfer[component_num] = pgs->set_transfer.green; |
1296 | 558 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1297 | 558 | non_id_count++; |
1298 | 558 | } |
1299 | 584 | } |
1300 | 9.98M | if (pgs->set_transfer.blue) { |
1301 | 342 | component_num = pgs->set_transfer.blue_component_num; |
1302 | 342 | if (component_num >= 0) { |
1303 | 316 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1304 | 316 | non_id_count--; |
1305 | 316 | pgs->effective_transfer[component_num] = pgs->set_transfer.blue; |
1306 | 316 | if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) |
1307 | 316 | non_id_count++; |
1308 | 316 | } |
1309 | 342 | } |
1310 | | |
1311 | | /* HT may not be initialized yet. Only do if the target is a halftone device. |
1312 | | Per the spec, the HT is a self-contained description of a halftoning process. |
1313 | | We don't use any xfer function from the HT if we are not halftoning */ |
1314 | 9.98M | if (pdht && !device_is_contone(pgs->device)) { |
1315 | | |
1316 | | /* Since the transfer function is pickled into the threshold array (if any)*/ |
1317 | | /* we need to free it so it can be reconstructed with the current transfer */ |
1318 | 3.58M | porder = &(pdht->order); |
1319 | 3.58M | if (porder->threshold != NULL) { |
1320 | 0 | gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, |
1321 | 0 | "set_effective_transfer(threshold)"); |
1322 | 0 | porder->threshold = 0; |
1323 | 0 | } |
1324 | 12.9M | for (i = 0; i < pdht->num_comp; i++) { |
1325 | 9.38M | pmap = pdht->components[i].corder.transfer; |
1326 | 9.38M | if (pmap != NULL) { |
1327 | 0 | if (pgs->effective_transfer[i]->proc != &gs_identity_transfer) |
1328 | 0 | non_id_count--; |
1329 | 0 | pgs->effective_transfer[i] = pmap; |
1330 | 0 | if (pgs->effective_transfer[i]->proc != &gs_identity_transfer) |
1331 | 0 | non_id_count++; |
1332 | 0 | } |
1333 | 9.38M | porder = &(pdht->components[i].corder); |
1334 | 9.38M | if (porder->threshold != NULL) { |
1335 | 18 | gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, |
1336 | 18 | "set_effective_transfer(threshold)"); |
1337 | 18 | porder->threshold = 0; |
1338 | 18 | } |
1339 | 9.38M | } |
1340 | 3.58M | } |
1341 | | |
1342 | 9.98M | pgs->effective_transfer_non_identity_count = non_id_count; |
1343 | 9.98M | } |
1344 | | |
1345 | | void |
1346 | | gx_set_effective_transfer(gs_gstate * pgs) |
1347 | 730k | { |
1348 | 730k | gx_gstate_set_effective_xfer(pgs); |
1349 | 730k | } |
1350 | | |
1351 | | /* Check if the transfer function for a component is monotonic. */ |
1352 | | /* Used to determine if we can do fast halftoning */ |
1353 | | bool |
1354 | | gx_transfer_is_monotonic(const gs_gstate *pgs, int plane_index) |
1355 | 149k | { |
1356 | 149k | if (pgs->effective_transfer[plane_index]->proc != gs_identity_transfer) { |
1357 | 149k | bool threshold_inverted; |
1358 | 149k | int t_level; |
1359 | 149k | frac mapped, prev; |
1360 | | |
1361 | 149k | prev = gx_map_color_frac(pgs, frac_0, effective_transfer[plane_index]); |
1362 | 149k | threshold_inverted = prev > |
1363 | 149k | gx_map_color_frac(pgs, frac_1, effective_transfer[plane_index]); |
1364 | 38.1M | for (t_level = 1; t_level < 255; t_level++) { |
1365 | 38.0M | mapped = gx_map_color_frac(pgs, byte2frac(t_level), effective_transfer[plane_index]); |
1366 | 38.0M | if ((threshold_inverted && mapped > prev) || |
1367 | 38.0M | (!threshold_inverted && mapped < prev)) |
1368 | 4 | return false; |
1369 | 38.0M | prev = mapped; |
1370 | 38.0M | } |
1371 | 149k | } |
1372 | 149k | return true; |
1373 | 149k | } |
1374 | | |
1375 | | /* This creates a threshold array from the tiles. Threshold is allocated in |
1376 | | non-gc memory and is not known to the GC. The algorithm cycles through the |
1377 | | threshold values, computing the shade the same way as gx_render_device_DeviceN |
1378 | | so that the threshold matches the non-threshold halftoning. |
1379 | | */ |
1380 | | int |
1381 | | gx_ht_construct_threshold( gx_ht_order *d_order, gx_device *dev, |
1382 | | const gs_gstate * pgs, int plane_index) |
1383 | 150k | { |
1384 | 150k | int i, j; |
1385 | 150k | unsigned char *thresh; |
1386 | 150k | gs_memory_t *memory = d_order ? d_order->data_memory->non_gc_memory : NULL; |
1387 | 150k | uint max_value; |
1388 | 150k | unsigned long hsize, nshades; |
1389 | 150k | int t_level; |
1390 | 150k | int row, col; |
1391 | 150k | int code; |
1392 | 150k | int num_repeat, shift, num_levels = d_order ? d_order->num_levels : 0; |
1393 | 150k | int row_kk, col_kk, kk; |
1394 | 150k | frac t_level_frac_color; |
1395 | 150k | int shade, base_shade = 0; |
1396 | 150k | bool have_transfer = false, threshold_inverted = false; |
1397 | | |
1398 | 150k | if (d_order == NULL) return -1; |
1399 | | /* We can have simple or complete orders. Simple ones tile the threshold |
1400 | | with shifts. To handle those we simply loop over the number of |
1401 | | repeats making sure to shift columns when we set our threshold values */ |
1402 | 150k | num_repeat = d_order->full_height / d_order->height; |
1403 | 150k | shift = d_order->shift; |
1404 | | |
1405 | 150k | if (d_order->threshold != NULL) return 0; |
1406 | 148k | thresh = (byte *)gs_malloc(memory, (size_t)d_order->width * d_order->full_height, 1, |
1407 | 148k | "gx_ht_construct_threshold"); |
1408 | 148k | if (thresh == NULL) { |
1409 | 0 | return -1 ; /* error if allocation failed */ |
1410 | 0 | } |
1411 | | /* Check if we need to apply a transfer function to the values */ |
1412 | 148k | if (pgs->effective_transfer[plane_index]->proc != gs_identity_transfer) { |
1413 | 148k | have_transfer = true; |
1414 | 148k | threshold_inverted = gx_map_color_frac(pgs, frac_0, effective_transfer[plane_index]) > |
1415 | 148k | gx_map_color_frac(pgs, frac_1, effective_transfer[plane_index]); |
1416 | 148k | } |
1417 | | /* Adjustments to ensure that we properly map our 256 levels into |
1418 | | the number of shades that we have in our halftone screen. For example |
1419 | | if we have a 16x16 screen, we have 257 shadings that we can represent |
1420 | | if we have a 2x2 screen, we have 5 shadings that we can represent. |
1421 | | Calculations are performed to match what happens in the tile filling |
1422 | | code */ |
1423 | 148k | max_value = (dev->color_info.gray_index == plane_index) ? |
1424 | 148k | dev->color_info.dither_grays - 1 : |
1425 | 148k | dev->color_info.dither_colors - 1; |
1426 | 148k | hsize = num_levels; |
1427 | 148k | nshades = hsize * max_value + 1; |
1428 | | |
1429 | | /* search upwards to find the correct value for the last threshold value */ |
1430 | | /* Use this to initialize the threshold array (transition to all white) */ |
1431 | 148k | t_level = 0; |
1432 | 35.6M | do { |
1433 | 35.6M | t_level++; |
1434 | 35.6M | t_level_frac_color = byte2frac(threshold_inverted ? 255 - t_level : t_level); |
1435 | 35.6M | if (have_transfer) |
1436 | 35.5M | t_level_frac_color = gx_map_color_frac(pgs, t_level_frac_color, effective_transfer[plane_index]); |
1437 | 35.6M | shade = t_level_frac_color * nshades / (frac_1_long + 1); |
1438 | 35.6M | } while (shade < num_levels && t_level < 255); |
1439 | | /* Initialize the thresholds to the lowest level that will be all white */ |
1440 | 5.61M | for( i = 0; i < d_order->width * d_order->full_height; i++ ) { |
1441 | 5.46M | thresh[i] = t_level; |
1442 | 5.46M | } |
1443 | 38.1M | for (t_level = 1; t_level < 256; t_level++) { |
1444 | 37.9M | t_level_frac_color = byte2frac(threshold_inverted ? 255 - t_level : t_level); |
1445 | 37.9M | if (have_transfer) |
1446 | 37.9M | t_level_frac_color = gx_map_color_frac(pgs, t_level_frac_color, effective_transfer[plane_index]); |
1447 | 37.9M | shade = t_level_frac_color * nshades / (frac_1_long + 1); |
1448 | 37.9M | if (shade < num_levels && shade > base_shade) { |
1449 | 2.53M | if (d_order->levels[shade] > d_order->levels[base_shade]) { |
1450 | | /* Loop over the number of dots that we have to set in going |
1451 | | to this new shade from the old shade */ |
1452 | 7.69M | for (j = d_order->levels[base_shade]; j < d_order->levels[shade]; j++) { |
1453 | 5.16M | gs_int_point ppt; |
1454 | 5.16M | code = d_order->procs->bit_index(d_order, j, &ppt); |
1455 | 5.16M | if (code < 0) |
1456 | 0 | return code; |
1457 | 5.16M | row = ppt.y; |
1458 | 5.16M | col = ppt.x; |
1459 | 5.16M | if( col < (int)d_order->width ) { |
1460 | 10.3M | for (kk = 0; kk < num_repeat; kk++) { |
1461 | 5.16M | row_kk = row + kk * d_order->height; |
1462 | 5.16M | col_kk = col + kk * shift; |
1463 | 5.16M | col_kk = col_kk % d_order->width; |
1464 | 5.16M | *(thresh + col_kk + (row_kk * d_order->width)) = t_level; |
1465 | 5.16M | } |
1466 | 5.16M | } |
1467 | 5.16M | } |
1468 | 2.53M | } |
1469 | 2.53M | base_shade = shade; |
1470 | 2.53M | } |
1471 | 37.9M | } |
1472 | 148k | d_order->threshold = thresh; |
1473 | 148k | d_order->threshold_inverted = threshold_inverted; |
1474 | 148k | if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) { |
1475 | 20.2k | for(i = 0; i < (int)d_order->height; i++ ) { |
1476 | 203k | for( j=(int)d_order->width-1; j>=0; j-- ) |
1477 | 185k | *(thresh+j+(i*d_order->width)) = 255 - *(thresh+j+(i*d_order->width)); |
1478 | 17.9k | } |
1479 | 2.27k | } |
1480 | | #ifdef DEBUG |
1481 | | if ( gs_debug_c('h') ) { |
1482 | | dmprintf3(memory, "threshold array component %d [ %d x %d ]:\n", |
1483 | | plane_index, (int)(d_order->full_height), (int)(d_order->width)); |
1484 | | for( i=0; i<(int)d_order->full_height; i++ ) { |
1485 | | dmprintf1(memory, "row %3d= ", i); |
1486 | | for( j=0; j<(int)(d_order->width); j++ ) { |
1487 | | dmprintf1(memory, "%02x ", *(thresh+j+(i*d_order->width)) ); |
1488 | | if ((j&31) == 31) |
1489 | | dmprintf(memory, "\n "); |
1490 | | } |
1491 | | if ((j&31) != 0) |
1492 | | dmprintf(memory, "\n"); |
1493 | | } |
1494 | | } |
1495 | | #endif |
1496 | | /* Large screens are easier to see as images */ |
1497 | | #if DUMP_SCREENS |
1498 | | { |
1499 | | char file_name[50]; |
1500 | | gp_file *fid; |
1501 | | |
1502 | | snprintf(file_name, 50, "Screen_From_Tiles_%dx%d.raw", d_order->width, d_order->full_height); |
1503 | | fid = gp_fopen(memory, file_name, "wb"); |
1504 | | if (fid) { |
1505 | | gp_fwrite(thresh, sizeof(unsigned char), d_order->width * d_order->full_height, fid); |
1506 | | gp_fclose(fid); |
1507 | | } |
1508 | | } |
1509 | | #endif |
1510 | | |
1511 | 148k | return 0; |
1512 | 148k | } |