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.h"
     19 
     20 //------------------------------------------------------------------------------
     21 // VP8BitReader
     22 
     23 void VP8BitReaderSetBuffer(VP8BitReader* const br,
     24                            const uint8_t* const start,
     25                            size_t size) {
     26   br->buf_     = start;
     27   br->buf_end_ = start + size;
     28   br->buf_max_ =
     29       (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
     30                                : start;
     31 }
     32 
     33 void VP8InitBitReader(VP8BitReader* const br,
     34                       const uint8_t* const start, size_t size) {
     35   assert(br != NULL);
     36   assert(start != NULL);
     37   assert(size < (1u << 31));   // limit ensured by format and upstream checks
     38   br->range_   = 255 - 1;
     39   br->value_   = 0;
     40   br->bits_    = -8;   // to load the very first 8bits
     41   br->eof_     = 0;
     42   VP8BitReaderSetBuffer(br, start, size);
     43   VP8LoadNewBytes(br);
     44 }
     45 
     46 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
     47   if (br->buf_ != NULL) {
     48     br->buf_ += offset;
     49     br->buf_end_ += offset;
     50     br->buf_max_ += offset;
     51   }
     52 }
     53 
     54 const uint8_t kVP8Log2Range[128] = {
     55      7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
     56   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     57   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     58   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     59   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     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   0
     64 };
     65 
     66 // range = ((range - 1) << kVP8Log2Range[range]) + 1
     67 const uint8_t kVP8NewRange[128] = {
     68   127, 127, 191, 127, 159, 191, 223, 127,
     69   143, 159, 175, 191, 207, 223, 239, 127,
     70   135, 143, 151, 159, 167, 175, 183, 191,
     71   199, 207, 215, 223, 231, 239, 247, 127,
     72   131, 135, 139, 143, 147, 151, 155, 159,
     73   163, 167, 171, 175, 179, 183, 187, 191,
     74   195, 199, 203, 207, 211, 215, 219, 223,
     75   227, 231, 235, 239, 243, 247, 251, 127,
     76   129, 131, 133, 135, 137, 139, 141, 143,
     77   145, 147, 149, 151, 153, 155, 157, 159,
     78   161, 163, 165, 167, 169, 171, 173, 175,
     79   177, 179, 181, 183, 185, 187, 189, 191,
     80   193, 195, 197, 199, 201, 203, 205, 207,
     81   209, 211, 213, 215, 217, 219, 221, 223,
     82   225, 227, 229, 231, 233, 235, 237, 239,
     83   241, 243, 245, 247, 249, 251, 253, 127
     84 };
     85 
     86 void VP8LoadFinalBytes(VP8BitReader* const br) {
     87   assert(br != NULL && br->buf_ != NULL);
     88   // Only read 8bits at a time
     89   if (br->buf_ < br->buf_end_) {
     90     br->bits_ += 8;
     91     br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
     92   } else if (!br->eof_) {
     93     br->value_ <<= 8;
     94     br->bits_ += 8;
     95     br->eof_ = 1;
     96   } else {
     97     br->bits_ = 0;  // This is to avoid undefined behaviour with shifts.
     98   }
     99 }
    100 
    101 //------------------------------------------------------------------------------
    102 // Higher-level calls
    103 
    104 uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
    105   uint32_t v = 0;
    106   while (bits-- > 0) {
    107     v |= VP8GetBit(br, 0x80) << bits;
    108   }
    109   return v;
    110 }
    111 
    112 int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
    113   const int value = VP8GetValue(br, bits);
    114   return VP8Get(br) ? -value : value;
    115 }
    116 
    117 //------------------------------------------------------------------------------
    118 // VP8LBitReader
    119 
    120 #define VP8L_LOG8_WBITS 4  // Number of bytes needed to store VP8L_WBITS bits.
    121 
    122 #if !defined(WEBP_FORCE_ALIGNED) && \
    123     (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
    124      defined(__i386__) || defined(_M_IX86) || \
    125      defined(__x86_64__) || defined(_M_X64))
    126 #define VP8L_USE_UNALIGNED_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   // TODO(jzern): given the fixed read size it may be possible to force
    195   //              alignment in this block.
    196 #if defined(VP8L_USE_UNALIGNED_LOAD)
    197   if (br->pos_ + sizeof(br->val_) < br->len_) {
    198     br->val_ >>= VP8L_WBITS;
    199     br->bit_pos_ -= VP8L_WBITS;
    200     // The expression below needs a little-endian arch to work correctly.
    201     // This gives a large speedup for decoding speed.
    202     br->val_ |= (vp8l_val_t)WebPMemToUint32(br->buf_ + br->pos_) <<
    203                 (VP8L_LBITS - VP8L_WBITS);
    204     br->pos_ += VP8L_LOG8_WBITS;
    205     return;
    206   }
    207 #endif
    208   ShiftBytes(br);       // Slow path.
    209 }
    210 
    211 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
    212   assert(n_bits >= 0);
    213   // Flag an error if end_of_stream or n_bits is more than allowed limit.
    214   if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
    215     const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
    216     const int new_bits = br->bit_pos_ + n_bits;
    217     br->bit_pos_ = new_bits;
    218     ShiftBytes(br);
    219     return val;
    220   } else {
    221     VP8LSetEndOfStream(br);
    222     return 0;
    223   }
    224 }
    225 
    226 //------------------------------------------------------------------------------
    227