1 // LSBFDecoder.h 2 3 #ifndef __STREAM_LSBFDECODER_H 4 #define __STREAM_LSBFDECODER_H 5 6 #include "../IStream.h" 7 8 namespace NStream { 9 namespace NLSBF { 10 11 const int kNumBigValueBits = 8 * 4; 12 13 const int kNumValueBytes = 3; 14 const int kNumValueBits = 8 * kNumValueBytes; 15 16 const UInt32 kMask = (1 << kNumValueBits) - 1; 17 18 extern Byte kInvertTable[256]; 19 // the Least Significant Bit of byte is First 20 21 template<class TInByte> 22 class CBaseDecoder 23 { 24 protected: 25 int m_BitPos; 26 UInt32 m_Value; 27 TInByte m_Stream; 28 public: 29 UInt32 NumExtraBytes; Create(UInt32 bufferSize)30 bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } SetStream(ISequentialInStream * inStream)31 void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); } ReleaseStream()32 void ReleaseStream() { m_Stream.ReleaseStream(); } Init()33 void Init() 34 { 35 m_Stream.Init(); 36 m_BitPos = kNumBigValueBits; 37 m_Value = 0; 38 NumExtraBytes = 0; 39 } GetProcessedSize()40 UInt64 GetProcessedSize() const 41 { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; } GetProcessedBitsSize()42 UInt64 GetProcessedBitsSize() const 43 { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); } GetBitPosition()44 int GetBitPosition() const { return (m_BitPos & 7); } 45 Normalize()46 void Normalize() 47 { 48 for (;m_BitPos >= 8; m_BitPos -= 8) 49 { 50 Byte b; 51 if (!m_Stream.ReadByte(b)) 52 { 53 b = 0xFF; // check it 54 NumExtraBytes++; 55 } 56 m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value; 57 } 58 } 59 ReadBits(int numBits)60 UInt32 ReadBits(int numBits) 61 { 62 Normalize(); 63 UInt32 res = m_Value & ((1 << numBits) - 1); 64 m_BitPos += numBits; 65 m_Value >>= numBits; 66 return res; 67 } 68 ExtraBitsWereRead()69 bool ExtraBitsWereRead() const 70 { 71 if (NumExtraBytes == 0) 72 return false; 73 return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); 74 } 75 }; 76 77 template<class TInByte> 78 class CDecoder: public CBaseDecoder<TInByte> 79 { 80 UInt32 m_NormalValue; 81 82 public: Init()83 void Init() 84 { 85 CBaseDecoder<TInByte>::Init(); 86 m_NormalValue = 0; 87 } 88 Normalize()89 void Normalize() 90 { 91 for (;this->m_BitPos >= 8; this->m_BitPos -= 8) 92 { 93 Byte b; 94 if (!this->m_Stream.ReadByte(b)) 95 { 96 b = 0xFF; // check it 97 this->NumExtraBytes++; 98 } 99 m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue; 100 this->m_Value = (this->m_Value << 8) | kInvertTable[b]; 101 } 102 } 103 GetValue(int numBits)104 UInt32 GetValue(int numBits) 105 { 106 Normalize(); 107 return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); 108 } 109 MovePos(int numBits)110 void MovePos(int numBits) 111 { 112 this->m_BitPos += numBits; 113 m_NormalValue >>= numBits; 114 } 115 ReadBits(int numBits)116 UInt32 ReadBits(int numBits) 117 { 118 Normalize(); 119 UInt32 res = m_NormalValue & ( (1 << numBits) - 1); 120 MovePos(numBits); 121 return res; 122 } 123 }; 124 125 }} 126 127 #endif 128