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); }
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); }
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); }