+++ /dev/null
-// DeflaterHuffman.cs\r
-// Copyright (C) 2001 Mike Krueger\r
-//\r
-// This file was translated from java, it was part of the GNU Classpath\r
-// Copyright (C) 2001 Free Software Foundation, Inc.\r
-//\r
-// This program is free software; you can redistribute it and/or\r
-// modify it under the terms of the GNU General Public License\r
-// as published by the Free Software Foundation; either version 2\r
-// of the License, or (at your option) any later version.\r
-//\r
-// This program is distributed in the hope that it will be useful,\r
-// but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-// GNU General Public License for more details.\r
-//\r
-// You should have received a copy of the GNU General Public License\r
-// along with this program; if not, write to the Free Software\r
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
-//\r
-// Linking this library statically or dynamically with other modules is\r
-// making a combined work based on this library. Thus, the terms and\r
-// conditions of the GNU General Public License cover the whole\r
-// combination.\r
-// \r
-// As a special exception, the copyright holders of this library give you\r
-// permission to link this library with independent modules to produce an\r
-// executable, regardless of the license terms of these independent\r
-// modules, and to copy and distribute the resulting executable under\r
-// terms of your choice, provided that you also meet, for each linked\r
-// independent module, the terms and conditions of the license of that\r
-// module. An independent module is a module which is not derived from\r
-// or based on this library. If you modify this library, you may extend\r
-// this exception to your version of the library, but you are not\r
-// obligated to do so. If you do not wish to do so, delete this\r
-// exception statement from your version.\r
-\r
-using System;\r
-\r
-namespace ICSharpCode.SharpZipLib.Zip.Compression \r
-{\r
- \r
- /// <summary>\r
- /// This is the DeflaterHuffman class.\r
- /// \r
- /// This class is <i>not</i> thread safe. This is inherent in the API, due\r
- /// to the split of deflate and setInput.\r
- /// \r
- /// author of the original java version : Jochen Hoenicke\r
- /// </summary>\r
- public class DeflaterHuffman\r
- {\r
- private static int BUFSIZE = 1 << (DeflaterConstants.DEFAULT_MEM_LEVEL + 6);\r
- private static int LITERAL_NUM = 286;\r
- private static int DIST_NUM = 30;\r
- private static int BITLEN_NUM = 19;\r
- private static int REP_3_6 = 16;\r
- private static int REP_3_10 = 17;\r
- private static int REP_11_138 = 18;\r
- private static int EOF_SYMBOL = 256;\r
- private static int[] BL_ORDER = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };\r
- \r
- private static byte[] bit4Reverse = {\r
- 0,\r
- 8,\r
- 4,\r
- 12,\r
- 2,\r
- 10,\r
- 6,\r
- 14,\r
- 1,\r
- 9,\r
- 5,\r
- 13,\r
- 3,\r
- 11,\r
- 7,\r
- 15\r
- };\r
- \r
- public class Tree \r
- {\r
- public short[] freqs;\r
- public byte[] length;\r
- public int minNumCodes, numCodes;\r
- \r
- short[] codes;\r
- int[] bl_counts;\r
- int maxLength;\r
- DeflaterHuffman dh;\r
- \r
- public Tree(DeflaterHuffman dh, int elems, int minCodes, int maxLength) \r
- {\r
- this.dh = dh;\r
- this.minNumCodes = minCodes;\r
- this.maxLength = maxLength;\r
- freqs = new short[elems];\r
- bl_counts = new int[maxLength];\r
- }\r
- \r
- public void Reset() \r
- {\r
- for (int i = 0; i < freqs.Length; i++) {\r
- freqs[i] = 0;\r
- }\r
- codes = null;\r
- length = null;\r
- }\r
- \r
- public void WriteSymbol(int code)\r
- {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // freqs[code]--;\r
- // // Console.Write("writeSymbol("+freqs.length+","+code+"): ");\r
- // }\r
- dh.pending.WriteBits(codes[code] & 0xffff, length[code]);\r
- }\r
- \r
- public void CheckEmpty()\r
- {\r
- bool empty = true;\r
- for (int i = 0; i < freqs.Length; i++) {\r
- if (freqs[i] != 0) {\r
- //Console.WriteLine("freqs["+i+"] == "+freqs[i]);\r
- empty = false;\r
- }\r
- }\r
- if (!empty) {\r
- throw new Exception();\r
- }\r
- //Console.WriteLine("checkEmpty suceeded!");\r
- }\r
- \r
- public void SetStaticCodes(short[] stCodes, byte[] stLength)\r
- {\r
- codes = stCodes;\r
- length = stLength;\r
- }\r
- \r
- public void BuildCodes() \r
- {\r
- int numSymbols = freqs.Length;\r
- int[] nextCode = new int[maxLength];\r
- int code = 0;\r
- codes = new short[freqs.Length];\r
- \r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("buildCodes: "+freqs.Length);\r
- // }\r
- \r
- for (int bits = 0; bits < maxLength; bits++) {\r
- nextCode[bits] = code;\r
- code += bl_counts[bits] << (15 - bits);\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("bits: "+(bits+1)+" count: "+bl_counts[bits]\r
- // +" nextCode: "+code); // HACK : Integer.toHexString(\r
- // }\r
- }\r
- if (DeflaterConstants.DEBUGGING && code != 65536) {\r
- throw new Exception("Inconsistent bl_counts!");\r
- }\r
- \r
- for (int i=0; i < numCodes; i++) {\r
- int bits = length[i];\r
- if (bits > 0) {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("codes["+i+"] = rev(" + nextCode[bits-1]+")," // HACK : Integer.toHexString(\r
- // +bits);\r
- // }\r
- codes[i] = BitReverse(nextCode[bits-1]);\r
- nextCode[bits-1] += 1 << (16 - bits);\r
- }\r
- }\r
- }\r
- \r
- void BuildLength(int[] childs)\r
- {\r
- this.length = new byte [freqs.Length];\r
- int numNodes = childs.Length / 2;\r
- int numLeafs = (numNodes + 1) / 2;\r
- int overflow = 0;\r
- \r
- for (int i = 0; i < maxLength; i++) {\r
- bl_counts[i] = 0;\r
- }\r
- \r
- /* First calculate optimal bit lengths */\r
- int[] lengths = new int[numNodes];\r
- lengths[numNodes-1] = 0;\r
- \r
- for (int i = numNodes - 1; i >= 0; i--) {\r
- if (childs[2*i+1] != -1) {\r
- int bitLength = lengths[i] + 1;\r
- if (bitLength > maxLength) {\r
- bitLength = maxLength;\r
- overflow++;\r
- }\r
- lengths[childs[2*i]] = lengths[childs[2*i+1]] = bitLength;\r
- } else {\r
- /* A leaf node */\r
- int bitLength = lengths[i];\r
- bl_counts[bitLength - 1]++;\r
- this.length[childs[2*i]] = (byte) lengths[i];\r
- }\r
- }\r
- \r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("Tree "+freqs.Length+" lengths:");\r
- // for (int i=0; i < numLeafs; i++) {\r
- // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]\r
- // + " len: "+length[childs[2*i]]);\r
- // }\r
- // }\r
- \r
- if (overflow == 0) {\r
- return;\r
- }\r
- \r
- int incrBitLen = maxLength - 1;\r
- do {\r
- /* Find the first bit length which could increase: */\r
- while (bl_counts[--incrBitLen] == 0)\r
- ;\r
- \r
- /* Move this node one down and remove a corresponding\r
- * amount of overflow nodes.\r
- */\r
- do {\r
- bl_counts[incrBitLen]--;\r
- bl_counts[++incrBitLen]++;\r
- overflow -= 1 << (maxLength - 1 - incrBitLen);\r
- } while (overflow > 0 && incrBitLen < maxLength - 1);\r
- } while (overflow > 0);\r
- \r
- /* We may have overshot above. Move some nodes from maxLength to\r
- * maxLength-1 in that case.\r
- */\r
- bl_counts[maxLength-1] += overflow;\r
- bl_counts[maxLength-2] -= overflow;\r
- \r
- /* Now recompute all bit lengths, scanning in increasing\r
- * frequency. It is simpler to reconstruct all lengths instead of\r
- * fixing only the wrong ones. This idea is taken from 'ar'\r
- * written by Haruhiko Okumura.\r
- *\r
- * The nodes were inserted with decreasing frequency into the childs\r
- * array.\r
- */\r
- int nodePtr = 2 * numLeafs;\r
- for (int bits = maxLength; bits != 0; bits--) {\r
- int n = bl_counts[bits-1];\r
- while (n > 0) {\r
- int childPtr = 2*childs[nodePtr++];\r
- if (childs[childPtr + 1] == -1) {\r
- /* We found another leaf */\r
- length[childs[childPtr]] = (byte) bits;\r
- n--;\r
- }\r
- }\r
- }\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("*** After overflow elimination. ***");\r
- // for (int i=0; i < numLeafs; i++) {\r
- // //Console.WriteLine("Node "+childs[2*i]+" freq: "+freqs[childs[2*i]]\r
- // + " len: "+length[childs[2*i]]);\r
- // }\r
- // }\r
- }\r
- \r
- public void BuildTree()\r
- {\r
- int numSymbols = freqs.Length;\r
- \r
- /* heap is a priority queue, sorted by frequency, least frequent\r
- * nodes first. The heap is a binary tree, with the property, that\r
- * the parent node is smaller than both child nodes. This assures\r
- * that the smallest node is the first parent.\r
- *\r
- * The binary tree is encoded in an array: 0 is root node and\r
- * the nodes 2*n+1, 2*n+2 are the child nodes of node n.\r
- */\r
- int[] heap = new int[numSymbols];\r
- int heapLen = 0;\r
- int maxCode = 0;\r
- for (int n = 0; n < numSymbols; n++) {\r
- int freq = freqs[n];\r
- if (freq != 0) {\r
- /* Insert n into heap */\r
- int pos = heapLen++;\r
- int ppos;\r
- while (pos > 0 && freqs[heap[ppos = (pos - 1) / 2]] > freq) {\r
- heap[pos] = heap[ppos];\r
- pos = ppos;\r
- }\r
- heap[pos] = n;\r
- \r
- maxCode = n;\r
- }\r
- }\r
- \r
- /* We could encode a single literal with 0 bits but then we\r
- * don't see the literals. Therefore we force at least two\r
- * literals to avoid this case. We don't care about order in\r
- * this case, both literals get a 1 bit code.\r
- */\r
- while (heapLen < 2) {\r
- int node = maxCode < 2 ? ++maxCode : 0;\r
- heap[heapLen++] = node;\r
- }\r
- \r
- numCodes = Math.Max(maxCode + 1, minNumCodes);\r
- \r
- int numLeafs = heapLen;\r
- int[] childs = new int[4*heapLen - 2];\r
- int[] values = new int[2*heapLen - 1];\r
- int numNodes = numLeafs;\r
- for (int i = 0; i < heapLen; i++) {\r
- int node = heap[i];\r
- childs[2*i] = node;\r
- childs[2*i+1] = -1;\r
- values[i] = freqs[node] << 8;\r
- heap[i] = i;\r
- }\r
- \r
- /* Construct the Huffman tree by repeatedly combining the least two\r
- * frequent nodes.\r
- */\r
- do {\r
- int first = heap[0];\r
- int last = heap[--heapLen];\r
- \r
- /* Propagate the hole to the leafs of the heap */\r
- int ppos = 0;\r
- int path = 1;\r
- \r
- while (path < heapLen) {\r
- if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {\r
- path++;\r
- }\r
- \r
- heap[ppos] = heap[path];\r
- ppos = path;\r
- path = path * 2 + 1;\r
- }\r
- \r
- /* Now propagate the last element down along path. Normally\r
- * it shouldn't go too deep.\r
- */\r
- int lastVal = values[last];\r
- while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {\r
- heap[path] = heap[ppos];\r
- }\r
- heap[path] = last;\r
- \r
- \r
- int second = heap[0];\r
- \r
- /* Create a new node father of first and second */\r
- last = numNodes++;\r
- childs[2*last] = first;\r
- childs[2*last+1] = second;\r
- int mindepth = Math.Min(values[first] & 0xff, values[second] & 0xff);\r
- values[last] = lastVal = values[first] + values[second] - mindepth + 1;\r
- \r
- /* Again, propagate the hole to the leafs */\r
- ppos = 0;\r
- path = 1;\r
- \r
- while (path < heapLen) {\r
- if (path + 1 < heapLen && values[heap[path]] > values[heap[path+1]]) {\r
- path++;\r
- }\r
- \r
- heap[ppos] = heap[path];\r
- ppos = path;\r
- path = ppos * 2 + 1;\r
- }\r
- \r
- /* Now propagate the new element down along path */\r
- while ((path = ppos) > 0 && values[heap[ppos = (path - 1)/2]] > lastVal) {\r
- heap[path] = heap[ppos];\r
- }\r
- heap[path] = last;\r
- } while (heapLen > 1);\r
- \r
- if (heap[0] != childs.Length / 2 - 1) {\r
- throw new Exception("Weird!");\r
- }\r
- BuildLength(childs);\r
- }\r
- \r
- public int GetEncodedLength()\r
- {\r
- int len = 0;\r
- for (int i = 0; i < freqs.Length; i++) {\r
- len += freqs[i] * length[i];\r
- }\r
- return len;\r
- }\r
- \r
- public void CalcBLFreq(Tree blTree) \r
- {\r
- int max_count; /* max repeat count */\r
- int min_count; /* min repeat count */\r
- int count; /* repeat count of the current code */\r
- int curlen = -1; /* length of current code */\r
- \r
- int i = 0;\r
- while (i < numCodes) {\r
- count = 1;\r
- int nextlen = length[i];\r
- if (nextlen == 0) {\r
- max_count = 138;\r
- min_count = 3;\r
- } else {\r
- max_count = 6;\r
- min_count = 3;\r
- if (curlen != nextlen) {\r
- blTree.freqs[nextlen]++;\r
- count = 0;\r
- }\r
- }\r
- curlen = nextlen;\r
- i++;\r
- \r
- while (i < numCodes && curlen == length[i]) {\r
- i++;\r
- if (++count >= max_count) {\r
- break;\r
- }\r
- }\r
- \r
- if (count < min_count) {\r
- blTree.freqs[curlen] += (short)count;\r
- } else if (curlen != 0) {\r
- blTree.freqs[REP_3_6]++;\r
- } else if (count <= 10) {\r
- blTree.freqs[REP_3_10]++;\r
- } else {\r
- blTree.freqs[REP_11_138]++;\r
- }\r
- }\r
- }\r
- \r
- public void WriteTree(Tree blTree)\r
- {\r
- int max_count; /* max repeat count */\r
- int min_count; /* min repeat count */\r
- int count; /* repeat count of the current code */\r
- int curlen = -1; /* length of current code */\r
- \r
- int i = 0;\r
- while (i < numCodes) {\r
- count = 1;\r
- int nextlen = length[i];\r
- if (nextlen == 0) {\r
- max_count = 138;\r
- min_count = 3;\r
- } else {\r
- max_count = 6;\r
- min_count = 3;\r
- if (curlen != nextlen) {\r
- blTree.WriteSymbol(nextlen);\r
- count = 0;\r
- }\r
- }\r
- curlen = nextlen;\r
- i++;\r
- \r
- while (i < numCodes && curlen == length[i]) {\r
- i++;\r
- if (++count >= max_count) {\r
- break;\r
- }\r
- }\r
- \r
- if (count < min_count) {\r
- while (count-- > 0) {\r
- blTree.WriteSymbol(curlen);\r
- }\r
- } else if (curlen != 0) {\r
- blTree.WriteSymbol(REP_3_6);\r
- dh.pending.WriteBits(count - 3, 2);\r
- } else if (count <= 10) {\r
- blTree.WriteSymbol(REP_3_10);\r
- dh.pending.WriteBits(count - 3, 3);\r
- } else {\r
- blTree.WriteSymbol(REP_11_138);\r
- dh.pending.WriteBits(count - 11, 7);\r
- }\r
- }\r
- }\r
- }\r
- \r
- public DeflaterPending pending;\r
- private Tree literalTree, distTree, blTree;\r
- \r
- private short[] d_buf;\r
- private byte[] l_buf;\r
- private int last_lit;\r
- private int extra_bits;\r
- \r
- private static short[] staticLCodes;\r
- private static byte[] staticLLength;\r
- private static short[] staticDCodes;\r
- private static byte[] staticDLength;\r
- \r
- /// <summary>\r
- /// Reverse the bits of a 16 bit value.\r
- /// </summary>\r
- public static short BitReverse(int value) \r
- {\r
- return (short) (bit4Reverse[value & 0xF] << 12 | \r
- bit4Reverse[(value >> 4) & 0xF] << 8 | \r
- bit4Reverse[(value >> 8) & 0xF] << 4 |\r
- bit4Reverse[value >> 12]);\r
- }\r
- \r
- \r
- static DeflaterHuffman() \r
- {\r
- /* See RFC 1951 3.2.6 */\r
- /* Literal codes */\r
- staticLCodes = new short[LITERAL_NUM];\r
- staticLLength = new byte[LITERAL_NUM];\r
- int i = 0;\r
- while (i < 144) {\r
- staticLCodes[i] = BitReverse((0x030 + i) << 8);\r
- staticLLength[i++] = 8;\r
- }\r
- while (i < 256) {\r
- staticLCodes[i] = BitReverse((0x190 - 144 + i) << 7);\r
- staticLLength[i++] = 9;\r
- }\r
- while (i < 280) {\r
- staticLCodes[i] = BitReverse((0x000 - 256 + i) << 9);\r
- staticLLength[i++] = 7;\r
- }\r
- while (i < LITERAL_NUM) {\r
- staticLCodes[i] = BitReverse((0x0c0 - 280 + i) << 8);\r
- staticLLength[i++] = 8;\r
- }\r
- \r
- /* Distant codes */\r
- staticDCodes = new short[DIST_NUM];\r
- staticDLength = new byte[DIST_NUM];\r
- for (i = 0; i < DIST_NUM; i++) {\r
- staticDCodes[i] = BitReverse(i << 11);\r
- staticDLength[i] = 5;\r
- }\r
- }\r
- \r
- public DeflaterHuffman(DeflaterPending pending)\r
- {\r
- this.pending = pending;\r
- \r
- literalTree = new Tree(this, LITERAL_NUM, 257, 15);\r
- distTree = new Tree(this, DIST_NUM, 1, 15);\r
- blTree = new Tree(this, BITLEN_NUM, 4, 7);\r
- \r
- d_buf = new short[BUFSIZE];\r
- l_buf = new byte [BUFSIZE];\r
- }\r
- \r
- public void Reset() \r
- {\r
- last_lit = 0;\r
- extra_bits = 0;\r
- literalTree.Reset();\r
- distTree.Reset();\r
- blTree.Reset();\r
- }\r
- \r
- int Lcode(int len) \r
- {\r
- if (len == 255) {\r
- return 285;\r
- }\r
- \r
- int code = 257;\r
- while (len >= 8) {\r
- code += 4;\r
- len >>= 1;\r
- }\r
- return code + len;\r
- }\r
- \r
- int Dcode(int distance) \r
- {\r
- int code = 0;\r
- while (distance >= 4) {\r
- code += 2;\r
- distance >>= 1;\r
- }\r
- return code + distance;\r
- }\r
- \r
- public void SendAllTrees(int blTreeCodes)\r
- {\r
- blTree.BuildCodes();\r
- literalTree.BuildCodes();\r
- distTree.BuildCodes();\r
- pending.WriteBits(literalTree.numCodes - 257, 5);\r
- pending.WriteBits(distTree.numCodes - 1, 5);\r
- pending.WriteBits(blTreeCodes - 4, 4);\r
- for (int rank = 0; rank < blTreeCodes; rank++) {\r
- pending.WriteBits(blTree.length[BL_ORDER[rank]], 3);\r
- }\r
- literalTree.WriteTree(blTree);\r
- distTree.WriteTree(blTree);\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // blTree.CheckEmpty();\r
- // }\r
- }\r
- \r
- public void CompressBlock()\r
- {\r
- for (int i = 0; i < last_lit; i++) {\r
- int litlen = l_buf[i] & 0xff;\r
- int dist = d_buf[i];\r
- if (dist-- != 0) {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // Console.Write("["+(dist+1)+","+(litlen+3)+"]: ");\r
- // }\r
- \r
- int lc = Lcode(litlen);\r
- literalTree.WriteSymbol(lc);\r
- \r
- int bits = (lc - 261) / 4;\r
- if (bits > 0 && bits <= 5) {\r
- pending.WriteBits(litlen & ((1 << bits) - 1), bits);\r
- }\r
- \r
- int dc = Dcode(dist);\r
- distTree.WriteSymbol(dc);\r
- \r
- bits = dc / 2 - 1;\r
- if (bits > 0) {\r
- pending.WriteBits(dist & ((1 << bits) - 1), bits);\r
- }\r
- } else {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // if (litlen > 32 && litlen < 127) {\r
- // Console.Write("("+(char)litlen+"): ");\r
- // } else {\r
- // Console.Write("{"+litlen+"}: ");\r
- // }\r
- // }\r
- literalTree.WriteSymbol(litlen);\r
- }\r
- }\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // Console.Write("EOF: ");\r
- // }\r
- literalTree.WriteSymbol(EOF_SYMBOL);\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // literalTree.CheckEmpty();\r
- // distTree.CheckEmpty();\r
- // }\r
- }\r
- \r
- public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)\r
- {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("Flushing stored block "+ storedLength);\r
- // }\r
- pending.WriteBits((DeflaterConstants.STORED_BLOCK << 1) + (lastBlock ? 1 : 0), 3);\r
- pending.AlignToByte();\r
- pending.WriteShort(storedLength);\r
- pending.WriteShort(~storedLength);\r
- pending.WriteBlock(stored, storedOffset, storedLength);\r
- Reset();\r
- }\r
- \r
- public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)\r
- {\r
- literalTree.freqs[EOF_SYMBOL]++;\r
- \r
- /* Build trees */\r
- literalTree.BuildTree();\r
- distTree.BuildTree();\r
- \r
- /* Calculate bitlen frequency */\r
- literalTree.CalcBLFreq(blTree);\r
- distTree.CalcBLFreq(blTree);\r
- \r
- /* Build bitlen tree */\r
- blTree.BuildTree();\r
- \r
- int blTreeCodes = 4;\r
- for (int i = 18; i > blTreeCodes; i--) {\r
- if (blTree.length[BL_ORDER[i]] > 0) {\r
- blTreeCodes = i+1;\r
- }\r
- }\r
- int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() + \r
- literalTree.GetEncodedLength() + distTree.GetEncodedLength() + \r
- extra_bits;\r
- \r
- int static_len = extra_bits;\r
- for (int i = 0; i < LITERAL_NUM; i++) {\r
- static_len += literalTree.freqs[i] * staticLLength[i];\r
- }\r
- for (int i = 0; i < DIST_NUM; i++) {\r
- static_len += distTree.freqs[i] * staticDLength[i];\r
- }\r
- if (opt_len >= static_len) {\r
- /* Force static trees */\r
- opt_len = static_len;\r
- }\r
- \r
- if (storedOffset >= 0 && storedLength+4 < opt_len >> 3) {\r
- /* Store Block */\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("Storing, since " + storedLength + " < " + opt_len\r
- // + " <= " + static_len);\r
- // }\r
- FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);\r
- } else if (opt_len == static_len) {\r
- /* Encode with static tree */\r
- pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);\r
- literalTree.SetStaticCodes(staticLCodes, staticLLength);\r
- distTree.SetStaticCodes(staticDCodes, staticDLength);\r
- CompressBlock();\r
- Reset();\r
- } else {\r
- /* Encode with dynamic tree */\r
- pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);\r
- SendAllTrees(blTreeCodes);\r
- CompressBlock();\r
- Reset();\r
- }\r
- }\r
- \r
- public bool IsFull()\r
- {\r
-// return last_lit + 16 >= BUFSIZE; // HACK: This was == 'last_lit == BUFSIZE', but errors occured with DeflateFast\r
- return last_lit >= BUFSIZE; // -jr- This is the correct form!\r
- }\r
- \r
- public bool TallyLit(int lit)\r
- {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // if (lit > 32 && lit < 127) {\r
- // //Console.WriteLine("("+(char)lit+")");\r
- // } else {\r
- // //Console.WriteLine("{"+lit+"}");\r
- // }\r
- // }\r
- d_buf[last_lit] = 0;\r
- l_buf[last_lit++] = (byte)lit;\r
- literalTree.freqs[lit]++;\r
- return IsFull();\r
- }\r
- \r
- public bool TallyDist(int dist, int len)\r
- {\r
- // if (DeflaterConstants.DEBUGGING) {\r
- // //Console.WriteLine("["+dist+","+len+"]");\r
- // }\r
- \r
- d_buf[last_lit] = (short)dist;\r
- l_buf[last_lit++] = (byte)(len - 3);\r
- \r
- int lc = Lcode(len - 3);\r
- literalTree.freqs[lc]++;\r
- if (lc >= 265 && lc < 285) {\r
- extra_bits += (lc - 261) / 4;\r
- }\r
- \r
- int dc = Dcode(dist - 1);\r
- distTree.freqs[dc]++;\r
- if (dc >= 4) {\r
- extra_bits += dc / 2 - 1;\r
- }\r
- return IsFull();\r
- }\r
- }\r
-}\r