1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FX_JPEG_TURBO_) 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * jdsample.c 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (C) 1991-1996, Thomas G. Lane. 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This file is part of the Independent JPEG Group's software. 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For conditions of distribution and use, see the accompanying README file. 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This file contains upsampling routines. 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Upsampling input data is counted in "row groups". A row group 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * sample rows of each component. Upsampling will normally produce 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * max_v_samp_factor pixel rows from each row group (but this could vary 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * if the upsampler is applying a scale factor of its own). 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * An excellent reference for image resampling is 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Digital Image Warping, George Wolberg, 1990. 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define JPEG_INTERNALS 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jinclude.h" 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jpeglib.h" 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Pointer to routine to upsample a single component */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef JMETHOD(void, upsample1_ptr, 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (j_decompress_ptr cinfo, jpeg_component_info * compptr, 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Private subobject */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct jpeg_upsampler pub; /* public fields */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Color conversion buffer. When using separate upsampling and color 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * conversion steps, this buffer holds one upsampled row group until it 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * has been color converted and output. 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Note: we do not allocate any storage for component(s) which are full-size, 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * ie do not need rescaling. The corresponding entry of color_buf[] is 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * simply set to point to the input data array, thereby avoiding copying. 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY color_buf[MAX_COMPONENTS]; 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Per-component upsampling method pointers */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample1_ptr methods[MAX_COMPONENTS]; 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int next_row_out; /* counts rows emitted from color_buf */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION rows_to_go; /* counts rows remaining in image */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Height of an input row group for each component. */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int rowgroup_height[MAX_COMPONENTS]; 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* These arrays save pixel expansion factors so that int_expand need not 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * recompute them each time. They are unused for other upsampling methods. 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UINT8 h_expand[MAX_COMPONENTS]; 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UINT8 v_expand[MAX_COMPONENTS]; 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} my_upsampler; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef my_upsampler * my_upsample_ptr; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Initialize for an upsampling pass. 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstart_pass_upsample (j_decompress_ptr cinfo) 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Mark the conversion buffer empty */ 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->next_row_out = cinfo->max_v_samp_factor; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initialize total-height counter for detecting bottom of image */ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->rows_to_go = cinfo->output_height; 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Control routine to do upsampling (and color conversion). 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * In this version we upsample each component independently. 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * We upsample one row group into the conversion buffer, then apply 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * color conversion a row at a time. 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovsep_upsample (j_decompress_ptr cinfo, 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail) 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ci; 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jpeg_component_info * compptr; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION num_rows; 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Fill the conversion buffer, if it's empty */ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (upsample->next_row_out >= cinfo->max_v_samp_factor) { 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ci++, compptr++) { 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Invoke per-component upsample method. Notice we pass a POINTER 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * to color_buf[ci], so that fullsize_upsample can change it. 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*upsample->methods[ci]) (cinfo, compptr, 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->color_buf + ci); 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->next_row_out = 0; 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Color-convert and emit rows */ 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* How many we have in the buffer: */ 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Not more than the distance to the end of the image. Need this test 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * in case the image height is not a multiple of max_v_samp_factor: 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (num_rows > upsample->rows_to_go) 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = upsample->rows_to_go; 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* And not more than what the client can accept: */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov out_rows_avail -= *out_row_ctr; 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (num_rows > out_rows_avail) 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = out_rows_avail; 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) upsample->next_row_out, 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov output_buf + *out_row_ctr, 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int) num_rows); 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Adjust counts */ 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_ctr += num_rows; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->rows_to_go -= num_rows; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->next_row_out += num_rows; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* When the buffer is emptied, declare this input row group consumed */ 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (upsample->next_row_out >= cinfo->max_v_samp_factor) 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*in_row_group_ctr)++; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * These are the routines invoked by sep_upsample to upsample pixel values 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * of a single component. One row group is processed per call. 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For full-size components, we just make color_buf[ci] point at the 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * input buffer, and thus avoid copying any data. Note that this is 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * safe only because sep_upsample doesn't declare the input row group 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * "consumed" until we are done color converting and emitting it. 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovfullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *output_data_ptr = input_data; 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This is a no-op version used for "uninteresting" components. 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * These components will not be referenced by color conversion. 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnoop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *output_data_ptr = NULL; /* safety check */ 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This version handles any integral sampling ratios. 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This is not used for typical JPEG files, so it need not be fast. 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Nor, for that matter, is it particularly accurate: the algorithm is 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * simple replication of the input pixel onto the corresponding output 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * pixels. The hi-falutin sampling literature refers to this as a 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * "box filter". A box filter tends to introduce visible artifacts, 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * so if you are actually going to use 3:1 or 4:1 sampling ratios 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * you would be well advised to improve this code. 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_data = *output_data_ptr; 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPROW inptr, outptr; 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPLE invalue; 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register int h; 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPROW outend; 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int h_expand, v_expand; 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inrow, outrow; 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h_expand = upsample->h_expand[compptr->component_index]; 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_expand = upsample->v_expand[compptr->component_index]; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow = outrow = 0; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outrow < cinfo->max_v_samp_factor) { 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Generate one output row with proper horizontal expansion */ 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr = input_data[inrow]; 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outptr = output_data[outrow]; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outend = outptr + cinfo->output_width; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outptr < outend) { 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = *inptr++; /* don't need GETJSAMPLE() here */ 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (h = h_expand; h > 0; h--) { 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = invalue; 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Generate any additional output rows by duplicating the first one */ 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (v_expand > 1) { 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jcopy_sample_rows(output_data, outrow, output_data, outrow+1, 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_expand-1, cinfo->output_width); 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow++; 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outrow += v_expand; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * It's still a box filter. 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovh2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_data = *output_data_ptr; 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPROW inptr, outptr; 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPLE invalue; 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPROW outend; 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inrow; 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr = input_data[inrow]; 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outptr = output_data[inrow]; 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outend = outptr + cinfo->output_width; 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outptr < outend) { 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = *inptr++; /* don't need GETJSAMPLE() here */ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = invalue; 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = invalue; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * It's still a box filter. 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovh2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_data = *output_data_ptr; 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPROW inptr, outptr; 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPLE invalue; 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPROW outend; 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inrow, outrow; 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow = outrow = 0; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outrow < cinfo->max_v_samp_factor) { 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr = input_data[inrow]; 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outptr = output_data[outrow]; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outend = outptr + cinfo->output_width; 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outptr < outend) { 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = *inptr++; /* don't need GETJSAMPLE() here */ 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = invalue; 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = invalue; 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jcopy_sample_rows(output_data, outrow, output_data, outrow+1, 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1, cinfo->output_width); 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow++; 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outrow += 2; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The upsampling algorithm is linear interpolation between pixel centers, 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * also known as a "triangle filter". This is a good compromise between 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * of the way between input pixel centers. 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * A note about the "bias" calculations: when rounding fractional values to 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * integer, we do not want to always round 0.5 up to the next integer. 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * If we did that, we'd introduce a noticeable bias towards larger values. 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Instead, this code is arranged so that 0.5 will be rounded up or down at 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * alternate pixel locations (a simple ordered dither pattern). 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovh2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_data = *output_data_ptr; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPROW inptr, outptr; 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register int invalue; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JDIMENSION colctr; 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inrow; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr = input_data[inrow]; 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outptr = output_data[inrow]; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special case for first column */ 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = GETJSAMPLE(*inptr++); 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) invalue; 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = GETJSAMPLE(*inptr++) * 3; 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special case for last column */ 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov invalue = GETJSAMPLE(*inptr); 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) invalue; 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Again a triangle filter; see comments for h2v1 case, above. 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * It is OK for us to reference the adjacent input rows because we demanded 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * context from the main buffer controller (see initialization code). 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovh2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_data = *output_data_ptr; 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JSAMPROW inptr0, inptr1, outptr; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if BITS_IN_JSAMPLE == 8 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register int thiscolsum, lastcolsum, nextcolsum; 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register INT32 thiscolsum, lastcolsum, nextcolsum; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register JDIMENSION colctr; 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int inrow, outrow, v; 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow = outrow = 0; 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (outrow < cinfo->max_v_samp_factor) { 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (v = 0; v < 2; v++) { 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* inptr0 points to nearest input row, inptr1 points to next nearest */ 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr0 = input_data[inrow]; 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (v == 0) /* next nearest is row above */ 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr1 = input_data[inrow-1]; 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else /* next nearest is row below */ 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inptr1 = input_data[inrow+1]; 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outptr = output_data[outrow++]; 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special case for first column */ 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastcolsum = thiscolsum; thiscolsum = nextcolsum; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastcolsum = thiscolsum; thiscolsum = nextcolsum; 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special case for last column */ 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrow++; 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Module initialization routine for upsampling. 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovGLOBAL(void) 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovjinit_upsampler (j_decompress_ptr cinfo) 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_upsample_ptr upsample; 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ci; 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jpeg_component_info * compptr; 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov boolean need_buffer, do_fancy; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int h_in_group, v_in_group, h_out_group, v_out_group; 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample = (my_upsample_ptr) 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SIZEOF(my_upsampler)); 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->upsample = (struct jpeg_upsampler *) upsample; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->pub.start_pass = start_pass_upsample; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->pub.upsample = sep_upsample; 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->pub.need_context_rows = FALSE; /* until we find out differently */ 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cinfo->CCIR601_sampling) /* this isn't supported */ 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * so don't ask for it. 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Verify we can handle the sampling factors, select per-component methods, 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * and create storage as needed. 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ci++, compptr++) { 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute size of an "input group" after IDCT scaling. This many samples 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->min_DCT_scaled_size; 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->min_DCT_scaled_size; 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h_out_group = cinfo->max_h_samp_factor; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_out_group = cinfo->max_v_samp_factor; 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov need_buffer = TRUE; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (! compptr->component_needed) { 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Don't bother to upsample an uninteresting component. */ 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = noop_upsample; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov need_buffer = FALSE; 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (h_in_group == h_out_group && v_in_group == v_out_group) { 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Fullsize components can be processed without any work. */ 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = fullsize_upsample; 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov need_buffer = FALSE; 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (h_in_group * 2 == h_out_group && 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_in_group == v_out_group) { 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special cases for 2h1v upsampling */ 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (do_fancy && compptr->downsampled_width > 2) 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = h2v1_fancy_upsample; 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = h2v1_upsample; 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (h_in_group * 2 == h_out_group && 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_in_group * 2 == v_out_group) { 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Special cases for 2h2v upsampling */ 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (do_fancy && compptr->downsampled_width > 2) { 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = h2v2_fancy_upsample; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->pub.need_context_rows = TRUE; 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = h2v2_upsample; 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if ((h_out_group % h_in_group) == 0 && 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (v_out_group % v_in_group) == 0) { 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Generic integral-factors upsampling method */ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->methods[ci] = int_upsample; 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (need_buffer) { 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) jround_up((long) cinfo->output_width, 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (long) cinfo->max_h_samp_factor), 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) cinfo->max_v_samp_factor); 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif //_FX_JPEG_TURBO_ 482