📄 deflate.java
字号:
// of the EOB plus what we have just sent of the empty static block. if (1 + last_eob_len + 10 - bi_valid < 9) { send_bits(STATIC_TREES << 1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); } last_eob_len = 7; } // Save the match info and tally the frequency counts. Return true if // the current block must be flushed. boolean _tr_tally(int dist, // distance of matched string int lc // match length-MIN_MATCH or unmatched char (if dist==0) ) { //pending_buf[d_buf+last_lit*2] = (byte)(dist>>>8); //pending_buf[d_buf+last_lit*2+1] = (byte)dist; //pending_buf[l_buf+last_lit] = (byte)lc; last_lit++; pending_buf.set(d_buf + last_lit * 2, (byte) (dist >>> 8)); pending_buf.set(d_buf + last_lit * 2 + 1, (byte) dist); pending_buf.set(l_buf + last_lit, (byte) lc); last_lit++; if (dist == 0) { // lc is the unmatched char //dyn_ltree[lc*2]++; dyn_ltree.set(lc * 2, (short) ((dyn_ltree.get(lc * 2)) + 1)); } else { matches++; // Here, lc is the match length - MIN_MATCH dist--; // dist = match distance - 1 //dyn_ltree[(Tree._length_code[lc]+LITERALS+1)*2]++; dyn_ltree.set((Tree._length_code[lc] + LITERALS + 1) * 2, (short) (dyn_ltree.get((Tree._length_code[lc] + LITERALS + 1) * 2) + 1)); //dyn_dtree[Tree.d_code(dist)*2]++; dyn_dtree.set(Tree.d_code(dist) * 2, (short) (dyn_dtree.get(Tree.d_code(dist) * 2) + 1)); } if ((last_lit & 0x1fff) == 0 && level > 2) { // Compute an upper bound for the compressed length int out_length = last_lit * 8; int in_length = strstart - block_start; int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { //out_length += (int)dyn_dtree[dcode*2] * (5L+Tree.extra_dbits[dcode]); out_length += (int) dyn_dtree.get(dcode * 2) * (5L + Tree.extra_dbits[dcode]); } out_length >>>= 3; if ((matches < (last_lit / 2)) && out_length < in_length / 2) { return true; } } return (last_lit == lit_bufsize - 1); // We avoid equality with lit_bufsize because of wraparound at 64K // on 16 bit machines and because stored blocks are restricted to // 64K-1 bytes. } // Send the block data compressed using the given Huffman trees void compress_block(short_AccessibleArray ltree, short_AccessibleArray dtree) { int dist; // distance of matched string int lc; // match length or unmatched char (if dist == 0) int lx = 0; // running index in l_buf int code; // the code to send int extra; // number of extra bits to send if (last_lit != 0) { do { //dist=((pending_buf[d_buf+lx*2]<<8)&0xff00) | (pending_buf[d_buf+lx*2+1]&0xff); //lc=(pending_buf[l_buf+lx])&0xff; lx++; dist = ((pending_buf.get(d_buf + lx * 2) << 8) & 0xff00) | (pending_buf.get(d_buf + lx * 2 + 1) & 0xff); lc = (pending_buf.get(l_buf + lx)) & 0xff; lx++; if (dist == 0) { send_code(lc, ltree); // send a literal byte } else { // Here, lc is the match length - MIN_MATCH code = Tree._length_code[lc]; send_code(code + LITERALS + 1, ltree); // send the length code extra = Tree.extra_lbits[code]; if (extra != 0) { lc -= Tree.base_length[code]; send_bits(lc, extra); // send the extra length bits } dist--; // dist is now the match distance - 1 code = Tree.d_code(dist); send_code(code, dtree); // send the distance code extra = Tree.extra_dbits[code]; if (extra != 0) { dist -= Tree.base_dist[code]; send_bits(dist, extra); // send the extra distance bits } } // literal or match pair ? // Check that the overlay between pending_buf and d_buf+l_buf is ok: } while (lx < last_lit); } send_code(END_BLOCK, ltree); //last_eob_len = ltree[END_BLOCK*2+1]; last_eob_len = ltree.get(END_BLOCK * 2 + 1); } // Set the data type to ASCII or BINARY, using a crude approximation: // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. // IN assertion: the fields freq of dyn_ltree are set and the total of all // frequencies does not exceed 64K (to fit in an int on 16 bit machines). void set_data_type() { int n = 0; int ascii_freq = 0; int bin_freq = 0; //while(n<7){ bin_freq += dyn_ltree[n*2]; n++;} while (n < 7) { bin_freq += dyn_ltree.get(n * 2); n++; } //while(n<128){ ascii_freq += dyn_ltree[n*2]; n++;} while (n < 128) { ascii_freq += dyn_ltree.get(n * 2); n++; } //while(n<LITERALS){ bin_freq += dyn_ltree[n*2]; n++;} while (n < LITERALS) { bin_freq += dyn_ltree.get(n * 2); n++; } data_type = (byte) (bin_freq > (ascii_freq >>> 2) ? Z_BINARY : Z_ASCII); } // Flush the bit buffer, keeping at most 7 bits in it. void bi_flush() { if (bi_valid == 16) { put_short(bi_buf); bi_buf = 0; bi_valid = 0; } else if (bi_valid >= 8) { put_byte((byte) bi_buf); bi_buf >>>= 8; bi_valid -= 8; } } // Flush the bit buffer and align the output on a byte boundary void bi_windup() { if (bi_valid > 8) { put_short(bi_buf); } else if (bi_valid > 0) { put_byte((byte) bi_buf); } bi_buf = 0; bi_valid = 0; } // Copy a stored block, storing first the length and its // one's complement if requested. void copy_block(int buf, // the input data int len, // its length boolean header // true if block header must be written ) { int index = 0; bi_windup(); // align on byte boundary last_eob_len = 8; // enough lookahead for inflate if (header) { put_short((short) len); put_short((short) ~len); } // while(len--!=0) { // put_byte(window[buf+index]); // index++; // } put_byte(window, buf, len); } void flush_block_only(boolean eof) { _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); block_start = strstart; strm.flush_pending(); } // Copy without compression as much as possible from the input stream, return // the current block state. // This function does not insert new strings in the dictionary since // uncompressible data is probably not useful. This function is used // only for the level=0 compression option. // NOTE: this function should be optimized to avoid extra copying from // window to pending_buf. int deflate_stored(int flush) { // Stored blocks are limited to 0xffff bytes, pending_buf is limited // to pending_buf_size, and each stored block has a 5 byte header: int max_block_size = 0xffff; int max_start; if (max_block_size > pending_buf_size - 5) { max_block_size = pending_buf_size - 5; } // Copy as much as possible from input to output: while (true) { // Fill the window as much as possible: if (lookahead <= 1) { fill_window(); if (lookahead == 0 && flush == Z_NO_FLUSH) { return NeedMore; } if (lookahead == 0) { break; } // flush the current block } strstart += lookahead; lookahead = 0; // Emit a stored block if pending_buf will be full: max_start = block_start + max_block_size; if (strstart == 0 || strstart >= max_start) { // strstart == 0 is possible when wraparound on 16-bit machine lookahead = (int) (strstart - max_start); strstart = (int) max_start; flush_block_only(false); if (strm.avail_out == 0) { return NeedMore; } } // Flush if we may have to slide, otherwise block_start may become // negative and the data will be gone: if (strstart - block_start >= w_size - MIN_LOOKAHEAD) { flush_block_only(false); if (strm.avail_out == 0) { return NeedMore; } } } flush_block_only(flush == Z_FINISH); if (strm.avail_out == 0) { return (flush == Z_FINISH) ? FinishStarted : NeedMore; } return flush == Z_FINISH ? FinishDone : BlockDone; } // Send a stored block void _tr_stored_block(int buf, // input block int stored_len, // length of input block boolean eof // true if this is the last block for a file ) { send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type copy_block(buf, stored_len, true); // with header } // Determine the best encoding for the current block: dynamic trees, static // trees or store, and output the encoded block to the zip file. void _tr_flush_block(int buf, // input block, or NULL if too old int stored_len, // length of input block boolean eof // true if this is the last block for a file ) { int opt_lenb, static_lenb;// opt_len and static_len in bytes int max_blindex = 0; // index of last bit length code of non zero freq // Build the Huffman trees unless a stored block is forced if (level > 0) { // Check if the file is ascii or binary if (data_type == Z_UNKNOWN) { set_data_type(); } // Construct the literal and distance trees l_desc.build_tree(this); d_desc.build_tree(this); // At this point, opt_len and static_len are the total bit lengths of // the compressed block data, excluding the tree representations. // Build the bit length tree for the above two trees, and get the index // in bl_order of the last bit length code to send. max_blindex = build_bl_tree(); // Determine the best encoding. Compute first the block length in bytes opt_lenb = (opt_len + 3 + 7) >>> 3; static_lenb = (static_len + 3 + 7) >>> 3; if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; } } else { opt_lenb = static_lenb = stored_len + 5; // force a stored block
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -