mdx-m3-viewer
Version:
A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.
77 lines (64 loc) • 1.8 kB
text/typescript
/**
* A bit stream.
*/
export default class BitStream {
buffer: ArrayBuffer;
uint8array: Uint8Array;
index: number = 0;
byteLength: number;
bitBuffer: number = 0;
bits: number = 0;
constructor(buffer: ArrayBuffer | TypedArray, byteOffset?: number, byteLength?: number) {
// If given a view, use its properties.
if (ArrayBuffer.isView(buffer)) {
byteOffset = buffer.byteOffset;
byteLength = buffer.byteLength;
buffer = buffer.buffer;
}
if (!(buffer instanceof ArrayBuffer)) {
throw new TypeError(`BitStream: expected ArrayBuffer or TypedArray, got ${buffer}`);
}
// For browsers not supporting the spec.
// Once upon a time I reported this issue on the Firefox tracker.
// Seems like Safari needs an issue report too.
byteOffset = byteOffset || 0;
byteLength = byteLength || buffer.byteLength;
this.buffer = buffer;
this.uint8array = new Uint8Array(buffer, byteOffset, byteLength);
this.byteLength = buffer.byteLength;
}
/**
* Peek a number of bits.
*/
peekBits(bits: number) {
this.loadBits(bits);
return this.bitBuffer & ((1 << bits) - 1);
}
/**
* Read a number of bits.
*/
readBits(bits: number) {
let data = this.peekBits(bits);
this.bitBuffer >>>= bits;
this.bits -= bits;
return data;
}
/**
* Skip a number of bits.
*/
skipBits(bits: number) {
this.loadBits(bits);
this.bitBuffer >>>= bits;
this.bits -= bits;
}
/**
* Load more bits into the buffer.
*/
loadBits(bits: number) {
while (this.bits < bits) {
this.bitBuffer += this.uint8array[this.index] << this.bits;
this.bits += 8;
this.index += 1;
}
}
}