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