tor-browser

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

jctrans.c (15276B)


      1 /*
      2 * jctrans.c
      3 *
      4 * This file was part of the Independent JPEG Group's software:
      5 * Copyright (C) 1995-1998, Thomas G. Lane.
      6 * Modified 2000-2009 by Guido Vollbeding.
      7 * libjpeg-turbo Modifications:
      8 * Copyright (C) 2020, 2022, D. R. Commander.
      9 * For conditions of distribution and use, see the accompanying README.ijg
     10 * file.
     11 *
     12 * This file contains library routines for transcoding compression,
     13 * that is, writing raw DCT coefficient arrays to an output JPEG file.
     14 * The routines in jcapimin.c will also be needed by a transcoder.
     15 */
     16 
     17 #define JPEG_INTERNALS
     18 #include "jinclude.h"
     19 #include "jpeglib.h"
     20 #include "jpegapicomp.h"
     21 
     22 
     23 /* Forward declarations */
     24 LOCAL(void) transencode_master_selection(j_compress_ptr cinfo,
     25                                         jvirt_barray_ptr *coef_arrays);
     26 LOCAL(void) transencode_coef_controller(j_compress_ptr cinfo,
     27                                        jvirt_barray_ptr *coef_arrays);
     28 
     29 
     30 /*
     31 * Compression initialization for writing raw-coefficient data.
     32 * Before calling this, all parameters and a data destination must be set up.
     33 * Call jpeg_finish_compress() to actually write the data.
     34 *
     35 * The number of passed virtual arrays must match cinfo->num_components.
     36 * Note that the virtual arrays need not be filled or even realized at
     37 * the time write_coefficients is called; indeed, if the virtual arrays
     38 * were requested from this compression object's memory manager, they
     39 * typically will be realized during this routine and filled afterwards.
     40 */
     41 
     42 GLOBAL(void)
     43 jpeg_write_coefficients(j_compress_ptr cinfo, jvirt_barray_ptr *coef_arrays)
     44 {
     45  if (cinfo->master->lossless)
     46    ERREXIT(cinfo, JERR_NOTIMPL);
     47 
     48  if (cinfo->global_state != CSTATE_START)
     49    ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
     50  /* Mark all tables to be written */
     51  jpeg_suppress_tables(cinfo, FALSE);
     52  /* (Re)initialize error mgr and destination modules */
     53  (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo);
     54  (*cinfo->dest->init_destination) (cinfo);
     55  /* Perform master selection of active modules */
     56  transencode_master_selection(cinfo, coef_arrays);
     57  /* Wait for jpeg_finish_compress() call */
     58  cinfo->next_scanline = 0;     /* so jpeg_write_marker works */
     59  cinfo->global_state = CSTATE_WRCOEFS;
     60 }
     61 
     62 
     63 /*
     64 * Initialize the compression object with default parameters,
     65 * then copy from the source object all parameters needed for lossless
     66 * transcoding.  Parameters that can be varied without loss (such as
     67 * scan script and Huffman optimization) are left in their default states.
     68 */
     69 
     70 GLOBAL(void)
     71 jpeg_copy_critical_parameters(j_decompress_ptr srcinfo, j_compress_ptr dstinfo)
     72 {
     73  JQUANT_TBL **qtblptr;
     74  jpeg_component_info *incomp, *outcomp;
     75  JQUANT_TBL *c_quant, *slot_quant;
     76  int tblno, ci, coefi;
     77 
     78  if (srcinfo->master->lossless)
     79    ERREXIT(dstinfo, JERR_NOTIMPL);
     80 
     81  /* Safety check to ensure start_compress not called yet. */
     82  if (dstinfo->global_state != CSTATE_START)
     83    ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
     84  /* Copy fundamental image dimensions */
     85  dstinfo->image_width = srcinfo->image_width;
     86  dstinfo->image_height = srcinfo->image_height;
     87  dstinfo->input_components = srcinfo->num_components;
     88  dstinfo->in_color_space = srcinfo->jpeg_color_space;
     89 #if JPEG_LIB_VERSION >= 70
     90  dstinfo->jpeg_width = srcinfo->output_width;
     91  dstinfo->jpeg_height = srcinfo->output_height;
     92  dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
     93  dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
     94 #endif
     95  /* Initialize all parameters to default values */
     96  jpeg_set_defaults(dstinfo);
     97  /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
     98   * Fix it to get the right header markers for the image colorspace.
     99   */
    100  jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
    101  dstinfo->data_precision = srcinfo->data_precision;
    102  dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
    103  /* Copy the source's quantization tables. */
    104  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
    105    if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
    106      qtblptr = &dstinfo->quant_tbl_ptrs[tblno];
    107      if (*qtblptr == NULL)
    108        *qtblptr = jpeg_alloc_quant_table((j_common_ptr)dstinfo);
    109      memcpy((*qtblptr)->quantval, srcinfo->quant_tbl_ptrs[tblno]->quantval,
    110             sizeof((*qtblptr)->quantval));
    111      (*qtblptr)->sent_table = FALSE;
    112    }
    113  }
    114  /* Copy the source's per-component info.
    115   * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
    116   */
    117  dstinfo->num_components = srcinfo->num_components;
    118  if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
    119    ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
    120             MAX_COMPONENTS);
    121  for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
    122       ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
    123    outcomp->component_id = incomp->component_id;
    124    outcomp->h_samp_factor = incomp->h_samp_factor;
    125    outcomp->v_samp_factor = incomp->v_samp_factor;
    126    outcomp->quant_tbl_no = incomp->quant_tbl_no;
    127    /* Make sure saved quantization table for component matches the qtable
    128     * slot.  If not, the input file re-used this qtable slot.
    129     * IJG encoder currently cannot duplicate this.
    130     */
    131    tblno = outcomp->quant_tbl_no;
    132    if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
    133        srcinfo->quant_tbl_ptrs[tblno] == NULL)
    134      ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
    135    slot_quant = srcinfo->quant_tbl_ptrs[tblno];
    136    c_quant = incomp->quant_table;
    137    if (c_quant != NULL) {
    138      for (coefi = 0; coefi < DCTSIZE2; coefi++) {
    139        if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
    140          ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
    141      }
    142    }
    143    /* Note: we do not copy the source's Huffman table assignments;
    144     * instead we rely on jpeg_set_colorspace to have made a suitable choice.
    145     */
    146  }
    147  /* Also copy JFIF version and resolution information, if available.
    148   * Strictly speaking this isn't "critical" info, but it's nearly
    149   * always appropriate to copy it if available.  In particular,
    150   * if the application chooses to copy JFIF 1.02 extension markers from
    151   * the source file, we need to copy the version to make sure we don't
    152   * emit a file that has 1.02 extensions but a claimed version of 1.01.
    153   * We will *not*, however, copy version info from mislabeled "2.01" files.
    154   */
    155  if (srcinfo->saw_JFIF_marker) {
    156    if (srcinfo->JFIF_major_version == 1) {
    157      dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
    158      dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
    159    }
    160    dstinfo->density_unit = srcinfo->density_unit;
    161    dstinfo->X_density = srcinfo->X_density;
    162    dstinfo->Y_density = srcinfo->Y_density;
    163  }
    164 }
    165 
    166 
    167 /*
    168 * Master selection of compression modules for transcoding.
    169 * This substitutes for jcinit.c's initialization of the full compressor.
    170 */
    171 
    172 LOCAL(void)
    173 transencode_master_selection(j_compress_ptr cinfo,
    174                             jvirt_barray_ptr *coef_arrays)
    175 {
    176  /* Although we don't actually use input_components for transcoding,
    177   * jcmaster.c's initial_setup will complain if input_components is 0.
    178   */
    179  cinfo->input_components = 1;
    180  /* Initialize master control (includes parameter checking/processing) */
    181  jinit_c_master_control(cinfo, TRUE /* transcode only */);
    182 
    183  /* Entropy encoding: either Huffman or arithmetic coding. */
    184  if (cinfo->arith_code) {
    185 #ifdef C_ARITH_CODING_SUPPORTED
    186    jinit_arith_encoder(cinfo);
    187 #else
    188    ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
    189 #endif
    190  } else {
    191    if (cinfo->progressive_mode) {
    192 #ifdef C_PROGRESSIVE_SUPPORTED
    193      jinit_phuff_encoder(cinfo);
    194 #else
    195      ERREXIT(cinfo, JERR_NOT_COMPILED);
    196 #endif
    197    } else
    198      jinit_huff_encoder(cinfo);
    199  }
    200 
    201  /* We need a special coefficient buffer controller. */
    202  transencode_coef_controller(cinfo, coef_arrays);
    203 
    204  jinit_marker_writer(cinfo);
    205 
    206  /* We can now tell the memory manager to allocate virtual arrays. */
    207  (*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo);
    208 
    209  /* Write the datastream header (SOI, JFIF) immediately.
    210   * Frame and scan headers are postponed till later.
    211   * This lets application insert special markers after the SOI.
    212   */
    213  (*cinfo->marker->write_file_header) (cinfo);
    214 }
    215 
    216 
    217 /*
    218 * The rest of this file is a special implementation of the coefficient
    219 * buffer controller.  This is similar to jccoefct.c, but it handles only
    220 * output from presupplied virtual arrays.  Furthermore, we generate any
    221 * dummy padding blocks on-the-fly rather than expecting them to be present
    222 * in the arrays.
    223 */
    224 
    225 /* Private buffer controller object */
    226 
    227 typedef struct {
    228  struct jpeg_c_coef_controller pub; /* public fields */
    229 
    230  JDIMENSION iMCU_row_num;      /* iMCU row # within image */
    231  JDIMENSION mcu_ctr;           /* counts MCUs processed in current row */
    232  int MCU_vert_offset;          /* counts MCU rows within iMCU row */
    233  int MCU_rows_per_iMCU_row;    /* number of such rows needed */
    234 
    235  /* Virtual block array for each component. */
    236  jvirt_barray_ptr *whole_image;
    237 
    238  /* Workspace for constructing dummy blocks at right/bottom edges. */
    239  JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
    240 } my_coef_controller;
    241 
    242 typedef my_coef_controller *my_coef_ptr;
    243 
    244 
    245 LOCAL(void)
    246 start_iMCU_row(j_compress_ptr cinfo)
    247 /* Reset within-iMCU-row counters for a new row */
    248 {
    249  my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
    250 
    251  /* In an interleaved scan, an MCU row is the same as an iMCU row.
    252   * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
    253   * But at the bottom of the image, process only what's left.
    254   */
    255  if (cinfo->comps_in_scan > 1) {
    256    coef->MCU_rows_per_iMCU_row = 1;
    257  } else {
    258    if (coef->iMCU_row_num < (cinfo->total_iMCU_rows - 1))
    259      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
    260    else
    261      coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
    262  }
    263 
    264  coef->mcu_ctr = 0;
    265  coef->MCU_vert_offset = 0;
    266 }
    267 
    268 
    269 /*
    270 * Initialize for a processing pass.
    271 */
    272 
    273 METHODDEF(void)
    274 start_pass_coef(j_compress_ptr cinfo, J_BUF_MODE pass_mode)
    275 {
    276  my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
    277 
    278  if (pass_mode != JBUF_CRANK_DEST)
    279    ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
    280 
    281  coef->iMCU_row_num = 0;
    282  start_iMCU_row(cinfo);
    283 }
    284 
    285 
    286 /*
    287 * Process some data.
    288 * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
    289 * per call, ie, v_samp_factor block rows for each component in the scan.
    290 * The data is obtained from the virtual arrays and fed to the entropy coder.
    291 * Returns TRUE if the iMCU row is completed, FALSE if suspended.
    292 *
    293 * NB: input_buf is ignored; it is likely to be a NULL pointer.
    294 */
    295 
    296 METHODDEF(boolean)
    297 compress_output(j_compress_ptr cinfo, JSAMPIMAGE input_buf)
    298 {
    299  my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
    300  JDIMENSION MCU_col_num;       /* index of current MCU within row */
    301  JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
    302  JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
    303  int blkn, ci, xindex, yindex, yoffset, blockcnt;
    304  JDIMENSION start_col;
    305  JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
    306  JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
    307  JBLOCKROW buffer_ptr;
    308  jpeg_component_info *compptr;
    309 
    310  /* Align the virtual buffers for the components used in this scan. */
    311  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    312    compptr = cinfo->cur_comp_info[ci];
    313    buffer[ci] = (*cinfo->mem->access_virt_barray)
    314      ((j_common_ptr)cinfo, coef->whole_image[compptr->component_index],
    315       coef->iMCU_row_num * compptr->v_samp_factor,
    316       (JDIMENSION)compptr->v_samp_factor, FALSE);
    317  }
    318 
    319  /* Loop to process one whole iMCU row */
    320  for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
    321       yoffset++) {
    322    for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
    323         MCU_col_num++) {
    324      /* Construct list of pointers to DCT blocks belonging to this MCU */
    325      blkn = 0;                 /* index of current DCT block within MCU */
    326      for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    327        compptr = cinfo->cur_comp_info[ci];
    328        start_col = MCU_col_num * compptr->MCU_width;
    329        blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width :
    330                                                  compptr->last_col_width;
    331        for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
    332          if (coef->iMCU_row_num < last_iMCU_row ||
    333              yindex + yoffset < compptr->last_row_height) {
    334            /* Fill in pointers to real blocks in this row */
    335            buffer_ptr = buffer[ci][yindex + yoffset] + start_col;
    336            for (xindex = 0; xindex < blockcnt; xindex++)
    337              MCU_buffer[blkn++] = buffer_ptr++;
    338          } else {
    339            /* At bottom of image, need a whole row of dummy blocks */
    340            xindex = 0;
    341          }
    342          /* Fill in any dummy blocks needed in this row.
    343           * Dummy blocks are filled in the same way as in jccoefct.c:
    344           * all zeroes in the AC entries, DC entries equal to previous
    345           * block's DC value.  The init routine has already zeroed the
    346           * AC entries, so we need only set the DC entries correctly.
    347           */
    348          for (; xindex < compptr->MCU_width; xindex++) {
    349            MCU_buffer[blkn] = coef->dummy_buffer[blkn];
    350            MCU_buffer[blkn][0][0] = MCU_buffer[blkn - 1][0][0];
    351            blkn++;
    352          }
    353        }
    354      }
    355      /* Try to write the MCU. */
    356      if (!(*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
    357        /* Suspension forced; update state counters and exit */
    358        coef->MCU_vert_offset = yoffset;
    359        coef->mcu_ctr = MCU_col_num;
    360        return FALSE;
    361      }
    362    }
    363    /* Completed an MCU row, but perhaps not an iMCU row */
    364    coef->mcu_ctr = 0;
    365  }
    366  /* Completed the iMCU row, advance counters for next one */
    367  coef->iMCU_row_num++;
    368  start_iMCU_row(cinfo);
    369  return TRUE;
    370 }
    371 
    372 
    373 METHODDEF(boolean)
    374 compress_output_12(j_compress_ptr cinfo, J12SAMPIMAGE input_buf)
    375 {
    376  return compress_output(cinfo, (JSAMPIMAGE)input_buf);
    377 }
    378 
    379 
    380 /*
    381 * Initialize coefficient buffer controller.
    382 *
    383 * Each passed coefficient array must be the right size for that
    384 * coefficient: width_in_blocks wide and height_in_blocks high,
    385 * with unitheight at least v_samp_factor.
    386 */
    387 
    388 LOCAL(void)
    389 transencode_coef_controller(j_compress_ptr cinfo,
    390                            jvirt_barray_ptr *coef_arrays)
    391 {
    392  my_coef_ptr coef;
    393  JBLOCKROW buffer;
    394  int i;
    395 
    396  coef = (my_coef_ptr)
    397    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    398                                sizeof(my_coef_controller));
    399  cinfo->coef = (struct jpeg_c_coef_controller *)coef;
    400  coef->pub.start_pass = start_pass_coef;
    401  coef->pub.compress_data = compress_output;
    402  coef->pub.compress_data_12 = compress_output_12;
    403 
    404  /* Save pointer to virtual arrays */
    405  coef->whole_image = coef_arrays;
    406 
    407  /* Allocate and pre-zero space for dummy DCT blocks. */
    408  buffer = (JBLOCKROW)
    409    (*cinfo->mem->alloc_large) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    410                                C_MAX_BLOCKS_IN_MCU * sizeof(JBLOCK));
    411  jzero_far((void *)buffer, C_MAX_BLOCKS_IN_MCU * sizeof(JBLOCK));
    412  for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
    413    coef->dummy_buffer[i] = buffer + i;
    414  }
    415 }