170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jcprepct.c 370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Copyright (C) 1994-1996, Thomas G. Lane. 570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file is part of the Independent JPEG Group's software. 670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For conditions of distribution and use, see the accompanying README file. 770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This file contains the compression preprocessing controller. 970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This controller manages the color conversion, downsampling, 1070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * and edge expansion steps. 1170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 1270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Most of the complexity here is associated with buffering input rows 1370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * as required by the downsampler. See the comments at the head of 1470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * jcsample.c for the downsampler's needs. 1570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 1670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define JPEG_INTERNALS 1870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jinclude.h" 1970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#include "jpeglib.h" 2070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 2270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* At present, jcsample.c can request context rows only for smoothing. 2370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * In the future, we might also need context rows for CCIR601 sampling 2470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * or other more-complex downsampling procedures. The code to support 2570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * context rows should be compiled only if needed. 2670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 2770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef INPUT_SMOOTHING_SUPPORTED 2870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#define CONTEXT_ROWS_SUPPORTED 2970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 3070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 3370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * For the simple (no-context-row) case, we just need to buffer one 3470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * row group's worth of pixels for the downsampling step. At the bottom of 3570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * the image, we pad to a full row group by replicating the last pixel row. 3670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * The downsampler's last output row is then replicated if needed to pad 3770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * out to a full iMCU row. 3870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 3970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * When providing context rows, we must buffer three row groups' worth of 4070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * pixels. Three row groups are physically allocated, but the row pointer 4170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * arrays are made five row groups high, with the extra pointers above and 4270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * below "wrapping around" to point to the last and first real row groups. 4370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * This allows the downsampler to access the proper context rows. 4470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * At the top and bottom of the image, we create dummy context rows by 4570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * copying the first or last real pixel row. This copying could be avoided 4670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the 4770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * trouble on the compression side. 4870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 4970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* Private buffer controller object */ 5270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef struct { 5470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine struct jpeg_c_prep_controller pub; /* public fields */ 5570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 5670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Downsampling input buffer. This buffer holds color-converted data 5770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * until we have enough to do a downsample step. 5870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 5970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY color_buf[MAX_COMPONENTS]; 6070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION rows_to_go; /* counts rows remaining in source image */ 6270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int next_buf_row; /* index of next row to store in color_buf */ 6370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 6470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ 6570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int this_row_group; /* starting row index of group to process */ 6670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int next_buf_stop; /* downsample when we reach this index */ 6770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 6870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} my_prep_controller; 6970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinetypedef my_prep_controller * my_prep_ptr; 7170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 7470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Initialize for a processing pass. 7570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 7670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 7770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 7870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinestart_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 7970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 8070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 8170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (pass_mode != JBUF_PASS_THRU) 8370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 8470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 8570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Initialize total-height counter for detecting bottom of image */ 8670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->rows_to_go = cinfo->image_height; 8770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Mark the conversion buffer empty */ 8870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row = 0; 8970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef CONTEXT_ROWS_SUPPORTED 9070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Preset additional state variables for context mode. 9170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * These aren't used in non-context mode, so we needn't test which mode. 9270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 9370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->this_row_group = 0; 9470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Set next_buf_stop to stop after two row groups have been read in. */ 9570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_stop = 2 * cinfo->max_v_samp_factor; 9670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 9770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 9870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 9970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 10070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 10170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Expand an image vertically from height input_rows to height output_rows, 10270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * by duplicating the bottom row. 10370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 10470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 10570a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 10670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkineexpand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, 10770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int input_rows, int output_rows) 10870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 10970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine register int row; 11070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (row = input_rows; row < output_rows; row++) { 11270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jcopy_sample_rows(image_data, input_rows-1, image_data, row, 11370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1, num_cols); 11470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 11570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 11670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 11870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 11970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Process some data in the simple no-context case. 12070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * 12170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Preprocessor output data is counted in "row groups". A row group 12270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * is defined to be v_samp_factor sample rows of each component. 12370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Downsampling will produce this much data from each max_v_samp_factor 12470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * input rows. 12570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 12670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 12770a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 12870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinepre_process_data (j_compress_ptr cinfo, 12970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 13070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION in_rows_avail, 13170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 13270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION out_row_groups_avail) 13370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 13470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 13570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int numrows, ci; 13670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION inrows; 13770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info * compptr; 13870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 13970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (*in_row_ctr < in_rows_avail && 14070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *out_row_group_ctr < out_row_groups_avail) { 14170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Do color conversion to fill the conversion buffer. */ 14270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrows = in_rows_avail - *in_row_ctr; 14370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows = cinfo->max_v_samp_factor - prep->next_buf_row; 14470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows = (int) MIN((JDIMENSION) numrows, inrows); 14570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 14670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf, 14770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) prep->next_buf_row, 14870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows); 14970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *in_row_ctr += numrows; 15070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row += numrows; 15170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->rows_to_go -= numrows; 15270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* If at bottom of image, pad to fill the conversion buffer. */ 15370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->rows_to_go == 0 && 15470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row < cinfo->max_v_samp_factor) { 15570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < cinfo->num_components; ci++) { 15670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 15770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row, cinfo->max_v_samp_factor); 15870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 15970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row = cinfo->max_v_samp_factor; 16070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 16170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* If we've filled the conversion buffer, empty it. */ 16270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->next_buf_row == cinfo->max_v_samp_factor) { 16370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->downsample->downsample) (cinfo, 16470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf, (JDIMENSION) 0, 16570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine output_buf, *out_row_group_ctr); 16670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row = 0; 16770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*out_row_group_ctr)++; 16870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 16970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* If at bottom of image, pad the output to a full iMCU height. 17070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Note we assume the caller is providing a one-iMCU-height output buffer! 17170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 17270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->rows_to_go == 0 && 17370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *out_row_group_ctr < out_row_groups_avail) { 17470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 17570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ci++, compptr++) { 17670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine expand_bottom_edge(output_buf[ci], 17770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine compptr->width_in_blocks * DCTSIZE, 17870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (int) (*out_row_group_ctr * compptr->v_samp_factor), 17970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (int) (out_row_groups_avail * compptr->v_samp_factor)); 18070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *out_row_group_ctr = out_row_groups_avail; 18270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; /* can exit outer loop without test */ 18370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 18570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 18670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 18870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef CONTEXT_ROWS_SUPPORTED 18970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 19170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Process some data in the context case. 19270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 19370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 19470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineMETHODDEF(void) 19570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinepre_process_context (j_compress_ptr cinfo, 19670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 19770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION in_rows_avail, 19870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, 19970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION out_row_groups_avail) 20070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 20170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 20270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int numrows, ci; 20370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int buf_height = cinfo->max_v_samp_factor * 3; 20470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JDIMENSION inrows; 20570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 20670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine while (*out_row_group_ctr < out_row_groups_avail) { 20770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (*in_row_ctr < in_rows_avail) { 20870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Do color conversion to fill the conversion buffer. */ 20970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine inrows = in_rows_avail - *in_row_ctr; 21070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows = prep->next_buf_stop - prep->next_buf_row; 21170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows = (int) MIN((JDIMENSION) numrows, inrows); 21270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, 21370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf, 21470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) prep->next_buf_row, 21570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine numrows); 21670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Pad at top of image, if first time through */ 21770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->rows_to_go == cinfo->image_height) { 21870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < cinfo->num_components; ci++) { 21970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int row; 22070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (row = 1; row <= cinfo->max_v_samp_factor; row++) { 22170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jcopy_sample_rows(prep->color_buf[ci], 0, 22270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf[ci], -row, 22370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 1, cinfo->image_width); 22470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 22770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine *in_row_ctr += numrows; 22870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row += numrows; 22970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->rows_to_go -= numrows; 23070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 23170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Return for more data, unless we are at the bottom of the image. */ 23270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->rows_to_go != 0) 23370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine break; 23470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* When at bottom of image, pad to fill the conversion buffer. */ 23570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->next_buf_row < prep->next_buf_stop) { 23670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0; ci < cinfo->num_components; ci++) { 23770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, 23870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row, prep->next_buf_stop); 23970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 24070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row = prep->next_buf_stop; 24170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 24270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 24370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* If we've gotten enough data, downsample a row group. */ 24470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->next_buf_row == prep->next_buf_stop) { 24570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->downsample->downsample) (cinfo, 24670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf, 24770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) prep->this_row_group, 24870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine output_buf, *out_row_group_ctr); 24970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*out_row_group_ctr)++; 25070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Advance pointers with wraparound as necessary. */ 25170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->this_row_group += cinfo->max_v_samp_factor; 25270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->this_row_group >= buf_height) 25370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->this_row_group = 0; 25470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (prep->next_buf_row >= buf_height) 25570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_row = 0; 25670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; 25770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 25870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 25970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 26070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 26170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 26270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 26370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Create the wrapped-around downsampling input buffer needed for context mode. 26470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 26570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 26670a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineLOCAL(void) 26770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinecreate_context_buffer (j_compress_ptr cinfo) 26870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 26970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_prep_ptr prep = (my_prep_ptr) cinfo->prep; 27070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int rgroup_height = cinfo->max_v_samp_factor; 27170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci, i; 27270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info * compptr; 27370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine JSAMPARRAY true_buffer, fake_buffer; 27470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 27570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Grab enough space for fake row pointers for all the components; 27670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * we need five row groups' worth of pointers for each component. 27770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 27870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fake_buffer = (JSAMPARRAY) 27970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 28070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (cinfo->num_components * 5 * rgroup_height) * 28170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(JSAMPROW)); 28270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 28370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 28470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ci++, compptr++) { 28570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Allocate the actual buffer space (3 row groups) for this component. 28670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We make the buffer wide enough to allow the downsampler to edge-expand 28770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * horizontally within the buffer, if it so chooses. 28870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 28970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine true_buffer = (*cinfo->mem->alloc_sarray) 29070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, JPOOL_IMAGE, 29170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * 29270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->max_h_samp_factor) / compptr->h_samp_factor), 29370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) (3 * rgroup_height)); 29470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Copy true buffer row pointers into the middle of the fake row array */ 29570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine MEMCOPY(fake_buffer + rgroup_height, true_buffer, 29670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 3 * rgroup_height * SIZEOF(JSAMPROW)); 29770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Fill in the above and below wraparound pointers */ 29870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (i = 0; i < rgroup_height; i++) { 29970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fake_buffer[i] = true_buffer[2 * rgroup_height + i]; 30070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fake_buffer[4 * rgroup_height + i] = true_buffer[i]; 30170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf[ci] = fake_buffer + rgroup_height; 30370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine fake_buffer += 5 * rgroup_height; /* point to space for next component */ 30470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 30570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 30670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 30770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif /* CONTEXT_ROWS_SUPPORTED */ 30870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 30970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine/* 31170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * Initialize preprocessing controller. 31270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 31370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 31470a18cd874a22452aca9e39e22275ed4538ed20bVladimir ChtchetkineGLOBAL(void) 31570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkinejinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) 31670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine{ 31770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine my_prep_ptr prep; 31870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine int ci; 31970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine jpeg_component_info * compptr; 32070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (need_full_buffer) /* safety check */ 32270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 32370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 32470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep = (my_prep_ptr) 32570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 32670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine SIZEOF(my_prep_controller)); 32770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->prep = (struct jpeg_c_prep_controller *) prep; 32870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->pub.start_pass = start_pass_prep; 32970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine 33070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Allocate the color conversion buffer. 33170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * We make the buffer wide enough to allow the downsampler to edge-expand 33270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine * horizontally within the buffer, if it so chooses. 33370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine */ 33470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine if (cinfo->downsample->need_context_rows) { 33570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* Set up to provide context rows */ 33670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#ifdef CONTEXT_ROWS_SUPPORTED 33770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->pub.pre_process_data = pre_process_context; 33870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine create_context_buffer(cinfo); 33970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#else 34070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ERREXIT(cinfo, JERR_NOT_COMPILED); 34170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine#endif 34270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } else { 34370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine /* No context, just make it tall enough for one row group */ 34470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->pub.pre_process_data = pre_process_data; 34570a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 34670a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ci++, compptr++) { 34770a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) 34870a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine ((j_common_ptr) cinfo, JPOOL_IMAGE, 34970a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * 35070a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine cinfo->max_h_samp_factor) / compptr->h_samp_factor), 35170a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine (JDIMENSION) cinfo->max_v_samp_factor); 35270a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35370a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine } 35470a18cd874a22452aca9e39e22275ed4538ed20bVladimir Chtchetkine} 355