Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/psi/zfdecode.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Additional decoding filter creation */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gsparam.h"
22
#include "gsstruct.h"
23
#include "ialloc.h"
24
#include "idict.h"
25
#include "idparam.h"
26
#include "ilevel.h"   /* for LL3 test */
27
#include "iparam.h"
28
#include "store.h"
29
#include "stream.h"   /* for setting is_temp */
30
#include "strimpl.h"
31
#include "sfilter.h"
32
#include "sa85x.h"
33
#include "scfx.h"
34
#include "scf.h"
35
#include "slzwx.h"
36
#include "spdiffx.h"
37
#include "spngpx.h"
38
#include "ifilter.h"
39
#include "ifilter2.h"
40
#include "ifrpred.h"
41
42
/* ------ ASCII85 filters ------ */
43
44
/* We include both encoding and decoding filters here, */
45
/* because it would be a nuisance to separate them. */
46
47
/* <target> ASCII85Encode/filter <file> */
48
/* <target> <dict> ASCII85Encode/filter <file> */
49
static int
50
zA85E(i_ctx_t *i_ctx_p)
51
0
{
52
0
    return filter_write_simple(i_ctx_p, &s_A85E_template);
53
0
}
54
55
/* <source> ASCII85Decode/filter <file> */
56
/* <source> <dict> ASCII85Decode/filter <file> */
57
static int
58
zA85D(i_ctx_t *i_ctx_p)
59
1
{
60
1
    os_ptr op = osp;
61
1
    stream_A85D_state ss;
62
1
    int code;
63
64
1
    if (r_has_type(op, t_dictionary)) {
65
0
        check_dict_read(*op);
66
0
        if ((code = dict_bool_param(op, "PDFRules", false, &ss.pdf_rules)) < 0)
67
0
            return code;
68
1
    } else {
69
1
        ss.pdf_rules = false;
70
1
    }
71
1
    return filter_read(i_ctx_p, 0, &s_A85D_template, (stream_state *)&ss, 0);
72
1
}
73
74
/* ------ CCITTFaxDecode filter ------ */
75
76
/* Common setup for encoding and decoding filters. */
77
extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state);
78
int
79
zcf_setup(os_ptr op, stream_CF_state *pcfs, gs_ref_memory_t *imem)
80
0
{
81
0
    dict_param_list list;
82
0
    int code = dict_param_list_read(&list, op, NULL, false, imem);
83
84
0
    if (code < 0)
85
0
        return code;
86
0
    s_CF_set_defaults_inline(pcfs);
87
0
    code = s_CF_put_params((gs_param_list *)&list, pcfs);
88
0
    iparam_list_release(&list);
89
0
    return code;
90
0
}
91
92
/* <source> <dict> CCITTFaxDecode/filter <file> */
93
/* <source> CCITTFaxDecode/filter <file> */
94
static int
95
zCFD(i_ctx_t *i_ctx_p)
96
0
{
97
0
    os_ptr op = osp;
98
0
    os_ptr dop;
99
0
    stream_CFD_state cfs;
100
0
    int code;
101
102
0
    if (r_has_type(op, t_dictionary)) {
103
0
        check_dict_read(*op);
104
0
        dop = op;
105
0
    } else
106
0
        dop = 0;
107
0
    code = zcf_setup(dop, (stream_CF_state *)&cfs, iimemory);
108
0
    if (code < 0)
109
0
        return code;
110
0
    return filter_read(i_ctx_p, 0, &s_CFD_template, (stream_state *)&cfs, 0);
111
0
}
112
113
/* ------ Common setup for possibly pixel-oriented decoding filters ------ */
114
115
int
116
filter_read_predictor(i_ctx_t *i_ctx_p, int npop,
117
                      const stream_template * templat, stream_state * st)
118
3
{
119
3
    os_ptr op = osp;
120
3
    int predictor, code;
121
3
    stream_PDiff_state pds;
122
3
    stream_PNGP_state pps;
123
124
3
    if (r_has_type(op, t_dictionary)) {
125
0
        if ((code = dict_int_param(op, "Predictor", 0, 15, 1, &predictor)) < 0)
126
0
            return code;
127
0
        switch (predictor) {
128
0
            case 0:   /* identity */
129
0
                predictor = 1;
130
0
            case 1:   /* identity */
131
0
                break;
132
0
            case 2:   /* componentwise horizontal differencing */
133
0
                code = zpd_setup(op, &pds);
134
0
                break;
135
0
            case 10:
136
0
            case 11:
137
0
            case 12:
138
0
            case 13:
139
0
            case 14:
140
0
            case 15:
141
                /* PNG prediction */
142
0
                code = zpp_setup(op, &pps);
143
0
                break;
144
0
            default:
145
0
                return_error(gs_error_rangecheck);
146
0
        }
147
0
        if (code < 0)
148
0
            return code;
149
0
    } else
150
3
        predictor = 1;
151
3
    if (predictor == 1)
152
3
        return filter_read(i_ctx_p, npop, templat, st, 0);
153
0
    {
154
        /* We need to cascade filters. */
155
0
        ref rsource, rdict;
156
0
        int code;
157
158
        /* Save the operands, just in case. */
159
0
        ref_assign(&rsource, op - 1);
160
0
        ref_assign(&rdict, op);
161
0
        code = filter_read(i_ctx_p, 1, templat, st, 0);
162
0
        if (code < 0)
163
0
            return code;
164
        /* filter_read changed osp.... */
165
0
        op = osp;
166
0
        code =
167
0
            (predictor == 2 ?
168
0
         filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0) :
169
0
          filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0));
170
0
        if (code < 0) {
171
            /* Restore the operands.  Don't bother trying to clean up */
172
            /* the first stream. */
173
0
            osp = ++op;
174
0
            ref_assign(op - 1, &rsource);
175
0
            ref_assign(op, &rdict);
176
0
            return code;
177
0
        }
178
        /*
179
         * Mark the compression stream as temporary, and propagate
180
         * CloseSource from it to the predictor stream.
181
         */
182
0
        filter_mark_strm_temp(op, 2);
183
0
        return code;
184
0
    }
185
0
}
186
187
/* ------ Generalized LZW/GIF decoding filter ------ */
188
189
/* Common setup for encoding and decoding filters. */
190
int
191
zlz_setup(os_ptr op, stream_LZW_state * plzs)
192
3
{
193
3
    int code, ech;
194
3
    const ref *dop;
195
196
3
    s_LZW_set_defaults_inline(plzs);
197
3
    if (r_has_type(op, t_dictionary)) {
198
0
        check_dict_read(*op);
199
0
        dop = op;
200
0
    } else
201
3
        dop = 0;
202
3
    if (   (code = dict_int_param(dop, "EarlyChange", 0, 1, 1,
203
3
                                  &ech)) < 0 ||
204
           /*
205
            * The following are not PostScript standard, although
206
            * LanguageLevel 3 provides the first two under different
207
            * names.
208
            */
209
3
           (code = dict_int_param(dop, "InitialCodeLength", 2, 11, 8,
210
3
                                  &plzs->InitialCodeLength)) < 0 ||
211
3
           (code = dict_bool_param(dop, "FirstBitLowOrder", false,
212
3
                                   &plzs->FirstBitLowOrder)) < 0 ||
213
3
           (code = dict_bool_param(dop, "BlockData", false,
214
3
                                   &plzs->BlockData)) < 0
215
3
        )
216
0
        return code;
217
3
    plzs->EarlyChange = ech != 0;
218
3
    return 0;
219
3
}
220
221
/* <source> LZWDecode/filter <file> */
222
/* <source> <dict> LZWDecode/filter <file> */
223
static int
224
zLZWD(i_ctx_t *i_ctx_p)
225
3
{
226
3
    os_ptr op = osp;
227
3
    stream_LZW_state lzs;
228
3
    int code = zlz_setup(op, &lzs);
229
230
3
    if (code < 0)
231
0
        return code;
232
3
    if (LL3_ENABLED && r_has_type(op, t_dictionary)) {
233
0
        int unit_size;
234
235
0
        if ((code = dict_bool_param(op, "LowBitFirst", lzs.FirstBitLowOrder,
236
0
                                    &lzs.FirstBitLowOrder)) < 0 ||
237
0
            (code = dict_int_param(op, "UnitSize", 3, 8, 8,
238
0
                                   &unit_size)) < 0
239
0
            )
240
0
            return code;
241
0
        if (code == 0 /* UnitSize specified */ )
242
0
            lzs.InitialCodeLength = unit_size + 1;
243
0
    }
244
3
    return filter_read_predictor(i_ctx_p, 0, &s_LZWD_template,
245
3
                                 (stream_state *) & lzs);
246
3
}
247
248
/* ------ Color differencing filters ------ */
249
250
/* We include both encoding and decoding filters here, */
251
/* because it would be a nuisance to separate them. */
252
253
/* Common setup for encoding and decoding filters. */
254
int
255
zpd_setup(os_ptr op, stream_PDiff_state * ppds)
256
0
{
257
0
    int code, bpc;
258
259
0
    check_type(*op, t_dictionary);
260
0
    check_dict_read(*op);
261
0
    if ((code = dict_int_param(op, "Colors", 1, s_PDiff_max_Colors, 1,
262
0
                               &ppds->Colors)) < 0 ||
263
0
        (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8,
264
0
                               &bpc)) < 0 ||
265
0
        (bpc & (bpc - 1)) != 0 ||
266
0
        (code = dict_int_param(op, "Columns", 1, max_int, 1,
267
0
                               &ppds->Columns)) < 0
268
0
        )
269
0
        return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
270
0
    ppds->BitsPerComponent = bpc;
271
0
    return 0;
272
0
}
273
274
/* ------ PNG pixel predictor filters ------ */
275
276
/* Common setup for encoding and decoding filters. */
277
int
278
zpp_setup(os_ptr op, stream_PNGP_state * ppps)
279
0
{
280
0
    int code, bpc;
281
282
0
    check_type(*op, t_dictionary);
283
0
    check_dict_read(*op);
284
0
    if ((code = dict_int_param(op, "Colors", 1, s_PNG_max_Colors, 1,
285
0
                               &ppps->Colors)) < 0 ||
286
0
        (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8,
287
0
                               &bpc)) < 0 ||
288
0
        (bpc & (bpc - 1)) != 0 ||
289
0
        (code = dict_uint_param(op, "Columns", 1, max_uint, 1,
290
0
                                &ppps->Columns)) < 0 ||
291
0
        (code = dict_int_param(op, "Predictor", 10, 15, 15,
292
0
                               &ppps->Predictor)) < 0
293
0
        )
294
0
        return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
295
0
    ppps->BitsPerComponent = bpc;
296
0
    return 0;
297
0
}
298
299
/* ---------------- Initialization procedure ---------------- */
300
301
const op_def zfdecode_op_defs[] = {
302
    op_def_begin_filter(),
303
    {"1ASCII85Encode", zA85E},
304
    {"1ASCII85Decode", zA85D},
305
    {"2CCITTFaxDecode", zCFD},
306
    {"1LZWDecode", zLZWD},
307
    op_def_end(0)
308
};