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