19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jcsample.c 39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1991-1996, Thomas G. Lane. 59f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file is part of the Independent JPEG Group's software. 69f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For conditions of distribution and use, see the accompanying README file. 79f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 89f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This file contains downsampling routines. 99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsampling input data is counted in "row groups". A row group 119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is defined to be max_v_samp_factor pixel rows of each component, 129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * from which the downsampler produces v_samp_factor sample rows. 139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * A single row group is processed in each call to the downsampler module. 149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The downsampler is responsible for edge-expansion of its output data 169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to fill an integral number of DCT blocks horizontally. The source buffer 179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * may be modified if it is helpful for this purpose (the source buffer is 189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * allocated wide enough to correspond to the desired output width). 199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The caller (the prep controller) is responsible for vertical padding. 209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The downsampler may request "context rows" by setting need_context_rows 229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * during startup. In this case, the input arrays will contain at least 239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * one row group's worth of pixels above and below the passed-in data; 249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the caller will create dummy rows at image top and bottom by replicating 259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the first or last real pixel row. 269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * An excellent reference for image resampling is 289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Digital Image Warping, George Wolberg, 1990. 299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. 309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The downsampling algorithm used here is a simple average of the source 329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * pixels covered by the output pixel. The hi-falutin sampling literature 339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * refers to this as a "box filter". In general the characteristics of a box 349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * filter are not very good, but for the specific cases we normally use (1:1 359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not 369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * nearly so bad. If you intend to use other sampling ratios, you'd be well 379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * advised to improve this code. 389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * A simple input-smoothing capability is provided. This is mainly intended 409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * for cleaning up color-dithered GIF input files (if you find it inadequate, 419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * we suggest using an external filtering program such as pnmconvol). When 429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * enabled, each input pixel P is replaced by a weighted sum of itself and its 439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF, 449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * where SF = (smoothing_factor / 1024). 459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Currently, smoothing is only supported for 2h2v sampling factors. 469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define JPEG_INTERNALS 499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h" 509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h" 519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Pointer to routine to downsample a single component */ 549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef JMETHOD(void, downsample1_ptr, 559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (j_compress_ptr cinfo, jpeg_component_info * compptr, 569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data)); 579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Private subobject */ 599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct { 619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project struct jpeg_downsampler pub; /* public fields */ 629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Downsampling method pointers, one per component */ 649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample1_ptr methods[MAX_COMPONENTS]; 659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} my_downsampler; 669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef my_downsampler * my_downsample_ptr; 689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize for a downsampling pass. 729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectstart_pass_downsample (j_compress_ptr cinfo) 769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* no work for now */ 789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Expand a component horizontally from width input_cols to width output_cols, 839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by duplicating the rightmost samples. 849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void) 879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectexpand_right_edge (JSAMPARRAY image_data, int num_rows, 889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION input_cols, JDIMENSION output_cols) 899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW ptr; 919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPLE pixval; 929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int count; 939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int row; 949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int numcols = (int) (output_cols - input_cols); 959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (numcols > 0) { 979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (row = 0; row < num_rows; row++) { 989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ptr = image_data[row] + input_cols; 999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project pixval = ptr[-1]; /* don't need GETJSAMPLE() here */ 1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (count = numcols; count > 0; count--) 1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *ptr++ = pixval; 1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Do downsampling for a whole row group (all components). 1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In this version we simply downsample each component independently. 1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectsep_downsample (j_compress_ptr cinfo, 1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPIMAGE input_buf, JDIMENSION in_row_index, 1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPIMAGE output_buf, JDIMENSION out_row_group_index) 1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample; 1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int ci; 1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jpeg_component_info * compptr; 1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY in_ptr, out_ptr; 1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ci++, compptr++) { 1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project in_ptr = input_buf[ci] + in_row_index; 1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor); 1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr); 1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * One row group is processed per call. 1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles arbitrary integral sampling ratios, without smoothing. 1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note that this version is not actually used for customary sampling ratios. 1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectint_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, 1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; 1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ 1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; 1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPROW inptr, outptr; 1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project INT32 outvalue; 1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor; 1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor; 1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project numpix = h_expand * v_expand; 1529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project numpix2 = numpix/2; 1539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Expand input data enough to let all the output samples be generated 1559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by the standard loop. Special-casing padded output would be more 1569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * efficient. 1579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(input_data, cinfo->max_v_samp_factor, 1599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, output_cols * h_expand); 1609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow = 0; 1629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { 1639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outptr = output_data[outrow]; 1649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outcol = 0, outcol_h = 0; outcol < output_cols; 1659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outcol++, outcol_h += h_expand) { 1669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outvalue = 0; 1679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (v = 0; v < v_expand; v++) { 1689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr = input_data[inrow+v] + outcol_h; 1699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (h = 0; h < h_expand; h++) { 1709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outvalue += (INT32) GETJSAMPLE(*inptr++); 1719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix); 1749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow += v_expand; 1769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 1779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 1789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 1819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 1829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles the special case of a full-size component, 1839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * without smoothing. 1849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 1859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 1879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, 1889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 1899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 1909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Copy the data */ 1919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jcopy_sample_rows(input_data, 0, output_data, 0, 1929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->max_v_samp_factor, cinfo->image_width); 1939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Edge-expand */ 1949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(output_data, cinfo->max_v_samp_factor, 1959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, compptr->width_in_blocks * DCTSIZE); 1969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 1979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 1999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 2009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 2019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles the common case of 2:1 horizontal and 1:1 vertical, 2029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * without smoothing. 2039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * 2049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * A note about the "bias" calculations: when rounding fractional values to 2059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * integer, we do not want to always round 0.5 up to the next integer. 2069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * If we did that, we'd introduce a noticeable bias towards larger values. 2079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Instead, this code is arranged so that 0.5 will be rounded up or down at 2089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * alternate pixel locations (a simple ordered dither pattern). 2099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 2129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecth2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, 2139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 2149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int outrow; 2169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION outcol; 2179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; 2189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW inptr, outptr; 2199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int bias; 2209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Expand input data enough to let all the output samples be generated 2229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by the standard loop. Special-casing padded output would be more 2239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * efficient. 2249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(input_data, cinfo->max_v_samp_factor, 2269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, output_cols * 2); 2279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { 2299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outptr = output_data[outrow]; 2309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr = input_data[outrow]; 2319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bias = 0; /* bias = 0,1,0,1,... for successive samples */ 2329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outcol = 0; outcol < output_cols; outcol++) { 2339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1]) 2349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project + bias) >> 1); 2359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bias ^= 1; /* 0=>1, 1=>0 */ 2369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr += 2; 2379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 2409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 2439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 2449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles the standard case of 2:1 horizontal and 2:1 vertical, 2459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * without smoothing. 2469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 2499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecth2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, 2509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 2519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int inrow, outrow; 2539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION outcol; 2549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; 2559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW inptr0, inptr1, outptr; 2569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register int bias; 2579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Expand input data enough to let all the output samples be generated 2599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by the standard loop. Special-casing padded output would be more 2609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * efficient. 2619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(input_data, cinfo->max_v_samp_factor, 2639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, output_cols * 2); 2649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow = 0; 2669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { 2679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outptr = output_data[outrow]; 2689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr0 = input_data[inrow]; 2699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr1 = input_data[inrow+1]; 2709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bias = 1; /* bias = 1,2,1,2,... for successive samples */ 2719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outcol = 0; outcol < output_cols; outcol++) { 2729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + 2739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]) 2749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project + bias) >> 2); 2759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project bias ^= 3; /* 1=>2, 2=>1 */ 2769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr0 += 2; inptr1 += 2; 2779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow += 2; 2799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 2809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 2819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef INPUT_SMOOTHING_SUPPORTED 2849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 2869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 2879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles the standard case of 2:1 horizontal and 2:1 vertical, 2889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * with smoothing. One row of context is required. 2899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 2909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 2919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 2929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecth2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, 2939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 2949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 2959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int inrow, outrow; 2969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION colctr; 2979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; 2989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; 2999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project INT32 membersum, neighsum, memberscale, neighscale; 3009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Expand input data enough to let all the output samples be generated 3029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by the standard loop. Special-casing padded output would be more 3039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * efficient. 3049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, 3069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, output_cols * 2); 3079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* We don't bother to form the individual "smoothed" input pixel values; 3099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * we can directly compute the output which is the average of the four 3109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * smoothed values. Each of the four member pixels contributes a fraction 3119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * (1-8*SF) to its own smoothed image and a fraction SF to each of the three 3129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final 3139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * output. The four corner-adjacent neighbor pixels contribute a fraction 3149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * SF to just one smoothed pixel, or SF/4 to the final output; while the 3159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * eight edge-adjacent neighbors contribute SF to each of two smoothed 3169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * pixels, or SF/2 overall. In order to use integer arithmetic, these 3179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * factors are scaled by 2^16 = 65536. 3189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Also recall that SF = smoothing_factor / 1024. 3199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */ 3229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */ 3239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow = 0; 3259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { 3269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outptr = output_data[outrow]; 3279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr0 = input_data[inrow]; 3289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr1 = input_data[inrow+1]; 3299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project above_ptr = input_data[inrow-1]; 3309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project below_ptr = input_data[inrow+2]; 3319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Special case for first column: pretend column -1 is same as column 0 */ 3339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + 3349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); 3359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + 3369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + 3379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) + 3389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]); 3399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += neighsum; 3409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) + 3419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]); 3429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 3439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); 3449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; 3459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (colctr = output_cols - 2; colctr > 0; colctr--) { 3479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* sum of pixels directly mapped to this output element */ 3489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + 3499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); 3509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* sum of edge-neighbor pixels */ 3519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + 3529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + 3539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) + 3549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]); 3559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* The edge-neighbors count twice as much as corner-neighbors */ 3569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += neighsum; 3579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Add in the corner-neighbors */ 3589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) + 3599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]); 3609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* form final output scaled up by 2^16 */ 3619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 3629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* round, descale and output it */ 3639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); 3649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2; 3659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Special case for last column */ 3689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) + 3699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]); 3709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) + 3719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) + 3729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) + 3739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]); 3749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += neighsum; 3759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) + 3769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]); 3779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 3789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr = (JSAMPLE) ((membersum + 32768) >> 16); 3799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inrow += 2; 3819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 3829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 3839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 3869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsample pixel values of a single component. 3879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This version handles the special case of a full-size component, 3889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * with smoothing. One row of context is required. 3899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 3909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 3919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void) 3929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectfullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, 3939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JSAMPARRAY input_data, JSAMPARRAY output_data) 3949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 3959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int outrow; 3969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION colctr; 3979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; 3989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project register JSAMPROW inptr, above_ptr, below_ptr, outptr; 3999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project INT32 membersum, neighsum, memberscale, neighscale; 4009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int colsum, lastcolsum, nextcolsum; 4019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Expand input data enough to let all the output samples be generated 4039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by the standard loop. Special-casing padded output would be more 4049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * efficient. 4059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2, 4079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->image_width, output_cols); 4089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Each of the eight neighbor pixels contributes a fraction SF to the 4109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * smoothed pixel, while the main pixel contributes (1-8*SF). In order 4119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * to use integer arithmetic, these factors are multiplied by 2^16 = 65536. 4129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Also recall that SF = smoothing_factor / 1024. 4139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */ 4169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighscale = cinfo->smoothing_factor * 64; /* scaled SF */ 4179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) { 4199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project outptr = output_data[outrow]; 4209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project inptr = input_data[outrow]; 4219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project above_ptr = input_data[outrow-1]; 4229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project below_ptr = input_data[outrow+1]; 4239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Special case for first column */ 4259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) + 4269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr); 4279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr++); 4289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + 4299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr); 4309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = colsum + (colsum - membersum) + nextcolsum; 4319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 4329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); 4339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project lastcolsum = colsum; colsum = nextcolsum; 4349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (colctr = output_cols - 2; colctr > 0; colctr--) { 4369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr++); 4379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project above_ptr++; below_ptr++; 4389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) + 4399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project GETJSAMPLE(*inptr); 4409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = lastcolsum + (colsum - membersum) + nextcolsum; 4419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 4429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16); 4439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project lastcolsum = colsum; colsum = nextcolsum; 4449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Special case for last column */ 4479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = GETJSAMPLE(*inptr); 4489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project neighsum = lastcolsum + (colsum - membersum) + colsum; 4499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project membersum = membersum * memberscale + neighsum * neighscale; 4509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *outptr = (JSAMPLE) ((membersum + 32768) >> 16); 4519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 4539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 4549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif /* INPUT_SMOOTHING_SUPPORTED */ 4569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* 4599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Module initialization routine for downsampling. 4609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Note that we must select a routine for each component. 4619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */ 4629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void) 4649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjinit_downsampler (j_compress_ptr cinfo) 4659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{ 4669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project my_downsample_ptr downsample; 4679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project int ci; 4689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project jpeg_component_info * compptr; 4699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project boolean smoothok = TRUE; 4709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample = (my_downsample_ptr) 4729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 4739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project SIZEOF(my_downsampler)); 4749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project cinfo->downsample = (struct jpeg_downsampler *) downsample; 4759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->pub.start_pass = start_pass_downsample; 4769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->pub.downsample = sep_downsample; 4779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->pub.need_context_rows = FALSE; 4789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->CCIR601_sampling) 4809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); 4819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 4829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project /* Verify we can handle the sampling factors, and set up method pointers */ 4839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 4849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ci++, compptr++) { 4859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (compptr->h_samp_factor == cinfo->max_h_samp_factor && 4869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project compptr->v_samp_factor == cinfo->max_v_samp_factor) { 4879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef INPUT_SMOOTHING_SUPPORTED 4889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->smoothing_factor) { 4899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = fullsize_smooth_downsample; 4909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->pub.need_context_rows = TRUE; 4919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else 4929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif 4939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = fullsize_downsample; 4949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && 4959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project compptr->v_samp_factor == cinfo->max_v_samp_factor) { 4969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project smoothok = FALSE; 4979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = h2v1_downsample; 4989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor && 4999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) { 5009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef INPUT_SMOOTHING_SUPPORTED 5019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->smoothing_factor) { 5029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = h2v2_smooth_downsample; 5039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->pub.need_context_rows = TRUE; 5049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else 5059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif 5069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = h2v2_downsample; 5079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 && 5089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) { 5099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project smoothok = FALSE; 5109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project downsample->methods[ci] = int_downsample; 5119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } else 5129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); 5139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project } 5149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project 5159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef INPUT_SMOOTHING_SUPPORTED 5169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project if (cinfo->smoothing_factor && !smoothok) 5179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL); 5189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif 5199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} 520