shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * jcmainct.c
shun-iwasawa 82a8f5
 *
shun-iwasawa 82a8f5
 * This file was part of the Independent JPEG Group's software:
shun-iwasawa 82a8f5
 * Copyright (C) 1994-1996, Thomas G. Lane.
shun-iwasawa 82a8f5
 * It was modified by The libjpeg-turbo Project to include only code relevant
shun-iwasawa 82a8f5
 * to libjpeg-turbo.
shun-iwasawa 82a8f5
 * For conditions of distribution and use, see the accompanying README.ijg
shun-iwasawa 82a8f5
 * file.
shun-iwasawa 82a8f5
 *
shun-iwasawa 82a8f5
 * This file contains the main buffer controller for compression.
shun-iwasawa 82a8f5
 * The main buffer lies between the pre-processor and the JPEG
shun-iwasawa 82a8f5
 * compressor proper; it holds downsampled data in the JPEG colorspace.
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
#define JPEG_INTERNALS
shun-iwasawa 82a8f5
#include "jinclude.h"
shun-iwasawa 82a8f5
#include "jpeglib.h"
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
/* Private buffer controller object */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
typedef struct {
shun-iwasawa 82a8f5
  struct jpeg_c_main_controller pub; /* public fields */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
shun-iwasawa 82a8f5
  JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
shun-iwasawa 82a8f5
  boolean suspended;            /* remember if we suspended output */
shun-iwasawa 82a8f5
  J_BUF_MODE pass_mode;         /* current operating mode */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* If using just a strip buffer, this points to the entire set of buffers
shun-iwasawa 82a8f5
   * (we allocate one for each component).  In the full-image case, this
shun-iwasawa 82a8f5
   * points to the currently accessible strips of the virtual arrays.
shun-iwasawa 82a8f5
   */
shun-iwasawa 82a8f5
  JSAMPARRAY buffer[MAX_COMPONENTS];
shun-iwasawa 82a8f5
} my_main_controller;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
typedef my_main_controller *my_main_ptr;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
/* Forward declarations */
shun-iwasawa 82a8f5
METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo,
shun-iwasawa 82a8f5
                                         JSAMPARRAY input_buf,
shun-iwasawa 82a8f5
                                         JDIMENSION *in_row_ctr,
shun-iwasawa 82a8f5
                                         JDIMENSION in_rows_avail);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * Initialize for a processing pass.
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
METHODDEF(void)
shun-iwasawa 82a8f5
start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
shun-iwasawa 82a8f5
{
shun-iwasawa 82a8f5
  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* Do nothing in raw-data mode. */
shun-iwasawa 82a8f5
  if (cinfo->raw_data_in)
shun-iwasawa 82a8f5
    return;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  if (pass_mode != JBUF_PASS_THRU)
shun-iwasawa 82a8f5
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  main_ptr->cur_iMCU_row = 0;   /* initialize counters */
shun-iwasawa 82a8f5
  main_ptr->rowgroup_ctr = 0;
shun-iwasawa 82a8f5
  main_ptr->suspended = FALSE;
shun-iwasawa 82a8f5
  main_ptr->pass_mode = pass_mode;      /* save mode for use by process_data */
shun-iwasawa 82a8f5
  main_ptr->pub.process_data = process_data_simple_main;
shun-iwasawa 82a8f5
}
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * Process some data.
shun-iwasawa 82a8f5
 * This routine handles the simple pass-through mode,
shun-iwasawa 82a8f5
 * where we have only a strip buffer.
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
METHODDEF(void)
shun-iwasawa 82a8f5
process_data_simple_main(j_compress_ptr cinfo, JSAMPARRAY input_buf,
shun-iwasawa 82a8f5
                         JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)
shun-iwasawa 82a8f5
{
shun-iwasawa 82a8f5
  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
shun-iwasawa 82a8f5
    /* Read input data if we haven't filled the main buffer yet */
shun-iwasawa 82a8f5
    if (main_ptr->rowgroup_ctr < DCTSIZE)
shun-iwasawa 82a8f5
      (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr,
shun-iwasawa 82a8f5
                                        in_rows_avail, main_ptr->buffer,
shun-iwasawa 82a8f5
                                        &main_ptr->rowgroup_ctr,
shun-iwasawa 82a8f5
                                        (JDIMENSION)DCTSIZE);
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    /* If we don't have a full iMCU row buffered, return to application for
shun-iwasawa 82a8f5
     * more data.  Note that preprocessor will always pad to fill the iMCU row
shun-iwasawa 82a8f5
     * at the bottom of the image.
shun-iwasawa 82a8f5
     */
shun-iwasawa 82a8f5
    if (main_ptr->rowgroup_ctr != DCTSIZE)
shun-iwasawa 82a8f5
      return;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
    /* Send the completed row to the compressor */
shun-iwasawa 82a8f5
    if (!(*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
shun-iwasawa 82a8f5
      /* If compressor did not consume the whole row, then we must need to
shun-iwasawa 82a8f5
       * suspend processing and return to the application.  In this situation
shun-iwasawa 82a8f5
       * we pretend we didn't yet consume the last input row; otherwise, if
shun-iwasawa 82a8f5
       * it happened to be the last row of the image, the application would
shun-iwasawa 82a8f5
       * think we were done.
shun-iwasawa 82a8f5
       */
shun-iwasawa 82a8f5
      if (!main_ptr->suspended) {
shun-iwasawa 82a8f5
        (*in_row_ctr)--;
shun-iwasawa 82a8f5
        main_ptr->suspended = TRUE;
shun-iwasawa 82a8f5
      }
shun-iwasawa 82a8f5
      return;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    /* We did finish the row.  Undo our little suspension hack if a previous
shun-iwasawa 82a8f5
     * call suspended; then mark the main buffer empty.
shun-iwasawa 82a8f5
     */
shun-iwasawa 82a8f5
    if (main_ptr->suspended) {
shun-iwasawa 82a8f5
      (*in_row_ctr)++;
shun-iwasawa 82a8f5
      main_ptr->suspended = FALSE;
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
    main_ptr->rowgroup_ctr = 0;
shun-iwasawa 82a8f5
    main_ptr->cur_iMCU_row++;
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
}
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
/*
shun-iwasawa 82a8f5
 * Initialize main buffer controller.
shun-iwasawa 82a8f5
 */
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
GLOBAL(void)
shun-iwasawa 82a8f5
jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
shun-iwasawa 82a8f5
{
shun-iwasawa 82a8f5
  my_main_ptr main_ptr;
shun-iwasawa 82a8f5
  int ci;
shun-iwasawa 82a8f5
  jpeg_component_info *compptr;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  main_ptr = (my_main_ptr)
shun-iwasawa 82a8f5
    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
shun-iwasawa 82a8f5
                                sizeof(my_main_controller));
shun-iwasawa 82a8f5
  cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
shun-iwasawa 82a8f5
  main_ptr->pub.start_pass = start_pass_main;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* We don't need to create a buffer in raw-data mode. */
shun-iwasawa 82a8f5
  if (cinfo->raw_data_in)
shun-iwasawa 82a8f5
    return;
shun-iwasawa 82a8f5
shun-iwasawa 82a8f5
  /* Create the buffer.  It holds downsampled data, so each component
shun-iwasawa 82a8f5
   * may be of a different size.
shun-iwasawa 82a8f5
   */
shun-iwasawa 82a8f5
  if (need_full_buffer) {
shun-iwasawa 82a8f5
    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
shun-iwasawa 82a8f5
  } else {
shun-iwasawa 82a8f5
    /* Allocate a strip buffer for each component */
shun-iwasawa 82a8f5
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
shun-iwasawa 82a8f5
         ci++, compptr++) {
shun-iwasawa 82a8f5
      main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
shun-iwasawa 82a8f5
        ((j_common_ptr)cinfo, JPOOL_IMAGE,
shun-iwasawa 82a8f5
         compptr->width_in_blocks * DCTSIZE,
shun-iwasawa 82a8f5
         (JDIMENSION)(compptr->v_samp_factor * DCTSIZE));
shun-iwasawa 82a8f5
    }
shun-iwasawa 82a8f5
  }
shun-iwasawa 82a8f5
}