private static void traverseTree(TreeNode<int, byte> startNode, string codeword) { if (startNode.Left == null && startNode.Right == null) { frequencyTable.Codewords[startNode.Value] = codeword; } else { if (startNode.Left != null) { traverseTree(startNode.Left, codeword + "0"); } if (startNode.Right != null) { traverseTree(startNode.Right, codeword + "1"); } } }
public static void DecodeStream(Stream inStream, Stream outStream) { int i = 0; // counter byte streamLength = 0, readCharacters = 0; // the root of Huffman Tree TreeNode<int, byte> huffmanTreeRoot = new TreeNode<int, byte>(-1, 0); TreeNode<int, byte> currentNode; frequencyTable = new FrequencyTable(); readHuffmanTreeFromStream(inStream); streamLength = (byte)inStream.ReadByte(); i = 0; // construct A Huffman Tree for (i = 0; i < frequencyTable.MaxTableSize; i++) { if (frequencyTable.Hits[i] != 0) { currentNode = huffmanTreeRoot; foreach (char c in frequencyTable.Codewords[i]) { if (c == '0') { if (currentNode.Left == null) currentNode.Left = new TreeNode<int, byte>(-1, 0); currentNode = currentNode.Left; } else if (c == '1') { if (currentNode.Right == null) currentNode.Right = new TreeNode<int, byte>(-1, 0); currentNode = currentNode.Right; } } currentNode.Key = 1; // this node contains a character (is a leaf) currentNode.Value = (byte)i; } } // Tree is ready, start decoding string buffer = "", bits = ""; //string pooledBuffer = ""; int nextByte = 0, nextNextByte; i = 0; nextNextByte = inStream.ReadByte(); while (nextByte != -1) { nextByte = nextNextByte; nextNextByte = inStream.ReadByte(); bits = decodeByteToBitString((byte)nextByte); if (bits.Length < 8) bits += new string('0', 8 - bits.Length); buffer += bits; //pooledBuffer += bits; currentNode = huffmanTreeRoot; // start from Tree root for (i = 0; i < buffer.Length; i++) { if (nextNextByte == -1) // end of stream { if (readCharacters == streamLength) break; } if (buffer[i] == '0') currentNode = currentNode.Left; else currentNode = currentNode.Right; if (currentNode.Key == 1) // character found { ++readCharacters; outStream.WriteByte(currentNode.Value); buffer = buffer.Substring(i + 1); i = -1; currentNode = huffmanTreeRoot; } } //nextByte = inStream.ReadByte(); } }
private static int compareTreeNodes(TreeNode<int, byte> node1, TreeNode<int, byte> node2) { if (node1 == null || node2 == null) return 0; if (node1.Key == node2.Key) return 0; else if (node1.Key > node2.Key) return 1; else return -1; }
public static void EncodeStream(Stream inStream, Stream outStream) { int i = 0; // counter int newFreq; // the list of all Huffman Tree nodes List<TreeNode<int, byte>> huffmanTree = new List<TreeNode<int, byte>>(); // the root of Huffman Tree TreeNode<int, byte> huffmanTreeRoot = new TreeNode<int, byte>(0, 0); frequencyTable = new FrequencyTable(); /*frequencyTable = new FrequencyEntry[256 ]; for (i = 0; i < frequencyTable.Length; ++i) frequencyTable[i] = new FrequencyEntry();*/ calculateFrequency(inStream); i = 0; // construct a forest for (i = 0; i < frequencyTable.MaxTableSize; i++) { if (frequencyTable.Hits[i] != 0) // add a new node to Huffman Tree, where character hits is the key // and the character itself is the value huffmanTree.Add(new TreeNode<int, byte>(frequencyTable.Hits[i], (byte)i)); } // link the nodes while (huffmanTree.Count > 1) { huffmanTree.Sort(compareTreeNodes); newFreq = huffmanTree[0].Key + huffmanTree[1].Key; TreeNode<int, byte> node = new TreeNode<int, byte>(newFreq, 0); node.Left = huffmanTree[0]; node.Right = huffmanTree[1]; node.Left.Parent = node; node.Right.Parent = node; huffmanTree.RemoveAt(0); huffmanTree.RemoveAt(0); huffmanTree.Add(node); huffmanTreeRoot = node; } //calculate codewords traverseTree(huffmanTreeRoot, ""); //wrtie table writeHuffmanTreeToStream(outStream); // outStream.WriteByte((byte)(inStream.Length % 256)); //wrtie encoded stream //string buffer = "", bits = ""; //string pooledBuffer = ""; BitBuffer bitBuffer = new BitBuffer(1, outStream); int nextChar = 0; inStream.Seek(0, SeekOrigin.Begin); nextChar = inStream.ReadByte(); while (nextChar != -1) { bitBuffer.AddToBuffer(frequencyTable.Codewords[nextChar]); //pooledBuffer += frequencyTable.Codewords[nextChar]; /*if (buffer.Length >= 8) { bits = buffer.Substring(0, 8); buffer = buffer.Substring(8); outStream.WriteByte(encodeBitString(bits)); }*/ nextChar = inStream.ReadByte(); } bitBuffer.Flush(); //if (buffer.Length > 0) // outStream.WriteByte(encodeBitString(buffer)); }