136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * jcmainct.c
336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
45033f3e19a31e8ad40c1a79700365aefe5664494DRC * This file was part of the Independent JPEG Group's software:
5489583f5165e05d37302e8eeec58104ea0109127Thomas G. Lane * Copyright (C) 1994-1996, Thomas G. Lane.
65033f3e19a31e8ad40c1a79700365aefe5664494DRC * It was modified by The libjpeg-turbo Project to include only code relevant
75033f3e19a31e8ad40c1a79700365aefe5664494DRC * to libjpeg-turbo.
836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * For conditions of distribution and use, see the accompanying README file.
936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane *
1036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This file contains the main buffer controller for compression.
1136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * The main buffer lies between the pre-processor and the JPEG
1236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * compressor proper; it holds downsampled data in the JPEG colorspace.
1336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
1436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#define JPEG_INTERNALS
1636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jinclude.h"
1736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane#include "jpeglib.h"
1836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
2036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Private buffer controller object */
2136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
2236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanetypedef struct {
2336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  struct jpeg_c_main_controller pub; /* public fields */
2436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
25e5eaf37440b8e337ab150c017df7c03faf846c51DRC  JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
26e5eaf37440b8e337ab150c017df7c03faf846c51DRC  JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
27e5eaf37440b8e337ab150c017df7c03faf846c51DRC  boolean suspended;            /* remember if we suspended output */
28e5eaf37440b8e337ab150c017df7c03faf846c51DRC  J_BUF_MODE pass_mode;         /* current operating mode */
2936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* If using just a strip buffer, this points to the entire set of buffers
3136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * (we allocate one for each component).  In the full-image case, this
3236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * points to the currently accessible strips of the virtual arrays.
3336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   */
3436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  JSAMPARRAY buffer[MAX_COMPONENTS];
3536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane} my_main_controller;
3636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanetypedef my_main_controller * my_main_ptr;
3836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
3936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/* Forward declarations */
41489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void) process_data_simple_main
42bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC        (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
43bc56b754e1a6a1db9ccadf64d6dda8a74140e1a3DRC         JDIMENSION in_rows_avail);
4436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
4636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
4736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize for a processing pass.
4836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
4936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
50489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
5136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanestart_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
5236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
537ed7b572032510d8c96972f624a97222818b5625DRC  my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
5436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
5536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Do nothing in raw-data mode. */
5636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->raw_data_in)
5736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    return;
5836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
59a29d6b4113aa64fd1ea790eea09e56f642f5e1cdDRC  if (pass_mode != JBUF_PASS_THRU)
60a29d6b4113aa64fd1ea790eea09e56f642f5e1cdDRC    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
61a29d6b4113aa64fd1ea790eea09e56f642f5e1cdDRC
62e5eaf37440b8e337ab150c017df7c03faf846c51DRC  main_ptr->cur_iMCU_row = 0;   /* initialize counters */
637ed7b572032510d8c96972f624a97222818b5625DRC  main_ptr->rowgroup_ctr = 0;
647ed7b572032510d8c96972f624a97222818b5625DRC  main_ptr->suspended = FALSE;
65e5eaf37440b8e337ab150c017df7c03faf846c51DRC  main_ptr->pass_mode = pass_mode;      /* save mode for use by process_data */
66a29d6b4113aa64fd1ea790eea09e56f642f5e1cdDRC  main_ptr->pub.process_data = process_data_simple_main;
6736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
6836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
6936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
7036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
7136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Process some data.
7236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * This routine handles the simple pass-through mode,
7336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * where we have only a strip buffer.
7436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
7536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
76489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneMETHODDEF(void)
7736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Laneprocess_data_simple_main (j_compress_ptr cinfo,
78e5eaf37440b8e337ab150c017df7c03faf846c51DRC                          JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
79e5eaf37440b8e337ab150c017df7c03faf846c51DRC                          JDIMENSION in_rows_avail)
8036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
817ed7b572032510d8c96972f624a97222818b5625DRC  my_main_ptr main_ptr = (my_main_ptr) cinfo->main;
8236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
837ed7b572032510d8c96972f624a97222818b5625DRC  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
8436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Read input data if we haven't filled the main buffer yet */
857ed7b572032510d8c96972f624a97222818b5625DRC    if (main_ptr->rowgroup_ctr < DCTSIZE)
8636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      (*cinfo->prep->pre_process_data) (cinfo,
87e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                        input_buf, in_row_ctr, in_rows_avail,
88e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                        main_ptr->buffer, &main_ptr->rowgroup_ctr,
89e5eaf37440b8e337ab150c017df7c03faf846c51DRC                                        (JDIMENSION) DCTSIZE);
9036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
9136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* If we don't have a full iMCU row buffered, return to application for
9236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * more data.  Note that preprocessor will always pad to fill the iMCU row
9336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * at the bottom of the image.
9436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
957ed7b572032510d8c96972f624a97222818b5625DRC    if (main_ptr->rowgroup_ctr != DCTSIZE)
9636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return;
9736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
9836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Send the completed row to the compressor */
997ed7b572032510d8c96972f624a97222818b5625DRC    if (! (*cinfo->coef->compress_data) (cinfo, main_ptr->buffer)) {
100a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane      /* If compressor did not consume the whole row, then we must need to
101a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane       * suspend processing and return to the application.  In this situation
102a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane       * we pretend we didn't yet consume the last input row; otherwise, if
103a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane       * it happened to be the last row of the image, the application would
104a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane       * think we were done.
105a8b67c4fbbfde9b4b4e03f2dea8f4f0b1900fc33Thomas G. Lane       */
1067ed7b572032510d8c96972f624a97222818b5625DRC      if (! main_ptr->suspended) {
107e5eaf37440b8e337ab150c017df7c03faf846c51DRC        (*in_row_ctr)--;
108e5eaf37440b8e337ab150c017df7c03faf846c51DRC        main_ptr->suspended = TRUE;
10936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      }
11036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      return;
11136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
11236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* We did finish the row.  Undo our little suspension hack if a previous
11336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     * call suspended; then mark the main buffer empty.
11436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane     */
1157ed7b572032510d8c96972f624a97222818b5625DRC    if (main_ptr->suspended) {
11636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane      (*in_row_ctr)++;
1177ed7b572032510d8c96972f624a97222818b5625DRC      main_ptr->suspended = FALSE;
11836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
1197ed7b572032510d8c96972f624a97222818b5625DRC    main_ptr->rowgroup_ctr = 0;
1207ed7b572032510d8c96972f624a97222818b5625DRC    main_ptr->cur_iMCU_row++;
12136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
12236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
12336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
12436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
12536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane/*
12636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane * Initialize main buffer controller.
12736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane */
12836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
129489583f5165e05d37302e8eeec58104ea0109127Thomas G. LaneGLOBAL(void)
13036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lanejinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
13136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane{
1327ed7b572032510d8c96972f624a97222818b5625DRC  my_main_ptr main_ptr;
13336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  int ci;
13436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  jpeg_component_info *compptr;
13536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
1367ed7b572032510d8c96972f624a97222818b5625DRC  main_ptr = (my_main_ptr)
13736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
1385de454b291f48382648a5d1dc2aa0fca8b5786d4DRC                                sizeof(my_main_controller));
1397ed7b572032510d8c96972f624a97222818b5625DRC  cinfo->main = (struct jpeg_c_main_controller *) main_ptr;
1407ed7b572032510d8c96972f624a97222818b5625DRC  main_ptr->pub.start_pass = start_pass_main;
14136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
14236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* We don't need to create a buffer in raw-data mode. */
14336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (cinfo->raw_data_in)
14436a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    return;
14536a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane
14636a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  /* Create the buffer.  It holds downsampled data, so each component
14736a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   * may be of a different size.
14836a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane   */
14936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  if (need_full_buffer) {
15036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
15136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  } else {
15236a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    /* Allocate a strip buffer for each component */
15336a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
154e5eaf37440b8e337ab150c017df7c03faf846c51DRC         ci++, compptr++) {
1557ed7b572032510d8c96972f624a97222818b5625DRC      main_ptr->buffer[ci] = (*cinfo->mem->alloc_sarray)
156e5eaf37440b8e337ab150c017df7c03faf846c51DRC        ((j_common_ptr) cinfo, JPOOL_IMAGE,
157e5eaf37440b8e337ab150c017df7c03faf846c51DRC         compptr->width_in_blocks * DCTSIZE,
158e5eaf37440b8e337ab150c017df7c03faf846c51DRC         (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
15936a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane    }
16036a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane  }
16136a4ccccd33f5cc9df62949554af87129ced7f84Thomas G. Lane}
162