xref: /plan9/sys/src/cmd/gs/src/zht1.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1994, 1997, 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: zht1.c,v 1.7 2005/10/11 10:04:28 leonardo Exp $ */
18 /* setcolorscreen operator */
19 #include "ghost.h"
20 #include "memory_.h"
21 #include "oper.h"
22 #include "estack.h"
23 #include "gsstruct.h"		/* must precede igstate.h, */
24 					/* because of #ifdef in gsht.h */
25 #include "ialloc.h"
26 #include "igstate.h"
27 #include "gsmatrix.h"
28 #include "gxdevice.h"		/* for gzht.h */
29 #include "gzht.h"
30 #include "gsstate.h"
31 #include "iht.h"
32 #include "store.h"
33 
34 /* Dummy spot function */
35 private float
spot_dummy(floatp x,floatp y)36 spot_dummy(floatp x, floatp y)
37 {
38     return (x + y) / 2;
39 }
40 
41 /* <red_freq> ... <gray_proc> setcolorscreen - */
42 private int setcolorscreen_finish(i_ctx_t *);
43 private int setcolorscreen_cleanup(i_ctx_t *);
44 private int
zsetcolorscreen(i_ctx_t * i_ctx_p)45 zsetcolorscreen(i_ctx_t *i_ctx_p)
46 {
47     os_ptr op = osp;
48     gs_colorscreen_halftone cscreen;
49     ref sprocs[4];
50     gs_halftone *pht;
51     gx_device_halftone *pdht;
52     int i;
53     int code = 0;
54     int space = 0;
55     gs_memory_t *mem;
56 
57     for (i = 0; i < 4; i++) {
58 	os_ptr op1 = op - 9 + i * 3;
59 	int code = zscreen_params(op1, &cscreen.screens.indexed[i]);
60 
61 	if (code < 0)
62 	    return code;
63 	cscreen.screens.indexed[i].spot_function = spot_dummy;
64 	sprocs[i] = *op1;
65 	space = max(space, r_space_index(op1));
66     }
67     mem = (gs_memory_t *)idmemory->spaces_indexed[space];
68     check_estack(8);		/* for sampling screens */
69     rc_alloc_struct_0(pht, gs_halftone, &st_halftone,
70 		      mem, pht = 0, "setcolorscreen(halftone)");
71     rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone,
72 		      mem, pdht = 0, "setcolorscreen(device halftone)");
73     if (pht == 0 || pdht == 0)
74 	code = gs_note_error(e_VMerror);
75     else {
76 	pht->type = ht_type_colorscreen;
77 	pht->params.colorscreen = cscreen;
78 	code = gs_sethalftone_prepare(igs, pht, pdht);
79     }
80     if (code >= 0) {		/* Schedule the sampling of the screens. */
81 	es_ptr esp0 = esp;	/* for backing out */
82 
83 	esp += 8;
84 	make_mark_estack(esp - 7, es_other, setcolorscreen_cleanup);
85 	memcpy(esp - 6, sprocs, sizeof(ref) * 4);	/* procs */
86 	make_istruct(esp - 2, 0, pht);
87 	make_istruct(esp - 1, 0, pdht);
88 	make_op_estack(esp, setcolorscreen_finish);
89 	for (i = 0; i < 4; i++) {
90 	    /* Shuffle the indices to correspond to */
91 	    /* the component order. */
92 	    code = zscreen_enum_init(i_ctx_p,
93 				     &pdht->components[(i + 1) & 3].corder,
94 				&pht->params.colorscreen.screens.indexed[i],
95 				     &sprocs[i], 0, 0, space);
96 	    if (code < 0) {
97 		esp = esp0;
98 		break;
99 	    }
100 	}
101     }
102     if (code < 0) {
103 	gs_free_object(mem, pdht, "setcolorscreen(device halftone)");
104 	gs_free_object(mem, pht, "setcolorscreen(halftone)");
105 	return code;
106     }
107     pop(12);
108     return o_push_estack;
109 }
110 /* Install the color screen after sampling. */
111 private int
setcolorscreen_finish(i_ctx_t * i_ctx_p)112 setcolorscreen_finish(i_ctx_t *i_ctx_p)
113 {
114     gx_device_halftone *pdht = r_ptr(esp, gx_device_halftone);
115     int code;
116 
117     pdht->order = pdht->components[0].corder;
118     code = gx_ht_install(igs, r_ptr(esp - 1, gs_halftone), pdht);
119     if (code < 0)
120 	return code;
121     memcpy(&istate->screen_procs.red, esp - 5, sizeof(ref) * 4);
122     make_null(&istate->halftone);
123     esp -= 7;
124     setcolorscreen_cleanup(i_ctx_p);
125     return o_pop_estack;
126 }
127 /* Clean up after installing the color screen. */
128 private int
setcolorscreen_cleanup(i_ctx_t * i_ctx_p)129 setcolorscreen_cleanup(i_ctx_t *i_ctx_p)
130 {
131     gs_halftone *pht = r_ptr(esp + 6, gs_halftone);
132     gx_device_halftone *pdht = r_ptr(esp + 7, gx_device_halftone);
133 
134     gs_free_object(pdht->rc.memory, pdht,
135 		   "setcolorscreen_cleanup(device halftone)");
136     gs_free_object(pht->rc.memory, pht,
137 		   "setcolorscreen_cleanup(halftone)");
138     return 0;
139 }
140 
141 /* ------ Initialization procedure ------ */
142 
143 const op_def zht1_op_defs[] =
144 {
145     {"<setcolorscreen", zsetcolorscreen},
146 		/* Internal operators */
147     {"0%setcolorscreen_finish", setcolorscreen_finish},
148     op_def_end(0)
149 };
150