image-in-browser
Version:
Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)
113 lines • 4.04 kB
JavaScript
import { LibError } from '../../error/lib-error.js';
export class LzwDecoder {
constructor() {
this._buffer = new Uint8Array(4096);
this._bitsToGet = 9;
this._bytePointer = 0;
this._nextData = 0;
this._nextBits = 0;
}
addString(string, newString) {
this._table[this._tableIndex] = newString;
this._prefix[this._tableIndex] = string;
this._tableIndex = this._tableIndex + 1;
if (this._tableIndex === 511) {
this._bitsToGet = 10;
}
else if (this._tableIndex === 1023) {
this._bitsToGet = 11;
}
else if (this._tableIndex === 2047) {
this._bitsToGet = 12;
}
}
getString(code) {
this._bufferLength = 0;
let c = code;
this._buffer[this._bufferLength++] = this._table[c];
c = this._prefix[c];
while (c !== LzwDecoder._noSuchCode) {
this._buffer[this._bufferLength++] = this._table[c];
c = this._prefix[c];
}
}
getNextCode() {
if (this._bytePointer >= this._dataLength) {
return 257;
}
while (this._nextBits < this._bitsToGet) {
if (this._bytePointer >= this._dataLength) {
return 257;
}
this._nextData =
((this._nextData << 8) + this._data[this._bytePointer++]) & 0xffffffff;
this._nextBits += 8;
}
this._nextBits -= this._bitsToGet;
const code = (this._nextData >>> this._nextBits) &
LzwDecoder._andTable[this._bitsToGet - 9];
return code;
}
initializeStringTable() {
this._table = new Uint8Array(LzwDecoder._lzMaxCode + 1);
this._prefix = new Uint32Array(LzwDecoder._lzMaxCode + 1);
this._prefix.fill(LzwDecoder._noSuchCode, 0, this._prefix.length);
for (let i = 0; i < 256; i++) {
this._table[i] = i;
}
this._bitsToGet = 9;
this._tableIndex = 258;
}
decode(p, out) {
this._out = out;
const outLen = out.length;
this._outPointer = 0;
this._data = p.buffer;
this._dataLength = this._data.length;
this._bytePointer = p.offset;
if (this._data[0] === 0x00 && this._data[1] === 0x01) {
throw new LibError('Invalid LZW Data');
}
this.initializeStringTable();
this._nextData = 0;
this._nextBits = 0;
let oldCode = 0;
let code = this.getNextCode();
while (code !== 257 && this._outPointer < outLen) {
if (code === 256) {
this.initializeStringTable();
code = this.getNextCode();
this._bufferLength = 0;
if (code === 257) {
break;
}
this._out[this._outPointer++] = code;
oldCode = code;
}
else {
if (code < this._tableIndex) {
this.getString(code);
for (let i = this._bufferLength - 1; i >= 0; --i) {
this._out[this._outPointer++] = this._buffer[i];
}
this.addString(oldCode, this._buffer[this._bufferLength - 1]);
oldCode = code;
}
else {
this.getString(oldCode);
for (let i = this._bufferLength - 1; i >= 0; --i) {
this._out[this._outPointer++] = this._buffer[i];
}
this._out[this._outPointer++] = this._buffer[this._bufferLength - 1];
this.addString(oldCode, this._buffer[this._bufferLength - 1]);
oldCode = code;
}
}
code = this.getNextCode();
}
}
}
LzwDecoder._lzMaxCode = 4095;
LzwDecoder._noSuchCode = 4098;
LzwDecoder._andTable = [511, 1023, 2047, 4095];
//# sourceMappingURL=tiff-lzw-decoder.js.map