1 /*
2 * jccoefct.c
3 *
4 * Copyright (C) 1994-1997, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
7 *
8 * This file contains the coefficient buffer controller for compression.
9 * This controller is the top level of the JPEG compressor proper.
10 * The coefficient buffer lies between forward-DCT and entropy encoding steps.
11 */
12
13 #define JPEG_INTERNALS
14 #include "jinclude.h"
15 #include "jpeglib.h"
16
17
18 /* We use a full-image coefficient buffer when doing Huffman optimization,
19 * and also for writing multiple-scan JPEG files. In all cases, the DCT
20 * step is run during the first pass, and subsequent passes need only read
21 * the buffered coefficients.
22 */
23 #ifdef ENTROPY_OPT_SUPPORTED
24 #define FULL_COEF_BUFFER_SUPPORTED
166 * block's DC value. (Thanks to Thomas Kinsman for this idea.)
167 */
168 blkn = 0;
169 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
170 compptr = cinfo->cur_comp_info[ci];
171 forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
172 blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
173 : compptr->last_col_width;
174 xpos = MCU_col_num * compptr->MCU_sample_width;
175 ypos = yoffset * compptr->DCT_v_scaled_size;
176 /* ypos == (yoffset+yindex) * DCTSIZE */
177 for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
178 if (coef->iMCU_row_num < last_iMCU_row ||
179 yoffset+yindex < compptr->last_row_height) {
180 (*forward_DCT) (cinfo, compptr,
181 input_buf[compptr->component_index],
182 coef->MCU_buffer[blkn],
183 ypos, xpos, (JDIMENSION) blockcnt);
184 if (blockcnt < compptr->MCU_width) {
185 /* Create some dummy blocks at the right edge of the image. */
186 jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
187 (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
188 for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
189 coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
190 }
191 }
192 } else {
193 /* Create a row of dummy blocks at the bottom of the image. */
194 jzero_far((void FAR *) coef->MCU_buffer[blkn],
195 compptr->MCU_width * SIZEOF(JBLOCK));
196 for (bi = 0; bi < compptr->MCU_width; bi++) {
197 coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
198 }
199 }
200 blkn += compptr->MCU_width;
201 ypos += compptr->DCT_v_scaled_size;
202 }
203 }
204 /* Try to write the MCU. In event of a suspension failure, we will
205 * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
206 */
207 if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
208 /* Suspension forced; update state counters and exit */
209 coef->MCU_vert_offset = yoffset;
210 coef->mcu_ctr = MCU_col_num;
211 return FALSE;
212 }
213 }
214 /* Completed an MCU row, but perhaps not an iMCU row */
273 if (block_rows == 0) block_rows = compptr->v_samp_factor;
274 }
275 blocks_across = compptr->width_in_blocks;
276 h_samp_factor = compptr->h_samp_factor;
277 /* Count number of dummy blocks to be added at the right margin. */
278 ndummy = (int) (blocks_across % h_samp_factor);
279 if (ndummy > 0)
280 ndummy = h_samp_factor - ndummy;
281 forward_DCT = cinfo->fdct->forward_DCT[ci];
282 /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
283 * on forward_DCT processes a complete horizontal row of DCT blocks.
284 */
285 for (block_row = 0; block_row < block_rows; block_row++) {
286 thisblockrow = buffer[block_row];
287 (*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
288 (JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
289 (JDIMENSION) 0, blocks_across);
290 if (ndummy > 0) {
291 /* Create dummy blocks at the right edge of the image. */
292 thisblockrow += blocks_across; /* => first dummy block */
293 jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
294 lastDC = thisblockrow[-1][0];
295 for (bi = 0; bi < ndummy; bi++) {
296 thisblockrow[bi][0] = lastDC;
297 }
298 }
299 }
300 /* If at end of image, create dummy block rows as needed.
301 * The tricky part here is that within each MCU, we want the DC values
302 * of the dummy blocks to match the last real block's DC value.
303 * This squeezes a few more bytes out of the resulting file...
304 */
305 if (coef->iMCU_row_num == last_iMCU_row) {
306 blocks_across += ndummy; /* include lower right corner */
307 MCUs_across = blocks_across / h_samp_factor;
308 for (block_row = block_rows; block_row < compptr->v_samp_factor;
309 block_row++) {
310 thisblockrow = buffer[block_row];
311 lastblockrow = buffer[block_row-1];
312 jzero_far((void FAR *) thisblockrow,
313 (size_t) (blocks_across * SIZEOF(JBLOCK)));
314 for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
315 lastDC = lastblockrow[h_samp_factor-1][0];
316 for (bi = 0; bi < h_samp_factor; bi++) {
317 thisblockrow[bi][0] = lastDC;
318 }
319 thisblockrow += h_samp_factor; /* advance to next MCU in row */
320 lastblockrow += h_samp_factor;
321 }
322 }
323 }
324 }
325 /* NB: compress_output will increment iMCU_row_num if successful.
326 * A suspension return will result in redoing all the work above next time.
327 */
328
329 /* Emit data to the entropy encoder, sharing code with subsequent passes */
330 return compress_output(cinfo, input_buf);
331 }
332
|
1 /*
2 * jccoefct.c
3 *
4 * Copyright (C) 1994-1997, Thomas G. Lane.
5 * Modified 2003-2011 by Guido Vollbeding.
6 * This file is part of the Independent JPEG Group's software.
7 * For conditions of distribution and use, see the accompanying README file.
8 *
9 * This file contains the coefficient buffer controller for compression.
10 * This controller is the top level of the JPEG compressor proper.
11 * The coefficient buffer lies between forward-DCT and entropy encoding steps.
12 */
13
14 #define JPEG_INTERNALS
15 #include "jinclude.h"
16 #include "jpeglib.h"
17
18
19 /* We use a full-image coefficient buffer when doing Huffman optimization,
20 * and also for writing multiple-scan JPEG files. In all cases, the DCT
21 * step is run during the first pass, and subsequent passes need only read
22 * the buffered coefficients.
23 */
24 #ifdef ENTROPY_OPT_SUPPORTED
25 #define FULL_COEF_BUFFER_SUPPORTED
167 * block's DC value. (Thanks to Thomas Kinsman for this idea.)
168 */
169 blkn = 0;
170 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
171 compptr = cinfo->cur_comp_info[ci];
172 forward_DCT = cinfo->fdct->forward_DCT[compptr->component_index];
173 blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
174 : compptr->last_col_width;
175 xpos = MCU_col_num * compptr->MCU_sample_width;
176 ypos = yoffset * compptr->DCT_v_scaled_size;
177 /* ypos == (yoffset+yindex) * DCTSIZE */
178 for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
179 if (coef->iMCU_row_num < last_iMCU_row ||
180 yoffset+yindex < compptr->last_row_height) {
181 (*forward_DCT) (cinfo, compptr,
182 input_buf[compptr->component_index],
183 coef->MCU_buffer[blkn],
184 ypos, xpos, (JDIMENSION) blockcnt);
185 if (blockcnt < compptr->MCU_width) {
186 /* Create some dummy blocks at the right edge of the image. */
187 FMEMZERO((void FAR *) coef->MCU_buffer[blkn + blockcnt],
188 (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
189 for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
190 coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
191 }
192 }
193 } else {
194 /* Create a row of dummy blocks at the bottom of the image. */
195 FMEMZERO((void FAR *) coef->MCU_buffer[blkn],
196 compptr->MCU_width * SIZEOF(JBLOCK));
197 for (bi = 0; bi < compptr->MCU_width; bi++) {
198 coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
199 }
200 }
201 blkn += compptr->MCU_width;
202 ypos += compptr->DCT_v_scaled_size;
203 }
204 }
205 /* Try to write the MCU. In event of a suspension failure, we will
206 * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
207 */
208 if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
209 /* Suspension forced; update state counters and exit */
210 coef->MCU_vert_offset = yoffset;
211 coef->mcu_ctr = MCU_col_num;
212 return FALSE;
213 }
214 }
215 /* Completed an MCU row, but perhaps not an iMCU row */
274 if (block_rows == 0) block_rows = compptr->v_samp_factor;
275 }
276 blocks_across = compptr->width_in_blocks;
277 h_samp_factor = compptr->h_samp_factor;
278 /* Count number of dummy blocks to be added at the right margin. */
279 ndummy = (int) (blocks_across % h_samp_factor);
280 if (ndummy > 0)
281 ndummy = h_samp_factor - ndummy;
282 forward_DCT = cinfo->fdct->forward_DCT[ci];
283 /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
284 * on forward_DCT processes a complete horizontal row of DCT blocks.
285 */
286 for (block_row = 0; block_row < block_rows; block_row++) {
287 thisblockrow = buffer[block_row];
288 (*forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow,
289 (JDIMENSION) (block_row * compptr->DCT_v_scaled_size),
290 (JDIMENSION) 0, blocks_across);
291 if (ndummy > 0) {
292 /* Create dummy blocks at the right edge of the image. */
293 thisblockrow += blocks_across; /* => first dummy block */
294 FMEMZERO((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
295 lastDC = thisblockrow[-1][0];
296 for (bi = 0; bi < ndummy; bi++) {
297 thisblockrow[bi][0] = lastDC;
298 }
299 }
300 }
301 /* If at end of image, create dummy block rows as needed.
302 * The tricky part here is that within each MCU, we want the DC values
303 * of the dummy blocks to match the last real block's DC value.
304 * This squeezes a few more bytes out of the resulting file...
305 */
306 if (coef->iMCU_row_num == last_iMCU_row) {
307 blocks_across += ndummy; /* include lower right corner */
308 MCUs_across = blocks_across / h_samp_factor;
309 for (block_row = block_rows; block_row < compptr->v_samp_factor;
310 block_row++) {
311 thisblockrow = buffer[block_row];
312 lastblockrow = buffer[block_row-1];
313 FMEMZERO((void FAR *) thisblockrow,
314 (size_t) (blocks_across * SIZEOF(JBLOCK)));
315 for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
316 lastDC = lastblockrow[h_samp_factor-1][0];
317 for (bi = 0; bi < h_samp_factor; bi++) {
318 thisblockrow[bi][0] = lastDC;
319 }
320 thisblockrow += h_samp_factor; /* advance to next MCU in row */
321 lastblockrow += h_samp_factor;
322 }
323 }
324 }
325 }
326 /* NB: compress_output will increment iMCU_row_num if successful.
327 * A suspension return will result in redoing all the work above next time.
328 */
329
330 /* Emit data to the entropy encoder, sharing code with subsequent passes */
331 return compress_output(cinfo, input_buf);
332 }
333
|