diff --git a/lib/zlib/deflate.js b/lib/zlib/deflate.js index 5ec531a..64fabed 100644 --- a/lib/zlib/deflate.js +++ b/lib/zlib/deflate.js @@ -40,12 +40,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. -var NIL = 0; function rank (f) { return ((f) << 1) - ((f) > 4 ? 9 : 0); } + /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it @@ -73,20 +73,19 @@ function flush_pending(strm) { } } + function flush_block_only (s, last) { trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last); s.block_start = s.strstart; flush_pending(s.strm); } -function update_hash (s, h, c) { - return (((h) << s.hash_shift) ^ (c)) & s.hash_mask; -} function put_byte(s, b) { s.pending_buf[s.pending++] = b; } + /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in @@ -99,6 +98,7 @@ function putShortMSB(s, b) { s.pending_buf[s.pending++] = b & 0xff; } + /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through @@ -147,7 +147,7 @@ function longest_match(s, cur_match) { var best_len = s.prev_length; /* best match length so far */ var nice_match = s.nice_match; /* stop if match long enough */ var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ? - s.strstart - (s.w_size - MIN_LOOKAHEAD) : NIL; + s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/; var _win = s.window; // shortcut @@ -254,13 +254,15 @@ function longest_match(s, cur_match) { */ function fill_window(s) { var _w_size = s.w_size; - var p = 0, n = 0, m = 0, more, str; + var p, n, m, more, str; //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); 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; @@ -334,12 +336,16 @@ function fill_window(s) { if (s.lookahead + s.insert >= MIN_MATCH) { str = s.strstart - s.insert; s.ins_h = s.window[str]; - s.ins_h = update_hash(s, s.ins_h, s.window[str + 1]); + + /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask; //#if MIN_MATCH != 3 // Call update_hash() MIN_MATCH-3 more times //#endif while (s.insert) { - s.ins_h = update_hash(s, s.ins_h, s.window[str + MIN_MATCH - 1]); + /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */ + s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask; + s.prev[str & s.w_mask] = s.head[s.ins_h]; s.head[s.ins_h] = str; str++; @@ -523,7 +529,7 @@ function deflate_fast(s, flush) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ - hash_head = NIL; + hash_head = 0/*NIL*/; if (s.lookahead >= MIN_MATCH) { /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; @@ -536,7 +542,7 @@ function deflate_fast(s, flush) { /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ - if (hash_head !== NIL && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { + if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). @@ -654,7 +660,7 @@ function deflate_slow(s, flush) { /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ - hash_head = NIL; + hash_head = 0/*NIL*/; if (s.lookahead >= MIN_MATCH) { /*** INSERT_STRING(s, s.strstart, hash_head); ***/ s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask; @@ -670,7 +676,7 @@ function deflate_slow(s, flush) { s.prev_match = s.match_start; s.match_length = MIN_MATCH-1; - if (hash_head !== NIL && s.prev_length < s.max_lazy_match && + if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match && s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match @@ -985,7 +991,7 @@ function lm_init(s) { s.window_size = 2 * s.w_size; /*** CLEAR_HASH(s); ***/ - utils.fill(s.head, NIL); + utils.fill(s.head, 0/*NIL*/); /* Set the default configuration parameters: */ @@ -1005,7 +1011,8 @@ function lm_init(s) { var TreeDesc = function() { - this.dyn_tree = []; /* the dynamic tree */ + // TODO: null or [] ? Check speed + this.dyn_tree = null; /* the dynamic tree */ this.max_code = 0; /* largest code with non zero frequency */ this.stat_desc = null; /* the corresponding static tree */ }; @@ -1068,7 +1075,7 @@ function DeflateState() { this.match_length = 0; /* length of best match */ this.prev_match = 0; /* previous match */ - this.match_available = 1; /* set if previous match exists */ + this.match_available = 0; /* set if previous match exists */ this.strstart = 0; /* start of string to insert */ this.match_start = 0; /* start of matching string */ this.lookahead = 0; /* number of valid bytes ahead in window */ @@ -1216,6 +1223,12 @@ function deflateResetKeep(strm) { strm.total_in = strm.total_out = 0; strm.data_type = c.Z_UNKNOWN; + // TODO: enable + /*if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + }*/ + var s = strm.state; s.pending = 0; s.pending_out = 0; @@ -1262,6 +1275,15 @@ function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { windowBits -= 16; } + + // TODO: enable + /*if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) { + return Z_STREAM_ERROR; + }*/ + + if (windowBits === 8) { windowBits = 9; } @@ -1281,7 +1303,7 @@ function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { s.hash_bits = memLevel + 7; s.hash_size = 1 << s.hash_bits; s.hash_mask = s.hash_size - 1; - s.hash_shift = (s.hash_bits + MIN_MATCH - 1) / MIN_MATCH; + s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH); s.window = utils.arrayCreate(s.w_size * 2); s.head = utils.array16Create(s.hash_size); @@ -1294,7 +1316,7 @@ function deflateInit2(strm, level, method, windowBits, memLevel, strategy) { s.pending_buf_size = s.lit_bufsize * 4; s.pending_buf = utils.arrayCreate(s.pending_buf_size); - s.d_buf = Math.floor(s.lit_bufsize / 2); + s.d_buf = s.lit_bufsize >> 1; s.l_buf = (1 + 2) * s.lit_bufsize; s.level = level; @@ -1310,21 +1332,26 @@ function deflateInit(strm, level) { function deflate(strm, flush) { - var s = strm.state; + var old_flush, s; -// if (strm.next_out == Z_NULL || -// (strm.next_in == Z_NULL && strm.avail_in !== 0) || -// (s.status == FINISH_STATE && flush != c.Z_FINISH)) { -// return c.Z_STREAM_ERROR; -// } - if (strm.avail_out === 0) { - return c.Z_BUF_ERROR; - } + // TODO: enable + /*if (strm.next_out == Z_NULL || + (strm.next_in == Z_NULL && strm.avail_in !== 0) || + (s.status == FINISH_STATE && flush != c.Z_FINISH)) { + return c.Z_STREAM_ERROR; + }*/ - s.strm = strm; - /* just in case */ - var old_flush = s.last_flush; - /* value of flush param for previous deflate call */ + s = strm.state; + + // TODO: enable + /*if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + }*/ + + s.strm = strm; /* just in case */ + old_flush = s.last_flush; s.last_flush = flush; /* Write the header */ @@ -1435,17 +1462,19 @@ function deflate(strm, flush) { */ } if (bstate === BS_BLOCK_DONE) { - /*if (flush === c.Z_PARTIAL_FLUSH) { - //todo:_tr_align(s); - } else*/ - if (flush !== c.Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + if (flush === c.Z_PARTIAL_FLUSH) { + // TODO: implement + trees._tr_align(s); + } + else if (flush !== c.Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + trees._tr_stored_block(s, 0, 0, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush === c.Z_FULL_FLUSH) { /*** CLEAR_HASH(s); ***/ /* forget history */ - utils.fill(s.head, NIL); + utils.fill(s.head, 0/*NIL*/); if (s.lookahead === 0) { s.strstart = 0; @@ -1456,8 +1485,7 @@ function deflate(strm, flush) { } flush_pending(strm); if (strm.avail_out === 0) { - s.last_flush = -1; - /* avoid BUF_ERROR at next call, see above */ + s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return c.Z_OK; } } diff --git a/lib/zlib/trees.js b/lib/zlib/trees.js index e28f140..b8c0cef 100644 --- a/lib/zlib/trees.js +++ b/lib/zlib/trees.js @@ -228,7 +228,7 @@ function gen_bitlen(s, desc) /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ - tree[(s.heap[s.heap_max])*2 + 1]/*.Len*/ = 0; /* root of the heap */ + tree[s.heap[s.heap_max]*2 + 1]/*.Len*/ = 0; /* root of the heap */ for (h = s.heap_max+1; h < HEAP_SIZE; h++) { n = s.heap[h]; @@ -305,7 +305,7 @@ function gen_codes(tree, max_code, bl_count) // int max_code; /* largest code with non zero frequency */ // ushf *bl_count; /* number of codes at each bit length */ { - var next_code = [/*MAX_BITS+1*/]; /* next code value for each bit length */ + var next_code = new Array(MAX_BITS+1); /* next code value for each bit length */ var code = 0; /* running code value */ var bits; /* bit index */ var n; /* code index */ @@ -436,7 +436,7 @@ function tr_static_init() { // 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(null, extra_blbits, 0, BL_CODES, MAX_BL_BITS); + static_bl_desc =new StaticTreeDesc(null, extra_blbits, 0, BL_CODES, MAX_BL_BITS); //static_init_done = true; } @@ -462,7 +462,7 @@ function init_block(s) { /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ -function bi_windup (s) +function bi_windup(s) { if (s.bi_valid > 8) { put_short(s, s.bi_buf); @@ -478,7 +478,7 @@ function bi_windup (s) * Copy a stored block, storing first the length and its * one's complement if requested. */ -function copy_block (s, buf, len, header) +function copy_block(s, buf, len, header) //DeflateState *s; //charf *buf; /* the input data */ //unsigned len; /* its length */ @@ -520,6 +520,7 @@ 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) { @@ -628,7 +629,7 @@ function build_tree(s, desc) for (n = 0; n < elems; n++) { if (tree[n * 2]/*.Freq*/ !== 0) { - s.heap[++(s.heap_len)] = max_code = n; + s.heap[++s.heap_len] = max_code = n; s.depth[n] = 0; } else { @@ -642,7 +643,7 @@ function build_tree(s, desc) * two codes of non zero frequency. */ while (s.heap_len < 2) { - node = s.heap[++(s.heap_len)] = (max_code < 2 ? ++max_code : 0); + node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0); tree[node * 2]/*.Freq*/ = 1; s.depth[node] = 0; s.opt_len--; @@ -675,8 +676,8 @@ function build_tree(s, desc) m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */ - s.heap[--(s.heap_max)] = n; /* keep the nodes sorted by frequency */ - s.heap[--(s.heap_max)] = m; + s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */ + s.heap[--s.heap_max] = m; /* Create a new node father of n and m */ tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/; @@ -689,7 +690,7 @@ function build_tree(s, desc) } while (s.heap_len >= 2); - s.heap[--(s.heap_max)] = s.heap[1/*SMALLEST*/]; + s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. @@ -991,7 +992,7 @@ function _tr_stored_block(s, buf, stored_len, last) //int last; /* one if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+(last ? 1 : 0), 3); /* send block type */ - copy_block(s, buf, stored_len, 1); /* with header */ + copy_block(s, buf, stored_len, true); /* with header */ } /* ===========================================================================