]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/zfilterx.c
Import cups.org releases
[thirdparty/cups.git] / pstoraster / zfilterx.c
1 /* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved.
2
3 This file is part of GNU Ghostscript.
4
5 GNU Ghostscript is distributed in the hope that it will be useful, but
6 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 to anyone for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing. Refer
9 to the GNU General Public License for full details.
10
11 Everyone is granted permission to copy, modify and redistribute GNU
12 Ghostscript, but only under the conditions described in the GNU General
13 Public License. A copy of this license is supposed to have been given
14 to you along with GNU Ghostscript so you can know your rights and
15 responsibilities. It should be in a file named COPYING. Among other
16 things, the copyright notice and this notice must be preserved on all
17 copies.
18
19 Aladdin Enterprises supports the work of the GNU Project, but is not
20 affiliated with the Free Software Foundation or the GNU Project. GNU
21 Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 GNU software to build or run it.
23 */
24
25 /*$Id$ */
26 /* Extended (non-standard) filter creation */
27 #include "memory_.h"
28 #include "ghost.h"
29 #include "oper.h"
30 #include "gsstruct.h"
31 #include "ialloc.h"
32 #include "idict.h"
33 #include "idparam.h"
34 #include "store.h"
35 #include "strimpl.h"
36 #include "sfilter.h"
37 #include "sbwbs.h"
38 #include "sbhc.h"
39 #include "sbtx.h"
40 #include "shcgen.h"
41 #include "smtf.h"
42 #include "spcxx.h"
43 #include "ifilter.h"
44
45 /* ------ Bounded Huffman code filters ------ */
46
47 /* Common setup for encoding and decoding filters */
48 private int
49 bhc_setup(os_ptr op, stream_BHC_state * pbhcs)
50 {
51 int code;
52 int num_counts;
53 int data[max_hc_length + 1 + 256 + max_zero_run + 1];
54 uint dsize;
55 int i;
56 uint num_values, accum;
57 ushort *counts;
58 ushort *values;
59
60 check_type(*op, t_dictionary);
61 check_dict_read(*op);
62 if ((code = dict_bool_param(op, "FirstBitLowOrder", false,
63 &pbhcs->FirstBitLowOrder)) < 0 ||
64 (code = dict_int_param(op, "MaxCodeLength", 1, max_hc_length,
65 max_hc_length, &num_counts)) < 0 ||
66 (code = dict_bool_param(op, "EndOfData", true,
67 &pbhcs->EndOfData)) < 0 ||
68 (code = dict_uint_param(op, "EncodeZeroRuns", 2, 256,
69 256, &pbhcs->EncodeZeroRuns)) < 0 ||
70 /* Note: the code returned from the following call */
71 /* is actually the number of elements in the array. */
72 (code = dict_int_array_param(op, "Tables", countof(data),
73 data)) <= 0
74 )
75 return (code < 0 ? code : gs_note_error(e_rangecheck));
76 dsize = code;
77 if (dsize <= num_counts + 2)
78 return_error(e_rangecheck);
79 for (i = 0, num_values = 0, accum = 0; i <= num_counts;
80 i++, accum <<= 1
81 ) {
82 int count = data[i];
83
84 if (count < 0)
85 return_error(e_rangecheck);
86 num_values += count;
87 accum += count;
88 }
89 if (dsize != num_counts + 1 + num_values ||
90 accum != 1 << (num_counts + 1) ||
91 pbhcs->EncodeZeroRuns >
92 (pbhcs->EndOfData ? num_values - 1 : num_values)
93 )
94 return_error(e_rangecheck);
95 for (; i < num_counts + 1 + num_values; i++) {
96 int value = data[i];
97
98 if (value < 0 || value >= num_values)
99 return_error(e_rangecheck);
100 }
101 pbhcs->definition.counts = counts =
102 (ushort *) ialloc_byte_array(num_counts + 1, sizeof(ushort),
103 "bhc_setup(counts)");
104 pbhcs->definition.values = values =
105 (ushort *) ialloc_byte_array(num_values, sizeof(ushort),
106 "bhc_setup(values)");
107 if (counts == 0 || values == 0) {
108 ifree_object(values, "bhc_setup(values)");
109 ifree_object(counts, "bhc_setup(counts)");
110 return_error(e_VMerror);
111 }
112 for (i = 0; i <= num_counts; i++)
113 counts[i] = data[i];
114 pbhcs->definition.counts = counts;
115 pbhcs->definition.num_counts = num_counts;
116 for (i = 0; i < num_values; i++)
117 values[i] = data[i + num_counts + 1];
118 pbhcs->definition.values = values;
119 pbhcs->definition.num_values = num_values;
120 return 0;
121 }
122
123 /* <target> <dict> BoundedHuffmanEncode/filter <file> */
124 private int
125 zBHCE(os_ptr op)
126 {
127 stream_BHCE_state bhcs;
128 int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
129
130 if (code < 0)
131 return code;
132 return filter_write(op, 0, &s_BHCE_template, (stream_state *)&bhcs, 0);
133 }
134
135 /* <source> <dict> BoundedHuffmanDecode/filter <file> */
136 private int
137 zBHCD(os_ptr op)
138 {
139 stream_BHCD_state bhcs;
140 int code = bhc_setup(op, (stream_BHC_state *)&bhcs);
141
142 if (code < 0)
143 return code;
144 return filter_read(op, 0, &s_BHCD_template, (stream_state *)&bhcs, 0);
145 }
146
147 /* <array> <max_length> .computecodes <array> */
148 /* The first max_length+1 elements of the array will be filled in with */
149 /* the code counts; the remaining elements will be replaced with */
150 /* the code values. This is the form needed for the Tables element of */
151 /* the dictionary parameter for the BoundedHuffman filters. */
152 private int
153 zcomputecodes(os_ptr op)
154 {
155 os_ptr op1 = op - 1;
156 uint asize;
157 hc_definition def;
158 ushort *data;
159 long *freqs;
160 int code = 0;
161
162 check_type(*op, t_integer);
163 check_write_type(*op1, t_array);
164 asize = r_size(op1);
165 if (op->value.intval < 1 || op->value.intval > max_hc_length)
166 return_error(e_rangecheck);
167 def.num_counts = op->value.intval;
168 if (asize < def.num_counts + 2)
169 return_error(e_rangecheck);
170 def.num_values = asize - (def.num_counts + 1);
171 data = (ushort *) gs_alloc_byte_array(imemory, asize, sizeof(ushort),
172 "zcomputecodes");
173 freqs = (long *)gs_alloc_byte_array(imemory, def.num_values,
174 sizeof(long),
175 "zcomputecodes(freqs)");
176
177 if (data == 0 || freqs == 0)
178 code = gs_note_error(e_VMerror);
179 else {
180 uint i;
181
182 def.counts = data;
183 def.values = data + (def.num_counts + 1);
184 for (i = 0; i < def.num_values; i++) {
185 const ref *pf = op1->value.const_refs + i + def.num_counts + 1;
186
187 if (!r_has_type(pf, t_integer)) {
188 code = gs_note_error(e_typecheck);
189 break;
190 }
191 freqs[i] = pf->value.intval;
192 }
193 if (!code) {
194 code = hc_compute(&def, freqs, imemory);
195 if (code >= 0) {
196 /* Copy back results. */
197 for (i = 0; i < asize; i++)
198 make_int(op1->value.refs + i, data[i]);
199 }
200 }
201 }
202 gs_free_object(imemory, freqs, "zcomputecodes(freqs)");
203 gs_free_object(imemory, data, "zcomputecodes");
204 if (code < 0)
205 return code;
206 pop(1);
207 return code;
208 }
209
210 /* ------ Burrows/Wheeler block sorting filters ------ */
211
212 /* Common setup for encoding and decoding filters */
213 private int
214 bwbs_setup(os_ptr op, stream_BWBS_state * pbwbss)
215 {
216 int code =
217 dict_int_param(op, "BlockSize", 1, max_int / sizeof(int) - 10, 16384,
218 &pbwbss->BlockSize);
219
220 if (code < 0)
221 return code;
222 return 0;
223 }
224
225 /* <target> <dict> BWBlockSortEncode/filter <file> */
226 private int
227 zBWBSE(os_ptr op)
228 {
229 stream_BWBSE_state bwbss;
230 int code;
231
232 check_type(*op, t_dictionary);
233 check_dict_read(*op);
234 code = bwbs_setup(op, (stream_BWBS_state *)&bwbss);
235 if (code < 0)
236 return code;
237 return filter_write(op, 0, &s_BWBSE_template, (stream_state *)&bwbss, 0);
238 }
239
240 /* <source> <dict> BWBlockSortDecode/filter <file> */
241 private int
242 zBWBSD(os_ptr op)
243 {
244 stream_BWBSD_state bwbss;
245 int code = bwbs_setup(op, (stream_BWBS_state *)&bwbss);
246
247 if (code < 0)
248 return code;
249 return filter_read(op, 0, &s_BWBSD_template, (stream_state *)&bwbss, 0);
250 }
251
252 /* ------ Byte translation filters ------ */
253
254 /* Common setup */
255 private int
256 bt_setup(os_ptr op, stream_BT_state * pbts)
257 {
258 check_read_type(*op, t_string);
259 if (r_size(op) != 256)
260 return_error(e_rangecheck);
261 memcpy(pbts->table, op->value.const_bytes, 256);
262 return 0;
263 }
264
265 /* <target> <table> ByteTranslateEncode/filter <file> */
266 /* <target> <table> <dict> ByteTranslateEncode/filter <file> */
267 private int
268 zBTE(os_ptr op)
269 {
270 stream_BT_state bts;
271 int code = bt_setup(op, &bts);
272
273 if (code < 0)
274 return code;
275 return filter_write(op, 0, &s_BTE_template, (stream_state *)&bts, 0);
276 }
277
278 /* <target> <table> ByteTranslateDecode/filter <file> */
279 /* <target> <table> <dict> ByteTranslateDecode/filter <file> */
280 private int
281 zBTD(os_ptr op)
282 {
283 stream_BT_state bts;
284 int code = bt_setup(op, &bts);
285
286 if (code < 0)
287 return code;
288 return filter_read(op, 0, &s_BTD_template, (stream_state *)&bts, 0);
289 }
290
291 /* ------ Move-to-front filters ------ */
292
293 /* <target> MoveToFrontEncode/filter <file> */
294 /* <target> <dict> MoveToFrontEncode/filter <file> */
295 private int
296 zMTFE(os_ptr op)
297 {
298 return filter_write_simple(op, &s_MTFE_template);
299 }
300
301 /* <source> MoveToFrontDecode/filter <file> */
302 /* <source> <dict> MoveToFrontDecode/filter <file> */
303 private int
304 zMTFD(os_ptr op)
305 {
306 return filter_read_simple(op, &s_MTFD_template);
307 }
308
309 /* ------ PCX decoding filter ------ */
310
311 /* <source> PCXDecode/filter <file> */
312 /* <source> <dict> PCXDecode/filter <file> */
313 private int
314 zPCXD(os_ptr op)
315 {
316 return filter_read_simple(op, &s_PCXD_template);
317 }
318
319 /* ================ Initialization procedure ================ */
320
321 const op_def zfilterx_op_defs[] =
322 {
323 {"2.computecodes", zcomputecodes}, /* not a filter */
324 op_def_begin_filter(),
325 /* Non-standard filters */
326 {"2BoundedHuffmanEncode", zBHCE},
327 {"2BoundedHuffmanDecode", zBHCD},
328 {"2BWBlockSortEncode", zBWBSE},
329 {"2BWBlockSortDecode", zBWBSD},
330 {"2ByteTranslateEncode", zBTE},
331 {"2ByteTranslateDecode", zBTD},
332 {"1MoveToFrontEncode", zMTFE},
333 {"1MoveToFrontDecode", zMTFD},
334 {"1PCXDecode", zPCXD},
335 op_def_end(0)
336 };