/src/libjpeg-turbo.2.1.x/jccoefct.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * jccoefct.c | 
| 3 |  |  * | 
| 4 |  |  * This file was part of the Independent JPEG Group's software: | 
| 5 |  |  * Copyright (C) 1994-1997, Thomas G. Lane. | 
| 6 |  |  * It was modified by The libjpeg-turbo Project to include only code and | 
| 7 |  |  * information relevant to libjpeg-turbo. | 
| 8 |  |  * For conditions of distribution and use, see the accompanying README.ijg | 
| 9 |  |  * file. | 
| 10 |  |  * | 
| 11 |  |  * This file contains the coefficient buffer controller for compression. | 
| 12 |  |  * This controller is the top level of the JPEG compressor proper. | 
| 13 |  |  * The coefficient buffer lies between forward-DCT and entropy encoding steps. | 
| 14 |  |  */ | 
| 15 |  |  | 
| 16 |  | #define JPEG_INTERNALS | 
| 17 |  | #include "jinclude.h" | 
| 18 |  | #include "jpeglib.h" | 
| 19 |  |  | 
| 20 |  |  | 
| 21 |  | /* We use a full-image coefficient buffer when doing Huffman optimization, | 
| 22 |  |  * and also for writing multiple-scan JPEG files.  In all cases, the DCT | 
| 23 |  |  * step is run during the first pass, and subsequent passes need only read | 
| 24 |  |  * the buffered coefficients. | 
| 25 |  |  */ | 
| 26 |  | #ifdef ENTROPY_OPT_SUPPORTED | 
| 27 |  | #define FULL_COEF_BUFFER_SUPPORTED | 
| 28 |  | #else | 
| 29 |  | #ifdef C_MULTISCAN_FILES_SUPPORTED | 
| 30 |  | #define FULL_COEF_BUFFER_SUPPORTED | 
| 31 |  | #endif | 
| 32 |  | #endif | 
| 33 |  |  | 
| 34 |  |  | 
| 35 |  | /* Private buffer controller object */ | 
| 36 |  |  | 
| 37 |  | typedef struct { | 
| 38 |  |   struct jpeg_c_coef_controller pub; /* public fields */ | 
| 39 |  |  | 
| 40 |  |   JDIMENSION iMCU_row_num;      /* iMCU row # within image */ | 
| 41 |  |   JDIMENSION mcu_ctr;           /* counts MCUs processed in current row */ | 
| 42 |  |   int MCU_vert_offset;          /* counts MCU rows within iMCU row */ | 
| 43 |  |   int MCU_rows_per_iMCU_row;    /* number of such rows needed */ | 
| 44 |  |  | 
| 45 |  |   /* For single-pass compression, it's sufficient to buffer just one MCU | 
| 46 |  |    * (although this may prove a bit slow in practice).  We allocate a | 
| 47 |  |    * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each | 
| 48 |  |    * MCU constructed and sent.  In multi-pass modes, this array points to the | 
| 49 |  |    * current MCU's blocks within the virtual arrays. | 
| 50 |  |    */ | 
| 51 |  |   JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; | 
| 52 |  |  | 
| 53 |  |   /* In multi-pass modes, we need a virtual block array for each component. */ | 
| 54 |  |   jvirt_barray_ptr whole_image[MAX_COMPONENTS]; | 
| 55 |  | } my_coef_controller; | 
| 56 |  |  | 
| 57 |  | typedef my_coef_controller *my_coef_ptr; | 
| 58 |  |  | 
| 59 |  |  | 
| 60 |  | /* Forward declarations */ | 
| 61 |  | METHODDEF(boolean) compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf); | 
| 62 |  | #ifdef FULL_COEF_BUFFER_SUPPORTED | 
| 63 |  | METHODDEF(boolean) compress_first_pass(j_compress_ptr cinfo, | 
| 64 |  |                                        JSAMPIMAGE input_buf); | 
| 65 |  | METHODDEF(boolean) compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf); | 
| 66 |  | #endif | 
| 67 |  |  | 
| 68 |  |  | 
| 69 |  | LOCAL(void) | 
| 70 |  | start_iMCU_row(j_compress_ptr cinfo) | 
| 71 |  | /* Reset within-iMCU-row counters for a new row */ | 
| 72 | 2.06M | { | 
| 73 | 2.06M |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 74 |  |  | 
| 75 |  |   /* In an interleaved scan, an MCU row is the same as an iMCU row. | 
| 76 |  |    * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. | 
| 77 |  |    * But at the bottom of the image, process only what's left. | 
| 78 |  |    */ | 
| 79 | 2.06M |   if (cinfo->comps_in_scan > 1) { | 
| 80 | 1.79M |     coef->MCU_rows_per_iMCU_row = 1; | 
| 81 | 1.79M |   } else { | 
| 82 | 271k |     if (coef->iMCU_row_num < (cinfo->total_iMCU_rows - 1)) | 
| 83 | 270k |       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; | 
| 84 | 1.00k |     else | 
| 85 | 1.00k |       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; | 
| 86 | 271k |   } | 
| 87 |  |  | 
| 88 | 2.06M |   coef->mcu_ctr = 0; | 
| 89 | 2.06M |   coef->MCU_vert_offset = 0; | 
| 90 | 2.06M | } | 
| 91 |  |  | 
| 92 |  |  | 
| 93 |  | /* | 
| 94 |  |  * Initialize for a processing pass. | 
| 95 |  |  */ | 
| 96 |  |  | 
| 97 |  | METHODDEF(void) | 
| 98 |  | start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode) | 
| 99 | 5.40k | { | 
| 100 | 5.40k |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 101 |  |  | 
| 102 | 5.40k |   coef->iMCU_row_num = 0; | 
| 103 | 5.40k |   start_iMCU_row(cinfo); | 
| 104 |  |  | 
| 105 | 5.40k |   switch (pass_mode) { | 
| 106 | 1.80k |   case JBUF_PASS_THRU: | 
| 107 | 1.80k |     if (coef->whole_image[0] != NULL) | 
| 108 | 0 |       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | 
| 109 | 1.80k |     coef->pub.compress_data = compress_data; | 
| 110 | 1.80k |     break; | 
| 111 | 0 | #ifdef FULL_COEF_BUFFER_SUPPORTED | 
| 112 | 2.47k |   case JBUF_SAVE_AND_PASS: | 
| 113 | 2.47k |     if (coef->whole_image[0] == NULL) | 
| 114 | 0 |       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | 
| 115 | 2.47k |     coef->pub.compress_data = compress_first_pass; | 
| 116 | 2.47k |     break; | 
| 117 | 1.12k |   case JBUF_CRANK_DEST: | 
| 118 | 1.12k |     if (coef->whole_image[0] == NULL) | 
| 119 | 0 |       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | 
| 120 | 1.12k |     coef->pub.compress_data = compress_output; | 
| 121 | 1.12k |     break; | 
| 122 | 0 | #endif | 
| 123 | 0 |   default: | 
| 124 | 0 |     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | 
| 125 | 0 |     break; | 
| 126 | 5.40k |   } | 
| 127 | 5.40k | } | 
| 128 |  |  | 
| 129 |  |  | 
| 130 |  | /* | 
| 131 |  |  * Process some data in the single-pass case. | 
| 132 |  |  * We process the equivalent of one fully interleaved MCU row ("iMCU" row) | 
| 133 |  |  * per call, ie, v_samp_factor block rows for each component in the image. | 
| 134 |  |  * Returns TRUE if the iMCU row is completed, FALSE if suspended. | 
| 135 |  |  * | 
| 136 |  |  * NB: input_buf contains a plane for each component in image, | 
| 137 |  |  * which we index according to the component's SOF position. | 
| 138 |  |  */ | 
| 139 |  |  | 
| 140 |  | METHODDEF(boolean) | 
| 141 |  | compress_data(j_compress_ptr cinfo, JSAMPIMAGE input_buf) | 
| 142 | 598k | { | 
| 143 | 598k |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 144 | 598k |   JDIMENSION MCU_col_num;       /* index of current MCU within row */ | 
| 145 | 598k |   JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; | 
| 146 | 598k |   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; | 
| 147 | 598k |   int blkn, bi, ci, yindex, yoffset, blockcnt; | 
| 148 | 598k |   JDIMENSION ypos, xpos; | 
| 149 | 598k |   jpeg_component_info *compptr; | 
| 150 |  |  | 
| 151 |  |   /* Loop to write as much as one whole iMCU row */ | 
| 152 | 1.19M |   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; | 
| 153 | 598k |        yoffset++) { | 
| 154 | 1.44M |     for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col; | 
| 155 | 845k |          MCU_col_num++) { | 
| 156 |  |       /* Determine where data comes from in input_buf and do the DCT thing. | 
| 157 |  |        * Each call on forward_DCT processes a horizontal row of DCT blocks | 
| 158 |  |        * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks | 
| 159 |  |        * sequentially.  Dummy blocks at the right or bottom edge are filled in | 
| 160 |  |        * specially.  The data in them does not matter for image reconstruction, | 
| 161 |  |        * so we fill them with values that will encode to the smallest amount of | 
| 162 |  |        * data, viz: all zeroes in the AC entries, DC entries equal to previous | 
| 163 |  |        * block's DC value.  (Thanks to Thomas Kinsman for this idea.) | 
| 164 |  |        */ | 
| 165 | 845k |       blkn = 0; | 
| 166 | 3.38M |       for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | 
| 167 | 2.53M |         compptr = cinfo->cur_comp_info[ci]; | 
| 168 | 2.53M |         blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width : | 
| 169 | 2.53M |                                                   compptr->last_col_width; | 
| 170 | 2.53M |         xpos = MCU_col_num * compptr->MCU_sample_width; | 
| 171 | 2.53M |         ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */ | 
| 172 | 5.91M |         for (yindex = 0; yindex < compptr->MCU_height; yindex++) { | 
| 173 | 3.38M |           if (coef->iMCU_row_num < last_iMCU_row || | 
| 174 | 3.38M |               yoffset + yindex < compptr->last_row_height) { | 
| 175 | 3.32M |             (*cinfo->fdct->forward_DCT) (cinfo, compptr, | 
| 176 | 3.32M |                                          input_buf[compptr->component_index], | 
| 177 | 3.32M |                                          coef->MCU_buffer[blkn], | 
| 178 | 3.32M |                                          ypos, xpos, (JDIMENSION)blockcnt); | 
| 179 | 3.32M |             if (blockcnt < compptr->MCU_width) { | 
| 180 |  |               /* Create some dummy blocks at the right edge of the image. */ | 
| 181 | 1.11M |               jzero_far((void *)coef->MCU_buffer[blkn + blockcnt], | 
| 182 | 1.11M |                         (compptr->MCU_width - blockcnt) * sizeof(JBLOCK)); | 
| 183 | 2.22M |               for (bi = blockcnt; bi < compptr->MCU_width; bi++) { | 
| 184 | 1.11M |                 coef->MCU_buffer[blkn + bi][0][0] = | 
| 185 | 1.11M |                   coef->MCU_buffer[blkn + bi - 1][0][0]; | 
| 186 | 1.11M |               } | 
| 187 | 1.11M |             } | 
| 188 | 3.32M |           } else { | 
| 189 |  |             /* Create a row of dummy blocks at the bottom of the image. */ | 
| 190 | 58.4k |             jzero_far((void *)coef->MCU_buffer[blkn], | 
| 191 | 58.4k |                       compptr->MCU_width * sizeof(JBLOCK)); | 
| 192 | 175k |             for (bi = 0; bi < compptr->MCU_width; bi++) { | 
| 193 | 116k |               coef->MCU_buffer[blkn + bi][0][0] = | 
| 194 | 116k |                 coef->MCU_buffer[blkn - 1][0][0]; | 
| 195 | 116k |             } | 
| 196 | 58.4k |           } | 
| 197 | 3.38M |           blkn += compptr->MCU_width; | 
| 198 | 3.38M |           ypos += DCTSIZE; | 
| 199 | 3.38M |         } | 
| 200 | 2.53M |       } | 
| 201 |  |       /* Try to write the MCU.  In event of a suspension failure, we will | 
| 202 |  |        * re-DCT the MCU on restart (a bit inefficient, could be fixed...) | 
| 203 |  |        */ | 
| 204 | 845k |       if (!(*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { | 
| 205 |  |         /* Suspension forced; update state counters and exit */ | 
| 206 | 0 |         coef->MCU_vert_offset = yoffset; | 
| 207 | 0 |         coef->mcu_ctr = MCU_col_num; | 
| 208 | 0 |         return FALSE; | 
| 209 | 0 |       } | 
| 210 | 845k |     } | 
| 211 |  |     /* Completed an MCU row, but perhaps not an iMCU row */ | 
| 212 | 598k |     coef->mcu_ctr = 0; | 
| 213 | 598k |   } | 
| 214 |  |   /* Completed the iMCU row, advance counters for next one */ | 
| 215 | 598k |   coef->iMCU_row_num++; | 
| 216 | 598k |   start_iMCU_row(cinfo); | 
| 217 | 598k |   return TRUE; | 
| 218 | 598k | } | 
| 219 |  |  | 
| 220 |  |  | 
| 221 |  | #ifdef FULL_COEF_BUFFER_SUPPORTED | 
| 222 |  |  | 
| 223 |  | /* | 
| 224 |  |  * Process some data in the first pass of a multi-pass case. | 
| 225 |  |  * We process the equivalent of one fully interleaved MCU row ("iMCU" row) | 
| 226 |  |  * per call, ie, v_samp_factor block rows for each component in the image. | 
| 227 |  |  * This amount of data is read from the source buffer, DCT'd and quantized, | 
| 228 |  |  * and saved into the virtual arrays.  We also generate suitable dummy blocks | 
| 229 |  |  * as needed at the right and lower edges.  (The dummy blocks are constructed | 
| 230 |  |  * in the virtual arrays, which have been padded appropriately.)  This makes | 
| 231 |  |  * it possible for subsequent passes not to worry about real vs. dummy blocks. | 
| 232 |  |  * | 
| 233 |  |  * We must also emit the data to the entropy encoder.  This is conveniently | 
| 234 |  |  * done by calling compress_output() after we've loaded the current strip | 
| 235 |  |  * of the virtual arrays. | 
| 236 |  |  * | 
| 237 |  |  * NB: input_buf contains a plane for each component in image.  All | 
| 238 |  |  * components are DCT'd and loaded into the virtual arrays in this pass. | 
| 239 |  |  * However, it may be that only a subset of the components are emitted to | 
| 240 |  |  * the entropy encoder during this first pass; be careful about looking | 
| 241 |  |  * at the scan-dependent variables (MCU dimensions, etc). | 
| 242 |  |  */ | 
| 243 |  |  | 
| 244 |  | METHODDEF(boolean) | 
| 245 |  | compress_first_pass(j_compress_ptr cinfo, JSAMPIMAGE input_buf) | 
| 246 | 735k | { | 
| 247 | 735k |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 248 | 735k |   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; | 
| 249 | 735k |   JDIMENSION blocks_across, MCUs_across, MCUindex; | 
| 250 | 735k |   int bi, ci, h_samp_factor, block_row, block_rows, ndummy; | 
| 251 | 735k |   JCOEF lastDC; | 
| 252 | 735k |   jpeg_component_info *compptr; | 
| 253 | 735k |   JBLOCKARRAY buffer; | 
| 254 | 735k |   JBLOCKROW thisblockrow, lastblockrow; | 
| 255 |  |  | 
| 256 | 2.66M |   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; | 
| 257 | 1.93M |        ci++, compptr++) { | 
| 258 |  |     /* Align the virtual buffer for this component. */ | 
| 259 | 1.93M |     buffer = (*cinfo->mem->access_virt_barray) | 
| 260 | 1.93M |       ((j_common_ptr)cinfo, coef->whole_image[ci], | 
| 261 | 1.93M |        coef->iMCU_row_num * compptr->v_samp_factor, | 
| 262 | 1.93M |        (JDIMENSION)compptr->v_samp_factor, TRUE); | 
| 263 |  |     /* Count non-dummy DCT block rows in this iMCU row. */ | 
| 264 | 1.93M |     if (coef->iMCU_row_num < last_iMCU_row) | 
| 265 | 1.92M |       block_rows = compptr->v_samp_factor; | 
| 266 | 2.98k |     else { | 
| 267 |  |       /* NB: can't use last_row_height here, since may not be set! */ | 
| 268 | 2.98k |       block_rows = (int)(compptr->height_in_blocks % compptr->v_samp_factor); | 
| 269 | 2.98k |       if (block_rows == 0) block_rows = compptr->v_samp_factor; | 
| 270 | 2.98k |     } | 
| 271 | 1.93M |     blocks_across = compptr->width_in_blocks; | 
| 272 | 1.93M |     h_samp_factor = compptr->h_samp_factor; | 
| 273 |  |     /* Count number of dummy blocks to be added at the right margin. */ | 
| 274 | 1.93M |     ndummy = (int)(blocks_across % h_samp_factor); | 
| 275 | 1.93M |     if (ndummy > 0) | 
| 276 | 1.31M |       ndummy = h_samp_factor - ndummy; | 
| 277 |  |     /* Perform DCT for all non-dummy blocks in this iMCU row.  Each call | 
| 278 |  |      * on forward_DCT processes a complete horizontal row of DCT blocks. | 
| 279 |  |      */ | 
| 280 | 5.06M |     for (block_row = 0; block_row < block_rows; block_row++) { | 
| 281 | 3.12M |       thisblockrow = buffer[block_row]; | 
| 282 | 3.12M |       (*cinfo->fdct->forward_DCT) (cinfo, compptr, | 
| 283 | 3.12M |                                    input_buf[ci], thisblockrow, | 
| 284 | 3.12M |                                    (JDIMENSION)(block_row * DCTSIZE), | 
| 285 | 3.12M |                                    (JDIMENSION)0, blocks_across); | 
| 286 | 3.12M |       if (ndummy > 0) { | 
| 287 |  |         /* Create dummy blocks at the right edge of the image. */ | 
| 288 | 1.89M |         thisblockrow += blocks_across; /* => first dummy block */ | 
| 289 | 1.89M |         jzero_far((void *)thisblockrow, ndummy * sizeof(JBLOCK)); | 
| 290 | 1.89M |         lastDC = thisblockrow[-1][0]; | 
| 291 | 5.13M |         for (bi = 0; bi < ndummy; bi++) { | 
| 292 | 3.23M |           thisblockrow[bi][0] = lastDC; | 
| 293 | 3.23M |         } | 
| 294 | 1.89M |       } | 
| 295 | 3.12M |     } | 
| 296 |  |     /* If at end of image, create dummy block rows as needed. | 
| 297 |  |      * The tricky part here is that within each MCU, we want the DC values | 
| 298 |  |      * of the dummy blocks to match the last real block's DC value. | 
| 299 |  |      * This squeezes a few more bytes out of the resulting file... | 
| 300 |  |      */ | 
| 301 | 1.93M |     if (coef->iMCU_row_num == last_iMCU_row) { | 
| 302 | 2.98k |       blocks_across += ndummy;  /* include lower right corner */ | 
| 303 | 2.98k |       MCUs_across = blocks_across / h_samp_factor; | 
| 304 | 4.35k |       for (block_row = block_rows; block_row < compptr->v_samp_factor; | 
| 305 | 2.98k |            block_row++) { | 
| 306 | 1.36k |         thisblockrow = buffer[block_row]; | 
| 307 | 1.36k |         lastblockrow = buffer[block_row - 1]; | 
| 308 | 1.36k |         jzero_far((void *)thisblockrow, | 
| 309 | 1.36k |                   (size_t)(blocks_across * sizeof(JBLOCK))); | 
| 310 | 60.4k |         for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) { | 
| 311 | 59.0k |           lastDC = lastblockrow[h_samp_factor - 1][0]; | 
| 312 | 147k |           for (bi = 0; bi < h_samp_factor; bi++) { | 
| 313 | 88.5k |             thisblockrow[bi][0] = lastDC; | 
| 314 | 88.5k |           } | 
| 315 | 59.0k |           thisblockrow += h_samp_factor; /* advance to next MCU in row */ | 
| 316 | 59.0k |           lastblockrow += h_samp_factor; | 
| 317 | 59.0k |         } | 
| 318 | 1.36k |       } | 
| 319 | 2.98k |     } | 
| 320 | 1.93M |   } | 
| 321 |  |   /* NB: compress_output will increment iMCU_row_num if successful. | 
| 322 |  |    * A suspension return will result in redoing all the work above next time. | 
| 323 |  |    */ | 
| 324 |  |  | 
| 325 |  |   /* Emit data to the entropy encoder, sharing code with subsequent passes */ | 
| 326 | 735k |   return compress_output(cinfo, input_buf); | 
| 327 | 735k | } | 
| 328 |  |  | 
| 329 |  |  | 
| 330 |  | /* | 
| 331 |  |  * Process some data in subsequent passes of a multi-pass case. | 
| 332 |  |  * We process the equivalent of one fully interleaved MCU row ("iMCU" row) | 
| 333 |  |  * per call, ie, v_samp_factor block rows for each component in the scan. | 
| 334 |  |  * The data is obtained from the virtual arrays and fed to the entropy coder. | 
| 335 |  |  * Returns TRUE if the iMCU row is completed, FALSE if suspended. | 
| 336 |  |  * | 
| 337 |  |  * NB: input_buf is ignored; it is likely to be a NULL pointer. | 
| 338 |  |  */ | 
| 339 |  |  | 
| 340 |  | METHODDEF(boolean) | 
| 341 |  | compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf) | 
| 342 | 1.46M | { | 
| 343 | 1.46M |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 344 | 1.46M |   JDIMENSION MCU_col_num;       /* index of current MCU within row */ | 
| 345 | 1.46M |   int blkn, ci, xindex, yindex, yoffset; | 
| 346 | 1.46M |   JDIMENSION start_col; | 
| 347 | 1.46M |   JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; | 
| 348 | 1.46M |   JBLOCKROW buffer_ptr; | 
| 349 | 1.46M |   jpeg_component_info *compptr; | 
| 350 |  |  | 
| 351 |  |   /* Align the virtual buffers for the components used in this scan. | 
| 352 |  |    * NB: during first pass, this is safe only because the buffers will | 
| 353 |  |    * already be aligned properly, so jmemmgr.c won't need to do any I/O. | 
| 354 |  |    */ | 
| 355 | 5.31M |   for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | 
| 356 | 3.85M |     compptr = cinfo->cur_comp_info[ci]; | 
| 357 | 3.85M |     buffer[ci] = (*cinfo->mem->access_virt_barray) | 
| 358 | 3.85M |       ((j_common_ptr)cinfo, coef->whole_image[compptr->component_index], | 
| 359 | 3.85M |        coef->iMCU_row_num * compptr->v_samp_factor, | 
| 360 | 3.85M |        (JDIMENSION)compptr->v_samp_factor, FALSE); | 
| 361 | 3.85M |   } | 
| 362 |  |  | 
| 363 |  |   /* Loop to process one whole iMCU row */ | 
| 364 | 2.92M |   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; | 
| 365 | 1.46M |        yoffset++) { | 
| 366 | 3.73M |     for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; | 
| 367 | 2.26M |          MCU_col_num++) { | 
| 368 |  |       /* Construct list of pointers to DCT blocks belonging to this MCU */ | 
| 369 | 2.26M |       blkn = 0;                 /* index of current DCT block within MCU */ | 
| 370 | 7.38M |       for (ci = 0; ci < cinfo->comps_in_scan; ci++) { | 
| 371 | 5.12M |         compptr = cinfo->cur_comp_info[ci]; | 
| 372 | 5.12M |         start_col = MCU_col_num * compptr->MCU_width; | 
| 373 | 13.0M |         for (yindex = 0; yindex < compptr->MCU_height; yindex++) { | 
| 374 | 7.97M |           buffer_ptr = buffer[ci][yindex + yoffset] + start_col; | 
| 375 | 23.0M |           for (xindex = 0; xindex < compptr->MCU_width; xindex++) { | 
| 376 | 15.1M |             coef->MCU_buffer[blkn++] = buffer_ptr++; | 
| 377 | 15.1M |           } | 
| 378 | 7.97M |         } | 
| 379 | 5.12M |       } | 
| 380 |  |       /* Try to write the MCU. */ | 
| 381 | 2.26M |       if (!(*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { | 
| 382 |  |         /* Suspension forced; update state counters and exit */ | 
| 383 | 0 |         coef->MCU_vert_offset = yoffset; | 
| 384 | 0 |         coef->mcu_ctr = MCU_col_num; | 
| 385 | 0 |         return FALSE; | 
| 386 | 0 |       } | 
| 387 | 2.26M |     } | 
| 388 |  |     /* Completed an MCU row, but perhaps not an iMCU row */ | 
| 389 | 1.46M |     coef->mcu_ctr = 0; | 
| 390 | 1.46M |   } | 
| 391 |  |   /* Completed the iMCU row, advance counters for next one */ | 
| 392 | 1.46M |   coef->iMCU_row_num++; | 
| 393 | 1.46M |   start_iMCU_row(cinfo); | 
| 394 | 1.46M |   return TRUE; | 
| 395 | 1.46M | } | 
| 396 |  |  | 
| 397 |  | #endif /* FULL_COEF_BUFFER_SUPPORTED */ | 
| 398 |  |  | 
| 399 |  |  | 
| 400 |  | /* | 
| 401 |  |  * Initialize coefficient buffer controller. | 
| 402 |  |  */ | 
| 403 |  |  | 
| 404 |  | GLOBAL(void) | 
| 405 |  | jinit_c_coef_controller(j_compress_ptr cinfo, boolean need_full_buffer) | 
| 406 | 4.27k | { | 
| 407 | 4.27k |   my_coef_ptr coef; | 
| 408 |  |  | 
| 409 | 4.27k |   coef = (my_coef_ptr) | 
| 410 | 4.27k |     (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, | 
| 411 | 4.27k |                                 sizeof(my_coef_controller)); | 
| 412 | 4.27k |   cinfo->coef = (struct jpeg_c_coef_controller *)coef; | 
| 413 | 4.27k |   coef->pub.start_pass = start_pass_coef; | 
| 414 |  |  | 
| 415 |  |   /* Create the coefficient buffer. */ | 
| 416 | 4.27k |   if (need_full_buffer) { | 
| 417 | 2.47k | #ifdef FULL_COEF_BUFFER_SUPPORTED | 
| 418 |  |     /* Allocate a full-image virtual array for each component, */ | 
| 419 |  |     /* padded to a multiple of samp_factor DCT blocks in each direction. */ | 
| 420 | 2.47k |     int ci; | 
| 421 | 2.47k |     jpeg_component_info *compptr; | 
| 422 |  |  | 
| 423 | 8.55k |     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; | 
| 424 | 6.08k |          ci++, compptr++) { | 
| 425 | 6.08k |       coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) | 
| 426 | 6.08k |         ((j_common_ptr)cinfo, JPOOL_IMAGE, FALSE, | 
| 427 | 6.08k |          (JDIMENSION)jround_up((long)compptr->width_in_blocks, | 
| 428 | 6.08k |                                (long)compptr->h_samp_factor), | 
| 429 | 6.08k |          (JDIMENSION)jround_up((long)compptr->height_in_blocks, | 
| 430 | 6.08k |                                (long)compptr->v_samp_factor), | 
| 431 | 6.08k |          (JDIMENSION)compptr->v_samp_factor); | 
| 432 | 6.08k |     } | 
| 433 |  | #else | 
| 434 |  |     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); | 
| 435 |  | #endif | 
| 436 | 2.47k |   } else { | 
| 437 |  |     /* We only need a single-MCU buffer. */ | 
| 438 | 1.80k |     JBLOCKROW buffer; | 
| 439 | 1.80k |     int i; | 
| 440 |  |  | 
| 441 | 1.80k |     buffer = (JBLOCKROW) | 
| 442 | 1.80k |       (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE, | 
| 443 | 1.80k |                                   C_MAX_BLOCKS_IN_MCU * sizeof(JBLOCK)); | 
| 444 | 19.8k |     for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { | 
| 445 | 18.0k |       coef->MCU_buffer[i] = buffer + i; | 
| 446 | 18.0k |     } | 
| 447 | 1.80k |     coef->whole_image[0] = NULL; /* flag for no virtual arrays */ | 
| 448 | 1.80k |   } | 
| 449 | 4.27k | } |