170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jdsample.c 370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1991-1996, Thomas G. Lane. 570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software. 670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file. 770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains upsampling routines. 970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Upsampling input data is counted in "row groups". A row group 1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) 1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * sample rows of each component. Upsampling will normally produce 1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * max_v_samp_factor pixel rows from each row group (but this could vary 1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * if the upsampler is applying a scale factor of its own). 1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * An excellent reference for image resampling is 1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Digital Image Warping, George Wolberg, 1990. 1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. 1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define JPEG_INTERNALS 2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jinclude.h" 2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jpeglib.h" 2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Pointer to routine to upsample a single component */ 2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef JMETHOD(void, upsample1_ptr, 2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (j_decompress_ptr cinfo, jpeg_component_info * compptr, 2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); 3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Private subobject */ 3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct { 3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine struct jpeg_upsampler pub; /* public fields */ 3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Color conversion buffer. When using separate upsampling and color 3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * conversion steps, this buffer holds one upsampled row group until it 3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * has been color converted and output. 3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note: we do not allocate any storage for component(s) which are full-size, 4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * ie do not need rescaling. The corresponding entry of color_buf[] is 4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * simply set to point to the input data array, thereby avoiding copying. 4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY color_buf[MAX_COMPONENTS]; 4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Per-component upsampling method pointers */ 4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample1_ptr methods[MAX_COMPONENTS]; 4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int next_row_out; /* counts rows emitted from color_buf */ 4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION rows_to_go; /* counts rows remaining in image */ 5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Height of an input row group for each component. */ 5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int rowgroup_height[MAX_COMPONENTS]; 5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* These arrays save pixel expansion factors so that int_expand need not 5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * recompute them each time. They are unused for other upsampling methods. 5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine UINT8 h_expand[MAX_COMPONENTS]; 5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine UINT8 v_expand[MAX_COMPONENTS]; 5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} my_upsampler; 6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef my_upsampler * my_upsample_ptr; 6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Initialize for an upsampling pass. 6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestart_pass_upsample (j_decompress_ptr cinfo) 7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Mark the conversion buffer empty */ 7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->next_row_out = cinfo->max_v_samp_factor; 7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Initialize total-height counter for detecting bottom of image */ 7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->rows_to_go = cinfo->output_height; 7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Control routine to do upsampling (and color conversion). 8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * In this version we upsample each component independently. 8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We upsample one row group into the conversion buffer, then apply 8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * color conversion a row at a time. 8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinesep_upsample (j_decompress_ptr cinfo, 9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION in_row_groups_avail, 9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION out_rows_avail) 9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci; 9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info * compptr; 9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION num_rows; 9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Fill the conversion buffer, if it's empty */ 10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (upsample->next_row_out >= cinfo->max_v_samp_factor) { 10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ci++, compptr++) { 10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Invoke per-component upsample method. Notice we pass a POINTER 10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * to color_buf[ci], so that fullsize_upsample can change it. 10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*upsample->methods[ci]) (cinfo, compptr, 10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), 10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->color_buf + ci); 11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->next_row_out = 0; 11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Color-convert and emit rows */ 11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* How many we have in the buffer: */ 11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); 11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Not more than the distance to the end of the image. Need this test 11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * in case the image height is not a multiple of max_v_samp_factor: 12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (num_rows > upsample->rows_to_go) 12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine num_rows = upsample->rows_to_go; 12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* And not more than what the client can accept: */ 12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine out_rows_avail -= *out_row_ctr; 12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (num_rows > out_rows_avail) 12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine num_rows = out_rows_avail; 12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, 12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) upsample->next_row_out, 13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine output_buf + *out_row_ctr, 13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (int) num_rows); 13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Adjust counts */ 13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *out_row_ctr += num_rows; 13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->rows_to_go -= num_rows; 13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->next_row_out += num_rows; 13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* When the buffer is emptied, declare this input row group consumed */ 13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (upsample->next_row_out >= cinfo->max_v_samp_factor) 13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*in_row_group_ctr)++; 14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These are the routines invoked by sep_upsample to upsample pixel values 14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * of a single component. One row group is processed per call. 14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For full-size components, we just make color_buf[ci] point at the 15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * input buffer, and thus avoid copying any data. Note that this is 15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * safe only because sep_upsample doesn't declare the input row group 15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * "consumed" until we are done color converting and emitting it. 15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinefullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *output_data_ptr = input_data; 16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is a no-op version used for "uninteresting" components. 16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These components will not be referenced by color conversion. 16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinenoop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *output_data_ptr = NULL; /* safety check */ 17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This version handles any integral sampling ratios. 17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This is not used for typical JPEG files, so it need not be fast. 18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Nor, for that matter, is it particularly accurate: the algorithm is 18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * simple replication of the input pixel onto the corresponding output 18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * pixels. The hi-falutin sampling literature refers to this as a 18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * "box filter". A box filter tends to introduce visible artifacts, 18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * so if you are actually going to use 3:1 or 4:1 sampling ratios 18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * you would be well advised to improve this code. 18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineint_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; 19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_data = *output_data_ptr; 19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPROW inptr, outptr; 19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPLE invalue; 19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int h; 19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPROW outend; 19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int h_expand, v_expand; 19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int inrow, outrow; 20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine h_expand = upsample->h_expand[compptr->component_index]; 20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_expand = upsample->v_expand[compptr->component_index]; 20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow = outrow = 0; 20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outrow < cinfo->max_v_samp_factor) { 20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Generate one output row with proper horizontal expansion */ 20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr = input_data[inrow]; 20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outptr = output_data[outrow]; 20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outend = outptr + cinfo->output_width; 21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outptr < outend) { 21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = *inptr++; /* don't need GETJSAMPLE() here */ 21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (h = h_expand; h > 0; h--) { 21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = invalue; 21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Generate any additional output rows by duplicating the first one */ 21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (v_expand > 1) { 21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jcopy_sample_rows(output_data, outrow, output_data, outrow+1, 21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_expand-1, cinfo->output_width); 22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow++; 22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outrow += v_expand; 22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. 22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * It's still a box filter. 23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineh2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_data = *output_data_ptr; 23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPROW inptr, outptr; 23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPLE invalue; 23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPROW outend; 24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int inrow; 24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { 24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr = input_data[inrow]; 24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outptr = output_data[inrow]; 24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outend = outptr + cinfo->output_width; 24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outptr < outend) { 24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = *inptr++; /* don't need GETJSAMPLE() here */ 24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = invalue; 24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = invalue; 25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. 25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * It's still a box filter. 25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineh2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_data = *output_data_ptr; 26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPROW inptr, outptr; 26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPLE invalue; 26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPROW outend; 26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int inrow, outrow; 26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow = outrow = 0; 27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outrow < cinfo->max_v_samp_factor) { 27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr = input_data[inrow]; 27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outptr = output_data[outrow]; 27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outend = outptr + cinfo->output_width; 27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outptr < outend) { 27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = *inptr++; /* don't need GETJSAMPLE() here */ 27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = invalue; 27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = invalue; 27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jcopy_sample_rows(output_data, outrow, output_data, outrow+1, 28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1, cinfo->output_width); 28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow++; 28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outrow += 2; 28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical. 29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The upsampling algorithm is linear interpolation between pixel centers, 29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * also known as a "triangle filter". This is a good compromise between 29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * speed and visual quality. The centers of the output pixels are 1/4 and 3/4 29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * of the way between input pixel centers. 29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * A note about the "bias" calculations: when rounding fractional values to 29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * integer, we do not want to always round 0.5 up to the next integer. 29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * If we did that, we'd introduce a noticeable bias towards larger values. 29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Instead, this code is arranged so that 0.5 will be rounded up or down at 30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * alternate pixel locations (a simple ordered dither pattern). 30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineh2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_data = *output_data_ptr; 30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPROW inptr, outptr; 30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int invalue; 31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JDIMENSION colctr; 31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int inrow; 31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { 31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr = input_data[inrow]; 31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outptr = output_data[inrow]; 31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special case for first column */ 31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = GETJSAMPLE(*inptr++); 31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) invalue; 31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2); 32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { 32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* General case: 3/4 * nearer pixel + 1/4 * further pixel */ 32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = GETJSAMPLE(*inptr++) * 3; 32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2); 32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2); 32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special case for last column */ 32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine invalue = GETJSAMPLE(*inptr); 33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2); 33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) invalue; 33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical. 33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Again a triangle filter; see comments for h2v1 case, above. 33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * It is OK for us to reference the adjacent input rows because we demanded 34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * context from the main buffer controller (see initialization code). 34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineh2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, 34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) 34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY output_data = *output_data_ptr; 34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JSAMPROW inptr0, inptr1, outptr; 35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#if BITS_IN_JSAMPLE == 8 35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int thiscolsum, lastcolsum, nextcolsum; 35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else 35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register INT32 thiscolsum, lastcolsum, nextcolsum; 35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 35570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register JDIMENSION colctr; 35670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int inrow, outrow, v; 35770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 35870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow = outrow = 0; 35970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (outrow < cinfo->max_v_samp_factor) { 36070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (v = 0; v < 2; v++) { 36170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* inptr0 points to nearest input row, inptr1 points to next nearest */ 36270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr0 = input_data[inrow]; 36370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (v == 0) /* next nearest is row above */ 36470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr1 = input_data[inrow-1]; 36570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine else /* next nearest is row below */ 36670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inptr1 = input_data[inrow+1]; 36770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine outptr = output_data[outrow++]; 36870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 36970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special case for first column */ 37070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 37170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 37270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4); 37370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); 37470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine lastcolsum = thiscolsum; thiscolsum = nextcolsum; 37570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 37670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) { 37770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */ 37870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */ 37970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++); 38070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); 38170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4); 38270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine lastcolsum = thiscolsum; thiscolsum = nextcolsum; 38370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 38470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 38570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special case for last column */ 38670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4); 38770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4); 38870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 38970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrow++; 39070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 39170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 39270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 39370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 39470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 39570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Module initialization routine for upsampling. 39670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 39770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 39870a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 39970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejinit_upsampler (j_decompress_ptr cinfo) 40070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 40170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_upsample_ptr upsample; 40270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci; 40370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info * compptr; 40470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine boolean need_buffer, do_fancy; 40570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int h_in_group, v_in_group, h_out_group, v_out_group; 40670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 40770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample = (my_upsample_ptr) 40870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 40970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(my_upsampler)); 41070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->upsample = (struct jpeg_upsampler *) upsample; 41170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->pub.start_pass = start_pass_upsample; 41270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->pub.upsample = sep_upsample; 41370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->pub.need_context_rows = FALSE; /* until we find out differently */ 41470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 41570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (cinfo->CCIR601_sampling) /* this isn't supported */ 41670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); 41770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 41870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, 41970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * so don't ask for it. 42070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 42170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; 42270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 42370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Verify we can handle the sampling factors, select per-component methods, 42470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * and create storage as needed. 42570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 42670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 42770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ci++, compptr++) { 42870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Compute size of an "input group" after IDCT scaling. This many samples 42970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. 43070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 43170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / 43270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->min_DCT_scaled_size; 43370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / 43470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->min_DCT_scaled_size; 43570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine h_out_group = cinfo->max_h_samp_factor; 43670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_out_group = cinfo->max_v_samp_factor; 43770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ 43870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine need_buffer = TRUE; 43970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (! compptr->component_needed) { 44070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Don't bother to upsample an uninteresting component. */ 44170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = noop_upsample; 44270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine need_buffer = FALSE; 44370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (h_in_group == h_out_group && v_in_group == v_out_group) { 44470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Fullsize components can be processed without any work. */ 44570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = fullsize_upsample; 44670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine need_buffer = FALSE; 44770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (h_in_group * 2 == h_out_group && 44870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_in_group == v_out_group) { 44970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special cases for 2h1v upsampling */ 45070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (do_fancy && compptr->downsampled_width > 2) 45170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = h2v1_fancy_upsample; 45270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine else 45370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = h2v1_upsample; 45470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if (h_in_group * 2 == h_out_group && 45570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine v_in_group * 2 == v_out_group) { 45670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Special cases for 2h2v upsampling */ 45770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (do_fancy && compptr->downsampled_width > 2) { 45870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = h2v2_fancy_upsample; 45970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->pub.need_context_rows = TRUE; 46070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else 46170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = h2v2_upsample; 46270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else if ((h_out_group % h_in_group) == 0 && 46370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (v_out_group % v_in_group) == 0) { 46470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Generic integral-factors upsampling method */ 46570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->methods[ci] = int_upsample; 46670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); 46770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); 46870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else 46970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); 47070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (need_buffer) { 47170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) 47270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, JPOOL_IMAGE, 47370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) jround_up((long) cinfo->output_width, 47470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (long) cinfo->max_h_samp_factor), 47570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) cinfo->max_v_samp_factor); 47670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 47770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 47870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 479