vrshoot
diff libs/libjpeg/jcmainct.c @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/libjpeg/jcmainct.c Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,293 @@ 1.4 +/* 1.5 + * jcmainct.c 1.6 + * 1.7 + * Copyright (C) 1994-1996, Thomas G. Lane. 1.8 + * This file is part of the Independent JPEG Group's software. 1.9 + * For conditions of distribution and use, see the accompanying README file. 1.10 + * 1.11 + * This file contains the main buffer controller for compression. 1.12 + * The main buffer lies between the pre-processor and the JPEG 1.13 + * compressor proper; it holds downsampled data in the JPEG colorspace. 1.14 + */ 1.15 + 1.16 +#define JPEG_INTERNALS 1.17 +#include "jinclude.h" 1.18 +#include "jpeglib.h" 1.19 + 1.20 + 1.21 +/* Note: currently, there is no operating mode in which a full-image buffer 1.22 + * is needed at this step. If there were, that mode could not be used with 1.23 + * "raw data" input, since this module is bypassed in that case. However, 1.24 + * we've left the code here for possible use in special applications. 1.25 + */ 1.26 +#undef FULL_MAIN_BUFFER_SUPPORTED 1.27 + 1.28 + 1.29 +/* Private buffer controller object */ 1.30 + 1.31 +typedef struct { 1.32 + struct jpeg_c_main_controller pub; /* public fields */ 1.33 + 1.34 + JDIMENSION cur_iMCU_row; /* number of current iMCU row */ 1.35 + JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */ 1.36 + boolean suspended; /* remember if we suspended output */ 1.37 + J_BUF_MODE pass_mode; /* current operating mode */ 1.38 + 1.39 + /* If using just a strip buffer, this points to the entire set of buffers 1.40 + * (we allocate one for each component). In the full-image case, this 1.41 + * points to the currently accessible strips of the virtual arrays. 1.42 + */ 1.43 + JSAMPARRAY buffer[MAX_COMPONENTS]; 1.44 + 1.45 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.46 + /* If using full-image storage, this array holds pointers to virtual-array 1.47 + * control blocks for each component. Unused if not full-image storage. 1.48 + */ 1.49 + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; 1.50 +#endif 1.51 +} my_main_controller; 1.52 + 1.53 +typedef my_main_controller * my_main_ptr; 1.54 + 1.55 + 1.56 +/* Forward declarations */ 1.57 +METHODDEF(void) process_data_simple_main 1.58 + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 1.59 + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 1.60 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.61 +METHODDEF(void) process_data_buffer_main 1.62 + JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf, 1.63 + JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)); 1.64 +#endif 1.65 + 1.66 + 1.67 +/* 1.68 + * Initialize for a processing pass. 1.69 + */ 1.70 + 1.71 +METHODDEF(void) 1.72 +start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 1.73 +{ 1.74 + my_main_ptr main = (my_main_ptr) cinfo->main; 1.75 + 1.76 + /* Do nothing in raw-data mode. */ 1.77 + if (cinfo->raw_data_in) 1.78 + return; 1.79 + 1.80 + main->cur_iMCU_row = 0; /* initialize counters */ 1.81 + main->rowgroup_ctr = 0; 1.82 + main->suspended = FALSE; 1.83 + main->pass_mode = pass_mode; /* save mode for use by process_data */ 1.84 + 1.85 + switch (pass_mode) { 1.86 + case JBUF_PASS_THRU: 1.87 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.88 + if (main->whole_image[0] != NULL) 1.89 + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 1.90 +#endif 1.91 + main->pub.process_data = process_data_simple_main; 1.92 + break; 1.93 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.94 + case JBUF_SAVE_SOURCE: 1.95 + case JBUF_CRANK_DEST: 1.96 + case JBUF_SAVE_AND_PASS: 1.97 + if (main->whole_image[0] == NULL) 1.98 + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 1.99 + main->pub.process_data = process_data_buffer_main; 1.100 + break; 1.101 +#endif 1.102 + default: 1.103 + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 1.104 + break; 1.105 + } 1.106 +} 1.107 + 1.108 + 1.109 +/* 1.110 + * Process some data. 1.111 + * This routine handles the simple pass-through mode, 1.112 + * where we have only a strip buffer. 1.113 + */ 1.114 + 1.115 +METHODDEF(void) 1.116 +process_data_simple_main (j_compress_ptr cinfo, 1.117 + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 1.118 + JDIMENSION in_rows_avail) 1.119 +{ 1.120 + my_main_ptr main = (my_main_ptr) cinfo->main; 1.121 + 1.122 + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { 1.123 + /* Read input data if we haven't filled the main buffer yet */ 1.124 + if (main->rowgroup_ctr < DCTSIZE) 1.125 + (*cinfo->prep->pre_process_data) (cinfo, 1.126 + input_buf, in_row_ctr, in_rows_avail, 1.127 + main->buffer, &main->rowgroup_ctr, 1.128 + (JDIMENSION) DCTSIZE); 1.129 + 1.130 + /* If we don't have a full iMCU row buffered, return to application for 1.131 + * more data. Note that preprocessor will always pad to fill the iMCU row 1.132 + * at the bottom of the image. 1.133 + */ 1.134 + if (main->rowgroup_ctr != DCTSIZE) 1.135 + return; 1.136 + 1.137 + /* Send the completed row to the compressor */ 1.138 + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { 1.139 + /* If compressor did not consume the whole row, then we must need to 1.140 + * suspend processing and return to the application. In this situation 1.141 + * we pretend we didn't yet consume the last input row; otherwise, if 1.142 + * it happened to be the last row of the image, the application would 1.143 + * think we were done. 1.144 + */ 1.145 + if (! main->suspended) { 1.146 + (*in_row_ctr)--; 1.147 + main->suspended = TRUE; 1.148 + } 1.149 + return; 1.150 + } 1.151 + /* We did finish the row. Undo our little suspension hack if a previous 1.152 + * call suspended; then mark the main buffer empty. 1.153 + */ 1.154 + if (main->suspended) { 1.155 + (*in_row_ctr)++; 1.156 + main->suspended = FALSE; 1.157 + } 1.158 + main->rowgroup_ctr = 0; 1.159 + main->cur_iMCU_row++; 1.160 + } 1.161 +} 1.162 + 1.163 + 1.164 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.165 + 1.166 +/* 1.167 + * Process some data. 1.168 + * This routine handles all of the modes that use a full-size buffer. 1.169 + */ 1.170 + 1.171 +METHODDEF(void) 1.172 +process_data_buffer_main (j_compress_ptr cinfo, 1.173 + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, 1.174 + JDIMENSION in_rows_avail) 1.175 +{ 1.176 + my_main_ptr main = (my_main_ptr) cinfo->main; 1.177 + int ci; 1.178 + jpeg_component_info *compptr; 1.179 + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); 1.180 + 1.181 + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { 1.182 + /* Realign the virtual buffers if at the start of an iMCU row. */ 1.183 + if (main->rowgroup_ctr == 0) { 1.184 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.185 + ci++, compptr++) { 1.186 + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) 1.187 + ((j_common_ptr) cinfo, main->whole_image[ci], 1.188 + main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), 1.189 + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); 1.190 + } 1.191 + /* In a read pass, pretend we just read some source data. */ 1.192 + if (! writing) { 1.193 + *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; 1.194 + main->rowgroup_ctr = DCTSIZE; 1.195 + } 1.196 + } 1.197 + 1.198 + /* If a write pass, read input data until the current iMCU row is full. */ 1.199 + /* Note: preprocessor will pad if necessary to fill the last iMCU row. */ 1.200 + if (writing) { 1.201 + (*cinfo->prep->pre_process_data) (cinfo, 1.202 + input_buf, in_row_ctr, in_rows_avail, 1.203 + main->buffer, &main->rowgroup_ctr, 1.204 + (JDIMENSION) DCTSIZE); 1.205 + /* Return to application if we need more data to fill the iMCU row. */ 1.206 + if (main->rowgroup_ctr < DCTSIZE) 1.207 + return; 1.208 + } 1.209 + 1.210 + /* Emit data, unless this is a sink-only pass. */ 1.211 + if (main->pass_mode != JBUF_SAVE_SOURCE) { 1.212 + if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) { 1.213 + /* If compressor did not consume the whole row, then we must need to 1.214 + * suspend processing and return to the application. In this situation 1.215 + * we pretend we didn't yet consume the last input row; otherwise, if 1.216 + * it happened to be the last row of the image, the application would 1.217 + * think we were done. 1.218 + */ 1.219 + if (! main->suspended) { 1.220 + (*in_row_ctr)--; 1.221 + main->suspended = TRUE; 1.222 + } 1.223 + return; 1.224 + } 1.225 + /* We did finish the row. Undo our little suspension hack if a previous 1.226 + * call suspended; then mark the main buffer empty. 1.227 + */ 1.228 + if (main->suspended) { 1.229 + (*in_row_ctr)++; 1.230 + main->suspended = FALSE; 1.231 + } 1.232 + } 1.233 + 1.234 + /* If get here, we are done with this iMCU row. Mark buffer empty. */ 1.235 + main->rowgroup_ctr = 0; 1.236 + main->cur_iMCU_row++; 1.237 + } 1.238 +} 1.239 + 1.240 +#endif /* FULL_MAIN_BUFFER_SUPPORTED */ 1.241 + 1.242 + 1.243 +/* 1.244 + * Initialize main buffer controller. 1.245 + */ 1.246 + 1.247 +GLOBAL(void) 1.248 +jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) 1.249 +{ 1.250 + my_main_ptr main; 1.251 + int ci; 1.252 + jpeg_component_info *compptr; 1.253 + 1.254 + main = (my_main_ptr) 1.255 + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.256 + SIZEOF(my_main_controller)); 1.257 + cinfo->main = (struct jpeg_c_main_controller *) main; 1.258 + main->pub.start_pass = start_pass_main; 1.259 + 1.260 + /* We don't need to create a buffer in raw-data mode. */ 1.261 + if (cinfo->raw_data_in) 1.262 + return; 1.263 + 1.264 + /* Create the buffer. It holds downsampled data, so each component 1.265 + * may be of a different size. 1.266 + */ 1.267 + if (need_full_buffer) { 1.268 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.269 + /* Allocate a full-image virtual array for each component */ 1.270 + /* Note we pad the bottom to a multiple of the iMCU height */ 1.271 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.272 + ci++, compptr++) { 1.273 + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) 1.274 + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, 1.275 + compptr->width_in_blocks * DCTSIZE, 1.276 + (JDIMENSION) jround_up((long) compptr->height_in_blocks, 1.277 + (long) compptr->v_samp_factor) * DCTSIZE, 1.278 + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 1.279 + } 1.280 +#else 1.281 + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 1.282 +#endif 1.283 + } else { 1.284 +#ifdef FULL_MAIN_BUFFER_SUPPORTED 1.285 + main->whole_image[0] = NULL; /* flag for no virtual arrays */ 1.286 +#endif 1.287 + /* Allocate a strip buffer for each component */ 1.288 + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; 1.289 + ci++, compptr++) { 1.290 + main->buffer[ci] = (*cinfo->mem->alloc_sarray) 1.291 + ((j_common_ptr) cinfo, JPOOL_IMAGE, 1.292 + compptr->width_in_blocks * DCTSIZE, 1.293 + (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); 1.294 + } 1.295 + } 1.296 +}