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