1 /* Copyright (C) 1998, 1999 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: sdeparam.c,v 1.6 2002/02/21 22:24:54 giles Exp $ */
18 /* DCTEncode filter parameter setting and reading */
19 #include "memory_.h"
20 #include "jpeglib_.h"
21 #include "gserror.h"
22 #include "gserrors.h"
23 #include "gstypes.h"
24 #include "gsmemory.h"
25 #include "gsparam.h"
26 #include "strimpl.h" /* sdct.h requires this */
27 #include "sdct.h"
28 #include "sdcparam.h"
29 #include "sjpeg.h"
30
31 /* Define a structure for the DCTEncode scalar parameters. */
32 typedef struct dcte_scalars_s {
33 int Columns;
34 int Rows;
35 int Colors;
36 gs_param_string Markers;
37 bool NoMarker;
38 int Resync;
39 int Blend;
40 } dcte_scalars_t;
41 private const dcte_scalars_t dcte_scalars_default =
42 {
43 0, 0, -1,
44 {0, 0}, 0 /*false */ , 0, 0
45 };
46 private const gs_param_item_t s_DCTE_param_items[] =
47 {
48 #define dctp(key, type, memb) { key, type, offset_of(dcte_scalars_t, memb) }
49 dctp("Columns", gs_param_type_int, Columns),
50 dctp("Rows", gs_param_type_int, Rows),
51 dctp("Colors", gs_param_type_int, Colors),
52 dctp("Marker", gs_param_type_string, Markers),
53 dctp("NoMarker", gs_param_type_bool, NoMarker),
54 dctp("Resync", gs_param_type_int, Resync),
55 dctp("Blend", gs_param_type_int, Blend),
56 #undef dctp
57 gs_param_item_end
58 };
59
60 /* ================ Get parameters ================ */
61
62 stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state); /* check */
63
64 /* Get a set of sampling values. */
65 private int
dcte_get_samples(gs_param_list * plist,gs_param_name key,int num_colors,const jpeg_compress_data * jcdp,gs_memory_t * mem,bool is_vert,bool all)66 dcte_get_samples(gs_param_list * plist, gs_param_name key, int num_colors,
67 const jpeg_compress_data * jcdp, gs_memory_t * mem, bool is_vert, bool all)
68 {
69 const jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
70 int samples[4];
71 bool write = all;
72 int i;
73
74 for (i = 0; i < num_colors; ++i)
75 write |= (samples[i] = (is_vert ? comp_info[i].v_samp_factor :
76 comp_info[i].h_samp_factor)) != 1;
77 if (write) {
78 int *data = (int *)gs_alloc_byte_array(mem, num_colors, sizeof(int),
79 "dcte_get_samples");
80 gs_param_int_array sa;
81
82 if (data == 0)
83 return_error(gs_error_VMerror);
84 sa.data = data;
85 sa.size = num_colors;
86 sa.persistent = true;
87 memcpy(data, samples, num_colors * sizeof(samples[0]));
88 return param_write_int_array(plist, key, &sa);
89 }
90 return 0;
91 }
92
93 int
s_DCTE_get_params(gs_param_list * plist,const stream_DCT_state * ss,bool all)94 s_DCTE_get_params(gs_param_list * plist, const stream_DCT_state * ss, bool all)
95 {
96 gs_memory_t *mem = ss->memory;
97 stream_DCT_state dcts_defaults;
98 const stream_DCT_state *defaults = 0;
99 dcte_scalars_t params;
100 const jpeg_compress_data *jcdp = ss->data.compress;
101 int code;
102
103 if (!all) {
104 jpeg_compress_data *jcdp_default = gs_alloc_struct_immovable(mem,
105 jpeg_compress_data, &st_jpeg_compress_data, "s_DCTE_get_params");
106 if (jcdp_default == 0)
107 return_error(gs_error_VMerror);
108 defaults = &dcts_defaults;
109 (*s_DCTE_template.set_defaults) ((stream_state *) & dcts_defaults);
110 dcts_defaults.data.compress = jcdp_default;
111 jcdp_default->memory = dcts_defaults.jpeg_memory = mem;
112 if ((code = gs_jpeg_create_compress(&dcts_defaults)) < 0)
113 goto fail; /* correct to do jpeg_destroy here */
114 /****** SET DEFAULTS HERE ******/
115 dcts_defaults.data.common->Picky = 0;
116 dcts_defaults.data.common->Relax = 0;
117 }
118 params.Columns = jcdp->cinfo.image_width;
119 params.Rows = jcdp->cinfo.image_height;
120 params.Colors = jcdp->cinfo.input_components;
121 params.Markers.data = ss->Markers.data;
122 params.Markers.size = ss->Markers.size;
123 params.Markers.persistent = false;
124 params.NoMarker = ss->NoMarker;
125 params.Resync = jcdp->cinfo.restart_interval;
126 /* What about Blend?? */
127 if ((code = s_DCT_get_params(plist, ss, defaults)) < 0 ||
128 (code = gs_param_write_items(plist, ¶ms,
129 &dcte_scalars_default,
130 s_DCTE_param_items)) < 0 ||
131 (code = dcte_get_samples(plist, "HSamples", params.Colors,
132 jcdp, mem, false, all)) < 0 ||
133 (code = dcte_get_samples(plist, "VSamples", params.Colors,
134 jcdp, mem, true, all)) < 0 ||
135 (code = s_DCT_get_quantization_tables(plist, ss, defaults, true)) < 0 ||
136 (code = s_DCT_get_huffman_tables(plist, ss, defaults, true)) < 0
137 )
138 DO_NOTHING;
139 /****** NYI ******/
140 fail:if (defaults) {
141 gs_jpeg_destroy(&dcts_defaults);
142 gs_free_object(mem, dcts_defaults.data.compress,
143 "s_DCTE_get_params");
144 }
145 return code;
146 }
147
148 /* ================ Put parameters ================ */
149
150 stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state); /* check */
151
152 /* Put a set of sampling values. */
153 private int
dcte_put_samples(gs_param_list * plist,gs_param_name key,int num_colors,jpeg_compress_data * jcdp,bool is_vert)154 dcte_put_samples(gs_param_list * plist, gs_param_name key, int num_colors,
155 jpeg_compress_data * jcdp, bool is_vert)
156 {
157 int code;
158 int i;
159 jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
160 UINT8 samples[4];
161
162 /*
163 * Adobe default is all sampling factors = 1,
164 * which is NOT the IJG default, so we must always assign values.
165 */
166 switch ((code = s_DCT_byte_params(plist, key, 0, num_colors,
167 samples))
168 ) {
169 default: /* error */
170 return code;
171 case 0:
172 break;
173 case 1:
174 samples[0] = samples[1] = samples[2] = samples[3] = 1;
175 }
176 for (i = 0; i < num_colors; i++) {
177 if (samples[i] < 1 || samples[i] > 4)
178 return_error(gs_error_rangecheck);
179 if (is_vert)
180 comp_info[i].v_samp_factor = samples[i];
181 else
182 comp_info[i].h_samp_factor = samples[i];
183 }
184 return 0;
185 }
186
187 /* Main procedure */
188 int
s_DCTE_put_params(gs_param_list * plist,stream_DCT_state * pdct)189 s_DCTE_put_params(gs_param_list * plist, stream_DCT_state * pdct)
190 {
191 jpeg_compress_data *jcdp = pdct->data.compress;
192 dcte_scalars_t params;
193 int i;
194 int code;
195
196 params = dcte_scalars_default;
197 /*
198 * Required parameters for DCTEncode.
199 * (DCTDecode gets the equivalent info from the SOF marker.)
200 */
201 code = gs_param_read_items(plist, ¶ms, s_DCTE_param_items);
202 if (code < 0)
203 return code;
204 if (params.Columns <= 0 || params.Columns > 0xffff ||
205 params.Rows <= 0 || params.Rows > 0xffff ||
206 params.Colors <= 0 || params.Colors == 2 || params.Colors > 4 ||
207 params.Resync < 0 || params.Resync > 0xffff ||
208 params.Blend < 0 || params.Blend > 1
209 )
210 return_error(gs_error_rangecheck);
211 jcdp->Picky = 0;
212 jcdp->Relax = 0;
213 if ((code = s_DCT_put_params(plist, pdct)) < 0)
214 return code;
215 /* Set up minimal image description & call set_defaults */
216 jcdp->cinfo.image_width = params.Columns;
217 jcdp->cinfo.image_height = params.Rows;
218 jcdp->cinfo.input_components = params.Colors;
219 switch (params.Colors) {
220 case 1:
221 jcdp->cinfo.in_color_space = JCS_GRAYSCALE;
222 break;
223 case 3:
224 jcdp->cinfo.in_color_space = JCS_RGB;
225 break;
226 case 4:
227 jcdp->cinfo.in_color_space = JCS_CMYK;
228 break;
229 default:
230 jcdp->cinfo.in_color_space = JCS_UNKNOWN;
231 }
232 if ((code = gs_jpeg_set_defaults(pdct)) < 0)
233 return code;
234 if ((code = s_DCT_put_huffman_tables(plist, pdct, false)) < 0)
235 return code;
236 switch ((code = s_DCT_put_quantization_tables(plist, pdct, false))) {
237 case 0:
238 break;
239 default:
240 return code;
241 case 1:
242 /* No QuantTables, but maybe a QFactor to apply to default. */
243 if (pdct->QFactor != 1.0) {
244 code = gs_jpeg_set_linear_quality(pdct,
245 (int)(min(pdct->QFactor, 100.0)
246 * 100.0 + 0.5),
247 TRUE);
248 if (code < 0)
249 return code;
250 }
251 }
252 /* Change IJG colorspace defaults as needed;
253 * set ColorTransform to what will go in the Adobe marker.
254 */
255 switch (params.Colors) {
256 case 3:
257 if (pdct->ColorTransform < 0)
258 pdct->ColorTransform = 1; /* default */
259 if (pdct->ColorTransform == 0) {
260 if ((code = gs_jpeg_set_colorspace(pdct, JCS_RGB)) < 0)
261 return code;
262 } else
263 pdct->ColorTransform = 1; /* flag YCC xform */
264 break;
265 case 4:
266 if (pdct->ColorTransform < 0)
267 pdct->ColorTransform = 0; /* default */
268 if (pdct->ColorTransform != 0) {
269 if ((code = gs_jpeg_set_colorspace(pdct, JCS_YCCK)) < 0)
270 return code;
271 pdct->ColorTransform = 2; /* flag YCCK xform */
272 } else {
273 if ((code = gs_jpeg_set_colorspace(pdct, JCS_CMYK)) < 0)
274 return code;
275 }
276 break;
277 default:
278 pdct->ColorTransform = 0; /* no transform otherwise */
279 break;
280 }
281 /* Optional encoding-only parameters */
282 pdct->Markers.data = params.Markers.data;
283 pdct->Markers.size = params.Markers.size;
284 pdct->NoMarker = params.NoMarker;
285 if ((code = dcte_put_samples(plist, "HSamples", params.Colors,
286 jcdp, false)) < 0 ||
287 (code = dcte_put_samples(plist, "VSamples", params.Colors,
288 jcdp, true)) < 0
289 )
290 return code;
291 jcdp->cinfo.write_JFIF_header = FALSE;
292 jcdp->cinfo.write_Adobe_marker = FALSE; /* must do it myself */
293 jcdp->cinfo.restart_interval = params.Resync;
294 /* What to do with Blend ??? */
295 if (pdct->data.common->Relax == 0) {
296 jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
297 int num_samples;
298
299 for (i = 0, num_samples = 0; i < params.Colors; i++)
300 num_samples += comp_info[i].h_samp_factor *
301 comp_info[i].v_samp_factor;
302 if (num_samples > 10)
303 return_error(gs_error_rangecheck);
304 /*
305 * Note: by default the IJG software does not allow
306 * num_samples to exceed 10, Relax or no. For full
307 * compatibility with Adobe's non-JPEG-compliant
308 * software, set MAX_BLOCKS_IN_MCU to 64 in jpeglib.h.
309 */
310 }
311 return 0;
312 }
313