Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / Compress / LzxDecoder.h
1 // LzxDecoder.h\r
2 \r
3 #ifndef __LZX_DECODER_H\r
4 #define __LZX_DECODER_H\r
5 \r
6 #include "../ICoder.h"\r
7 \r
8 #include "../Common/InBuffer.h"\r
9 \r
10 #include "HuffmanDecoder.h"\r
11 #include "LzOutWindow.h"\r
12 #include "Lzx.h"\r
13 #include "Lzx86Converter.h"\r
14 \r
15 namespace NCompress {\r
16 namespace NLzx {\r
17 \r
18 namespace NBitStream {\r
19 \r
20 const unsigned kNumBigValueBits = 8 * 4;\r
21 const unsigned kNumValueBits = 17;\r
22 const UInt32 kBitDecoderValueMask = (1 << kNumValueBits) - 1;\r
23 \r
24 class CDecoder\r
25 {\r
26   CInBuffer m_Stream;\r
27   UInt32 m_Value;\r
28   unsigned m_BitPos;\r
29 public:\r
30   CDecoder() {}\r
31   bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }\r
32 \r
33   void SetStream(ISequentialInStream *s) { m_Stream.SetStream(s); }\r
34   void ReleaseStream() { m_Stream.ReleaseStream(); }\r
35 \r
36   void Init()\r
37   {\r
38     m_Stream.Init();\r
39     m_BitPos = kNumBigValueBits;\r
40   }\r
41 \r
42   UInt64 GetProcessedSize() const { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }\r
43   \r
44   unsigned GetBitPosition() const { return m_BitPos & 0xF; }\r
45 \r
46   void Normalize()\r
47   {\r
48     for (; m_BitPos >= 16; m_BitPos -= 16)\r
49     {\r
50       Byte b0 = m_Stream.ReadByte();\r
51       Byte b1 = m_Stream.ReadByte();\r
52       m_Value = (m_Value << 8) | b1;\r
53       m_Value = (m_Value << 8) | b0;\r
54     }\r
55   }\r
56 \r
57   UInt32 GetValue(unsigned numBits) const\r
58   {\r
59     return ((m_Value >> ((32 - kNumValueBits) - m_BitPos)) & kBitDecoderValueMask) >> (kNumValueBits - numBits);\r
60   }\r
61   \r
62   void MovePos(unsigned numBits)\r
63   {\r
64     m_BitPos += numBits;\r
65     Normalize();\r
66   }\r
67 \r
68   UInt32 ReadBits(unsigned numBits)\r
69   {\r
70     UInt32 res = GetValue(numBits);\r
71     MovePos(numBits);\r
72     return res;\r
73   }\r
74 \r
75   UInt32 ReadBitsBig(unsigned numBits)\r
76   {\r
77     unsigned numBits0 = numBits / 2;\r
78     unsigned numBits1 = numBits - numBits0;\r
79     UInt32 res = ReadBits(numBits0) << numBits1;\r
80     return res + ReadBits(numBits1);\r
81   }\r
82 \r
83   bool ReadUInt32(UInt32 &v)\r
84   {\r
85     if (m_BitPos != 0)\r
86       return false;\r
87     v = ((m_Value >> 16) & 0xFFFF) | ((m_Value << 16) & 0xFFFF0000);\r
88     m_BitPos = kNumBigValueBits;\r
89     return true;\r
90   }\r
91 \r
92   Byte DirectReadByte() { return m_Stream.ReadByte(); }\r
93 \r
94 };\r
95 }\r
96 \r
97 class CDecoder :\r
98   public ICompressCoder,\r
99   public CMyUnknownImp\r
100 {\r
101   NBitStream::CDecoder m_InBitStream;\r
102   CLzOutWindow m_OutWindowStream;\r
103 \r
104   UInt32 m_RepDistances[kNumRepDistances];\r
105   UInt32 m_NumPosLenSlots;\r
106 \r
107   bool m_IsUncompressedBlock;\r
108   bool m_AlignIsUsed;\r
109 \r
110   NCompress::NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;\r
111   NCompress::NHuffman::CDecoder<kNumHuffmanBits, kNumLenSymbols> m_LenDecoder;\r
112   NCompress::NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;\r
113   NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;\r
114 \r
115   Byte m_LastMainLevels[kMainTableSize];\r
116   Byte m_LastLenLevels[kNumLenSymbols];\r
117 \r
118   Cx86ConvertOutStream *m_x86ConvertOutStreamSpec;\r
119   CMyComPtr<ISequentialOutStream> m_x86ConvertOutStream;\r
120 \r
121   UInt32 m_UnCompressedBlockSize;\r
122 \r
123   bool _keepHistory;\r
124   int _remainLen;\r
125   bool _skipByte;\r
126 \r
127   bool _wimMode;\r
128 \r
129   UInt32 ReadBits(unsigned numBits);\r
130   bool ReadTable(Byte *lastLevels, Byte *newLevels, UInt32 numSymbols);\r
131   bool ReadTables();\r
132   void ClearPrevLevels();\r
133 \r
134   HRESULT CodeSpec(UInt32 size);\r
135 \r
136   HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
137       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
138 public:\r
139   CDecoder(bool wimMode = false);\r
140 \r
141   MY_UNKNOWN_IMP\r
142 \r
143   void ReleaseStreams();\r
144   STDMETHOD(Flush)();\r
145 \r
146   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,\r
147       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);\r
148 \r
149   STDMETHOD(SetInStream)(ISequentialInStream *inStream);\r
150   STDMETHOD(ReleaseInStream)();\r
151   STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);\r
152 \r
153   HRESULT SetParams(unsigned numDictBits);\r
154   void SetKeepHistory(bool keepHistory) {  _keepHistory = keepHistory; }\r
155 };\r
156 \r
157 }}\r
158 \r
159 #endif\r