Mercurial > vba-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
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; | |
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); } | |
43 | |
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 } | |
57 | |
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 } | |
66 | |
67 bool ExtraBitsWereRead() const | |
68 { | |
69 if (NumExtraBytes == 0) | |
70 return false; | |
71 return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3)); | |
72 } | |
73 }; | |
74 | |
75 template<class TInByte> | |
76 class CDecoder: public CBaseDecoder<TInByte> | |
77 { | |
78 UInt32 m_NormalValue; | |
79 | |
80 public: | |
81 void Init() | |
82 { | |
83 CBaseDecoder<TInByte>::Init(); | |
84 m_NormalValue = 0; | |
85 } | |
86 | |
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 } | |
101 | |
102 UInt32 GetValue(int numBits) | |
103 { | |
104 Normalize(); | |
105 return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits); | |
106 } | |
107 | |
108 void MovePos(int numBits) | |
109 { | |
110 this->m_BitPos += numBits; | |
111 m_NormalValue >>= numBits; | |
112 } | |
113 | |
114 UInt32 ReadBits(int numBits) | |
115 { | |
116 Normalize(); | |
117 UInt32 res = m_NormalValue & ( (1 << numBits) - 1); | |
118 MovePos(numBits); | |
119 return res; | |
120 } | |
121 }; | |
122 | |
123 } | |
124 | |
125 #endif |