Exemplo n.º 1
0
        private void UnpInitData(bool Solid)
        {
            if (!Solid)
            {
                Utility.Memset <uint>(OldDist, 0, OldDist.Length);
                OldDistPtr = 0;
                LastDist   = LastLength = 0;
//    memset(Window,0,MaxWinSize);
                //memset(&BlockTables,0,sizeof(BlockTables));
                BlockTables = new UnpackBlockTables();
                // sharpcompress: no default ctor for struct
                BlockTables.Init();
                UnpPtr      = WrPtr = 0;
                WriteBorder = Math.Min(MaxWinSize, UNPACK_MAX_WRITE) & MaxWinMask;
            }
            // Filters never share several solid files, so we can safely reset them
            // even in solid archive.
            InitFilters();

            Inp.InitBitInput();
            WrittenFileSize = 0;
            ReadTop         = 0;
            ReadBorder      = 0;

            //memset(&BlockHeader,0,sizeof(BlockHeader));
            BlockHeader           = new UnpackBlockHeader();
            BlockHeader.BlockSize = -1; // '-1' means not defined yet.
#if !RarV2017_SFX_MODULE
            UnpInitData20(Solid);
#endif
            //UnpInitData30(Solid);
            UnpInitData50(Solid);
        }
Exemplo n.º 2
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);
        }
Exemplo n.º 3
0
        private bool ReadTables(BitInput Inp, ref UnpackBlockHeader Header, ref UnpackBlockTables Tables)
        {
            if (!Header.TablePresent)
            {
                return(true);
            }

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

            byte[] BitLength = new byte[BC];
            for (uint I = 0; I < BC; I++)
            {
                uint Length = (byte)(Inp.fgetbits() >> 12);
                Inp.faddbits(4);
                if (Length == 15)
                {
                    uint ZeroCount = (byte)(Inp.fgetbits() >> 12);
                    Inp.faddbits(4);
                    if (ZeroCount == 0)
                    {
                        BitLength[I] = 15;
                    }
                    else
                    {
                        ZeroCount += 2;
                        while (ZeroCount-- > 0 && I < BitLength.Length)
                        {
                            BitLength[I++] = 0;
                        }

                        I--;
                    }
                }
                else
                {
                    BitLength[I] = (byte)Length;
                }
            }

            MakeDecodeTables(BitLength, 0, Tables.BD, BC);

            byte[]     Table     = new byte[HUFF_TABLE_SIZE];
            const uint TableSize = HUFF_TABLE_SIZE;

            for (uint I = 0; I < TableSize;)
            {
                if (!Inp.ExternalBuffer && Inp.InAddr > ReadTop - 5)
                {
                    if (!UnpReadBuf())
                    {
                        return(false);
                    }
                }

                uint Number = DecodeNumber(Inp, Tables.BD);
                if (Number < 16)
                {
                    Table[I] = (byte)Number;
                    I++;
                }
                else
                if (Number < 18)
                {
                    uint N;
                    if (Number == 16)
                    {
                        N = (Inp.fgetbits() >> 13) + 3;
                        Inp.faddbits(3);
                    }
                    else
                    {
                        N = (Inp.fgetbits() >> 9) + 11;
                        Inp.faddbits(7);
                    }
                    if (I == 0)
                    {
                        // We cannot have "repeat previous" code at the first position.
                        // Multiple such codes would shift Inp position without changing I,
                        // which can lead to reading beyond of Inp boundary in mutithreading
                        // mode, where Inp.ExternalBuffer disables bounds check and we just
                        // reserve a lot of buffer space to not need such check normally.
                        return(false);
                    }
                    else
                    {
                        while (N-- > 0 && I < TableSize)
                        {
                            Table[I] = Table[I - 1];
                            I++;
                        }
                    }
                }
                else
                {
                    uint N;
                    if (Number == 18)
                    {
                        N = (Inp.fgetbits() >> 13) + 3;
                        Inp.faddbits(3);
                    }
                    else
                    {
                        N = (Inp.fgetbits() >> 9) + 11;
                        Inp.faddbits(7);
                    }
                    while (N-- > 0 && I < TableSize)
                    {
                        Table[I++] = 0;
                    }
                }
            }
            TablesRead5 = true;
            if (!Inp.ExternalBuffer && Inp.InAddr > ReadTop)
            {
                return(false);
            }

            MakeDecodeTables(Table, 0, Tables.LD, NC);
            MakeDecodeTables(Table, (int)NC, Tables.DD, DC);
            MakeDecodeTables(Table, (int)(NC + DC), Tables.LDD, LDC);
            MakeDecodeTables(Table, (int)(NC + DC + LDC), Tables.RD, RC);
            return(true);
        }