Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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, &params,
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
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
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, &params, 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
}