1 /* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 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: zht2.c,v 1.14 2005/10/11 10:04:28 leonardo Exp $ */
18 /* Level 2 sethalftone operator */
19 #include "ghost.h"
20 #include "oper.h"
21 #include "gsstruct.h"
22 #include "gxdevice.h" /* for gzht.h */
23 #include "gzht.h"
24 #include "estack.h"
25 #include "ialloc.h"
26 #include "iddict.h"
27 #include "idparam.h"
28 #include "igstate.h"
29 #include "icolor.h"
30 #include "iht.h"
31 #include "store.h"
32 #include "iname.h"
33 #include "zht2.h"
34
35 /* Forward references */
36 private int dict_spot_params(const ref *, gs_spot_halftone *, ref *, ref *);
37 private int dict_spot_results(i_ctx_t *, ref *, const gs_spot_halftone *);
38 private int dict_threshold_params(const ref *, gs_threshold_halftone *,
39 ref *);
40 private int dict_threshold2_params(const ref *, gs_threshold2_halftone *,
41 ref *, gs_memory_t *);
42
43 /*
44 * This routine translates a gs_separation_name value into a character string
45 * pointer and a string length.
46 */
47 int
gs_get_colorname_string(const gs_memory_t * mem,gs_separation_name colorname_index,unsigned char ** ppstr,unsigned int * pname_size)48 gs_get_colorname_string(const gs_memory_t *mem, gs_separation_name colorname_index,
49 unsigned char **ppstr, unsigned int *pname_size)
50 {
51 ref nref;
52
53 name_index_ref(mem, colorname_index, &nref);
54 name_string_ref(mem, &nref, &nref);
55 return obj_string_data(mem, &nref, (const unsigned char**) ppstr, pname_size);
56 }
57
58 /* Dummy spot function */
59 private float
spot1_dummy(floatp x,floatp y)60 spot1_dummy(floatp x, floatp y)
61 {
62 return (x + y) / 2;
63 }
64
65 /* <dict> <dict5> .sethalftone5 - */
66 private int sethalftone_finish(i_ctx_t *);
67 private int sethalftone_cleanup(i_ctx_t *);
68 private int
zsethalftone5(i_ctx_t * i_ctx_p)69 zsethalftone5(i_ctx_t *i_ctx_p)
70 {
71 os_ptr op = osp;
72 uint count;
73 gs_halftone_component *phtc;
74 gs_halftone_component *pc;
75 int code = 0;
76 int j;
77 gs_halftone *pht;
78 gx_device_halftone *pdht;
79 ref sprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1];
80 ref tprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1];
81 gs_memory_t *mem;
82 uint edepth = ref_stack_count(&e_stack);
83 int npop = 2;
84 int dict_enum = dict_first(op);
85 ref rvalue[2];
86 int cname, colorant_number;
87 byte * pname;
88 uint name_size;
89 int halftonetype, type = 0;
90 gs_state *pgs = igs;
91 int space_index = r_space_index(op - 1);
92
93 mem = (gs_memory_t *) idmemory->spaces_indexed[space_index];
94
95 check_type(*op, t_dictionary);
96 check_dict_read(*op);
97 check_type(op[-1], t_dictionary);
98 check_dict_read(op[-1]);
99
100 /*
101 * We think that Type 2 and Type 4 halftones, like
102 * screens set by setcolorscreen, adapt automatically to
103 * the device color space, so we need to mark them
104 * with a different internal halftone type.
105 */
106 dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type);
107 halftonetype = (type == 2 || type == 4)
108 ? ht_type_multiple_colorscreen
109 : ht_type_multiple;
110
111 /* Count how many components that we will actually use. */
112
113 for (count = 0; ;) {
114 bool have_default = false;
115
116 /* Move to next element in the dictionary */
117 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1)
118 break;
119 /*
120 * Verify that we have a valid component. We may have a
121 * /HalfToneType entry.
122 */
123 if (!r_has_type(&rvalue[1], t_dictionary))
124 continue;
125
126 /* Get the name of the component verify that we will use it. */
127 cname = name_index(mem, &rvalue[0]);
128 code = gs_get_colorname_string(mem, cname, &pname, &name_size);
129 if (code < 0)
130 break;
131 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size,
132 halftonetype);
133 if (colorant_number < 0)
134 continue;
135 else if (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
136 /* If here then we have the "Default" component */
137 if (have_default)
138 return_error(e_rangecheck);
139 have_default = true;
140 }
141
142 count++;
143 /*
144 * Check to see if we have already reached the legal number of
145 * components.
146 */
147 if (count > GS_CLIENT_COLOR_MAX_COMPONENTS + 1) {
148 code = gs_note_error(e_rangecheck);
149 break;
150 }
151 }
152
153 check_estack(5); /* for sampling Type 1 screens */
154 refset_null(sprocs, count);
155 refset_null(tprocs, count);
156 rc_alloc_struct_0(pht, gs_halftone, &st_halftone,
157 imemory, pht = 0, ".sethalftone5");
158 phtc = gs_alloc_struct_array(mem, count, gs_halftone_component,
159 &st_ht_component_element,
160 ".sethalftone5");
161 rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone,
162 imemory, pdht = 0, ".sethalftone5");
163 if (pht == 0 || phtc == 0 || pdht == 0) {
164 j = 0; /* Quiet the compiler:
165 gs_note_error isn't necessarily identity,
166 so j could be left ununitialized. */
167 code = gs_note_error(e_VMerror);
168 } else {
169 dict_enum = dict_first(op);
170 for (j = 0, pc = phtc; ;) {
171 int type;
172
173 /* Move to next element in the dictionary */
174 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1)
175 break;
176 /*
177 * Verify that we have a valid component. We may have a
178 * /HalfToneType entry.
179 */
180 if (!r_has_type(&rvalue[1], t_dictionary))
181 continue;
182
183 /* Get the name of the component */
184 cname = name_index(mem, &rvalue[0]);
185 code = gs_get_colorname_string(mem, cname, &pname, &name_size);
186 if (code < 0)
187 break;
188 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size,
189 halftonetype);
190 if (colorant_number < 0)
191 continue; /* Do not use this component */
192 pc->cname = cname;
193 pc->comp_number = colorant_number;
194
195 /* Now process the component dictionary */
196 check_dict_read(rvalue[1]);
197 if (dict_int_param(&rvalue[1], "HalftoneType", 1, 7, 0, &type) < 0) {
198 code = gs_note_error(e_typecheck);
199 break;
200 }
201 switch (type) {
202 default:
203 code = gs_note_error(e_rangecheck);
204 break;
205 case 1:
206 code = dict_spot_params(&rvalue[1], &pc->params.spot,
207 sprocs + j, tprocs + j);
208 pc->params.spot.screen.spot_function = spot1_dummy;
209 pc->type = ht_type_spot;
210 break;
211 case 3:
212 code = dict_threshold_params(&rvalue[1], &pc->params.threshold,
213 tprocs + j);
214 pc->type = ht_type_threshold;
215 break;
216 case 7:
217 code = dict_threshold2_params(&rvalue[1], &pc->params.threshold2,
218 tprocs + j, imemory);
219 pc->type = ht_type_threshold2;
220 break;
221 }
222 if (code < 0)
223 break;
224 pc++;
225 j++;
226 }
227 }
228 if (code >= 0) {
229 pht->type = halftonetype;
230 pht->params.multiple.components = phtc;
231 pht->params.multiple.num_comp = j;
232 pht->params.multiple.get_colorname_string = gs_get_colorname_string;
233 code = gs_sethalftone_prepare(igs, pht, pdht);
234 }
235 if (code >= 0) {
236 /*
237 * Put the actual frequency and angle in the spot function component dictionaries.
238 */
239 dict_enum = dict_first(op);
240 for (pc = phtc; ; ) {
241 /* Move to next element in the dictionary */
242 if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1)
243 break;
244
245 /* Verify that we have a valid component */
246 if (!r_has_type(&rvalue[1], t_dictionary))
247 continue;
248
249 /* Get the name of the component and verify that we will use it. */
250 cname = name_index(mem, &rvalue[0]);
251 code = gs_get_colorname_string(mem, cname, &pname, &name_size);
252 if (code < 0)
253 break;
254 colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size,
255 halftonetype);
256 if (colorant_number < 0)
257 continue;
258
259 if (pc->type == ht_type_spot) {
260 code = dict_spot_results(i_ctx_p, &rvalue[1], &pc->params.spot);
261 if (code < 0)
262 break;
263 }
264 pc++;
265 }
266 }
267 if (code >= 0) {
268 /*
269 * Schedule the sampling of any Type 1 screens,
270 * and any (Type 1 or Type 3) TransferFunctions.
271 * Save the stack depths in case we have to back out.
272 */
273 uint odepth = ref_stack_count(&o_stack);
274 ref odict, odict5;
275
276 odict = op[-1];
277 odict5 = *op;
278 pop(2);
279 op = osp;
280 esp += 5;
281 make_mark_estack(esp - 4, es_other, sethalftone_cleanup);
282 esp[-3] = odict;
283 make_istruct(esp - 2, 0, pht);
284 make_istruct(esp - 1, 0, pdht);
285 make_op_estack(esp, sethalftone_finish);
286 for (j = 0; j < count; j++) {
287 gx_ht_order *porder = NULL;
288
289 if (pdht->components == 0)
290 porder = &pdht->order;
291 else {
292 /* Find the component in pdht that matches component j in
293 the pht; gs_sethalftone_prepare() may permute these. */
294 int k;
295 int comp_number = phtc[j].comp_number;
296 for (k = 0; k < count; k++) {
297 if (pdht->components[k].comp_number == comp_number) {
298 porder = &pdht->components[k].corder;
299 break;
300 }
301 }
302 }
303 switch (phtc[j].type) {
304 case ht_type_spot:
305 code = zscreen_enum_init(i_ctx_p, porder,
306 &phtc[j].params.spot.screen,
307 &sprocs[j], 0, 0, space_index);
308 if (code < 0)
309 break;
310 /* falls through */
311 case ht_type_threshold:
312 if (!r_has_type(tprocs + j, t__invalid)) {
313 /* Schedule TransferFunction sampling. */
314 /****** check_xstack IS WRONG ******/
315 check_ostack(zcolor_remap_one_ostack);
316 check_estack(zcolor_remap_one_estack);
317 code = zcolor_remap_one(i_ctx_p, tprocs + j,
318 porder->transfer, igs,
319 zcolor_remap_one_finish);
320 op = osp;
321 }
322 break;
323 default: /* not possible here, but to keep */
324 /* the compilers happy.... */
325 ;
326 }
327 if (code < 0) { /* Restore the stack. */
328 ref_stack_pop_to(&o_stack, odepth);
329 ref_stack_pop_to(&e_stack, edepth);
330 op = osp;
331 op[-1] = odict;
332 *op = odict5;
333 break;
334 }
335 npop = 0;
336 }
337 }
338 if (code < 0) {
339 gs_free_object(mem, pdht, ".sethalftone5");
340 gs_free_object(mem, phtc, ".sethalftone5");
341 gs_free_object(mem, pht, ".sethalftone5");
342 return code;
343 }
344 pop(npop);
345 return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0);
346 }
347
348 /* Install the halftone after sampling. */
349 private int
sethalftone_finish(i_ctx_t * i_ctx_p)350 sethalftone_finish(i_ctx_t *i_ctx_p)
351 {
352 gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
353 int code;
354
355 if (pdht->components)
356 pdht->order = pdht->components[0].corder;
357 code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht);
358 if (code < 0)
359 return code;
360 istate->halftone = esp[-2];
361 esp -= 4;
362 sethalftone_cleanup(i_ctx_p);
363 return o_pop_estack;
364 }
365 /* Clean up after installing the halftone. */
366 private int
sethalftone_cleanup(i_ctx_t * i_ctx_p)367 sethalftone_cleanup(i_ctx_t *i_ctx_p)
368 {
369 gx_device_halftone *pdht = r_ptr(&esp[4], gx_device_halftone);
370 gs_halftone *pht = r_ptr(&esp[3], gs_halftone);
371
372 gs_free_object(pdht->rc.memory, pdht,
373 "sethalftone_cleanup(device halftone)");
374 gs_free_object(pht->rc.memory, pht,
375 "sethalftone_cleanup(halftone)");
376 return 0;
377 }
378
379 /* ------ Initialization procedure ------ */
380
381 const op_def zht2_l2_op_defs[] =
382 {
383 op_def_begin_level2(),
384 {"2.sethalftone5", zsethalftone5},
385 /* Internal operators */
386 {"0%sethalftone_finish", sethalftone_finish},
387 op_def_end(0)
388 };
389
390 /* ------ Internal routines ------ */
391
392 /* Extract frequency, angle, spot function, and accurate screens flag */
393 /* from a dictionary. */
394 private int
dict_spot_params(const ref * pdict,gs_spot_halftone * psp,ref * psproc,ref * ptproc)395 dict_spot_params(const ref * pdict, gs_spot_halftone * psp,
396 ref * psproc, ref * ptproc)
397 {
398 int code;
399
400 check_dict_read(*pdict);
401 if ((code = dict_float_param(pdict, "Frequency", 0.0,
402 &psp->screen.frequency)) != 0 ||
403 (code = dict_float_param(pdict, "Angle", 0.0,
404 &psp->screen.angle)) != 0 ||
405 (code = dict_proc_param(pdict, "SpotFunction", psproc, false)) != 0 ||
406 (code = dict_bool_param(pdict, "AccurateScreens",
407 gs_currentaccuratescreens(),
408 &psp->accurate_screens)) < 0 ||
409 (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0
410 )
411 return (code < 0 ? code : e_undefined);
412 psp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer);
413 psp->transfer_closure.proc = 0;
414 psp->transfer_closure.data = 0;
415 return 0;
416 }
417
418 /* Set actual frequency and angle in a dictionary. */
419 private int
dict_real_result(i_ctx_t * i_ctx_p,ref * pdict,const char * kstr,floatp val)420 dict_real_result(i_ctx_t *i_ctx_p, ref * pdict, const char *kstr, floatp val)
421 {
422 int code = 0;
423 ref *ignore;
424
425 if (dict_find_string(pdict, kstr, &ignore) > 0) {
426 ref rval;
427
428 check_dict_write(*pdict);
429 make_real(&rval, val);
430 code = idict_put_string(pdict, kstr, &rval);
431 }
432 return code;
433 }
434 private int
dict_spot_results(i_ctx_t * i_ctx_p,ref * pdict,const gs_spot_halftone * psp)435 dict_spot_results(i_ctx_t *i_ctx_p, ref * pdict, const gs_spot_halftone * psp)
436 {
437 int code;
438
439 code = dict_real_result(i_ctx_p, pdict, "ActualFrequency",
440 psp->screen.actual_frequency);
441 if (code < 0)
442 return code;
443 return dict_real_result(i_ctx_p, pdict, "ActualAngle",
444 psp->screen.actual_angle);
445 }
446
447 /* Extract Width, Height, and TransferFunction from a dictionary. */
448 private int
dict_threshold_common_params(const ref * pdict,gs_threshold_halftone_common * ptp,ref ** pptstring,ref * ptproc)449 dict_threshold_common_params(const ref * pdict,
450 gs_threshold_halftone_common * ptp,
451 ref **pptstring, ref *ptproc)
452 {
453 int code;
454
455 check_dict_read(*pdict);
456 if ((code = dict_int_param(pdict, "Width", 1, 0x7fff, -1,
457 &ptp->width)) < 0 ||
458 (code = dict_int_param(pdict, "Height", 1, 0x7fff, -1,
459 &ptp->height)) < 0 ||
460 (code = dict_find_string(pdict, "Thresholds", pptstring)) <= 0 ||
461 (code = dict_proc_param(pdict, "TransferFunction", ptproc, false)) < 0
462 )
463 return (code < 0 ? code : e_undefined);
464 ptp->transfer_closure.proc = 0;
465 ptp->transfer_closure.data = 0;
466 return code;
467 }
468
469 /* Extract threshold common parameters + Thresholds. */
470 private int
dict_threshold_params(const ref * pdict,gs_threshold_halftone * ptp,ref * ptproc)471 dict_threshold_params(const ref * pdict, gs_threshold_halftone * ptp,
472 ref * ptproc)
473 {
474 ref *tstring;
475 int code =
476 dict_threshold_common_params(pdict,
477 (gs_threshold_halftone_common *)ptp,
478 &tstring, ptproc);
479
480 if (code < 0)
481 return code;
482 check_read_type_only(*tstring, t_string);
483 if (r_size(tstring) != (long)ptp->width * ptp->height)
484 return_error(e_rangecheck);
485 ptp->thresholds.data = tstring->value.const_bytes;
486 ptp->thresholds.size = r_size(tstring);
487 ptp->transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_mapped_transfer);
488 return 0;
489 }
490
491 /* Extract threshold common parameters + Thresholds, Width2, Height2, */
492 /* BitsPerSample. */
493 private int
dict_threshold2_params(const ref * pdict,gs_threshold2_halftone * ptp,ref * ptproc,gs_memory_t * mem)494 dict_threshold2_params(const ref * pdict, gs_threshold2_halftone * ptp,
495 ref * ptproc, gs_memory_t *mem)
496 {
497 ref *tstring;
498 int code =
499 dict_threshold_common_params(pdict,
500 (gs_threshold_halftone_common *)ptp,
501 &tstring, ptproc);
502 int bps;
503 uint size;
504 int cw2, ch2;
505
506 if (code < 0 ||
507 (code = cw2 = dict_int_param(pdict, "Width2", 0, 0x7fff, 0,
508 &ptp->width2)) < 0 ||
509 (code = ch2 = dict_int_param(pdict, "Height2", 0, 0x7fff, 0,
510 &ptp->height2)) < 0 ||
511 (code = dict_int_param(pdict, "BitsPerSample", 8, 16, -1, &bps)) < 0
512 )
513 return code;
514 if ((bps != 8 && bps != 16) || cw2 != ch2 ||
515 (!cw2 && (ptp->width2 == 0 || ptp->height2 == 0))
516 )
517 return_error(e_rangecheck);
518 ptp->bytes_per_sample = bps / 8;
519 switch (r_type(tstring)) {
520 case t_string:
521 size = r_size(tstring);
522 gs_bytestring_from_string(&ptp->thresholds, tstring->value.const_bytes,
523 size);
524 break;
525 case t_astruct:
526 if (gs_object_type(mem, tstring->value.pstruct) != &st_bytes)
527 return_error(e_typecheck);
528 size = gs_object_size(mem, tstring->value.pstruct);
529 gs_bytestring_from_bytes(&ptp->thresholds, r_ptr(tstring, byte),
530 0, size);
531 break;
532 default:
533 return_error(e_typecheck);
534 }
535 check_read(*tstring);
536 if (size != (ptp->width * ptp->height + ptp->width2 * ptp->height2) *
537 ptp->bytes_per_sample)
538 return_error(e_rangecheck);
539 return 0;
540 }
541