tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jcmainct.c (5632B)


      1 /*
      2 * jcmainct.c
      3 *
      4 * This file was part of the Independent JPEG Group's software:
      5 * Copyright (C) 1994-1996, Thomas G. Lane.
      6 * Lossless JPEG Modifications:
      7 * Copyright (C) 1999, Ken Murchison.
      8 * libjpeg-turbo Modifications:
      9 * Copyright (C) 2022, D. R. Commander.
     10 * For conditions of distribution and use, see the accompanying README.ijg
     11 * file.
     12 *
     13 * This file contains the main buffer controller for compression.
     14 * The main buffer lies between the pre-processor and the JPEG
     15 * compressor proper; it holds downsampled data in the JPEG colorspace.
     16 */
     17 
     18 #define JPEG_INTERNALS
     19 #include "jinclude.h"
     20 #include "jpeglib.h"
     21 #include "jsamplecomp.h"
     22 
     23 
     24 #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
     25 
     26 /* Private buffer controller object */
     27 
     28 typedef struct {
     29  struct jpeg_c_main_controller pub; /* public fields */
     30 
     31  JDIMENSION cur_iMCU_row;      /* number of current iMCU row */
     32  JDIMENSION rowgroup_ctr;      /* counts row groups received in iMCU row */
     33  boolean suspended;            /* remember if we suspended output */
     34  J_BUF_MODE pass_mode;         /* current operating mode */
     35 
     36  /* If using just a strip buffer, this points to the entire set of buffers
     37   * (we allocate one for each component).  In the full-image case, this
     38   * points to the currently accessible strips of the virtual arrays.
     39   */
     40  _JSAMPARRAY buffer[MAX_COMPONENTS];
     41 } my_main_controller;
     42 
     43 typedef my_main_controller *my_main_ptr;
     44 
     45 
     46 /* Forward declarations */
     47 METHODDEF(void) process_data_simple_main(j_compress_ptr cinfo,
     48                                         _JSAMPARRAY input_buf,
     49                                         JDIMENSION *in_row_ctr,
     50                                         JDIMENSION in_rows_avail);
     51 
     52 
     53 /*
     54 * Initialize for a processing pass.
     55 */
     56 
     57 METHODDEF(void)
     58 start_pass_main(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
     59 {
     60  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
     61 
     62  /* Do nothing in raw-data mode. */
     63  if (cinfo->raw_data_in)
     64    return;
     65 
     66  if (pass_mode != JBUF_PASS_THRU)
     67    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
     68 
     69  main_ptr->cur_iMCU_row = 0;   /* initialize counters */
     70  main_ptr->rowgroup_ctr = 0;
     71  main_ptr->suspended = FALSE;
     72  main_ptr->pass_mode = pass_mode;      /* save mode for use by process_data */
     73  main_ptr->pub._process_data = process_data_simple_main;
     74 }
     75 
     76 
     77 /*
     78 * Process some data.
     79 * This routine handles the simple pass-through mode,
     80 * where we have only a strip buffer.
     81 */
     82 
     83 METHODDEF(void)
     84 process_data_simple_main(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
     85                         JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail)
     86 {
     87  my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
     88  JDIMENSION data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
     89 
     90  while (main_ptr->cur_iMCU_row < cinfo->total_iMCU_rows) {
     91    /* Read input data if we haven't filled the main buffer yet */
     92    if (main_ptr->rowgroup_ctr < data_unit)
     93      (*cinfo->prep->_pre_process_data) (cinfo, input_buf, in_row_ctr,
     94                                         in_rows_avail, main_ptr->buffer,
     95                                         &main_ptr->rowgroup_ctr, data_unit);
     96 
     97    /* If we don't have a full iMCU row buffered, return to application for
     98     * more data.  Note that preprocessor will always pad to fill the iMCU row
     99     * at the bottom of the image.
    100     */
    101    if (main_ptr->rowgroup_ctr != data_unit)
    102      return;
    103 
    104    /* Send the completed row to the compressor */
    105    if (!(*cinfo->coef->_compress_data) (cinfo, main_ptr->buffer)) {
    106      /* If compressor did not consume the whole row, then we must need to
    107       * suspend processing and return to the application.  In this situation
    108       * we pretend we didn't yet consume the last input row; otherwise, if
    109       * it happened to be the last row of the image, the application would
    110       * think we were done.
    111       */
    112      if (!main_ptr->suspended) {
    113        (*in_row_ctr)--;
    114        main_ptr->suspended = TRUE;
    115      }
    116      return;
    117    }
    118    /* We did finish the row.  Undo our little suspension hack if a previous
    119     * call suspended; then mark the main buffer empty.
    120     */
    121    if (main_ptr->suspended) {
    122      (*in_row_ctr)++;
    123      main_ptr->suspended = FALSE;
    124    }
    125    main_ptr->rowgroup_ctr = 0;
    126    main_ptr->cur_iMCU_row++;
    127  }
    128 }
    129 
    130 
    131 /*
    132 * Initialize main buffer controller.
    133 */
    134 
    135 GLOBAL(void)
    136 _jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
    137 {
    138  my_main_ptr main_ptr;
    139  int ci;
    140  jpeg_component_info *compptr;
    141  int data_unit = cinfo->master->lossless ? 1 : DCTSIZE;
    142 
    143  if (cinfo->data_precision != BITS_IN_JSAMPLE)
    144    ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    145 
    146  main_ptr = (my_main_ptr)
    147    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    148                                sizeof(my_main_controller));
    149  cinfo->main = (struct jpeg_c_main_controller *)main_ptr;
    150  main_ptr->pub.start_pass = start_pass_main;
    151 
    152  /* We don't need to create a buffer in raw-data mode. */
    153  if (cinfo->raw_data_in)
    154    return;
    155 
    156  /* Create the buffer.  It holds downsampled data, so each component
    157   * may be of a different size.
    158   */
    159  if (need_full_buffer) {
    160    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    161  } else {
    162    /* Allocate a strip buffer for each component */
    163    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    164         ci++, compptr++) {
    165      main_ptr->buffer[ci] = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
    166        ((j_common_ptr)cinfo, JPOOL_IMAGE,
    167         compptr->width_in_blocks * data_unit,
    168         (JDIMENSION)(compptr->v_samp_factor * data_unit));
    169    }
    170  }
    171 }
    172 
    173 #endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */