19f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
29f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jcprepct.c
39f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
49f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Copyright (C) 1994-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 the compression preprocessing controller.
99f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This controller manages the color conversion, downsampling,
109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * and edge expansion steps.
119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Most of the complexity here is associated with buffering input rows
139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * as required by the downsampler.  See the comments at the head of
149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * jcsample.c for the downsampler's needs.
159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define JPEG_INTERNALS
189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jinclude.h"
199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#include "jpeglib.h"
209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* At present, jcsample.c can request context rows only for smoothing.
239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * In the future, we might also need context rows for CCIR601 sampling
249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * or other more-complex downsampling procedures.  The code to support
259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * context rows should be compiled only if needed.
269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef INPUT_SMOOTHING_SUPPORTED
289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#define CONTEXT_ROWS_SUPPORTED
299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * For the simple (no-context-row) case, we just need to buffer one
349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * row group's worth of pixels for the downsampling step.  At the bottom of
359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * the image, we pad to a full row group by replicating the last pixel row.
369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * The downsampler's last output row is then replicated if needed to pad
379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * out to a full iMCU row.
389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * When providing context rows, we must buffer three row groups' worth of
409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * pixels.  Three row groups are physically allocated, but the row pointer
419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * arrays are made five row groups high, with the extra pointers above and
429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * below "wrapping around" to point to the last and first real row groups.
439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * This allows the downsampler to access the proper context rows.
449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * At the top and bottom of the image, we create dummy context rows by
459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * copying the first or last real pixel row.  This copying could be avoided
469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * trouble on the compression side.
489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/* Private buffer controller object */
529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef struct {
549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  struct jpeg_c_prep_controller pub; /* public fields */
559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Downsampling input buffer.  This buffer holds color-converted data
579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * until we have enough to do a downsample step.
589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPARRAY color_buf[MAX_COMPONENTS];
609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION rows_to_go;	/* counts rows remaining in source image */
629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int next_buf_row;		/* index of next row to store in color_buf */
639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef CONTEXT_ROWS_SUPPORTED	/* only needed for context case */
659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int this_row_group;		/* starting row index of group to process */
669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int next_buf_stop;		/* downsample when we reach this index */
679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project} my_prep_controller;
699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projecttypedef my_prep_controller * my_prep_ptr;
719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize for a processing pass.
759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectstart_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (pass_mode != JBUF_PASS_THRU)
839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Initialize total-height counter for detecting bottom of image */
869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep->rows_to_go = cinfo->image_height;
879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Mark the conversion buffer empty */
889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep->next_buf_row = 0;
899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef CONTEXT_ROWS_SUPPORTED
909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Preset additional state variables for context mode.
919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * These aren't used in non-context mode, so we needn't test which mode.
929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep->this_row_group = 0;
949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Set next_buf_stop to stop after two row groups have been read in. */
959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
1019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Expand an image vertically from height input_rows to height output_rows,
1029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * by duplicating the bottom row.
1039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
1069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectexpand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
1079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		    int input_rows, int output_rows)
1089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
1099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  register int row;
1109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (row = input_rows; row < output_rows; row++) {
1129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    jcopy_sample_rows(image_data, input_rows-1, image_data, row,
1139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		      1, num_cols);
1149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
1159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
1169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
1199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Process some data in the simple no-context case.
1209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project *
1219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Preprocessor output data is counted in "row groups".  A row group
1229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * is defined to be v_samp_factor sample rows of each component.
1239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Downsampling will produce this much data from each max_v_samp_factor
1249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * input rows.
1259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
1289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectpre_process_data (j_compress_ptr cinfo,
1299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
1309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  JDIMENSION in_rows_avail,
1319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
1329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		  JDIMENSION out_row_groups_avail)
1339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
1349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
1359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int numrows, ci;
1369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION inrows;
1379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  jpeg_component_info * compptr;
1389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  while (*in_row_ctr < in_rows_avail &&
1409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	 *out_row_group_ctr < out_row_groups_avail) {
1419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Do color conversion to fill the conversion buffer. */
1429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    inrows = in_rows_avail - *in_row_ctr;
1439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
1449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    numrows = (int) MIN((JDIMENSION) numrows, inrows);
1459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
1469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				       prep->color_buf,
1479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				       (JDIMENSION) prep->next_buf_row,
1489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				       numrows);
1499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    *in_row_ctr += numrows;
1509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    prep->next_buf_row += numrows;
1519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    prep->rows_to_go -= numrows;
1529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* If at bottom of image, pad to fill the conversion buffer. */
1539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (prep->rows_to_go == 0 &&
1549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	prep->next_buf_row < cinfo->max_v_samp_factor) {
1559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (ci = 0; ci < cinfo->num_components; ci++) {
1569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
1579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			   prep->next_buf_row, cinfo->max_v_samp_factor);
1589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
1599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->next_buf_row = cinfo->max_v_samp_factor;
1609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
1619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* If we've filled the conversion buffer, empty it. */
1629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (prep->next_buf_row == cinfo->max_v_samp_factor) {
1639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      (*cinfo->downsample->downsample) (cinfo,
1649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					prep->color_buf, (JDIMENSION) 0,
1659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					output_buf, *out_row_group_ctr);
1669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->next_buf_row = 0;
1679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      (*out_row_group_ctr)++;
1689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
1699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* If at bottom of image, pad the output to a full iMCU height.
1709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * Note we assume the caller is providing a one-iMCU-height output buffer!
1719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
1729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (prep->rows_to_go == 0 &&
1739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	*out_row_group_ctr < out_row_groups_avail) {
1749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
1759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	   ci++, compptr++) {
1769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	expand_bottom_edge(output_buf[ci],
1779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			   compptr->width_in_blocks * DCTSIZE,
1789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			   (int) (*out_row_group_ctr * compptr->v_samp_factor),
1799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			   (int) (out_row_groups_avail * compptr->v_samp_factor));
1809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
1819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      *out_row_group_ctr = out_row_groups_avail;
1829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      break;			/* can exit outer loop without test */
1839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
1849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
1859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
1869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef CONTEXT_ROWS_SUPPORTED
1899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
1919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Process some data in the context case.
1929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
1939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
1949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectMETHODDEF(void)
1959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectpre_process_context (j_compress_ptr cinfo,
1969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		     JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
1979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		     JDIMENSION in_rows_avail,
1989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		     JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
1999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		     JDIMENSION out_row_groups_avail)
2009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
2019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
2029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int numrows, ci;
2039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int buf_height = cinfo->max_v_samp_factor * 3;
2049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JDIMENSION inrows;
2059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  while (*out_row_group_ctr < out_row_groups_avail) {
2079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (*in_row_ctr < in_rows_avail) {
2089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Do color conversion to fill the conversion buffer. */
2099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      inrows = in_rows_avail - *in_row_ctr;
2109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      numrows = prep->next_buf_stop - prep->next_buf_row;
2119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      numrows = (int) MIN((JDIMENSION) numrows, inrows);
2129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
2139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					 prep->color_buf,
2149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					 (JDIMENSION) prep->next_buf_row,
2159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					 numrows);
2169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Pad at top of image, if first time through */
2179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (prep->rows_to_go == cinfo->image_height) {
2189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (ci = 0; ci < cinfo->num_components; ci++) {
2199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  int row;
2209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
2219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    jcopy_sample_rows(prep->color_buf[ci], 0,
2229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			      prep->color_buf[ci], -row,
2239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			      1, cinfo->image_width);
2249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  }
2259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	}
2269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
2279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      *in_row_ctr += numrows;
2289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->next_buf_row += numrows;
2299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->rows_to_go -= numrows;
2309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    } else {
2319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Return for more data, unless we are at the bottom of the image. */
2329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (prep->rows_to_go != 0)
2339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	break;
2349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* When at bottom of image, pad to fill the conversion buffer. */
2359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (prep->next_buf_row < prep->next_buf_stop) {
2369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	for (ci = 0; ci < cinfo->num_components; ci++) {
2379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	  expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
2389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			     prep->next_buf_row, prep->next_buf_stop);
2399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	}
2409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	prep->next_buf_row = prep->next_buf_stop;
2419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      }
2429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
2439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* If we've gotten enough data, downsample a row group. */
2449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    if (prep->next_buf_row == prep->next_buf_stop) {
2459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      (*cinfo->downsample->downsample) (cinfo,
2469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					prep->color_buf,
2479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					(JDIMENSION) prep->this_row_group,
2489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project					output_buf, *out_row_group_ctr);
2499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      (*out_row_group_ctr)++;
2509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      /* Advance pointers with wraparound as necessary. */
2519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->this_row_group += cinfo->max_v_samp_factor;
2529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (prep->this_row_group >= buf_height)
2539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	prep->this_row_group = 0;
2549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      if (prep->next_buf_row >= buf_height)
2559f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	prep->next_buf_row = 0;
2569f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
2579f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
2589f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
2599f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
2609f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2619f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2629f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
2639f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Create the wrapped-around downsampling input buffer needed for context mode.
2649f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
2659f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2669f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectLOCAL(void)
2679f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectcreate_context_buffer (j_compress_ptr cinfo)
2689f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
2699f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
2709f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int rgroup_height = cinfo->max_v_samp_factor;
2719f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int ci, i;
2729f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  jpeg_component_info * compptr;
2739f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  JSAMPARRAY true_buffer, fake_buffer;
2749f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2759f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Grab enough space for fake row pointers for all the components;
2769f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * we need five row groups' worth of pointers for each component.
2779f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
2789f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  fake_buffer = (JSAMPARRAY)
2799f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
2809f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				(cinfo->num_components * 5 * rgroup_height) *
2819f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				SIZEOF(JSAMPROW));
2829f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
2839f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
2849f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       ci++, compptr++) {
2859f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Allocate the actual buffer space (3 row groups) for this component.
2869f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * We make the buffer wide enough to allow the downsampler to edge-expand
2879f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     * horizontally within the buffer, if it so chooses.
2889f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project     */
2899f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    true_buffer = (*cinfo->mem->alloc_sarray)
2909f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      ((j_common_ptr) cinfo, JPOOL_IMAGE,
2919f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
2929f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project		      cinfo->max_h_samp_factor) / compptr->h_samp_factor),
2939f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project       (JDIMENSION) (3 * rgroup_height));
2949f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Copy true buffer row pointers into the middle of the fake row array */
2959f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    MEMCOPY(fake_buffer + rgroup_height, true_buffer,
2969f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	    3 * rgroup_height * SIZEOF(JSAMPROW));
2979f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Fill in the above and below wraparound pointers */
2989f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (i = 0; i < rgroup_height; i++) {
2999f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      fake_buffer[i] = true_buffer[2 * rgroup_height + i];
3009f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      fake_buffer[4 * rgroup_height + i] = true_buffer[i];
3019f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
3029f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    prep->color_buf[ci] = fake_buffer + rgroup_height;
3039f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    fake_buffer += 5 * rgroup_height; /* point to space for next component */
3049f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
3059f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
3069f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3079f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif /* CONTEXT_ROWS_SUPPORTED */
3089f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3099f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3109f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project/*
3119f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project * Initialize preprocessing controller.
3129f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project */
3139f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3149f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source ProjectGLOBAL(void)
3159f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Projectjinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
3169f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project{
3179f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  my_prep_ptr prep;
3189f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  int ci;
3199f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  jpeg_component_info * compptr;
3209f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3219f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (need_full_buffer)		/* safety check */
3229f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
3239f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3249f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep = (my_prep_ptr)
3259f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
3269f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project				SIZEOF(my_prep_controller));
3279f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  cinfo->prep = (struct jpeg_c_prep_controller *) prep;
3289f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  prep->pub.start_pass = start_pass_prep;
3299f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project
3309f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  /* Allocate the color conversion buffer.
3319f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * We make the buffer wide enough to allow the downsampler to edge-expand
3329f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   * horizontally within the buffer, if it so chooses.
3339f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project   */
3349f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  if (cinfo->downsample->need_context_rows) {
3359f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* Set up to provide context rows */
3369f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#ifdef CONTEXT_ROWS_SUPPORTED
3379f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    prep->pub.pre_process_data = pre_process_context;
3389f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    create_context_buffer(cinfo);
3399f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#else
3409f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    ERREXIT(cinfo, JERR_NOT_COMPILED);
3419f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project#endif
3429f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  } else {
3439f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    /* No context, just make it tall enough for one row group */
3449f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    prep->pub.pre_process_data = pre_process_data;
3459f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
3469f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	 ci++, compptr++) {
3479f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project      prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
3489f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	((j_common_ptr) cinfo, JPOOL_IMAGE,
3499f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	 (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
3509f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project			cinfo->max_h_samp_factor) / compptr->h_samp_factor),
3519f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project	 (JDIMENSION) cinfo->max_v_samp_factor);
3529f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project    }
3539f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project  }
3549f5d49a1588e438ae7ceabd0c94172117e3303aaThe Android Open Source Project}
355