Represents a bit buffer.
This structure is designed for internal use in CrystalMpq. Incorrect usage of the structure will lead to bugs or even worse, memory leaks. The structure shall always be initialized using this constructor. Once created, there shall never be more than one living copy of the structure. The structure shall always be passed as a reference parameter and never as a value parameter. Once the structure have been used for its purposes, it shall be released using the Dispose method. After the structure has been disposed, the instance shall never be used again.
Ejemplo n.º 1
0
        private static int DecodeValue(ref BitBuffer bitBuffer, Node node)
        {
            // This cannot cause an infinite loop if the tables are correct.
            while (node.Value == -1) node = node[bitBuffer.GetBit()];

            return node.Value;
        }
Ejemplo n.º 2
0
        // 'explode' decompression
        public static int DecompressBlock(byte[] inBuffer, int index, int count, byte[] outBuffer)
        {
            bool ascii;
            byte b;

            b = inBuffer[index++];

            // Check the ASCII encoding flag
            if (b == 0)
            {
                ascii = false;                     // Don't use ASCII encoding
            }
            else if (b == 1)
            {
                ascii = true;                          // Use ASCII encoding
            }
            else
            {
                throw new InvalidDataException();
            }

            b = inBuffer[index++];
            if (b < 4 || b > 6)
            {
                throw new InvalidDataException();
            }

            int dictSize      = 0x40 << b;        // Calculate dictionnary size
            int lowOffsetSize = b;

            var bitBuffer = new BitBuffer(inBuffer, index, count - 2);

            try
            {
                int i = 0;

                while (i < outBuffer.Length && !bitBuffer.Eof)
                {
                    int t = bitBuffer.GetBit();

                    if (t == 0)                     // Litteral
                    {
                        // Depending on the compression mode, this can either be a raw byte or a coded ASCII character
                        t = ascii ? DecodeValue(ref bitBuffer, asciiTree) : bitBuffer.GetByte();

                        outBuffer[i++] = (byte)t;
                    }
                    else                     // Length/Offset Pair
                    {
                        // Get the length
                        int length = DecodeValue(ref bitBuffer, lengthTree);
                        if (length == 519)
                        {
                            break;                                        // Length 519 means end of stream
                        }
                        // Get the offset
                        int offsetHigh = DecodeValue(ref bitBuffer, offsetTree);
                        int offset     = length == 2 ?
                                         i - ((offsetHigh << 2) | bitBuffer.GetBits(2)) - 1 :
                                         i - ((offsetHigh << lowOffsetSize) | bitBuffer.GetBits(lowOffsetSize)) - 1;

                        if (offset < 0)
                        {
                            throw new InvalidDataException();
                        }

                        // Copy
                        while (length-- != 0)
                        {
                            outBuffer[i++] = outBuffer[offset++];
                        }
                    }
                }

                return(i);
            }
            finally { bitBuffer.Dispose(); }
        }
Ejemplo n.º 3
0
        // 'explode' decompression
        public static int DecompressBlock(byte[] inBuffer, int index, int count, byte[] outBuffer)
        {
            bool ascii;
            byte b;

            b = inBuffer[index++];

            // Check the ASCII encoding flag
            if (b == 0) ascii = false; // Don't use ASCII encoding
            else if (b == 1) ascii = true; // Use ASCII encoding
            else throw new InvalidDataException();

            b = inBuffer[index++];
            if (b < 4 || b > 6) throw new InvalidDataException();

            int dictSize = 0x40 << b; // Calculate dictionnary size
            int lowOffsetSize = b;

            var bitBuffer = new BitBuffer(inBuffer, index, count - 2);

            try
            {
                int i = 0;

                while (i < outBuffer.Length && !bitBuffer.Eof)
                {
                    int t = bitBuffer.GetBit();

                    if (t == 0) // Litteral
                    {
                        // Depending on the compression mode, this can either be a raw byte or a coded ASCII character
                        t = ascii ? DecodeValue(ref bitBuffer, asciiTree) : bitBuffer.GetByte();

                        outBuffer[i++] = (byte)t;
                    }
                    else // Length/Offset Pair
                    {
                        // Get the length
                        int length = DecodeValue(ref bitBuffer, lengthTree);
                        if (length == 519) break; // Length 519 means end of stream

                        // Get the offset
                        int offsetHigh = DecodeValue(ref bitBuffer, offsetTree);
                        int offset = length == 2 ?
                            i - ((offsetHigh << 2) | bitBuffer.GetBits(2)) - 1 :
                            i - ((offsetHigh << lowOffsetSize) | bitBuffer.GetBits(lowOffsetSize)) - 1;

                        if (offset < 0) throw new InvalidDataException();

                        // Copy
                        while (length-- != 0) outBuffer[i++] = outBuffer[offset++];
                    }
                }

                return i;
            }
            finally { bitBuffer.Dispose(); }
        }
Ejemplo n.º 4
0
        public void DecompressBlock(byte[] inBuffer, int index, int count, byte[] outBuffer)
        {
            BitBuffer buffer;
            byte compressionType;

            compressionType = inBuffer[index++];
            buffer = new BitBuffer(inBuffer, index, count - 1);

            BuildTree(HuffmanTree.data[compressionType]);
        }