JCMAINCT.c
上传用户:qiutianh
上传日期:2022-08-08
资源大小:939k
文件大小:10k
源码类别:

图形图象

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////////////
  2. //
  3. // Note : this file is included as part of the Smaller Animals Software
  4. // JpegFile package. Though this file has not been modified from it's 
  5. // original IJG 6a form, it is not the responsibility on the Independent
  6. // JPEG Group to answer questions regarding this code.
  7. //
  8. // Any questions you have about this code should be addressed to :
  9. //
  10. // CHRISDL@PAGESZ.NET - the distributor of this package.
  11. //
  12. // Remember, by including this code in the JpegFile package, Smaller 
  13. // Animals Software assumes all responsibilities for answering questions
  14. // about it. If we (SA Software) can't answer your questions ourselves, we 
  15. // will direct you to people who can.
  16. //
  17. // Thanks, CDL.
  18. //
  19. ////////////////////////////////////////////////////////////////////////
  20. /*
  21.  * jcmainct.c
  22.  *
  23.  * Copyright (C) 1994-1996, Thomas G. Lane.
  24.  * This file is part of the Independent JPEG Group's software.
  25.  * For conditions of distribution and use, see the accompanying README file.
  26.  *
  27.  * This file contains the main buffer controller for compression.
  28.  * The main buffer lies between the pre-processor and the JPEG
  29.  * compressor proper; it holds downsampled data in the JPEG colorspace.
  30.  */
  31. #define JPEG_INTERNALS
  32. #include "jinclude.h"
  33. #include "jpeglib.h"
  34. /* Note: currently, there is no operating mode in which a full-image buffer
  35.  * is needed at this step.  If there were, that mode could not be used with
  36.  * "raw data" input, since this module is bypassed in that case.  However,
  37.  * we've left the code here for possible use in special applications.
  38.  */
  39. #undef FULL_MAIN_BUFFER_SUPPORTED
  40. /* Private buffer controller object */
  41. typedef struct {
  42.   struct jpeg_c_main_controller pub; /* public fields */
  43.   JDIMENSION cur_iMCU_row; /* number of current iMCU row */
  44.   JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
  45.   boolean suspended; /* remember if we suspended output */
  46.   J_BUF_MODE pass_mode; /* current operating mode */
  47.   /* If using just a strip buffer, this points to the entire set of buffers
  48.    * (we allocate one for each component).  In the full-image case, this
  49.    * points to the currently accessible strips of the virtual arrays.
  50.    */
  51.   JSAMPARRAY buffer[MAX_COMPONENTS];
  52. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  53.   /* If using full-image storage, this array holds pointers to virtual-array
  54.    * control blocks for each component.  Unused if not full-image storage.
  55.    */
  56.   jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
  57. #endif
  58. } my_main_controller;
  59. typedef my_main_controller * my_main_ptr;
  60. /* Forward declarations */
  61. METHODDEF(void) process_data_simple_main
  62. JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
  63.      JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
  64. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  65. METHODDEF(void) process_data_buffer_main
  66. JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
  67.      JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
  68. #endif
  69. /*
  70.  * Initialize for a processing pass.
  71.  */
  72. METHODDEF(void)
  73. start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
  74. {
  75.   my_main_ptr main = (my_main_ptr) cinfo->main;
  76.   /* Do nothing in raw-data mode. */
  77.   if (cinfo->raw_data_in)
  78.     return;
  79.   main->cur_iMCU_row = 0; /* initialize counters */
  80.   main->rowgroup_ctr = 0;
  81.   main->suspended = FALSE;
  82.   main->pass_mode = pass_mode; /* save mode for use by process_data */
  83.   switch (pass_mode) {
  84.   case JBUF_PASS_THRU:
  85. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  86.     if (main->whole_image[0] != NULL)
  87.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  88. #endif
  89.     main->pub.process_data = process_data_simple_main;
  90.     break;
  91. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  92.   case JBUF_SAVE_SOURCE:
  93.   case JBUF_CRANK_DEST:
  94.   case JBUF_SAVE_AND_PASS:
  95.     if (main->whole_image[0] == NULL)
  96.       ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  97.     main->pub.process_data = process_data_buffer_main;
  98.     break;
  99. #endif
  100.   default:
  101.     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  102.     break;
  103.   }
  104. }
  105. /*
  106.  * Process some data.
  107.  * This routine handles the simple pass-through mode,
  108.  * where we have only a strip buffer.
  109.  */
  110. METHODDEF(void)
  111. process_data_simple_main (j_compress_ptr cinfo,
  112.   JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
  113.   JDIMENSION in_rows_avail)
  114. {
  115.   my_main_ptr main = (my_main_ptr) cinfo->main;
  116.   while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
  117.     /* Read input data if we haven't filled the main buffer yet */
  118.     if (main->rowgroup_ctr < DCTSIZE)
  119.       (*cinfo->prep->pre_process_data) (cinfo,
  120. input_buf, in_row_ctr, in_rows_avail,
  121. main->buffer, &main->rowgroup_ctr,
  122. (JDIMENSION) DCTSIZE);
  123.     /* If we don't have a full iMCU row buffered, return to application for
  124.      * more data.  Note that preprocessor will always pad to fill the iMCU row
  125.      * at the bottom of the image.
  126.      */
  127.     if (main->rowgroup_ctr != DCTSIZE)
  128.       return;
  129.     /* Send the completed row to the compressor */
  130.     if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
  131.       /* If compressor did not consume the whole row, then we must need to
  132.        * suspend processing and return to the application.  In this situation
  133.        * we pretend we didn't yet consume the last input row; otherwise, if
  134.        * it happened to be the last row of the image, the application would
  135.        * think we were done.
  136.        */
  137.       if (! main->suspended) {
  138. (*in_row_ctr)--;
  139. main->suspended = TRUE;
  140.       }
  141.       return;
  142.     }
  143.     /* We did finish the row.  Undo our little suspension hack if a previous
  144.      * call suspended; then mark the main buffer empty.
  145.      */
  146.     if (main->suspended) {
  147.       (*in_row_ctr)++;
  148.       main->suspended = FALSE;
  149.     }
  150.     main->rowgroup_ctr = 0;
  151.     main->cur_iMCU_row++;
  152.   }
  153. }
  154. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  155. /*
  156.  * Process some data.
  157.  * This routine handles all of the modes that use a full-size buffer.
  158.  */
  159. METHODDEF(void)
  160. process_data_buffer_main (j_compress_ptr cinfo,
  161.   JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
  162.   JDIMENSION in_rows_avail)
  163. {
  164.   my_main_ptr main = (my_main_ptr) cinfo->main;
  165.   int ci;
  166.   jpeg_component_info *compptr;
  167.   boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
  168.   while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
  169.     /* Realign the virtual buffers if at the start of an iMCU row. */
  170.     if (main->rowgroup_ctr == 0) {
  171.       for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  172.    ci++, compptr++) {
  173. main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
  174.   ((j_common_ptr) cinfo, main->whole_image[ci],
  175.    main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
  176.    (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
  177.       }
  178.       /* In a read pass, pretend we just read some source data. */
  179.       if (! writing) {
  180. *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
  181. main->rowgroup_ctr = DCTSIZE;
  182.       }
  183.     }
  184.     /* If a write pass, read input data until the current iMCU row is full. */
  185.     /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
  186.     if (writing) {
  187.       (*cinfo->prep->pre_process_data) (cinfo,
  188. input_buf, in_row_ctr, in_rows_avail,
  189. main->buffer, &main->rowgroup_ctr,
  190. (JDIMENSION) DCTSIZE);
  191.       /* Return to application if we need more data to fill the iMCU row. */
  192.       if (main->rowgroup_ctr < DCTSIZE)
  193. return;
  194.     }
  195.     /* Emit data, unless this is a sink-only pass. */
  196.     if (main->pass_mode != JBUF_SAVE_SOURCE) {
  197.       if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
  198. /* If compressor did not consume the whole row, then we must need to
  199.  * suspend processing and return to the application.  In this situation
  200.  * we pretend we didn't yet consume the last input row; otherwise, if
  201.  * it happened to be the last row of the image, the application would
  202.  * think we were done.
  203.  */
  204. if (! main->suspended) {
  205.   (*in_row_ctr)--;
  206.   main->suspended = TRUE;
  207. }
  208. return;
  209.       }
  210.       /* We did finish the row.  Undo our little suspension hack if a previous
  211.        * call suspended; then mark the main buffer empty.
  212.        */
  213.       if (main->suspended) {
  214. (*in_row_ctr)++;
  215. main->suspended = FALSE;
  216.       }
  217.     }
  218.     /* If get here, we are done with this iMCU row.  Mark buffer empty. */
  219.     main->rowgroup_ctr = 0;
  220.     main->cur_iMCU_row++;
  221.   }
  222. }
  223. #endif /* FULL_MAIN_BUFFER_SUPPORTED */
  224. /*
  225.  * Initialize main buffer controller.
  226.  */
  227. GLOBAL(void)
  228. jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
  229. {
  230.   my_main_ptr main;
  231.   int ci;
  232.   jpeg_component_info *compptr;
  233.   main = (my_main_ptr)
  234.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  235. SIZEOF(my_main_controller));
  236.   cinfo->main = (struct jpeg_c_main_controller *) main;
  237.   main->pub.start_pass = start_pass_main;
  238.   /* We don't need to create a buffer in raw-data mode. */
  239.   if (cinfo->raw_data_in)
  240.     return;
  241.   /* Create the buffer.  It holds downsampled data, so each component
  242.    * may be of a different size.
  243.    */
  244.   if (need_full_buffer) {
  245. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  246.     /* Allocate a full-image virtual array for each component */
  247.     /* Note we pad the bottom to a multiple of the iMCU height */
  248.     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  249.  ci++, compptr++) {
  250.       main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
  251. ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
  252.  compptr->width_in_blocks * DCTSIZE,
  253.  (JDIMENSION) jround_up((long) compptr->height_in_blocks,
  254. (long) compptr->v_samp_factor) * DCTSIZE,
  255.  (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
  256.     }
  257. #else
  258.     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
  259. #endif
  260.   } else {
  261. #ifdef FULL_MAIN_BUFFER_SUPPORTED
  262.     main->whole_image[0] = NULL; /* flag for no virtual arrays */
  263. #endif
  264.     /* Allocate a strip buffer for each component */
  265.     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
  266.  ci++, compptr++) {
  267.       main->buffer[ci] = (*cinfo->mem->alloc_sarray)
  268. ((j_common_ptr) cinfo, JPOOL_IMAGE,
  269.  compptr->width_in_blocks * DCTSIZE,
  270.  (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
  271.     }
  272.   }
  273. }