📄 deflate.java
字号:
// Initialize the first block of the first file: init_block(); } void init_block() { // Initialize the trees. //for(int i = 0; i < L_CODES; i++) dyn_ltree[i*2] = 0; for (int i = 0; i < L_CODES; i++) { dyn_ltree.set(i * 2, (short) 0); } //for(int i= 0; i < D_CODES; i++) dyn_dtree[i*2] = 0; for (int i = 0; i < D_CODES; i++) { dyn_dtree.set(i * 2, (short) 0); } //for(int i= 0; i < BL_CODES; i++) bl_tree[i*2] = 0; for (int i = 0; i < BL_CODES; i++) { bl_tree.set(i * 2, (short) 0); } //dyn_ltree[END_BLOCK*2] = 1; dyn_ltree.set(END_BLOCK * 2, (short) 1); opt_len = static_len = 0; last_lit = matches = 0; } // Restore the heap property by moving down the tree starting at node k, // exchanging a node with the smallest of its two sons if necessary, stopping // when the heap property is re-established (each father smaller than its // two sons). void pqdownheap(short_array tree, // the tree to restore int k // node to move down ) { int v = heap[k]; int j = k << 1; // left son of k while (j <= heap_len) { // Set j to the smallest of the two sons: if (j < heap_len && smaller(tree, heap[j + 1], heap[j], depth)) { j++; } // Exit if v is smaller than both sons if (smaller(tree, v, heap[j], depth)) { break; } // Exchange v with the smallest son heap[k] = heap[j]; k = j; // And continue down the tree, setting j to the left son of k j <<= 1; } heap[k] = v; } static final boolean smaller(short_array tree, int n, int m, byte_array depth) { //return (tree[n*2] < tree[m*2] || was originally commented // (tree[n*2] == tree[m*2] && depth[n] <= depth[m])); was originally commented //return (tree[n*2] < tree[m*2] || (tree[n*2] == tree[m*2] && depth.get(n)<= depth.get(m))); return (tree.get(n * 2) < tree.get(m * 2) || (tree.get(n * 2) == tree.get(m * 2) && depth.get(n) <= depth.get(m))); } // Scan a literal or distance tree to determine the frequencies of the codes // in the bit length tree. void scan_tree(short_array tree,// the tree to be scanned int max_code // and its largest code of non zero frequency ) { int n; // iterates over all tree elements int prevlen = -1; // last emitted length int curlen; // length of current code //int nextlen = tree[0*2+1]; // length of next code int nextlen = tree.get(0 * 2 + 1); // length of next code int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count if (nextlen == 0) { max_count = 138; min_count = 3; } // tree[(max_code+1)*2+1] = (short)0xffff; // guard tree.set((max_code + 1) * 2 + 1, (short) 0xffff); // guard for (n = 0; n <= max_code; n++) { //curlen = nextlen; nextlen = tree[(n+1)*2+1]; curlen = nextlen; nextlen = tree.get((n + 1) * 2 + 1); if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { //bl_tree[curlen*2] += count; bl_tree.set(curlen * 2, (short) (bl_tree.get(curlen * 2) + count)); } else if (curlen != 0) { //if(curlen != prevlen) bl_tree[curlen*2]++; if (curlen != prevlen) { bl_tree.set(curlen * 2, (short) (bl_tree.get(curlen * 2) + 1)); } //bl_tree[REP_3_6*2]++; bl_tree.set(REP_3_6 * 2, (short) (bl_tree.get(REP_3_6 * 2) + 1)); } else if (count <= 10) { //bl_tree[REPZ_3_10*2]++; bl_tree.set(REPZ_3_10 * 2, (short) (bl_tree.get(REPZ_3_10 * 2) + 1)); } else { //bl_tree[REPZ_11_138*2]++; bl_tree.set(REPZ_11_138 * 2, (short) (bl_tree.get(REPZ_11_138 * 2) + 1)); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138; min_count = 3; } else if (curlen == nextlen) { max_count = 6; min_count = 3; } else { max_count = 7; min_count = 4; } } } // Construct the Huffman tree for the bit lengths and return the index in // bl_order of the last bit length code to send. int build_bl_tree() { int max_blindex; // index of last bit length code of non zero freq // Determine the bit length frequencies for literal and distance trees scan_tree(dyn_ltree, l_desc.max_code); scan_tree(dyn_dtree, d_desc.max_code); // Build the bit length tree: bl_desc.build_tree(this); // opt_len now includes the length of the tree representations, except // the lengths of the bit lengths codes and the 5+5+4 bits for the counts. // Determine the number of bit length codes to send. The pkzip format // requires that at least 4 bit length codes be sent. (appnote.txt says // 3 but the actual value used is 4.) for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) { //if (bl_tree[Tree.bl_order[max_blindex]*2+1] != 0) break; if (bl_tree.get(Tree.bl_order[max_blindex] * 2 + 1) != 0) { break; } } // Update opt_len to include the bit length tree and counts opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; return max_blindex; } // Send the header for a block using dynamic Huffman trees: the counts, the // lengths of the bit length codes, the literal tree and the distance tree. // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. void send_all_trees(int lcodes, int dcodes, int blcodes) { int rank; // index in bl_order send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt send_bits(dcodes - 1, 5); send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt for (rank = 0; rank < blcodes; rank++) { //send_bits(bl_tree[Tree.bl_order[rank]*2+1], 3); send_bits(bl_tree.get(Tree.bl_order[rank] * 2 + 1), 3); }//for send_tree(dyn_ltree, lcodes - 1); // literal tree send_tree(dyn_dtree, dcodes - 1); // distance tree } // Send a literal or distance tree in compressed form, using the codes in // bl_tree. void send_tree(short_array tree,// the tree to be sent int max_code // and its largest code of non zero frequency ) { int n; // iterates over all tree elements int prevlen = -1; // last emitted length int curlen; // length of current code //int nextlen = tree[0*2+1]; // length of next code int nextlen = tree.get(0 * 2 + 1); // length of next code int count = 0; // repeat count of the current code int max_count = 7; // max repeat count int min_count = 4; // min repeat count if (nextlen == 0) { max_count = 138; min_count = 3; } for (n = 0; n <= max_code; n++) { //curlen = nextlen; nextlen = tree[(n+1)*2+1]; curlen = nextlen; nextlen = tree.get((n + 1) * 2 + 1); if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(curlen, bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(curlen, bl_tree); count--; } send_code(REP_3_6, bl_tree); send_bits(count - 3, 2); } else if (count <= 10) { send_code(REPZ_3_10, bl_tree); send_bits(count - 3, 3); } else { send_code(REPZ_11_138, bl_tree); send_bits(count - 11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138; min_count = 3; } else if (curlen == nextlen) { max_count = 6; min_count = 3; } else { max_count = 7; min_count = 4; } } } // Output a byte on the stream. // IN assertion: there is enough room in pending_buf. final void put_byte(byte_array p, int start, int len) { //System.arraycopy(p, start, pending_buf, pending, len); byte_array.Copy(p, start, pending_buf, pending, len); pending += len; } final void put_byte(byte c) { //pending_buf[pending++]=c; pending_buf.set(pending++, c); } final void put_short(int w) { put_byte((byte) (w/*&0xff*/)); put_byte((byte) (w >>> 8)); } final void putShortMSB(int b) { put_byte((byte) (b >> 8)); put_byte((byte) (b/*&0xff*/)); } final void send_code(int c, short_AccessibleArray tree) { //send_bits((tree[c*2]&0xffff), (tree[c*2+1]&0xffff)); send_bits((tree.get(c * 2) & 0xffff), (tree.get(c * 2 + 1) & 0xffff)); } void send_bits(int value, int length) { int len = length; if (bi_valid > (int) Buf_size - len) { int val = value;// bi_buf |= (val << bi_valid); bi_buf |= ((val << bi_valid) & 0xffff); put_short(bi_buf); bi_buf = (short) (val >>> (Buf_size - bi_valid)); bi_valid += len - Buf_size; } else {// bi_buf |= (value) << bi_valid; bi_buf |= (((value) << bi_valid) & 0xffff); bi_valid += len; } } // Send one empty static block to give enough lookahead for inflate. // This takes 10 bits, of which 7 may remain in the bit buffer. // The current inflate code requires 9 bits of lookahead. If the // last two codes for the previous block (real code plus EOB) were coded // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode // the last real code. In this case we send two empty static blocks instead // of one. (There are no problems if the previous block is stored or fixed.) // To simplify the code, we assume the worst case of last real code encoded // on one bit only. void _tr_align() { send_bits(STATIC_TREES << 1, 3); send_code(END_BLOCK, StaticTree.static_ltree); bi_flush(); // Of the 10 bits for the empty block, we have already sent // (10 - bi_valid) bits. The lookahead for the last real code (before // the EOB of the previous block) was thus at least one plus the length
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -