]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/zfdecode.c
Import cups.org releases
[thirdparty/cups.git] / pstoraster / zfdecode.c
1 /* Copyright (C) 1994, 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 /* Additional decoding filter creation */
27 #include "memory_.h"
28 #include "ghost.h"
29 #include "oper.h"
30 #include "gsparam.h"
31 #include "gsstruct.h"
32 #include "ialloc.h"
33 #include "idict.h"
34 #include "idparam.h"
35 #include "ilevel.h" /* for LL3 test */
36 #include "iparam.h"
37 #include "store.h"
38 #include "stream.h" /* for setting is_temp */
39 #include "strimpl.h"
40 #include "sfilter.h"
41 #include "sa85x.h"
42 #include "scfx.h"
43 #include "scf.h"
44 #include "slzwx.h"
45 #include "spdiffx.h"
46 #include "spngpx.h"
47 #include "ifilter.h"
48
49 /* Import the Level 2 scanner extensions. */
50 extern const stream_template *scan_ascii85_template;
51
52 /* Initialize the Level 2 scanner for ASCII85 strings. */
53 private void
54 zfdecode_init(void)
55 {
56 scan_ascii85_template = &s_A85D_template;
57 }
58
59 /* ------ ASCII85 filters ------ */
60
61 /* We include both encoding and decoding filters here, */
62 /* because it would be a nuisance to separate them. */
63
64 /* <target> ASCII85Encode/filter <file> */
65 /* <target> <dict> ASCII85Encode/filter <file> */
66 private int
67 zA85E(os_ptr op)
68 {
69 return filter_write_simple(op, &s_A85E_template);
70 }
71
72 /* <source> ASCII85Decode/filter <file> */
73 /* <source> <dict> ASCII85Decode/filter <file> */
74 private int
75 zA85D(os_ptr op)
76 {
77 return filter_read_simple(op, &s_A85D_template);
78 }
79
80 /* ------ CCITTFaxDecode filter ------ */
81
82 /* Common setup for encoding and decoding filters. */
83 extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state);
84 int
85 zcf_setup(os_ptr op, stream_CF_state * pcfs)
86 {
87 dict_param_list list;
88 int code = dict_param_list_read(&list, op, NULL, false);
89
90 if (code < 0)
91 return code;
92 s_CF_set_defaults_inline(pcfs);
93 code = s_CF_put_params((gs_param_list *) & list, pcfs);
94 iparam_list_release(&list);
95 return code;
96 }
97
98 /* <source> <dict> CCITTFaxDecode/filter <file> */
99 /* <source> CCITTFaxDecode/filter <file> */
100 private int
101 zCFD(os_ptr op)
102 {
103 os_ptr dop;
104 stream_CFD_state cfs;
105 int code;
106
107 if (r_has_type(op, t_dictionary)) {
108 check_dict_read(*op);
109 dop = op;
110 } else
111 dop = 0;
112 code = zcf_setup(dop, (stream_CF_state *) & cfs);
113 if (code < 0)
114 return code;
115 return filter_read(op, 0, &s_CFD_template, (stream_state *) & cfs, 0);
116 }
117
118 /* ------ Common setup for possibly pixel-oriented decoding filters ------ */
119
120 /* Forward declarations */
121 int zpd_setup(P2(os_ptr op, stream_PDiff_state * ppds));
122 int zpp_setup(P2(os_ptr op, stream_PNGP_state * ppps));
123
124 int
125 filter_read_predictor(os_ptr op, int npop, const stream_template * template,
126 stream_state * st)
127 {
128 int predictor, code;
129 stream_PDiff_state pds;
130 stream_PNGP_state pps;
131
132 if (r_has_type(op, t_dictionary)) {
133 if ((code = dict_int_param(op, "Predictor", 0, 15, 1, &predictor)) < 0)
134 return code;
135 switch (predictor) {
136 case 0: /* identity */
137 predictor = 1;
138 case 1: /* identity */
139 break;
140 case 2: /* componentwise horizontal differencing */
141 code = zpd_setup(op, &pds);
142 break;
143 case 10:
144 case 11:
145 case 12:
146 case 13:
147 case 14:
148 case 15:
149 /* PNG prediction */
150 code = zpp_setup(op, &pps);
151 break;
152 default:
153 return_error(e_rangecheck);
154 }
155 if (code < 0)
156 return code;
157 } else
158 predictor = 1;
159 if (predictor == 1)
160 return filter_read(op, npop, template, st, 0);
161 {
162 /* We need to cascade filters. */
163 ref rsource, rdict, rfd;
164 int code;
165
166 /* Save the operands, just in case. */
167 ref_assign(&rsource, op - 1);
168 ref_assign(&rdict, op);
169 code = filter_read(op, 1, template, st, 0);
170 if (code < 0)
171 return code;
172 /* filter_read changed osp.... */
173 op = osp;
174 ref_assign(&rfd, op);
175 code =
176 (predictor == 2 ?
177 filter_read(op, 0, &s_PDiffD_template, (stream_state *) & pds, 0) :
178 filter_read(op, 0, &s_PNGPD_template, (stream_state *) & pps, 0));
179 if (code < 0) {
180 /* Restore the operands. Don't bother trying to clean up */
181 /* the first stream. */
182 osp = ++op;
183 ref_assign(op - 1, &rsource);
184 ref_assign(op, &rdict);
185 return code;
186 }
187 filter_mark_temp(&rfd, 2); /* Mark the decompression stream as temporary. */
188 return code;
189 }
190 }
191
192 /* ------ Generalized LZW/GIF decoding filter ------ */
193
194 /* Common setup for encoding and decoding filters. */
195 int
196 zlz_setup(os_ptr op, stream_LZW_state * plzs)
197 {
198 int code;
199 const ref *dop;
200
201 if (r_has_type(op, t_dictionary)) {
202 check_dict_read(*op);
203 dop = op;
204 } else
205 dop = 0;
206 if ( (code = dict_int_param(dop, "EarlyChange", 0, 1, 1,
207 &plzs->EarlyChange)) < 0 ||
208 /*
209 * The following are not PostScript standard, although
210 * LanguageLevel 3 provides the first two under different
211 * names.
212 */
213 (code = dict_int_param(dop, "InitialCodeLength", 2, 11, 8,
214 &plzs->InitialCodeLength)) < 0 ||
215 (code = dict_bool_param(dop, "FirstBitLowOrder", false,
216 &plzs->FirstBitLowOrder)) < 0 ||
217 (code = dict_bool_param(dop, "BlockData", false,
218 &plzs->BlockData)) < 0
219 )
220 return code;
221 return 0;
222 }
223
224 /* <source> LZWDecode/filter <file> */
225 /* <source> <dict> LZWDecode/filter <file> */
226 private int
227 zLZWD(os_ptr op)
228 {
229 stream_LZW_state lzs;
230 int code = zlz_setup(op, &lzs);
231
232 if (code < 0)
233 return code;
234 if (LL3_ENABLED && r_has_type(op, t_dictionary)) {
235 int unit_size;
236
237 if ((code = dict_bool_param(op, "LowBitFirst", lzs.FirstBitLowOrder,
238 &lzs.FirstBitLowOrder)) < 0 ||
239 (code = dict_int_param(op, "UnitSize", 3, 8, 8,
240 &unit_size)) < 0
241 )
242 return code;
243 if (code == 0 /* UnitSize specified */ )
244 lzs.InitialCodeLength = unit_size + 1;
245 }
246 return filter_read_predictor(op, 0, &s_LZWD_template,
247 (stream_state *) & lzs);
248 }
249
250 /* ------ Color differencing filters ------ */
251
252 /* We include both encoding and decoding filters here, */
253 /* because it would be a nuisance to separate them. */
254
255 /* Common setup for encoding and decoding filters. */
256 int
257 zpd_setup(os_ptr op, stream_PDiff_state * ppds)
258 {
259 int code, bpc;
260
261 check_type(*op, t_dictionary);
262 check_dict_read(*op);
263 if ((code = dict_int_param(op, "Colors", 1, 4, 1,
264 &ppds->Colors)) < 0 ||
265 (code = dict_int_param(op, "BitsPerComponent", 1, 8, 8,
266 &bpc)) < 0 ||
267 (bpc & (bpc - 1)) != 0 ||
268 (code = dict_int_param(op, "Columns", 1, max_int, 1,
269 &ppds->Columns)) < 0
270 )
271 return (code < 0 ? code : gs_note_error(e_rangecheck));
272 ppds->BitsPerComponent = bpc;
273 return 0;
274 }
275
276 /* <target> <dict> PixelDifferenceEncode/filter <file> */
277 private int
278 zPDiffE(os_ptr op)
279 {
280 stream_PDiff_state pds;
281 int code = zpd_setup(op, &pds);
282
283 if (code < 0)
284 return code;
285 return filter_write(op, 0, &s_PDiffE_template, (stream_state *) & pds, 0);
286 }
287
288 /* <source> <dict> PixelDifferenceDecode/filter <file> */
289 private int
290 zPDiffD(os_ptr op)
291 {
292 stream_PDiff_state pds;
293 int code = zpd_setup(op, &pds);
294
295 if (code < 0)
296 return code;
297 return filter_read(op, 0, &s_PDiffD_template, (stream_state *) & pds, 0);
298 }
299
300 /* ------ PNG pixel predictor filters ------ */
301
302 /* Common setup for encoding and decoding filters. */
303 int
304 zpp_setup(os_ptr op, stream_PNGP_state * ppps)
305 {
306 int code, bpc;
307
308 check_type(*op, t_dictionary);
309 check_dict_read(*op);
310 if ((code = dict_int_param(op, "Colors", 1, 16, 1,
311 &ppps->Colors)) < 0 ||
312 (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8,
313 &bpc)) < 0 ||
314 (bpc & (bpc - 1)) != 0 ||
315 (code = dict_uint_param(op, "Columns", 1, max_uint, 1,
316 &ppps->Columns)) < 0 ||
317 (code = dict_int_param(op, "Predictor", 10, 15, 15,
318 &ppps->Predictor)) < 0
319 )
320 return (code < 0 ? code : gs_note_error(e_rangecheck));
321 ppps->BitsPerComponent = bpc;
322 return 0;
323 }
324
325 /* <target> <dict> PNGPredictorEncode/filter <file> */
326 private int
327 zPNGPE(os_ptr op)
328 {
329 stream_PNGP_state pps;
330 int code = zpp_setup(op, &pps);
331
332 if (code < 0)
333 return code;
334 return filter_write(op, 0, &s_PNGPE_template, (stream_state *) & pps, 0);
335 }
336
337 /* <source> <dict> PNGPredictorDecode/filter <file> */
338 private int
339 zPNGPD(os_ptr op)
340 {
341 stream_PNGP_state pps;
342 int code = zpp_setup(op, &pps);
343
344 if (code < 0)
345 return code;
346 return filter_read(op, 0, &s_PNGPD_template, (stream_state *) & pps, 0);
347 }
348
349 /* ---------------- Initialization procedure ---------------- */
350
351 const op_def zfdecode_op_defs[] =
352 {
353 op_def_begin_filter(),
354 {"1ASCII85Encode", zA85E},
355 {"1ASCII85Decode", zA85D},
356 {"2CCITTFaxDecode", zCFD},
357 {"1LZWDecode", zLZWD},
358 {"2PixelDifferenceDecode", zPDiffD},
359 {"2PixelDifferenceEncode", zPDiffE},
360 {"2PNGPredictorDecode", zPNGPD},
361 {"2PNGPredictorEncode", zPNGPE},
362 op_def_end(zfdecode_init)
363 };