Coverage Report

Created: 2025-06-10 07:06

/src/ghostpdl/psi/zfdctd.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
/* DCTDecode filter creation */
18
#include "memory_.h"
19
#include "stdio_.h"   /* for jpeglib.h */
20
#include "jpeglib_.h"
21
#include "ghost.h"
22
#include "oper.h"
23
#include "gsmemory.h"
24
#include "strimpl.h"
25
#include "sdct.h"
26
#include "sjpeg.h"
27
#include "ialloc.h"
28
#include "ifilter.h"
29
#include "iparam.h"
30
31
#include "igstate.h"  /* For igs macro */
32
#include "gxdevcli.h" /* for dev_spec_op */
33
#include "gxdevsop.h" /* For spec_op enumerated types */
34
35
private_st_jpeg_decompress_data();
36
37
/* Import the parameter processing procedure from sddparam.c */
38
stream_state_proc_put_params(s_DCTD_put_params, stream_DCT_state);
39
40
/* Find the memory that will be used for allocating the stream. */
41
static gs_ref_memory_t *
42
find_stream_memory(i_ctx_t *i_ctx_p, int npop, uint *space)
43
0
{
44
0
    uint use_space = max(*space, avm_global);
45
0
    os_ptr sop = osp - npop;
46
47
0
    if (r_has_type(sop, t_dictionary)) {
48
0
        --sop;
49
0
    }
50
0
    *space = max(use_space, r_space(sop));
51
52
0
    return idmemory->spaces_indexed[*space >> r_space_shift];
53
0
}
54
55
static int PS_DCTD_PassThrough(void *d, byte *Buffer, int Size)
56
0
{
57
0
    gx_device *dev = (gx_device *)d;
58
59
0
    if (Buffer == NULL) {
60
0
        if (Size == 0)
61
0
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_end, NULL, 0);
62
0
        else
63
0
            dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_begin, NULL, 0);
64
0
    } else {
65
0
        dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_data, Buffer, Size);
66
0
    }
67
0
    return 0;
68
0
}
69
70
/* <source> <dict> DCTDecode/filter <file> */
71
/* <source> DCTDecode/filter <file> */
72
static int
73
zDCTD(i_ctx_t *i_ctx_p)
74
0
{
75
0
    os_ptr op = osp;
76
0
    gs_memory_t *mem;
77
0
    stream_DCT_state state;
78
0
    dict_param_list list;
79
0
    jpeg_decompress_data *jddp;
80
0
    int code;
81
0
    const ref *dop;
82
0
    uint dspace;
83
0
    gx_device *dev = gs_currentdevice(igs);
84
85
0
    check_op(1);
86
0
    if (r_has_type(op, t_dictionary)) {
87
0
        dop = op, dspace = r_space(op);
88
0
        check_op(2);
89
0
    }
90
0
    else
91
0
        dop = 0, dspace = 0;
92
0
    mem = (gs_memory_t *)find_stream_memory(i_ctx_p, 0, &dspace);
93
0
    state.memory = mem;
94
    /* First allocate space for IJG parameters. */
95
0
    jddp = gs_alloc_struct_immovable(mem,jpeg_decompress_data,
96
0
      &st_jpeg_decompress_data, "zDCTD");
97
0
    if (jddp == 0)
98
0
        return_error(gs_error_VMerror);
99
0
    if (s_DCTD_template.set_defaults)
100
0
        (*s_DCTD_template.set_defaults) ((stream_state *) & state);
101
0
    state.data.decompress = jddp;
102
0
    jddp->memory = state.jpeg_memory = mem; /* set now for allocation */
103
0
    jddp->scanline_buffer = NULL; /* set this early for safe error exit */
104
0
    state.report_error = filter_report_error; /* in case create fails */
105
0
    if ((code = gs_jpeg_create_decompress(&state)) < 0)
106
0
        goto fail;   /* correct to do jpeg_destroy here */
107
    /* Read parameters from dictionary */
108
0
    if ((code = dict_param_list_read(&list, dop, NULL, false, iimemory)) < 0)
109
0
        goto fail;
110
0
    if ((code = s_DCTD_put_params((gs_param_list *) & list, &state)) < 0)
111
0
        goto rel;
112
113
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_JPEG_passthrough_query, NULL, 0) > 0) {
114
0
        jddp->StartedPassThrough = 0;
115
0
        jddp->PassThrough = 1;
116
0
        jddp->PassThroughfn = (PS_DCTD_PassThrough);
117
0
        jddp->device = (void *)dev;
118
0
    }
119
0
    else {
120
0
        jddp->PassThrough = 0;
121
0
        jddp->device = (void *)NULL;
122
0
    }
123
124
    /* Create the filter. */
125
0
    jddp->templat = s_DCTD_template;
126
0
    code = filter_read(i_ctx_p, 0, &jddp->templat,
127
0
                       (stream_state *) & state, dspace);
128
0
    if (code >= 0)   /* Success! */
129
0
        return code;
130
    /*
131
     * We assume that if filter_read fails, the stream has not been
132
     * registered for closing, so s_DCTD_release will never be called.
133
     * Therefore we free the allocated memory before failing.
134
     */
135
0
rel:
136
0
    iparam_list_release(&list);
137
0
fail:
138
0
    gs_jpeg_destroy(&state);
139
0
    gs_free_object(mem, jddp, "zDCTD fail");
140
0
    return code;
141
0
}
142
143
/* ------ Initialization procedure ------ */
144
145
const op_def zfdctd_op_defs[] =
146
{
147
    op_def_begin_filter(),
148
    {"2DCTDecode", zDCTD},
149
    op_def_end(0)
150
};