home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / jlib / jdapistd.cpp < prev    next >
C/C++ Source or Header  |  2000-05-16  |  10KB  |  302 lines

  1. //-------------------------------------------------------------------------//
  2. //          Windows Graphics Programming: Win32 GDI and DirectDraw         //
  3. //                        ISBN  0-13-086985-6                              //
  4. //                                                                         //
  5. //  Modified by: Yuan, Feng                             www.fengyuan.com   //
  6. //  Changes    : C++, exception, in-memory source, BGR byte order          //
  7. //  Version    : 1.00.000, May 31, 2000                                    //
  8. //-------------------------------------------------------------------------//
  9.  
  10. /*
  11.  * jdapistd.c
  12.  *
  13.  * Copyright (C) 1994-1996, Thomas G. Lane.
  14.  * This file is part of the Independent JPEG Group's software.
  15.  * For conditions of distribution and use, see the accompanying README file.
  16.  *
  17.  * This file contains application interface code for the decompression half
  18.  * of the JPEG library.  These are the "standard" API routines that are
  19.  * used in the normal full-decompression case.  They are not used by a
  20.  * transcoding-only application.  Note that if an application links in
  21.  * jpeg_start_decompress, it will end up linking in the entire decompressor.
  22.  * We thus must separate this file from jdapimin.c to avoid linking the
  23.  * whole decompression library into a transcoder.
  24.  */
  25.  
  26. #define JPEG_INTERNALS
  27. #include "jinclude.h"
  28. #include "jpeglib.h"
  29.  
  30.  
  31. /* Forward declarations */
  32. LOCAL(boolean) output_pass_setup (j_decompress_ptr cinfo);
  33.  
  34.  
  35. /*
  36.  * Decompression initialization.
  37.  * jpeg_read_header must be completed before calling this.
  38.  *
  39.  * If a multipass operating mode was selected, this will do all but the
  40.  * last pass, and thus may take a great deal of time.
  41.  *
  42.  * Returns FALSE if suspended.  The return value need be inspected only if
  43.  * a suspending data source is used.
  44.  */
  45.  
  46. boolean jpeg_decompress_struct::jpeg_start_decompress(void)
  47. {
  48.     if (global_state == DSTATE_READY) 
  49.     {
  50.         /* First call: initialize master control, select active modules */
  51.         jinit_master_decompress(this);
  52.         
  53.         if (buffered_image) 
  54.         {
  55.             /* No more work here; expecting jpeg_start_output next */
  56.             global_state = DSTATE_BUFIMAGE;
  57.             return TRUE;
  58.         }
  59.         global_state = DSTATE_PRELOAD;
  60.     }
  61.   
  62.     if (global_state == DSTATE_PRELOAD) 
  63.     {
  64.         /* If file has multiple scans, absorb them all into the coef buffer */
  65.         if (inputctl->has_multiple_scans) 
  66.         {
  67. #ifdef D_MULTISCAN_FILES_SUPPORTED
  68.             for (;;) 
  69.             {
  70.                 int retcode;
  71.                 /* Call progress monitor hook if present */
  72.                 if (progress != NULL)
  73.                     progress->progress_monitor(this);
  74.     
  75.                 /* Absorb some more input */
  76.                 retcode = (*inputctl->consume_input) (this);
  77.                 
  78.                 if (retcode == JPEG_SUSPENDED)
  79.                     return FALSE;
  80.                 
  81.                 if (retcode == JPEG_REACHED_EOI)
  82.                     break;
  83.     
  84.                 /* Advance progress counter if appropriate */
  85.                 if (progress != NULL &&
  86.                     (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) 
  87.                 {
  88.                     if (++progress->pass_counter >= progress->pass_limit) 
  89.                     {
  90.                         /* jdmaster underestimated number of scans; ratchet up one scan */
  91.                         progress->pass_limit += (long) total_iMCU_rows;
  92.                     }
  93.                 }
  94.             }
  95. #else
  96.             ERREXIT(this, JERR_NOT_COMPILED);
  97. #endif /* D_MULTISCAN_FILES_SUPPORTED */
  98.         }
  99.         
  100.         output_scan_number = input_scan_number;
  101.     } 
  102.     else if (global_state != DSTATE_PRESCAN)
  103.         ERREXIT1(JERR_BAD_STATE, global_state);
  104.   
  105.     /* Perform any dummy output passes, and set up for the final pass */
  106.     return output_pass_setup(this);
  107. }
  108.  
  109.  
  110. /*
  111.  * Set up for an output pass, and perform any dummy pass(es) needed.
  112.  * Common subroutine for jpeg_start_decompress and jpeg_start_output.
  113.  * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
  114.  * Exit: If done, returns TRUE and sets global_state for proper output mode.
  115.  *       If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
  116.  */
  117.  
  118. LOCAL(boolean)
  119. output_pass_setup (j_decompress_ptr cinfo)
  120. {
  121.   if (cinfo->global_state != DSTATE_PRESCAN) {
  122.     /* First call: do pass setup */
  123.     (*cinfo->master->prepare_for_output_pass) (cinfo);
  124.     cinfo->output_scanline = 0;
  125.     cinfo->global_state = DSTATE_PRESCAN;
  126.   }
  127.   /* Loop over any required dummy passes */
  128.   while (cinfo->master->is_dummy_pass) {
  129. #ifdef QUANT_2PASS_SUPPORTED
  130.     /* Crank through the dummy pass */
  131.     while (cinfo->output_scanline < cinfo->output_height) {
  132.       JDIMENSION last_scanline;
  133.       /* Call progress monitor hook if present */
  134.       if (cinfo->progress != NULL) {
  135.     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
  136.     cinfo->progress->pass_limit = (long) cinfo->output_height;
  137.     cinfo->progress->progress_monitor(cinfo);
  138.       }
  139.       /* Process some data */
  140.       last_scanline = cinfo->output_scanline;
  141.       (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
  142.                     &cinfo->output_scanline, (JDIMENSION) 0);
  143.       if (cinfo->output_scanline == last_scanline)
  144.     return FALSE;        /* No progress made, must suspend */
  145.     }
  146.     /* Finish up dummy pass, and set up for another one */
  147.     (*cinfo->master->finish_output_pass) (cinfo);
  148.     (*cinfo->master->prepare_for_output_pass) (cinfo);
  149.     cinfo->output_scanline = 0;
  150. #else
  151.     ERREXIT(cinfo, JERR_NOT_COMPILED);
  152. #endif /* QUANT_2PASS_SUPPORTED */
  153.   }
  154.   /* Ready for application to drive output pass through
  155.    * jpeg_read_scanlines or jpeg_read_raw_data.
  156.    */
  157.   cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
  158.   return TRUE;
  159. }
  160.  
  161.  
  162. /*
  163.  * Read some scanlines of data from the JPEG decompressor.
  164.  *
  165.  * The return value will be the number of lines actually read.
  166.  * This may be less than the number requested in several cases,
  167.  * including bottom of image, data source suspension, and operating
  168.  * modes that emit multiple scanlines at a time.
  169.  *
  170.  * Note: we warn about excess calls to jpeg_read_scanlines() since
  171.  * this likely signals an application programmer error.  However,
  172.  * an oversize buffer (max_lines > scanlines remaining) is not an error.
  173.  */
  174.  
  175. JDIMENSION jpeg_decompress_struct::jpeg_read_scanlines(JSAMPARRAY scanlines, JDIMENSION max_lines)
  176. {
  177.     JDIMENSION row_ctr;
  178.  
  179.     if ( global_state != DSTATE_SCANNING )
  180.         ERREXIT1(JERR_BAD_STATE, global_state);
  181.   
  182.     if ( output_scanline >= output_height) 
  183.     {
  184.         WARNMS(JWRN_TOO_MUCH_DATA);
  185.         return 0;
  186.     }
  187.  
  188.     /* Call progress monitor hook if present */
  189.     if (progress != NULL) 
  190.     {
  191.         progress->pass_counter = (long) output_scanline;
  192.         progress->pass_limit = (long) output_height;
  193.         progress->progress_monitor(this);
  194.     }
  195.  
  196.     /* Process some data */
  197.     row_ctr = 0;
  198.     (*main->process_data) (this, scanlines, &row_ctr, max_lines);
  199.     output_scanline += row_ctr;
  200.     
  201.     return row_ctr;
  202. }
  203.  
  204.  
  205. /*
  206.  * Alternate entry point to read raw data.
  207.  * Processes exactly one iMCU row per call, unless suspended.
  208.  */
  209.  
  210. GLOBAL(JDIMENSION)
  211. jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
  212.             JDIMENSION max_lines)
  213. {
  214.   JDIMENSION lines_per_iMCU_row;
  215.  
  216.   if (cinfo->global_state != DSTATE_RAW_OK)
  217.     cinfo->ERREXIT1(JERR_BAD_STATE, cinfo->global_state);
  218.   if (cinfo->output_scanline >= cinfo->output_height) {
  219.     cinfo->WARNMS(JWRN_TOO_MUCH_DATA);
  220.     return 0;
  221.   }
  222.  
  223.   /* Call progress monitor hook if present */
  224.   if (cinfo->progress != NULL) {
  225.     cinfo->progress->pass_counter = (long) cinfo->output_scanline;
  226.     cinfo->progress->pass_limit = (long) cinfo->output_height;
  227.     cinfo->progress->progress_monitor(cinfo);
  228.   }
  229.  
  230.   /* Verify that at least one iMCU row can be returned. */
  231.   lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
  232.   if (max_lines < lines_per_iMCU_row)
  233.     cinfo->ERREXIT(JERR_BUFFER_SIZE);
  234.  
  235.   /* Decompress directly into user's buffer. */
  236.   if (! (*cinfo->coef->decompress_data) (cinfo, data))
  237.     return 0;            /* suspension forced, can do nothing more */
  238.  
  239.   /* OK, we processed one iMCU row. */
  240.   cinfo->output_scanline += lines_per_iMCU_row;
  241.   return lines_per_iMCU_row;
  242. }
  243.  
  244.  
  245. /* Additional entry points for buffered-image mode. */
  246.  
  247. #ifdef D_MULTISCAN_FILES_SUPPORTED
  248.  
  249. /*
  250.  * Initialize for an output pass in buffered-image mode.
  251.  */
  252.  
  253. GLOBAL(boolean)
  254. jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
  255. {
  256.   if (cinfo->global_state != DSTATE_BUFIMAGE &&
  257.       cinfo->global_state != DSTATE_PRESCAN)
  258.     cinfo->ERREXIT1(JERR_BAD_STATE, cinfo->global_state);
  259.   /* Limit scan number to valid range */
  260.   if (scan_number <= 0)
  261.     scan_number = 1;
  262.   if (cinfo->inputctl->eoi_reached &&
  263.       scan_number > cinfo->input_scan_number)
  264.     scan_number = cinfo->input_scan_number;
  265.   cinfo->output_scan_number = scan_number;
  266.   /* Perform any dummy output passes, and set up for the real pass */
  267.   return output_pass_setup(cinfo);
  268. }
  269.  
  270.  
  271. /*
  272.  * Finish up after an output pass in buffered-image mode.
  273.  *
  274.  * Returns FALSE if suspended.  The return value need be inspected only if
  275.  * a suspending data source is used.
  276.  */
  277.  
  278. GLOBAL(boolean)
  279. jpeg_finish_output (j_decompress_ptr cinfo)
  280. {
  281.   if ((cinfo->global_state == DSTATE_SCANNING ||
  282.        cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
  283.     /* Terminate this pass. */
  284.     /* We do not require the whole pass to have been completed. */
  285.     (*cinfo->master->finish_output_pass) (cinfo);
  286.     cinfo->global_state = DSTATE_BUFPOST;
  287.   } else if (cinfo->global_state != DSTATE_BUFPOST) {
  288.     /* BUFPOST = repeat call after a suspension, anything else is error */
  289.     cinfo->ERREXIT1(JERR_BAD_STATE, cinfo->global_state);
  290.   }
  291.   /* Read markers looking for SOS or EOI */
  292.   while (cinfo->input_scan_number <= cinfo->output_scan_number &&
  293.      ! cinfo->inputctl->eoi_reached) {
  294.     if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
  295.       return FALSE;        /* Suspend, come back later */
  296.   }
  297.   cinfo->global_state = DSTATE_BUFIMAGE;
  298.   return TRUE;
  299. }
  300.  
  301. #endif /* D_MULTISCAN_FILES_SUPPORTED */
  302.