📄 deflate.java
字号:
// but we will ignore the current match anyway. match_length = MIN_MATCH - 1; } } // If there was a match at the previous step and the current // match is not better, output the previous match: if (prev_length >= MIN_MATCH && match_length <= prev_length) { int max_insert = strstart + lookahead - MIN_MATCH; // Do not insert strings in hash table beyond this. // check_match(strstart-1, prev_match, prev_length); bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); // Insert in hash table all strings up to the end of the match. // strstart-1 and strstart are already inserted. If there is not // enough lookahead, the last two strings are not inserted in // the hash table. lookahead -= prev_length - 1; prev_length -= 2; do { if (++strstart <= max_insert) { //ins_h=(((ins_h)<<hash_shift)^(window[(strstart)+(MIN_MATCH-1)]&0xff))&hash_mask; ins_h = (((ins_h) << hash_shift) ^ (window.get((strstart) + (MIN_MATCH - 1)) & 0xff)) & hash_mask; //hash_head=(head[ins_h]&0xffff); hash_head = (head.get(ins_h) & 0xffff); //prev[strstart&w_mask]=head[ins_h]; prev.set(strstart & w_mask, head.get(ins_h)); //head[ins_h]=(short)strstart; head.set(ins_h, (short) strstart); } } while (--prev_length != 0); match_available = 0; match_length = MIN_MATCH - 1; strstart++; if (bflush) { flush_block_only(false); if (strm.avail_out == 0) { return NeedMore; } } } else if (match_available != 0) { // If there was no match at the previous position, output a // single literal. If there was a match but the current match // is longer, truncate the previous match to a single literal. //bflush=_tr_tally(0, window[strstart-1]&0xff); bflush = _tr_tally(0, window.get(strstart - 1) & 0xff); if (bflush) { flush_block_only(false); } strstart++; lookahead--; if (strm.avail_out == 0) { return NeedMore; } } else { // There is no previous match to compare with, wait for // the next step to decide. match_available = 1; strstart++; lookahead--; } } if (match_available != 0) { //bflush=_tr_tally(0, window[strstart-1]&0xff); bflush = _tr_tally(0, window.get(strstart - 1) & 0xff); match_available = 0; } flush_block_only(flush == Z_FINISH); if (strm.avail_out == 0) { if (flush == Z_FINISH) { return FinishStarted; } else { return NeedMore; } } return flush == Z_FINISH ? FinishDone : BlockDone; } int longest_match(int cur_match) { int chain_length = max_chain_length; // max hash chain length int scan = strstart; // current string int match; // matched string int len; // length of current match int best_len = prev_length; // best match length so far int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; int nice_match = this.nice_match; // Stop when cur_match becomes <= limit. To simplify the code, // we prevent matches with the string of window index 0. int wmask = w_mask; int strend = strstart + MAX_MATCH; //byte scan_end1 = window[scan+best_len-1]; //byte scan_end = window[scan+best_len]; byte scan_end1 = window.get(scan + best_len - 1); byte scan_end = window.get(scan + best_len); // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. // It is easy to get rid of this optimization if necessary. // Do not waste too much time if we already have a good match: if (prev_length >= good_match) { chain_length >>= 2; } // Do not look for matches beyond the end of the input. This is necessary // to make deflate deterministic. if (nice_match > lookahead) { nice_match = lookahead; } do { match = cur_match; // Skip to next match if the match length cannot increase // or if the match length is less than 2: // if (window[match+best_len] != scan_end || // window[match+best_len-1] != scan_end1 || // window[match] != window[scan] || // window[++match] != window[scan+1]) continue; if (window.get(match + best_len) != scan_end || window.get(match + best_len - 1) != scan_end1 || window.get(match) != window.get(scan) || window.get(++match) != window.get(scan + 1)) { continue; } // The check at best_len-1 can be removed because it will be made // again later. (This heuristic is not always a win.) // It is not necessary to compare scan[2] and match[2] since they // are always equal when the other bytes match, given that // the hash keys are equal and that HASH_BITS >= 8. scan += 2; match++; // We check for insufficient lookahead only every 8th comparison; // the 256th check will be made at strstart+258. do { //} while (window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // window[++scan] == window[++match] && // scan < strend); } while (window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && window.get(++scan) == window.get(++match) && scan < strend); len = MAX_MATCH - (int) (strend - scan); scan = strend - MAX_MATCH; if (len > best_len) { match_start = cur_match; best_len = len; if (len >= nice_match) { break; } //scan_end1 = window[scan+best_len-1]; //scan_end = window[scan+best_len]; scan_end1 = window.get(scan + best_len - 1); scan_end = window.get(scan + best_len); } //} while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit } while ((cur_match = (prev.get(cur_match & wmask) & 0xffff)) > limit && --chain_length != 0); if (best_len <= lookahead) { return best_len; } return lookahead; } int deflateInit(ZStream strm, int level, int bits) { return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); } int deflateInit(ZStream strm, int level) { return deflateInit(strm, level, MAX_WBITS); } int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy) { int noheader = 0; // byte[] my_version=ZLIB_VERSION; // // if (version == null || version[0] != my_version[0] // || stream_size != sizeof(z_stream)) { // return Z_VERSION_ERROR; // } strm.msg = null; if (level == Z_DEFAULT_COMPRESSION) { level = 6; } if (windowBits < 0) { // undocumented feature: suppress zlib header noheader = 1; windowBits = -windowBits; } if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { return Z_STREAM_ERROR; } strm.dstate = (Deflate) this; this.noheader = noheader; w_bits = windowBits; w_size = 1 << w_bits; w_mask = w_size - 1; hash_bits = memLevel + 7; hash_size = 1 << hash_bits; hash_mask = hash_size - 1; hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); window = new_byte(w_size * 2, 500, "window"); prev = new_short2(w_size, 256, "prev"); head = new_short2(hash_size, 256, "head");//32kb not depend on amount of data lit_bufsize = 1 << (memLevel + 6); // 16K elements by default // We overlay pending_buf and d_buf+l_buf. This works since the average // output size for (length,distance) codes is <= 24 bits. pending_buf = new_byte(lit_bufsize * 4, 500, "pending_buf"); pending_buf_size = lit_bufsize * 4; d_buf = lit_bufsize / 2; l_buf = (1 + 2) * lit_bufsize; this.level = level;//System.out.println("level="+level); this.strategy = strategy; this.method = (byte) method; return deflateReset(strm); } int deflateReset(ZStream strm) { strm.total_in = strm.total_out = 0; strm.msg = null; // strm.data_type = Z_UNKNOWN; pending = 0; pending_out = 0; if (noheader < 0) { noheader = 0; // was set to -1 by deflate(..., Z_FINISH); } status = (noheader != 0) ? BUSY_STATE : INIT_STATE; strm.adler = strm._adler.adler32(0, (byte_array) null, 0, 0); last_flush = Z_NO_FLUSH; tr_init(); lm_init(); return Z_OK; } int deflateEnd() { if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } // Deallocate in reverse order of allocations: pending_buf = null; head = null; prev = null; window = null; // free // dstate=null; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } int deflateParams(ZStream strm, in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -