Esempio n. 1
0
        private uint ReadFilterData(BitInput Inp)
        {
            uint ByteCount = (Inp.fgetbits() >> 14) + 1;

            Inp.addbits(2);

            uint Data = 0;

            for (uint I = 0; I < ByteCount; I++)
            {
                Data += (Inp.fgetbits() >> 8) << (int)(I * 8);
                Inp.addbits(8);
            }
            return(Data);
        }
Esempio n. 2
0
        private uint DecodeNumber(BitInput Inp, DecodeTable Dec)
        {
            // Left aligned 15 bit length raw bit field.
            uint BitField = Inp.getbits() & 0xfffe;

            if (BitField < Dec.DecodeLen[Dec.QuickBits])
            {
                uint Code = BitField >> (int)(16 - Dec.QuickBits);
                Inp.addbits(Dec.QuickLen[Code]);
                return(Dec.QuickNum[Code]);
            }

            // Detect the real bit length for current code.
            uint Bits = 15;

            for (uint I = Dec.QuickBits + 1; I < 15; I++)
            {
                if (BitField < Dec.DecodeLen[I])
                {
                    Bits = I;
                    break;
                }
            }

            Inp.addbits(Bits);

            // Calculate the distance from the start code for current bit length.
            uint Dist = BitField - Dec.DecodeLen[Bits - 1];

            // Start codes are left aligned, but we need the normal right aligned
            // number. So we shift the distance to the right.
            Dist >>= (int)(16 - Bits);

            // Now we can calculate the position in the code list. It is the sum
            // of first position for current bit length and right aligned distance
            // between our bit field and start code for current bit length.
            uint Pos = Dec.DecodePos[Bits] + Dist;

            // Out of bounds safety check required for damaged archives.
            if (Pos >= Dec.MaxNum)
            {
                Pos = 0;
            }

            // Convert the position in the code list to position in alphabet
            // and return it.
            return(Dec.DecodeNum[Pos]);
        }
Esempio n. 3
0
        private bool ReadBlockHeader(BitInput Inp, ref UnpackBlockHeader Header)
        {
            Header.HeaderSize = 0;

            if (!Inp.ExternalBuffer && Inp.InAddr > ReadTop - 7)
            {
                if (!UnpReadBuf())
                {
                    return(false);
                }
            }

            Inp.faddbits((uint)((8 - Inp.InBit) & 7));

            byte BlockFlags = (byte)(Inp.fgetbits() >> 8);

            Inp.faddbits(8);
            uint ByteCount = (uint)(((BlockFlags >> 3) & 3) + 1); // Block size byte count.

            if (ByteCount == 4)
            {
                return(false);
            }

            Header.HeaderSize = (int)(2 + ByteCount);

            Header.BlockBitSize = (BlockFlags & 7) + 1;

            byte SavedCheckSum = (byte)(Inp.fgetbits() >> 8);

            Inp.faddbits(8);

            int BlockSize = 0;

            for (uint I = 0; I < ByteCount; I++)
            {
                BlockSize += (int)((Inp.fgetbits() >> 8) << (int)(I * 8));
                Inp.addbits(8);
            }

            Header.BlockSize = BlockSize;
            byte CheckSum = (byte)(0x5a ^ BlockFlags ^ BlockSize ^ (BlockSize >> 8) ^ (BlockSize >> 16));

            if (CheckSum != SavedCheckSum)
            {
                return(false);
            }

            Header.BlockStart = Inp.InAddr;
            ReadBorder        = Math.Min(ReadBorder, Header.BlockStart + Header.BlockSize - 1);

            Header.LastBlockInFile = (BlockFlags & 0x40) != 0;
            Header.TablePresent    = (BlockFlags & 0x80) != 0;
            return(true);
        }
Esempio n. 4
0
        private uint SlotToLength(BitInput Inp, uint Slot)
        {
            uint LBits, Length = 2;

            if (Slot < 8)
            {
                LBits   = 0;
                Length += Slot;
            }
            else
            {
                LBits   = Slot / 4 - 1;
                Length += (4 | (Slot & 3)) << (int)LBits;
            }

            if (LBits > 0)
            {
                Length += Inp.getbits() >> (int)(16 - LBits);
                Inp.addbits(LBits);
            }
            return(Length);
        }