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