mirror of
https://github.com/0x5eal/rbxts-pako.git
synced 2025-04-04 10:50:59 +01:00
begin inffast implementation
This commit is contained in:
parent
e05b8f897c
commit
9a3d43cd34
4 changed files with 488 additions and 54 deletions
|
@ -147,8 +147,7 @@ Inflate.prototype.push = function(data, mode) {
|
|||
var status, _mode;
|
||||
|
||||
if (this.ended) { return false; }
|
||||
|
||||
_mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
|
||||
_mode = c.Z_NO_FLUSH;
|
||||
|
||||
strm.next_in = data;
|
||||
strm.next_in_index = 0;
|
||||
|
@ -174,6 +173,7 @@ Inflate.prototype.push = function(data, mode) {
|
|||
}
|
||||
} while (strm.avail_in > 0 || strm.avail_out === 0);
|
||||
|
||||
_mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
|
||||
// Finalize on the last chunk.
|
||||
if (_mode === c.Z_FINISH) {
|
||||
status = zlib_inflate.inflateEnd(this.strm);
|
||||
|
@ -251,7 +251,7 @@ function inflate(input, options) {
|
|||
inflator.push(input, true);
|
||||
|
||||
// That will never happens, if you don't cheat with options :)
|
||||
if (inflator.err) { throw msg[inflator.err]; }
|
||||
if (inflator.err) { throw msg[inflator.err]+':'+inflator.strm.msg; }
|
||||
|
||||
return inflator.result;
|
||||
}
|
||||
|
|
|
@ -65,12 +65,14 @@ module.exports = function inflate_fast(strm, start) {
|
|||
var len; /* match length, unused bytes */
|
||||
var dist; /* match distance */
|
||||
var from; /* where to copy match from */
|
||||
var idx = 0;
|
||||
|
||||
|
||||
var input, output; // JS specific, because we have no pointers
|
||||
|
||||
/* copy state to local variables */
|
||||
state = strm.state;
|
||||
here = state.here;
|
||||
_in = strm.next_in_index;
|
||||
input = strm.next_in;
|
||||
last = strm.avail_in - 5;
|
||||
|
@ -103,7 +105,10 @@ module.exports = function inflate_fast(strm, start) {
|
|||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = lcode[hold & lmask];
|
||||
idx = hold & lmask;
|
||||
here.op = lcode.op[idx];
|
||||
here.val = lcode.val[idx];
|
||||
here.bits = lcode.bits[idx];
|
||||
|
||||
dolen:
|
||||
do { // Goto emulation
|
||||
|
@ -136,7 +141,7 @@ module.exports = function inflate_fast(strm, start) {
|
|||
hold += input[_in++] << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
dcode.fill(hold & dmask, here);
|
||||
|
||||
dodist:
|
||||
do { // goto emulation
|
||||
|
@ -266,7 +271,7 @@ module.exports = function inflate_fast(strm, start) {
|
|||
}
|
||||
}
|
||||
else if ((op & 64) === 0) { /* 2nd level distance code */
|
||||
here = dcode[here.val + (hold & ((1 << op) - 1))];
|
||||
dcode.fill(here.val + (hold & ((1 << op) - 1)), here);
|
||||
continue dodist;
|
||||
}
|
||||
else {
|
||||
|
@ -277,7 +282,7 @@ module.exports = function inflate_fast(strm, start) {
|
|||
} while (0);
|
||||
}
|
||||
else if ((op & 64) === 0) { /* 2nd level length code */
|
||||
here = lcode[here.val + (hold & ((1 << op) - 1))];
|
||||
lcode.fill(here.val + (hold & ((1 << op) - 1)), here);
|
||||
continue dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
|
|
|
@ -4,8 +4,12 @@
|
|||
var utils = require('./utils');
|
||||
var adler32 = require('./adler32');
|
||||
var crc32 = require('./crc32');
|
||||
var inflate_fast = null;//require('./inf_fast');
|
||||
var inflate_fast = require('./inffast');
|
||||
var inflate_table = require('./inftrees');
|
||||
|
||||
var CODES = 0;
|
||||
var LENS = 1;
|
||||
var DISTS = 2;
|
||||
|
||||
/* Public constants ==========================================================*/
|
||||
/* ===========================================================================*/
|
||||
|
@ -87,11 +91,29 @@ var MAX_WBITS = 15;
|
|||
/* 32K LZ77 window */
|
||||
var DEF_WBITS = MAX_WBITS;
|
||||
|
||||
//function Code() {
|
||||
// this.op = 0; /* operation, extra bits, table bits */
|
||||
// this.bits = 0; /* bits in this part of the code */
|
||||
// this.val = 0; /* offset in table or code value */
|
||||
//}
|
||||
function Code() {
|
||||
this.op = 0; /* operation, extra bits, table bits */
|
||||
this.bits = 0; /* bits in this part of the code */
|
||||
this.val = 0; /* offset in table or code value */
|
||||
}
|
||||
|
||||
function CodeTable(length) {
|
||||
this.op = length ? utils.array16Create(length) : null;
|
||||
this.val = length ? utils.array16Create(length): null;
|
||||
this.bits = length ? utils.array16Create(length) : null;
|
||||
}
|
||||
|
||||
CodeTable.prototype.fill = function(idx, code) {
|
||||
code.bits = this.bits[idx];
|
||||
code.op = this.op[idx];
|
||||
code.val = this.val[idx];
|
||||
};
|
||||
|
||||
CodeTable.prototype.set = function(idx, code) {
|
||||
this.bits[idx] = code.bits;
|
||||
this.op[idx] = code.op;
|
||||
this.val[idx] = code.val;
|
||||
};
|
||||
|
||||
function InflateState() {
|
||||
this.mode = 0; /* current inflate mode */
|
||||
|
@ -124,8 +146,8 @@ function InflateState() {
|
|||
this.extra = 0; /* extra bits needed */
|
||||
|
||||
/* fixed and dynamic code tables */
|
||||
this.lencode = 0; /* starting table for length/literal codes */
|
||||
this.distcode = 0; /* starting table for distance codes */
|
||||
this.lencode = null; /* starting table for length/literal codes */
|
||||
this.distcode = null; /* starting table for distance codes */
|
||||
this.lenbits = 0; /* index bits for lencode */
|
||||
this.distbits = 0; /* index bits for distcode */
|
||||
|
||||
|
@ -134,18 +156,32 @@ function InflateState() {
|
|||
this.nlen = 0; /* number of length code lengths */
|
||||
this.ndist = 0; /* number of distance code lengths */
|
||||
this.have = 0; /* number of code lengths in lens[] */
|
||||
this.next = 0; /* next available space in codes[] */
|
||||
this.next = null; /* next available space in codes[] */
|
||||
this.next_index = 0;
|
||||
|
||||
//unsigned short array
|
||||
//todo: test later with Uint16Array
|
||||
this.lens = new utils.createArray16(320); /* temporary storage for code lengths */
|
||||
this.work = new utils.createArray16(280); /* work area for code table building */
|
||||
this.lens = utils.array16Create(320); /* temporary storage for code lengths */
|
||||
this.work = utils.array16Create(280); /* work area for code table building */
|
||||
|
||||
// TODO: 8 or 16 bits?
|
||||
this.codes = new utils.createArray16(ENOUGH); /* space for code tables */
|
||||
this.codes = new CodeTable(ENOUGH); /* space for code tables */
|
||||
this.sane = 0; /* if false, allow invalid distance too far */
|
||||
this.back = 0; /* bits back of last unprocessed length/lit */
|
||||
this.was = 0; /* initial length of match */
|
||||
|
||||
this.here = new Code();
|
||||
}
|
||||
|
||||
function InfTableOptions(type, lens, codes, table, table_index, bits, work) {
|
||||
this.type = type;
|
||||
this.lens = lens;
|
||||
this.codes = codes;
|
||||
this.table = table;
|
||||
this.table_index = table_index;
|
||||
this.bits = bits;
|
||||
this.work = work;
|
||||
this.here = new Code();
|
||||
}
|
||||
|
||||
function inflateResetKeep(strm) {
|
||||
|
@ -270,8 +306,58 @@ function inflatePrime(strm, bits, value) {
|
|||
used for threaded applications, since the rewriting of the tables and virgin
|
||||
may not be thread-safe.
|
||||
*/
|
||||
function fixedtables(/*state*/) {
|
||||
//var virgin = true;
|
||||
//var lenfix, distfix;
|
||||
//var fixed = new CodeTable(544);
|
||||
|
||||
var lenfix = new CodeTable();
|
||||
lenfix.op = utils.array16Create([96,0,0,20,18,0,0,0,16,0,0,0,0,0,0,0,16,0,0,0,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,64,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,96,0,0,21,18,0,0,0,16,0,0,0,0,0,0,0,16,0,0,0,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,16,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,64,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,96,0,0,20,18,0,0,0,16,0,0,0,0,0,0,0,16,0,0,0,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,64,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,96,0,0,21,18,0,0,0,16,0,0,0,0,0,0,0,16,0,0,0,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,16,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,21,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0,16,0,0,64,19,0,0,0,17,0,0,0,0,0,0,0,16,0,0,0,20,0,0,0,18,0,0,0,0,0,0,0]);
|
||||
lenfix.bits = utils.array16Create([7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,8,7,8,8,9,7,8,8,9,8,8,8,9,7,8,8,9,7,8,8,9,7,8,8,9,8,8,8,9]);
|
||||
lenfix.val = utils.array16Create([0,80,16,115,31,112,48,192,10,96,32,160,0,128,64,224,6,88,24,144,59,120,56,208,17,104,40,176,8,136,72,240,4,84,20,227,43,116,52,200,13,100,36,168,4,132,68,232,8,92,28,152,83,124,60,216,23,108,44,184,12,140,76,248,3,82,18,163,35,114,50,196,11,98,34,164,2,130,66,228,7,90,26,148,67,122,58,212,19,106,42,180,10,138,74,244,5,86,22,0,51,118,54,204,15,102,38,172,6,134,70,236,9,94,30,156,99,126,62,220,27,110,46,188,14,142,78,252,0,81,17,131,31,113,49,194,10,97,33,162,1,129,65,226,6,89,25,146,59,121,57,210,17,105,41,178,9,137,73,242,4,85,21,258,43,117,53,202,13,101,37,170,5,133,69,234,8,93,29,154,83,125,61,218,23,109,45,186,13,141,77,250,3,83,19,195,35,115,51,198,11,99,35,166,3,131,67,230,7,91,27,150,67,123,59,214,19,107,43,182,11,139,75,246,5,87,23,0,51,119,55,206,15,103,39,174,7,135,71,238,9,95,31,158,99,127,63,222,27,111,47,190,15,143,79,254,0,80,16,115,31,112,48,193,10,96,32,161,0,128,64,225,6,88,24,145,59,120,56,209,17,104,40,177,8,136,72,241,4,84,20,227,43,116,52,201,13,100,36,169,4,132,68,233,8,92,28,153,83,124,60,217,23,108,44,185,12,140,76,249,3,82,18,163,35,114,50,197,11,98,34,165,2,130,66,229,7,90,26,149,67,122,58,213,19,106,42,181,10,138,74,245,5,86,22,0,51,118,54,205,15,102,38,173,6,134,70,237,9,94,30,157,99,126,62,221,27,110,46,189,14,142,78,253,0,81,17,131,31,113,49,195,10,97,33,163,1,129,65,227,6,89,25,147,59,121,57,211,17,105,41,179,9,137,73,243,4,85,21,258,43,117,53,203,13,101,37,171,5,133,69,235,8,93,29,155,83,125,61,219,23,109,45,187,13,141,77,251,3,83,19,195,35,115,51,199,11,99,35,167,3,131,67,231,7,91,27,151,67,123,59,215,19,107,43,183,11,139,75,247,5,87,23,0,51,119,55,207,15,103,39,175,7,135,71,239,9,95,31,159,99,127,63,223,27,111,47,191,15,143,79,255]);
|
||||
|
||||
var distfix = new CodeTable();
|
||||
distfix.op = utils.array16Create([16,23,19,27,17,25,21,29,16,24,20,28,18,26,22,64,16,23,19,27,17,25,21,29,16,24,20,28,18,26,22,64]);
|
||||
distfix.bits = utils.array16Create([5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5]);
|
||||
distfix.val = utils.array16Create([1,257,17,4097,5,1025,65,16385,3,513,33,8193,9,2049,129,0,2,385,25,6145,7,1537,97,24577,4,769,49,12289,13,3073,193,0]);
|
||||
|
||||
|
||||
function fixedtables(state) {
|
||||
//#ifdef BUILDFIXED
|
||||
|
||||
// /* build fixed huffman tables if first call (may not be thread safe) */
|
||||
// if (virgin) {
|
||||
// var sym, bits;
|
||||
// var next;
|
||||
//
|
||||
// /* literal/length table */
|
||||
// sym = 0;
|
||||
// while (sym < 144) state.lens[sym++] = 8;
|
||||
// while (sym < 256) state.lens[sym++] = 9;
|
||||
// while (sym < 280) state.lens[sym++] = 7;
|
||||
// while (sym < 288) state.lens[sym++] = 8;
|
||||
// next = fixed;
|
||||
// lenfix = next;
|
||||
// bits = 9;
|
||||
// inflate_table(new InfTableOptions(LENS, state.lens, 288, next,0, bits, state.work));
|
||||
//
|
||||
// /* distance table */
|
||||
// sym = 0;
|
||||
// while (sym < 32) state.lens[sym++] = 5;
|
||||
// distfix = next;
|
||||
// bits = 5;
|
||||
//
|
||||
// inflate_table(new InfTableOptions(DISTS, state.lens, 32, next,0, bits, state.work));
|
||||
//
|
||||
// /* do this just once */
|
||||
// virgin = false;
|
||||
// }
|
||||
//#else /* !BUILDFIXED */
|
||||
//# include "inffixed.h"
|
||||
//#endif /* BUILDFIXED */
|
||||
state.lencode = lenfix;
|
||||
state.lenbits = 9;
|
||||
state.distcode = distfix;
|
||||
state.distbits = 5;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -326,11 +412,13 @@ function inflate(strm, flush) {
|
|||
var _in, _out; /* save starting available input and output */
|
||||
var copy; /* number of stored or match bytes to copy */
|
||||
var from; /* where to copy match bytes from */
|
||||
var here; /* current decoding table entry */
|
||||
var from_source;
|
||||
var here = new Code(); /* current decoding table entry */
|
||||
var last; /* parent table entry */
|
||||
var len; /* length to copy for repeats, bits to drop */
|
||||
var ret; /* return code */
|
||||
var hbuf = utils.createArray(4); /* buffer for gzip header crc calculation */
|
||||
var hbuf = utils.arrayCreate(4); /* buffer for gzip header crc calculation */
|
||||
var opts;
|
||||
|
||||
var n; // temporary var for NEED_BITS
|
||||
|
||||
|
@ -887,10 +975,14 @@ function inflate(strm, flush) {
|
|||
}
|
||||
state.next = state.codes;
|
||||
// TODO:
|
||||
/*state.lencode = (const code FAR *)(state.next);
|
||||
state.lencode = state.next;
|
||||
state.lenbits = 7;
|
||||
ret = inflate_table(CODES, state.lens, 19, &(state.next), &(state.lenbits), state.work);
|
||||
*/
|
||||
|
||||
opts = new InfTableOptions(CODES, state.lens, 19, state.next, state.next_index, state.lenbits, state.work);
|
||||
ret = inflate_table(opts);
|
||||
state.next_index = opts.table_index;
|
||||
state.lenbits = opts.bits;
|
||||
|
||||
if (ret) {
|
||||
strm.msg = 'invalid code lengths set';
|
||||
state.mode = BAD;
|
||||
|
@ -903,7 +995,7 @@ function inflate(strm, flush) {
|
|||
case CODELENS:
|
||||
while (state.have < state.nlen + state.ndist) {
|
||||
for (;;) {
|
||||
here = state.lencode[(hold & ((1 << state.lenbits) - 1))/*BITS(state.lenbits)*/];
|
||||
state.lencode(hold & ((1 << state.lenbits) - 1), here);/*BITS(state.lenbits)*/
|
||||
if ((here.bits) <= bits) { break; }
|
||||
//--- PULLBYTE() ---//
|
||||
if (have === 0) { return inf_leave(); }
|
||||
|
@ -1000,10 +1092,10 @@ function inflate(strm, flush) {
|
|||
}
|
||||
|
||||
/* handle error breaks in while */
|
||||
/* if (state.mode === BAD) { break; }
|
||||
if (state.mode === BAD) { break; }
|
||||
|
||||
/* check for end-of-block code (better have one) */
|
||||
/* if (state.lens[256] === 0) {
|
||||
if (state.lens[256] === 0) {
|
||||
strm.msg = 'invalid code -- missing end-of-block';
|
||||
state.mode = BAD;
|
||||
break;
|
||||
|
@ -1012,20 +1104,28 @@ function inflate(strm, flush) {
|
|||
/* build code tables -- note: do not change the lenbits or distbits
|
||||
values here (9 and 6) without reading the comments in inftrees.h
|
||||
concerning the ENOUGH constants, which depend on those values */
|
||||
/* state.next = state.codes;
|
||||
state.lencode = (const code FAR *)(state.next);
|
||||
state.next = state.codes;
|
||||
state.lencode = state.next;
|
||||
state.lenbits = 9;
|
||||
ret = inflate_table(LENS, state.lens, state.nlen, &(state.next),
|
||||
&(state.lenbits), state.work);
|
||||
|
||||
opts = new InfTableOptions(LENS, state.lens, state.nlen,state.next,state.next_index, state.lenbits, state.work);
|
||||
ret = inflate_table(opts);
|
||||
state.next_index = opts.table_index;
|
||||
state.lenbits = opts.bits;
|
||||
|
||||
if (ret) {
|
||||
strm.msg = 'invalid literal/lengths set';
|
||||
state.mode = BAD;
|
||||
break;
|
||||
}
|
||||
state.distcode = (const code FAR *)(state.next);
|
||||
state.distcode = state.next;
|
||||
state.distbits = 6;
|
||||
ret = inflate_table(DISTS, state.lens + state.nlen, state.ndist,
|
||||
&(state.next), &(state.distbits), state.work);
|
||||
|
||||
opts = new InfTableOptions(DISTS, state.lens + state.nlen, state.ndist, state.next,state.next_index, state.distbits, state.work);
|
||||
ret = inflate_table(opts);
|
||||
state.next_index = opts.table_index;
|
||||
state.lenbits = opts.bits;
|
||||
|
||||
if (ret) {
|
||||
strm.msg = 'invalid distances set';
|
||||
state.mode = BAD;
|
||||
|
@ -1050,7 +1150,7 @@ function inflate(strm, flush) {
|
|||
}
|
||||
state.back = 0;
|
||||
for (;;) {
|
||||
here = state.lencode[hold & ((1 << state.lenbits) -1)/*BITS(state.lenbits)*/];
|
||||
state.lencode.fill(hold & ((1 << state.lenbits) -1),here); /*BITS(state.lenbits)*/
|
||||
if (here.bits <= bits) { break; }
|
||||
//--- PULLBYTE() ---//
|
||||
if (have === 0) { return inf_leave(); }
|
||||
|
@ -1062,8 +1162,8 @@ function inflate(strm, flush) {
|
|||
if (here.op && (here.op & 0xf0) === 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state.lencode[last.val +
|
||||
((hold & ((1 << (last.bits + last.op)) -1))/*BITS(last.bits + last.op)*/ >> last.bits)];
|
||||
state.lencode(last.val +
|
||||
((hold & ((1 << (last.bits + last.op)) -1))/*BITS(last.bits + last.op)*/ >> last.bits), here);
|
||||
if ((last.bits + here.bits) <= bits) { break; }
|
||||
//--- PULLBYTE() ---//
|
||||
if (have === 0) { return inf_leave(); }
|
||||
|
@ -1129,7 +1229,7 @@ function inflate(strm, flush) {
|
|||
/* falls through */
|
||||
case DIST:
|
||||
for (;;) {
|
||||
here = state.distcode[hold & ((1 << state.distbits) -1)/*BITS(state.distbits)*/];
|
||||
state.distcode.fill(hold & ((1 << state.distbits) -1), here);/*BITS(state.distbits)*/
|
||||
if ((here.bits) <= bits) { break; }
|
||||
//--- PULLBYTE() ---//
|
||||
if (have === 0) { return inf_leave(); }
|
||||
|
@ -1141,8 +1241,8 @@ function inflate(strm, flush) {
|
|||
if ((here.op & 0xf0) === 0) {
|
||||
last = here;
|
||||
for (;;) {
|
||||
here = state.distcode[last.val +
|
||||
(hold & ((1 << (last.bits + last.op)) -1)/*BITS(last.bits + last.op)*/ >> last.bits)];
|
||||
state.distcode.fill(last.val +
|
||||
(hold & ((1 << (last.bits + last.op)) -1)/*BITS(last.bits + last.op)*/ >> last.bits), here);
|
||||
if ((last.bits + here.bits) <= bits) { break; }
|
||||
//--- PULLBYTE() ---//
|
||||
if (have === 0) { return inf_leave(); }
|
||||
|
@ -1212,16 +1312,16 @@ function inflate(strm, flush) {
|
|||
}
|
||||
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
//Trace((stderr, "inflate.c too far\n"));
|
||||
copy -= state.whave;
|
||||
if (copy > state.length) { copy = state.length; }
|
||||
if (copy > left) { copy = left; }
|
||||
left -= copy;
|
||||
state.length -= copy;
|
||||
do {
|
||||
output[put++] = 0;
|
||||
} while (--copy);
|
||||
if (state.length === 0) { state.mode = LEN; }
|
||||
break;
|
||||
// copy -= state.whave;
|
||||
// if (copy > state.length) { copy = state.length; }
|
||||
// if (copy > left) { copy = left; }
|
||||
// left -= copy;
|
||||
// state.length -= copy;
|
||||
// do {
|
||||
// output[put++] = 0;
|
||||
// } while (--copy);
|
||||
// if (state.length === 0) { state.mode = LEN; }
|
||||
// break;
|
||||
//#endif
|
||||
}
|
||||
if (copy > state.wnext) {
|
||||
|
@ -1232,8 +1332,10 @@ function inflate(strm, flush) {
|
|||
from = state.wnext - copy;
|
||||
}
|
||||
if (copy > state.length) { copy = state.length; }
|
||||
from_source = state.window;
|
||||
}
|
||||
else { /* copy from output */
|
||||
from_source = output;
|
||||
from = put - state.offset;
|
||||
copy = state.length;
|
||||
}
|
||||
|
@ -1241,7 +1343,7 @@ function inflate(strm, flush) {
|
|||
left -= copy;
|
||||
state.length -= copy;
|
||||
do {
|
||||
output[put++] = state.window[from++];
|
||||
output[put++] = from_source[from++];
|
||||
} while (--copy);
|
||||
if (state.length === 0) { state.mode = LEN; }
|
||||
break;
|
||||
|
@ -1323,8 +1425,15 @@ function inflate(strm, flush) {
|
|||
}
|
||||
}
|
||||
|
||||
function inflateEnd(/*strm*/) {
|
||||
|
||||
function inflateEnd(strm) {
|
||||
// if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
|
||||
// return Z_STREAM_ERROR;
|
||||
var state = strm.state;
|
||||
if (state.window) {
|
||||
state.window = null;
|
||||
}
|
||||
strm.state = null;
|
||||
return Z_OK;
|
||||
}
|
||||
|
||||
function inflateGetDictionary(/*strm, dictionary, dictLength*/) {
|
||||
|
|
320
lib/zlib/inftrees.js
Normal file
320
lib/zlib/inftrees.js
Normal file
|
@ -0,0 +1,320 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
var utils = require('./utils');
|
||||
|
||||
var MAXBITS = 15;
|
||||
var ENOUGH_LENS = 852;
|
||||
var ENOUGH_DISTS = 592;
|
||||
//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
|
||||
|
||||
var CODES = 0;
|
||||
var LENS = 1;
|
||||
var DISTS = 2;
|
||||
|
||||
var lbase = [ /* Length codes 257..285 base */
|
||||
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
|
||||
];
|
||||
|
||||
var lext = [ /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
|
||||
];
|
||||
|
||||
var dbase = [ /* Distance codes 0..29 base */
|
||||
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, 0, 0
|
||||
];
|
||||
|
||||
var dext = [ /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64
|
||||
];
|
||||
|
||||
module.exports = function inflate_table(opts)
|
||||
{
|
||||
var type = opts.type,
|
||||
lens = opts.lens,
|
||||
codes = opts.codes,
|
||||
table = opts.table,
|
||||
bits = opts.bits,
|
||||
work = opts.work,
|
||||
here = opts.here; /* table entry for duplication */
|
||||
|
||||
var len = 0; /* a code's length in bits */
|
||||
var sym = 0; /* index of code symbols */
|
||||
var min = 0, max = 0; /* minimum and maximum code lengths */
|
||||
var root = 0; /* number of index bits for root table */
|
||||
var curr = 0; /* number of index bits for current table */
|
||||
var drop = 0; /* code bits to drop for sub-table */
|
||||
var left = 0; /* number of prefix codes available */
|
||||
var used = 0; /* code entries in table used */
|
||||
var huff = 0; /* Huffman code */
|
||||
var incr; /* for incrementing code, index */
|
||||
var fill; /* index for replicating entries */
|
||||
var low; /* low bits for current root entry */
|
||||
var mask; /* mask for low root bits */
|
||||
var next; /* next available space in table */
|
||||
var base = null; /* base value table to use */
|
||||
var base_index = 0;
|
||||
// var shoextra; /* extra bits table to use */
|
||||
var end; /* use base and extra for symbol > end */
|
||||
var count = utils.array16Create(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */
|
||||
var offs = utils.array16Create(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */
|
||||
var extra = null;
|
||||
var extra_index = 0;
|
||||
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++) {
|
||||
count[len] = 0;
|
||||
}
|
||||
for (sym = 0; sym < codes; sym++) {
|
||||
count[lens[sym]]++;
|
||||
}
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = bits;
|
||||
for (max = MAXBITS; max >= 1; max--) {
|
||||
if (count[max] !== 0) { break; }
|
||||
}
|
||||
if (root > max) {
|
||||
root = max;
|
||||
}
|
||||
if (max === 0) { /* no symbols to code at all */
|
||||
table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
|
||||
table.bits[opts.table_index] = 1; //here.bits = (var char)1;
|
||||
table.val[opts.table_index++] = 0; //here.val = (var short)0;
|
||||
|
||||
table.op[opts.table_index] = 64;
|
||||
table.bits[opts.table_index] = 1;
|
||||
table.val[opts.table_index++] = 0;
|
||||
opts.bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min < max; min++) {
|
||||
if (count[min] !== 0) { break; }
|
||||
}
|
||||
if (root < min) {
|
||||
root = min;
|
||||
}
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) { return -1; } /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type === CODES || max !== 1)) {
|
||||
return -1; /* incomplete set */
|
||||
}
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++) {
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
}
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++) {
|
||||
if (lens[sym] !== 0) {
|
||||
work[offs[lens[sym]]++] = sym;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked for LENS and DIST tables against
|
||||
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
|
||||
the initial root table size constants. See the comments in inftrees.h
|
||||
for more information.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base_index -= 257;
|
||||
extra = lext;
|
||||
extra_index -= 257;
|
||||
end = 256;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize opts for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = opts.table_index; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = -1; /* trigger new sub-table when len > root */
|
||||
used = 1 << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
here.bits = len - drop;
|
||||
if (work[sym] < end) {
|
||||
here.op = 0;
|
||||
here.val = work[sym];
|
||||
}
|
||||
else if (work[sym] > end) {
|
||||
here.op = extra[extra_index + work[sym]];
|
||||
here.val = base[base_index + work[sym]];
|
||||
}
|
||||
else {
|
||||
here.op = 32 + 64; /* end of block */
|
||||
here.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1 << (len - drop);
|
||||
fill = 1 << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
table.set(next + (huff >> drop) + fill, here);
|
||||
} while (fill !== 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1 << (len - 1);
|
||||
while (huff & incr) {
|
||||
incr >>= 1;
|
||||
}
|
||||
if (incr !== 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
} else {
|
||||
huff = 0;
|
||||
}
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) === 0) {
|
||||
if (len === max) { break; }
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) !== low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop === 0) {
|
||||
drop = root;
|
||||
}
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = 1 << curr;
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) { break; }
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1 << curr;
|
||||
if ((type === LENS && used > ENOUGH_LENS) ||
|
||||
(type === DISTS && used > ENOUGH_DISTS)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
table.op[low] = curr;
|
||||
table.bits[low] = root;
|
||||
table.val[low] = next - opts.table_index;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff !== 0) {
|
||||
table.op[next + huff] = 64; /* invalid code marker */
|
||||
table.bits[next + huff] = len - drop;
|
||||
table.val[next + huff] = 0;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
opts.table_index += used;
|
||||
opts.bits = root;
|
||||
return 0;
|
||||
};
|
Loading…
Add table
Reference in a new issue