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