Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/jpeg/jdsample.c
4389 views
1
/*
2
* jdsample.c
3
*
4
* Copyright (C) 1991-1996, Thomas G. Lane.
5
* Modified 2002-2020 by Guido Vollbeding.
6
* This file is part of the Independent JPEG Group's software.
7
* For conditions of distribution and use, see the accompanying README file.
8
*
9
* This file contains upsampling routines.
10
*
11
* Upsampling input data is counted in "row groups". A row group
12
* is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
13
* sample rows of each component. Upsampling will normally produce
14
* max_v_samp_factor pixel rows from each row group (but this could vary
15
* if the upsampler is applying a scale factor of its own).
16
*
17
* An excellent reference for image resampling is
18
* Digital Image Warping, George Wolberg, 1990.
19
* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
20
*/
21
22
#define JPEG_INTERNALS
23
#include "jinclude.h"
24
#include "jpeglib.h"
25
26
27
/* Pointer to routine to upsample a single component */
28
typedef JMETHOD(void, upsample1_ptr,
29
(j_decompress_ptr cinfo, jpeg_component_info * compptr,
30
JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr));
31
32
/* Private subobject */
33
34
typedef struct {
35
struct jpeg_upsampler pub; /* public fields */
36
37
/* Color conversion buffer. When using separate upsampling and color
38
* conversion steps, this buffer holds one upsampled row group until it
39
* has been color converted and output.
40
* Note: we do not allocate any storage for component(s) which are full-size,
41
* ie do not need rescaling. The corresponding entry of color_buf[] is
42
* simply set to point to the input data array, thereby avoiding copying.
43
*/
44
JSAMPARRAY color_buf[MAX_COMPONENTS];
45
46
/* Per-component upsampling method pointers */
47
upsample1_ptr methods[MAX_COMPONENTS];
48
49
int next_row_out; /* counts rows emitted from color_buf */
50
JDIMENSION rows_to_go; /* counts rows remaining in image */
51
52
/* Height of an input row group for each component. */
53
int rowgroup_height[MAX_COMPONENTS];
54
55
/* These arrays save pixel expansion factors so that int_expand need not
56
* recompute them each time. They are unused for other upsampling methods.
57
*/
58
UINT8 h_expand[MAX_COMPONENTS];
59
UINT8 v_expand[MAX_COMPONENTS];
60
} my_upsampler;
61
62
typedef my_upsampler * my_upsample_ptr;
63
64
65
/*
66
* Initialize for an upsampling pass.
67
*/
68
69
METHODDEF(void)
70
start_pass_upsample (j_decompress_ptr cinfo)
71
{
72
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
73
74
/* Mark the conversion buffer empty */
75
upsample->next_row_out = cinfo->max_v_samp_factor;
76
/* Initialize total-height counter for detecting bottom of image */
77
upsample->rows_to_go = cinfo->output_height;
78
}
79
80
81
/*
82
* Control routine to do upsampling (and color conversion).
83
*
84
* In this version we upsample each component independently.
85
* We upsample one row group into the conversion buffer, then apply
86
* color conversion a row at a time.
87
*/
88
89
METHODDEF(void)
90
sep_upsample (j_decompress_ptr cinfo,
91
JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
92
JDIMENSION in_row_groups_avail,
93
JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
94
JDIMENSION out_rows_avail)
95
{
96
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
97
int ci;
98
jpeg_component_info * compptr;
99
JDIMENSION num_rows;
100
101
/* Fill the conversion buffer, if it's empty */
102
if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
103
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
104
ci++, compptr++) {
105
/* Don't bother to upsample an uninteresting component. */
106
if (! compptr->component_needed)
107
continue;
108
/* Invoke per-component upsample method. Notice we pass a POINTER
109
* to color_buf[ci], so that fullsize_upsample can change it.
110
*/
111
(*upsample->methods[ci]) (cinfo, compptr,
112
input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
113
upsample->color_buf + ci);
114
}
115
upsample->next_row_out = 0;
116
}
117
118
/* Color-convert and emit rows */
119
120
/* How many we have in the buffer: */
121
num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
122
/* Not more than the distance to the end of the image. Need this test
123
* in case the image height is not a multiple of max_v_samp_factor:
124
*/
125
if (num_rows > upsample->rows_to_go)
126
num_rows = upsample->rows_to_go;
127
/* And not more than what the client can accept: */
128
out_rows_avail -= *out_row_ctr;
129
if (num_rows > out_rows_avail)
130
num_rows = out_rows_avail;
131
132
(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
133
(JDIMENSION) upsample->next_row_out,
134
output_buf + *out_row_ctr,
135
(int) num_rows);
136
137
/* Adjust counts */
138
*out_row_ctr += num_rows;
139
upsample->rows_to_go -= num_rows;
140
upsample->next_row_out += num_rows;
141
/* When the buffer is emptied, declare this input row group consumed */
142
if (upsample->next_row_out >= cinfo->max_v_samp_factor)
143
(*in_row_group_ctr)++;
144
}
145
146
147
/*
148
* These are the routines invoked by sep_upsample to upsample pixel values
149
* of a single component. One row group is processed per call.
150
*/
151
152
153
/*
154
* For full-size components, we just make color_buf[ci] point at the
155
* input buffer, and thus avoid copying any data. Note that this is
156
* safe only because sep_upsample doesn't declare the input row group
157
* "consumed" until we are done color converting and emitting it.
158
*/
159
160
METHODDEF(void)
161
fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
162
JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr)
163
{
164
*output_data_ptr = input_data;
165
}
166
167
168
/*
169
* This version handles any integral sampling ratios.
170
* This is not used for typical JPEG files, so it need not be fast.
171
* Nor, for that matter, is it particularly accurate: the algorithm is
172
* simple replication of the input pixel onto the corresponding output
173
* pixels. The hi-falutin sampling literature refers to this as a
174
* "box filter". A box filter tends to introduce visible artifacts,
175
* so if you are actually going to use 3:1 or 4:1 sampling ratios
176
* you would be well advised to improve this code.
177
*/
178
179
METHODDEF(void)
180
int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
181
JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr)
182
{
183
my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
184
JSAMPARRAY output_data, output_end;
185
register JSAMPROW inptr, outptr;
186
register JSAMPLE invalue;
187
register int h;
188
JSAMPROW outend;
189
int h_expand, v_expand;
190
191
h_expand = upsample->h_expand[compptr->component_index];
192
v_expand = upsample->v_expand[compptr->component_index];
193
194
output_data = *output_data_ptr;
195
output_end = output_data + cinfo->max_v_samp_factor;
196
for (; output_data < output_end; output_data += v_expand) {
197
/* Generate one output row with proper horizontal expansion */
198
inptr = *input_data++;
199
outptr = *output_data;
200
outend = outptr + cinfo->output_width;
201
while (outptr < outend) {
202
invalue = *inptr++; /* don't need GETJSAMPLE() here */
203
for (h = h_expand; h > 0; h--) {
204
*outptr++ = invalue;
205
}
206
}
207
/* Generate any additional output rows by duplicating the first one */
208
if (v_expand > 1) {
209
jcopy_sample_rows(output_data, output_data + 1,
210
v_expand - 1, cinfo->output_width);
211
}
212
}
213
}
214
215
216
/*
217
* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
218
* It's still a box filter.
219
*/
220
221
METHODDEF(void)
222
h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
223
JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr)
224
{
225
JSAMPARRAY output_data = *output_data_ptr;
226
register JSAMPROW inptr, outptr;
227
register JSAMPLE invalue;
228
JSAMPROW outend;
229
int outrow;
230
231
for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) {
232
inptr = input_data[outrow];
233
outptr = output_data[outrow];
234
outend = outptr + cinfo->output_width;
235
while (outptr < outend) {
236
invalue = *inptr++; /* don't need GETJSAMPLE() here */
237
*outptr++ = invalue;
238
*outptr++ = invalue;
239
}
240
}
241
}
242
243
244
/*
245
* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
246
* It's still a box filter.
247
*/
248
249
METHODDEF(void)
250
h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
251
JSAMPARRAY input_data, JSAMPIMAGE output_data_ptr)
252
{
253
JSAMPARRAY output_data, output_end;
254
register JSAMPROW inptr, outptr;
255
register JSAMPLE invalue;
256
JSAMPROW outend;
257
258
output_data = *output_data_ptr;
259
output_end = output_data + cinfo->max_v_samp_factor;
260
for (; output_data < output_end; output_data += 2) {
261
inptr = *input_data++;
262
outptr = *output_data;
263
outend = outptr + cinfo->output_width;
264
while (outptr < outend) {
265
invalue = *inptr++; /* don't need GETJSAMPLE() here */
266
*outptr++ = invalue;
267
*outptr++ = invalue;
268
}
269
jcopy_sample_rows(output_data, output_data + 1,
270
1, cinfo->output_width);
271
}
272
}
273
274
275
/*
276
* Module initialization routine for upsampling.
277
*/
278
279
GLOBAL(void)
280
jinit_upsampler (j_decompress_ptr cinfo)
281
{
282
my_upsample_ptr upsample;
283
int ci;
284
jpeg_component_info * compptr;
285
int h_in_group, v_in_group, h_out_group, v_out_group;
286
287
upsample = (my_upsample_ptr) (*cinfo->mem->alloc_small)
288
((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_upsampler));
289
cinfo->upsample = &upsample->pub;
290
upsample->pub.start_pass = start_pass_upsample;
291
upsample->pub.upsample = sep_upsample;
292
upsample->pub.need_context_rows = FALSE; /* until we find out differently */
293
294
if (cinfo->CCIR601_sampling) /* this isn't supported */
295
ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
296
297
/* Verify we can handle the sampling factors, select per-component methods,
298
* and create storage as needed.
299
*/
300
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
301
ci++, compptr++) {
302
/* Don't bother to upsample an uninteresting component. */
303
if (! compptr->component_needed)
304
continue;
305
/* Compute size of an "input group" after IDCT scaling. This many samples
306
* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
307
*/
308
h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
309
cinfo->min_DCT_h_scaled_size;
310
v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
311
cinfo->min_DCT_v_scaled_size;
312
h_out_group = cinfo->max_h_samp_factor;
313
v_out_group = cinfo->max_v_samp_factor;
314
upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
315
if (h_in_group == h_out_group && v_in_group == v_out_group) {
316
/* Fullsize components can be processed without any work. */
317
upsample->methods[ci] = fullsize_upsample;
318
continue; /* don't need to allocate buffer */
319
}
320
if (h_in_group * 2 == h_out_group && v_in_group == v_out_group) {
321
/* Special case for 2h1v upsampling */
322
upsample->methods[ci] = h2v1_upsample;
323
} else if (h_in_group * 2 == h_out_group &&
324
v_in_group * 2 == v_out_group) {
325
/* Special case for 2h2v upsampling */
326
upsample->methods[ci] = h2v2_upsample;
327
} else if ((h_out_group % h_in_group) == 0 &&
328
(v_out_group % v_in_group) == 0) {
329
/* Generic integral-factors upsampling method */
330
upsample->methods[ci] = int_upsample;
331
upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
332
upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
333
} else
334
ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
335
upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
336
((j_common_ptr) cinfo, JPOOL_IMAGE,
337
(JDIMENSION) jround_up((long) cinfo->output_width,
338
(long) cinfo->max_h_samp_factor),
339
(JDIMENSION) cinfo->max_v_samp_factor);
340
}
341
}
342
343