1 // BitmDecoder.h -- the Most Significant Bit of byte is First 2 3 #ifndef ZIP7_INC_BITM_DECODER_H 4 #define ZIP7_INC_BITM_DECODER_H 5 6 #include "../IStream.h" 7 8 namespace NBitm { 9 10 const unsigned kNumBigValueBits = 8 * 4; 11 const unsigned kNumValueBytes = 3; 12 const unsigned kNumValueBits = 8 * kNumValueBytes; 13 14 const UInt32 kMask = (1 << kNumValueBits) - 1; 15 16 // _bitPos - the number of free bits (high bits in _value) 17 // (kNumBigValueBits - _bitPos) = (32 - _bitPos) == the number of ready to read bits (low bits of _value) 18 19 template<class TInByte> 20 class CDecoder 21 { 22 unsigned _bitPos; 23 UInt32 _value; 24 TInByte _stream; 25 public: Create(UInt32 bufSize)26 bool Create(UInt32 bufSize) { return _stream.Create(bufSize); } SetStream(ISequentialInStream * inStream)27 void SetStream(ISequentialInStream *inStream) { _stream.SetStream(inStream);} 28 Init()29 void Init() 30 { 31 _stream.Init(); 32 _bitPos = kNumBigValueBits; 33 _value = 0; 34 Normalize(); 35 } 36 GetStreamSize()37 UInt64 GetStreamSize() const { return _stream.GetStreamSize(); } GetProcessedSize()38 UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() - ((kNumBigValueBits - _bitPos) >> 3); } 39 ExtraBitsWereRead()40 bool ExtraBitsWereRead() const 41 { 42 return (_stream.NumExtraBytes > 4 || kNumBigValueBits - _bitPos < (_stream.NumExtraBytes << 3)); 43 } 44 ExtraBitsWereRead_Fast()45 bool ExtraBitsWereRead_Fast() const 46 { 47 return (_stream.NumExtraBytes > 4); 48 } 49 50 Z7_FORCE_INLINE Normalize()51 void Normalize() 52 { 53 for (; _bitPos >= 8; _bitPos -= 8) 54 _value = (_value << 8) | _stream.ReadByte(); 55 } 56 57 Z7_FORCE_INLINE GetValue(unsigned numBits)58 UInt32 GetValue(unsigned numBits) const 59 { 60 // return (_value << _bitPos) >> (kNumBigValueBits - numBits); 61 return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits); 62 } 63 64 Z7_FORCE_INLINE GetValue_InHigh32bits()65 UInt32 GetValue_InHigh32bits() const 66 { 67 return this->_value << this->_bitPos; 68 } 69 70 Z7_FORCE_INLINE MovePos(unsigned numBits)71 void MovePos(unsigned numBits) 72 { 73 _bitPos += numBits; 74 Normalize(); 75 } 76 77 Z7_FORCE_INLINE ReadBits(unsigned numBits)78 UInt32 ReadBits(unsigned numBits) 79 { 80 UInt32 res = GetValue(numBits); 81 MovePos(numBits); 82 return res; 83 } 84 85 /* 86 unsigned ReadBit() 87 { 88 UInt32 res = ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - 1); 89 if (++_bitPos >= 8) 90 { 91 _value = (_value << 8) | _stream.ReadByte(); 92 _bitPos -= 8; 93 } 94 return (unsigned)res; 95 } 96 */ 97 AlignToByte()98 void AlignToByte() { MovePos((kNumBigValueBits - _bitPos) & 7); } 99 100 Z7_FORCE_INLINE ReadAlignBits()101 UInt32 ReadAlignBits() { return ReadBits((kNumBigValueBits - _bitPos) & 7); } 102 }; 103 104 } 105 106 #endif 107