view src/win32/7zip/7z/CPP/7zip/Compress/BitlDecoder.h @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line source
1 // BitlDecoder.h -- the Least Significant Bit of byte is First
3 #ifndef __BITL_DECODER_H
4 #define __BITL_DECODER_H
6 #include "../IStream.h"
8 namespace NBitl {
10 const int kNumBigValueBits = 8 * 4;
12 const int kNumValueBytes = 3;
13 const int kNumValueBits = 8 * kNumValueBytes;
15 const UInt32 kMask = (1 << kNumValueBits) - 1;
17 extern Byte kInvertTable[256];
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;
28 bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
29 void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
30 void ReleaseStream() { m_Stream.ReleaseStream(); }
31 void Init()
32 {
33 m_Stream.Init();
34 m_BitPos = kNumBigValueBits;
35 m_Value = 0;
36 NumExtraBytes = 0;
37 }
38 UInt64 GetProcessedSize() const
39 { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
40 UInt64 GetProcessedBitsSize() const
41 { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
42 int GetBitPosition() const { return (m_BitPos & 7); }
44 void Normalize()
45 {
46 for (;m_BitPos >= 8; m_BitPos -= 8)
47 {
48 Byte b = 0;
49 if (!m_Stream.ReadByte(b))
50 {
51 b = 0xFF; // check it
52 NumExtraBytes++;
53 }
54 m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
55 }
56 }
58 UInt32 ReadBits(int numBits)
59 {
60 Normalize();
61 UInt32 res = m_Value & ((1 << numBits) - 1);
62 m_BitPos += numBits;
63 m_Value >>= numBits;
64 return res;
65 }
67 bool ExtraBitsWereRead() const
68 {
69 if (NumExtraBytes == 0)
70 return false;
71 return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
72 }
73 };
75 template<class TInByte>
76 class CDecoder: public CBaseDecoder<TInByte>
77 {
78 UInt32 m_NormalValue;
80 public:
81 void Init()
82 {
83 CBaseDecoder<TInByte>::Init();
84 m_NormalValue = 0;
85 }
87 void Normalize()
88 {
89 for (; this->m_BitPos >= 8; this->m_BitPos -= 8)
90 {
91 Byte b = 0;
92 if (!this->m_Stream.ReadByte(b))
93 {
94 b = 0xFF; // check it
95 this->NumExtraBytes++;
96 }
97 m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
98 this->m_Value = (this->m_Value << 8) | kInvertTable[b];
99 }
100 }
102 UInt32 GetValue(int numBits)
103 {
104 Normalize();
105 return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
106 }
108 void MovePos(int numBits)
109 {
110 this->m_BitPos += numBits;
111 m_NormalValue >>= numBits;
112 }
114 UInt32 ReadBits(int numBits)
115 {
116 Normalize();
117 UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
118 MovePos(numBits);
119 return res;
120 }
121 };
123 }
125 #endif