2 Copyright 1993-2002 by Easy Software Products.
3 Copyright 1998 Aladdin Enterprises. All rights reserved.
5 This file is part of GNU Ghostscript.
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.
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
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.
29 /*$Id: sdeparam.c,v 1.4 2002/01/02 17:59:12 mike Exp $ */
30 /* DCTEncode filter parameter setting and reading */
38 #include "strimpl.h" /* sdct.h requires this */
43 /* Define a structure for the DCTEncode scalar parameters. */
44 typedef struct dcte_scalars_s
{
48 gs_param_string Markers
;
53 private const dcte_scalars_t dcte_scalars_default
=
56 {0, 0}, 0 /*false */ , 0, 0
58 private const gs_param_item_t s_DCTE_param_items
[] =
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
),
72 /* ================ Get parameters ================ */
74 stream_state_proc_get_params(s_DCTE_get_params
, stream_DCT_state
); /* check */
76 /* Get a set of sampling values. */
78 dcte_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
)
81 const jpeg_component_info
*comp_info
= jcdp
->cinfo
.comp_info
;
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;
90 int *data
= (int *)gs_alloc_byte_array(mem
, num_colors
, sizeof(int),
92 gs_param_int_array sa
;
95 return_error(gs_error_VMerror
);
99 memcpy(data
, samples
, num_colors
* sizeof(samples
[0]));
100 return param_write_int_array(plist
, key
, &sa
);
106 s_DCTE_get_params(gs_param_list
* plist
, const stream_DCT_state
* ss
, bool all
)
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
;
116 jpeg_compress_data
*jcdp_default
=
117 (jpeg_compress_data
*)
118 gs_alloc_bytes_immovable(mem
, sizeof(*jcdp
), "s_DCTE_get_params");
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;
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
, ¶ms
,
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
155 gs_jpeg_destroy(&dcts_defaults
);
156 gs_free_object(mem
, dcts_defaults
.data
.compress
,
157 "s_DCTE_get_params");
162 /* ================ Put parameters ================ */
164 stream_state_proc_put_params(s_DCTE_put_params
, stream_DCT_state
); /* check */
166 /* Put a set of sampling values. */
168 dcte_put_samples(gs_param_list
* plist
, gs_param_name key
, int num_colors
,
169 jpeg_compress_data
* jcdp
, bool is_vert
)
173 jpeg_component_info
*comp_info
= jcdp
->cinfo
.comp_info
;
177 * Adobe default is all sampling factors = 1,
178 * which is NOT the IJG default, so we must always assign values.
180 switch ((code
= s_DCT_byte_params(plist
, key
, 0, num_colors
,
188 samples
[0] = samples
[1] = samples
[2] = samples
[3] = 1;
190 for (i
= 0; i
< num_colors
; i
++) {
191 if (samples
[i
] < 1 || samples
[i
] > 4)
192 return_error(gs_error_rangecheck
);
194 comp_info
[i
].v_samp_factor
= samples
[i
];
196 comp_info
[i
].h_samp_factor
= samples
[i
];
203 s_DCTE_put_params(gs_param_list
* plist
, stream_DCT_state
* pdct
)
205 jpeg_compress_data
*jcdp
= pdct
->data
.compress
;
206 dcte_scalars_t params
;
210 params
= dcte_scalars_default
;
212 * Required parameters for DCTEncode.
213 * (DCTDecode gets the equivalent info from the SOF marker.)
215 code
= gs_param_read_items(plist
, ¶ms
, s_DCTE_param_items
);
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
224 return_error(gs_error_rangecheck
);
225 /****** HACK: SET DEFAULTS HERE ******/
228 if ((code
= s_DCT_put_params(plist
, pdct
)) < 0 ||
229 (code
= s_DCT_put_huffman_tables(plist
, pdct
, false)) < 0
232 switch ((code
= s_DCT_put_quantization_tables(plist
, pdct
, false))) {
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)
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
) {
254 jcdp
->cinfo
.in_color_space
= JCS_GRAYSCALE
;
257 jcdp
->cinfo
.in_color_space
= JCS_RGB
;
260 jcdp
->cinfo
.in_color_space
= JCS_CMYK
;
263 jcdp
->cinfo
.in_color_space
= JCS_UNKNOWN
;
265 if ((code
= gs_jpeg_set_defaults(pdct
)) < 0)
267 /* Change IJG colorspace defaults as needed;
268 * set ColorTransform to what will go in the Adobe marker.
270 switch (params
.Colors
) {
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)
278 pdct
->ColorTransform
= 1; /* flag YCC xform */
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)
286 pdct
->ColorTransform
= 2; /* flag YCCK xform */
288 if ((code
= gs_jpeg_set_colorspace(pdct
, JCS_CMYK
)) < 0)
293 pdct
->ColorTransform
= 0; /* no transform otherwise */
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
,
302 (code
= dcte_put_samples(plist
, "VSamples", params
.Colors
,
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
;
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
);
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.
328 #endif /* HAVE_LIBJPEG */