1 /* Copyright (C) 1991, 2000 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: zfilter2.c,v 1.6 2004/09/26 16:19:27 ray Exp $ */
18 /* Additional filter creation */
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "oper.h"
22 #include "gsstruct.h"
23 #include "ialloc.h"
24 #include "idict.h"
25 #include "idparam.h"
26 #include "store.h"
27 #include "strimpl.h"
28 #include "sfilter.h"
29 #include "scfx.h"
30 #include "slzwx.h"
31 #include "spdiffx.h"
32 #include "spngpx.h"
33 #include "ifilter.h"
34 #include "ifilter2.h"
35 #include "ifwpred.h"
36
37 /* ------ CCITTFaxEncode filter ------ */
38
39 /* <target> <dict> CCITTFaxEncode/filter <file> */
40 private int
zCFE(i_ctx_t * i_ctx_p)41 zCFE(i_ctx_t *i_ctx_p)
42 {
43 os_ptr op = osp;
44 stream_CFE_state cfs;
45 int code;
46
47 check_type(*op, t_dictionary);
48 check_dict_read(*op);
49 code = zcf_setup(op, (stream_CF_state *)&cfs, iimemory);
50 if (code < 0)
51 return code;
52 return filter_write(i_ctx_p, 0, &s_CFE_template, (stream_state *)&cfs, 0);
53 }
54
55 /* ------ Common setup for possibly pixel-oriented encoding filters ------ */
56
57 int
filter_write_predictor(i_ctx_t * i_ctx_p,int npop,const stream_template * template,stream_state * st)58 filter_write_predictor(i_ctx_t *i_ctx_p, int npop,
59 const stream_template * template, stream_state * st)
60 {
61 os_ptr op = osp;
62 int predictor, code;
63 stream_PDiff_state pds;
64 stream_PNGP_state pps;
65
66 if (r_has_type(op, t_dictionary)) {
67 if ((code = dict_int_param(op, "Predictor", 0, 15, 1, &predictor)) < 0)
68 return code;
69 switch (predictor) {
70 case 0: /* identity */
71 predictor = 1;
72 case 1: /* identity */
73 break;
74 case 2: /* componentwise horizontal differencing */
75 code = zpd_setup(op, &pds);
76 break;
77 case 10:
78 case 11:
79 case 12:
80 case 13:
81 case 14:
82 case 15:
83 /* PNG prediction */
84 code = zpp_setup(op, &pps);
85 break;
86 default:
87 return_error(e_rangecheck);
88 }
89 if (code < 0)
90 return code;
91 } else
92 predictor = 1;
93 if (predictor == 1)
94 return filter_write(i_ctx_p, npop, template, st, 0);
95 {
96 /* We need to cascade filters. */
97 ref rtarget, rdict;
98 int code;
99
100 /* Save the operands, just in case. */
101 ref_assign(&rtarget, op - 1);
102 ref_assign(&rdict, op);
103 code = filter_write(i_ctx_p, npop, template, st, 0);
104 if (code < 0)
105 return code;
106 /* filter_write changed osp.... */
107 op = osp;
108 code =
109 (predictor == 2 ?
110 filter_write(i_ctx_p, 0, &s_PDiffE_template, (stream_state *)&pds, 0) :
111 filter_write(i_ctx_p, 0, &s_PNGPE_template, (stream_state *)&pps, 0));
112 if (code < 0) {
113 /* Restore the operands. Don't bother trying to clean up */
114 /* the first stream. */
115 osp = ++op;
116 ref_assign(op - 1, &rtarget);
117 ref_assign(op, &rdict);
118 return code;
119 }
120 /*
121 * Mark the compression stream as temporary, and propagate
122 * CloseTarget from it to the predictor stream.
123 */
124 filter_mark_strm_temp(op, 2);
125 return code;
126 }
127 }
128
129 /* ------ LZW encoding filter ------ */
130
131 /* <target> LZWEncode/filter <file> */
132 /* <target> <dict> LZWEncode/filter <file> */
133 private int
zLZWE(i_ctx_t * i_ctx_p)134 zLZWE(i_ctx_t *i_ctx_p)
135 {
136 os_ptr op = osp;
137 stream_LZW_state lzs;
138 int code = zlz_setup(op, &lzs);
139
140 if (code < 0)
141 return code;
142 return filter_write_predictor(i_ctx_p, 0, &s_LZWE_template,
143 (stream_state *) & lzs);
144 }
145
146 /* ================ Initialization procedure ================ */
147
148 const op_def zfilter2_op_defs[] =
149 {
150 op_def_begin_filter(),
151 {"2CCITTFaxEncode", zCFE},
152 {"1LZWEncode", zLZWE},
153 op_def_end(0)
154 };
155