/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 | | }; |