]> git.ipfire.org Git - thirdparty/cups.git/blame - pstoraster/sdeparam.c
Copyright update...
[thirdparty/cups.git] / pstoraster / sdeparam.c
CommitLineData
c153bcda 1/*
efb2f309 2 Copyright 1993-2002 by Easy Software Products.
c153bcda 3 Copyright 1998 Aladdin Enterprises. All rights reserved.
caddbb58 4
5 This file is part of GNU Ghostscript.
6
7 GNU Ghostscript is distributed in the hope that it will be useful, but
8 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
9 to anyone for the consequences of using it or for whether it serves any
10 particular purpose or works at all, unless he says so in writing. Refer
11 to the GNU General Public License for full details.
12
13 Everyone is granted permission to copy, modify and redistribute GNU
14 Ghostscript, but only under the conditions described in the GNU General
15 Public License. A copy of this license is supposed to have been given
16 to you along with GNU Ghostscript so you can know your rights and
17 responsibilities. It should be in a file named COPYING. Among other
18 things, the copyright notice and this notice must be preserved on all
19 copies.
20
21 Aladdin Enterprises supports the work of the GNU Project, but is not
22 affiliated with the Free Software Foundation or the GNU Project. GNU
23 Ghostscript, as distributed by Aladdin Enterprises, does not require any
24 GNU software to build or run it.
25*/
26
c153bcda 27#include <config.h>
28#ifdef HAVE_LIBJPEG
efb2f309 29/*$Id: sdeparam.c,v 1.4 2002/01/02 17:59:12 mike Exp $ */
caddbb58 30/* DCTEncode filter parameter setting and reading */
31#include "memory_.h"
32#include "jpeglib.h"
33#include "gserror.h"
34#include "gserrors.h"
35#include "gstypes.h"
36#include "gsmemory.h"
37#include "gsparam.h"
38#include "strimpl.h" /* sdct.h requires this */
39#include "sdct.h"
40#include "sdcparam.h"
41#include "sjpeg.h"
42
43/* Define a structure for the DCTEncode scalar parameters. */
44typedef struct dcte_scalars_s {
45 int Columns;
46 int Rows;
47 int Colors;
48 gs_param_string Markers;
49 bool NoMarker;
50 int Resync;
51 int Blend;
52} dcte_scalars_t;
53private const dcte_scalars_t dcte_scalars_default =
54{
55 0, 0, -1,
56 {0, 0}, 0 /*false */ , 0, 0
57};
58private const gs_param_item_t s_DCTE_param_items[] =
59{
60#define dctp(key, type, memb) { key, type, offset_of(dcte_scalars_t, memb) }
61 dctp("Columns", gs_param_type_int, Columns),
62 dctp("Rows", gs_param_type_int, Rows),
63 dctp("Colors", gs_param_type_int, Colors),
64 dctp("Marker", gs_param_type_string, Markers),
65 dctp("NoMarker", gs_param_type_bool, NoMarker),
66 dctp("Resync", gs_param_type_int, Resync),
67 dctp("Blend", gs_param_type_int, Blend),
68#undef dctp
69 gs_param_item_end
70};
71
72/* ================ Get parameters ================ */
73
74stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state); /* check */
75
76/* Get a set of sampling values. */
77private int
78dcte_get_samples(gs_param_list * plist, gs_param_name key, int num_colors,
79 const jpeg_compress_data * jcdp, gs_memory_t * mem, bool is_vert, bool all)
80{
81 const jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
82 int samples[4];
83 bool write = all;
84 int i;
85
86 for (i = 0; i < num_colors; ++i)
87 write |= (samples[i] = (is_vert ? comp_info[i].v_samp_factor :
88 comp_info[i].h_samp_factor)) != 1;
89 if (write) {
90 int *data = (int *)gs_alloc_byte_array(mem, num_colors, sizeof(int),
91 "dcte_get_samples");
92 gs_param_int_array sa;
93
94 if (data == 0)
95 return_error(gs_error_VMerror);
96 sa.data = data;
97 sa.size = num_colors;
98 sa.persistent = true;
99 memcpy(data, samples, num_colors * sizeof(samples[0]));
100 return param_write_int_array(plist, key, &sa);
101 }
102 return 0;
103}
104
105int
106s_DCTE_get_params(gs_param_list * plist, const stream_DCT_state * ss, bool all)
107{
108 gs_memory_t *mem = ss->memory;
109 stream_DCT_state dcts_defaults;
110 const stream_DCT_state *defaults = 0;
111 dcte_scalars_t params;
112 const jpeg_compress_data *jcdp = ss->data.compress;
113 int code;
114
115 if (!all) {
116 jpeg_compress_data *jcdp_default =
117 (jpeg_compress_data *)
118 gs_alloc_bytes_immovable(mem, sizeof(*jcdp), "s_DCTE_get_params");
119
120 if (jcdp_default == 0)
121 return_error(gs_error_VMerror);
122 defaults = &dcts_defaults;
123 (*s_DCTE_template.set_defaults) ((stream_state *) & dcts_defaults);
124 dcts_defaults.data.compress = jcdp_default;
125 jcdp_default->memory = dcts_defaults.jpeg_memory = mem;
126 if ((code = gs_jpeg_create_compress(&dcts_defaults)) < 0)
127 goto fail; /* correct to do jpeg_destroy here */
128/****** SET DEFAULTS HERE ******/
129 dcts_defaults.data.common->Picky = 0;
130 dcts_defaults.data.common->Relax = 0;
131 }
132 params.Columns = jcdp->cinfo.image_width;
133 params.Rows = jcdp->cinfo.image_height;
134 params.Colors = jcdp->cinfo.input_components;
135 params.Markers.data = ss->Markers.data;
136 params.Markers.size = ss->Markers.size;
137 params.Markers.persistent = false;
138 params.NoMarker = ss->NoMarker;
139 params.Resync = jcdp->cinfo.restart_interval;
140 /* What about Blend?? */
141 if ((code = s_DCT_get_params(plist, ss, defaults)) < 0 ||
142 (code = gs_param_write_items(plist, &params,
143 &dcte_scalars_default,
144 s_DCTE_param_items)) < 0 ||
145 (code = dcte_get_samples(plist, "HSamples", params.Colors,
146 jcdp, mem, false, all)) < 0 ||
147 (code = dcte_get_samples(plist, "VSamples", params.Colors,
148 jcdp, mem, true, all)) < 0 ||
149 (code = s_DCT_get_quantization_tables(plist, ss, defaults, true)) < 0 ||
150 (code = s_DCT_get_huffman_tables(plist, ss, defaults, true)) < 0
151 )
152 DO_NOTHING;
153/****** NYI ******/
154 fail:if (defaults) {
155 gs_jpeg_destroy(&dcts_defaults);
156 gs_free_object(mem, dcts_defaults.data.compress,
157 "s_DCTE_get_params");
158 }
159 return code;
160}
161
162/* ================ Put parameters ================ */
163
164stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state); /* check */
165
166/* Put a set of sampling values. */
167private int
168dcte_put_samples(gs_param_list * plist, gs_param_name key, int num_colors,
169 jpeg_compress_data * jcdp, bool is_vert)
170{
171 int code;
172 int i;
173 jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
174 UINT8 samples[4];
175
176 /*
177 * Adobe default is all sampling factors = 1,
178 * which is NOT the IJG default, so we must always assign values.
179 */
180 switch ((code = s_DCT_byte_params(plist, key, 0, num_colors,
181 samples))
182 ) {
183 default: /* error */
184 return code;
185 case 0:
186 break;
187 case 1:
188 samples[0] = samples[1] = samples[2] = samples[3] = 1;
189 }
190 for (i = 0; i < num_colors; i++) {
191 if (samples[i] < 1 || samples[i] > 4)
192 return_error(gs_error_rangecheck);
193 if (is_vert)
194 comp_info[i].v_samp_factor = samples[i];
195 else
196 comp_info[i].h_samp_factor = samples[i];
197 }
198 return 0;
199}
200
201/* Main procedure */
202int
203s_DCTE_put_params(gs_param_list * plist, stream_DCT_state * pdct)
204{
205 jpeg_compress_data *jcdp = pdct->data.compress;
206 dcte_scalars_t params;
207 int i;
208 int code;
209
210 params = dcte_scalars_default;
211 /*
212 * Required parameters for DCTEncode.
213 * (DCTDecode gets the equivalent info from the SOF marker.)
214 */
215 code = gs_param_read_items(plist, &params, s_DCTE_param_items);
216 if (code < 0)
217 return code;
218 if (params.Columns <= 0 || params.Columns > 0xffff ||
219 params.Rows <= 0 || params.Rows > 0xffff ||
220 params.Colors <= 0 || params.Colors == 2 || params.Colors > 4 ||
221 params.Resync < 0 || params.Resync > 0xffff ||
222 params.Blend < 0 || params.Blend > 1
223 )
224 return_error(gs_error_rangecheck);
225/****** HACK: SET DEFAULTS HERE ******/
226 jcdp->Picky = 0;
227 jcdp->Relax = 0;
228 if ((code = s_DCT_put_params(plist, pdct)) < 0 ||
229 (code = s_DCT_put_huffman_tables(plist, pdct, false)) < 0
230 )
231 return code;
232 switch ((code = s_DCT_put_quantization_tables(plist, pdct, false))) {
233 case 0:
234 break;
235 default:
236 return code;
237 case 1:
238 /* No QuantTables, but maybe a QFactor to apply to default. */
239 if (pdct->QFactor != 1.0) {
240 code = gs_jpeg_set_linear_quality(pdct,
241 (int)(min(pdct->QFactor, 100.0)
242 * 100.0 + 0.5),
243 TRUE);
244 if (code < 0)
245 return code;
246 }
247 }
248 /* Set up minimal image description & call set_defaults */
249 jcdp->cinfo.image_width = params.Columns;
250 jcdp->cinfo.image_height = params.Rows;
251 jcdp->cinfo.input_components = params.Colors;
252 switch (params.Colors) {
253 case 1:
254 jcdp->cinfo.in_color_space = JCS_GRAYSCALE;
255 break;
256 case 3:
257 jcdp->cinfo.in_color_space = JCS_RGB;
258 break;
259 case 4:
260 jcdp->cinfo.in_color_space = JCS_CMYK;
261 break;
262 default:
263 jcdp->cinfo.in_color_space = JCS_UNKNOWN;
264 }
265 if ((code = gs_jpeg_set_defaults(pdct)) < 0)
266 return code;
267 /* Change IJG colorspace defaults as needed;
268 * set ColorTransform to what will go in the Adobe marker.
269 */
270 switch (params.Colors) {
271 case 3:
272 if (pdct->ColorTransform < 0)
273 pdct->ColorTransform = 1; /* default */
274 if (pdct->ColorTransform == 0) {
275 if ((code = gs_jpeg_set_colorspace(pdct, JCS_RGB)) < 0)
276 return code;
277 } else
278 pdct->ColorTransform = 1; /* flag YCC xform */
279 break;
280 case 4:
281 if (pdct->ColorTransform < 0)
282 pdct->ColorTransform = 0; /* default */
283 if (pdct->ColorTransform != 0) {
284 if ((code = gs_jpeg_set_colorspace(pdct, JCS_YCCK)) < 0)
285 return code;
286 pdct->ColorTransform = 2; /* flag YCCK xform */
287 } else {
288 if ((code = gs_jpeg_set_colorspace(pdct, JCS_CMYK)) < 0)
289 return code;
290 }
291 break;
292 default:
293 pdct->ColorTransform = 0; /* no transform otherwise */
294 break;
295 }
296 /* Optional encoding-only parameters */
297 pdct->Markers.data = params.Markers.data;
298 pdct->Markers.size = params.Markers.size;
299 pdct->NoMarker = params.NoMarker;
300 if ((code = dcte_put_samples(plist, "HSamples", params.Colors,
301 jcdp, false)) < 0 ||
302 (code = dcte_put_samples(plist, "VSamples", params.Colors,
303 jcdp, true)) < 0
304 )
305 return code;
306 jcdp->cinfo.write_JFIF_header = FALSE;
307 jcdp->cinfo.write_Adobe_marker = FALSE; /* must do it myself */
308 jcdp->cinfo.restart_interval = params.Resync;
309 /* What to do with Blend ??? */
310 if (pdct->data.common->Relax == 0) {
311 jpeg_component_info *comp_info = jcdp->cinfo.comp_info;
312 int num_samples;
313
314 for (i = 0, num_samples = 0; i < params.Colors; i++)
315 num_samples += comp_info[i].h_samp_factor *
316 comp_info[i].v_samp_factor;
317 if (num_samples > 10)
318 return_error(gs_error_rangecheck);
319 /*
320 * Note: by default the IJG software does not allow
321 * num_samples to exceed 10, Relax or no. For full
322 * compatibility with Adobe's non-JPEG-compliant
323 * software, set MAX_BLOCKS_IN_MCU to 64 in jpeglib.h.
324 */
325 }
326 return 0;
327}
c153bcda 328#endif /* HAVE_LIBJPEG */