4 * Copyright (C) 1991-1996, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
8 * This file contains upsampling routines.
10 * Upsampling input data is counted in "row groups". A row group
11 * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
12 * sample rows of each component. Upsampling will normally produce
13 * max_v_samp_factor pixel rows from each row group (but this could vary
14 * if the upsampler is applying a scale factor of its own).
16 * An excellent reference for image resampling is
17 * Digital Image Warping, George Wolberg, 1990.
18 * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
21 #define JPEG_INTERNALS
26 /* Pointer to routine to upsample a single component */
27 typedef JMETHOD(void, upsample1_ptr
,
28 (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
29 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
));
31 /* Private subobject */
34 struct jpeg_upsampler pub
; /* public fields */
36 /* Color conversion buffer. When using separate upsampling and color
37 * conversion steps, this buffer holds one upsampled row group until it
38 * has been color converted and output.
39 * Note: we do not allocate any storage for component(s) which are full-size,
40 * ie do not need rescaling. The corresponding entry of color_buf[] is
41 * simply set to point to the input data array, thereby avoiding copying.
43 JSAMPARRAY color_buf
[MAX_COMPONENTS
];
45 /* Per-component upsampling method pointers */
46 upsample1_ptr methods
[MAX_COMPONENTS
];
48 int next_row_out
; /* counts rows emitted from color_buf */
49 JDIMENSION rows_to_go
; /* counts rows remaining in image */
51 /* Height of an input row group for each component. */
52 int rowgroup_height
[MAX_COMPONENTS
];
54 /* These arrays save pixel expansion factors so that int_expand need not
55 * recompute them each time. They are unused for other upsampling methods.
57 UINT8 h_expand
[MAX_COMPONENTS
];
58 UINT8 v_expand
[MAX_COMPONENTS
];
61 typedef my_upsampler
* my_upsample_ptr
;
65 * Initialize for an upsampling pass.
69 start_pass_upsample (j_decompress_ptr cinfo
)
71 my_upsample_ptr upsample
= (my_upsample_ptr
) cinfo
->upsample
;
73 /* Mark the conversion buffer empty */
74 upsample
->next_row_out
= cinfo
->max_v_samp_factor
;
75 /* Initialize total-height counter for detecting bottom of image */
76 upsample
->rows_to_go
= cinfo
->output_height
;
81 * Control routine to do upsampling (and color conversion).
83 * In this version we upsample each component independently.
84 * We upsample one row group into the conversion buffer, then apply
85 * color conversion a row at a time.
89 sep_upsample (j_decompress_ptr cinfo
,
90 JSAMPIMAGE input_buf
, JDIMENSION
*in_row_group_ctr
,
91 JDIMENSION in_row_groups_avail
,
92 JSAMPARRAY output_buf
, JDIMENSION
*out_row_ctr
,
93 JDIMENSION out_rows_avail
)
95 my_upsample_ptr upsample
= (my_upsample_ptr
) cinfo
->upsample
;
97 jpeg_component_info
* compptr
;
100 /* Fill the conversion buffer, if it's empty */
101 if (upsample
->next_row_out
>= cinfo
->max_v_samp_factor
) {
102 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
104 /* Invoke per-component upsample method. Notice we pass a POINTER
105 * to color_buf[ci], so that fullsize_upsample can change it.
107 (*upsample
->methods
[ci
]) (cinfo
, compptr
,
108 input_buf
[ci
] + (*in_row_group_ctr
* upsample
->rowgroup_height
[ci
]),
109 upsample
->color_buf
+ ci
);
111 upsample
->next_row_out
= 0;
114 /* Color-convert and emit rows */
116 /* How many we have in the buffer: */
117 num_rows
= (JDIMENSION
) (cinfo
->max_v_samp_factor
- upsample
->next_row_out
);
118 /* Not more than the distance to the end of the image. Need this test
119 * in case the image height is not a multiple of max_v_samp_factor:
121 if (num_rows
> upsample
->rows_to_go
)
122 num_rows
= upsample
->rows_to_go
;
123 /* And not more than what the client can accept: */
124 out_rows_avail
-= *out_row_ctr
;
125 if (num_rows
> out_rows_avail
)
126 num_rows
= out_rows_avail
;
128 (*cinfo
->cconvert
->color_convert
) (cinfo
, upsample
->color_buf
,
129 (JDIMENSION
) upsample
->next_row_out
,
130 output_buf
+ *out_row_ctr
,
134 *out_row_ctr
+= num_rows
;
135 upsample
->rows_to_go
-= num_rows
;
136 upsample
->next_row_out
+= num_rows
;
137 /* When the buffer is emptied, declare this input row group consumed */
138 if (upsample
->next_row_out
>= cinfo
->max_v_samp_factor
)
139 (*in_row_group_ctr
)++;
144 * These are the routines invoked by sep_upsample to upsample pixel values
145 * of a single component. One row group is processed per call.
150 * For full-size components, we just make color_buf[ci] point at the
151 * input buffer, and thus avoid copying any data. Note that this is
152 * safe only because sep_upsample doesn't declare the input row group
153 * "consumed" until we are done color converting and emitting it.
157 fullsize_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
158 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
160 *output_data_ptr
= input_data
;
165 * This is a no-op version used for "uninteresting" components.
166 * These components will not be referenced by color conversion.
170 noop_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
171 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
173 *output_data_ptr
= NULL
; /* safety check */
178 * This version handles any integral sampling ratios.
179 * This is not used for typical JPEG files, so it need not be fast.
180 * Nor, for that matter, is it particularly accurate: the algorithm is
181 * simple replication of the input pixel onto the corresponding output
182 * pixels. The hi-falutin sampling literature refers to this as a
183 * "box filter". A box filter tends to introduce visible artifacts,
184 * so if you are actually going to use 3:1 or 4:1 sampling ratios
185 * you would be well advised to improve this code.
189 int_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
190 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
192 my_upsample_ptr upsample
= (my_upsample_ptr
) cinfo
->upsample
;
193 JSAMPARRAY output_data
= *output_data_ptr
;
194 register JSAMPROW inptr
, outptr
;
195 register JSAMPLE invalue
;
198 int h_expand
, v_expand
;
201 h_expand
= upsample
->h_expand
[compptr
->component_index
];
202 v_expand
= upsample
->v_expand
[compptr
->component_index
];
205 while (outrow
< cinfo
->max_v_samp_factor
) {
206 /* Generate one output row with proper horizontal expansion */
207 inptr
= input_data
[inrow
];
208 outptr
= output_data
[outrow
];
209 outend
= outptr
+ cinfo
->output_width
;
210 while (outptr
< outend
) {
211 invalue
= *inptr
++; /* don't need GETJSAMPLE() here */
212 for (h
= h_expand
; h
> 0; h
--) {
216 /* Generate any additional output rows by duplicating the first one */
218 jcopy_sample_rows(output_data
, outrow
, output_data
, outrow
+1,
219 v_expand
-1, cinfo
->output_width
);
228 * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
229 * It's still a box filter.
233 h2v1_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
234 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
236 JSAMPARRAY output_data
= *output_data_ptr
;
237 register JSAMPROW inptr
, outptr
;
238 register JSAMPLE invalue
;
242 for (inrow
= 0; inrow
< cinfo
->max_v_samp_factor
; inrow
++) {
243 inptr
= input_data
[inrow
];
244 outptr
= output_data
[inrow
];
245 outend
= outptr
+ cinfo
->output_width
;
246 while (outptr
< outend
) {
247 invalue
= *inptr
++; /* don't need GETJSAMPLE() here */
256 * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
257 * It's still a box filter.
261 h2v2_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
262 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
264 JSAMPARRAY output_data
= *output_data_ptr
;
265 register JSAMPROW inptr
, outptr
;
266 register JSAMPLE invalue
;
271 while (outrow
< cinfo
->max_v_samp_factor
) {
272 inptr
= input_data
[inrow
];
273 outptr
= output_data
[outrow
];
274 outend
= outptr
+ cinfo
->output_width
;
275 while (outptr
< outend
) {
276 invalue
= *inptr
++; /* don't need GETJSAMPLE() here */
280 jcopy_sample_rows(output_data
, outrow
, output_data
, outrow
+1,
281 1, cinfo
->output_width
);
289 * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
291 * The upsampling algorithm is linear interpolation between pixel centers,
292 * also known as a "triangle filter". This is a good compromise between
293 * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
294 * of the way between input pixel centers.
296 * A note about the "bias" calculations: when rounding fractional values to
297 * integer, we do not want to always round 0.5 up to the next integer.
298 * If we did that, we'd introduce a noticeable bias towards larger values.
299 * Instead, this code is arranged so that 0.5 will be rounded up or down at
300 * alternate pixel locations (a simple ordered dither pattern).
304 h2v1_fancy_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
305 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
307 JSAMPARRAY output_data
= *output_data_ptr
;
308 register JSAMPROW inptr
, outptr
;
309 register int invalue
;
310 register JDIMENSION colctr
;
313 for (inrow
= 0; inrow
< cinfo
->max_v_samp_factor
; inrow
++) {
314 inptr
= input_data
[inrow
];
315 outptr
= output_data
[inrow
];
316 /* Special case for first column */
317 invalue
= GETJSAMPLE(*inptr
++);
318 *outptr
++ = (JSAMPLE
) invalue
;
319 *outptr
++ = (JSAMPLE
) ((invalue
* 3 + GETJSAMPLE(*inptr
) + 2) >> 2);
321 for (colctr
= compptr
->downsampled_width
- 2; colctr
> 0; colctr
--) {
322 /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
323 invalue
= GETJSAMPLE(*inptr
++) * 3;
324 *outptr
++ = (JSAMPLE
) ((invalue
+ GETJSAMPLE(inptr
[-2]) + 1) >> 2);
325 *outptr
++ = (JSAMPLE
) ((invalue
+ GETJSAMPLE(*inptr
) + 2) >> 2);
328 /* Special case for last column */
329 invalue
= GETJSAMPLE(*inptr
);
330 *outptr
++ = (JSAMPLE
) ((invalue
* 3 + GETJSAMPLE(inptr
[-1]) + 1) >> 2);
331 *outptr
++ = (JSAMPLE
) invalue
;
337 * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
338 * Again a triangle filter; see comments for h2v1 case, above.
340 * It is OK for us to reference the adjacent input rows because we demanded
341 * context from the main buffer controller (see initialization code).
345 h2v2_fancy_upsample (j_decompress_ptr cinfo
, jpeg_component_info
* compptr
,
346 JSAMPARRAY input_data
, JSAMPARRAY
* output_data_ptr
)
348 JSAMPARRAY output_data
= *output_data_ptr
;
349 register JSAMPROW inptr0
, inptr1
, outptr
;
350 #if BITS_IN_JSAMPLE == 8
351 register int thiscolsum
, lastcolsum
, nextcolsum
;
353 register INT32 thiscolsum
, lastcolsum
, nextcolsum
;
355 register JDIMENSION colctr
;
356 int inrow
, outrow
, v
;
359 while (outrow
< cinfo
->max_v_samp_factor
) {
360 for (v
= 0; v
< 2; v
++) {
361 /* inptr0 points to nearest input row, inptr1 points to next nearest */
362 inptr0
= input_data
[inrow
];
363 if (v
== 0) /* next nearest is row above */
364 inptr1
= input_data
[inrow
-1];
365 else /* next nearest is row below */
366 inptr1
= input_data
[inrow
+1];
367 outptr
= output_data
[outrow
++];
369 /* Special case for first column */
370 thiscolsum
= GETJSAMPLE(*inptr0
++) * 3 + GETJSAMPLE(*inptr1
++);
371 nextcolsum
= GETJSAMPLE(*inptr0
++) * 3 + GETJSAMPLE(*inptr1
++);
372 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 4 + 8) >> 4);
373 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 3 + nextcolsum
+ 7) >> 4);
374 lastcolsum
= thiscolsum
; thiscolsum
= nextcolsum
;
376 for (colctr
= compptr
->downsampled_width
- 2; colctr
> 0; colctr
--) {
377 /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
378 /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
379 nextcolsum
= GETJSAMPLE(*inptr0
++) * 3 + GETJSAMPLE(*inptr1
++);
380 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 3 + lastcolsum
+ 8) >> 4);
381 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 3 + nextcolsum
+ 7) >> 4);
382 lastcolsum
= thiscolsum
; thiscolsum
= nextcolsum
;
385 /* Special case for last column */
386 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 3 + lastcolsum
+ 8) >> 4);
387 *outptr
++ = (JSAMPLE
) ((thiscolsum
* 4 + 7) >> 4);
395 * Module initialization routine for upsampling.
399 jinit_upsampler (j_decompress_ptr cinfo
)
401 my_upsample_ptr upsample
;
403 jpeg_component_info
* compptr
;
404 boolean need_buffer
, do_fancy
;
405 int h_in_group
, v_in_group
, h_out_group
, v_out_group
;
407 upsample
= (my_upsample_ptr
)
408 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
409 SIZEOF(my_upsampler
));
410 cinfo
->upsample
= (struct jpeg_upsampler
*) upsample
;
411 upsample
->pub
.start_pass
= start_pass_upsample
;
412 upsample
->pub
.upsample
= sep_upsample
;
413 upsample
->pub
.need_context_rows
= FALSE
; /* until we find out differently */
415 if (cinfo
->CCIR601_sampling
) /* this isn't supported */
416 ERREXIT(cinfo
, JERR_CCIR601_NOTIMPL
);
418 /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
419 * so don't ask for it.
421 do_fancy
= cinfo
->do_fancy_upsampling
&& cinfo
->min_DCT_scaled_size
> 1;
423 /* Verify we can handle the sampling factors, select per-component methods,
424 * and create storage as needed.
426 for (ci
= 0, compptr
= cinfo
->comp_info
; ci
< cinfo
->num_components
;
428 /* Compute size of an "input group" after IDCT scaling. This many samples
429 * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
431 h_in_group
= (compptr
->h_samp_factor
* compptr
->DCT_scaled_size
) /
432 cinfo
->min_DCT_scaled_size
;
433 v_in_group
= (compptr
->v_samp_factor
* compptr
->DCT_scaled_size
) /
434 cinfo
->min_DCT_scaled_size
;
435 h_out_group
= cinfo
->max_h_samp_factor
;
436 v_out_group
= cinfo
->max_v_samp_factor
;
437 upsample
->rowgroup_height
[ci
] = v_in_group
; /* save for use later */
439 if (! compptr
->component_needed
) {
440 /* Don't bother to upsample an uninteresting component. */
441 upsample
->methods
[ci
] = noop_upsample
;
443 } else if (h_in_group
== h_out_group
&& v_in_group
== v_out_group
) {
444 /* Fullsize components can be processed without any work. */
445 upsample
->methods
[ci
] = fullsize_upsample
;
447 } else if (h_in_group
* 2 == h_out_group
&&
448 v_in_group
== v_out_group
) {
449 /* Special cases for 2h1v upsampling */
450 if (do_fancy
&& compptr
->downsampled_width
> 2)
451 upsample
->methods
[ci
] = h2v1_fancy_upsample
;
453 upsample
->methods
[ci
] = h2v1_upsample
;
454 } else if (h_in_group
* 2 == h_out_group
&&
455 v_in_group
* 2 == v_out_group
) {
456 /* Special cases for 2h2v upsampling */
457 if (do_fancy
&& compptr
->downsampled_width
> 2) {
458 upsample
->methods
[ci
] = h2v2_fancy_upsample
;
459 upsample
->pub
.need_context_rows
= TRUE
;
461 upsample
->methods
[ci
] = h2v2_upsample
;
462 } else if ((h_out_group
% h_in_group
) == 0 &&
463 (v_out_group
% v_in_group
) == 0) {
464 /* Generic integral-factors upsampling method */
465 upsample
->methods
[ci
] = int_upsample
;
466 upsample
->h_expand
[ci
] = (UINT8
) (h_out_group
/ h_in_group
);
467 upsample
->v_expand
[ci
] = (UINT8
) (v_out_group
/ v_in_group
);
469 ERREXIT(cinfo
, JERR_FRACT_SAMPLE_NOTIMPL
);
471 upsample
->color_buf
[ci
] = (*cinfo
->mem
->alloc_sarray
)
472 ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
473 (JDIMENSION
) jround_up((long) cinfo
->output_width
,
474 (long) cinfo
->max_h_samp_factor
),
475 (JDIMENSION
) cinfo
->max_v_samp_factor
);