1
0
Fork 0
mirror of https://github.com/0x5eal/rbxts-pako.git synced 2025-04-14 17:03:53 +01:00

fast inflate implementation

This commit is contained in:
nik 2014-03-11 12:00:40 -03:00
parent 9a3d43cd34
commit 5f9b67413b
4 changed files with 146 additions and 74 deletions

View file

@ -22,7 +22,7 @@ function adler32(adler, buf, len, pos) {
s2 %= 65521; s2 %= 65521;
} }
return (s1 | (s2 << 16)); return (s1 | (s2 << 16)) >>> 0;
} }

View file

@ -65,7 +65,7 @@ module.exports = function inflate_fast(strm, start) {
var len; /* match length, unused bytes */ var len; /* match length, unused bytes */
var dist; /* match distance */ var dist; /* match distance */
var from; /* where to copy match from */ var from; /* where to copy match from */
var idx = 0; var from_source;
var input, output; // JS specific, because we have no pointers var input, output; // JS specific, because we have no pointers
@ -75,7 +75,7 @@ module.exports = function inflate_fast(strm, start) {
here = state.here; here = state.here;
_in = strm.next_in_index; _in = strm.next_in_index;
input = strm.next_in; input = strm.next_in;
last = strm.avail_in - 5; last = _in + (strm.avail_in - 5);
_out = strm.next_out_index; _out = strm.next_out_index;
output = strm.next_out; output = strm.next_out;
beg = _out - (start - strm.avail_out); beg = _out - (start - strm.avail_out);
@ -94,6 +94,9 @@ module.exports = function inflate_fast(strm, start) {
lmask = (1 << state.lenbits) - 1; lmask = (1 << state.lenbits) - 1;
dmask = (1 << state.distbits) - 1; dmask = (1 << state.distbits) - 1;
//goto flags
var _dolen, _dodist;
/* decode literals and length/distances until end-of-block or not enough /* decode literals and length/distances until end-of-block or not enough
input data or output space */ input data or output space */
@ -105,13 +108,12 @@ module.exports = function inflate_fast(strm, start) {
hold += input[_in++] << bits; hold += input[_in++] << bits;
bits += 8; bits += 8;
} }
idx = hold & lmask;
here.op = lcode.op[idx]; lcode.fill(hold & lmask, here);
here.val = lcode.val[idx];
here.bits = lcode.bits[idx];
dolen: dolen:
do { // Goto emulation do { // Goto emulation
_dolen = false;
op = here.bits; op = here.bits;
hold >>>= op; hold >>>= op;
bits -= op; bits -= op;
@ -145,6 +147,7 @@ module.exports = function inflate_fast(strm, start) {
dodist: dodist:
do { // goto emulation do { // goto emulation
_dodist = false;
op = here.bits; op = here.bits;
hold >>>= op; hold >>>= op;
bits -= op; bits -= op;
@ -182,26 +185,27 @@ module.exports = function inflate_fast(strm, start) {
break top; break top;
} }
//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (len <= op - whave) { // if (len <= op - whave) {
do { // do {
output[_out++] = 0; // output[_out++] = 0;
} while (--len); // } while (--len);
continue top; // continue top;
} // }
len -= op - whave; // len -= op - whave;
do { // do {
output[_out++] = 0; // output[_out++] = 0;
} while (--op > whave); // } while (--op > whave);
if (op === 0) { // if (op === 0) {
from = _out - dist; // from = _out - dist;
do { // do {
output[_out++] = output[from++]; // output[_out++] = output[from++];
} while (--len); // } while (--len);
continue top; // continue top;
} // }
//#endif //#endif
} }
from = 0; // window index from = 0; // window index
from_source = window;
if (wnext === 0) { /* very common case */ if (wnext === 0) { /* very common case */
from += wsize - op; from += wsize - op;
if (op < len) { /* some from window */ if (op < len) { /* some from window */
@ -210,6 +214,7 @@ module.exports = function inflate_fast(strm, start) {
output[_out++] = window[from++]; output[_out++] = window[from++];
} while (--op); } while (--op);
from = _out - dist; /* rest from output */ from = _out - dist; /* rest from output */
from_source = output;
} }
} }
else if (wnext < op) { /* wrap around window */ else if (wnext < op) { /* wrap around window */
@ -228,6 +233,7 @@ module.exports = function inflate_fast(strm, start) {
output[_out++] = window[from++]; output[_out++] = window[from++];
} while (--op); } while (--op);
from = _out - dist; /* rest from output */ from = _out - dist; /* rest from output */
from_source = output;
} }
} }
} }
@ -239,18 +245,19 @@ module.exports = function inflate_fast(strm, start) {
output[_out++] = window[from++]; output[_out++] = window[from++];
} while (--op); } while (--op);
from = _out - dist; /* rest from output */ from = _out - dist; /* rest from output */
from_source = output;
} }
} }
while (len > 2) { while (len > 2) {
output[_out++] = window[from++]; output[_out++] = from_source[from++];
output[_out++] = window[from++]; output[_out++] = from_source[from++];
output[_out++] = window[from++]; output[_out++] = from_source[from++];
len -= 3; len -= 3;
} }
if (len) { if (len) {
output[_out++] = window[from++]; output[_out++] = from_source[from++];
if (len > 1) { if (len > 1) {
output[_out++] = window[from++]; output[_out++] = from_source[from++];
} }
} }
} }
@ -272,6 +279,7 @@ module.exports = function inflate_fast(strm, start) {
} }
else if ((op & 64) === 0) { /* 2nd level distance code */ else if ((op & 64) === 0) { /* 2nd level distance code */
dcode.fill(here.val + (hold & ((1 << op) - 1)), here); dcode.fill(here.val + (hold & ((1 << op) - 1)), here);
_dodist = true;
continue dodist; continue dodist;
} }
else { else {
@ -279,10 +287,11 @@ module.exports = function inflate_fast(strm, start) {
state.mode = BAD; state.mode = BAD;
break top; break top;
} }
} while (0); } while (_dodist);
} }
else if ((op & 64) === 0) { /* 2nd level length code */ else if ((op & 64) === 0) { /* 2nd level length code */
lcode.fill(here.val + (hold & ((1 << op) - 1)), here); lcode.fill(here.val + (hold & ((1 << op) - 1)), here);
_dolen = true;
continue dolen; continue dolen;
} }
else if (op & 32) { /* end-of-block */ else if (op & 32) { /* end-of-block */
@ -295,7 +304,7 @@ module.exports = function inflate_fast(strm, start) {
state.mode = BAD; state.mode = BAD;
break top; break top;
} }
} while (0); } while (_dolen);
} while (_in < last && _out < end); } while (_in < last && _out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */

View file

@ -97,10 +97,18 @@ function Code() {
this.val = 0; /* offset in table or code value */ this.val = 0; /* offset in table or code value */
} }
Code.prototype.clone = function() {
var new_code = new Code();
new_code.op = this.op;
new_code.bits = this.bits;
new_code.val = this.val;
return new_code;
};
function CodeTable(length) { function CodeTable(length) {
this.op = length ? utils.array16Create(length) : null; this.op = length ? utils.arrayCreate(length) : null;
this.val = length ? utils.array16Create(length): null; this.val = length ? utils.array16Create(length): null;
this.bits = length ? utils.array16Create(length) : null; this.bits = length ? utils.arrayCreate(length) : null;
} }
CodeTable.prototype.fill = function(idx, code) { CodeTable.prototype.fill = function(idx, code) {
@ -115,6 +123,12 @@ CodeTable.prototype.set = function(idx, code) {
this.val[idx] = code.val; this.val[idx] = code.val;
}; };
CodeTable.prototype.copy = function(table) {
utils.arraySet(this.bits,table.bits,0,table.bits.length,0);
utils.arraySet(this.op,table.op,0,table.op.length,0);
utils.arraySet(this.val,table.val,0,table.val.length,0);
};
function InflateState() { function InflateState() {
this.mode = 0; /* current inflate mode */ this.mode = 0; /* current inflate mode */
this.last = false; /* true if processing last block */ this.last = false; /* true if processing last block */
@ -173,9 +187,10 @@ function InflateState() {
this.here = new Code(); this.here = new Code();
} }
function InfTableOptions(type, lens, codes, table, table_index, bits, work) { function InfTableOptions(type, lens, lens_index, codes, table, table_index, bits, work) {
this.type = type; this.type = type;
this.lens = lens; this.lens = lens;
this.lens_index = lens_index;
this.codes = codes; this.codes = codes;
this.table = table; this.table = table;
this.table_index = table_index; this.table_index = table_index;
@ -202,7 +217,12 @@ function inflateResetKeep(strm) {
state.head = null/*Z_NULL*/; state.head = null/*Z_NULL*/;
state.hold = 0; state.hold = 0;
state.bits = 0; state.bits = 0;
state.lencode = state.distcode = state.next = state.codes; //state.lencode = state.distcode = state.next = state.codes;
//utils.arraySet(state.lencode,state.codes,0,state.codes.length,0);
//utils.arraySet(state.distcode,state.codes,0,state.codes.length,0);
state.lencode = new CodeTable(ENOUGH);
state.distcode = new CodeTable(ENOUGH);
state.sane = 1; state.sane = 1;
state.back = -1; state.back = -1;
//Tracev((stderr, "inflate: reset\n")); //Tracev((stderr, "inflate: reset\n"));
@ -310,16 +330,6 @@ function inflatePrime(strm, bits, value) {
//var lenfix, distfix; //var lenfix, distfix;
//var fixed = new CodeTable(544); //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) { function fixedtables(state) {
//#ifdef BUILDFIXED //#ifdef BUILDFIXED
@ -354,6 +364,16 @@ function fixedtables(state) {
//#else /* !BUILDFIXED */ //#else /* !BUILDFIXED */
//# include "inffixed.h" //# include "inffixed.h"
//#endif /* BUILDFIXED */ //#endif /* BUILDFIXED */
var lenfix = new CodeTable(544);
utils.arraySet(lenfix.op,[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], 0, 544, 0);
utils.arraySet(lenfix.bits,[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], 0, 544, 0);
utils.arraySet(lenfix.val,[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], 0, 544, 0);
var distfix = new CodeTable(32);
utils.arraySet(distfix.op, [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], 0, 32, 0);
utils.arraySet(distfix.bits, [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], 0, 32, 0);
utils.arraySet(distfix.val, [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], 0, 32, 0);
state.lencode = lenfix; state.lencode = lenfix;
state.lenbits = 9; state.lenbits = 9;
state.distcode = distfix; state.distcode = distfix;
@ -396,11 +416,48 @@ function fixedtables(state) {
output will fall in the output data, making match copies simpler and faster. output will fall in the output data, making match copies simpler and faster.
The advantage may be dependent on the size of the processor's data caches. The advantage may be dependent on the size of the processor's data caches.
*/ */
function updatewindow(/*strm, end, copy*/) { function updatewindow(strm, src, end, copy) {
var dist;
var state = strm.state;
/* if it hasn't been done already, allocate space for the window */
if (state.window === null) {
state.wsize = 1 << state.wbits;
state.wnext = 0;
state.whave = 0;
state.window = utils.arrayCreate(state.wsize);
}
/* copy state->wsize or less output bytes into the circular window */
if (copy >= state.wsize) {
utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0);
state.wnext = 0;
state.whave = state.wsize;
}
else {
dist = state.wsize - state.wnext;
if (dist > copy) {
dist = copy;
}
//zmemcpy(state->window + state->wnext, end - copy, dist);
utils.arraySet(state.window,src, end - copy, dist, state.wnext);
copy -= dist;
if (copy) {
//zmemcpy(state->window, end - copy, copy);
utils.arraySet(state.window,src, end - copy, copy, 0);
state.wnext = copy;
state.whave = state.wsize;
}
else {
state.wnext += dist;
if (state.wnext === state.wsize) { state.wnext = 0; }
if (state.whave < state.wsize) { state.whave += dist; }
}
}
return 0;
} }
function inflate(strm, flush) { function inflate(strm, flush) {
var state; var state;
var input, output; // input/output buffers var input, output; // input/output buffers
@ -446,10 +503,10 @@ function inflate(strm, flush) {
} }
function ZSWAP32(q) { function ZSWAP32(q) {
return ((q >>> 24) & 0xff) + return (((q >>> 24) & 0xff) +
((q >>> 8) & 0xff00) + ((q >>> 8) & 0xff00) +
((q & 0xff00) << 8) + ((q & 0xff00) << 8) +
((q & 0xff) << 24); ((q & 0xff) << 24)) >>> 0;
} }
/* /*
@ -462,7 +519,7 @@ function inflate(strm, flush) {
RESTORE(); RESTORE();
if (state.wsize || (_out !== strm.avail_out && state.mode < BAD && if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
(state.mode < CHECK || flush !== Z_FINISH))) { (state.mode < CHECK || flush !== Z_FINISH))) {
if (updatewindow(strm, strm.next_out_index, _out - strm.avail_out)) { if (updatewindow(strm, strm.next_out, strm.next_out_index, _out - strm.avail_out)) {
state.mode = MEM; state.mode = MEM;
return Z_MEM_ERROR; return Z_MEM_ERROR;
} }
@ -973,14 +1030,14 @@ function inflate(strm, flush) {
while (state.have < 19) { while (state.have < 19) {
state.lens[order[state.have++]] = 0; state.lens[order[state.have++]] = 0;
} }
state.next = state.codes; //state.next = state.codes;
// TODO: // TODO:
state.lencode = state.next; //state.lencode = state.next;
state.lencode.copy(state.codes);
state.lenbits = 7; state.lenbits = 7;
opts = new InfTableOptions(CODES, state.lens, 19, state.next, state.next_index, state.lenbits, state.work); opts = new InfTableOptions(CODES, state.lens, 0, 19, state.lencode, 0, state.lenbits, state.work);
ret = inflate_table(opts); ret = inflate_table(opts);
state.next_index = opts.table_index;
state.lenbits = opts.bits; state.lenbits = opts.bits;
if (ret) { if (ret) {
@ -995,7 +1052,7 @@ function inflate(strm, flush) {
case CODELENS: case CODELENS:
while (state.have < state.nlen + state.ndist) { while (state.have < state.nlen + state.ndist) {
for (;;) { for (;;) {
state.lencode(hold & ((1 << state.lenbits) - 1), here);/*BITS(state.lenbits)*/ state.lencode.fill(hold & ((1 << state.lenbits) - 1), here);/*BITS(state.lenbits)*/
if ((here.bits) <= bits) { break; } if ((here.bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { return inf_leave(); } if (have === 0) { return inf_leave(); }
@ -1104,27 +1161,28 @@ function inflate(strm, flush) {
/* build code tables -- note: do not change the lenbits or distbits /* build code tables -- note: do not change the lenbits or distbits
values here (9 and 6) without reading the comments in inftrees.h values here (9 and 6) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */ concerning the ENOUGH constants, which depend on those values */
state.next = state.codes; state.lencode.copy(state.codes);
state.lencode = state.next;
state.lenbits = 9; state.lenbits = 9;
opts = new InfTableOptions(LENS, state.lens, state.nlen,state.next,state.next_index, state.lenbits, state.work); opts = new InfTableOptions(LENS, state.lens, 0, state.nlen,state.lencode,0, state.lenbits, state.work);
ret = inflate_table(opts); ret = inflate_table(opts);
state.next_index = opts.table_index; // state.next_index = opts.table_index;
state.lenbits = opts.bits; state.lenbits = opts.bits;
// state.lencode = state.next;
if (ret) { if (ret) {
strm.msg = 'invalid literal/lengths set'; strm.msg = 'invalid literal/lengths set';
state.mode = BAD; state.mode = BAD;
break; break;
} }
state.distcode = state.next;
state.distbits = 6;
opts = new InfTableOptions(DISTS, state.lens + state.nlen, state.ndist, state.next,state.next_index, state.distbits, state.work); state.distbits = 6;
state.distcode.copy(state.codes);
opts = new InfTableOptions(DISTS, state.lens, state.nlen, state.ndist, state.distcode,0, state.distbits, state.work);
ret = inflate_table(opts); ret = inflate_table(opts);
state.next_index = opts.table_index; // state.next_index = opts.table_index;
state.lenbits = opts.bits; state.distbits = opts.bits;
// state.distcode = state.next;
if (ret) { if (ret) {
strm.msg = 'invalid distances set'; strm.msg = 'invalid distances set';
@ -1160,9 +1218,9 @@ function inflate(strm, flush) {
//---// //---//
} }
if (here.op && (here.op & 0xf0) === 0) { if (here.op && (here.op & 0xf0) === 0) {
last = here; last = here.clone();
for (;;) { for (;;) {
state.lencode(last.val + state.lencode.fill(last.val +
((hold & ((1 << (last.bits + last.op)) -1))/*BITS(last.bits + last.op)*/ >> last.bits), here); ((hold & ((1 << (last.bits + last.op)) -1))/*BITS(last.bits + last.op)*/ >> last.bits), here);
if ((last.bits + here.bits) <= bits) { break; } if ((last.bits + here.bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
@ -1239,10 +1297,10 @@ function inflate(strm, flush) {
//---// //---//
} }
if ((here.op & 0xf0) === 0) { if ((here.op & 0xf0) === 0) {
last = here; last = here.clone();
for (;;) { for (;;) {
state.distcode.fill(last.val + state.distcode.fill(last.val +
(hold & ((1 << (last.bits + last.op)) -1)/*BITS(last.bits + last.op)*/ >> last.bits), here); ((hold & ((1 << (last.bits + last.op)) -1))/*BITS(last.bits + last.op)*/ >> last.bits), here);
if ((last.bits + here.bits) <= bits) { break; } if ((last.bits + here.bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { return inf_leave(); } if (have === 0) { return inf_leave(); }
@ -1360,6 +1418,7 @@ function inflate(strm, flush) {
if (have === 0) { return inf_leave(); } if (have === 0) { return inf_leave(); }
have--; have--;
hold += input[next++] << bits; hold += input[next++] << bits;
hold >>>= 0;
bits += 8; bits += 8;
} }
//===// //===//

View file

@ -104,7 +104,7 @@ module.exports = function inflate_table(opts)
count[len] = 0; count[len] = 0;
} }
for (sym = 0; sym < codes; sym++) { for (sym = 0; sym < codes; sym++) {
count[lens[sym]]++; count[lens[opts.lens_index + sym]]++;
} }
/* bound code lengths, force root to be within code lengths */ /* bound code lengths, force root to be within code lengths */
@ -138,7 +138,9 @@ module.exports = function inflate_table(opts)
for (len = 1; len <= MAXBITS; len++) { for (len = 1; len <= MAXBITS; len++) {
left <<= 1; left <<= 1;
left -= count[len]; left -= count[len];
if (left < 0) { return -1; } /* over-subscribed */ if (left < 0) {
return -1;
} /* over-subscribed */
} }
if (left > 0 && (type === CODES || max !== 1)) { if (left > 0 && (type === CODES || max !== 1)) {
return -1; /* incomplete set */ return -1; /* incomplete set */
@ -152,8 +154,8 @@ module.exports = function inflate_table(opts)
/* sort symbols by length, by symbol order within each length */ /* sort symbols by length, by symbol order within each length */
for (sym = 0; sym < codes; sym++) { for (sym = 0; sym < codes; sym++) {
if (lens[sym] !== 0) { if (lens[opts.lens_index + sym] !== 0) {
work[offs[lens[sym]]++] = sym; work[offs[lens[opts.lens_index + sym]]++] = sym;
} }
} }
@ -224,8 +226,10 @@ module.exports = function inflate_table(opts)
return 1; return 1;
} }
var i=0;
/* process all codes and make table entries */ /* process all codes and make table entries */
for (;;) { for (;;) {
i++;
/* create table entry */ /* create table entry */
here.bits = len - drop; here.bits = len - drop;
if (work[sym] < end) { if (work[sym] < end) {
@ -266,7 +270,7 @@ module.exports = function inflate_table(opts)
sym++; sym++;
if (--(count[len]) === 0) { if (--(count[len]) === 0) {
if (len === max) { break; } if (len === max) { break; }
len = lens[work[sym]]; len = lens[opts.lens_index + work[sym]];
} }
/* create new sub-table if needed */ /* create new sub-table if needed */