jdapistd.c
上传用户:wuyixingx
上传日期:2007-01-08
资源大小:745k
文件大小:9k
源码类别:

图形图象

开发平台:

C/C++

  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. #define JPEG_INTERNALS
  17. #include "jinclude.h"
  18. #include "jpeglib.h"
  19. /* Forward declarations */
  20. LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
  21. /*
  22.  * Decompression initialization.
  23.  * jpeg_read_header must be completed before calling this.
  24.  *
  25.  * If a multipass operating mode was selected, this will do all but the
  26.  * last pass, and thus may take a great deal of time.
  27.  *
  28.  * Returns FALSE if suspended.  The return value need be inspected only if
  29.  * a suspending data source is used.
  30.  */
  31. GLOBAL(boolean)
  32. jpeg_start_decompress (j_decompress_ptr cinfo)
  33. {
  34.   if (cinfo->global_state == DSTATE_READY) {
  35.     /* First call: initialize master control, select active modules */
  36.     jinit_master_decompress(cinfo);
  37.     if (cinfo->buffered_image) {
  38.       /* No more work here; expecting jpeg_start_output next */
  39.       cinfo->global_state = DSTATE_BUFIMAGE;
  40.       return TRUE;
  41.     }
  42.     cinfo->global_state = DSTATE_PRELOAD;
  43.   }
  44.   if (cinfo->global_state == DSTATE_PRELOAD) {
  45.     /* If file has multiple scans, absorb them all into the coef buffer */
  46.     if (cinfo->inputctl->has_multiple_scans) {
  47. #ifdef D_MULTISCAN_FILES_SUPPORTED
  48.       for (;;) {
  49. int retcode;
  50. /* Call progress monitor hook if present */
  51. if (cinfo->progress != NULL)
  52.   (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  53. /* Absorb some more input */
  54. retcode = (*cinfo->inputctl->consume_input) (cinfo);
  55. if (retcode == JPEG_SUSPENDED)
  56.   return FALSE;
  57. if (retcode == JPEG_REACHED_EOI)
  58.   break;
  59. /* Advance progress counter if appropriate */
  60. if (cinfo->progress != NULL &&
  61.     (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
  62.   if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
  63.     /* jdmaster underestimated number of scans; ratchet up one scan */
  64.     cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
  65.   }
  66. }
  67.       }
  68. #else
  69.       ERREXIT(cinfo, JERR_NOT_COMPILED);
  70. #endif /* D_MULTISCAN_FILES_SUPPORTED */
  71.     }
  72.     cinfo->output_scan_number = cinfo->input_scan_number;
  73.   } else if (cinfo->global_state != DSTATE_PRESCAN)
  74.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  75.   /* Perform any dummy output passes, and set up for the final pass */
  76.   return output_pass_setup(cinfo);
  77. }
  78. /*
  79.  * Set up for an output pass, and perform any dummy pass(es) needed.
  80.  * Common subroutine for jpeg_start_decompress and jpeg_start_output.
  81.  * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
  82.  * Exit: If done, returns TRUE and sets global_state for proper output mode.
  83.  *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
  84.  */
  85. LOCAL(boolean)
  86. output_pass_setup (j_decompress_ptr cinfo)
  87. {
  88.   if (cinfo->global_state != DSTATE_PRESCAN) {
  89.     /* First call: do pass setup */
  90.     (*cinfo->master->prepare_for_output_pass) (cinfo);
  91.     cinfo->output_scanline = 0;
  92.     cinfo->global_state = DSTATE_PRESCAN;
  93.   }
  94.   /* Loop over any required dummy passes */
  95.   while (cinfo->master->is_dummy_pass) {
  96. #ifdef QUANT_2PASS_SUPPORTED
  97.     /* Crank through the dummy pass */
  98.     while (cinfo->output_scanline < cinfo->output_height) {
  99.       JDIMENSION last_scanline;
  100.       /* Call progress monitor hook if present */
  101.       if (cinfo->progress != NULL) {
  102. cinfo->progress->pass_counter = (long) cinfo->output_scanline;
  103. cinfo->progress->pass_limit = (long) cinfo->output_height;
  104. (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  105.       }
  106.       /* Process some data */
  107.       last_scanline = cinfo->output_scanline;
  108.       (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
  109.     &cinfo->output_scanline, (JDIMENSION) 0);
  110.       if (cinfo->output_scanline == last_scanline)
  111. return FALSE; /* No progress made, must suspend */
  112.     }
  113.     /* Finish up dummy pass, and set up for another one */
  114.     (*cinfo->master->finish_output_pass) (cinfo);
  115.     (*cinfo->master->prepare_for_output_pass) (cinfo);
  116.     cinfo->output_scanline = 0;
  117. #else
  118.     ERREXIT(cinfo, JERR_NOT_COMPILED);
  119. #endif /* QUANT_2PASS_SUPPORTED */
  120.   }
  121.   /* Ready for application to drive output pass through
  122.    * jpeg_read_scanlines or jpeg_read_raw_data.
  123.    */
  124.   cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
  125.   return TRUE;
  126. }
  127. /*
  128.  * Read some scanlines of data from the JPEG decompressor.
  129.  *
  130.  * The return value will be the number of lines actually read.
  131.  * This may be less than the number requested in several cases,
  132.  * including bottom of image, data source suspension, and operating
  133.  * modes that emit multiple scanlines at a time.
  134.  *
  135.  * Note: we warn about excess calls to jpeg_read_scanlines() since
  136.  * this likely signals an application programmer error.  However,
  137.  * an oversize buffer (max_lines > scanlines remaining) is not an error.
  138.  */
  139. GLOBAL(JDIMENSION)
  140. jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
  141.      JDIMENSION max_lines)
  142. {
  143.   JDIMENSION row_ctr;
  144.   if (cinfo->global_state != DSTATE_SCANNING)
  145.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  146.   if (cinfo->output_scanline >= cinfo->output_height) {
  147.     WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
  148.     return 0;
  149.   }
  150.   /* Call progress monitor hook if present */
  151.   if (cinfo->progress != NULL) {
  152.     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
  153.     cinfo->progress->pass_limit = (long) cinfo->output_height;
  154.     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  155.   }
  156.   /* Process some data */
  157.   row_ctr = 0;
  158.   (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
  159.   cinfo->output_scanline += row_ctr;
  160.   return row_ctr;
  161. }
  162. /*
  163.  * Alternate entry point to read raw data.
  164.  * Processes exactly one iMCU row per call, unless suspended.
  165.  */
  166. GLOBAL(JDIMENSION)
  167. jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
  168.     JDIMENSION max_lines)
  169. {
  170.   JDIMENSION lines_per_iMCU_row;
  171.   if (cinfo->global_state != DSTATE_RAW_OK)
  172.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  173.   if (cinfo->output_scanline >= cinfo->output_height) {
  174.     WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
  175.     return 0;
  176.   }
  177.   /* Call progress monitor hook if present */
  178.   if (cinfo->progress != NULL) {
  179.     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
  180.     cinfo->progress->pass_limit = (long) cinfo->output_height;
  181.     (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
  182.   }
  183.   /* Verify that at least one iMCU row can be returned. */
  184.   lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
  185.   if (max_lines < lines_per_iMCU_row)
  186.     ERREXIT(cinfo, JERR_BUFFER_SIZE);
  187.   /* Decompress directly into user's buffer. */
  188.   if (! (*cinfo->coef->decompress_data) (cinfo, data))
  189.     return 0; /* suspension forced, can do nothing more */
  190.   /* OK, we processed one iMCU row. */
  191.   cinfo->output_scanline += lines_per_iMCU_row;
  192.   return lines_per_iMCU_row;
  193. }
  194. /* Additional entry points for buffered-image mode. */
  195. #ifdef D_MULTISCAN_FILES_SUPPORTED
  196. /*
  197.  * Initialize for an output pass in buffered-image mode.
  198.  */
  199. GLOBAL(boolean)
  200. jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
  201. {
  202.   if (cinfo->global_state != DSTATE_BUFIMAGE &&
  203.       cinfo->global_state != DSTATE_PRESCAN)
  204.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  205.   /* Limit scan number to valid range */
  206.   if (scan_number <= 0)
  207.     scan_number = 1;
  208.   if (cinfo->inputctl->eoi_reached &&
  209.       scan_number > cinfo->input_scan_number)
  210.     scan_number = cinfo->input_scan_number;
  211.   cinfo->output_scan_number = scan_number;
  212.   /* Perform any dummy output passes, and set up for the real pass */
  213.   return output_pass_setup(cinfo);
  214. }
  215. /*
  216.  * Finish up after an output pass in buffered-image mode.
  217.  *
  218.  * Returns FALSE if suspended.  The return value need be inspected only if
  219.  * a suspending data source is used.
  220.  */
  221. GLOBAL(boolean)
  222. jpeg_finish_output (j_decompress_ptr cinfo)
  223. {
  224.   if ((cinfo->global_state == DSTATE_SCANNING ||
  225.        cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
  226.     /* Terminate this pass. */
  227.     /* We do not require the whole pass to have been completed. */
  228.     (*cinfo->master->finish_output_pass) (cinfo);
  229.     cinfo->global_state = DSTATE_BUFPOST;
  230.   } else if (cinfo->global_state != DSTATE_BUFPOST) {
  231.     /* BUFPOST = repeat call after a suspension, anything else is error */
  232.     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
  233.   }
  234.   /* Read markers looking for SOS or EOI */
  235.   while (cinfo->input_scan_number <= cinfo->output_scan_number &&
  236.  ! cinfo->inputctl->eoi_reached) {
  237.     if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
  238.       return FALSE; /* Suspend, come back later */
  239.   }
  240.   cinfo->global_state = DSTATE_BUFIMAGE;
  241.   return TRUE;
  242. }
  243. #endif /* D_MULTISCAN_FILES_SUPPORTED */