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