1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | "use strict";
|
23 |
|
24 | Object.defineProperty(exports, "__esModule", {
|
25 | value: true
|
26 | });
|
27 | exports.LZWStream = void 0;
|
28 |
|
29 | var _decode_stream = require("./decode_stream.js");
|
30 |
|
31 | class LZWStream extends _decode_stream.DecodeStream {
|
32 | constructor(str, maybeLength, earlyChange) {
|
33 | super(maybeLength);
|
34 | this.str = str;
|
35 | this.dict = str.dict;
|
36 | this.cachedData = 0;
|
37 | this.bitsCached = 0;
|
38 | const maxLzwDictionarySize = 4096;
|
39 | const lzwState = {
|
40 | earlyChange,
|
41 | codeLength: 9,
|
42 | nextCode: 258,
|
43 | dictionaryValues: new Uint8Array(maxLzwDictionarySize),
|
44 | dictionaryLengths: new Uint16Array(maxLzwDictionarySize),
|
45 | dictionaryPrevCodes: new Uint16Array(maxLzwDictionarySize),
|
46 | currentSequence: new Uint8Array(maxLzwDictionarySize),
|
47 | currentSequenceLength: 0
|
48 | };
|
49 |
|
50 | for (let i = 0; i < 256; ++i) {
|
51 | lzwState.dictionaryValues[i] = i;
|
52 | lzwState.dictionaryLengths[i] = 1;
|
53 | }
|
54 |
|
55 | this.lzwState = lzwState;
|
56 | }
|
57 |
|
58 | readBits(n) {
|
59 | let bitsCached = this.bitsCached;
|
60 | let cachedData = this.cachedData;
|
61 |
|
62 | while (bitsCached < n) {
|
63 | const c = this.str.getByte();
|
64 |
|
65 | if (c === -1) {
|
66 | this.eof = true;
|
67 | return null;
|
68 | }
|
69 |
|
70 | cachedData = cachedData << 8 | c;
|
71 | bitsCached += 8;
|
72 | }
|
73 |
|
74 | this.bitsCached = bitsCached -= n;
|
75 | this.cachedData = cachedData;
|
76 | this.lastCode = null;
|
77 | return cachedData >>> bitsCached & (1 << n) - 1;
|
78 | }
|
79 |
|
80 | readBlock() {
|
81 | const blockSize = 512,
|
82 | decodedSizeDelta = blockSize;
|
83 | let estimatedDecodedSize = blockSize * 2;
|
84 | let i, j, q;
|
85 | const lzwState = this.lzwState;
|
86 |
|
87 | if (!lzwState) {
|
88 | return;
|
89 | }
|
90 |
|
91 | const earlyChange = lzwState.earlyChange;
|
92 | let nextCode = lzwState.nextCode;
|
93 | const dictionaryValues = lzwState.dictionaryValues;
|
94 | const dictionaryLengths = lzwState.dictionaryLengths;
|
95 | const dictionaryPrevCodes = lzwState.dictionaryPrevCodes;
|
96 | let codeLength = lzwState.codeLength;
|
97 | let prevCode = lzwState.prevCode;
|
98 | const currentSequence = lzwState.currentSequence;
|
99 | let currentSequenceLength = lzwState.currentSequenceLength;
|
100 | let decodedLength = 0;
|
101 | let currentBufferLength = this.bufferLength;
|
102 | let buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);
|
103 |
|
104 | for (i = 0; i < blockSize; i++) {
|
105 | const code = this.readBits(codeLength);
|
106 | const hasPrev = currentSequenceLength > 0;
|
107 |
|
108 | if (code < 256) {
|
109 | currentSequence[0] = code;
|
110 | currentSequenceLength = 1;
|
111 | } else if (code >= 258) {
|
112 | if (code < nextCode) {
|
113 | currentSequenceLength = dictionaryLengths[code];
|
114 |
|
115 | for (j = currentSequenceLength - 1, q = code; j >= 0; j--) {
|
116 | currentSequence[j] = dictionaryValues[q];
|
117 | q = dictionaryPrevCodes[q];
|
118 | }
|
119 | } else {
|
120 | currentSequence[currentSequenceLength++] = currentSequence[0];
|
121 | }
|
122 | } else if (code === 256) {
|
123 | codeLength = 9;
|
124 | nextCode = 258;
|
125 | currentSequenceLength = 0;
|
126 | continue;
|
127 | } else {
|
128 | this.eof = true;
|
129 | delete this.lzwState;
|
130 | break;
|
131 | }
|
132 |
|
133 | if (hasPrev) {
|
134 | dictionaryPrevCodes[nextCode] = prevCode;
|
135 | dictionaryLengths[nextCode] = dictionaryLengths[prevCode] + 1;
|
136 | dictionaryValues[nextCode] = currentSequence[0];
|
137 | nextCode++;
|
138 | codeLength = nextCode + earlyChange & nextCode + earlyChange - 1 ? codeLength : Math.min(Math.log(nextCode + earlyChange) / 0.6931471805599453 + 1, 12) | 0;
|
139 | }
|
140 |
|
141 | prevCode = code;
|
142 | decodedLength += currentSequenceLength;
|
143 |
|
144 | if (estimatedDecodedSize < decodedLength) {
|
145 | do {
|
146 | estimatedDecodedSize += decodedSizeDelta;
|
147 | } while (estimatedDecodedSize < decodedLength);
|
148 |
|
149 | buffer = this.ensureBuffer(this.bufferLength + estimatedDecodedSize);
|
150 | }
|
151 |
|
152 | for (j = 0; j < currentSequenceLength; j++) {
|
153 | buffer[currentBufferLength++] = currentSequence[j];
|
154 | }
|
155 | }
|
156 |
|
157 | lzwState.nextCode = nextCode;
|
158 | lzwState.codeLength = codeLength;
|
159 | lzwState.prevCode = prevCode;
|
160 | lzwState.currentSequenceLength = currentSequenceLength;
|
161 | this.bufferLength = currentBufferLength;
|
162 | }
|
163 |
|
164 | }
|
165 |
|
166 | exports.LZWStream = LZWStream; |
\ | No newline at end of file |