blob: 84f1911423e98c16ae05aaa799357e525e37a2be [file] [log] [blame]
import 'dart:typed_data';
import '../../image_exception.dart';
import '../../util/input_buffer.dart';
class VP8LBitReader {
int bitPos = 0;
VP8LBitReader(this._input) {
_buffer8 = Uint8List.view(_buffer.buffer);
_buffer8[0] = _input.readByte();
_buffer8[1] = _input.readByte();
_buffer8[2] = _input.readByte();
_buffer8[3] = _input.readByte();
_buffer8[4] = _input.readByte();
_buffer8[5] = _input.readByte();
_buffer8[6] = _input.readByte();
_buffer8[7] = _input.readByte();
}
/// Return the prefetched bits, so they can be looked up.
int prefetchBits() {
int b2 = 0;
if (bitPos < 32) {
b2 = (_buffer[0] >> bitPos) +
((_buffer[1] & BIT_MASK[bitPos]) * (BIT_MASK[32 - bitPos] + 1));
} else if (bitPos == 32) {
b2 = _buffer[1];
} else {
b2 = _buffer[1] >> (bitPos - 32);
}
return b2;
}
bool get isEOS => (_input.isEOS && bitPos >= LBITS);
/// Advances the read buffer by 4 bytes to make room for reading next 32 bits.
void fillBitWindow() {
if (bitPos >= WBITS) {
_shiftBytes();
}
}
/// Reads the specified number of bits from Read Buffer.
int readBits(int numBits) {
// Flag an error if end_of_stream or n_bits is more than allowed limit.
if (!isEOS && numBits < MAX_NUM_BIT_READ) {
//final int value = (buffer >> bitPos) & BIT_MASK[numBits];
final int value = prefetchBits() & BIT_MASK[numBits];
bitPos += numBits;
_shiftBytes();
return value;
} else {
throw new ImageException('Not enough data in input.');
}
}
/// If not at EOS, reload up to LBITS byte-by-byte
void _shiftBytes() {
while (bitPos >= 8 && !_input.isEOS) {
int b = _input.readByte();
// buffer >>= 8
_buffer[0] = (_buffer[0] >> 8) + ((_buffer[1] & 0xff) * 0x1000000);
_buffer[1] >>= 8;
// buffer |= b << (LBITS - 8)
_buffer[1] |= b * 0x1000000;
bitPos -= 8;
}
}
InputBuffer _input;
Uint32List _buffer = Uint32List(2);
Uint8List _buffer8;
/// The number of bytes used for the bit buffer.
static const int VALUE_SIZE = 8;
static const int MAX_NUM_BIT_READ = 25;
/// Number of bits prefetched.
static const int LBITS = 64;
/// Minimum number of bytes needed after fillBitWindow.
static const int WBITS = 32;
/// Number of bytes needed to store WBITS bits.
static const int LOG8_WBITS = 4;
static const List<int> BIT_MASK = const [
0,
1,
3,
7,
15,
31,
63,
127,
255,
511,
1023,
2047,
4095,
8191,
16383,
32767,
65535,
131071,
262143,
524287,
1048575,
2097151,
4194303,
8388607,
16777215,
33554431,
67108863,
134217727,
268435455,
536870911,
1073741823,
2147483647,
4294967295
];
}