1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * jcmainct.c 3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Copyright (C) 1994-1996, Thomas G. Lane. 5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file is part of the Independent JPEG Group's software. 6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * For conditions of distribution and use, see the accompanying README file. 7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This file contains the main buffer controller for compression. 9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The main buffer lies between the pre-processor and the JPEG 10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * compressor proper; it holds downsampled data in the JPEG colorspace. 11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define JPEG_INTERNALS 14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jinclude.h" 15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "jpeglib.h" 16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Note: currently, there is no operating mode in which a full-image buffer 19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * is needed at this step. If there were, that mode could not be used with 20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * "raw data" input, since this module is bypassed in that case. However, 21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * we've left the code here for possible use in special applications. 22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#undef FULL_MAIN_BUFFER_SUPPORTED 24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Private buffer controller object */ 27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef struct { 29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov struct jpeg_c_main_controller pub; /* public fields */ 30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION cur_iMCU_row; /* number of current iMCU row */ 32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ 33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov boolean suspended; /* remember if we suspended output */ 34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov J_BUF_MODE pass_mode; /* current operating mode */ 35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If using just a strip buffer, this points to the entire set of buffers 37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * (we allocate one for each component). In the full-image case, this 38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * points to the currently accessible strips of the virtual arrays. 39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JSAMPARRAY buffer[MAX_COMPONENTS]; 41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If using full-image storage, this array holds pointers to virtual-array 44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * control blocks for each component. Unused if not full-image storage. 45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; 47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} my_main_controller; 49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef my_main_controller * my_main_ptr; 51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Forward declarations */ 54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void) process_data_simple_main 55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void) process_data_buffer_main 59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Initialize for a processing pass. 66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void) 69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstart_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{ 71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov my_main_ptr main = (my_main_ptr) cinfo->main; 72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Do nothing in raw-data mode. */ 74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (cinfo->raw_data_in) 75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->cur_iMCU_row = 0; /* initialize counters */ 78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->rowgroup_ctr = 0; 79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->suspended = FALSE; 80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->pass_mode = pass_mode; /* save mode for use by process_data */ 81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov switch (pass_mode) { 83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov case JBUF_PASS_THRU: 84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->whole_image[0] != NULL) 86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->pub.process_data = process_data_simple_main; 89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov break; 90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov case JBUF_SAVE_SOURCE: 92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov case JBUF_CRANK_DEST: 93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov case JBUF_SAVE_AND_PASS: 94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->whole_image[0] == NULL) 95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->pub.process_data = process_data_buffer_main; 97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov break; 98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov default: 100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov break; 102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Process some data. 108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This routine handles the simple pass-through mode, 109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * where we have only a strip buffer. 110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void) 113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprocess_data_simple_main (j_compress_ptr cinfo, 114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION in_rows_avail) 116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{ 117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov my_main_ptr main = (my_main_ptr) cinfo->main; 118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { 120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Read input data if we haven't filled the main buffer yet */ 121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->rowgroup_ctr < DCTSIZE) 122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*cinfo->prep->pre_process_data) (cinfo, 123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov input_buf, in_row_ctr, in_rows_avail, 124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->buffer, &main->rowgroup_ctr, 125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) DCTSIZE); 126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If we don't have a full iMCU row buffered, return to application for 128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * more data. Note that preprocessor will always pad to fill the iMCU row 129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * at the bottom of the image. 130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->rowgroup_ctr != DCTSIZE) 132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Send the completed row to the compressor */ 135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { 136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If compressor did not consume the whole row, then we must need to 137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * suspend processing and return to the application. In this situation 138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * we pretend we didn't yet consume the last input row; otherwise, if 139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * it happened to be the last row of the image, the application would 140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * think we were done. 141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (! main->suspended) { 143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*in_row_ctr)--; 144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->suspended = TRUE; 145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* We did finish the row. Undo our little suspension hack if a previous 149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * call suspended; then mark the main buffer empty. 150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->suspended) { 152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*in_row_ctr)++; 153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->suspended = FALSE; 154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->rowgroup_ctr = 0; 156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->cur_iMCU_row++; 157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Process some data. 165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * This routine handles all of the modes that use a full-size buffer. 166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovMETHODDEF(void) 169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprocess_data_buffer_main (j_compress_ptr cinfo, 170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov JDIMENSION in_rows_avail) 172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{ 173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov my_main_ptr main = (my_main_ptr) cinfo->main; 174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov int ci; 175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov jpeg_component_info *compptr; 176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov boolean writing = (main->pass_mode != JBUF_CRANK_DEST); 177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { 179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Realign the virtual buffers if at the start of an iMCU row. */ 180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->rowgroup_ctr == 0) { 181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ci++, compptr++) { 183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->buffer[ci] = (*cinfo->mem->access_virt_sarray) 184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ((j_common_ptr) cinfo, main->whole_image[ci], 185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), 186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); 187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* In a read pass, pretend we just read some source data. */ 189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (! writing) { 190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; 191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->rowgroup_ctr = DCTSIZE; 192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If a write pass, read input data until the current iMCU row is full. */ 196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ 197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (writing) { 198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*cinfo->prep->pre_process_data) (cinfo, 199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov input_buf, in_row_ctr, in_rows_avail, 200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->buffer, &main->rowgroup_ctr, 201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) DCTSIZE); 202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Return to application if we need more data to fill the iMCU row. */ 203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->rowgroup_ctr < DCTSIZE) 204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Emit data, unless this is a sink-only pass. */ 208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->pass_mode != JBUF_SAVE_SOURCE) { 209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { 210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If compressor did not consume the whole row, then we must need to 211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * suspend processing and return to the application. In this situation 212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * we pretend we didn't yet consume the last input row; otherwise, if 213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * it happened to be the last row of the image, the application would 214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * think we were done. 215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (! main->suspended) { 217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*in_row_ctr)--; 218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->suspended = TRUE; 219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* We did finish the row. Undo our little suspension hack if a previous 223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * call suspended; then mark the main buffer empty. 224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (main->suspended) { 226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*in_row_ctr)++; 227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->suspended = FALSE; 228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* If get here, we are done with this iMCU row. Mark buffer empty. */ 232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->rowgroup_ctr = 0; 233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->cur_iMCU_row++; 234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif /* FULL_MAIN_BUFFER_SUPPORTED */ 238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* 241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Initialize main buffer controller. 242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovGLOBAL(void) 245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovjinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) 246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{ 247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov my_main_ptr main; 248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov int ci; 249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov jpeg_component_info *compptr; 250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main = (my_main_ptr) 252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov SIZEOF(my_main_controller)); 254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov cinfo->main = (struct jpeg_c_main_controller *) main; 255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->pub.start_pass = start_pass_main; 256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* We don't need to create a buffer in raw-data mode. */ 258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (cinfo->raw_data_in) 259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return; 260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Create the buffer. It holds downsampled data, so each component 262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * may be of a different size. 263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */ 264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if (need_full_buffer) { 265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Allocate a full-image virtual array for each component */ 267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Note we pad the bottom to a multiple of the iMCU height */ 268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ci++, compptr++) { 270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) 271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov compptr->width_in_blocks * DCTSIZE, 273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) jround_up((long) compptr->height_in_blocks, 274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (long) compptr->v_samp_factor) * DCTSIZE, 275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#else 278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } else { 281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef FULL_MAIN_BUFFER_SUPPORTED 282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->whole_image[0] = NULL; /* flag for no virtual arrays */ 283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif 284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Allocate a strip buffer for each component */ 285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ci++, compptr++) { 287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov main->buffer[ci] = (*cinfo->mem->alloc_sarray) 288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ((j_common_ptr) cinfo, JPOOL_IMAGE, 289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov compptr->width_in_blocks * DCTSIZE, 290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov} 294