1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FX_JPEG_TURBO_) 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * jdpostct.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 decompression postprocessing controller. 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This controller manages the upsampling, color conversion, and color 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * quantization/reduction steps; specifically, it controls the buffering 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * between upsample/color conversion and color quantization/reduction. 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * If no color quantization/reduction is required, then this module has no 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * work to do, and it just hands off to the upsample/color conversion code. 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * An integrated upsample/convert/quantize process would replace this module 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * entirely. 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define JPEG_INTERNALS 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jinclude.h" 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "jpeglib.h" 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Private buffer controller object */ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct { 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct jpeg_d_post_controller pub; /* public fields */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Color quantization source buffer: this holds output data from 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * the upsample/color conversion step to be passed to the quantizer. 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For two-pass color quantization, we need a full-image buffer; 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * for one-pass operation, a strip buffer is sufficient. 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION strip_height; /* buffer size in rows */ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for two-pass mode only: */ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION starting_row; /* row # of first row in current strip */ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION next_row; /* index of next row to fill/empty in strip */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} my_post_controller; 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef my_post_controller * my_post_ptr; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Forward declarations */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) post_process_1pass 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JPP((j_decompress_ptr cinfo, 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail)); 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef QUANT_2PASS_SUPPORTED 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) post_process_prepass 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JPP((j_decompress_ptr cinfo, 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail)); 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) post_process_2pass 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JPP((j_decompress_ptr cinfo, 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail)); 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Initialize for a processing pass. 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstart_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_post_ptr post = (my_post_ptr) cinfo->post; 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch (pass_mode) { 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case JBUF_PASS_THRU: 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cinfo->quantize_colors) { 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Single-pass processing with color quantization. */ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->pub.post_process_data = post_process_1pass; 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We could be doing buffered-image output before starting a 2-pass 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * color quantization; in that case, jinit_d_post_controller did not 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * allocate a strip buffer. Use the virtual-array buffer as workspace. 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->buffer == NULL) { 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer = (*cinfo->mem->access_virt_sarray) 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, post->whole_image, 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) 0, post->strip_height, TRUE); 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* For single-pass processing without color quantization, 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * I have no work to do; just call the upsampler directly. 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->pub.post_process_data = cinfo->upsample->upsample; 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef QUANT_2PASS_SUPPORTED 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case JBUF_SAVE_AND_PASS: 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* First pass of 2-pass quantization */ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->whole_image == NULL) 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->pub.post_process_data = post_process_prepass; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case JBUF_CRANK_DEST: 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Second pass of 2-pass quantization */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->whole_image == NULL) 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->pub.post_process_data = post_process_2pass; 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* QUANT_2PASS_SUPPORTED */ 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->starting_row = post->next_row = 0; 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Process some data in the one-pass (strip buffer) case. 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * This is used for color precision reduction as well as one-pass quantization. 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpost_process_1pass (j_decompress_ptr cinfo, 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail) 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_post_ptr post = (my_post_ptr) cinfo->post; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION num_rows, max_rows; 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Fill the buffer, but not more than what we can dump out in one go. */ 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note we rely on the upsampler to detect bottom of image. */ 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_rows = out_rows_avail - *out_row_ctr; 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (max_rows > post->strip_height) 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_rows = post->strip_height; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = 0; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->upsample->upsample) (cinfo, 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov input_buf, in_row_group_ctr, in_row_groups_avail, 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer, &num_rows, max_rows); 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Quantize and emit data. */ 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cquantize->color_quantize) (cinfo, 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer, output_buf + *out_row_ctr, (int) num_rows); 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_ctr += num_rows; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef QUANT_2PASS_SUPPORTED 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Process some data in the first pass of 2-pass quantization. 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpost_process_prepass (j_decompress_ptr cinfo, 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail) 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_post_ptr post = (my_post_ptr) cinfo->post; 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION old_next_row, num_rows; 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Reposition virtual buffer if at start of strip. */ 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->next_row == 0) { 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer = (*cinfo->mem->access_virt_sarray) 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, post->whole_image, 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->starting_row, post->strip_height, TRUE); 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Upsample some data (up to a strip height's worth). */ 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old_next_row = post->next_row; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->upsample->upsample) (cinfo, 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov input_buf, in_row_group_ctr, in_row_groups_avail, 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer, &post->next_row, post->strip_height); 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Allow quantizer to scan new data. No data is emitted, */ 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* but we advance out_row_ctr so outer loop can tell when we're done. */ 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->next_row > old_next_row) { 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = post->next_row - old_next_row; 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JSAMPARRAY) NULL, (int) num_rows); 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_ctr += num_rows; 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Advance if we filled the strip. */ 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->next_row >= post->strip_height) { 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->starting_row += post->strip_height; 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->next_row = 0; 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Process some data in the second pass of 2-pass quantization. 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovMETHODDEF(void) 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpost_process_2pass (j_decompress_ptr cinfo, 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION in_row_groups_avail, 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION out_rows_avail) 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_post_ptr post = (my_post_ptr) cinfo->post; 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov JDIMENSION num_rows, max_rows; 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Reposition virtual buffer if at start of strip. */ 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->next_row == 0) { 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer = (*cinfo->mem->access_virt_sarray) 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, post->whole_image, 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->starting_row, post->strip_height, FALSE); 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Determine number of rows to emit. */ 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = post->strip_height - post->next_row; /* available in strip */ 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (num_rows > max_rows) 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = max_rows; 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We have to check bottom of image here, can't depend on upsampler. */ 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_rows = cinfo->output_height - post->starting_row; 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (num_rows > max_rows) 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_rows = max_rows; 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Quantize and emit data. */ 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->cquantize->color_quantize) (cinfo, 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer + post->next_row, output_buf + *out_row_ctr, 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int) num_rows); 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *out_row_ctr += num_rows; 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Advance if we filled the strip. */ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->next_row += num_rows; 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (post->next_row >= post->strip_height) { 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->starting_row += post->strip_height; 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->next_row = 0; 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* QUANT_2PASS_SUPPORTED */ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Initialize postprocessing controller. 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovGLOBAL(void) 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovjinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov my_post_ptr post; 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post = (my_post_ptr) 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SIZEOF(my_post_controller)); 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->post = (struct jpeg_d_post_controller *) post; 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->pub.start_pass = start_pass_dpost; 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->whole_image = NULL; /* flag for no virtual arrays */ 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer = NULL; /* flag for no strip buffer */ 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Create the quantization buffer, if needed */ 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (cinfo->quantize_colors) { 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The buffer strip height is max_v_samp_factor, which is typically 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * an efficient number of rows for upsampling to return. 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * (In the presence of output rescaling, we might want to be smarter?) 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (need_full_buffer) { 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Two-pass color quantization: need full-image storage. */ 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We round up the number of rows to a multiple of the strip height. */ 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef QUANT_2PASS_SUPPORTED 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->whole_image = (*cinfo->mem->request_virt_sarray) 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->output_width * cinfo->out_color_components, 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (JDIMENSION) jround_up((long) cinfo->output_height, 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (long) post->strip_height), 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->strip_height); 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* QUANT_2PASS_SUPPORTED */ 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* One-pass color quantization: just make a strip buffer. */ 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->buffer = (*cinfo->mem->alloc_sarray) 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cinfo->output_width * cinfo->out_color_components, 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov post->strip_height); 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif //_FX_JPEG_TURBO_ 294