home *** CD-ROM | disk | FTP | other *** search
/ PC World Plus! (NZ) 2001 June / HDC50.iso / Info / Extras / Jpeg / SRC / JDAPISTD.C < prev    next >
C/C++ Source or Header  |  1999-08-11  |  10KB  |  276 lines

  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 */
  276.