JDPOSTCT.C
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:9k
源码类别:

图片显示

开发平台:

Visual C++

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