js-cfb/bits/79_flate.js

162 lines
5.2 KiB
JavaScript

var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */
var LEN_LN = [ 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 ];
/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */
var DST_LN = [ 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 ];
function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; }
var use_typed_arrays = typeof Uint8Array !== 'undefined';
var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : [];
for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q);
function bit_swap_n(n, b) {
var rev = bitswap8[n & 0xFF];
if(b <= 8) return rev >>> (8-b);
rev = (rev << 8) | bitswap8[(n>>8)&0xFF];
if(b <= 16) return rev >>> (16-b);
rev = (rev << 8) | bitswap8[(n>>16)&0xFF];
return rev >>> (24-b);
}
/* helpers for unaligned bit reads */
function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; }
function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; }
function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; }
function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; }
function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; }
/* works up to n = 3 * 8 + 1 = 25 */
function read_bits_n(buf, bl, n) {
var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1);
var v = buf[h] >>> w;
if(n < 8 - w) return v & f;
v |= buf[h+1]<<(8-w);
if(n < 16 - w) return v & f;
v |= buf[h+2]<<(16-w);
if(n < 24 - w) return v & f;
v |= buf[h+3]<<(24-w);
return v & f;
}
/* helpers for unaligned bit writes */
function write_bits_3(buf, bl, v) { var w = bl & 7, h = bl >>> 3;
if(w <= 5) buf[h] |= (v & 7) << w;
else {
buf[h] |= (v << w) & 0xFF;
buf[h+1] = (v&7) >> (8-w);
}
return bl + 3;
}
function write_bits_1(buf, bl, v) {
var w = bl & 7, h = bl >>> 3;
v = (v&1) << w;
buf[h] |= v;
return bl + 1;
}
function write_bits_8(buf, bl, v) {
var w = bl & 7, h = bl >>> 3;
v <<= w;
buf[h] |= v & 0xFF; v >>>= 8;
buf[h+1] = v;
return bl + 8;
}
function write_bits_16(buf, bl, v) {
var w = bl & 7, h = bl >>> 3;
v <<= w;
buf[h] |= v & 0xFF; v >>>= 8;
buf[h+1] = v & 0xFF;
buf[h+2] = v >>> 8;
return bl + 16;
}
/* until ArrayBuffer#realloc is a thing, fake a realloc */
function realloc(b, sz/*:number*/) {
var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0;
if(L >= sz) return b;
if(has_buf) {
var o = new_unsafe_buf(M);
// $FlowIgnore
if(b.copy) b.copy(o);
else for(; i < b.length; ++i) o[i] = b[i];
return o;
} else if(use_typed_arrays) {
var a = new Uint8Array(M);
if(a.set) a.set(b);
else for(; i < L; ++i) a[i] = b[i];
return a;
}
b.length = M;
return b;
}
/* zero-filled arrays for older browsers */
function zero_fill_array(n) {
var o = new Array(n);
for(var i = 0; i < n; ++i) o[i] = 0;
return o;
}
/* build tree (used for literals and lengths) */
function build_tree(clens, cmap, MAX/*:number*/)/*:number*/ {
var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length;
var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
for(i = 0; i < 32; ++i) bl_count[i] = 0;
for(i = L; i < MAX; ++i) clens[i] = 0;
L = clens.length;
var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // []
/* build code tree */
for(i = 0; i < L; ++i) {
bl_count[(w = clens[i])]++;
if(maxlen < w) maxlen = w;
ctree[i] = 0;
}
bl_count[0] = 0;
for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1);
for(i = 0; i < L; ++i) {
ccode = clens[i];
if(ccode != 0) ctree[i] = bl_count[ccode+16]++;
}
/* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */
var cleni = 0;
for(i = 0; i < L; ++i) {
cleni = clens[i];
if(cleni != 0) {
ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni);
for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j)
cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4);
}
}
return maxlen;
}
/* Fixed Huffman */
var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);
var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
if(!use_typed_arrays) {
for(var i = 0; i < 512; ++i) fix_lmap[i] = 0;
for(i = 0; i < 32; ++i) fix_dmap[i] = 0;
}
(function() {
var dlens/*:Array<number>*/ = [];
var i = 0;
for(;i<32; i++) dlens.push(5);
build_tree(dlens, fix_dmap, 32);
var clens/*:Array<number>*/ = [];
i = 0;
for(; i<=143; i++) clens.push(8);
for(; i<=255; i++) clens.push(9);
for(; i<=279; i++) clens.push(7);
for(; i<=287; i++) clens.push(8);
build_tree(clens, fix_lmap, 288);
})();