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@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 23void 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 33void 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 46void 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 54const 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 67const 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 86void 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 104uint32_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 112int32_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 129static 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 139void 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 163void 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 174static 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 180static 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 192void 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 211uint32_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