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