Home | History | Annotate | Download | only in utils
      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 non-inlined methods
     11 //
     12 // Author: Skal (pascal.massimino (at) gmail.com)
     13 
     14 #ifdef HAVE_CONFIG_H
     15 #include "../webp/config.h"
     16 #endif
     17 
     18 #include "./bit_reader_inl_utils.h"
     19 #include "../utils/utils.h"
     20 
     21 //------------------------------------------------------------------------------
     22 // VP8BitReader
     23 
     24 void VP8BitReaderSetBuffer(VP8BitReader* const br,
     25                            const uint8_t* const start,
     26                            size_t size) {
     27   br->buf_     = start;
     28   br->buf_end_ = start + size;
     29   br->buf_max_ =
     30       (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
     31                                : start;
     32 }
     33 
     34 void VP8InitBitReader(VP8BitReader* const br,
     35                       const uint8_t* const start, size_t size) {
     36   assert(br != NULL);
     37   assert(start != NULL);
     38   assert(size < (1u << 31));   // limit ensured by format and upstream checks
     39   br->range_   = 255 - 1;
     40   br->value_   = 0;
     41   br->bits_    = -8;   // to load the very first 8bits
     42   br->eof_     = 0;
     43   VP8BitReaderSetBuffer(br, start, size);
     44   VP8LoadNewBytes(br);
     45 }
     46 
     47 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
     48   if (br->buf_ != NULL) {
     49     br->buf_ += offset;
     50     br->buf_end_ += offset;
     51     br->buf_max_ += offset;
     52   }
     53 }
     54 
     55 const uint8_t kVP8Log2Range[128] = {
     56      7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
     57   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     58   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     59   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     60   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     61   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     62   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     63   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     64   0
     65 };
     66 
     67 // range = ((range - 1) << kVP8Log2Range[range]) + 1
     68 const uint8_t kVP8NewRange[128] = {
     69   127, 127, 191, 127, 159, 191, 223, 127,
     70   143, 159, 175, 191, 207, 223, 239, 127,
     71   135, 143, 151, 159, 167, 175, 183, 191,
     72   199, 207, 215, 223, 231, 239, 247, 127,
     73   131, 135, 139, 143, 147, 151, 155, 159,
     74   163, 167, 171, 175, 179, 183, 187, 191,
     75   195, 199, 203, 207, 211, 215, 219, 223,
     76   227, 231, 235, 239, 243, 247, 251, 127,
     77   129, 131, 133, 135, 137, 139, 141, 143,
     78   145, 147, 149, 151, 153, 155, 157, 159,
     79   161, 163, 165, 167, 169, 171, 173, 175,
     80   177, 179, 181, 183, 185, 187, 189, 191,
     81   193, 195, 197, 199, 201, 203, 205, 207,
     82   209, 211, 213, 215, 217, 219, 221, 223,
     83   225, 227, 229, 231, 233, 235, 237, 239,
     84   241, 243, 245, 247, 249, 251, 253, 127
     85 };
     86 
     87 void VP8LoadFinalBytes(VP8BitReader* const br) {
     88   assert(br != NULL && br->buf_ != NULL);
     89   // Only read 8bits at a time
     90   if (br->buf_ < br->buf_end_) {
     91     br->bits_ += 8;
     92     br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
     93   } else if (!br->eof_) {
     94     br->value_ <<= 8;
     95     br->bits_ += 8;
     96     br->eof_ = 1;
     97   } else {
     98     br->bits_ = 0;  // This is to avoid undefined behaviour with shifts.
     99   }
    100 }
    101 
    102 //------------------------------------------------------------------------------
    103 // Higher-level calls
    104 
    105 uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
    106   uint32_t v = 0;
    107   while (bits-- > 0) {
    108     v |= VP8GetBit(br, 0x80) << bits;
    109   }
    110   return v;
    111 }
    112 
    113 int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
    114   const int value = VP8GetValue(br, bits);
    115   return VP8Get(br) ? -value : value;
    116 }
    117 
    118 //------------------------------------------------------------------------------
    119 // VP8LBitReader
    120 
    121 #define VP8L_LOG8_WBITS 4  // Number of bytes needed to store VP8L_WBITS bits.
    122 
    123 #if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
    124     defined(__i386__) || defined(_M_IX86) || \
    125     defined(__x86_64__) || defined(_M_X64)
    126 #define VP8L_USE_FAST_LOAD
    127 #endif
    128 
    129 static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = {
    130   0,
    131   0x000001, 0x000003, 0x000007, 0x00000f,
    132   0x00001f, 0x00003f, 0x00007f, 0x0000ff,
    133   0x0001ff, 0x0003ff, 0x0007ff, 0x000fff,
    134   0x001fff, 0x003fff, 0x007fff, 0x00ffff,
    135   0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,
    136   0x1fffff, 0x3fffff, 0x7fffff, 0xffffff
    137 };
    138 
    139 void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start,
    140                        size_t length) {
    141   size_t i;
    142   vp8l_val_t value = 0;
    143   assert(br != NULL);
    144   assert(start != NULL);
    145   assert(length < 0xfffffff8u);   // can't happen with a RIFF chunk.
    146 
    147   br->len_ = length;
    148   br->val_ = 0;
    149   br->bit_pos_ = 0;
    150   br->eos_ = 0;
    151 
    152   if (length > sizeof(br->val_)) {
    153     length = sizeof(br->val_);
    154   }
    155   for (i = 0; i < length; ++i) {
    156     value |= (vp8l_val_t)start[i] << (8 * i);
    157   }
    158   br->val_ = value;
    159   br->pos_ = length;
    160   br->buf_ = start;
    161 }
    162 
    163 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
    164                             const uint8_t* const buf, size_t len) {
    165   assert(br != NULL);
    166   assert(buf != NULL);
    167   assert(len < 0xfffffff8u);   // can't happen with a RIFF chunk.
    168   br->buf_ = buf;
    169   br->len_ = len;
    170   // pos_ > len_ should be considered a param error.
    171   br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
    172 }
    173 
    174 static void VP8LSetEndOfStream(VP8LBitReader* const br) {
    175   br->eos_ = 1;
    176   br->bit_pos_ = 0;  // To avoid undefined behaviour with shifts.
    177 }
    178 
    179 // If not at EOS, reload up to VP8L_LBITS byte-by-byte
    180 static void ShiftBytes(VP8LBitReader* const br) {
    181   while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
    182     br->val_ >>= 8;
    183     br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
    184     ++br->pos_;
    185     br->bit_pos_ -= 8;
    186   }
    187   if (VP8LIsEndOfStream(br)) {
    188     VP8LSetEndOfStream(br);
    189   }
    190 }
    191 
    192 void VP8LDoFillBitWindow(VP8LBitReader* const br) {
    193   assert(br->bit_pos_ >= VP8L_WBITS);
    194 #if defined(VP8L_USE_FAST_LOAD)
    195   if (br->pos_ + sizeof(br->val_) < br->len_) {
    196     br->val_ >>= VP8L_WBITS;
    197     br->bit_pos_ -= VP8L_WBITS;
    198     br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) <<
    199                 (VP8L_LBITS - VP8L_WBITS);
    200     br->pos_ += VP8L_LOG8_WBITS;
    201     return;
    202   }
    203 #endif
    204   ShiftBytes(br);       // Slow path.
    205 }
    206 
    207 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
    208   assert(n_bits >= 0);
    209   // Flag an error if end_of_stream or n_bits is more than allowed limit.
    210   if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
    211     const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
    212     const int new_bits = br->bit_pos_ + n_bits;
    213     br->bit_pos_ = new_bits;
    214     ShiftBytes(br);
    215     return val;
    216   } else {
    217     VP8LSetEndOfStream(br);
    218     return 0;
    219   }
    220 }
    221 
    222 //------------------------------------------------------------------------------
    223