home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / jlib / jdpostct.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-16  |  10.2 KB  |  297 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.  * jdpostct.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 the decompression postprocessing controller.
  18.  * This controller manages the upsampling, color conversion, and color
  19.  * quantization/reduction steps; specifically, it controls the buffering
  20.  * between upsample/color conversion and color quantization/reduction.
  21.  *
  22.  * If no color quantization/reduction is required, then this module has no
  23.  * work to do, and it just hands off to the upsample/color conversion code.
  24.  * An integrated upsample/convert/quantize process would replace this module
  25.  * entirely.
  26.  */
  27.  
  28. #define JPEG_INTERNALS
  29. #include "jinclude.h"
  30. #include "jpeglib.h"
  31.  
  32.  
  33. /* Private buffer controller object */
  34.  
  35. typedef struct {
  36.   struct jpeg_d_post_controller pub; /* public fields */
  37.  
  38.   /* Color quantization source buffer: this holds output data from
  39.    * the upsample/color conversion step to be passed to the quantizer.
  40.    * For two-pass color quantization, we need a full-image buffer;
  41.    * for one-pass operation, a strip buffer is sufficient.
  42.    */
  43.   jvirt_sarray_ptr whole_image;    /* virtual array, or NULL if one-pass */
  44.   JSAMPARRAY buffer;        /* strip buffer, or current strip of virtual */
  45.   JDIMENSION strip_height;    /* buffer size in rows */
  46.   /* for two-pass mode only: */
  47.   JDIMENSION starting_row;    /* row # of first row in current strip */
  48.   JDIMENSION next_row;        /* index of next row to fill/empty in strip */
  49. } my_post_controller;
  50.  
  51. typedef my_post_controller * my_post_ptr;
  52.  
  53.  
  54. /* Forward declarations */
  55. void post_process_1pass
  56.     (j_decompress_ptr cinfo,
  57.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  58.          JDIMENSION in_row_groups_avail,
  59.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  60.          JDIMENSION out_rows_avail);
  61.  
  62. #ifdef QUANT_2PASS_SUPPORTED
  63. void post_process_prepass
  64.     (j_decompress_ptr cinfo,
  65.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  66.          JDIMENSION in_row_groups_avail,
  67.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  68.          JDIMENSION out_rows_avail);
  69.  
  70. void post_process_2pass
  71.     (j_decompress_ptr cinfo,
  72.          JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  73.          JDIMENSION in_row_groups_avail,
  74.          JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  75.          JDIMENSION out_rows_avail);
  76. #endif
  77.  
  78.  
  79. /*
  80.  * Initialize for a processing pass.
  81.  */
  82.  
  83. void start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
  84. {
  85.   my_post_ptr post = (my_post_ptr) cinfo->post;
  86.  
  87.   switch (pass_mode) {
  88.   case JBUF_PASS_THRU:
  89.     if (cinfo->quantize_colors) {
  90.       /* Single-pass processing with color quantization. */
  91.       post->pub.post_process_data = post_process_1pass;
  92.       /* We could be doing buffered-image output before starting a 2-pass
  93.        * color quantization; in that case, jinit_d_post_controller did not
  94.        * allocate a strip buffer.  Use the virtual-array buffer as workspace.
  95.        */
  96.       if (post->buffer == NULL) {
  97.     post->buffer = cinfo->mem->access_virt_sarray
  98.       (post->whole_image,
  99.        (JDIMENSION) 0, post->strip_height, TRUE);
  100.       }
  101.     } else {
  102.       /* For single-pass processing without color quantization,
  103.        * I have no work to do; just call the upsampler directly.
  104.        */
  105.       post->pub.post_process_data = cinfo->upsample->upsample;
  106.     }
  107.     break;
  108. #ifdef QUANT_2PASS_SUPPORTED
  109.   case JBUF_SAVE_AND_PASS:
  110.     /* First pass of 2-pass quantization */
  111.     if (post->whole_image == NULL)
  112.       cinfo->ERREXIT(JERR_BAD_BUFFER_MODE);
  113.     post->pub.post_process_data = post_process_prepass;
  114.     break;
  115.   case JBUF_CRANK_DEST:
  116.     /* Second pass of 2-pass quantization */
  117.     if (post->whole_image == NULL)
  118.       cinfo->ERREXIT(JERR_BAD_BUFFER_MODE);
  119.     post->pub.post_process_data = post_process_2pass;
  120.     break;
  121. #endif /* QUANT_2PASS_SUPPORTED */
  122.   default:
  123.     cinfo->ERREXIT(JERR_BAD_BUFFER_MODE);
  124.     break;
  125.   }
  126.   post->starting_row = post->next_row = 0;
  127. }
  128.  
  129.  
  130. /*
  131.  * Process some data in the one-pass (strip buffer) case.
  132.  * This is used for color precision reduction as well as one-pass quantization.
  133.  */
  134.  
  135. void post_process_1pass (j_decompress_ptr cinfo,
  136.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  137.             JDIMENSION in_row_groups_avail,
  138.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  139.             JDIMENSION out_rows_avail)
  140. {
  141.   my_post_ptr post = (my_post_ptr) cinfo->post;
  142.   JDIMENSION num_rows, max_rows;
  143.  
  144.   /* Fill the buffer, but not more than what we can dump out in one go. */
  145.   /* Note we rely on the upsampler to detect bottom of image. */
  146.   max_rows = out_rows_avail - *out_row_ctr;
  147.   if (max_rows > post->strip_height)
  148.     max_rows = post->strip_height;
  149.   num_rows = 0;
  150.   (*cinfo->upsample->upsample) (cinfo,
  151.         input_buf, in_row_group_ctr, in_row_groups_avail,
  152.         post->buffer, &num_rows, max_rows);
  153.   /* Quantize and emit data. */
  154.   (*cinfo->cquantize->color_quantize) (cinfo,
  155.         post->buffer, output_buf + *out_row_ctr, (int) num_rows);
  156.   *out_row_ctr += num_rows;
  157. }
  158.  
  159.  
  160. #ifdef QUANT_2PASS_SUPPORTED
  161.  
  162. /*
  163.  * Process some data in the first pass of 2-pass quantization.
  164.  */
  165.  
  166. void post_process_prepass (j_decompress_ptr cinfo,
  167.               JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  168.               JDIMENSION in_row_groups_avail,
  169.               JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  170.               JDIMENSION out_rows_avail)
  171. {
  172.   my_post_ptr post = (my_post_ptr) cinfo->post;
  173.   JDIMENSION old_next_row, num_rows;
  174.  
  175.   /* Reposition virtual buffer if at start of strip. */
  176.   if (post->next_row == 0) {
  177.     post->buffer = cinfo->mem->access_virt_sarray
  178.     (post->whole_image,
  179.      post->starting_row, post->strip_height, TRUE);
  180.   }
  181.  
  182.   /* Upsample some data (up to a strip height's worth). */
  183.   old_next_row = post->next_row;
  184.   (*cinfo->upsample->upsample) (cinfo,
  185.         input_buf, in_row_group_ctr, in_row_groups_avail,
  186.         post->buffer, &post->next_row, post->strip_height);
  187.  
  188.   /* Allow quantizer to scan new data.  No data is emitted, */
  189.   /* but we advance out_row_ctr so outer loop can tell when we're done. */
  190.   if (post->next_row > old_next_row) {
  191.     num_rows = post->next_row - old_next_row;
  192.     (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
  193.                      (JSAMPARRAY) NULL, (int) num_rows);
  194.     *out_row_ctr += num_rows;
  195.   }
  196.  
  197.   /* Advance if we filled the strip. */
  198.   if (post->next_row >= post->strip_height) {
  199.     post->starting_row += post->strip_height;
  200.     post->next_row = 0;
  201.   }
  202. }
  203.  
  204.  
  205. /*
  206.  * Process some data in the second pass of 2-pass quantization.
  207.  */
  208.  
  209. void post_process_2pass (j_decompress_ptr cinfo,
  210.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  211.             JDIMENSION in_row_groups_avail,
  212.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  213.             JDIMENSION out_rows_avail)
  214. {
  215.   my_post_ptr post = (my_post_ptr) cinfo->post;
  216.   JDIMENSION num_rows, max_rows;
  217.  
  218.   /* Reposition virtual buffer if at start of strip. */
  219.   if (post->next_row == 0) {
  220.     post->buffer = cinfo->mem->access_virt_sarray
  221.     (post->whole_image,
  222.      post->starting_row, post->strip_height, FALSE);
  223.   }
  224.  
  225.   /* Determine number of rows to emit. */
  226.   num_rows = post->strip_height - post->next_row; /* available in strip */
  227.   max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
  228.   if (num_rows > max_rows)
  229.     num_rows = max_rows;
  230.   /* We have to check bottom of image here, can't depend on upsampler. */
  231.   max_rows = cinfo->output_height - post->starting_row;
  232.   if (num_rows > max_rows)
  233.     num_rows = max_rows;
  234.  
  235.   /* Quantize and emit data. */
  236.   (*cinfo->cquantize->color_quantize) (cinfo,
  237.         post->buffer + post->next_row, output_buf + *out_row_ctr,
  238.         (int) num_rows);
  239.   *out_row_ctr += num_rows;
  240.  
  241.   /* Advance if we filled the strip. */
  242.   post->next_row += num_rows;
  243.   if (post->next_row >= post->strip_height) {
  244.     post->starting_row += post->strip_height;
  245.     post->next_row = 0;
  246.   }
  247. }
  248.  
  249. #endif /* QUANT_2PASS_SUPPORTED */
  250.  
  251.  
  252. /*
  253.  * Initialize postprocessing controller.
  254.  */
  255.  
  256. GLOBAL(void)
  257. jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
  258. {
  259.   my_post_ptr post;
  260.  
  261.   post = (my_post_ptr)
  262.     cinfo->mem->alloc_small(JPOOL_IMAGE, sizeof(my_post_controller));
  263.   cinfo->post = (struct jpeg_d_post_controller *) post;
  264.   post->pub.start_pass = start_pass_dpost;
  265.   post->whole_image = NULL;    /* flag for no virtual arrays */
  266.   post->buffer = NULL;        /* flag for no strip buffer */
  267.  
  268.   /* Create the quantization buffer, if needed */
  269.   if (cinfo->quantize_colors) {
  270.     /* The buffer strip height is max_v_samp_factor, which is typically
  271.      * an efficient number of rows for upsampling to return.
  272.      * (In the presence of output rescaling, we might want to be smarter?)
  273.      */
  274.     post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
  275.     if (need_full_buffer) {
  276.       /* Two-pass color quantization: need full-image storage. */
  277.       /* We round up the number of rows to a multiple of the strip height. */
  278. #ifdef QUANT_2PASS_SUPPORTED
  279.       post->whole_image = cinfo->mem->request_virt_sarray
  280.     (JPOOL_IMAGE, FALSE,
  281.      cinfo->output_width * cinfo->out_color_components,
  282.      (JDIMENSION) jround_up((long) cinfo->output_height,
  283.                 (long) post->strip_height),
  284.      post->strip_height);
  285. #else
  286.       cinfo->ERREXIT(JERR_BAD_BUFFER_MODE);
  287. #endif /* QUANT_2PASS_SUPPORTED */
  288.     } else {
  289.       /* One-pass color quantization: just make a strip buffer. */
  290.       post->buffer = cinfo->mem->alloc_sarray
  291.     (JPOOL_IMAGE,
  292.      cinfo->output_width * cinfo->out_color_components,
  293.      post->strip_height);
  294.     }
  295.   }
  296. }
  297.