1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FX_JPEG_TURBO_) 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * jcprepct.c 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (C) 1994-1996, Thomas G. Lane. 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This file is part of the Independent JPEG Group's software. 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For conditions of distribution and use, see the accompanying README file. 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This file contains the compression preprocessing controller. 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This controller manages the color conversion, downsampling, 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * and edge expansion steps. 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Most of the complexity here is associated with buffering input rows 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * as required by the downsampler. See the comments at the head of 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * jcsample.c for the downsampler's needs. 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define JPEG_INTERNALS 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jinclude.h" 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jpeglib.h" 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* At present, jcsample.c can request context rows only for smoothing. 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * In the future, we might also need context rows for CCIR601 sampling 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * or other more-complex downsampling procedures. The code to support 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * context rows should be compiled only if needed. 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef INPUT_SMOOTHING_SUPPORTED 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CONTEXT_ROWS_SUPPORTED 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For the simple (no-context-row) case, we just need to buffer one 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * row group's worth of pixels for the downsampling step. At the bottom of 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * the image, we pad to a full row group by replicating the last pixel row. 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The downsampler's last output row is then replicated if needed to pad 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * out to a full iMCU row. 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * When providing context rows, we must buffer three row groups' worth of 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * pixels. Three row groups are physically allocated, but the row pointer 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * arrays are made five row groups high, with the extra pointers above and 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * below "wrapping around" to point to the last and first real row groups. 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This allows the downsampler to access the proper context rows. 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * At the top and bottom of the image, we create dummy context rows by 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * copying the first or last real pixel row. This copying could be avoided 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * trouble on the compression side. 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Private buffer controller object */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct jpeg_c_prep_controller pub; /* public fields */ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Downsampling input buffer. This buffer holds color-converted data 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * until we have enough to do a downsample step. 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY color_buf[MAX_COMPONENTS]; 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION rows_to_go; /* counts rows remaining in source image */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int next_buf_row; /* index of next row to store in color_buf */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int this_row_group; /* starting row index of group to process */ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int next_buf_stop; /* downsample when we reach this index */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} my_prep_controller; 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef my_prep_controller * my_prep_ptr; 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Initialize for a processing pass. 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstart_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pass_mode != JBUF_PASS_THRU) 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initialize total-height counter for detecting bottom of image */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->rows_to_go = cinfo->image_height; 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Mark the conversion buffer empty */ 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row = 0; 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CONTEXT_ROWS_SUPPORTED 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Preset additional state variables for context mode. 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * These aren't used in non-context mode, so we needn't test which mode. 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->this_row_group = 0; 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set next_buf_stop to stop after two row groups have been read in. */ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Expand an image vertically from height input_rows to height output_rows, 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * by duplicating the bottom row. 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovLOCAL(void) 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovexpand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int input_rows, int output_rows) 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov register int row; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (row = input_rows; row < output_rows; row++) { 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jcopy_sample_rows(image_data, input_rows-1, image_data, row, 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1, num_cols); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Process some data in the simple no-context case. 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Preprocessor output data is counted in "row groups". A row group 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * is defined to be v_samp_factor sample rows of each component. 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Downsampling will produce this much data from each max_v_samp_factor 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * input rows. 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpre_process_data (j_compress_ptr cinfo, 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_rows_avail, 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_row_groups_avail) 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int numrows, ci; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION inrows; 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jpeg_component_info * compptr; 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (*in_row_ctr < in_rows_avail && 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_group_ctr < out_row_groups_avail) { 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Do color conversion to fill the conversion buffer. */ 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrows = in_rows_avail - *in_row_ctr; 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows = cinfo->max_v_samp_factor - prep->next_buf_row; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows = (int) MIN((JDIMENSION) numrows, inrows); 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf, 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) prep->next_buf_row, 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows); 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *in_row_ctr += numrows; 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row += numrows; 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->rows_to_go -= numrows; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If at bottom of image, pad to fill the conversion buffer. */ 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->rows_to_go == 0 && 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row < cinfo->max_v_samp_factor) { 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0; ci < cinfo->num_components; ci++) { 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row, cinfo->max_v_samp_factor); 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row = cinfo->max_v_samp_factor; 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we've filled the conversion buffer, empty it. */ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->next_buf_row == cinfo->max_v_samp_factor) { 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->downsample->downsample) (cinfo, 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf, (JDIMENSION) 0, 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov output_buf, *out_row_group_ctr); 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row = 0; 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*out_row_group_ctr)++; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If at bottom of image, pad the output to a full iMCU height. 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Note we assume the caller is providing a one-iMCU-height output buffer! 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->rows_to_go == 0 && 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_group_ctr < out_row_groups_avail) { 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ci++, compptr++) { 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov expand_bottom_edge(output_buf[ci], 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov compptr->width_in_blocks * DCTSIZE, 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int) (*out_row_group_ctr * compptr->v_samp_factor), 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int) (out_row_groups_avail * compptr->v_samp_factor)); 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_group_ctr = out_row_groups_avail; 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; /* can exit outer loop without test */ 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CONTEXT_ROWS_SUPPORTED 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Process some data in the context case. 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpre_process_context (j_compress_ptr cinfo, 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_rows_avail, 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_row_groups_avail) 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int numrows, ci; 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int buf_height = cinfo->max_v_samp_factor * 3; 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION inrows; 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (*out_row_group_ctr < out_row_groups_avail) { 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (*in_row_ctr < in_rows_avail) { 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Do color conversion to fill the conversion buffer. */ 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov inrows = in_rows_avail - *in_row_ctr; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows = prep->next_buf_stop - prep->next_buf_row; 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows = (int) MIN((JDIMENSION) numrows, inrows); 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf, 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) prep->next_buf_row, 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov numrows); 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Pad at top of image, if first time through */ 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->rows_to_go == cinfo->image_height) { 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0; ci < cinfo->num_components; ci++) { 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int row; 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (row = 1; row <= cinfo->max_v_samp_factor; row++) { 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jcopy_sample_rows(prep->color_buf[ci], 0, 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf[ci], -row, 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1, cinfo->image_width); 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *in_row_ctr += numrows; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row += numrows; 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->rows_to_go -= numrows; 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Return for more data, unless we are at the bottom of the image. */ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->rows_to_go != 0) 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* When at bottom of image, pad to fill the conversion buffer. */ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->next_buf_row < prep->next_buf_stop) { 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0; ci < cinfo->num_components; ci++) { 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row, prep->next_buf_stop); 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row = prep->next_buf_stop; 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* If we've gotten enough data, downsample a row group. */ 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->next_buf_row == prep->next_buf_stop) { 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->downsample->downsample) (cinfo, 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf, 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) prep->this_row_group, 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov output_buf, *out_row_group_ctr); 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*out_row_group_ctr)++; 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Advance pointers with wraparound as necessary. */ 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->this_row_group += cinfo->max_v_samp_factor; 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->this_row_group >= buf_height) 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->this_row_group = 0; 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (prep->next_buf_row >= buf_height) 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_row = 0; 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Create the wrapped-around downsampling input buffer needed for context mode. 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovLOCAL(void) 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovcreate_context_buffer (j_compress_ptr cinfo) 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int rgroup_height = cinfo->max_v_samp_factor; 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ci, i; 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jpeg_component_info * compptr; 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY true_buffer, fake_buffer; 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Grab enough space for fake row pointers for all the components; 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * we need five row groups' worth of pointers for each component. 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fake_buffer = (JSAMPARRAY) 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (cinfo->num_components * 5 * rgroup_height) * 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SIZEOF(JSAMPROW)); 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ci++, compptr++) { 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Allocate the actual buffer space (3 row groups) for this component. 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * We make the buffer wide enough to allow the downsampler to edge-expand 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * horizontally within the buffer, if it so chooses. 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov true_buffer = (*cinfo->mem->alloc_sarray) 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->max_h_samp_factor) / compptr->h_samp_factor), 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) (3 * rgroup_height)); 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Copy true buffer row pointers into the middle of the fake row array */ 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov MEMCOPY(fake_buffer + rgroup_height, true_buffer, 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3 * rgroup_height * SIZEOF(JSAMPROW)); 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Fill in the above and below wraparound pointers */ 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (i = 0; i < rgroup_height; i++) { 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fake_buffer[i] = true_buffer[2 * rgroup_height + i]; 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fake_buffer[4 * rgroup_height + i] = true_buffer[i]; 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf[ci] = fake_buffer + rgroup_height; 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fake_buffer += 5 * rgroup_height; /* point to space for next component */ 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* CONTEXT_ROWS_SUPPORTED */ 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Initialize preprocessing controller. 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovGLOBAL(void) 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovjinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_prep_ptr prep; 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int ci; 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jpeg_component_info * compptr; 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (need_full_buffer) /* safety check */ 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep = (my_prep_ptr) 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SIZEOF(my_prep_controller)); 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->prep = (struct jpeg_c_prep_controller *) prep; 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->pub.start_pass = start_pass_prep; 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Allocate the color conversion buffer. 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * We make the buffer wide enough to allow the downsampler to edge-expand 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * horizontally within the buffer, if it so chooses. 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cinfo->downsample->need_context_rows) { 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set up to provide context rows */ 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef CONTEXT_ROWS_SUPPORTED 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->pub.pre_process_data = pre_process_context; 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov create_context_buffer(cinfo); 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_NOT_COMPILED); 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* No context, just make it tall enough for one row group */ 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->pub.pre_process_data = pre_process_data; 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ci++, compptr++) { 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->max_h_samp_factor) / compptr->h_samp_factor), 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) cinfo->max_v_samp_factor); 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif //_FX_JPEG_TURBO_ 358