Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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
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
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
}