xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/BitmDecoder.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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