From 4854b9754fd2cc6d7c19e29dcf059c16d567672e Mon Sep 17 00:00:00 2001 From: Jeff Schiller Date: Thu, 16 Feb 2023 20:31:51 -0800 Subject: [PATCH] Add better documentation for how MTL and LTM modes work for BitStream --- build/io/bitstream-def.js | 27 ++++++++++++++++++++++++++- io/bitstream-worker.js | 27 ++++++++++++++++++++++++++- io/bitstream.js | 27 ++++++++++++++++++++++++++- tests/io-bitstream.spec.js | 4 ++-- 4 files changed, 80 insertions(+), 5 deletions(-) diff --git a/build/io/bitstream-def.js b/build/io/bitstream-def.js index b2c4e90..f73ec97 100644 --- a/build/io/bitstream-def.js +++ b/build/io/bitstream-def.js @@ -18,12 +18,34 @@ * Note that this stream is optimized, and thus, will *NOT* throw an error if * the end of the stream is reached. Only use this in scenarios where you * already have all the bits you need. + * + * Bit reading always proceeds from the first byte in the buffer, to the + * second byte, and so on. The MTL flag controls which bit is considered + * first *inside* the byte. + * + * An Example for how Most-To-Least vs Least-to-Most mode works: + * + * If you have an ArrayBuffer with the following two Uint8s: + * 185 (0b10111001) and 66 (0b01000010) + * and you perform a series of readBits: 2 bits, then 3, then 5, then 6. + * + * A BitStream in "mtl" mode will yield the following: + * - readBits(2) => 2 ('10') + * - readBits(3) => 7 ('111') + * - readBits(5) => 5 ('00101') + * - readBits(6) => 2 ('000010') + * + * A BitStream in "ltm" mode will yield the following: + * - readBits(2) => 1 ('01') + * - readBits(3) => 6 ('110') + * - readBits(5) => 21 ('10101') + * - readBits(6) => 16 ('010000') */ class BitStream { /** * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. * @param {boolean} mtl Whether the stream reads bits from the byte starting with the - * most-significant-bit (bit 7) to least-significant (bit 0). False means the direciton is + * most-significant-bit (bit 7) to least-significant (bit 0). False means the direction is * from least-significant-bit (bit 0) to most-significant (bit 7). * @param {Number} opt_offset The offset into the ArrayBuffer * @param {Number} opt_length The length of this BitStream @@ -69,6 +91,7 @@ /** * Returns how many bites have been read in the stream since the beginning of time. + * @returns {number} */ getNumBitsRead() { return this.bitsRead_; @@ -76,6 +99,7 @@ /** * Returns how many bits are currently in the stream left to be read. + * @returns {number} */ getNumBitsLeft() { const bitsLeftInByte = 8 - this.bitPtr; @@ -201,6 +225,7 @@ * Bit at (bytePtr,bitPtr) has the highest position in returning data. * Taken from getbits.hpp in unrar. * TODO: Move this out of BitStream and into unrar. + * @returns {number} */ getBits() { return (((((this.bytes[this.bytePtr] & 0xff) << 16) + diff --git a/io/bitstream-worker.js b/io/bitstream-worker.js index 8c1d787..f59a658 100644 --- a/io/bitstream-worker.js +++ b/io/bitstream-worker.js @@ -22,12 +22,34 @@ bitjs.io.BitStream = * Note that this stream is optimized, and thus, will *NOT* throw an error if * the end of the stream is reached. Only use this in scenarios where you * already have all the bits you need. + * + * Bit reading always proceeds from the first byte in the buffer, to the + * second byte, and so on. The MTL flag controls which bit is considered + * first *inside* the byte. + * + * An Example for how Most-To-Least vs Least-to-Most mode works: + * + * If you have an ArrayBuffer with the following two Uint8s: + * 185 (0b10111001) and 66 (0b01000010) + * and you perform a series of readBits: 2 bits, then 3, then 5, then 6. + * + * A BitStream in "mtl" mode will yield the following: + * - readBits(2) => 2 ('10') + * - readBits(3) => 7 ('111') + * - readBits(5) => 5 ('00101') + * - readBits(6) => 2 ('000010') + * + * A BitStream in "ltm" mode will yield the following: + * - readBits(2) => 1 ('01') + * - readBits(3) => 6 ('110') + * - readBits(5) => 21 ('10101') + * - readBits(6) => 16 ('010000') */ class BitStream { /** * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. * @param {boolean} mtl Whether the stream reads bits from the byte starting with the - * most-significant-bit (bit 7) to least-significant (bit 0). False means the direciton is + * most-significant-bit (bit 7) to least-significant (bit 0). False means the direction is * from least-significant-bit (bit 0) to most-significant (bit 7). * @param {Number} opt_offset The offset into the ArrayBuffer * @param {Number} opt_length The length of this BitStream @@ -73,6 +95,7 @@ bitjs.io.BitStream = /** * Returns how many bites have been read in the stream since the beginning of time. + * @returns {number} */ getNumBitsRead() { return this.bitsRead_; @@ -80,6 +103,7 @@ bitjs.io.BitStream = /** * Returns how many bits are currently in the stream left to be read. + * @returns {number} */ getNumBitsLeft() { const bitsLeftInByte = 8 - this.bitPtr; @@ -205,6 +229,7 @@ bitjs.io.BitStream = * Bit at (bytePtr,bitPtr) has the highest position in returning data. * Taken from getbits.hpp in unrar. * TODO: Move this out of BitStream and into unrar. + * @returns {number} */ getBits() { return (((((this.bytes[this.bytePtr] & 0xff) << 16) + diff --git a/io/bitstream.js b/io/bitstream.js index 67fa69e..b2eabd6 100644 --- a/io/bitstream.js +++ b/io/bitstream.js @@ -20,12 +20,34 @@ export const BitStream = * Note that this stream is optimized, and thus, will *NOT* throw an error if * the end of the stream is reached. Only use this in scenarios where you * already have all the bits you need. + * + * Bit reading always proceeds from the first byte in the buffer, to the + * second byte, and so on. The MTL flag controls which bit is considered + * first *inside* the byte. + * + * An Example for how Most-To-Least vs Least-to-Most mode works: + * + * If you have an ArrayBuffer with the following two Uint8s: + * 185 (0b10111001) and 66 (0b01000010) + * and you perform a series of readBits: 2 bits, then 3, then 5, then 6. + * + * A BitStream in "mtl" mode will yield the following: + * - readBits(2) => 2 ('10') + * - readBits(3) => 7 ('111') + * - readBits(5) => 5 ('00101') + * - readBits(6) => 2 ('000010') + * + * A BitStream in "ltm" mode will yield the following: + * - readBits(2) => 1 ('01') + * - readBits(3) => 6 ('110') + * - readBits(5) => 21 ('10101') + * - readBits(6) => 16 ('010000') */ class BitStream { /** * @param {ArrayBuffer} ab An ArrayBuffer object or a Uint8Array. * @param {boolean} mtl Whether the stream reads bits from the byte starting with the - * most-significant-bit (bit 7) to least-significant (bit 0). False means the direciton is + * most-significant-bit (bit 7) to least-significant (bit 0). False means the direction is * from least-significant-bit (bit 0) to most-significant (bit 7). * @param {Number} opt_offset The offset into the ArrayBuffer * @param {Number} opt_length The length of this BitStream @@ -71,6 +93,7 @@ export const BitStream = /** * Returns how many bites have been read in the stream since the beginning of time. + * @returns {number} */ getNumBitsRead() { return this.bitsRead_; @@ -78,6 +101,7 @@ export const BitStream = /** * Returns how many bits are currently in the stream left to be read. + * @returns {number} */ getNumBitsLeft() { const bitsLeftInByte = 8 - this.bitPtr; @@ -203,6 +227,7 @@ export const BitStream = * Bit at (bytePtr,bitPtr) has the highest position in returning data. * Taken from getbits.hpp in unrar. * TODO: Move this out of BitStream and into unrar. + * @returns {number} */ getBits() { return (((((this.bytes[this.bytePtr] & 0xff) << 16) + diff --git a/tests/io-bitstream.spec.js b/tests/io-bitstream.spec.js index aa5cfd9..d4f863d 100644 --- a/tests/io-bitstream.spec.js +++ b/tests/io-bitstream.spec.js @@ -20,7 +20,7 @@ describe('bitjs.io.BitStream', () => { }); it('BitPeekAndRead_RTL', () => { - const stream = new BitStream(array.buffer, true /* rtl */); + const stream = new BitStream(array.buffer, true /* mtl */); // 0110 = 2 + 4 = 6 expect(stream.readBits(4)).equals(6); // 0101 011 = 1 + 2 + 8 + 32 = 43 @@ -35,7 +35,7 @@ describe('bitjs.io.BitStream', () => { }); it('BitPeekAndRead_LTR', () => { - const stream = new BitStream(array.buffer, false /* rtl */); + const stream = new BitStream(array.buffer, false /* mtl */); // 0101 = 2 + 4 = 6 expect(stream.peekBits(4)).equals(5);