117 lines
3.1 KiB
JavaScript
117 lines
3.1 KiB
JavaScript
var _deflateRaw = (function() {
|
|
var DST_LN_RE = use_typed_arrays ? new Uint8Array(0x8000) : [];
|
|
for(var j = 0, k = 0; j < DST_LN.length; ++j) {
|
|
for(; k < DST_LN[j+1]; ++k) DST_LN_RE[k] = j;
|
|
}
|
|
for(;k < 32768; ++k) DST_LN_RE[k] = 29;
|
|
|
|
var LEN_LN_RE = use_typed_arrays ? new Uint8Array(0x102) : [];
|
|
for(j = 0, k = 0; j < LEN_LN.length; ++j) {
|
|
for(; k < LEN_LN[j+1]; ++k) LEN_LN_RE[k] = j;
|
|
}
|
|
|
|
function write_stored(data, out) {
|
|
var boff = 0;
|
|
while(boff < data.length) {
|
|
var L = Math.min(0xFFFF, data.length - boff);
|
|
var h = boff + L == data.length;
|
|
out.write_shift(1, +h);
|
|
out.write_shift(2, L);
|
|
out.write_shift(2, (~L) & 0xFFFF);
|
|
while(L-- > 0) out[out.l++] = data[boff++];
|
|
}
|
|
return out.l;
|
|
}
|
|
|
|
/* Fixed Huffman */
|
|
function write_huff_fixed(data, out) {
|
|
var bl = 0;
|
|
var boff = 0;
|
|
var addrs = use_typed_arrays ? new Uint16Array(0x8000) : [];
|
|
while(boff < data.length) {
|
|
var L = /* data.length - boff; */ Math.min(0xFFFF, data.length - boff);
|
|
|
|
/* write a stored block for short data */
|
|
if(L < 10) {
|
|
bl = write_bits_3(out, bl, +!!(boff + L == data.length)); // jshint ignore:line
|
|
if(bl & 7) bl += 8 - (bl & 7);
|
|
out.l = (bl / 8) | 0;
|
|
out.write_shift(2, L);
|
|
out.write_shift(2, (~L) & 0xFFFF);
|
|
while(L-- > 0) out[out.l++] = data[boff++];
|
|
bl = out.l * 8;
|
|
continue;
|
|
}
|
|
|
|
bl = write_bits_3(out, bl, +!!(boff + L == data.length) + 2); // jshint ignore:line
|
|
var hash = 0;
|
|
while(L-- > 0) {
|
|
var d = data[boff];
|
|
hash = ((hash << 5) ^ d) & 0x7FFF;
|
|
|
|
var match = -1, mlen = 0;
|
|
|
|
if((match = addrs[hash])) {
|
|
match |= boff & ~0x7FFF;
|
|
if(match > boff) match -= 0x8000;
|
|
if(match < boff) while(data[match + mlen] == data[boff + mlen] && mlen < 250) ++mlen;
|
|
}
|
|
|
|
if(mlen > 2) {
|
|
/* Copy Token */
|
|
d = LEN_LN_RE[mlen];
|
|
if(d <= 22) bl = write_bits_8(out, bl, bitswap8[d+1]>>1) - 1;
|
|
else {
|
|
write_bits_8(out, bl, 3);
|
|
bl += 5;
|
|
write_bits_8(out, bl, bitswap8[d-23]>>5);
|
|
bl += 3;
|
|
}
|
|
var len_eb = (d < 8) ? 0 : ((d - 4)>>2);
|
|
if(len_eb > 0) {
|
|
write_bits_16(out, bl, mlen - LEN_LN[d]);
|
|
bl += len_eb;
|
|
}
|
|
|
|
d = DST_LN_RE[boff - match];
|
|
bl = write_bits_8(out, bl, bitswap8[d]>>3);
|
|
bl -= 3;
|
|
|
|
var dst_eb = d < 4 ? 0 : (d-2)>>1;
|
|
if(dst_eb > 0) {
|
|
write_bits_16(out, bl, boff - match - DST_LN[d]);
|
|
bl += dst_eb;
|
|
}
|
|
for(var q = 0; q < mlen; ++q) {
|
|
addrs[hash] = boff & 0x7FFF;
|
|
hash = ((hash << 5) ^ data[boff]) & 0x7FFF;
|
|
++boff;
|
|
}
|
|
L-= mlen - 1;
|
|
} else {
|
|
/* Literal Token */
|
|
if(d <= 143) d = d + 48;
|
|
else bl = write_bits_1(out, bl, 1);
|
|
bl = write_bits_8(out, bl, bitswap8[d]);
|
|
addrs[hash] = boff & 0x7FFF;
|
|
++boff;
|
|
}
|
|
}
|
|
|
|
bl = write_bits_8(out, bl, 0) - 1;
|
|
}
|
|
out.l = ((bl + 7)/8)|0;
|
|
return out.l;
|
|
}
|
|
return function _deflateRaw(data, out) {
|
|
if(data.length < 8) return write_stored(data, out);
|
|
return write_huff_fixed(data, out);
|
|
};
|
|
})();
|
|
|
|
function _deflate(data) {
|
|
var buf = new_buf(50+Math.floor(data.length*1.1));
|
|
var off = _deflateRaw(data, buf);
|
|
return buf.slice(0, off);
|
|
}
|