4  * Copyright (C) 1994-1996, 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. 
   8  * This file contains application interface code for the decompression half 
   9  * of the JPEG library.  These are the "standard" API routines that are 
  10  * used in the normal full-decompression case.  They are not used by a 
  11  * transcoding-only application.  Note that if an application links in 
  12  * jpeg_start_decompress, it will end up linking in the entire decompressor. 
  13  * We thus must separate this file from jdapimin.c to avoid linking the 
  14  * whole decompression library into a transcoder. 
  17 #define JPEG_INTERNALS 
  22 /* Forward declarations */ 
  23 LOCAL(wxjpeg_boolean
) output_pass_setup 
JPP((j_decompress_ptr cinfo
)); 
  27  * Decompression initialization. 
  28  * jpeg_read_header must be completed before calling this. 
  30  * If a multipass operating mode was selected, this will do all but the 
  31  * last pass, and thus may take a great deal of time. 
  33  * Returns FALSE if suspended.  The return value need be inspected only if 
  34  * a suspending data source is used. 
  37 GLOBAL(wxjpeg_boolean
) 
  38 jpeg_start_decompress (j_decompress_ptr cinfo
) 
  40   if (cinfo
->global_state 
== DSTATE_READY
) { 
  41     /* First call: initialize master control, select active modules */ 
  42     jinit_master_decompress(cinfo
); 
  43     if (cinfo
->buffered_image
) { 
  44       /* No more work here; expecting jpeg_start_output next */ 
  45       cinfo
->global_state 
= DSTATE_BUFIMAGE
; 
  48     cinfo
->global_state 
= DSTATE_PRELOAD
; 
  50   if (cinfo
->global_state 
== DSTATE_PRELOAD
) { 
  51     /* If file has multiple scans, absorb them all into the coef buffer */ 
  52     if (cinfo
->inputctl
->has_multiple_scans
) { 
  53 #ifdef D_MULTISCAN_FILES_SUPPORTED 
  56         /* Call progress monitor hook if present */ 
  57         if (cinfo
->progress 
!= NULL
) 
  58           (*cinfo
->progress
->progress_monitor
) ((j_common_ptr
) cinfo
); 
  59         /* Absorb some more input */ 
  60         retcode 
= (*cinfo
->inputctl
->consume_input
) (cinfo
); 
  61         if (retcode 
== JPEG_SUSPENDED
) 
  63         if (retcode 
== JPEG_REACHED_EOI
) 
  65         /* Advance progress counter if appropriate */ 
  66         if (cinfo
->progress 
!= NULL 
&& 
  67             (retcode 
== JPEG_ROW_COMPLETED 
|| retcode 
== JPEG_REACHED_SOS
)) { 
  68           if (++cinfo
->progress
->pass_counter 
>= cinfo
->progress
->pass_limit
) { 
  69             /* jdmaster underestimated number of scans; ratchet up one scan */ 
  70             cinfo
->progress
->pass_limit 
+= (long) cinfo
->total_iMCU_rows
; 
  75       ERREXIT(cinfo
, JERR_NOT_COMPILED
); 
  76 #endif /* D_MULTISCAN_FILES_SUPPORTED */ 
  78     cinfo
->output_scan_number 
= cinfo
->input_scan_number
; 
  79   } else if (cinfo
->global_state 
!= DSTATE_PRESCAN
) 
  80     ERREXIT1(cinfo
, JERR_BAD_STATE
, cinfo
->global_state
); 
  81   /* Perform any dummy output passes, and set up for the final pass */ 
  82   return output_pass_setup(cinfo
); 
  87  * Set up for an output pass, and perform any dummy pass(es) needed. 
  88  * Common subroutine for jpeg_start_decompress and jpeg_start_output. 
  89  * Entry: global_state = DSTATE_PRESCAN only if previously suspended. 
  90  * Exit: If done, returns TRUE and sets global_state for proper output mode. 
  91  *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. 
  95 output_pass_setup (j_decompress_ptr cinfo
) 
  97   if (cinfo
->global_state 
!= DSTATE_PRESCAN
) { 
  98     /* First call: do pass setup */ 
  99     (*cinfo
->master
->prepare_for_output_pass
) (cinfo
); 
 100     cinfo
->output_scanline 
= 0; 
 101     cinfo
->global_state 
= DSTATE_PRESCAN
; 
 103   /* Loop over any required dummy passes */ 
 104   while (cinfo
->master
->is_dummy_pass
) { 
 105 #ifdef QUANT_2PASS_SUPPORTED 
 106     /* Crank through the dummy pass */ 
 107     while (cinfo
->output_scanline 
< cinfo
->output_height
) { 
 108       JDIMENSION last_scanline
; 
 109       /* Call progress monitor hook if present */ 
 110       if (cinfo
->progress 
!= NULL
) { 
 111         cinfo
->progress
->pass_counter 
= (long) cinfo
->output_scanline
; 
 112         cinfo
->progress
->pass_limit 
= (long) cinfo
->output_height
; 
 113         (*cinfo
->progress
->progress_monitor
) ((j_common_ptr
) cinfo
); 
 115       /* Process some data */ 
 116       last_scanline 
= cinfo
->output_scanline
; 
 117       (*cinfo
->main
->process_data
) (cinfo
, (JSAMPARRAY
) NULL
, 
 118                                     &cinfo
->output_scanline
, (JDIMENSION
) 0); 
 119       if (cinfo
->output_scanline 
== last_scanline
) 
 120         return FALSE
;           /* No progress made, must suspend */ 
 122     /* Finish up dummy pass, and set up for another one */ 
 123     (*cinfo
->master
->finish_output_pass
) (cinfo
); 
 124     (*cinfo
->master
->prepare_for_output_pass
) (cinfo
); 
 125     cinfo
->output_scanline 
= 0; 
 127     ERREXIT(cinfo
, JERR_NOT_COMPILED
); 
 128 #endif /* QUANT_2PASS_SUPPORTED */ 
 130   /* Ready for application to drive output pass through 
 131    * jpeg_read_scanlines or jpeg_read_raw_data. 
 133   cinfo
->global_state 
= cinfo
->raw_data_out 
? DSTATE_RAW_OK 
: DSTATE_SCANNING
; 
 139  * Read some scanlines of data from the JPEG decompressor. 
 141  * The return value will be the number of lines actually read. 
 142  * This may be less than the number requested in several cases, 
 143  * including bottom of image, data source suspension, and operating 
 144  * modes that emit multiple scanlines at a time. 
 146  * Note: we warn about excess calls to jpeg_read_scanlines() since 
 147  * this likely signals an application programmer error.  However, 
 148  * an oversize buffer (max_lines > scanlines remaining) is not an error. 
 152 jpeg_read_scanlines (j_decompress_ptr cinfo
, JSAMPARRAY scanlines
, 
 153                      JDIMENSION max_lines
) 
 157   if (cinfo
->global_state 
!= DSTATE_SCANNING
) 
 158     ERREXIT1(cinfo
, JERR_BAD_STATE
, cinfo
->global_state
); 
 159   if (cinfo
->output_scanline 
>= cinfo
->output_height
) { 
 160     WARNMS(cinfo
, JWRN_TOO_MUCH_DATA
); 
 164   /* Call progress monitor hook if present */ 
 165   if (cinfo
->progress 
!= NULL
) { 
 166     cinfo
->progress
->pass_counter 
= (long) cinfo
->output_scanline
; 
 167     cinfo
->progress
->pass_limit 
= (long) cinfo
->output_height
; 
 168     (*cinfo
->progress
->progress_monitor
) ((j_common_ptr
) cinfo
); 
 171   /* Process some data */ 
 173   (*cinfo
->main
->process_data
) (cinfo
, scanlines
, &row_ctr
, max_lines
); 
 174   cinfo
->output_scanline 
+= row_ctr
; 
 180  * Alternate entry point to read raw data. 
 181  * Processes exactly one iMCU row per call, unless suspended. 
 185 jpeg_read_raw_data (j_decompress_ptr cinfo
, JSAMPIMAGE data
, 
 186                     JDIMENSION max_lines
) 
 188   JDIMENSION lines_per_iMCU_row
; 
 190   if (cinfo
->global_state 
!= DSTATE_RAW_OK
) 
 191     ERREXIT1(cinfo
, JERR_BAD_STATE
, cinfo
->global_state
); 
 192   if (cinfo
->output_scanline 
>= cinfo
->output_height
) { 
 193     WARNMS(cinfo
, JWRN_TOO_MUCH_DATA
); 
 197   /* Call progress monitor hook if present */ 
 198   if (cinfo
->progress 
!= NULL
) { 
 199     cinfo
->progress
->pass_counter 
= (long) cinfo
->output_scanline
; 
 200     cinfo
->progress
->pass_limit 
= (long) cinfo
->output_height
; 
 201     (*cinfo
->progress
->progress_monitor
) ((j_common_ptr
) cinfo
); 
 204   /* Verify that at least one iMCU row can be returned. */ 
 205   lines_per_iMCU_row 
= cinfo
->max_v_samp_factor 
* cinfo
->min_DCT_scaled_size
; 
 206   if (max_lines 
< lines_per_iMCU_row
) 
 207     ERREXIT(cinfo
, JERR_BUFFER_SIZE
); 
 209   /* Decompress directly into user's buffer. */ 
 210   if (! (*cinfo
->coef
->decompress_data
) (cinfo
, data
)) 
 211     return 0;                   /* suspension forced, can do nothing more */ 
 213   /* OK, we processed one iMCU row. */ 
 214   cinfo
->output_scanline 
+= lines_per_iMCU_row
; 
 215   return lines_per_iMCU_row
; 
 219 /* Additional entry points for buffered-image mode. */ 
 221 #ifdef D_MULTISCAN_FILES_SUPPORTED 
 224  * Initialize for an output pass in buffered-image mode. 
 227 GLOBAL(wxjpeg_boolean
) 
 228 jpeg_start_output (j_decompress_ptr cinfo
, int scan_number
) 
 230   if (cinfo
->global_state 
!= DSTATE_BUFIMAGE 
&& 
 231       cinfo
->global_state 
!= DSTATE_PRESCAN
) 
 232     ERREXIT1(cinfo
, JERR_BAD_STATE
, cinfo
->global_state
); 
 233   /* Limit scan number to valid range */ 
 234   if (scan_number 
<= 0) 
 236   if (cinfo
->inputctl
->eoi_reached 
&& 
 237       scan_number 
> cinfo
->input_scan_number
) 
 238     scan_number 
= cinfo
->input_scan_number
; 
 239   cinfo
->output_scan_number 
= scan_number
; 
 240   /* Perform any dummy output passes, and set up for the real pass */ 
 241   return output_pass_setup(cinfo
); 
 246  * Finish up after an output pass in buffered-image mode. 
 248  * Returns FALSE if suspended.  The return value need be inspected only if 
 249  * a suspending data source is used. 
 252 GLOBAL(wxjpeg_boolean
) 
 253 jpeg_finish_output (j_decompress_ptr cinfo
) 
 255   if ((cinfo
->global_state 
== DSTATE_SCANNING 
|| 
 256        cinfo
->global_state 
== DSTATE_RAW_OK
) && cinfo
->buffered_image
) { 
 257     /* Terminate this pass. */ 
 258     /* We do not require the whole pass to have been completed. */ 
 259     (*cinfo
->master
->finish_output_pass
) (cinfo
); 
 260     cinfo
->global_state 
= DSTATE_BUFPOST
; 
 261   } else if (cinfo
->global_state 
!= DSTATE_BUFPOST
) { 
 262     /* BUFPOST = repeat call after a suspension, anything else is error */ 
 263     ERREXIT1(cinfo
, JERR_BAD_STATE
, cinfo
->global_state
); 
 265   /* Read markers looking for SOS or EOI */ 
 266   while (cinfo
->input_scan_number 
<= cinfo
->output_scan_number 
&& 
 267          ! cinfo
->inputctl
->eoi_reached
) { 
 268     if ((*cinfo
->inputctl
->consume_input
) (cinfo
) == JPEG_SUSPENDED
) 
 269       return FALSE
;             /* Suspend, come back later */ 
 271   cinfo
->global_state 
= DSTATE_BUFIMAGE
; 
 275 #endif /* D_MULTISCAN_FILES_SUPPORTED */