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