Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/libwebp/src/utils/bit_reader_utils.c
16358 views
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 ([email protected])
13
14
#ifdef HAVE_CONFIG_H
15
#include "src/webp/config.h"
16
#endif
17
18
#include "src/utils/bit_reader_inl_utils.h"
19
#include "src/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
224