Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        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);
        }