Path: blob/master/src/java.desktop/share/native/libjavajpeg/jdsample.c
41149 views
/*1* reserved comment block2* DO NOT REMOVE OR ALTER!3*/4/*5* jdsample.c6*7* Copyright (C) 1991-1996, Thomas G. Lane.8* This file is part of the Independent JPEG Group's software.9* For conditions of distribution and use, see the accompanying README file.10*11* This file contains upsampling routines.12*13* Upsampling input data is counted in "row groups". A row group14* is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)15* sample rows of each component. Upsampling will normally produce16* max_v_samp_factor pixel rows from each row group (but this could vary17* if the upsampler is applying a scale factor of its own).18*19* An excellent reference for image resampling is20* Digital Image Warping, George Wolberg, 1990.21* Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.22*/2324#define JPEG_INTERNALS25#include "jinclude.h"26#include "jpeglib.h"272829/* Pointer to routine to upsample a single component */30typedef JMETHOD(void, upsample1_ptr,31(j_decompress_ptr cinfo, jpeg_component_info * compptr,32JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));3334/* Private subobject */3536typedef struct {37struct jpeg_upsampler pub; /* public fields */3839/* Color conversion buffer. When using separate upsampling and color40* conversion steps, this buffer holds one upsampled row group until it41* has been color converted and output.42* Note: we do not allocate any storage for component(s) which are full-size,43* ie do not need rescaling. The corresponding entry of color_buf[] is44* simply set to point to the input data array, thereby avoiding copying.45*/46JSAMPARRAY color_buf[MAX_COMPONENTS];4748/* Per-component upsampling method pointers */49upsample1_ptr methods[MAX_COMPONENTS];5051int next_row_out; /* counts rows emitted from color_buf */52JDIMENSION rows_to_go; /* counts rows remaining in image */5354/* Height of an input row group for each component. */55int rowgroup_height[MAX_COMPONENTS];5657/* These arrays save pixel expansion factors so that int_expand need not58* recompute them each time. They are unused for other upsampling methods.59*/60UINT8 h_expand[MAX_COMPONENTS];61UINT8 v_expand[MAX_COMPONENTS];62} my_upsampler;6364typedef my_upsampler * my_upsample_ptr;656667/*68* Initialize for an upsampling pass.69*/7071METHODDEF(void)72start_pass_upsample (j_decompress_ptr cinfo)73{74my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;7576/* Mark the conversion buffer empty */77upsample->next_row_out = cinfo->max_v_samp_factor;78/* Initialize total-height counter for detecting bottom of image */79upsample->rows_to_go = cinfo->output_height;80}818283/*84* Control routine to do upsampling (and color conversion).85*86* In this version we upsample each component independently.87* We upsample one row group into the conversion buffer, then apply88* color conversion a row at a time.89*/9091METHODDEF(void)92sep_upsample (j_decompress_ptr cinfo,93JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,94JDIMENSION in_row_groups_avail,95JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,96JDIMENSION out_rows_avail)97{98my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;99int ci;100jpeg_component_info * compptr;101JDIMENSION num_rows;102103/* Fill the conversion buffer, if it's empty */104if (upsample->next_row_out >= cinfo->max_v_samp_factor) {105for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;106ci++, compptr++) {107/* Invoke per-component upsample method. Notice we pass a POINTER108* to color_buf[ci], so that fullsize_upsample can change it.109*/110(*upsample->methods[ci]) (cinfo, compptr,111input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),112upsample->color_buf + ci);113}114upsample->next_row_out = 0;115}116117/* Color-convert and emit rows */118119/* How many we have in the buffer: */120num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);121/* Not more than the distance to the end of the image. Need this test122* in case the image height is not a multiple of max_v_samp_factor:123*/124if (num_rows > upsample->rows_to_go)125num_rows = upsample->rows_to_go;126/* And not more than what the client can accept: */127out_rows_avail -= *out_row_ctr;128if (num_rows > out_rows_avail)129num_rows = out_rows_avail;130131(*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,132(JDIMENSION) upsample->next_row_out,133output_buf + *out_row_ctr,134(int) num_rows);135136/* Adjust counts */137*out_row_ctr += num_rows;138upsample->rows_to_go -= num_rows;139upsample->next_row_out += num_rows;140/* When the buffer is emptied, declare this input row group consumed */141if (upsample->next_row_out >= cinfo->max_v_samp_factor)142(*in_row_group_ctr)++;143}144145146/*147* These are the routines invoked by sep_upsample to upsample pixel values148* of a single component. One row group is processed per call.149*/150151152/*153* For full-size components, we just make color_buf[ci] point at the154* input buffer, and thus avoid copying any data. Note that this is155* safe only because sep_upsample doesn't declare the input row group156* "consumed" until we are done color converting and emitting it.157*/158159METHODDEF(void)160fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,161JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)162{163*output_data_ptr = input_data;164}165166167/*168* This is a no-op version used for "uninteresting" components.169* These components will not be referenced by color conversion.170*/171172METHODDEF(void)173noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,174JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)175{176*output_data_ptr = NULL; /* safety check */177}178179180/*181* This version handles any integral sampling ratios.182* This is not used for typical JPEG files, so it need not be fast.183* Nor, for that matter, is it particularly accurate: the algorithm is184* simple replication of the input pixel onto the corresponding output185* pixels. The hi-falutin sampling literature refers to this as a186* "box filter". A box filter tends to introduce visible artifacts,187* so if you are actually going to use 3:1 or 4:1 sampling ratios188* you would be well advised to improve this code.189*/190191METHODDEF(void)192int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,193JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)194{195my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;196JSAMPARRAY output_data = *output_data_ptr;197register JSAMPROW inptr, outptr;198register JSAMPLE invalue;199register int h;200JSAMPROW outend;201int h_expand, v_expand;202int inrow, outrow;203204h_expand = upsample->h_expand[compptr->component_index];205v_expand = upsample->v_expand[compptr->component_index];206207inrow = outrow = 0;208while (outrow < cinfo->max_v_samp_factor) {209/* Generate one output row with proper horizontal expansion */210inptr = input_data[inrow];211outptr = output_data[outrow];212outend = outptr + cinfo->output_width;213while (outptr < outend) {214invalue = *inptr++; /* don't need GETJSAMPLE() here */215for (h = h_expand; h > 0; h--) {216*outptr++ = invalue;217}218}219/* Generate any additional output rows by duplicating the first one */220if (v_expand > 1) {221jcopy_sample_rows(output_data, outrow, output_data, outrow+1,222v_expand-1, cinfo->output_width);223}224inrow++;225outrow += v_expand;226}227}228229230/*231* Fast processing for the common case of 2:1 horizontal and 1:1 vertical.232* It's still a box filter.233*/234235METHODDEF(void)236h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,237JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)238{239JSAMPARRAY output_data = *output_data_ptr;240register JSAMPROW inptr, outptr;241register JSAMPLE invalue;242JSAMPROW outend;243int inrow;244245for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {246inptr = input_data[inrow];247outptr = output_data[inrow];248outend = outptr + cinfo->output_width;249while (outptr < outend) {250invalue = *inptr++; /* don't need GETJSAMPLE() here */251*outptr++ = invalue;252*outptr++ = invalue;253}254}255}256257258/*259* Fast processing for the common case of 2:1 horizontal and 2:1 vertical.260* It's still a box filter.261*/262263METHODDEF(void)264h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,265JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)266{267JSAMPARRAY output_data = *output_data_ptr;268register JSAMPROW inptr, outptr;269register JSAMPLE invalue;270JSAMPROW outend;271int inrow, outrow;272273inrow = outrow = 0;274while (outrow < cinfo->max_v_samp_factor) {275inptr = input_data[inrow];276outptr = output_data[outrow];277outend = outptr + cinfo->output_width;278while (outptr < outend) {279invalue = *inptr++; /* don't need GETJSAMPLE() here */280*outptr++ = invalue;281*outptr++ = invalue;282}283jcopy_sample_rows(output_data, outrow, output_data, outrow+1,2841, cinfo->output_width);285inrow++;286outrow += 2;287}288}289290291/*292* Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.293*294* The upsampling algorithm is linear interpolation between pixel centers,295* also known as a "triangle filter". This is a good compromise between296* speed and visual quality. The centers of the output pixels are 1/4 and 3/4297* of the way between input pixel centers.298*299* A note about the "bias" calculations: when rounding fractional values to300* integer, we do not want to always round 0.5 up to the next integer.301* If we did that, we'd introduce a noticeable bias towards larger values.302* Instead, this code is arranged so that 0.5 will be rounded up or down at303* alternate pixel locations (a simple ordered dither pattern).304*/305306METHODDEF(void)307h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,308JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)309{310JSAMPARRAY output_data = *output_data_ptr;311register JSAMPROW inptr, outptr;312register int invalue;313register JDIMENSION colctr;314int inrow;315316for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {317inptr = input_data[inrow];318outptr = output_data[inrow];319/* Special case for first column */320invalue = GETJSAMPLE(*inptr++);321*outptr++ = (JSAMPLE) invalue;322*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);323324for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {325/* General case: 3/4 * nearer pixel + 1/4 * further pixel */326invalue = GETJSAMPLE(*inptr++) * 3;327*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);328*outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);329}330331/* Special case for last column */332invalue = GETJSAMPLE(*inptr);333*outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);334*outptr++ = (JSAMPLE) invalue;335}336}337338339/*340* Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.341* Again a triangle filter; see comments for h2v1 case, above.342*343* It is OK for us to reference the adjacent input rows because we demanded344* context from the main buffer controller (see initialization code).345*/346347METHODDEF(void)348h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,349JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)350{351JSAMPARRAY output_data = *output_data_ptr;352register JSAMPROW inptr0, inptr1, outptr;353#if BITS_IN_JSAMPLE == 8354register int thiscolsum, lastcolsum, nextcolsum;355#else356register INT32 thiscolsum, lastcolsum, nextcolsum;357#endif358register JDIMENSION colctr;359int inrow, outrow, v;360361inrow = outrow = 0;362while (outrow < cinfo->max_v_samp_factor) {363for (v = 0; v < 2; v++) {364/* inptr0 points to nearest input row, inptr1 points to next nearest */365inptr0 = input_data[inrow];366if (v == 0) /* next nearest is row above */367inptr1 = input_data[inrow-1];368else /* next nearest is row below */369inptr1 = input_data[inrow+1];370outptr = output_data[outrow++];371372/* Special case for first column */373thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);374nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);375*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);376*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);377lastcolsum = thiscolsum; thiscolsum = nextcolsum;378379for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {380/* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */381/* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */382nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);383*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);384*outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);385lastcolsum = thiscolsum; thiscolsum = nextcolsum;386}387388/* Special case for last column */389*outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);390*outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);391}392inrow++;393}394}395396397/*398* Module initialization routine for upsampling.399*/400401GLOBAL(void)402jinit_upsampler (j_decompress_ptr cinfo)403{404my_upsample_ptr upsample;405int ci;406jpeg_component_info * compptr;407boolean need_buffer, do_fancy;408int h_in_group, v_in_group, h_out_group, v_out_group;409410upsample = (my_upsample_ptr)411(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,412SIZEOF(my_upsampler));413cinfo->upsample = (struct jpeg_upsampler *) upsample;414upsample->pub.start_pass = start_pass_upsample;415upsample->pub.upsample = sep_upsample;416upsample->pub.need_context_rows = FALSE; /* until we find out differently */417418if (cinfo->CCIR601_sampling) /* this isn't supported */419ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);420421/* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,422* so don't ask for it.423*/424do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;425426/* Verify we can handle the sampling factors, select per-component methods,427* and create storage as needed.428*/429for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;430ci++, compptr++) {431/* Compute size of an "input group" after IDCT scaling. This many samples432* are to be converted to max_h_samp_factor * max_v_samp_factor pixels.433*/434h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /435cinfo->min_DCT_scaled_size;436v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /437cinfo->min_DCT_scaled_size;438h_out_group = cinfo->max_h_samp_factor;439v_out_group = cinfo->max_v_samp_factor;440upsample->rowgroup_height[ci] = v_in_group; /* save for use later */441need_buffer = TRUE;442if (! compptr->component_needed) {443/* Don't bother to upsample an uninteresting component. */444upsample->methods[ci] = noop_upsample;445need_buffer = FALSE;446} else if (h_in_group == h_out_group && v_in_group == v_out_group) {447/* Fullsize components can be processed without any work. */448upsample->methods[ci] = fullsize_upsample;449need_buffer = FALSE;450} else if (h_in_group * 2 == h_out_group &&451v_in_group == v_out_group) {452/* Special cases for 2h1v upsampling */453if (do_fancy && compptr->downsampled_width > 2)454upsample->methods[ci] = h2v1_fancy_upsample;455else456upsample->methods[ci] = h2v1_upsample;457} else if (h_in_group * 2 == h_out_group &&458v_in_group * 2 == v_out_group) {459/* Special cases for 2h2v upsampling */460if (do_fancy && compptr->downsampled_width > 2) {461upsample->methods[ci] = h2v2_fancy_upsample;462upsample->pub.need_context_rows = TRUE;463} else464upsample->methods[ci] = h2v2_upsample;465} else if ((h_out_group % h_in_group) == 0 &&466(v_out_group % v_in_group) == 0) {467/* Generic integral-factors upsampling method */468upsample->methods[ci] = int_upsample;469upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);470upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);471} else472ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);473if (need_buffer) {474upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)475((j_common_ptr) cinfo, JPOOL_IMAGE,476(JDIMENSION) jround_up((long) cinfo->output_width,477(long) cinfo->max_h_samp_factor),478(JDIMENSION) cinfo->max_v_samp_factor);479}480}481}482483484