1
0
Fork 0
mirror of https://github.com/codedread/bitjs synced 2025-10-03 09:39:16 +02:00

Updates to jsdoc for better IDE analysis. A couple other minor tweaks.

This commit is contained in:
Jeff Schiller 2021-12-12 11:01:41 -08:00
parent 843caf4e61
commit 2a90e32c89
7 changed files with 69 additions and 18 deletions

View file

@ -72,7 +72,6 @@ const BIT = [0x01, 0x02, 0x04, 0x08,
0x100, 0x200, 0x400, 0x800,
0x1000, 0x2000, 0x4000, 0x8000];
class ZipLocalFile {
// takes a ByteStream and parses out the local file information
constructor(bstream) {
@ -209,9 +208,18 @@ class ZipLocalFile {
}
}
// returns a table of Huffman codes
// each entry's index is its code and its value is a JavaScript object
// containing {length: 6, symbol: X}
/**
* @typedef SymbolLengthPair
* @property {number} length
* @property {number} symbol
*/
/**
* Returns a table of Huffman codes. Each entry's key is its code and its value is a JavaScript
* object containing {length: 6, symbol: X}.
* @param {number[]} bitLengths
* @returns {Map<number, SymbolLengthPair>}
*/
function getHuffmanCodes(bitLengths) {
// ensure bitLengths is an array containing at least one element
if (typeof bitLengths != typeof [] || bitLengths.length < 1) {
@ -251,6 +259,7 @@ function getHuffmanCodes(bitLengths) {
}
// Step 3: Assign numerical values to all codes
/** @type Map<number, SymbolLengthPair> */
const table = new Map();
for (let n = 0; n < numLengths; ++n) {
const len = bitLengths[n];
@ -282,6 +291,7 @@ function getHuffmanCodes(bitLengths) {
// fixed Huffman codes go from 7-9 bits, so we need an array whose index can hold up to 9 bits
let fixedHCtoLiteral = null;
let fixedHCtoDistance = null;
/** @returns {Map<number, SymbolLengthPair>} */
function getFixedLiteralTable() {
// create once
if (!fixedHCtoLiteral) {
@ -297,6 +307,7 @@ function getFixedLiteralTable() {
return fixedHCtoLiteral;
}
/** @returns {Map<number, SymbolLengthPair>} */
function getFixedDistanceTable() {
// create once
if (!fixedHCtoDistance) {
@ -309,8 +320,13 @@ function getFixedDistanceTable() {
return fixedHCtoDistance;
}
// extract one bit at a time until we find a matching Huffman Code
// then return that symbol
/**
* Extract one bit at a time until we find a matching Huffman Code
* then return that symbol.
* @param {bitjs.io.BitStream} bstream
* @param {Map<number, SymbolLengthPair>} hcTable
* @returns {number}
*/
function decodeSymbol(bstream, hcTable) {
let code = 0;
let len = 0;
@ -326,7 +342,7 @@ function decodeSymbol(bstream, hcTable) {
if (hcTable.has(code) && hcTable.get(code).length == len) {
break;
}
if (len > hcTable.maxLength) {
if (len > hcTable.length) {
err(`Bit stream out of sync, didn't find a Huffman Code, length was ${len} ` +
`and table only max code length of ${hcTable.length}`);
break;
@ -396,6 +412,13 @@ const DistLookupTable = [
[13, 16385], [13, 24577]
];
/**
* @param {bitjs.io.BitStream} bstream
* @param {Map<number, SymbolLengthPair>} hcLiteralTable
* @param {Map<number, SymbolLengthPair>} hcDistanceTable
* @param {bitjs.io.ByteBuffer} buffer
* @returns
*/
function inflateBlockData(bstream, hcLiteralTable, hcDistanceTable, buffer) {
/*
loop (until end of block code recognized)
@ -412,11 +435,9 @@ function inflateBlockData(bstream, hcLiteralTable, hcDistanceTable, buffer) {
stream, and copy length bytes from this
position to the output stream.
*/
let numSymbols = 0;
let blockSize = 0;
for (; ;) {
const symbol = decodeSymbol(bstream, hcLiteralTable);
++numSymbols;
if (symbol < 256) {
// copy literal byte to output
buffer.insertByte(symbol);
@ -458,15 +479,20 @@ function inflateBlockData(bstream, hcLiteralTable, hcDistanceTable, buffer) {
return blockSize;
}
// {Uint8Array} compressedData A Uint8Array of the compressed file data.
// compression method 8
// deflate: http://tools.ietf.org/html/rfc1951
/**
* Compression method 8. Deflate: http://tools.ietf.org/html/rfc1951
* @param {Uint8Array} compressedData A Uint8Array of the compressed file data.
* @param {number} numDecompressedBytes
* @returns {Uint8Array} The decompressed array.
*/
function inflate(compressedData, numDecompressedBytes) {
// Bit stream representing the compressed data.
/** @type {bitjs.io.BitStream} */
const bstream = new bitjs.io.BitStream(compressedData.buffer,
false /* rtl */,
compressedData.byteOffset,
compressedData.byteLength);
/** @type {bitjs.io.ByteBuffer} */
const buffer = new bitjs.io.ByteBuffer(numDecompressedBytes);
let blockSize = 0;
@ -523,17 +549,18 @@ function inflate(compressedData, numDecompressedBytes) {
// and distance tables together
const literalCodeLengths = [];
let prevCodeLength = 0;
while (literalCodeLengths.length < numLiteralLengthCodes + numDistanceCodes) {
const maxCodeLengths = numLiteralLengthCodes + numDistanceCodes;
while (literalCodeLengths.length < maxCodeLengths) {
const symbol = decodeSymbol(bstream, codeLengthsCodes);
if (symbol <= 15) {
literalCodeLengths.push(symbol);
prevCodeLength = symbol;
} else if (symbol == 16) {
} else if (symbol === 16) {
let repeat = bstream.readBits(2) + 3;
while (repeat--) {
literalCodeLengths.push(prevCodeLength);
}
} else if (symbol == 17) {
} else if (symbol === 17) {
let repeat = bstream.readBits(3) + 3;
while (repeat--) {
literalCodeLengths.push(0);

View file

@ -1,4 +1,4 @@
OUT_PATH=/out/io
OUT_PATH=../../io
BITSTREAM_MODULE=${OUT_PATH}/bitstream.js
BITSTREAM_WORKER=${OUT_PATH}/bitstream-worker.js

View file

@ -21,7 +21,15 @@
if (typeof numBytes != typeof 1 || numBytes <= 0) {
throw "Error! ByteBuffer initialized with '" + numBytes + "'";
}
/**
* @type {Uint8Array}
* @public
*/
this.data = new Uint8Array(numBytes);
/**
* @type {number}
* @public
*/
this.ptr = 0;
}

View file

@ -25,7 +25,15 @@ bitjs.io.ByteBuffer =
if (typeof numBytes != typeof 1 || numBytes <= 0) {
throw "Error! ByteBuffer initialized with '" + numBytes + "'";
}
/**
* @type {Uint8Array}
* @public
*/
this.data = new Uint8Array(numBytes);
/**
* @type {number}
* @public
*/
this.ptr = 0;
}

View file

@ -23,7 +23,15 @@ export const ByteBuffer =
if (typeof numBytes != typeof 1 || numBytes <= 0) {
throw "Error! ByteBuffer initialized with '" + numBytes + "'";
}
/**
* @type {Uint8Array}
* @public
*/
this.data = new Uint8Array(numBytes);
/**
* @type {number}
* @public
*/
this.ptr = 0;
}