Path: blob/master/3rdparty/libjpeg-turbo/src/jdsample.c
16337 views
/*1* jdsample.c2*3* This file was part of the Independent JPEG Group's software:4* Copyright (C) 1991-1996, Thomas G. Lane.5* libjpeg-turbo Modifications:6* Copyright 2009 Pierre Ossman <[email protected]> for Cendio AB7* Copyright (C) 2010, 2015-2016, D. R. Commander.8* Copyright (C) 2014, MIPS Technologies, Inc., California.9* Copyright (C) 2015, Google, Inc.10* For conditions of distribution and use, see the accompanying README.ijg11* file.12*13* This file contains upsampling routines.14*15* Upsampling input data is counted in "row groups". A row group16* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)17* sample rows of each component. Upsampling will normally produce18* max_v_samp_factor pixel rows from each row group (but this could vary19* if the upsampler is applying a scale factor of its own).20*21* An excellent reference for image resampling is22* Digital Image Warping, George Wolberg, 1990.23* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.24*/2526#include "jinclude.h"27#include "jdsample.h"28#include "jsimd.h"29#include "jpegcomp.h"30313233/*34* Initialize for an upsampling pass.35*/3637METHODDEF(void)38start_pass_upsample (j_decompress_ptr cinfo)39{40my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;4142/* Mark the conversion buffer empty */43upsample->next_row_out = cinfo->max_v_samp_factor;44/* Initialize total-height counter for detecting bottom of image */45upsample->rows_to_go = cinfo->output_height;46}474849/*50* Control routine to do upsampling (and color conversion).51*52* In this version we upsample each component independently.53* We upsample one row group into the conversion buffer, then apply54* color conversion a row at a time.55*/5657METHODDEF(void)58sep_upsample (j_decompress_ptr cinfo,59JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,60JDIMENSION in_row_groups_avail,61JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,62JDIMENSION out_rows_avail)63{64my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;65int ci;66jpeg_component_info *compptr;67JDIMENSION num_rows;6869/* Fill the conversion buffer, if it's empty */70if (upsample->next_row_out >= cinfo->max_v_samp_factor) {71for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;72ci++, compptr++) {73/* Invoke per-component upsample method. Notice we pass a POINTER74* to color_buf[ci], so that fullsize_upsample can change it.75*/76(*upsample->methods[ci]) (cinfo, compptr,77input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),78upsample->color_buf + ci);79}80upsample->next_row_out = 0;81}8283/* Color-convert and emit rows */8485/* How many we have in the buffer: */86num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);87/* Not more than the distance to the end of the image. Need this test88* in case the image height is not a multiple of max_v_samp_factor:89*/90if (num_rows > upsample->rows_to_go)91num_rows = upsample->rows_to_go;92/* And not more than what the client can accept: */93out_rows_avail -= *out_row_ctr;94if (num_rows > out_rows_avail)95num_rows = out_rows_avail;9697(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,98(JDIMENSION) upsample->next_row_out,99output_buf + *out_row_ctr,100(int) num_rows);101102/* Adjust counts */103*out_row_ctr += num_rows;104upsample->rows_to_go -= num_rows;105upsample->next_row_out += num_rows;106/* When the buffer is emptied, declare this input row group consumed */107if (upsample->next_row_out >= cinfo->max_v_samp_factor)108(*in_row_group_ctr)++;109}110111112/*113* These are the routines invoked by sep_upsample to upsample pixel values114* of a single component. One row group is processed per call.115*/116117118/*119* For full-size components, we just make color_buf[ci] point at the120* input buffer, and thus avoid copying any data. Note that this is121* safe only because sep_upsample doesn't declare the input row group122* "consumed" until we are done color converting and emitting it.123*/124125METHODDEF(void)126fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,127JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)128{129*output_data_ptr = input_data;130}131132133/*134* This is a no-op version used for "uninteresting" components.135* These components will not be referenced by color conversion.136*/137138METHODDEF(void)139noop_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,140JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)141{142*output_data_ptr = NULL; /* safety check */143}144145146/*147* This version handles any integral sampling ratios.148* This is not used for typical JPEG files, so it need not be fast.149* Nor, for that matter, is it particularly accurate: the algorithm is150* simple replication of the input pixel onto the corresponding output151* pixels. The hi-falutin sampling literature refers to this as a152* "box filter". A box filter tends to introduce visible artifacts,153* so if you are actually going to use 3:1 or 4:1 sampling ratios154* you would be well advised to improve this code.155*/156157METHODDEF(void)158int_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,159JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)160{161my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;162JSAMPARRAY output_data = *output_data_ptr;163register JSAMPROW inptr, outptr;164register JSAMPLE invalue;165register int h;166JSAMPROW outend;167int h_expand, v_expand;168int inrow, outrow;169170h_expand = upsample->h_expand[compptr->component_index];171v_expand = upsample->v_expand[compptr->component_index];172173inrow = outrow = 0;174while (outrow < cinfo->max_v_samp_factor) {175/* Generate one output row with proper horizontal expansion */176inptr = input_data[inrow];177outptr = output_data[outrow];178outend = outptr + cinfo->output_width;179while (outptr < outend) {180invalue = *inptr++; /* don't need GETJSAMPLE() here */181for (h = h_expand; h > 0; h--) {182*outptr++ = invalue;183}184}185/* Generate any additional output rows by duplicating the first one */186if (v_expand > 1) {187jcopy_sample_rows(output_data, outrow, output_data, outrow+1,188v_expand-1, cinfo->output_width);189}190inrow++;191outrow += v_expand;192}193}194195196/*197* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.198* It's still a box filter.199*/200201METHODDEF(void)202h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,203JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)204{205JSAMPARRAY output_data = *output_data_ptr;206register JSAMPROW inptr, outptr;207register JSAMPLE invalue;208JSAMPROW outend;209int inrow;210211for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {212inptr = input_data[inrow];213outptr = output_data[inrow];214outend = outptr + cinfo->output_width;215while (outptr < outend) {216invalue = *inptr++; /* don't need GETJSAMPLE() here */217*outptr++ = invalue;218*outptr++ = invalue;219}220}221}222223224/*225* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.226* It's still a box filter.227*/228229METHODDEF(void)230h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,231JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)232{233JSAMPARRAY output_data = *output_data_ptr;234register JSAMPROW inptr, outptr;235register JSAMPLE invalue;236JSAMPROW outend;237int inrow, outrow;238239inrow = outrow = 0;240while (outrow < cinfo->max_v_samp_factor) {241inptr = input_data[inrow];242outptr = output_data[outrow];243outend = outptr + cinfo->output_width;244while (outptr < outend) {245invalue = *inptr++; /* don't need GETJSAMPLE() here */246*outptr++ = invalue;247*outptr++ = invalue;248}249jcopy_sample_rows(output_data, outrow, output_data, outrow+1,2501, cinfo->output_width);251inrow++;252outrow += 2;253}254}255256257/*258* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.259*260* The upsampling algorithm is linear interpolation between pixel centers,261* also known as a "triangle filter". This is a good compromise between262* speed and visual quality. The centers of the output pixels are 1/4 and 3/4263* of the way between input pixel centers.264*265* A note about the "bias" calculations: when rounding fractional values to266* integer, we do not want to always round 0.5 up to the next integer.267* If we did that, we'd introduce a noticeable bias towards larger values.268* Instead, this code is arranged so that 0.5 will be rounded up or down at269* alternate pixel locations (a simple ordered dither pattern).270*/271272METHODDEF(void)273h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,274JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)275{276JSAMPARRAY output_data = *output_data_ptr;277register JSAMPROW inptr, outptr;278register int invalue;279register JDIMENSION colctr;280int inrow;281282for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {283inptr = input_data[inrow];284outptr = output_data[inrow];285/* Special case for first column */286invalue = GETJSAMPLE(*inptr++);287*outptr++ = (JSAMPLE) invalue;288*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);289290for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {291/* General case: 3/4 * nearer pixel + 1/4 * further pixel */292invalue = GETJSAMPLE(*inptr++) * 3;293*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);294*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);295}296297/* Special case for last column */298invalue = GETJSAMPLE(*inptr);299*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);300*outptr++ = (JSAMPLE) invalue;301}302}303304305/*306* Fancy processing for 1:1 horizontal and 2:1 vertical (4:4:0 subsampling).307*308* This is a less common case, but it can be encountered when losslessly309* rotating/transposing a JPEG file that uses 4:2:2 chroma subsampling.310*/311312METHODDEF(void)313h1v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,314JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)315{316JSAMPARRAY output_data = *output_data_ptr;317JSAMPROW inptr0, inptr1, outptr;318#if BITS_IN_JSAMPLE == 8319int thiscolsum;320#else321JLONG thiscolsum;322#endif323JDIMENSION colctr;324int inrow, outrow, v;325326inrow = outrow = 0;327while (outrow < cinfo->max_v_samp_factor) {328for (v = 0; v < 2; v++) {329/* inptr0 points to nearest input row, inptr1 points to next nearest */330inptr0 = input_data[inrow];331if (v == 0) /* next nearest is row above */332inptr1 = input_data[inrow-1];333else /* next nearest is row below */334inptr1 = input_data[inrow+1];335outptr = output_data[outrow++];336337for(colctr = 0; colctr < compptr->downsampled_width; colctr++) {338thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);339*outptr++ = (JSAMPLE) ((thiscolsum + 1) >> 2);340}341}342inrow++;343}344}345346347/*348* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.349* Again a triangle filter; see comments for h2v1 case, above.350*351* It is OK for us to reference the adjacent input rows because we demanded352* context from the main buffer controller (see initialization code).353*/354355METHODDEF(void)356h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info *compptr,357JSAMPARRAY input_data, JSAMPARRAY *output_data_ptr)358{359JSAMPARRAY output_data = *output_data_ptr;360register JSAMPROW inptr0, inptr1, outptr;361#if BITS_IN_JSAMPLE == 8362register int thiscolsum, lastcolsum, nextcolsum;363#else364register JLONG thiscolsum, lastcolsum, nextcolsum;365#endif366register JDIMENSION colctr;367int inrow, outrow, v;368369inrow = outrow = 0;370while (outrow < cinfo->max_v_samp_factor) {371for (v = 0; v < 2; v++) {372/* inptr0 points to nearest input row, inptr1 points to next nearest */373inptr0 = input_data[inrow];374if (v == 0) /* next nearest is row above */375inptr1 = input_data[inrow-1];376else /* next nearest is row below */377inptr1 = input_data[inrow+1];378outptr = output_data[outrow++];379380/* Special case for first column */381thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);382nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);383*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);384*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);385lastcolsum = thiscolsum; thiscolsum = nextcolsum;386387for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {388/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */389/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */390nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);391*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);392*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);393lastcolsum = thiscolsum; thiscolsum = nextcolsum;394}395396/* Special case for last column */397*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);398*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);399}400inrow++;401}402}403404405/*406* Module initialization routine for upsampling.407*/408409GLOBAL(void)410jinit_upsampler (j_decompress_ptr cinfo)411{412my_upsample_ptr upsample;413int ci;414jpeg_component_info *compptr;415boolean need_buffer, do_fancy;416int h_in_group, v_in_group, h_out_group, v_out_group;417418if (!cinfo->master->jinit_upsampler_no_alloc) {419upsample = (my_upsample_ptr)420(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,421sizeof(my_upsampler));422cinfo->upsample = (struct jpeg_upsampler *) upsample;423upsample->pub.start_pass = start_pass_upsample;424upsample->pub.upsample = sep_upsample;425upsample->pub.need_context_rows = FALSE; /* until we find out differently */426} else427upsample = (my_upsample_ptr) cinfo->upsample;428429if (cinfo->CCIR601_sampling) /* this isn't supported */430ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);431432/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,433* so don't ask for it.434*/435do_fancy = cinfo->do_fancy_upsampling && cinfo->_min_DCT_scaled_size > 1;436437/* Verify we can handle the sampling factors, select per-component methods,438* and create storage as needed.439*/440for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;441ci++, compptr++) {442/* Compute size of an "input group" after IDCT scaling. This many samples443* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.444*/445h_in_group = (compptr->h_samp_factor * compptr->_DCT_scaled_size) /446cinfo->_min_DCT_scaled_size;447v_in_group = (compptr->v_samp_factor * compptr->_DCT_scaled_size) /448cinfo->_min_DCT_scaled_size;449h_out_group = cinfo->max_h_samp_factor;450v_out_group = cinfo->max_v_samp_factor;451upsample->rowgroup_height[ci] = v_in_group; /* save for use later */452need_buffer = TRUE;453if (! compptr->component_needed) {454/* Don't bother to upsample an uninteresting component. */455upsample->methods[ci] = noop_upsample;456need_buffer = FALSE;457} else if (h_in_group == h_out_group && v_in_group == v_out_group) {458/* Fullsize components can be processed without any work. */459upsample->methods[ci] = fullsize_upsample;460need_buffer = FALSE;461} else if (h_in_group * 2 == h_out_group &&462v_in_group == v_out_group) {463/* Special cases for 2h1v upsampling */464if (do_fancy && compptr->downsampled_width > 2) {465if (jsimd_can_h2v1_fancy_upsample())466upsample->methods[ci] = jsimd_h2v1_fancy_upsample;467else468upsample->methods[ci] = h2v1_fancy_upsample;469} else {470if (jsimd_can_h2v1_upsample())471upsample->methods[ci] = jsimd_h2v1_upsample;472else473upsample->methods[ci] = h2v1_upsample;474}475} else if (h_in_group == h_out_group &&476v_in_group * 2 == v_out_group && do_fancy) {477/* Non-fancy upsampling is handled by the generic method */478upsample->methods[ci] = h1v2_fancy_upsample;479upsample->pub.need_context_rows = TRUE;480} else if (h_in_group * 2 == h_out_group &&481v_in_group * 2 == v_out_group) {482/* Special cases for 2h2v upsampling */483if (do_fancy && compptr->downsampled_width > 2) {484if (jsimd_can_h2v2_fancy_upsample())485upsample->methods[ci] = jsimd_h2v2_fancy_upsample;486else487upsample->methods[ci] = h2v2_fancy_upsample;488upsample->pub.need_context_rows = TRUE;489} else {490if (jsimd_can_h2v2_upsample())491upsample->methods[ci] = jsimd_h2v2_upsample;492else493upsample->methods[ci] = h2v2_upsample;494}495} else if ((h_out_group % h_in_group) == 0 &&496(v_out_group % v_in_group) == 0) {497/* Generic integral-factors upsampling method */498#if defined(__mips__)499if (jsimd_can_int_upsample())500upsample->methods[ci] = jsimd_int_upsample;501else502#endif503upsample->methods[ci] = int_upsample;504upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);505upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);506} else507ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);508if (need_buffer && !cinfo->master->jinit_upsampler_no_alloc) {509upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)510((j_common_ptr) cinfo, JPOOL_IMAGE,511(JDIMENSION) jround_up((long) cinfo->output_width,512(long) cinfo->max_h_samp_factor),513(JDIMENSION) cinfo->max_v_samp_factor);514}515}516}517518519