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