xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/BitmEncoder.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // BitmEncoder.h -- the Most Significant Bit of byte is First
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_BITM_ENCODER_H
4*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_BITM_ENCODER_H
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../IStream.h"
7*f6dc9357SAndroid Build Coastguard Worker 
8*f6dc9357SAndroid Build Coastguard Worker template<class TOutByte>
9*f6dc9357SAndroid Build Coastguard Worker class CBitmEncoder
10*f6dc9357SAndroid Build Coastguard Worker {
11*f6dc9357SAndroid Build Coastguard Worker   unsigned _bitPos;
12*f6dc9357SAndroid Build Coastguard Worker   Byte _curByte;
13*f6dc9357SAndroid Build Coastguard Worker   TOutByte _stream;
14*f6dc9357SAndroid Build Coastguard Worker public:
Create(UInt32 bufferSize)15*f6dc9357SAndroid Build Coastguard Worker   bool Create(UInt32 bufferSize) { return _stream.Create(bufferSize); }
SetStream(ISequentialOutStream * outStream)16*f6dc9357SAndroid Build Coastguard Worker   void SetStream(ISequentialOutStream *outStream) { _stream.SetStream(outStream);}
GetProcessedSize()17*f6dc9357SAndroid Build Coastguard Worker   UInt64 GetProcessedSize() const { return _stream.GetProcessedSize() + ((8 - _bitPos + 7) >> 3); }
Init()18*f6dc9357SAndroid Build Coastguard Worker   void Init()
19*f6dc9357SAndroid Build Coastguard Worker   {
20*f6dc9357SAndroid Build Coastguard Worker     _stream.Init();
21*f6dc9357SAndroid Build Coastguard Worker     _bitPos = 8;
22*f6dc9357SAndroid Build Coastguard Worker     _curByte = 0;
23*f6dc9357SAndroid Build Coastguard Worker   }
Flush()24*f6dc9357SAndroid Build Coastguard Worker   HRESULT Flush()
25*f6dc9357SAndroid Build Coastguard Worker   {
26*f6dc9357SAndroid Build Coastguard Worker     if (_bitPos < 8)
27*f6dc9357SAndroid Build Coastguard Worker       WriteBits(0, _bitPos);
28*f6dc9357SAndroid Build Coastguard Worker     return _stream.Flush();
29*f6dc9357SAndroid Build Coastguard Worker   }
WriteBits(UInt32 value,unsigned numBits)30*f6dc9357SAndroid Build Coastguard Worker   void WriteBits(UInt32 value, unsigned numBits)
31*f6dc9357SAndroid Build Coastguard Worker   {
32*f6dc9357SAndroid Build Coastguard Worker     while (numBits > 0)
33*f6dc9357SAndroid Build Coastguard Worker     {
34*f6dc9357SAndroid Build Coastguard Worker       if (numBits < _bitPos)
35*f6dc9357SAndroid Build Coastguard Worker       {
36*f6dc9357SAndroid Build Coastguard Worker         _curByte = (Byte)(_curByte | (value << (_bitPos -= numBits)));
37*f6dc9357SAndroid Build Coastguard Worker         return;
38*f6dc9357SAndroid Build Coastguard Worker       }
39*f6dc9357SAndroid Build Coastguard Worker       numBits -= _bitPos;
40*f6dc9357SAndroid Build Coastguard Worker       UInt32 newBits = (value >> numBits);
41*f6dc9357SAndroid Build Coastguard Worker       value -= (newBits << numBits);
42*f6dc9357SAndroid Build Coastguard Worker       _stream.WriteByte((Byte)(_curByte | newBits));
43*f6dc9357SAndroid Build Coastguard Worker       _bitPos = 8;
44*f6dc9357SAndroid Build Coastguard Worker       _curByte = 0;
45*f6dc9357SAndroid Build Coastguard Worker     }
46*f6dc9357SAndroid Build Coastguard Worker   }
47*f6dc9357SAndroid Build Coastguard Worker };
48*f6dc9357SAndroid Build Coastguard Worker 
49*f6dc9357SAndroid Build Coastguard Worker #endif
50