tor-browser

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

bit_reader_utils.h (7708B)


      1 // Copyright 2010 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 // Boolean decoder
     11 //
     12 // Author: Skal (pascal.massimino@gmail.com)
     13 //         Vikas Arora (vikaas.arora@gmail.com)
     14 
     15 #ifndef WEBP_UTILS_BIT_READER_UTILS_H_
     16 #define WEBP_UTILS_BIT_READER_UTILS_H_
     17 
     18 #include <assert.h>
     19 #include <stddef.h>
     20 
     21 #ifdef _MSC_VER
     22 #include <stdlib.h>  // _byteswap_ulong
     23 #endif
     24 #include "src/dsp/cpu.h"
     25 #include "src/webp/types.h"
     26 
     27 // Warning! This macro triggers quite some MACRO wizardry around func signature!
     28 #if !defined(BITTRACE)
     29 #define BITTRACE 0    // 0 = off, 1 = print bits, 2 = print bytes
     30 #endif
     31 
     32 #if (BITTRACE > 0)
     33 struct VP8BitReader;
     34 extern void BitTrace(const struct VP8BitReader* const br, const char label[]);
     35 #define BT_TRACK(br) BitTrace(br, label)
     36 #define VP8Get(BR, L) VP8GetValue(BR, 1, L)
     37 #else
     38 #define BT_TRACK(br)
     39 // We'll REMOVE the 'const char label[]' from all signatures and calls (!!):
     40 #define VP8GetValue(BR, N, L) VP8GetValue(BR, N)
     41 #define VP8Get(BR, L) VP8GetValue(BR, 1, L)
     42 #define VP8GetSignedValue(BR, N, L) VP8GetSignedValue(BR, N)
     43 #define VP8GetBit(BR, P, L) VP8GetBit(BR, P)
     44 #define VP8GetBitAlt(BR, P, L) VP8GetBitAlt(BR, P)
     45 #define VP8GetSigned(BR, V, L) VP8GetSigned(BR, V)
     46 #endif
     47 
     48 #ifdef __cplusplus
     49 extern "C" {
     50 #endif
     51 
     52 // The Boolean decoder needs to maintain infinite precision on the 'value'
     53 // field. However, since 'range' is only 8bit, we only need an active window of
     54 // 8 bits for 'value". Left bits (MSB) gets zeroed and shifted away when
     55 // 'value' falls below 128, 'range' is updated, and fresh bits read from the
     56 // bitstream are brought in as LSB. To avoid reading the fresh bits one by one
     57 // (slow), we cache BITS of them ahead. The total of (BITS + 8) bits must fit
     58 // into a natural register (with type bit_t). To fetch BITS bits from bitstream
     59 // we use a type lbit_t.
     60 //
     61 // BITS can be any multiple of 8 from 8 to 56 (inclusive).
     62 // Pick values that fit natural register size.
     63 
     64 #if defined(__i386__) || defined(_M_IX86)      // x86 32bit
     65 #define BITS 24
     66 #elif defined(__x86_64__) || defined(_M_X64)   // x86 64bit
     67 #define BITS 56
     68 #elif defined(__arm__) || defined(_M_ARM)      // ARM
     69 #define BITS 24
     70 #elif WEBP_AARCH64                             // ARM 64bit
     71 #define BITS 56
     72 #elif defined(__mips__)                        // MIPS
     73 #define BITS 24
     74 #elif defined(__wasm__)                        // WASM
     75 #define BITS 56
     76 #else                                          // reasonable default
     77 #define BITS 24
     78 #endif
     79 
     80 //------------------------------------------------------------------------------
     81 // Derived types and constants:
     82 //   bit_t = natural register type for storing 'value' (which is BITS+8 bits)
     83 //   range_t = register for 'range' (which is 8bits only)
     84 
     85 #if (BITS > 24)
     86 typedef uint64_t bit_t;
     87 #else
     88 typedef uint32_t bit_t;
     89 #endif
     90 
     91 typedef uint32_t range_t;
     92 
     93 //------------------------------------------------------------------------------
     94 // Bitreader
     95 
     96 typedef struct VP8BitReader VP8BitReader;
     97 struct VP8BitReader {
     98  // boolean decoder  (keep the field ordering as is!)
     99  bit_t value;               // current value
    100  range_t range;             // current range minus 1. In [127, 254] interval.
    101  int bits;                  // number of valid bits left
    102  // read buffer
    103  const uint8_t* buf;        // next byte to be read
    104  const uint8_t* buf_end;    // end of read buffer
    105  const uint8_t* buf_max;    // max packed-read position on buffer
    106  int eof;                   // true if input is exhausted
    107 };
    108 
    109 // Initialize the bit reader and the boolean decoder.
    110 void VP8InitBitReader(VP8BitReader* const br,
    111                      const uint8_t* const start, size_t size);
    112 // Sets the working read buffer.
    113 void VP8BitReaderSetBuffer(VP8BitReader* const br,
    114                           const uint8_t* const start, size_t size);
    115 
    116 // Update internal pointers to displace the byte buffer by the
    117 // relative offset 'offset'.
    118 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset);
    119 
    120 // return the next value made of 'num_bits' bits
    121 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits, const char label[]);
    122 
    123 // return the next value with sign-extension.
    124 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits,
    125                          const char label[]);
    126 
    127 // bit_reader_inl.h will implement the following methods:
    128 //   static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob, ...)
    129 //   static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v, ...)
    130 // and should be included by the .c files that actually need them.
    131 // This is to avoid recompiling the whole library whenever this file is touched,
    132 // and also allowing platform-specific ad-hoc hacks.
    133 
    134 // -----------------------------------------------------------------------------
    135 // Bitreader for lossless format
    136 
    137 // maximum number of bits (inclusive) the bit-reader can handle:
    138 #define VP8L_MAX_NUM_BIT_READ 24
    139 
    140 #define VP8L_LBITS 64  // Number of bits prefetched (= bit-size of vp8l_val_t).
    141 #define VP8L_WBITS 32  // Minimum number of bytes ready after VP8LFillBitWindow.
    142 
    143 typedef uint64_t vp8l_val_t;  // right now, this bit-reader can only use 64bit.
    144 
    145 typedef struct {
    146  vp8l_val_t     val;        // pre-fetched bits
    147  const uint8_t* buf;        // input byte buffer
    148  size_t         len;        // buffer length
    149  size_t         pos;        // byte position in buf
    150  int            bit_pos;    // current bit-reading position in val
    151  int            eos;        // true if a bit was read past the end of buffer
    152 } VP8LBitReader;
    153 
    154 void VP8LInitBitReader(VP8LBitReader* const br,
    155                       const uint8_t* const start,
    156                       size_t length);
    157 
    158 //  Sets a new data buffer.
    159 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
    160                            const uint8_t* const buffer, size_t length);
    161 
    162 // Reads the specified number of bits from read buffer.
    163 // Flags an error in case end_of_stream or n_bits is more than the allowed limit
    164 // of VP8L_MAX_NUM_BIT_READ (inclusive).
    165 // Flags 'eos' if this read attempt is going to cross the read buffer.
    166 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
    167 
    168 // Return the prefetched bits, so they can be looked up.
    169 static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
    170  return (uint32_t)(br->val >> (br->bit_pos & (VP8L_LBITS - 1)));
    171 }
    172 
    173 // Returns true if there was an attempt at reading bit past the end of
    174 // the buffer. Doesn't set br->eos flag.
    175 static WEBP_INLINE int VP8LIsEndOfStream(const VP8LBitReader* const br) {
    176  assert(br->pos <= br->len);
    177  return br->eos || ((br->pos == br->len) && (br->bit_pos > VP8L_LBITS));
    178 }
    179 
    180 // For jumping over a number of bits in the bit stream when accessed with
    181 // VP8LPrefetchBits and VP8LFillBitWindow.
    182 // This function does *not* set br->eos, since it's speed-critical.
    183 // Use with extreme care!
    184 static WEBP_INLINE void VP8LSetBitPos(VP8LBitReader* const br, int val) {
    185  br->bit_pos = val;
    186 }
    187 
    188 // Advances the read buffer by 4 bytes to make room for reading next 32 bits.
    189 // Speed critical, but infrequent part of the code can be non-inlined.
    190 extern void VP8LDoFillBitWindow(VP8LBitReader* const br);
    191 static WEBP_INLINE void VP8LFillBitWindow(VP8LBitReader* const br) {
    192  if (br->bit_pos >= VP8L_WBITS) VP8LDoFillBitWindow(br);
    193 }
    194 
    195 #ifdef __cplusplus
    196 }    // extern "C"
    197 #endif
    198 
    199 #endif  // WEBP_UTILS_BIT_READER_UTILS_H_