jdapistd.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jdapistd.c (9348B)
       ---
            1 /*
            2  * jdapistd.c
            3  *
            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.
            7  *
            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.
           15  */
           16 
           17 #define JPEG_INTERNALS
           18 #include "jinclude.h"
           19 #include "jpeglib.h"
           20 
           21 
           22 /* Forward declarations */
           23 LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
           24 
           25 
           26 /*
           27  * Decompression initialization.
           28  * jpeg_read_header must be completed before calling this.
           29  *
           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.
           32  *
           33  * Returns FALSE if suspended.  The return value need be inspected only if
           34  * a suspending data source is used.
           35  */
           36 
           37 GLOBAL(boolean)
           38 jpeg_start_decompress (j_decompress_ptr cinfo)
           39 {
           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;
           46       return TRUE;
           47     }
           48     cinfo->global_state = DSTATE_PRELOAD;
           49   }
           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
           54       for (;;) {
           55         int retcode;
           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)
           62           return FALSE;
           63         if (retcode == JPEG_REACHED_EOI)
           64           break;
           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;
           71           }
           72         }
           73       }
           74 #else
           75       ERREXIT(cinfo, JERR_NOT_COMPILED);
           76 #endif /* D_MULTISCAN_FILES_SUPPORTED */
           77     }
           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);
           83 }
           84 
           85 
           86 /*
           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.
           92  */
           93 
           94 LOCAL(boolean)
           95 output_pass_setup (j_decompress_ptr cinfo)
           96 {
           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;
          102   }
          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);
          114       }
          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 */
          121     }
          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;
          126 #else
          127     ERREXIT(cinfo, JERR_NOT_COMPILED);
          128 #endif /* QUANT_2PASS_SUPPORTED */
          129   }
          130   /* Ready for application to drive output pass through
          131    * jpeg_read_scanlines or jpeg_read_raw_data.
          132    */
          133   cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
          134   return TRUE;
          135 }
          136 
          137 
          138 /*
          139  * Read some scanlines of data from the JPEG decompressor.
          140  *
          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.
          145  *
          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.
          149  */
          150 
          151 GLOBAL(JDIMENSION)
          152 jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
          153                      JDIMENSION max_lines)
          154 {
          155   JDIMENSION row_ctr;
          156 
          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);
          161     return 0;
          162   }
          163 
          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);
          169   }
          170 
          171   /* Process some data */
          172   row_ctr = 0;
          173   (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
          174   cinfo->output_scanline += row_ctr;
          175   return row_ctr;
          176 }
          177 
          178 
          179 /*
          180  * Alternate entry point to read raw data.
          181  * Processes exactly one iMCU row per call, unless suspended.
          182  */
          183 
          184 GLOBAL(JDIMENSION)
          185 jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
          186                     JDIMENSION max_lines)
          187 {
          188   JDIMENSION lines_per_iMCU_row;
          189 
          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);
          194     return 0;
          195   }
          196 
          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);
          202   }
          203 
          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);
          208 
          209   /* Decompress directly into user's buffer. */
          210   if (! (*cinfo->coef->decompress_data) (cinfo, data))
          211     return 0;                        /* suspension forced, can do nothing more */
          212 
          213   /* OK, we processed one iMCU row. */
          214   cinfo->output_scanline += lines_per_iMCU_row;
          215   return lines_per_iMCU_row;
          216 }
          217 
          218 
          219 /* Additional entry points for buffered-image mode. */
          220 
          221 #ifdef D_MULTISCAN_FILES_SUPPORTED
          222 
          223 /*
          224  * Initialize for an output pass in buffered-image mode.
          225  */
          226 
          227 GLOBAL(boolean)
          228 jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
          229 {
          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)
          235     scan_number = 1;
          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);
          242 }
          243 
          244 
          245 /*
          246  * Finish up after an output pass in buffered-image mode.
          247  *
          248  * Returns FALSE if suspended.  The return value need be inspected only if
          249  * a suspending data source is used.
          250  */
          251 
          252 GLOBAL(boolean)
          253 jpeg_finish_output (j_decompress_ptr cinfo)
          254 {
          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);
          264   }
          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 */
          270   }
          271   cinfo->global_state = DSTATE_BUFIMAGE;
          272   return TRUE;
          273 }
          274 
          275 #endif /* D_MULTISCAN_FILES_SUPPORTED */