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