tor-browser

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

jclhuff.c (18635B)


      1 /*
      2 * jclhuff.c
      3 *
      4 * This file was part of the Independent JPEG Group's software:
      5 * Copyright (C) 1991-1997, 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 Huffman entropy encoding routines for lossless JPEG.
     14 *
     15 * Much of the complexity here has to do with supporting output suspension.
     16 * If the data destination module demands suspension, we want to be able to
     17 * back up to the start of the current MCU.  To do this, we copy state
     18 * variables into local working storage, and update them back to the
     19 * permanent JPEG objects only upon successful completion of an MCU.
     20 */
     21 
     22 #define JPEG_INTERNALS
     23 #include "jinclude.h"
     24 #include "jpeglib.h"
     25 #include "jlossls.h"            /* Private declarations for lossless codec */
     26 #include "jchuff.h"             /* Declarations shared with jc*huff.c */
     27 
     28 
     29 #ifdef C_LOSSLESS_SUPPORTED
     30 
     31 /* The legal range of a spatial difference is
     32 * -32767 .. +32768.
     33 * Hence the magnitude should always fit in 16 bits.
     34 */
     35 
     36 #define MAX_DIFF_BITS  16
     37 
     38 
     39 /* Expanded entropy encoder object for Huffman encoding in lossless mode.
     40 *
     41 * The savable_state subrecord contains fields that change within an MCU,
     42 * but must not be updated permanently until we complete the MCU.
     43 */
     44 
     45 typedef struct {
     46  size_t put_buffer;            /* current bit-accumulation buffer */
     47  int put_bits;                 /* # of bits now in it */
     48 } savable_state;
     49 
     50 
     51 typedef struct {
     52  int ci, yoffset, MCU_width;
     53 } lhe_input_ptr_info;
     54 
     55 
     56 typedef struct {
     57  struct jpeg_entropy_encoder pub; /* public fields */
     58 
     59  savable_state saved;          /* Bit buffer at start of MCU */
     60 
     61  /* These fields are NOT loaded into local working state. */
     62  unsigned int restarts_to_go;  /* MCUs left in this restart interval */
     63  int next_restart_num;         /* next restart number to write (0-7) */
     64 
     65  /* Pointers to derived tables (these workspaces have image lifespan) */
     66  c_derived_tbl *derived_tbls[NUM_HUFF_TBLS];
     67 
     68  /* Pointers to derived tables to be used for each data unit within an MCU */
     69  c_derived_tbl *cur_tbls[C_MAX_BLOCKS_IN_MCU];
     70 
     71 #ifdef ENTROPY_OPT_SUPPORTED    /* Statistics tables for optimization */
     72  long *count_ptrs[NUM_HUFF_TBLS];
     73 
     74  /* Pointers to stats tables to be used for each data unit within an MCU */
     75  long *cur_counts[C_MAX_BLOCKS_IN_MCU];
     76 #endif
     77 
     78  /* Pointers to the proper input difference row for each group of data units
     79   * within an MCU.  For each component, there are Vi groups of Hi data units.
     80   */
     81  JDIFFROW input_ptr[C_MAX_BLOCKS_IN_MCU];
     82 
     83  /* Number of input pointers in use for the current MCU.  This is the sum
     84   * of all Vi in the MCU.
     85   */
     86  int num_input_ptrs;
     87 
     88  /* Information used for positioning the input pointers within the input
     89   * difference rows.
     90   */
     91  lhe_input_ptr_info input_ptr_info[C_MAX_BLOCKS_IN_MCU];
     92 
     93  /* Index of the proper input pointer for each data unit within an MCU */
     94  int input_ptr_index[C_MAX_BLOCKS_IN_MCU];
     95 
     96 } lhuff_entropy_encoder;
     97 
     98 typedef lhuff_entropy_encoder *lhuff_entropy_ptr;
     99 
    100 /* Working state while writing an MCU.
    101 * This struct contains all the fields that are needed by subroutines.
    102 */
    103 
    104 typedef struct {
    105  JOCTET *next_output_byte;     /* => next byte to write in buffer */
    106  size_t free_in_buffer;        /* # of byte spaces remaining in buffer */
    107  savable_state cur;            /* Current bit buffer & DC state */
    108  j_compress_ptr cinfo;         /* dump_buffer needs access to this */
    109 } working_state;
    110 
    111 
    112 /* Forward declarations */
    113 METHODDEF(JDIMENSION) encode_mcus_huff(j_compress_ptr cinfo,
    114                                       JDIFFIMAGE diff_buf,
    115                                       JDIMENSION MCU_row_num,
    116                                       JDIMENSION MCU_col_num,
    117                                       JDIMENSION nMCU);
    118 METHODDEF(void) finish_pass_huff(j_compress_ptr cinfo);
    119 #ifdef ENTROPY_OPT_SUPPORTED
    120 METHODDEF(JDIMENSION) encode_mcus_gather(j_compress_ptr cinfo,
    121                                         JDIFFIMAGE diff_buf,
    122                                         JDIMENSION MCU_row_num,
    123                                         JDIMENSION MCU_col_num,
    124                                         JDIMENSION nMCU);
    125 METHODDEF(void) finish_pass_gather(j_compress_ptr cinfo);
    126 #endif
    127 
    128 
    129 /*
    130 * Initialize for a Huffman-compressed scan.
    131 * If gather_statistics is TRUE, we do not output anything during the scan,
    132 * just count the Huffman symbols used and generate Huffman code tables.
    133 */
    134 
    135 METHODDEF(void)
    136 start_pass_lhuff(j_compress_ptr cinfo, boolean gather_statistics)
    137 {
    138  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
    139  int ci, dctbl, sampn, ptrn, yoffset, xoffset;
    140  jpeg_component_info *compptr;
    141 
    142  if (gather_statistics) {
    143 #ifdef ENTROPY_OPT_SUPPORTED
    144    entropy->pub.encode_mcus = encode_mcus_gather;
    145    entropy->pub.finish_pass = finish_pass_gather;
    146 #else
    147    ERREXIT(cinfo, JERR_NOT_COMPILED);
    148 #endif
    149  } else {
    150    entropy->pub.encode_mcus = encode_mcus_huff;
    151    entropy->pub.finish_pass = finish_pass_huff;
    152  }
    153 
    154  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    155    compptr = cinfo->cur_comp_info[ci];
    156    dctbl = compptr->dc_tbl_no;
    157    if (gather_statistics) {
    158 #ifdef ENTROPY_OPT_SUPPORTED
    159      /* Check for invalid table indexes */
    160      /* (make_c_derived_tbl does this in the other path) */
    161      if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
    162        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
    163      /* Allocate and zero the statistics tables */
    164      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
    165      if (entropy->count_ptrs[dctbl] == NULL)
    166        entropy->count_ptrs[dctbl] = (long *)
    167          (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    168                                      257 * sizeof(long));
    169      memset(entropy->count_ptrs[dctbl], 0, 257 * sizeof(long));
    170 #endif
    171    } else {
    172      /* Compute derived values for Huffman tables */
    173      /* We may do this more than once for a table, but it's not expensive */
    174      jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
    175                              &entropy->derived_tbls[dctbl]);
    176    }
    177  }
    178 
    179  /* Precalculate encoding info for each sample in an MCU of this scan */
    180  for (sampn = 0, ptrn = 0; sampn < cinfo->blocks_in_MCU;) {
    181    compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]];
    182    ci = compptr->component_index;
    183    for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) {
    184      /* Precalculate the setup info for each input pointer */
    185      entropy->input_ptr_info[ptrn].ci = ci;
    186      entropy->input_ptr_info[ptrn].yoffset = yoffset;
    187      entropy->input_ptr_info[ptrn].MCU_width = compptr->MCU_width;
    188      for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) {
    189        /* Precalculate the input pointer index for each sample */
    190        entropy->input_ptr_index[sampn] = ptrn;
    191        /* Precalculate which tables to use for each sample */
    192        entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no];
    193        entropy->cur_counts[sampn] = entropy->count_ptrs[compptr->dc_tbl_no];
    194      }
    195    }
    196  }
    197  entropy->num_input_ptrs = ptrn;
    198 
    199  /* Initialize bit buffer to empty */
    200  entropy->saved.put_buffer = 0;
    201  entropy->saved.put_bits = 0;
    202 
    203  /* Initialize restart stuff */
    204  entropy->restarts_to_go = cinfo->restart_interval;
    205  entropy->next_restart_num = 0;
    206 }
    207 
    208 
    209 /* Outputting bytes to the file */
    210 
    211 /* Emit a byte, taking 'action' if must suspend. */
    212 #define emit_byte(state, val, action) { \
    213  *(state)->next_output_byte++ = (JOCTET)(val); \
    214  if (--(state)->free_in_buffer == 0) \
    215    if (!dump_buffer(state)) \
    216      { action; } \
    217 }
    218 
    219 
    220 LOCAL(boolean)
    221 dump_buffer(working_state *state)
    222 /* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
    223 {
    224  struct jpeg_destination_mgr *dest = state->cinfo->dest;
    225 
    226  if (!(*dest->empty_output_buffer) (state->cinfo))
    227    return FALSE;
    228  /* After a successful buffer dump, must reset buffer pointers */
    229  state->next_output_byte = dest->next_output_byte;
    230  state->free_in_buffer = dest->free_in_buffer;
    231  return TRUE;
    232 }
    233 
    234 
    235 /* Outputting bits to the file */
    236 
    237 /* Only the right 24 bits of put_buffer are used; the valid bits are
    238 * left-justified in this part.  At most 16 bits can be passed to emit_bits
    239 * in one call, and we never retain more than 7 bits in put_buffer
    240 * between calls, so 24 bits are sufficient.
    241 */
    242 
    243 INLINE
    244 LOCAL(boolean)
    245 emit_bits(working_state *state, unsigned int code, int size)
    246 /* Emit some bits; return TRUE if successful, FALSE if must suspend */
    247 {
    248  /* This routine is heavily used, so it's worth coding tightly. */
    249  register size_t put_buffer = (size_t)code;
    250  register int put_bits = state->cur.put_bits;
    251 
    252  /* if size is 0, caller used an invalid Huffman table entry */
    253  if (size == 0)
    254    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
    255 
    256  put_buffer &= (((size_t)1) << size) - 1; /* mask off any extra bits in code */
    257 
    258  put_bits += size;             /* new number of bits in buffer */
    259 
    260  put_buffer <<= 24 - put_bits; /* align incoming bits */
    261 
    262  put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
    263 
    264  while (put_bits >= 8) {
    265    int c = (int)((put_buffer >> 16) & 0xFF);
    266 
    267    emit_byte(state, c, return FALSE);
    268    if (c == 0xFF) {            /* need to stuff a zero byte? */
    269      emit_byte(state, 0, return FALSE);
    270    }
    271    put_buffer <<= 8;
    272    put_bits -= 8;
    273  }
    274 
    275  state->cur.put_buffer = put_buffer; /* update state variables */
    276  state->cur.put_bits = put_bits;
    277 
    278  return TRUE;
    279 }
    280 
    281 
    282 LOCAL(boolean)
    283 flush_bits(working_state *state)
    284 {
    285  if (!emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
    286    return FALSE;
    287  state->cur.put_buffer = 0;    /* and reset bit-buffer to empty */
    288  state->cur.put_bits = 0;
    289  return TRUE;
    290 }
    291 
    292 
    293 /*
    294 * Emit a restart marker & resynchronize predictions.
    295 */
    296 
    297 LOCAL(boolean)
    298 emit_restart(working_state *state, int restart_num)
    299 {
    300  if (!flush_bits(state))
    301    return FALSE;
    302 
    303  emit_byte(state, 0xFF, return FALSE);
    304  emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
    305 
    306  /* The restart counter is not updated until we successfully write the MCU. */
    307 
    308  return TRUE;
    309 }
    310 
    311 
    312 /*
    313 * Encode and output nMCU MCUs' worth of Huffman-compressed differences.
    314 */
    315 
    316 METHODDEF(JDIMENSION)
    317 encode_mcus_huff(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
    318                 JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
    319                 JDIMENSION nMCU)
    320 {
    321  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
    322  working_state state;
    323  int sampn, ci, yoffset, MCU_width, ptrn;
    324  JDIMENSION mcu_num;
    325 
    326  /* Load up working state */
    327  state.next_output_byte = cinfo->dest->next_output_byte;
    328  state.free_in_buffer = cinfo->dest->free_in_buffer;
    329  state.cur = entropy->saved;
    330  state.cinfo = cinfo;
    331 
    332  /* Emit restart marker if needed */
    333  if (cinfo->restart_interval) {
    334    if (entropy->restarts_to_go == 0)
    335      if (!emit_restart(&state, entropy->next_restart_num))
    336        return 0;
    337  }
    338 
    339  /* Set input pointer locations based on MCU_col_num */
    340  for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
    341    ci = entropy->input_ptr_info[ptrn].ci;
    342    yoffset = entropy->input_ptr_info[ptrn].yoffset;
    343    MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
    344    entropy->input_ptr[ptrn] =
    345      diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
    346  }
    347 
    348  for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
    349 
    350    /* Inner loop handles the samples in the MCU */
    351    for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
    352      register int temp, temp2;
    353      register int nbits;
    354      c_derived_tbl *dctbl = entropy->cur_tbls[sampn];
    355 
    356      /* Encode the difference per section H.1.2.2 */
    357 
    358      /* Input the sample difference */
    359      temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
    360 
    361      if (temp & 0x8000) {      /* instead of temp < 0 */
    362        temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
    363        if (temp == 0)          /* special case: magnitude = 32768 */
    364          temp2 = temp = 0x8000;
    365        temp2 = ~temp;          /* one's complement of magnitude */
    366      } else {
    367        temp &= 0x7FFF;         /* abs value mod 2^16 */
    368        temp2 = temp;           /* magnitude */
    369      }
    370 
    371      /* Find the number of bits needed for the magnitude of the difference */
    372      nbits = 0;
    373      while (temp) {
    374        nbits++;
    375        temp >>= 1;
    376      }
    377      /* Check for out-of-range difference values.
    378       */
    379      if (nbits > MAX_DIFF_BITS)
    380        ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    381 
    382      /* Emit the Huffman-coded symbol for the number of bits */
    383      if (!emit_bits(&state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
    384        return mcu_num;
    385 
    386      /* Emit that number of bits of the value, if positive, */
    387      /* or the complement of its magnitude, if negative. */
    388      if (nbits &&              /* emit_bits rejects calls with size 0 */
    389          nbits != 16)          /* special case: no bits should be emitted */
    390        if (!emit_bits(&state, (unsigned int)temp2, nbits))
    391          return mcu_num;
    392    }
    393 
    394    /* Completed MCU, so update state */
    395    cinfo->dest->next_output_byte = state.next_output_byte;
    396    cinfo->dest->free_in_buffer = state.free_in_buffer;
    397    entropy->saved = state.cur;
    398 
    399    /* Update restart-interval state too */
    400    if (cinfo->restart_interval) {
    401      if (entropy->restarts_to_go == 0) {
    402        entropy->restarts_to_go = cinfo->restart_interval;
    403        entropy->next_restart_num++;
    404        entropy->next_restart_num &= 7;
    405      }
    406      entropy->restarts_to_go--;
    407    }
    408 
    409  }
    410 
    411  return nMCU;
    412 }
    413 
    414 
    415 /*
    416 * Finish up at the end of a Huffman-compressed scan.
    417 */
    418 
    419 METHODDEF(void)
    420 finish_pass_huff(j_compress_ptr cinfo)
    421 {
    422  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
    423  working_state state;
    424 
    425  /* Load up working state ... flush_bits needs it */
    426  state.next_output_byte = cinfo->dest->next_output_byte;
    427  state.free_in_buffer = cinfo->dest->free_in_buffer;
    428  state.cur = entropy->saved;
    429  state.cinfo = cinfo;
    430 
    431  /* Flush out the last data */
    432  if (!flush_bits(&state))
    433    ERREXIT(cinfo, JERR_CANT_SUSPEND);
    434 
    435  /* Update state */
    436  cinfo->dest->next_output_byte = state.next_output_byte;
    437  cinfo->dest->free_in_buffer = state.free_in_buffer;
    438  entropy->saved = state.cur;
    439 }
    440 
    441 
    442 /*
    443 * Huffman coding optimization.
    444 *
    445 * We first scan the supplied data and count the number of uses of each symbol
    446 * that is to be Huffman-coded. (This process MUST agree with the code above.)
    447 * Then we build a Huffman coding tree for the observed counts.
    448 * Symbols which are not needed at all for the particular image are not
    449 * assigned any code, which saves space in the DHT marker as well as in
    450 * the compressed data.
    451 */
    452 
    453 #ifdef ENTROPY_OPT_SUPPORTED
    454 
    455 /*
    456 * Trial-encode nMCU MCUs' worth of Huffman-compressed differences.
    457 * No data is actually output, so no suspension return is possible.
    458 */
    459 
    460 METHODDEF(JDIMENSION)
    461 encode_mcus_gather(j_compress_ptr cinfo, JDIFFIMAGE diff_buf,
    462                   JDIMENSION MCU_row_num, JDIMENSION MCU_col_num,
    463                   JDIMENSION nMCU)
    464 {
    465  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
    466  int sampn, ci, yoffset, MCU_width, ptrn;
    467  JDIMENSION mcu_num;
    468 
    469  /* Take care of restart intervals if needed */
    470  if (cinfo->restart_interval) {
    471    if (entropy->restarts_to_go == 0) {
    472      /* Update restart state */
    473      entropy->restarts_to_go = cinfo->restart_interval;
    474    }
    475    entropy->restarts_to_go--;
    476  }
    477 
    478  /* Set input pointer locations based on MCU_col_num */
    479  for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) {
    480    ci = entropy->input_ptr_info[ptrn].ci;
    481    yoffset = entropy->input_ptr_info[ptrn].yoffset;
    482    MCU_width = entropy->input_ptr_info[ptrn].MCU_width;
    483    entropy->input_ptr[ptrn] =
    484      diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width);
    485  }
    486 
    487  for (mcu_num = 0; mcu_num < nMCU; mcu_num++) {
    488 
    489    /* Inner loop handles the samples in the MCU */
    490    for (sampn = 0; sampn < cinfo->blocks_in_MCU; sampn++) {
    491      register int temp;
    492      register int nbits;
    493      long *counts = entropy->cur_counts[sampn];
    494 
    495      /* Encode the difference per section H.1.2.2 */
    496 
    497      /* Input the sample difference */
    498      temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++;
    499 
    500      if (temp & 0x8000) {      /* instead of temp < 0 */
    501        temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */
    502        if (temp == 0)          /* special case: magnitude = 32768 */
    503          temp = 0x8000;
    504      } else
    505        temp &= 0x7FFF;         /* abs value mod 2^16 */
    506 
    507      /* Find the number of bits needed for the magnitude of the difference */
    508      nbits = 0;
    509      while (temp) {
    510        nbits++;
    511        temp >>= 1;
    512      }
    513      /* Check for out-of-range difference values.
    514       */
    515      if (nbits > MAX_DIFF_BITS)
    516        ERREXIT(cinfo, JERR_BAD_DCT_COEF);
    517 
    518      /* Count the Huffman symbol for the number of bits */
    519      counts[nbits]++;
    520    }
    521  }
    522 
    523  return nMCU;
    524 }
    525 
    526 
    527 /*
    528 * Finish up a statistics-gathering pass and create the new Huffman tables.
    529 */
    530 
    531 METHODDEF(void)
    532 finish_pass_gather(j_compress_ptr cinfo)
    533 {
    534  lhuff_entropy_ptr entropy = (lhuff_entropy_ptr)cinfo->entropy;
    535  int ci, dctbl;
    536  jpeg_component_info *compptr;
    537  JHUFF_TBL **htblptr;
    538  boolean did_dc[NUM_HUFF_TBLS];
    539 
    540  /* It's important not to apply jpeg_gen_optimal_table more than once
    541   * per table, because it clobbers the input frequency counts!
    542   */
    543  memset(did_dc, 0, sizeof(did_dc));
    544 
    545  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
    546    compptr = cinfo->cur_comp_info[ci];
    547    dctbl = compptr->dc_tbl_no;
    548    if (!did_dc[dctbl]) {
    549      htblptr = &cinfo->dc_huff_tbl_ptrs[dctbl];
    550      if (*htblptr == NULL)
    551        *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
    552      jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[dctbl]);
    553      did_dc[dctbl] = TRUE;
    554    }
    555  }
    556 }
    557 
    558 
    559 #endif /* ENTROPY_OPT_SUPPORTED */
    560 
    561 
    562 /*
    563 * Module initialization routine for Huffman entropy encoding.
    564 */
    565 
    566 GLOBAL(void)
    567 jinit_lhuff_encoder(j_compress_ptr cinfo)
    568 {
    569  lhuff_entropy_ptr entropy;
    570  int i;
    571 
    572  entropy = (lhuff_entropy_ptr)
    573    (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
    574                                sizeof(lhuff_entropy_encoder));
    575  cinfo->entropy = (struct jpeg_entropy_encoder *)entropy;
    576  entropy->pub.start_pass = start_pass_lhuff;
    577 
    578  /* Mark tables unallocated */
    579  for (i = 0; i < NUM_HUFF_TBLS; i++) {
    580    entropy->derived_tbls[i] = NULL;
    581 #ifdef ENTROPY_OPT_SUPPORTED
    582    entropy->count_ptrs[i] = NULL;
    583 #endif
    584  }
    585 }
    586 
    587 #endif /* C_LOSSLESS_SUPPORTED */