jdpostct.c revision 5de454b291f48382648a5d1dc2aa0fca8b5786d4
136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * jdpostct.c 336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 45033f3e19a31e8ad40c1a79700365aefe5664494DRC * This file was part of the Independent JPEG Group's software: 5489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane * Copyright (C) 1994-1996, Thomas G. Lane. 65033f3e19a31e8ad40c1a79700365aefe5664494DRC * It was modified by The libjpeg-turbo Project to include only code relevant 75033f3e19a31e8ad40c1a79700365aefe5664494DRC * to libjpeg-turbo. 836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For conditions of distribution and use, see the accompanying README file. 936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 1036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This file contains the decompression postprocessing controller. 1136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This controller manages the upsampling, color conversion, and color 1236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * quantization/reduction steps; specifically, it controls the buffering 1336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * between upsample/color conversion and color quantization/reduction. 1436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * 1536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * If no color quantization/reduction is required, then this module has no 1636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * work to do, and it just hands off to the upsample/color conversion code. 1736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * An integrated upsample/convert/quantize process would replace this module 1836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * entirely. 1936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 2036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define JPEG_INTERNALS 2236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jinclude.h" 2336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jpeglib.h" 2436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Private buffer controller object */ 2736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 2836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanetypedef struct { 2936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane struct jpeg_d_post_controller pub; /* public fields */ 3036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 3136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Color quantization source buffer: this holds output data from 3236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * the upsample/color conversion step to be passed to the quantizer. 3336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For two-pass color quantization, we need a full-image buffer; 3436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * for one-pass operation, a strip buffer is sufficient. 3536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 36e5eaf37440b8e337ab150c017df7c03faf846c51DRC jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ 37e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ 38e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION strip_height; /* buffer size in rows */ 3936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* for two-pass mode only: */ 40e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION starting_row; /* row # of first row in current strip */ 41e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION next_row; /* index of next row to fill/empty in strip */ 4236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} my_post_controller; 4336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 4436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanetypedef my_post_controller * my_post_ptr; 4536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 4636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 4736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Forward declarations */ 48489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) post_process_1pass 49bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 50bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, 51bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 52bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION out_rows_avail); 5336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 54489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) post_process_prepass 55bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 56bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, 57bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 58bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION out_rows_avail); 59489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) post_process_2pass 60bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC (j_decompress_ptr cinfo, JSAMPIMAGE input_buf, 61bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION *in_row_group_ctr, JDIMENSION in_row_groups_avail, 62bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 63bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC JDIMENSION out_rows_avail); 6436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif 6536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 6636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 6736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 6836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize for a processing pass. 6936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 7036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 71489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) 7236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanestart_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) 7336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 7436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane my_post_ptr post = (my_post_ptr) cinfo->post; 7536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 7636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane switch (pass_mode) { 7736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case JBUF_PASS_THRU: 7836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (cinfo->quantize_colors) { 7936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Single-pass processing with color quantization. */ 8036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->pub.post_process_data = post_process_1pass; 81bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* We could be doing buffered-image output before starting a 2-pass 82bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * color quantization; in that case, jinit_d_post_controller did not 83bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane * allocate a strip buffer. Use the virtual-array buffer as workspace. 84bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane */ 85bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane if (post->buffer == NULL) { 86e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer = (*cinfo->mem->access_virt_sarray) 87e5eaf37440b8e337ab150c017df7c03faf846c51DRC ((j_common_ptr) cinfo, post->whole_image, 88e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JDIMENSION) 0, post->strip_height, TRUE); 89bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane } 9036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 9136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* For single-pass processing without color quantization, 9236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * I have no work to do; just call the upsampler directly. 9336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 9436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->pub.post_process_data = cinfo->upsample->upsample; 9536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 9636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 9736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 9836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case JBUF_SAVE_AND_PASS: 9936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* First pass of 2-pass quantization */ 10036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->whole_image == NULL) 10136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 10236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->pub.post_process_data = post_process_prepass; 10336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 10436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane case JBUF_CRANK_DEST: 10536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Second pass of 2-pass quantization */ 10636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->whole_image == NULL) 10736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 10836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->pub.post_process_data = post_process_2pass; 10936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 11036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif /* QUANT_2PASS_SUPPORTED */ 11136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane default: 11236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 11336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane break; 11436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 11536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->starting_row = post->next_row = 0; 11636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 11736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 11836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 11936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 12036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Process some data in the one-pass (strip buffer) case. 12136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This is used for color precision reduction as well as one-pass quantization. 12236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 12336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 124489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) 12536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanepost_process_1pass (j_decompress_ptr cinfo, 126e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 127e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION in_row_groups_avail, 128e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 129e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION out_rows_avail) 13036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 13136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane my_post_ptr post = (my_post_ptr) cinfo->post; 13236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane JDIMENSION num_rows, max_rows; 13336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 13436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Fill the buffer, but not more than what we can dump out in one go. */ 13536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Note we rely on the upsampler to detect bottom of image. */ 13636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane max_rows = out_rows_avail - *out_row_ctr; 13736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (max_rows > post->strip_height) 13836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane max_rows = post->strip_height; 13936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane num_rows = 0; 14036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->upsample->upsample) (cinfo, 141e5eaf37440b8e337ab150c017df7c03faf846c51DRC input_buf, in_row_group_ctr, in_row_groups_avail, 142e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer, &num_rows, max_rows); 14336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Quantize and emit data. */ 14436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->cquantize->color_quantize) (cinfo, 145e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer, output_buf + *out_row_ctr, (int) num_rows); 14636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *out_row_ctr += num_rows; 14736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 14836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 14936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 15036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 15136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 15236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 15336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Process some data in the first pass of 2-pass quantization. 15436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 15536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 156489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) 15736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanepost_process_prepass (j_decompress_ptr cinfo, 158e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 159e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION in_row_groups_avail, 160e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 161e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION out_rows_avail) 16236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 16336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane my_post_ptr post = (my_post_ptr) cinfo->post; 16436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane JDIMENSION old_next_row, num_rows; 16536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 16636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Reposition virtual buffer if at start of strip. */ 16736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->next_row == 0) { 16836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->buffer = (*cinfo->mem->access_virt_sarray) 169e5eaf37440b8e337ab150c017df7c03faf846c51DRC ((j_common_ptr) cinfo, post->whole_image, 170e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->starting_row, post->strip_height, TRUE); 17136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 17236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 17336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Upsample some data (up to a strip height's worth). */ 17436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane old_next_row = post->next_row; 17536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->upsample->upsample) (cinfo, 176e5eaf37440b8e337ab150c017df7c03faf846c51DRC input_buf, in_row_group_ctr, in_row_groups_avail, 177e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer, &post->next_row, post->strip_height); 17836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 17936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Allow quantizer to scan new data. No data is emitted, */ 18036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* but we advance out_row_ctr so outer loop can tell when we're done. */ 18136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->next_row > old_next_row) { 18236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane num_rows = post->next_row - old_next_row; 18336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, 184e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JSAMPARRAY) NULL, (int) num_rows); 18536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *out_row_ctr += num_rows; 18636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 18736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 18836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Advance if we filled the strip. */ 18936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->next_row >= post->strip_height) { 19036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->starting_row += post->strip_height; 19136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->next_row = 0; 19236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 19336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 19436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 19536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 19636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 19736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Process some data in the second pass of 2-pass quantization. 19836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 19936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 200489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) 20136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanepost_process_2pass (j_decompress_ptr cinfo, 202e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, 203e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION in_row_groups_avail, 204e5eaf37440b8e337ab150c017df7c03faf846c51DRC JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, 205e5eaf37440b8e337ab150c017df7c03faf846c51DRC JDIMENSION out_rows_avail) 20636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 20736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane my_post_ptr post = (my_post_ptr) cinfo->post; 20836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane JDIMENSION num_rows, max_rows; 20936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 21036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Reposition virtual buffer if at start of strip. */ 21136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->next_row == 0) { 21236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->buffer = (*cinfo->mem->access_virt_sarray) 213e5eaf37440b8e337ab150c017df7c03faf846c51DRC ((j_common_ptr) cinfo, post->whole_image, 214e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->starting_row, post->strip_height, FALSE); 21536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 21636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 21736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Determine number of rows to emit. */ 21836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane num_rows = post->strip_height - post->next_row; /* available in strip */ 21936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ 22036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (num_rows > max_rows) 22136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane num_rows = max_rows; 22236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* We have to check bottom of image here, can't depend on upsampler. */ 22336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane max_rows = cinfo->output_height - post->starting_row; 22436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (num_rows > max_rows) 22536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane num_rows = max_rows; 22636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 22736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Quantize and emit data. */ 22836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->cquantize->color_quantize) (cinfo, 229e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer + post->next_row, output_buf + *out_row_ctr, 230e5eaf37440b8e337ab150c017df7c03faf846c51DRC (int) num_rows); 23136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *out_row_ctr += num_rows; 23236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 23336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Advance if we filled the strip. */ 23436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->next_row += num_rows; 23536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (post->next_row >= post->strip_height) { 23636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->starting_row += post->strip_height; 23736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->next_row = 0; 23836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 23936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 24036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 24136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif /* QUANT_2PASS_SUPPORTED */ 24236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 24336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 24436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* 24536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize postprocessing controller. 24636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 24736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 248489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(void) 24936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanejinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) 25036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{ 25136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane my_post_ptr post; 25236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 25336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post = (my_post_ptr) 25436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 2555de454b291f48382648a5d1dc2aa0fca8b5786d4DRC sizeof(my_post_controller)); 25636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane cinfo->post = (struct jpeg_d_post_controller *) post; 25736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->pub.start_pass = start_pass_dpost; 258e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->whole_image = NULL; /* flag for no virtual arrays */ 259e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->buffer = NULL; /* flag for no strip buffer */ 26036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane 26136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Create the quantization buffer, if needed */ 26236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (cinfo->quantize_colors) { 26336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* The buffer strip height is max_v_samp_factor, which is typically 26436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * an efficient number of rows for upsampling to return. 26536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * (In the presence of output rescaling, we might want to be smarter?) 26636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */ 26736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; 26836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane if (need_full_buffer) { 26936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* Two-pass color quantization: need full-image storage. */ 270bc79e0680a45d1ca330d690dae0340c8e17ab5e3Thomas G. Lane /* We round up the number of rows to a multiple of the strip height. */ 27136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#ifdef QUANT_2PASS_SUPPORTED 27236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->whole_image = (*cinfo->mem->request_virt_sarray) 273e5eaf37440b8e337ab150c017df7c03faf846c51DRC ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 274e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->output_width * cinfo->out_color_components, 275e5eaf37440b8e337ab150c017df7c03faf846c51DRC (JDIMENSION) jround_up((long) cinfo->output_height, 276e5eaf37440b8e337ab150c017df7c03faf846c51DRC (long) post->strip_height), 277e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->strip_height); 27836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#else 27936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 28036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#endif /* QUANT_2PASS_SUPPORTED */ 28136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } else { 28236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane /* One-pass color quantization: just make a strip buffer. */ 28336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane post->buffer = (*cinfo->mem->alloc_sarray) 284e5eaf37440b8e337ab150c017df7c03faf846c51DRC ((j_common_ptr) cinfo, JPOOL_IMAGE, 285e5eaf37440b8e337ab150c017df7c03faf846c51DRC cinfo->output_width * cinfo->out_color_components, 286e5eaf37440b8e337ab150c017df7c03faf846c51DRC post->strip_height); 28736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 28836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane } 28936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} 290