UNPKG

14.8 kBJavaScriptView Raw
1var Buffer = require("buffer").Buffer;
2
3function JSInflater(/*Buffer*/input) {
4
5 var WSIZE = 0x8000,
6 slide = new Buffer(0x10000),
7 windowPos = 0,
8 fixedTableList = null,
9 fixedTableDist,
10 fixedLookup,
11 bitBuf = 0,
12 bitLen = 0,
13 method = -1,
14 eof = false,
15 copyLen = 0,
16 copyDist = 0,
17 tblList, tblDist, bitList, bitdist,
18
19 inputPosition = 0,
20
21 MASK_BITS = [0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff],
22 LENS = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0],
23 LEXT = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99],
24 DISTS = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577],
25 DEXT = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13],
26 BITORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
27
28 function HuffTable(clen, cnum, cval, blist, elist, lookupm) {
29
30 this.status = 0;
31 this.root = null;
32 this.maxbit = 0;
33
34 var el, f, tail,
35 offsets = [],
36 countTbl = [],
37 sTbl = [],
38 values = [],
39 tentry = {extra: 0, bitcnt: 0, lbase: 0, next: null};
40
41 tail = this.root = null;
42 for(var i = 0; i < 0x11; i++) { countTbl[i] = 0; sTbl[i] = 0; offsets[i] = 0; }
43 for(i = 0; i < 0x120; i++) values[i] = 0;
44
45 el = cnum > 256 ? clen[256] : 16;
46
47 var pidx = -1;
48 while (++pidx < cnum) countTbl[clen[pidx]]++;
49
50 if(countTbl[0] == cnum) return;
51
52 for(var j = 1; j <= 16; j++) if(countTbl[j] != 0) break;
53 var bitLen = j;
54 for(i = 16; i != 0; i--) if(countTbl[i] != 0) break;
55 var maxLen = i;
56
57 lookupm < j && (lookupm = j);
58
59 var dCodes = 1 << j;
60 for(; j < i; j++, dCodes <<= 1)
61 if((dCodes -= countTbl[j]) < 0) {
62 this.status = 2;
63 this.maxbit = lookupm;
64 return;
65 }
66
67 if((dCodes -= countTbl[i]) < 0) {
68 this.status = 2;
69 this.maxbit = lookupm;
70 return;
71 }
72
73 countTbl[i] += dCodes;
74 offsets[1] = j = 0;
75 pidx = 1;
76 var xp = 2;
77 while(--i > 0) offsets[xp++] = (j += countTbl[pidx++]);
78 pidx = 0;
79 i = 0;
80 do {
81 (j = clen[pidx++]) && (values[offsets[j]++] = i);
82 } while(++i < cnum);
83 cnum = offsets[maxLen];
84 offsets[0] = i = 0;
85 pidx = 0;
86
87 var level = -1,
88 w = sTbl[0] = 0,
89 cnode = null,
90 tblCnt = 0,
91 tblStack = [];
92
93 for(; bitLen <= maxLen; bitLen++) {
94 var kccnt = countTbl[bitLen];
95 while(kccnt-- > 0) {
96 while(bitLen > w + sTbl[1 + level]) {
97 w += sTbl[1 + level];
98 level++;
99 tblCnt = (tblCnt = maxLen - w) > lookupm ? lookupm : tblCnt;
100 if((f = 1 << (j = bitLen - w)) > kccnt + 1) {
101 f -= kccnt + 1;
102 xp = bitLen;
103 while(++j < tblCnt) {
104 if((f <<= 1) <= countTbl[++xp]) break;
105 f -= countTbl[xp];
106 }
107 }
108 if(w + j > el && w < el) j = el - w;
109 tblCnt = 1 << j;
110 sTbl[1 + level] = j;
111 cnode = [];
112 while (cnode.length < tblCnt) cnode.push({extra: 0, bitcnt: 0, lbase: 0, next: null});
113 if (tail == null) {
114 tail = this.root = {next:null, list:null};
115 } else {
116 tail = tail.next = {next:null, list:null}
117 }
118 tail.next = null;
119 tail.list = cnode;
120
121 tblStack[level] = cnode;
122
123 if(level > 0) {
124 offsets[level] = i;
125 tentry.bitcnt = sTbl[level];
126 tentry.extra = 16 + j;
127 tentry.next = cnode;
128 j = (i & ((1 << w) - 1)) >> (w - sTbl[level]);
129
130 tblStack[level-1][j].extra = tentry.extra;
131 tblStack[level-1][j].bitcnt = tentry.bitcnt;
132 tblStack[level-1][j].lbase = tentry.lbase;
133 tblStack[level-1][j].next = tentry.next;
134 }
135 }
136 tentry.bitcnt = bitLen - w;
137 if(pidx >= cnum)
138 tentry.extra = 99;
139 else if(values[pidx] < cval) {
140 tentry.extra = (values[pidx] < 256 ? 16 : 15);
141 tentry.lbase = values[pidx++];
142 } else {
143 tentry.extra = elist[values[pidx] - cval];
144 tentry.lbase = blist[values[pidx++] - cval];
145 }
146
147 f = 1 << (bitLen - w);
148 for(j = i >> w; j < tblCnt; j += f) {
149 cnode[j].extra = tentry.extra;
150 cnode[j].bitcnt = tentry.bitcnt;
151 cnode[j].lbase = tentry.lbase;
152 cnode[j].next = tentry.next;
153 }
154 for(j = 1 << (bitLen - 1); (i & j) != 0; j >>= 1)
155 i ^= j;
156 i ^= j;
157 while((i & ((1 << w) - 1)) != offsets[level]) {
158 w -= sTbl[level];
159 level--;
160 }
161 }
162 }
163
164 this.maxbit = sTbl[1];
165 this.status = ((dCodes != 0 && maxLen != 1) ? 1 : 0);
166 }
167
168 function addBits(n) {
169 while(bitLen < n) {
170 bitBuf |= input[inputPosition++] << bitLen;
171 bitLen += 8;
172 }
173 return bitBuf;
174 }
175
176 function cutBits(n) {
177 bitLen -= n;
178 return bitBuf >>= n;
179 }
180
181 function maskBits(n) {
182 while(bitLen < n) {
183 bitBuf |= input[inputPosition++] << bitLen;
184 bitLen += 8;
185 }
186 var res = bitBuf & MASK_BITS[n];
187 bitBuf >>= n;
188 bitLen -= n;
189 return res;
190 }
191
192 function codes(buff, off, size) {
193 var e, t;
194 if(size == 0) return 0;
195
196 var n = 0;
197 for(;;) {
198 t = tblList.list[addBits(bitList) & MASK_BITS[bitList]];
199 e = t.extra;
200 while(e > 16) {
201 if(e == 99) return -1;
202 cutBits(t.bitcnt);
203 e -= 16;
204 t = t.next[addBits(e) & MASK_BITS[e]];
205 e = t.extra;
206 }
207 cutBits(t.bitcnt);
208 if(e == 16) {
209 windowPos &= WSIZE - 1;
210 buff[off + n++] = slide[windowPos++] = t.lbase;
211 if(n == size) return size;
212 continue;
213 }
214 if(e == 15) break;
215
216 copyLen = t.lbase + maskBits(e);
217 t = tblDist.list[addBits(bitdist) & MASK_BITS[bitdist]];
218 e = t.extra;
219
220 while(e > 16) {
221 if(e == 99) return -1;
222 cutBits(t.bitcnt);
223 e -= 16;
224 t = t.next[addBits(e) & MASK_BITS[e]];
225 e = t.extra
226 }
227 cutBits(t.bitcnt);
228 copyDist = windowPos - t.lbase - maskBits(e);
229
230 while(copyLen > 0 && n < size) {
231 copyLen--;
232 copyDist &= WSIZE - 1;
233 windowPos &= WSIZE - 1;
234 buff[off + n++] = slide[windowPos++] = slide[copyDist++];
235 }
236
237 if(n == size) return size;
238 }
239
240 method = -1; // done
241 return n;
242 }
243
244 function stored(buff, off, size) {
245 cutBits(bitLen & 7);
246 var n = maskBits(0x10);
247 if(n != ((~maskBits(0x10)) & 0xffff)) return -1;
248 copyLen = n;
249
250 n = 0;
251 while(copyLen > 0 && n < size) {
252 copyLen--;
253 windowPos &= WSIZE - 1;
254 buff[off + n++] = slide[windowPos++] = maskBits(8);
255 }
256
257 if(copyLen == 0) method = -1;
258 return n;
259 }
260
261 function fixed(buff, off, size) {
262 var fixed_bd = 0;
263 if(fixedTableList == null) {
264 var lengths = [];
265
266 for(var symbol = 0; symbol < 144; symbol++) lengths[symbol] = 8;
267 for(; symbol < 256; symbol++) lengths[symbol] = 9;
268 for(; symbol < 280; symbol++) lengths[symbol] = 7;
269 for(; symbol < 288; symbol++) lengths[symbol] = 8;
270
271 fixedLookup = 7;
272
273 var htbl = new HuffTable(lengths, 288, 257, LENS, LEXT, fixedLookup);
274
275 if(htbl.status != 0) return -1;
276
277 fixedTableList = htbl.root;
278 fixedLookup = htbl.maxbit;
279
280 for(symbol = 0; symbol < 30; symbol++) lengths[symbol] = 5;
281 fixed_bd = 5;
282
283 htbl = new HuffTable(lengths, 30, 0, DISTS, DEXT, fixed_bd);
284 if(htbl.status > 1) {
285 fixedTableList = null;
286 return -1;
287 }
288 fixedTableDist = htbl.root;
289 fixed_bd = htbl.maxbit;
290 }
291
292 tblList = fixedTableList;
293 tblDist = fixedTableDist;
294 bitList = fixedLookup;
295 bitdist = fixed_bd;
296 return codes(buff, off, size);
297 }
298
299 function dynamic(buff, off, size) {
300 var ll = new Array(0x023C);
301
302 for (var m = 0; m < 0x023C; m++) ll[m] = 0;
303
304 var llencnt = 257 + maskBits(5),
305 dcodescnt = 1 + maskBits(5),
306 bitlencnt = 4 + maskBits(4);
307
308 if(llencnt > 286 || dcodescnt > 30) return -1;
309
310 for(var j = 0; j < bitlencnt; j++) ll[BITORDER[j]] = maskBits(3);
311 for(; j < 19; j++) ll[BITORDER[j]] = 0;
312
313 // build decoding table for trees--single level, 7 bit lookup
314 bitList = 7;
315 var hufTable = new HuffTable(ll, 19, 19, null, null, bitList);
316 if(hufTable.status != 0)
317 return -1; // incomplete code set
318
319 tblList = hufTable.root;
320 bitList = hufTable.maxbit;
321 var lencnt = llencnt + dcodescnt,
322 i = 0,
323 lastLen = 0;
324 while(i < lencnt) {
325 var hufLcode = tblList.list[addBits(bitList) & MASK_BITS[bitList]];
326 j = hufLcode.bitcnt;
327 cutBits(j);
328 j = hufLcode.lbase;
329 if(j < 16)
330 ll[i++] = lastLen = j;
331 else if(j == 16) {
332 j = 3 + maskBits(2);
333 if(i + j > lencnt) return -1;
334 while(j-- > 0) ll[i++] = lastLen;
335 } else if(j == 17) {
336 j = 3 + maskBits(3);
337 if(i + j > lencnt) return -1;
338 while(j-- > 0) ll[i++] = 0;
339 lastLen = 0;
340 } else {
341 j = 11 + maskBits(7);
342 if(i + j > lencnt) return -1;
343 while(j-- > 0) ll[i++] = 0;
344 lastLen = 0;
345 }
346 }
347 bitList = 9;
348 hufTable = new HuffTable(ll, llencnt, 257, LENS, LEXT, bitList);
349 bitList == 0 && (hufTable.status = 1);
350
351 if (hufTable.status != 0) return -1;
352
353 tblList = hufTable.root;
354 bitList = hufTable.maxbit;
355
356 for(i = 0; i < dcodescnt; i++) ll[i] = ll[i + llencnt];
357 bitdist = 6;
358 hufTable = new HuffTable(ll, dcodescnt, 0, DISTS, DEXT, bitdist);
359 tblDist = hufTable.root;
360 bitdist = hufTable.maxbit;
361
362 if((bitdist == 0 && llencnt > 257) || hufTable.status != 0) return -1;
363
364 return codes(buff, off, size);
365 }
366
367 return {
368 inflate : function(/*Buffer*/outputBuffer) {
369 tblList = null;
370
371 var size = outputBuffer.length,
372 offset = 0, i;
373
374 while(offset < size) {
375 if(eof && method == -1) return;
376 if(copyLen > 0) {
377 if(method != 0) {
378 while(copyLen > 0 && offset < size) {
379 copyLen--;
380 copyDist &= WSIZE - 1;
381 windowPos &= WSIZE - 1;
382 outputBuffer[offset++] = slide[windowPos++] = slide[copyDist++];
383 }
384 } else {
385 while(copyLen > 0 && offset < size) {
386 copyLen--;
387 windowPos &= WSIZE - 1;
388 outputBuffer[offset++] = slide[windowPos++] = maskBits(8);
389 }
390 copyLen == 0 && (method = -1); // done
391 }
392 if (offset == size) return;
393 }
394
395 if(method == -1) {
396 if(eof) break;
397 eof = maskBits(1) != 0;
398 method = maskBits(2);
399 tblList = null;
400 copyLen = 0;
401 }
402 switch(method) {
403 case 0: i = stored(outputBuffer, offset, size - offset); break;
404 case 1: i = tblList != null ? codes(outputBuffer, offset, size - offset) : fixed(outputBuffer, offset, size - offset); break;
405 case 2: i = tblList != null ? codes(outputBuffer, offset, size - offset) : dynamic(outputBuffer, offset, size - offset); break;
406 default: i = -1; break;
407 }
408
409 if(i == -1) return;
410 offset += i;
411 }
412 }
413 };
414}
415
416module.exports = function(/*Buffer*/inbuf) {
417 var zlib = require("zlib");
418 return {
419 inflateAsync : function(/*Function*/callback) {
420 var tmp = zlib.createInflateRaw(),
421 parts = [], total = 0;
422 tmp.on('data', function(data) {
423 parts.push(data);
424 total += data.length;
425 });
426 tmp.on('end', function() {
427 var buf = new Buffer(total), written = 0;
428 buf.fill(0);
429
430 for (var i = 0; i < parts.length; i++) {
431 var part = parts[i];
432 part.copy(buf, written);
433 written += part.length;
434 }
435 callback && callback(buf);
436 });
437 tmp.end(inbuf)
438 },
439
440 inflate : function(/*Buffer*/outputBuffer) {
441 var x = new JSInflater(inbuf);
442 x.inflate(outputBuffer);
443 delete(x);
444 }
445 }
446};
\No newline at end of file