Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/zfdecode.c
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
/* 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
0
{
60
0
    os_ptr op = osp;
61
0
    stream_A85D_state ss;
62
0
    int code;
63
64
0
    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
0
    } else {
69
0
        ss.pdf_rules = false;
70
0
    }
71
0
    return filter_read(i_ctx_p, 0, &s_A85D_template, (stream_state *)&ss, 0);
72
0
}
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
0
{
119
0
    os_ptr op = osp;
120
0
    int predictor, code;
121
0
    stream_PDiff_state pds;
122
0
    stream_PNGP_state pps;
123
124
0
    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
0
        predictor = 1;
151
0
    if (predictor == 1)
152
0
        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
0
{
193
0
    int code;
194
0
    const ref *dop;
195
196
0
    s_LZW_set_defaults_inline(plzs);
197
0
    if (r_has_type(op, t_dictionary)) {
198
0
        check_dict_read(*op);
199
0
        dop = op;
200
0
    } else
201
0
        dop = 0;
202
0
    if (   (code = dict_int_param(dop, "EarlyChange", 0, 1, 1,
203
0
                                  &plzs->EarlyChange)) < 0 ||
204
           /*
205
            * The following are not PostScript standard, although
206
            * LanguageLevel 3 provides the first two under different
207
            * names.
208
            */
209
0
           (code = dict_int_param(dop, "InitialCodeLength", 2, 11, 8,
210
0
                                  &plzs->InitialCodeLength)) < 0 ||
211
0
           (code = dict_bool_param(dop, "FirstBitLowOrder", false,
212
0
                                   &plzs->FirstBitLowOrder)) < 0 ||
213
0
           (code = dict_bool_param(dop, "BlockData", false,
214
0
                                   &plzs->BlockData)) < 0
215
0
        )
216
0
        return code;
217
0
    return 0;
218
0
}
219
220
/* <source> LZWDecode/filter <file> */
221
/* <source> <dict> LZWDecode/filter <file> */
222
static int
223
zLZWD(i_ctx_t *i_ctx_p)
224
0
{
225
0
    os_ptr op = osp;
226
0
    stream_LZW_state lzs;
227
0
    int code = zlz_setup(op, &lzs);
228
229
0
    if (code < 0)
230
0
        return code;
231
0
    if (LL3_ENABLED && r_has_type(op, t_dictionary)) {
232
0
        int unit_size;
233
234
0
        if ((code = dict_bool_param(op, "LowBitFirst", lzs.FirstBitLowOrder,
235
0
                                    &lzs.FirstBitLowOrder)) < 0 ||
236
0
            (code = dict_int_param(op, "UnitSize", 3, 8, 8,
237
0
                                   &unit_size)) < 0
238
0
            )
239
0
            return code;
240
0
        if (code == 0 /* UnitSize specified */ )
241
0
            lzs.InitialCodeLength = unit_size + 1;
242
0
    }
243
0
    return filter_read_predictor(i_ctx_p, 0, &s_LZWD_template,
244
0
                                 (stream_state *) & lzs);
245
0
}
246
247
/* ------ Color differencing filters ------ */
248
249
/* We include both encoding and decoding filters here, */
250
/* because it would be a nuisance to separate them. */
251
252
/* Common setup for encoding and decoding filters. */
253
int
254
zpd_setup(os_ptr op, stream_PDiff_state * ppds)
255
0
{
256
0
    int code, bpc;
257
258
0
    check_type(*op, t_dictionary);
259
0
    check_dict_read(*op);
260
0
    if ((code = dict_int_param(op, "Colors", 1, s_PDiff_max_Colors, 1,
261
0
                               &ppds->Colors)) < 0 ||
262
0
        (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8,
263
0
                               &bpc)) < 0 ||
264
0
        (bpc & (bpc - 1)) != 0 ||
265
0
        (code = dict_int_param(op, "Columns", 1, max_int, 1,
266
0
                               &ppds->Columns)) < 0
267
0
        )
268
0
        return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
269
0
    ppds->BitsPerComponent = bpc;
270
0
    return 0;
271
0
}
272
273
/* <target> <dict> PixelDifferenceEncode/filter <file> */
274
static int
275
zPDiffE(i_ctx_t *i_ctx_p)
276
0
{
277
0
    os_ptr op = osp;
278
0
    stream_PDiff_state pds;
279
0
    int code = zpd_setup(op, &pds);
280
281
0
    if (code < 0)
282
0
        return code;
283
0
    return filter_write(i_ctx_p, 0, &s_PDiffE_template, (stream_state *) & pds, 0);
284
0
}
285
286
/* <source> <dict> PixelDifferenceDecode/filter <file> */
287
static int
288
zPDiffD(i_ctx_t *i_ctx_p)
289
0
{
290
0
    os_ptr op = osp;
291
0
    stream_PDiff_state pds;
292
0
    int code = zpd_setup(op, &pds);
293
294
0
    if (code < 0)
295
0
        return code;
296
0
    return filter_read(i_ctx_p, 0, &s_PDiffD_template, (stream_state *) & pds, 0);
297
0
}
298
299
/* ------ PNG pixel predictor filters ------ */
300
301
/* Common setup for encoding and decoding filters. */
302
int
303
zpp_setup(os_ptr op, stream_PNGP_state * ppps)
304
0
{
305
0
    int code, bpc;
306
307
0
    check_type(*op, t_dictionary);
308
0
    check_dict_read(*op);
309
0
    if ((code = dict_int_param(op, "Colors", 1, s_PNG_max_Colors, 1,
310
0
                               &ppps->Colors)) < 0 ||
311
0
        (code = dict_int_param(op, "BitsPerComponent", 1, 16, 8,
312
0
                               &bpc)) < 0 ||
313
0
        (bpc & (bpc - 1)) != 0 ||
314
0
        (code = dict_uint_param(op, "Columns", 1, max_uint, 1,
315
0
                                &ppps->Columns)) < 0 ||
316
0
        (code = dict_int_param(op, "Predictor", 10, 15, 15,
317
0
                               &ppps->Predictor)) < 0
318
0
        )
319
0
        return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
320
0
    ppps->BitsPerComponent = bpc;
321
0
    return 0;
322
0
}
323
324
/* <target> <dict> PNGPredictorEncode/filter <file> */
325
static int
326
zPNGPE(i_ctx_t *i_ctx_p)
327
0
{
328
0
    os_ptr op = osp;
329
0
    stream_PNGP_state pps;
330
0
    int code = zpp_setup(op, &pps);
331
332
0
    if (code < 0)
333
0
        return code;
334
0
    return filter_write(i_ctx_p, 0, &s_PNGPE_template, (stream_state *) & pps, 0);
335
0
}
336
337
/* <source> <dict> PNGPredictorDecode/filter <file> */
338
static int
339
zPNGPD(i_ctx_t *i_ctx_p)
340
0
{
341
0
    os_ptr op = osp;
342
0
    stream_PNGP_state pps;
343
0
    int code = zpp_setup(op, &pps);
344
345
0
    if (code < 0)
346
0
        return code;
347
0
    return filter_read(i_ctx_p, 0, &s_PNGPD_template, (stream_state *) & pps, 0);
348
0
}
349
350
/* ---------------- Initialization procedure ---------------- */
351
352
const op_def zfdecode_op_defs[] = {
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(0)
363
};