|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 /* 00002 * jcmainct.c 00003 * 00004 * Copyright (C) 1994-1996, Thomas G. Lane. 00005 * This file is part of the Independent JPEG Group's software. 00006 * For conditions of distribution and use, see the accompanying README file. 00007 * 00008 * This file contains the main buffer controller for compression. 00009 * The main buffer lies between the pre-processor and the JPEG 00010 * compressor proper; it holds downsampled data in the JPEG colorspace. 00011 */ 00012 00013 #define JPEG_INTERNALS 00014 #include "jinclude.h" 00015 #include "jpeglib.h" 00016 00017 00018 /* Note: currently, there is no operating mode in which a full-image buffer 00019 * is needed at this step. If there were, that mode could not be used with 00020 * "raw data" input, since this module is bypassed in that case. However, 00021 * we've left the code here for possible use in special applications. 00022 */ 00023 #undef FULL_MAIN_BUFFER_SUPPORTED 00024 00025 00026 /* Private buffer controller object */ 00027 00028 typedef struct { 00029 struct jpeg_c_main_controller pub; /* public fields */ 00030 00031 JDIMENSION cur_iMCU_row; /* number of current iMCU row */ 00032 JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ 00033 boolean suspended; /* remember if we suspended output */ 00034 J_BUF_MODE pass_mode; /* current operating mode */ 00035 00036 /* If using just a strip buffer, this points to the entire set of buffers 00037 * (we allocate one for each component). In the full-image case, this 00038 * points to the currently accessible strips of the virtual arrays. 00039 */ 00040 JSAMPARRAY buffer[MAX_COMPONENTS]; 00041 00042 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00043 /* If using full-image storage, this array holds pointers to virtual-array 00044 * control blocks for each component. Unused if not full-image storage. 00045 */ 00046 jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; 00047 #endif 00048 } my_main_controller; 00049 00050 typedef my_main_controller * my_main_ptr; 00051 00052 00053 /* Forward declarations */ 00054 METHODDEF(void) process_data_simple_main 00055 JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 00056 JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 00057 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00058 METHODDEF(void) process_data_buffer_main 00059 JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 00060 JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 00061 #endif 00062 00063 00064 /* 00065 * Initialize for a processing pass. 00066 */ 00067 00068 METHODDEF(void) 00069 start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 00070 { 00071 my_main_ptr jmain = (my_main_ptr) cinfo->main; 00072 00073 /* Do nothing in raw-data mode. */ 00074 if (cinfo->raw_data_in) 00075 return; 00076 00077 jmain->cur_iMCU_row = 0; /* initialize counters */ 00078 jmain->rowgroup_ctr = 0; 00079 jmain->suspended = FALSE; 00080 jmain->pass_mode = pass_mode; /* save mode for use by process_data */ 00081 00082 switch (pass_mode) { 00083 case JBUF_PASS_THRU: 00084 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00085 if (jmain->whole_image[0] != NULL) 00086 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00087 #endif 00088 jmain->pub.process_data = process_data_simple_main; 00089 break; 00090 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00091 case JBUF_SAVE_SOURCE: 00092 case JBUF_CRANK_DEST: 00093 case JBUF_SAVE_AND_PASS: 00094 if (jmain->whole_image[0] == NULL) 00095 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00096 jmain->pub.process_data = process_data_buffer_main; 00097 break; 00098 #endif 00099 default: 00100 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00101 break; 00102 } 00103 } 00104 00105 00106 /* 00107 * Process some data. 00108 * This routine handles the simple pass-through mode, 00109 * where we have only a strip buffer. 00110 */ 00111 00112 METHODDEF(void) 00113 process_data_simple_main (j_compress_ptr cinfo, 00114 JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 00115 JDIMENSION in_rows_avail) 00116 { 00117 my_main_ptr jmain = (my_main_ptr) cinfo->main; 00118 00119 while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { 00120 /* Read input data if we haven't filled the main buffer yet */ 00121 if (jmain->rowgroup_ctr < DCTSIZE) 00122 (*cinfo->prep->pre_process_data) (cinfo, 00123 input_buf, in_row_ctr, in_rows_avail, 00124 jmain->buffer, &jmain->rowgroup_ctr, 00125 (JDIMENSION) DCTSIZE); 00126 00127 /* If we don't have a full iMCU row buffered, return to application for 00128 * more data. Note that preprocessor will always pad to fill the iMCU row 00129 * at the bottom of the image. 00130 */ 00131 if (jmain->rowgroup_ctr != DCTSIZE) 00132 return; 00133 00134 /* Send the completed row to the compressor */ 00135 if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { 00136 /* If compressor did not consume the whole row, then we must need to 00137 * suspend processing and return to the application. In this situation 00138 * we pretend we didn't yet consume the last input row; otherwise, if 00139 * it happened to be the last row of the image, the application would 00140 * think we were done. 00141 */ 00142 if (! jmain->suspended) { 00143 (*in_row_ctr)--; 00144 jmain->suspended = TRUE; 00145 } 00146 return; 00147 } 00148 /* We did finish the row. Undo our little suspension hack if a previous 00149 * call suspended; then mark the main buffer empty. 00150 */ 00151 if (jmain->suspended) { 00152 (*in_row_ctr)++; 00153 jmain->suspended = FALSE; 00154 } 00155 jmain->rowgroup_ctr = 0; 00156 jmain->cur_iMCU_row++; 00157 } 00158 } 00159 00160 00161 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00162 00163 /* 00164 * Process some data. 00165 * This routine handles all of the modes that use a full-size buffer. 00166 */ 00167 00168 METHODDEF(void) 00169 process_data_buffer_main (j_compress_ptr cinfo, 00170 JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 00171 JDIMENSION in_rows_avail) 00172 { 00173 my_main_ptr jmain = (my_main_ptr) cinfo->main; 00174 int ci; 00175 jpeg_component_info *compptr; 00176 boolean writing = (jmain->pass_mode != JBUF_CRANK_DEST); 00177 00178 while (jmain->cur_iMCU_row < cinfo->total_iMCU_rows) { 00179 /* Realign the virtual buffers if at the start of an iMCU row. */ 00180 if (jmain->rowgroup_ctr == 0) { 00181 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00182 ci++, compptr++) { 00183 jmain->buffer[ci] = (*cinfo->mem->access_virt_sarray) 00184 ((j_common_ptr) cinfo, jmain->whole_image[ci], 00185 jmain->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), 00186 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); 00187 } 00188 /* In a read pass, pretend we just read some source data. */ 00189 if (! writing) { 00190 *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; 00191 jmain->rowgroup_ctr = DCTSIZE; 00192 } 00193 } 00194 00195 /* If a write pass, read input data until the current iMCU row is full. */ 00196 /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ 00197 if (writing) { 00198 (*cinfo->prep->pre_process_data) (cinfo, 00199 input_buf, in_row_ctr, in_rows_avail, 00200 jmain->buffer, &jmain->rowgroup_ctr, 00201 (JDIMENSION) DCTSIZE); 00202 /* Return to application if we need more data to fill the iMCU row. */ 00203 if (jmain->rowgroup_ctr < DCTSIZE) 00204 return; 00205 } 00206 00207 /* Emit data, unless this is a sink-only pass. */ 00208 if (jmain->pass_mode != JBUF_SAVE_SOURCE) { 00209 if (! (*cinfo->coef->compress_data) (cinfo, jmain->buffer)) { 00210 /* If compressor did not consume the whole row, then we must need to 00211 * suspend processing and return to the application. In this situation 00212 * we pretend we didn't yet consume the last input row; otherwise, if 00213 * it happened to be the last row of the image, the application would 00214 * think we were done. 00215 */ 00216 if (! jmain->suspended) { 00217 (*in_row_ctr)--; 00218 jmain->suspended = TRUE; 00219 } 00220 return; 00221 } 00222 /* We did finish the row. Undo our little suspension hack if a previous 00223 * call suspended; then mark the main buffer empty. 00224 */ 00225 if (jmain->suspended) { 00226 (*in_row_ctr)++; 00227 jmain->suspended = FALSE; 00228 } 00229 } 00230 00231 /* If get here, we are done with this iMCU row. Mark buffer empty. */ 00232 jmain->rowgroup_ctr = 0; 00233 jmain->cur_iMCU_row++; 00234 } 00235 } 00236 00237 #endif /* FULL_MAIN_BUFFER_SUPPORTED */ 00238 00239 00240 /* 00241 * Initialize main buffer controller. 00242 */ 00243 00244 GLOBAL(void) 00245 jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) 00246 { 00247 my_main_ptr jmain; 00248 int ci; 00249 jpeg_component_info *compptr; 00250 00251 jmain = (my_main_ptr) 00252 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 00253 SIZEOF(my_main_controller)); 00254 cinfo->main = (struct jpeg_c_main_controller *) jmain; 00255 jmain->pub.start_pass = start_pass_main; 00256 00257 /* We don't need to create a buffer in raw-data mode. */ 00258 if (cinfo->raw_data_in) 00259 return; 00260 00261 /* Create the buffer. It holds downsampled data, so each component 00262 * may be of a different size. 00263 */ 00264 if (need_full_buffer) { 00265 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00266 /* Allocate a full-image virtual array for each component */ 00267 /* Note we pad the bottom to a multiple of the iMCU height */ 00268 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00269 ci++, compptr++) { 00270 jmain->whole_image[ci] = (*cinfo->mem->request_virt_sarray) 00271 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 00272 compptr->width_in_blocks * DCTSIZE, 00273 (JDIMENSION) jround_up((long) compptr->height_in_blocks, 00274 (long) compptr->v_samp_factor) * DCTSIZE, 00275 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 00276 } 00277 #else 00278 ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 00279 #endif 00280 } else { 00281 #ifdef FULL_MAIN_BUFFER_SUPPORTED 00282 jmain->whole_image[0] = NULL; /* flag for no virtual arrays */ 00283 #endif 00284 /* Allocate a strip buffer for each component */ 00285 for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 00286 ci++, compptr++) { 00287 jmain->buffer[ci] = (*cinfo->mem->alloc_sarray) 00288 ((j_common_ptr) cinfo, JPOOL_IMAGE, 00289 compptr->width_in_blocks * DCTSIZE, 00290 (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 00291 } 00292 } 00293 }