aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Compress/BZip2Decoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress/BZip2Decoder.h')
-rw-r--r--CPP/7zip/Compress/BZip2Decoder.h402
1 files changed, 402 insertions, 0 deletions
diff --git a/CPP/7zip/Compress/BZip2Decoder.h b/CPP/7zip/Compress/BZip2Decoder.h
new file mode 100644
index 0000000..8fe4ef1
--- /dev/null
+++ b/CPP/7zip/Compress/BZip2Decoder.h
@@ -0,0 +1,402 @@
1// Compress/BZip2Decoder.h
2
3#ifndef __COMPRESS_BZIP2_DECODER_H
4#define __COMPRESS_BZIP2_DECODER_H
5
6#include "../../Common/MyCom.h"
7
8// #define NO_READ_FROM_CODER
9// #define _7ZIP_ST
10
11#ifndef _7ZIP_ST
12#include "../../Windows/Synchronization.h"
13#include "../../Windows/Thread.h"
14#endif
15
16#include "../ICoder.h"
17
18#include "BZip2Const.h"
19#include "BZip2Crc.h"
20#include "HuffmanDecoder.h"
21#include "Mtf8.h"
22
23namespace NCompress {
24namespace NBZip2 {
25
26bool IsEndSig(const Byte *p) throw();
27bool IsBlockSig(const Byte *p) throw();
28
29const unsigned kNumTableBits = 9;
30const unsigned kNumBitsMax = kMaxHuffmanLen;
31
32typedef NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize, kNumTableBits> CHuffmanDecoder;
33
34
35struct CBlockProps
36{
37 UInt32 blockSize;
38 UInt32 origPtr;
39 unsigned randMode;
40
41 CBlockProps(): blockSize(0), origPtr(0), randMode(0) {}
42};
43
44
45struct CBitDecoder
46{
47 unsigned _numBits;
48 UInt32 _value;
49 const Byte *_buf;
50 const Byte *_lim;
51
52 void InitBitDecoder()
53 {
54 _numBits = 0;
55 _value = 0;
56 }
57
58 void AlignToByte()
59 {
60 unsigned bits = _numBits & 7;
61 _numBits -= bits;
62 _value <<= bits;
63 }
64
65 /*
66 bool AreRemainByteBitsEmpty() const
67 {
68 unsigned bits = _numBits & 7;
69 if (bits != 0)
70 return (_value >> (32 - bits)) == 0;
71 return true;
72 }
73 */
74
75 SRes ReadByte(int &b);
76
77 CBitDecoder():
78 _buf(NULL),
79 _lim(NULL)
80 {
81 InitBitDecoder();
82 }
83};
84
85
86// 19.03: we allow additional 8 selectors to support files created by lbzip2.
87const UInt32 kNumSelectorsMax_Decoder = kNumSelectorsMax + 8;
88
89struct CBase: public CBitDecoder
90{
91 unsigned numInUse;
92 UInt32 groupIndex;
93 UInt32 groupSize;
94 unsigned runPower;
95 UInt32 runCounter;
96 UInt32 blockSize;
97
98 UInt32 *Counters;
99 UInt32 blockSizeMax;
100
101 unsigned state;
102 unsigned state2;
103 unsigned state3;
104 unsigned state4;
105 unsigned state5;
106 unsigned numTables;
107 UInt32 numSelectors;
108
109 CBlockProps Props;
110
111private:
112 CMtf8Decoder mtf;
113 Byte selectors[kNumSelectorsMax_Decoder];
114 CHuffmanDecoder huffs[kNumTablesMax];
115
116 Byte lens[kMaxAlphaSize];
117
118 Byte temp[10];
119
120public:
121 UInt32 crc;
122 CBZip2CombinedCrc CombinedCrc;
123
124 bool IsBz;
125 bool StreamCrcError;
126 bool MinorError;
127 bool NeedMoreInput;
128
129 bool DecodeAllStreams;
130
131 UInt64 NumStreams;
132 UInt64 NumBlocks;
133 UInt64 FinishedPackSize;
134
135 ISequentialInStream *InStream;
136
137 #ifndef NO_READ_FROM_CODER
138 CMyComPtr<ISequentialInStream> InStreamRef;
139 #endif
140
141 CBase():
142 StreamCrcError(false),
143 MinorError(false),
144 NeedMoreInput(false),
145
146 DecodeAllStreams(false),
147
148 NumStreams(0),
149 NumBlocks(0),
150 FinishedPackSize(0)
151 {}
152
153 void InitNumStreams2()
154 {
155 StreamCrcError = false;
156 MinorError = false;
157 NeedMoreInput = 0;
158 NumStreams = 0;
159 NumBlocks = 0;
160 FinishedPackSize = 0;
161 }
162
163 SRes ReadStreamSignature2();
164 SRes ReadBlockSignature2();
165
166 /* ReadBlock2() : Props->randMode:
167 in: need read randMode bit
168 out: randMode status */
169 SRes ReadBlock2();
170};
171
172
173class CSpecState
174{
175 UInt32 _tPos;
176 unsigned _prevByte;
177 int _reps;
178
179public:
180 CBZip2Crc _crc;
181 UInt32 _blockSize;
182 UInt32 *_tt;
183
184 int _randToGo;
185 unsigned _randIndex;
186
187 void Init(UInt32 origPtr, unsigned randMode) throw();
188
189 bool Finished() const { return _reps <= 0 && _blockSize == 0; }
190
191 Byte *Decode(Byte *data, size_t size) throw();
192};
193
194
195
196
197class CDecoder :
198 public ICompressCoder,
199 public ICompressSetFinishMode,
200 public ICompressGetInStreamProcessedSize,
201 public ICompressReadUnusedFromInBuf,
202
203 #ifndef NO_READ_FROM_CODER
204 public ICompressSetInStream,
205 public ICompressSetOutStreamSize,
206 public ISequentialInStream,
207 #endif
208
209 #ifndef _7ZIP_ST
210 public ICompressSetCoderMt,
211 #endif
212
213 public CMyUnknownImp
214{
215 Byte *_outBuf;
216 size_t _outPos;
217 UInt64 _outWritten;
218 ISequentialOutStream *_outStream;
219 HRESULT _writeRes;
220
221protected:
222 HRESULT ErrorResult; // for ISequentialInStream::Read mode only
223
224public:
225
226 UInt32 _calcedBlockCrc;
227 bool _blockFinished;
228 bool BlockCrcError;
229
230 bool FinishMode;
231 bool _outSizeDefined;
232 UInt64 _outSize;
233 UInt64 _outPosTotal;
234
235 CSpecState _spec;
236 UInt32 *_counters;
237
238 #ifndef _7ZIP_ST
239
240 struct CBlock
241 {
242 bool StopScout;
243
244 bool WasFinished;
245 bool Crc_Defined;
246 // bool NextCrc_Defined;
247
248 UInt32 Crc;
249 UInt32 NextCrc;
250 HRESULT Res;
251 UInt64 PackPos;
252
253 CBlockProps Props;
254 };
255
256 CBlock _block;
257
258 bool NeedWaitScout;
259 bool MtMode;
260
261 NWindows::CThread Thread;
262 NWindows::NSynchronization::CAutoResetEvent DecoderEvent;
263 NWindows::NSynchronization::CAutoResetEvent ScoutEvent;
264 // HRESULT ScoutRes;
265
266 Byte MtPad[1 << 7]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
267
268
269 void RunScout();
270
271 void WaitScout()
272 {
273 if (NeedWaitScout)
274 {
275 DecoderEvent.Lock();
276 NeedWaitScout = false;
277 }
278 }
279
280 class CWaitScout_Releaser
281 {
282 CDecoder *_decoder;
283 public:
284 CWaitScout_Releaser(CDecoder *decoder): _decoder(decoder) {}
285 ~CWaitScout_Releaser() { _decoder->WaitScout(); }
286 };
287
288 HRESULT CreateThread();
289
290 #endif
291
292 Byte *_inBuf;
293 UInt64 _inProcessed;
294 bool _inputFinished;
295 HRESULT _inputRes;
296
297 CBase Base;
298
299 bool GetCrcError() const { return BlockCrcError || Base.StreamCrcError; }
300
301 void InitOutSize(const UInt64 *outSize);
302
303 bool CreateInputBufer();
304
305 void InitInputBuffer()
306 {
307 // We use InitInputBuffer() before stream init.
308 // So don't read from stream here
309 _inProcessed = 0;
310 Base._buf = _inBuf;
311 Base._lim = _inBuf;
312 Base.InitBitDecoder();
313 }
314
315 UInt64 GetInputProcessedSize() const
316 {
317 // for NSIS case : we need also look the number of bits in bitDecoder
318 return _inProcessed + (size_t)(Base._buf - _inBuf);
319 }
320
321 UInt64 GetInStreamSize() const
322 {
323 return _inProcessed + (size_t)(Base._buf - _inBuf) - (Base._numBits >> 3);
324 }
325
326 UInt64 GetOutProcessedSize() const { return _outWritten + _outPos; }
327
328 HRESULT ReadInput();
329
330 void StartNewStream();
331
332 HRESULT ReadStreamSignature();
333 HRESULT StartRead();
334
335 HRESULT ReadBlockSignature();
336 HRESULT ReadBlock();
337
338 HRESULT Flush();
339 HRESULT DecodeBlock(const CBlockProps &props);
340 HRESULT DecodeStreams(ICompressProgressInfo *progress);
341
342 MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
343 MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
344 MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
345 MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf)
346
347 #ifndef NO_READ_FROM_CODER
348 MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
349 MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
350 MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
351 #endif
352
353 #ifndef _7ZIP_ST
354 MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
355 #endif
356
357 MY_QUERYINTERFACE_END
358 MY_ADDREF_RELEASE
359
360
361 STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
362 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
363
364 STDMETHOD(SetFinishMode)(UInt32 finishMode);
365 STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
366 STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize);
367
368 UInt64 GetNumStreams() const { return Base.NumStreams; }
369 UInt64 GetNumBlocks() const { return Base.NumBlocks; }
370
371 #ifndef NO_READ_FROM_CODER
372
373 STDMETHOD(SetInStream)(ISequentialInStream *inStream);
374 STDMETHOD(ReleaseInStream)();
375 STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
376 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
377
378 #endif
379
380 #ifndef _7ZIP_ST
381 STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
382 #endif
383
384 CDecoder();
385 ~CDecoder();
386};
387
388
389
390#ifndef NO_READ_FROM_CODER
391
392class CNsisDecoder : public CDecoder
393{
394public:
395 STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
396};
397
398#endif
399
400}}
401
402#endif