/src/libjpeg-turbo.main/jdapistd.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * jdapistd.c | 
| 3 |  |  * | 
| 4 |  |  * This file was part of the Independent JPEG Group's software: | 
| 5 |  |  * Copyright (C) 1994-1996, Thomas G. Lane. | 
| 6 |  |  * libjpeg-turbo Modifications: | 
| 7 |  |  * Copyright (C) 2010, 2015-2020, 2022-2023, D. R. Commander. | 
| 8 |  |  * Copyright (C) 2015, Google, Inc. | 
| 9 |  |  * For conditions of distribution and use, see the accompanying README.ijg | 
| 10 |  |  * file. | 
| 11 |  |  * | 
| 12 |  |  * This file contains application interface code for the decompression half | 
| 13 |  |  * of the JPEG library.  These are the "standard" API routines that are | 
| 14 |  |  * used in the normal full-decompression case.  They are not used by a | 
| 15 |  |  * transcoding-only application.  Note that if an application links in | 
| 16 |  |  * jpeg_start_decompress, it will end up linking in the entire decompressor. | 
| 17 |  |  * We thus must separate this file from jdapimin.c to avoid linking the | 
| 18 |  |  * whole decompression library into a transcoder. | 
| 19 |  |  */ | 
| 20 |  |  | 
| 21 |  | #include "jinclude.h" | 
| 22 |  | #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) | 
| 23 |  | #include "jdmainct.h" | 
| 24 |  | #include "jdcoefct.h" | 
| 25 |  | #else | 
| 26 |  | #define JPEG_INTERNALS | 
| 27 |  | #include "jpeglib.h" | 
| 28 |  | #endif | 
| 29 |  | #include "jdmaster.h" | 
| 30 |  | #include "jdmerge.h" | 
| 31 |  | #include "jdsample.h" | 
| 32 |  | #include "jmemsys.h" | 
| 33 |  |  | 
| 34 |  | #if BITS_IN_JSAMPLE == 8 | 
| 35 |  |  | 
| 36 |  | /* Forward declarations */ | 
| 37 |  | LOCAL(boolean) output_pass_setup(j_decompress_ptr cinfo); | 
| 38 |  |  | 
| 39 |  |  | 
| 40 |  | /* | 
| 41 |  |  * Decompression initialization. | 
| 42 |  |  * jpeg_read_header must be completed before calling this. | 
| 43 |  |  * | 
| 44 |  |  * If a multipass operating mode was selected, this will do all but the | 
| 45 |  |  * last pass, and thus may take a great deal of time. | 
| 46 |  |  * | 
| 47 |  |  * Returns FALSE if suspended.  The return value need be inspected only if | 
| 48 |  |  * a suspending data source is used. | 
| 49 |  |  */ | 
| 50 |  |  | 
| 51 |  | GLOBAL(boolean) | 
| 52 |  | jpeg_start_decompress(j_decompress_ptr cinfo) | 
| 53 | 4.59k | { | 
| 54 | 4.59k |   if (cinfo->global_state == DSTATE_READY) { | 
| 55 |  |     /* First call: initialize master control, select active modules */ | 
| 56 | 4.59k |     jinit_master_decompress(cinfo); | 
| 57 | 4.59k |     if (cinfo->buffered_image) { | 
| 58 |  |       /* No more work here; expecting jpeg_start_output next */ | 
| 59 | 0 |       cinfo->global_state = DSTATE_BUFIMAGE; | 
| 60 | 0 |       return TRUE; | 
| 61 | 0 |     } | 
| 62 | 4.59k |     cinfo->global_state = DSTATE_PRELOAD; | 
| 63 | 4.59k |   } | 
| 64 | 4.59k |   if (cinfo->global_state == DSTATE_PRELOAD) { | 
| 65 |  |     /* If file has multiple scans, absorb them all into the coef buffer */ | 
| 66 | 4.14k |     if (cinfo->inputctl->has_multiple_scans) { | 
| 67 | 3.49k | #ifdef D_MULTISCAN_FILES_SUPPORTED | 
| 68 | 42.1M |       for (;;) { | 
| 69 | 42.1M |         int retcode; | 
| 70 |  |         /* Call progress monitor hook if present */ | 
| 71 | 42.1M |         if (cinfo->progress != NULL) | 
| 72 | 42.1M |           (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); | 
| 73 |  |         /* Absorb some more input */ | 
| 74 | 42.1M |         retcode = (*cinfo->inputctl->consume_input) (cinfo); | 
| 75 | 42.1M |         if (retcode == JPEG_SUSPENDED) | 
| 76 | 0 |           return FALSE; | 
| 77 | 42.1M |         if (retcode == JPEG_REACHED_EOI) | 
| 78 | 3.11k |           break; | 
| 79 |  |         /* Advance progress counter if appropriate */ | 
| 80 | 42.1M |         if (cinfo->progress != NULL && | 
| 81 | 42.1M |             (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { | 
| 82 | 42.1M |           if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { | 
| 83 |  |             /* jdmaster underestimated number of scans; ratchet up one scan */ | 
| 84 | 18.1k |             cinfo->progress->pass_limit += (long)cinfo->total_iMCU_rows; | 
| 85 | 18.1k |           } | 
| 86 | 42.1M |         } | 
| 87 | 42.1M |       } | 
| 88 |  | #else | 
| 89 |  |       ERREXIT(cinfo, JERR_NOT_COMPILED); | 
| 90 |  | #endif /* D_MULTISCAN_FILES_SUPPORTED */ | 
| 91 | 3.49k |     } | 
| 92 | 4.14k |     cinfo->output_scan_number = cinfo->input_scan_number; | 
| 93 | 4.14k |   } else if (cinfo->global_state != DSTATE_PRESCAN) | 
| 94 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 95 |  |   /* Perform any dummy output passes, and set up for the final pass */ | 
| 96 | 4.59k |   return output_pass_setup(cinfo); | 
| 97 | 4.59k | } | 
| 98 |  |  | 
| 99 |  |  | 
| 100 |  | /* | 
| 101 |  |  * Set up for an output pass, and perform any dummy pass(es) needed. | 
| 102 |  |  * Common subroutine for jpeg_start_decompress and jpeg_start_output. | 
| 103 |  |  * Entry: global_state = DSTATE_PRESCAN only if previously suspended. | 
| 104 |  |  * Exit: If done, returns TRUE and sets global_state for proper output mode. | 
| 105 |  |  *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. | 
| 106 |  |  */ | 
| 107 |  |  | 
| 108 |  | LOCAL(boolean) | 
| 109 |  | output_pass_setup(j_decompress_ptr cinfo) | 
| 110 | 3.77k | { | 
| 111 | 3.77k |   if (cinfo->global_state != DSTATE_PRESCAN) { | 
| 112 |  |     /* First call: do pass setup */ | 
| 113 | 3.77k |     (*cinfo->master->prepare_for_output_pass) (cinfo); | 
| 114 | 3.77k |     cinfo->output_scanline = 0; | 
| 115 | 3.77k |     cinfo->global_state = DSTATE_PRESCAN; | 
| 116 | 3.77k |   } | 
| 117 |  |   /* Loop over any required dummy passes */ | 
| 118 | 3.77k |   while (cinfo->master->is_dummy_pass) { | 
| 119 | 0 | #ifdef QUANT_2PASS_SUPPORTED | 
| 120 |  |     /* Crank through the dummy pass */ | 
| 121 | 0 |     while (cinfo->output_scanline < cinfo->output_height) { | 
| 122 | 0 |       JDIMENSION last_scanline; | 
| 123 |  |       /* Call progress monitor hook if present */ | 
| 124 | 0 |       if (cinfo->progress != NULL) { | 
| 125 | 0 |         cinfo->progress->pass_counter = (long)cinfo->output_scanline; | 
| 126 | 0 |         cinfo->progress->pass_limit = (long)cinfo->output_height; | 
| 127 | 0 |         (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); | 
| 128 | 0 |       } | 
| 129 |  |       /* Process some data */ | 
| 130 | 0 |       last_scanline = cinfo->output_scanline; | 
| 131 | 0 | #ifdef D_LOSSLESS_SUPPORTED | 
| 132 | 0 |       if (cinfo->data_precision == 16) | 
| 133 | 0 |         (*cinfo->main->process_data_16) (cinfo, (J16SAMPARRAY)NULL, | 
| 134 | 0 |                                          &cinfo->output_scanline, | 
| 135 | 0 |                                          (JDIMENSION)0); | 
| 136 | 0 |       else | 
| 137 | 0 | #endif | 
| 138 | 0 |       if (cinfo->data_precision == 12) | 
| 139 | 0 |         (*cinfo->main->process_data_12) (cinfo, (J12SAMPARRAY)NULL, | 
| 140 | 0 |                                          &cinfo->output_scanline, | 
| 141 | 0 |                                          (JDIMENSION)0); | 
| 142 | 0 |       else | 
| 143 | 0 |         (*cinfo->main->process_data) (cinfo, (JSAMPARRAY)NULL, | 
| 144 | 0 |                                       &cinfo->output_scanline, (JDIMENSION)0); | 
| 145 | 0 |       if (cinfo->output_scanline == last_scanline) | 
| 146 | 0 |         return FALSE;           /* No progress made, must suspend */ | 
| 147 | 0 |     } | 
| 148 |  |     /* Finish up dummy pass, and set up for another one */ | 
| 149 | 0 |     (*cinfo->master->finish_output_pass) (cinfo); | 
| 150 | 0 |     (*cinfo->master->prepare_for_output_pass) (cinfo); | 
| 151 | 0 |     cinfo->output_scanline = 0; | 
| 152 |  | #else | 
| 153 |  |     ERREXIT(cinfo, JERR_NOT_COMPILED); | 
| 154 |  | #endif /* QUANT_2PASS_SUPPORTED */ | 
| 155 | 0 |   } | 
| 156 |  |   /* Ready for application to drive output pass through | 
| 157 |  |    * _jpeg_read_scanlines or _jpeg_read_raw_data. | 
| 158 |  |    */ | 
| 159 | 3.77k |   cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; | 
| 160 | 3.77k |   return TRUE; | 
| 161 | 3.77k | } | 
| 162 |  |  | 
| 163 |  | #endif /* BITS_IN_JSAMPLE == 8 */ | 
| 164 |  |  | 
| 165 |  |  | 
| 166 |  | #if BITS_IN_JSAMPLE != 16 | 
| 167 |  |  | 
| 168 |  | /* | 
| 169 |  |  * Enable partial scanline decompression | 
| 170 |  |  * | 
| 171 |  |  * Must be called after jpeg_start_decompress() and before any calls to | 
| 172 |  |  * _jpeg_read_scanlines() or _jpeg_skip_scanlines(). | 
| 173 |  |  * | 
| 174 |  |  * Refer to libjpeg.txt for more information. | 
| 175 |  |  */ | 
| 176 |  |  | 
| 177 |  | GLOBAL(void) | 
| 178 |  | _jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset, | 
| 179 |  |                     JDIMENSION *width) | 
| 180 | 0 | { | 
| 181 | 0 |   int ci, align, orig_downsampled_width; | 
| 182 | 0 |   JDIMENSION input_xoffset; | 
| 183 | 0 |   boolean reinit_upsampler = FALSE; | 
| 184 | 0 |   jpeg_component_info *compptr; | 
| 185 | 0 | #ifdef UPSAMPLE_MERGING_SUPPORTED | 
| 186 | 0 |   my_master_ptr master = (my_master_ptr)cinfo->master; | 
| 187 | 0 | #endif | 
| 188 |  | 
 | 
| 189 | 0 |   if (cinfo->data_precision != BITS_IN_JSAMPLE) | 
| 190 | 0 |     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 
| 191 |  | 
 | 
| 192 | 0 |   if (cinfo->master->lossless) | 
| 193 | 0 |     ERREXIT(cinfo, JERR_NOTIMPL); | 
| 194 |  | 
 | 
| 195 | 0 |   if ((cinfo->global_state != DSTATE_SCANNING && | 
| 196 | 0 |        cinfo->global_state != DSTATE_BUFIMAGE) || cinfo->output_scanline != 0) | 
| 197 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 198 |  | 
 | 
| 199 | 0 |   if (!xoffset || !width) | 
| 200 | 0 |     ERREXIT(cinfo, JERR_BAD_CROP_SPEC); | 
| 201 |  |  | 
| 202 |  |   /* xoffset and width must fall within the output image dimensions. */ | 
| 203 | 0 |   if (*width == 0 || *xoffset + *width > cinfo->output_width) | 
| 204 | 0 |     ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); | 
| 205 |  |  | 
| 206 |  |   /* No need to do anything if the caller wants the entire width. */ | 
| 207 | 0 |   if (*width == cinfo->output_width) | 
| 208 | 0 |     return; | 
| 209 |  |  | 
| 210 |  |   /* Ensuring the proper alignment of xoffset is tricky.  At minimum, it | 
| 211 |  |    * must align with an MCU boundary, because: | 
| 212 |  |    * | 
| 213 |  |    *   (1) The IDCT is performed in blocks, and it is not feasible to modify | 
| 214 |  |    *       the algorithm so that it can transform partial blocks. | 
| 215 |  |    *   (2) Because of the SIMD extensions, any input buffer passed to the | 
| 216 |  |    *       upsampling and color conversion routines must be aligned to the | 
| 217 |  |    *       SIMD word size (for instance, 128-bit in the case of SSE2.)  The | 
| 218 |  |    *       easiest way to accomplish this without copying data is to ensure | 
| 219 |  |    *       that upsampling and color conversion begin at the start of the | 
| 220 |  |    *       first MCU column that will be inverse transformed. | 
| 221 |  |    * | 
| 222 |  |    * In practice, we actually impose a stricter alignment requirement.  We | 
| 223 |  |    * require that xoffset be a multiple of the maximum MCU column width of all | 
| 224 |  |    * of the components (the "iMCU column width.")  This is to simplify the | 
| 225 |  |    * single-pass decompression case, allowing us to use the same MCU column | 
| 226 |  |    * width for all of the components. | 
| 227 |  |    */ | 
| 228 | 0 |   if (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) | 
| 229 | 0 |     align = cinfo->_min_DCT_scaled_size; | 
| 230 | 0 |   else | 
| 231 | 0 |     align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor; | 
| 232 |  |  | 
| 233 |  |   /* Adjust xoffset to the nearest iMCU boundary <= the requested value */ | 
| 234 | 0 |   input_xoffset = *xoffset; | 
| 235 | 0 |   *xoffset = (input_xoffset / align) * align; | 
| 236 |  |  | 
| 237 |  |   /* Adjust the width so that the right edge of the output image is as | 
| 238 |  |    * requested (only the left edge is altered.)  It is important that calling | 
| 239 |  |    * programs check this value after this function returns, so that they can | 
| 240 |  |    * allocate an output buffer with the appropriate size. | 
| 241 |  |    */ | 
| 242 | 0 |   *width = *width + input_xoffset - *xoffset; | 
| 243 | 0 |   cinfo->output_width = *width; | 
| 244 | 0 | #ifdef UPSAMPLE_MERGING_SUPPORTED | 
| 245 | 0 |   if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) { | 
| 246 | 0 |     my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; | 
| 247 | 0 |     upsample->out_row_width = | 
| 248 | 0 |       cinfo->output_width * cinfo->out_color_components; | 
| 249 | 0 |   } | 
| 250 | 0 | #endif | 
| 251 |  |  | 
| 252 |  |   /* Set the first and last iMCU columns that we must decompress.  These values | 
| 253 |  |    * will be used in single-scan decompressions. | 
| 254 |  |    */ | 
| 255 | 0 |   cinfo->master->first_iMCU_col = (JDIMENSION)(long)(*xoffset) / (long)align; | 
| 256 | 0 |   cinfo->master->last_iMCU_col = | 
| 257 | 0 |     (JDIMENSION)jdiv_round_up((long)(*xoffset + cinfo->output_width), | 
| 258 | 0 |                               (long)align) - 1; | 
| 259 |  | 
 | 
| 260 | 0 |   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; | 
| 261 | 0 |        ci++, compptr++) { | 
| 262 | 0 |     int hsf = (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) ? | 
| 263 | 0 |               1 : compptr->h_samp_factor; | 
| 264 |  |  | 
| 265 |  |     /* Set downsampled_width to the new output width. */ | 
| 266 | 0 |     orig_downsampled_width = compptr->downsampled_width; | 
| 267 | 0 |     compptr->downsampled_width = | 
| 268 | 0 |       (JDIMENSION)jdiv_round_up((long)cinfo->output_width * | 
| 269 | 0 |                                 (long)(compptr->h_samp_factor * | 
| 270 | 0 |                                        compptr->_DCT_scaled_size), | 
| 271 | 0 |                                 (long)(cinfo->max_h_samp_factor * | 
| 272 | 0 |                                        cinfo->_min_DCT_scaled_size)); | 
| 273 | 0 |     if (compptr->downsampled_width < 2 && orig_downsampled_width >= 2) | 
| 274 | 0 |       reinit_upsampler = TRUE; | 
| 275 |  |  | 
| 276 |  |     /* Set the first and last iMCU columns that we must decompress.  These | 
| 277 |  |      * values will be used in multi-scan decompressions. | 
| 278 |  |      */ | 
| 279 | 0 |     cinfo->master->first_MCU_col[ci] = | 
| 280 | 0 |       (JDIMENSION)(long)(*xoffset * hsf) / (long)align; | 
| 281 | 0 |     cinfo->master->last_MCU_col[ci] = | 
| 282 | 0 |       (JDIMENSION)jdiv_round_up((long)((*xoffset + cinfo->output_width) * hsf), | 
| 283 | 0 |                                 (long)align) - 1; | 
| 284 | 0 |   } | 
| 285 |  | 
 | 
| 286 | 0 |   if (reinit_upsampler) { | 
| 287 | 0 |     cinfo->master->jinit_upsampler_no_alloc = TRUE; | 
| 288 | 0 |     _jinit_upsampler(cinfo); | 
| 289 | 0 |     cinfo->master->jinit_upsampler_no_alloc = FALSE; | 
| 290 | 0 |   } | 
| 291 | 0 | } Unexecuted instantiation: jpeg12_crop_scanlineUnexecuted instantiation: jpeg_crop_scanline | 
| 292 |  |  | 
| 293 |  | #endif /* BITS_IN_JSAMPLE != 16 */ | 
| 294 |  |  | 
| 295 |  |  | 
| 296 |  | /* | 
| 297 |  |  * Read some scanlines of data from the JPEG decompressor. | 
| 298 |  |  * | 
| 299 |  |  * The return value will be the number of lines actually read. | 
| 300 |  |  * This may be less than the number requested in several cases, | 
| 301 |  |  * including bottom of image, data source suspension, and operating | 
| 302 |  |  * modes that emit multiple scanlines at a time. | 
| 303 |  |  * | 
| 304 |  |  * Note: we warn about excess calls to _jpeg_read_scanlines() since | 
| 305 |  |  * this likely signals an application programmer error.  However, | 
| 306 |  |  * an oversize buffer (max_lines > scanlines remaining) is not an error. | 
| 307 |  |  */ | 
| 308 |  |  | 
| 309 |  | GLOBAL(JDIMENSION) | 
| 310 |  | _jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines, | 
| 311 |  |                      JDIMENSION max_lines) | 
| 312 | 0 | { | 
| 313 | 0 | #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) | 
| 314 | 0 |   JDIMENSION row_ctr; | 
| 315 |  | 
 | 
| 316 | 0 |   if (cinfo->data_precision != BITS_IN_JSAMPLE) | 
| 317 | 0 |     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 
| 318 |  | 
 | 
| 319 | 0 |   if (cinfo->global_state != DSTATE_SCANNING) | 
| 320 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 321 | 0 |   if (cinfo->output_scanline >= cinfo->output_height) { | 
| 322 | 0 |     WARNMS(cinfo, JWRN_TOO_MUCH_DATA); | 
| 323 | 0 |     return 0; | 
| 324 | 0 |   } | 
| 325 |  |  | 
| 326 |  |   /* Call progress monitor hook if present */ | 
| 327 | 0 |   if (cinfo->progress != NULL) { | 
| 328 | 0 |     cinfo->progress->pass_counter = (long)cinfo->output_scanline; | 
| 329 | 0 |     cinfo->progress->pass_limit = (long)cinfo->output_height; | 
| 330 | 0 |     (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); | 
| 331 | 0 |   } | 
| 332 |  |  | 
| 333 |  |   /* Process some data */ | 
| 334 | 0 |   row_ctr = 0; | 
| 335 | 0 |   (*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, max_lines); | 
| 336 | 0 |   cinfo->output_scanline += row_ctr; | 
| 337 | 0 |   return row_ctr; | 
| 338 |  | #else | 
| 339 |  |   ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 
| 340 |  |   return 0; | 
| 341 |  | #endif | 
| 342 | 0 | } Unexecuted instantiation: jpeg12_read_scanlinesUnexecuted instantiation: jpeg16_read_scanlinesUnexecuted instantiation: jpeg_read_scanlines | 
| 343 |  |  | 
| 344 |  |  | 
| 345 |  | #if BITS_IN_JSAMPLE != 16 | 
| 346 |  |  | 
| 347 |  | /* Dummy color convert function used by _jpeg_skip_scanlines() */ | 
| 348 |  | LOCAL(void) | 
| 349 |  | noop_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, | 
| 350 |  |              JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) | 
| 351 | 0 | { | 
| 352 | 0 | } | 
| 353 |  |  | 
| 354 |  |  | 
| 355 |  | /* Dummy quantize function used by _jpeg_skip_scanlines() */ | 
| 356 |  | LOCAL(void) | 
| 357 |  | noop_quantize(j_decompress_ptr cinfo, _JSAMPARRAY input_buf, | 
| 358 |  |               _JSAMPARRAY output_buf, int num_rows) | 
| 359 | 0 | { | 
| 360 | 0 | } | 
| 361 |  |  | 
| 362 |  |  | 
| 363 |  | /* | 
| 364 |  |  * In some cases, it is best to call _jpeg_read_scanlines() and discard the | 
| 365 |  |  * output, rather than skipping the scanlines, because this allows us to | 
| 366 |  |  * maintain the internal state of the context-based upsampler.  In these cases, | 
| 367 |  |  * we set up and tear down a dummy color converter in order to avoid valgrind | 
| 368 |  |  * errors and to achieve the best possible performance. | 
| 369 |  |  */ | 
| 370 |  |  | 
| 371 |  | LOCAL(void) | 
| 372 |  | read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | 
| 373 | 0 | { | 
| 374 | 0 |   JDIMENSION n; | 
| 375 | 0 | #ifdef UPSAMPLE_MERGING_SUPPORTED | 
| 376 | 0 |   my_master_ptr master = (my_master_ptr)cinfo->master; | 
| 377 | 0 | #endif | 
| 378 | 0 |   _JSAMPLE dummy_sample[1] = { 0 }; | 
| 379 | 0 |   _JSAMPROW dummy_row = dummy_sample; | 
| 380 | 0 |   _JSAMPARRAY scanlines = NULL; | 
| 381 | 0 |   void (*color_convert) (j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, | 
| 382 | 0 |                          JDIMENSION input_row, _JSAMPARRAY output_buf, | 
| 383 | 0 |                          int num_rows) = NULL; | 
| 384 | 0 |   void (*color_quantize) (j_decompress_ptr cinfo, _JSAMPARRAY input_buf, | 
| 385 | 0 |                           _JSAMPARRAY output_buf, int num_rows) = NULL; | 
| 386 |  | 
 | 
| 387 | 0 |   if (cinfo->cconvert && cinfo->cconvert->_color_convert) { | 
| 388 | 0 |     color_convert = cinfo->cconvert->_color_convert; | 
| 389 | 0 |     cinfo->cconvert->_color_convert = noop_convert; | 
| 390 |  |     /* This just prevents UBSan from complaining about adding 0 to a NULL | 
| 391 |  |      * pointer.  The pointer isn't actually used. | 
| 392 |  |      */ | 
| 393 | 0 |     scanlines = &dummy_row; | 
| 394 | 0 |   } | 
| 395 |  | 
 | 
| 396 | 0 |   if (cinfo->cquantize && cinfo->cquantize->_color_quantize) { | 
| 397 | 0 |     color_quantize = cinfo->cquantize->_color_quantize; | 
| 398 | 0 |     cinfo->cquantize->_color_quantize = noop_quantize; | 
| 399 | 0 |   } | 
| 400 |  | 
 | 
| 401 | 0 | #ifdef UPSAMPLE_MERGING_SUPPORTED | 
| 402 | 0 |   if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) { | 
| 403 | 0 |     my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample; | 
| 404 | 0 |     scanlines = &upsample->spare_row; | 
| 405 | 0 |   } | 
| 406 | 0 | #endif | 
| 407 |  | 
 | 
| 408 | 0 |   for (n = 0; n < num_lines; n++) | 
| 409 | 0 |     _jpeg_read_scanlines(cinfo, scanlines, 1); | 
| 410 |  | 
 | 
| 411 | 0 |   if (color_convert) | 
| 412 | 0 |     cinfo->cconvert->_color_convert = color_convert; | 
| 413 |  | 
 | 
| 414 | 0 |   if (color_quantize) | 
| 415 | 0 |     cinfo->cquantize->_color_quantize = color_quantize; | 
| 416 | 0 | } | 
| 417 |  |  | 
| 418 |  |  | 
| 419 |  | /* | 
| 420 |  |  * Called by _jpeg_skip_scanlines().  This partially skips a decompress block | 
| 421 |  |  * by incrementing the rowgroup counter. | 
| 422 |  |  */ | 
| 423 |  |  | 
| 424 |  | LOCAL(void) | 
| 425 |  | increment_simple_rowgroup_ctr(j_decompress_ptr cinfo, JDIMENSION rows) | 
| 426 | 0 | { | 
| 427 | 0 |   JDIMENSION rows_left; | 
| 428 | 0 |   my_main_ptr main_ptr = (my_main_ptr)cinfo->main; | 
| 429 | 0 |   my_master_ptr master = (my_master_ptr)cinfo->master; | 
| 430 |  | 
 | 
| 431 | 0 |   if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) { | 
| 432 | 0 |     read_and_discard_scanlines(cinfo, rows); | 
| 433 | 0 |     return; | 
| 434 | 0 |   } | 
| 435 |  |  | 
| 436 |  |   /* Increment the counter to the next row group after the skipped rows. */ | 
| 437 | 0 |   main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor; | 
| 438 |  |  | 
| 439 |  |   /* Partially skipping a row group would involve modifying the internal state | 
| 440 |  |    * of the upsampler, so read the remaining rows into a dummy buffer instead. | 
| 441 |  |    */ | 
| 442 | 0 |   rows_left = rows % cinfo->max_v_samp_factor; | 
| 443 | 0 |   cinfo->output_scanline += rows - rows_left; | 
| 444 |  | 
 | 
| 445 | 0 |   read_and_discard_scanlines(cinfo, rows_left); | 
| 446 | 0 | } | 
| 447 |  |  | 
| 448 |  | /* | 
| 449 |  |  * Skips some scanlines of data from the JPEG decompressor. | 
| 450 |  |  * | 
| 451 |  |  * The return value will be the number of lines actually skipped.  If skipping | 
| 452 |  |  * num_lines would move beyond the end of the image, then the actual number of | 
| 453 |  |  * lines remaining in the image is returned.  Otherwise, the return value will | 
| 454 |  |  * be equal to num_lines. | 
| 455 |  |  * | 
| 456 |  |  * Refer to libjpeg.txt for more information. | 
| 457 |  |  */ | 
| 458 |  |  | 
| 459 |  | GLOBAL(JDIMENSION) | 
| 460 |  | _jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) | 
| 461 | 0 | { | 
| 462 | 0 |   my_main_ptr main_ptr = (my_main_ptr)cinfo->main; | 
| 463 | 0 |   my_coef_ptr coef = (my_coef_ptr)cinfo->coef; | 
| 464 | 0 |   my_master_ptr master = (my_master_ptr)cinfo->master; | 
| 465 | 0 |   my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample; | 
| 466 | 0 |   JDIMENSION i, x; | 
| 467 | 0 |   int y; | 
| 468 | 0 |   JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row; | 
| 469 | 0 |   JDIMENSION lines_to_skip, lines_to_read; | 
| 470 |  | 
 | 
| 471 | 0 |   if (cinfo->data_precision != BITS_IN_JSAMPLE) | 
| 472 | 0 |     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 
| 473 |  | 
 | 
| 474 | 0 |   if (cinfo->master->lossless) | 
| 475 | 0 |     ERREXIT(cinfo, JERR_NOTIMPL); | 
| 476 |  |  | 
| 477 |  |   /* Two-pass color quantization is not supported. */ | 
| 478 | 0 |   if (cinfo->quantize_colors && cinfo->two_pass_quantize) | 
| 479 | 0 |     ERREXIT(cinfo, JERR_NOTIMPL); | 
| 480 |  | 
 | 
| 481 | 0 |   if (cinfo->global_state != DSTATE_SCANNING) | 
| 482 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 483 |  |  | 
| 484 |  |   /* Do not skip past the bottom of the image. */ | 
| 485 | 0 |   if (cinfo->output_scanline + num_lines >= cinfo->output_height) { | 
| 486 | 0 |     num_lines = cinfo->output_height - cinfo->output_scanline; | 
| 487 | 0 |     cinfo->output_scanline = cinfo->output_height; | 
| 488 | 0 |     (*cinfo->inputctl->finish_input_pass) (cinfo); | 
| 489 | 0 |     cinfo->inputctl->eoi_reached = TRUE; | 
| 490 | 0 |     return num_lines; | 
| 491 | 0 |   } | 
| 492 |  |  | 
| 493 | 0 |   if (num_lines == 0) | 
| 494 | 0 |     return 0; | 
| 495 |  |  | 
| 496 | 0 |   lines_per_iMCU_row = cinfo->_min_DCT_scaled_size * cinfo->max_v_samp_factor; | 
| 497 | 0 |   lines_left_in_iMCU_row = | 
| 498 | 0 |     (lines_per_iMCU_row - (cinfo->output_scanline % lines_per_iMCU_row)) % | 
| 499 | 0 |     lines_per_iMCU_row; | 
| 500 | 0 |   lines_after_iMCU_row = num_lines - lines_left_in_iMCU_row; | 
| 501 |  |  | 
| 502 |  |   /* Skip the lines remaining in the current iMCU row.  When upsampling | 
| 503 |  |    * requires context rows, we need the previous and next rows in order to read | 
| 504 |  |    * the current row.  This adds some complexity. | 
| 505 |  |    */ | 
| 506 | 0 |   if (cinfo->upsample->need_context_rows) { | 
| 507 |  |     /* If the skipped lines would not move us past the current iMCU row, we | 
| 508 |  |      * read the lines and ignore them.  There might be a faster way of doing | 
| 509 |  |      * this, but we are facing increasing complexity for diminishing returns. | 
| 510 |  |      * The increasing complexity would be a by-product of meddling with the | 
| 511 |  |      * state machine used to skip context rows.  Near the end of an iMCU row, | 
| 512 |  |      * the next iMCU row may have already been entropy-decoded.  In this unique | 
| 513 |  |      * case, we will read the next iMCU row if we cannot skip past it as well. | 
| 514 |  |      */ | 
| 515 | 0 |     if ((num_lines < lines_left_in_iMCU_row + 1) || | 
| 516 | 0 |         (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full && | 
| 517 | 0 |          lines_after_iMCU_row < lines_per_iMCU_row + 1)) { | 
| 518 | 0 |       read_and_discard_scanlines(cinfo, num_lines); | 
| 519 | 0 |       return num_lines; | 
| 520 | 0 |     } | 
| 521 |  |  | 
| 522 |  |     /* If the next iMCU row has already been entropy-decoded, make sure that | 
| 523 |  |      * we do not skip too far. | 
| 524 |  |      */ | 
| 525 | 0 |     if (lines_left_in_iMCU_row <= 1 && main_ptr->buffer_full) { | 
| 526 | 0 |       cinfo->output_scanline += lines_left_in_iMCU_row + lines_per_iMCU_row; | 
| 527 | 0 |       lines_after_iMCU_row -= lines_per_iMCU_row; | 
| 528 | 0 |     } else { | 
| 529 | 0 |       cinfo->output_scanline += lines_left_in_iMCU_row; | 
| 530 | 0 |     } | 
| 531 |  |  | 
| 532 |  |     /* If we have just completed the first block, adjust the buffer pointers */ | 
| 533 | 0 |     if (main_ptr->iMCU_row_ctr == 0 || | 
| 534 | 0 |         (main_ptr->iMCU_row_ctr == 1 && lines_left_in_iMCU_row > 2)) | 
| 535 | 0 |       set_wraparound_pointers(cinfo); | 
| 536 | 0 |     main_ptr->buffer_full = FALSE; | 
| 537 | 0 |     main_ptr->rowgroup_ctr = 0; | 
| 538 | 0 |     main_ptr->context_state = CTX_PREPARE_FOR_IMCU; | 
| 539 | 0 |     if (!master->using_merged_upsample) { | 
| 540 | 0 |       upsample->next_row_out = cinfo->max_v_samp_factor; | 
| 541 | 0 |       upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | 
| 542 | 0 |     } | 
| 543 | 0 |   } | 
| 544 |  |  | 
| 545 |  |   /* Skipping is much simpler when context rows are not required. */ | 
| 546 | 0 |   else { | 
| 547 | 0 |     if (num_lines < lines_left_in_iMCU_row) { | 
| 548 | 0 |       increment_simple_rowgroup_ctr(cinfo, num_lines); | 
| 549 | 0 |       return num_lines; | 
| 550 | 0 |     } else { | 
| 551 | 0 |       cinfo->output_scanline += lines_left_in_iMCU_row; | 
| 552 | 0 |       main_ptr->buffer_full = FALSE; | 
| 553 | 0 |       main_ptr->rowgroup_ctr = 0; | 
| 554 | 0 |       if (!master->using_merged_upsample) { | 
| 555 | 0 |         upsample->next_row_out = cinfo->max_v_samp_factor; | 
| 556 | 0 |         upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | 
| 557 | 0 |       } | 
| 558 | 0 |     } | 
| 559 | 0 |   } | 
| 560 |  |  | 
| 561 |  |   /* Calculate how many full iMCU rows we can skip. */ | 
| 562 | 0 |   if (cinfo->upsample->need_context_rows) | 
| 563 | 0 |     lines_to_skip = ((lines_after_iMCU_row - 1) / lines_per_iMCU_row) * | 
| 564 | 0 |                     lines_per_iMCU_row; | 
| 565 | 0 |   else | 
| 566 | 0 |     lines_to_skip = (lines_after_iMCU_row / lines_per_iMCU_row) * | 
| 567 | 0 |                     lines_per_iMCU_row; | 
| 568 |  |   /* Calculate the number of lines that remain to be skipped after skipping all | 
| 569 |  |    * of the full iMCU rows that we can.  We will not read these lines unless we | 
| 570 |  |    * have to. | 
| 571 |  |    */ | 
| 572 | 0 |   lines_to_read = lines_after_iMCU_row - lines_to_skip; | 
| 573 |  |  | 
| 574 |  |   /* For images requiring multiple scans (progressive, non-interleaved, etc.), | 
| 575 |  |    * all of the entropy decoding occurs in jpeg_start_decompress(), assuming | 
| 576 |  |    * that the input data source is non-suspending.  This makes skipping easy. | 
| 577 |  |    */ | 
| 578 | 0 |   if (cinfo->inputctl->has_multiple_scans || cinfo->buffered_image) { | 
| 579 | 0 |     if (cinfo->upsample->need_context_rows) { | 
| 580 | 0 |       cinfo->output_scanline += lines_to_skip; | 
| 581 | 0 |       cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row; | 
| 582 | 0 |       main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row; | 
| 583 |  |       /* It is complex to properly move to the middle of a context block, so | 
| 584 |  |        * read the remaining lines instead of skipping them. | 
| 585 |  |        */ | 
| 586 | 0 |       read_and_discard_scanlines(cinfo, lines_to_read); | 
| 587 | 0 |     } else { | 
| 588 | 0 |       cinfo->output_scanline += lines_to_skip; | 
| 589 | 0 |       cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row; | 
| 590 | 0 |       increment_simple_rowgroup_ctr(cinfo, lines_to_read); | 
| 591 | 0 |     } | 
| 592 | 0 |     if (!master->using_merged_upsample) | 
| 593 | 0 |       upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | 
| 594 | 0 |     return num_lines; | 
| 595 | 0 |   } | 
| 596 |  |  | 
| 597 |  |   /* Skip the iMCU rows that we can safely skip. */ | 
| 598 | 0 |   for (i = 0; i < lines_to_skip; i += lines_per_iMCU_row) { | 
| 599 | 0 |     for (y = 0; y < coef->MCU_rows_per_iMCU_row; y++) { | 
| 600 | 0 |       for (x = 0; x < cinfo->MCUs_per_row; x++) { | 
| 601 |  |         /* Calling decode_mcu() with a NULL pointer causes it to discard the | 
| 602 |  |          * decoded coefficients.  This is ~5% faster for large subsets, but | 
| 603 |  |          * it's tough to tell a difference for smaller images. | 
| 604 |  |          */ | 
| 605 | 0 |         if (!cinfo->entropy->insufficient_data) | 
| 606 | 0 |           cinfo->master->last_good_iMCU_row = cinfo->input_iMCU_row; | 
| 607 | 0 |         (*cinfo->entropy->decode_mcu) (cinfo, NULL); | 
| 608 | 0 |       } | 
| 609 | 0 |     } | 
| 610 | 0 |     cinfo->input_iMCU_row++; | 
| 611 | 0 |     cinfo->output_iMCU_row++; | 
| 612 | 0 |     if (cinfo->input_iMCU_row < cinfo->total_iMCU_rows) | 
| 613 | 0 |       start_iMCU_row(cinfo); | 
| 614 | 0 |     else | 
| 615 | 0 |       (*cinfo->inputctl->finish_input_pass) (cinfo); | 
| 616 | 0 |   } | 
| 617 | 0 |   cinfo->output_scanline += lines_to_skip; | 
| 618 |  | 
 | 
| 619 | 0 |   if (cinfo->upsample->need_context_rows) { | 
| 620 |  |     /* Context-based upsampling keeps track of iMCU rows. */ | 
| 621 | 0 |     main_ptr->iMCU_row_ctr += lines_to_skip / lines_per_iMCU_row; | 
| 622 |  |  | 
| 623 |  |     /* It is complex to properly move to the middle of a context block, so | 
| 624 |  |      * read the remaining lines instead of skipping them. | 
| 625 |  |      */ | 
| 626 | 0 |     read_and_discard_scanlines(cinfo, lines_to_read); | 
| 627 | 0 |   } else { | 
| 628 | 0 |     increment_simple_rowgroup_ctr(cinfo, lines_to_read); | 
| 629 | 0 |   } | 
| 630 |  |  | 
| 631 |  |   /* Since skipping lines involves skipping the upsampling step, the value of | 
| 632 |  |    * "rows_to_go" will become invalid unless we set it here.  NOTE: This is a | 
| 633 |  |    * bit odd, since "rows_to_go" seems to be redundantly keeping track of | 
| 634 |  |    * output_scanline. | 
| 635 |  |    */ | 
| 636 | 0 |   if (!master->using_merged_upsample) | 
| 637 | 0 |     upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline; | 
| 638 |  |  | 
| 639 |  |   /* Always skip the requested number of lines. */ | 
| 640 | 0 |   return num_lines; | 
| 641 | 0 | } Unexecuted instantiation: jpeg12_skip_scanlinesUnexecuted instantiation: jpeg_skip_scanlines | 
| 642 |  |  | 
| 643 |  | /* | 
| 644 |  |  * Alternate entry point to read raw data. | 
| 645 |  |  * Processes exactly one iMCU row per call, unless suspended. | 
| 646 |  |  */ | 
| 647 |  |  | 
| 648 |  | GLOBAL(JDIMENSION) | 
| 649 |  | _jpeg_read_raw_data(j_decompress_ptr cinfo, _JSAMPIMAGE data, | 
| 650 |  |                     JDIMENSION max_lines) | 
| 651 | 1.10M | { | 
| 652 | 1.10M |   JDIMENSION lines_per_iMCU_row; | 
| 653 |  |  | 
| 654 | 1.10M |   if (cinfo->data_precision != BITS_IN_JSAMPLE) | 
| 655 | 831 |     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); | 
| 656 |  |  | 
| 657 | 1.10M |   if (cinfo->master->lossless) | 
| 658 | 291 |     ERREXIT(cinfo, JERR_NOTIMPL); | 
| 659 |  |  | 
| 660 | 1.10M |   if (cinfo->global_state != DSTATE_RAW_OK) | 
| 661 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 662 | 1.10M |   if (cinfo->output_scanline >= cinfo->output_height) { | 
| 663 | 0 |     WARNMS(cinfo, JWRN_TOO_MUCH_DATA); | 
| 664 | 0 |     return 0; | 
| 665 | 0 |   } | 
| 666 |  |  | 
| 667 |  |   /* Call progress monitor hook if present */ | 
| 668 | 1.10M |   if (cinfo->progress != NULL) { | 
| 669 | 1.10M |     cinfo->progress->pass_counter = (long)cinfo->output_scanline; | 
| 670 | 1.10M |     cinfo->progress->pass_limit = (long)cinfo->output_height; | 
| 671 | 1.10M |     (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); | 
| 672 | 1.10M |   } | 
| 673 |  |  | 
| 674 |  |   /* Verify that at least one iMCU row can be returned. */ | 
| 675 | 1.10M |   lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size; | 
| 676 | 1.10M |   if (max_lines < lines_per_iMCU_row) | 
| 677 | 0 |     ERREXIT(cinfo, JERR_BUFFER_SIZE); | 
| 678 |  |  | 
| 679 |  |   /* Decompress directly into user's buffer. */ | 
| 680 | 1.10M |   if (!(*cinfo->coef->_decompress_data) (cinfo, data)) | 
| 681 | 0 |     return 0;                   /* suspension forced, can do nothing more */ | 
| 682 |  |  | 
| 683 |  |   /* OK, we processed one iMCU row. */ | 
| 684 | 1.10M |   cinfo->output_scanline += lines_per_iMCU_row; | 
| 685 | 1.10M |   return lines_per_iMCU_row; | 
| 686 | 1.10M | } Unexecuted instantiation: jpeg12_read_raw_data| Line | Count | Source |  | 651 | 1.10M | { |  | 652 | 1.10M |   JDIMENSION lines_per_iMCU_row; |  | 653 |  |  |  | 654 | 1.10M |   if (cinfo->data_precision != BITS_IN_JSAMPLE) |  | 655 | 831 |     ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); |  | 656 |  |  |  | 657 | 1.10M |   if (cinfo->master->lossless) |  | 658 | 291 |     ERREXIT(cinfo, JERR_NOTIMPL); |  | 659 |  |  |  | 660 | 1.10M |   if (cinfo->global_state != DSTATE_RAW_OK) |  | 661 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); |  | 662 | 1.10M |   if (cinfo->output_scanline >= cinfo->output_height) { |  | 663 | 0 |     WARNMS(cinfo, JWRN_TOO_MUCH_DATA); |  | 664 | 0 |     return 0; |  | 665 | 0 |   } |  | 666 |  |  |  | 667 |  |   /* Call progress monitor hook if present */ |  | 668 | 1.10M |   if (cinfo->progress != NULL) { |  | 669 | 1.10M |     cinfo->progress->pass_counter = (long)cinfo->output_scanline; |  | 670 | 1.10M |     cinfo->progress->pass_limit = (long)cinfo->output_height; |  | 671 | 1.10M |     (*cinfo->progress->progress_monitor) ((j_common_ptr)cinfo); |  | 672 | 1.10M |   } |  | 673 |  |  |  | 674 |  |   /* Verify that at least one iMCU row can be returned. */ |  | 675 | 1.10M |   lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->_min_DCT_scaled_size; |  | 676 | 1.10M |   if (max_lines < lines_per_iMCU_row) |  | 677 | 0 |     ERREXIT(cinfo, JERR_BUFFER_SIZE); |  | 678 |  |  |  | 679 |  |   /* Decompress directly into user's buffer. */ |  | 680 | 1.10M |   if (!(*cinfo->coef->_decompress_data) (cinfo, data)) |  | 681 | 0 |     return 0;                   /* suspension forced, can do nothing more */ |  | 682 |  |  |  | 683 |  |   /* OK, we processed one iMCU row. */ |  | 684 | 1.10M |   cinfo->output_scanline += lines_per_iMCU_row; |  | 685 | 1.10M |   return lines_per_iMCU_row; |  | 686 | 1.10M | } | 
 | 
| 687 |  |  | 
| 688 |  | #endif /* BITS_IN_JSAMPLE != 16 */ | 
| 689 |  |  | 
| 690 |  |  | 
| 691 |  | #if BITS_IN_JSAMPLE == 8 | 
| 692 |  |  | 
| 693 |  | /* Additional entry points for buffered-image mode. */ | 
| 694 |  |  | 
| 695 |  | #ifdef D_MULTISCAN_FILES_SUPPORTED | 
| 696 |  |  | 
| 697 |  | /* | 
| 698 |  |  * Initialize for an output pass in buffered-image mode. | 
| 699 |  |  */ | 
| 700 |  |  | 
| 701 |  | GLOBAL(boolean) | 
| 702 |  | jpeg_start_output(j_decompress_ptr cinfo, int scan_number) | 
| 703 | 0 | { | 
| 704 | 0 |   if (cinfo->global_state != DSTATE_BUFIMAGE && | 
| 705 | 0 |       cinfo->global_state != DSTATE_PRESCAN) | 
| 706 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 707 |  |   /* Limit scan number to valid range */ | 
| 708 | 0 |   if (scan_number <= 0) | 
| 709 | 0 |     scan_number = 1; | 
| 710 | 0 |   if (cinfo->inputctl->eoi_reached && scan_number > cinfo->input_scan_number) | 
| 711 | 0 |     scan_number = cinfo->input_scan_number; | 
| 712 | 0 |   cinfo->output_scan_number = scan_number; | 
| 713 |  |   /* Perform any dummy output passes, and set up for the real pass */ | 
| 714 | 0 |   return output_pass_setup(cinfo); | 
| 715 | 0 | } | 
| 716 |  |  | 
| 717 |  |  | 
| 718 |  | /* | 
| 719 |  |  * Finish up after an output pass in buffered-image mode. | 
| 720 |  |  * | 
| 721 |  |  * Returns FALSE if suspended.  The return value need be inspected only if | 
| 722 |  |  * a suspending data source is used. | 
| 723 |  |  */ | 
| 724 |  |  | 
| 725 |  | GLOBAL(boolean) | 
| 726 |  | jpeg_finish_output(j_decompress_ptr cinfo) | 
| 727 | 0 | { | 
| 728 | 0 |   if ((cinfo->global_state == DSTATE_SCANNING || | 
| 729 | 0 |        cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { | 
| 730 |  |     /* Terminate this pass. */ | 
| 731 |  |     /* We do not require the whole pass to have been completed. */ | 
| 732 | 0 |     (*cinfo->master->finish_output_pass) (cinfo); | 
| 733 | 0 |     cinfo->global_state = DSTATE_BUFPOST; | 
| 734 | 0 |   } else if (cinfo->global_state != DSTATE_BUFPOST) { | 
| 735 |  |     /* BUFPOST = repeat call after a suspension, anything else is error */ | 
| 736 | 0 |     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); | 
| 737 | 0 |   } | 
| 738 |  |   /* Read markers looking for SOS or EOI */ | 
| 739 | 0 |   while (cinfo->input_scan_number <= cinfo->output_scan_number && | 
| 740 | 0 |          !cinfo->inputctl->eoi_reached) { | 
| 741 | 0 |     if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) | 
| 742 | 0 |       return FALSE;             /* Suspend, come back later */ | 
| 743 | 0 |   } | 
| 744 | 0 |   cinfo->global_state = DSTATE_BUFIMAGE; | 
| 745 | 0 |   return TRUE; | 
| 746 | 0 | } | 
| 747 |  |  | 
| 748 |  | #endif /* D_MULTISCAN_FILES_SUPPORTED */ | 
| 749 |  |  | 
| 750 |  | #endif /* BITS_IN_JSAMPLE == 8 */ |