Example #1
0
        private static int DecodeLiteral(BitStreamReader bitStream, PkLibCompressionType compressionType)
        {
            Contract.Requires(bitStream != null);

            // Return values:
            // 0x000 to 0x0ff: One byte from compressed file.
            // 0x100 to 0x305: Copy previous block (0x100 = 1 byte).
            // -1: End of stream.
            switch (bitStream.ReadBits(1))
            {
            case -1:
                return(-1);

            case 1:
                // The next bits are positions in buffers.
                int pos = _sPosition2[bitStream.PeekByte()];

                // Skip the bits we just used.
                var numBits = _sLenBits[pos];
                Contract.Assume(numBits < BitStreamReader.MaxBitCount);
                if (bitStream.ReadBits(numBits) == -1)
                {
                    return(-1);
                }

                var nBits = _sExLenBits[pos];
                if (nBits != 0)
                {
                    Contract.Assume(nBits < BitStreamReader.MaxBitCount);
                    var val2 = bitStream.ReadBits(nBits);
                    if (val2 == -1 && (pos + val2 != 0x10e))
                    {
                        return(-1);
                    }

                    pos = _sLenBase[pos] + val2;
                }

                return(pos + 0x100);    // Return number of bytes to repeat.

            case 0:
                if (compressionType == PkLibCompressionType.Binary)
                {
                    return(bitStream.ReadBits(sizeof(byte) * 8));
                }

                // TODO: Implement ASCII mode.
                throw new NotImplementedException("ASCII mode is not yet implemented.");

            default:
                return(0);
            }
        }
Example #2
0
        private static int DecodeDistance(BitStreamReader bitStream, int length, int dictSizeBits)
        {
            Contract.Requires(bitStream != null);
            Contract.Requires(length >= 0);
            Contract.Requires(dictSizeBits >= 0);
            Contract.Requires(dictSizeBits < BitStreamReader.MaxBitCount);

            if (bitStream.EnsureBits(8) == false)
            {
                return(0);
            }

            var pos  = (int)_sPosition1[bitStream.PeekByte()];
            var skip = _sDistBits[pos]; // Number of bits to skip.

            // Skip the appropriate number of bits
            Contract.Assume(skip < BitStreamReader.MaxBitCount);
            if (bitStream.ReadBits(skip) == -1)
            {
                return(0);
            }

            if (length == 2)
            {
                if (bitStream.EnsureBits(2) == false)
                {
                    return(0);
                }

                pos = (pos << 2) | bitStream.ReadBits(2);
            }
            else
            {
                if (bitStream.EnsureBits(dictSizeBits) == false)
                {
                    return(0);
                }

                pos = ((pos << dictSizeBits)) | bitStream.ReadBits(dictSizeBits);
            }

            return(pos + 1);
        }
Example #3
0
        private static int DecodeDistance(BitStreamReader bitStream, int length, int dictSizeBits)
        {
            Contract.Requires(bitStream != null);
            Contract.Requires(length >= 0);
            Contract.Requires(dictSizeBits >= 0);
            Contract.Requires(dictSizeBits < BitStreamReader.MaxBitCount);

            if (bitStream.EnsureBits(8) == false)
                return 0;

            var pos = (int)_sPosition1[bitStream.PeekByte()];
            var skip = _sDistBits[pos]; // Number of bits to skip.

            // Skip the appropriate number of bits
            Contract.Assume(skip < BitStreamReader.MaxBitCount);
            if (bitStream.ReadBits(skip) == -1)
                return 0;

            if (length == 2)
            {
                if (bitStream.EnsureBits(2) == false)
                    return 0;

                pos = (pos << 2) | bitStream.ReadBits(2);
            }
            else
            {
                if (bitStream.EnsureBits(dictSizeBits) == false)
                    return 0;

                pos = ((pos << dictSizeBits)) | bitStream.ReadBits(dictSizeBits);
            }

            return pos + 1;
        }
Example #4
0
        private static int DecodeLiteral(BitStreamReader bitStream, PkLibCompressionType compressionType)
        {
            Contract.Requires(bitStream != null);

            // Return values:
            // 0x000 to 0x0ff: One byte from compressed file.
            // 0x100 to 0x305: Copy previous block (0x100 = 1 byte).
            // -1: End of stream.
            switch (bitStream.ReadBits(1))
            {
                case -1:
                    return -1;
                case 1:
                    // The next bits are positions in buffers.
                    int pos = _sPosition2[bitStream.PeekByte()];

                    // Skip the bits we just used.
                    var numBits = _sLenBits[pos];
                    Contract.Assume(numBits < BitStreamReader.MaxBitCount);
                    if (bitStream.ReadBits(numBits) == -1)
                        return -1;
    
                    var nBits = _sExLenBits[pos];
                    if (nBits != 0)
                    {
                        Contract.Assume(nBits < BitStreamReader.MaxBitCount);
                        var val2 = bitStream.ReadBits(nBits);
                        if (val2 == -1 && (pos + val2 != 0x10e))
                            return -1;

                        pos = _sLenBase[pos] + val2;
                    }

                    return pos + 0x100; // Return number of bytes to repeat.
                case 0:
                    if (compressionType == PkLibCompressionType.Binary)
                        return bitStream.ReadBits(sizeof(byte) * 8);

                    // TODO: Implement ASCII mode.
                    throw new NotImplementedException("ASCII mode is not yet implemented.");
                default:
                    return 0;
            }
        }