diff --git a/lib/zlib/deflate.js b/lib/zlib/deflate.js index db43b30..0e96d0e 100644 --- a/lib/zlib/deflate.js +++ b/lib/zlib/deflate.js @@ -12,12 +12,20 @@ var MAX_WBITS = 15; /* 32K LZ77 window */ var DEF_MEM_LEVEL = 8; -var D_CODES = 30; -var BL_CODES = 19; var LENGTH_CODES = 29; +/* number of length codes, not counting the special END_BLOCK code */ var LITERALS = 256; +/* number of literal bytes 0..255 */ var L_CODES = LITERALS + 1 + LENGTH_CODES; +/* number of Literal or Length codes, including the END_BLOCK code */ +var D_CODES = 30; +/* number of distance codes */ +var BL_CODES = 19; +/* number of codes used to transfer the bit lengths */ var HEAP_SIZE = 2*L_CODES + 1; +/* maximum heap size */ +var MAX_BITS = 15; +/* All codes must not exceed MAX_BITS bits */ var MIN_MATCH = 3; var MAX_MATCH = 258; @@ -41,10 +49,12 @@ var BS_FINISH_DONE = 4; /* finish done, accept no more input or output */ var OS_CODE = 0x03; // Unix :) . Don't detect, use this default. -function rank (f) { +function rank(f) { return ((f) << 1) - ((f) > 4 ? 9 : 0); } +function zero(buf) { var len = buf.length; while (--len) { buf[len] = 0; } } + /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes @@ -261,17 +271,18 @@ function fill_window(s) { do { more = s.window_size - s.lookahead - s.strstart; - // TODO: this check seems to be needed only for - // 2-byte int-s (16-bit arch) - if (more === 0 && s.strstart === 0 && s.lookahead === 0) { - more = _w_size; - - } else if (more === -1) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } + /* Deal with !@#$% 64K limit: */ + //if (sizeof(int) <= 2) { + // if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + // more = wsize; + // + // } else if (more == (unsigned)(-1)) { + // /* Very unlikely, but possible on 16 bit machine if + // * strstart == 0 && lookahead == 1 (input done a byte at time) + // */ + // more--; + // } + //} /* If the window is almost full and there is insufficient lookahead, @@ -292,8 +303,6 @@ function fill_window(s) { zlib, so we don't care about this pathological case.) */ - // TODO: check if shortlinks to `s.head` & `s.prev` improve speed. - n = s.hash_size; p = n; do { @@ -984,7 +993,7 @@ function lm_init(s) { s.window_size = 2 * s.w_size; /*** CLEAR_HASH(s); ***/ - utils.fill(s.head, 0/*NIL*/); + zero(s.head); // Fill with NIL (= 0); /* Set the default configuration parameters: */ @@ -1100,23 +1109,18 @@ function DeflateState() { /* Didn't use ct_data typedef below to suppress compiler warning */ -// TODO: review effectivity of lazy tree structures init - // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ -// TODO: consider use 2 separate arrays, instead of one interleaved - // Use flat array of DOUBLE size, with interleaved fata, // because JS does not support effective - this.dyn_ltree = new Array(HEAP_SIZE * 2); - this.dyn_dtree = new Array((2*D_CODES+1) * 2); - this.bl_tree = new Array((2*BL_CODES+1) * 2); - // TODO: check if can be skipped - utils.fill(this.dyn_ltree, 0); - utils.fill(this.dyn_dtree, 0); - utils.fill(this.bl_tree, 0); + this.dyn_ltree = utils.array16Create(HEAP_SIZE * 2); + this.dyn_dtree = utils.array16Create((2*D_CODES+1) * 2); + this.bl_tree = utils.array16Create((2*BL_CODES+1) * 2); + zero(this.dyn_ltree); + zero(this.dyn_dtree); + zero(this.bl_tree); // struct tree_desc_s l_desc; /* desc. for literal tree */ // struct tree_desc_s d_desc; /* desc. for distance tree */ @@ -1130,14 +1134,12 @@ function DeflateState() { this.bl_desc = null; /* desc. for bit length tree */ //ush bl_count[MAX_BITS+1]; - this.bl_count = []; - // TODO: fixed size, check if Uint16Array helps + this.bl_count = utils.array16Create(MAX_BITS+1); /* number of codes at each bit length for an optimal tree */ //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - // TODO: fixed size, check if Uint16Array helps - this.heap = new Array(2*L_CODES+1); /* heap used to build the Huffman trees */ - utils.fill(this.heap, 0); + this.heap = utils.array16Create(2*L_CODES+1); /* heap used to build the Huffman trees */ + zero(this.heap); this.heap_len = 0; /* number of elements in the heap */ this.heap_max = 0; /* element of largest frequency */ @@ -1145,8 +1147,8 @@ function DeflateState() { * The same heap array is used to build all trees. */ - this.depth = new Array(2*L_CODES+1); //uch depth[2*L_CODES+1]; - utils.fill(this.depth, 0); + this.depth = utils.array16Create(2*L_CODES+1); //uch depth[2*L_CODES+1]; + zero(this.depth); /* Depth of each subtree used as tie breaker for trees of equal frequency */ @@ -1174,7 +1176,6 @@ function DeflateState() { this.last_lit = 0; /* running index in l_buf */ - // TODO: fixed size, check if Uint8Array helps this.d_buf = 0; /* Buffer index for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag @@ -1460,7 +1461,7 @@ function deflate(strm, flush) { */ if (flush === c.Z_FULL_FLUSH) { /*** CLEAR_HASH(s); ***/ /* forget history */ - utils.fill(s.head, 0/*NIL*/); + zero(s.head); // Fill with NIL (= 0); if (s.lookahead === 0) { s.strstart = 0; diff --git a/lib/zlib/trees.js b/lib/zlib/trees.js index 1837f93..996d1a9 100644 --- a/lib/zlib/trees.js +++ b/lib/zlib/trees.js @@ -4,6 +4,9 @@ var c = require('constants'); var utils = require('./utils'); + +function zero(buf) { var len = buf.length; while (--len) { buf[len] = 0; } } + // From zutil.h var STORED_BLOCK = 0; @@ -89,7 +92,7 @@ var DIST_CODE_LEN = 512; /* see definition of array dist_code below */ // !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1 var static_ltree = new Array((L_CODES+2) * 2); -utils.fill(static_ltree, 0); +zero(static_ltree); /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init @@ -97,28 +100,28 @@ utils.fill(static_ltree, 0); */ var static_dtree = new Array(D_CODES * 2); -utils.fill(static_dtree, 0); +zero(static_dtree); /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ var _dist_code = new Array(DIST_CODE_LEN); -utils.fill(_dist_code, 0); +zero(_dist_code); /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ var _length_code = new Array(MAX_MATCH-MIN_MATCH+1); -utils.fill(_length_code, 0); +zero(_length_code); /* length code for each normalized match length (0 == MIN_MATCH) */ var base_length = new Array(LENGTH_CODES); -utils.fill(base_length, 0); +zero(base_length); /* First normalized length for each code (0 = MIN_MATCH) */ var base_dist = new Array(D_CODES); -utils.fill(base_dist, 0); +zero(base_dist); /* First normalized distance for each code (0 = distance of 1) */ @@ -141,7 +144,6 @@ var static_bl_desc; var TreeDesc = function(dyn_tree, stat_desc) { - // TODO: null or [] ? Check speed this.dyn_tree = dyn_tree; /* the dynamic tree */ this.max_code = 0; /* largest code with non zero frequency */ this.stat_desc = stat_desc; /* the corresponding static tree */ @@ -444,10 +446,7 @@ function tr_static_init() { // Now data ready and we can init static trees static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS); static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS); - // TODO: we could pass empty array instead of null in original - // BUT (!) at first check, that it will not break condition in build_tree() - // static_bl_desc =new StaticTreeDesc([], extra_blbits, 0, BL_CODES, MAX_BL_BITS); - static_bl_desc =new StaticTreeDesc([], extra_blbits, 0, BL_CODES, MAX_BL_BITS); + static_bl_desc =new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS); //static_init_done = true; } @@ -512,7 +511,6 @@ function copy_block(s, buf, len, header) * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ -// TODO: inline manually if deoptimized & if that change speed function smaller(tree, n, m, depth) { var _n2 = n*2; var _m2 = m*2; @@ -531,7 +529,6 @@ function pqdownheap(s, tree, k) // ct_data *tree; /* the tree to restore */ // int k; /* node to move down */ { - // TODO: check if shortcut to `heap` needed var v = s.heap[k]; var j = k << 1; /* left son of k */ while (j <= s.heap_len) { @@ -659,10 +656,8 @@ function build_tree(s, desc) tree[node * 2]/*.Freq*/ = 1; s.depth[node] = 0; s.opt_len--; -// TODO: check this condition! -// see init of `static_bl_desc`, we like set empty array instead of null + if (has_stree) { -// if (stree.length) { s.static_len -= stree[node*2 + 1]/*.Len*/; } /* node is 0 or 1 so it does not have extra bits */ @@ -977,7 +972,6 @@ function _tr_init(s) static_init_done = true; } -// TODO: check that this does not affect speed (we could recreate the class) s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc); s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc); s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc); diff --git a/lib/zlib/utils.js b/lib/zlib/utils.js index 1512308..64caa71 100644 --- a/lib/zlib/utils.js +++ b/lib/zlib/utils.js @@ -84,18 +84,6 @@ exports.array16Create = function (length) { }; -// Fill Array || Typed Array with constant -// -exports.fill = function (buf, val) { - var len = buf.length; - - if (!len) { return;} - - // fastest for untyped Array - while (--len) { buf[len] = val; } -}; - - // Join array of chunks to single array. // Expect Array of (Array(Bytes) || Uint8Array). //