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