private void GetAllHuffmanCodes(HuffmanTree tree, ushort code, byte codeLength) { if (tree.IsLeaf()) { CodeTable[tree.Character] = new HuffmanCode(code, codeLength); _NumberOfCodes++; return; } GetAllHuffmanCodes(tree.Left, (ushort)(code << 1), (byte)(codeLength + 1)); GetAllHuffmanCodes(tree.Right, (ushort)((code << 1) | 1), (byte)(codeLength + 1)); }
public HuffmanCodeTable(HuffmanTree tree) { CodeTable = new HuffmanCode[0xFFFF + 1]; if (tree.IsLeaf()) { CodeTable[tree.Character] = new HuffmanCode(0, 1); _NumberOfCodes = 1; return; } _NumberOfCodes = 0; GetAllHuffmanCodes(tree, 0, 0); }
private static void EncodeTree(HuffmanTree tree, ushort[] buffer, ref int bitPosition) { if (tree.IsLeaf()) { buffer[bitPosition / 16] |= (ushort)(0x8000 >> (int)(bitPosition % 16)); bitPosition++; AppendCode(buffer, (ushort)tree.Character, ref bitPosition); return; } bitPosition++; EncodeTree(tree.Left, buffer, ref bitPosition); EncodeTree(tree.Right, buffer, ref bitPosition); }
public static string Decode(string filename) { byte[] buffer; try { buffer = File.ReadAllBytes(filename); } catch { throw; } if (buffer.Length == 0) { return(""); } int fileFormatVersion = buffer[0] & 0xFC; if (fileFormatVersion > FileFormatVersion) { throw new FormatException("File '" + filename + "' has a newer format (file format version " + fileFormatVersion.ToString("00") + "), or is invalid or corrupted."); } if (buffer.Length < 8) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } int treeLengthInBytes = ((int)(buffer[0] & 0x03) << 16) | ((int)buffer[1] << 8) | ((int)buffer[2]); int bitsOfLastByteOfTree = buffer[3] >> 4; int bitsOfLastByteOfText = buffer[3] & 0x0F; if (bitsOfLastByteOfTree < 1 || bitsOfLastByteOfTree > 8 || bitsOfLastByteOfText < 1 || bitsOfLastByteOfText > 8 || treeLengthInBytes < 3 || treeLengthInBytes > 147456 || buffer.Length < 5 + treeLengthInBytes) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } HuffmanTree tree = new HuffmanTree(); int treeBitPosition = 32; try { DecodeTree(tree, buffer, ref treeBitPosition, (3 + treeLengthInBytes) * 8 + bitsOfLastByteOfTree); } catch (FormatException) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } string decodedText = ""; if (tree.IsLeaf()) { for (int i = 4 + treeLengthInBytes; i < buffer.Length; i++) { if (buffer[i] != 0) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } } int numOfChars = (buffer.Length - treeLengthInBytes - 5) * 8 + bitsOfLastByteOfText; for (int i = 0; i < numOfChars; i++) { decodedText += tree.Character; } return(decodedText); } HuffmanTree currentNode = tree; for (int i = 4 + treeLengthInBytes; i < buffer.Length - 1; i++) { for (byte mask = 0x80; mask != 0; mask >>= 1) { if ((buffer[i] & mask) != 0) { currentNode = currentNode.Right; } else { currentNode = currentNode.Left; } if (currentNode == null) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } if (currentNode.IsLeaf()) { decodedText += currentNode.Character; currentNode = tree; } } } for (byte mask = 0x80, count = 0; count < bitsOfLastByteOfText; mask >>= 1, count++) { if ((buffer[buffer.Length - 1] & mask) != 0) { currentNode = currentNode.Right; } else { currentNode = currentNode.Left; } if (currentNode == null) { throw new FormatException("File '" + filename + "' is invalid or corrupted."); } if (currentNode.IsLeaf()) { decodedText += currentNode.Character; currentNode = tree; } } return(decodedText); }