rlm@1
|
1 // Compress/BZip2Decoder.h
|
rlm@1
|
2
|
rlm@1
|
3 #ifndef __COMPRESS_BZIP2_DECODER_H
|
rlm@1
|
4 #define __COMPRESS_BZIP2_DECODER_H
|
rlm@1
|
5
|
rlm@1
|
6 #include "../../Common/MyCom.h"
|
rlm@1
|
7
|
rlm@1
|
8 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
9 #include "../../Windows/Synchronization.h"
|
rlm@1
|
10 #include "../../Windows/Thread.h"
|
rlm@1
|
11 #endif
|
rlm@1
|
12
|
rlm@1
|
13 #include "../ICoder.h"
|
rlm@1
|
14
|
rlm@1
|
15 #include "../Common/InBuffer.h"
|
rlm@1
|
16 #include "../Common/OutBuffer.h"
|
rlm@1
|
17
|
rlm@1
|
18 #include "BitmDecoder.h"
|
rlm@1
|
19 #include "BZip2Const.h"
|
rlm@1
|
20 #include "BZip2Crc.h"
|
rlm@1
|
21 #include "HuffmanDecoder.h"
|
rlm@1
|
22
|
rlm@1
|
23 namespace NCompress {
|
rlm@1
|
24 namespace NBZip2 {
|
rlm@1
|
25
|
rlm@1
|
26 typedef NCompress::NHuffman::CDecoder<kMaxHuffmanLen, kMaxAlphaSize> CHuffmanDecoder;
|
rlm@1
|
27
|
rlm@1
|
28 class CDecoder;
|
rlm@1
|
29
|
rlm@1
|
30 struct CState
|
rlm@1
|
31 {
|
rlm@1
|
32 UInt32 *Counters;
|
rlm@1
|
33
|
rlm@1
|
34 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
35
|
rlm@1
|
36 CDecoder *Decoder;
|
rlm@1
|
37 NWindows::CThread Thread;
|
rlm@1
|
38 bool m_OptimizeNumTables;
|
rlm@1
|
39
|
rlm@1
|
40 NWindows::NSynchronization::CAutoResetEvent StreamWasFinishedEvent;
|
rlm@1
|
41 NWindows::NSynchronization::CAutoResetEvent WaitingWasStartedEvent;
|
rlm@1
|
42
|
rlm@1
|
43 // it's not member of this thread. We just need one event per thread
|
rlm@1
|
44 NWindows::NSynchronization::CAutoResetEvent CanWriteEvent;
|
rlm@1
|
45
|
rlm@1
|
46 Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
rlm@1
|
47
|
rlm@1
|
48 HRESULT Create();
|
rlm@1
|
49 void FinishStream();
|
rlm@1
|
50 void ThreadFunc();
|
rlm@1
|
51
|
rlm@1
|
52 #endif
|
rlm@1
|
53
|
rlm@1
|
54 CState(): Counters(0) {}
|
rlm@1
|
55 ~CState() { Free(); }
|
rlm@1
|
56 bool Alloc();
|
rlm@1
|
57 void Free();
|
rlm@1
|
58 };
|
rlm@1
|
59
|
rlm@1
|
60 class CDecoder :
|
rlm@1
|
61 public ICompressCoder,
|
rlm@1
|
62 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
63 public ICompressSetCoderMt,
|
rlm@1
|
64 #endif
|
rlm@1
|
65 public ICompressGetInStreamProcessedSize,
|
rlm@1
|
66 public CMyUnknownImp
|
rlm@1
|
67 {
|
rlm@1
|
68 public:
|
rlm@1
|
69 COutBuffer m_OutStream;
|
rlm@1
|
70 Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
|
rlm@1
|
71 NBitm::CDecoder<CInBuffer> m_InStream;
|
rlm@1
|
72 Byte m_Selectors[kNumSelectorsMax];
|
rlm@1
|
73 CHuffmanDecoder m_HuffmanDecoders[kNumTablesMax];
|
rlm@1
|
74 private:
|
rlm@1
|
75
|
rlm@1
|
76 UInt32 m_NumThreadsPrev;
|
rlm@1
|
77
|
rlm@1
|
78 UInt32 ReadBits(int numBits);
|
rlm@1
|
79 Byte ReadByte();
|
rlm@1
|
80 bool ReadBit();
|
rlm@1
|
81 UInt32 ReadCrc();
|
rlm@1
|
82 HRESULT PrepareBlock(CState &state);
|
rlm@1
|
83 HRESULT DecodeFile(bool &isBZ, ICompressProgressInfo *progress);
|
rlm@1
|
84 HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
rlm@1
|
85 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
rlm@1
|
86 class CDecoderFlusher
|
rlm@1
|
87 {
|
rlm@1
|
88 CDecoder *_decoder;
|
rlm@1
|
89 public:
|
rlm@1
|
90 bool NeedFlush;
|
rlm@1
|
91 CDecoderFlusher(CDecoder *decoder): _decoder(decoder), NeedFlush(true) {}
|
rlm@1
|
92 ~CDecoderFlusher()
|
rlm@1
|
93 {
|
rlm@1
|
94 if (NeedFlush)
|
rlm@1
|
95 _decoder->Flush();
|
rlm@1
|
96 _decoder->ReleaseStreams();
|
rlm@1
|
97 }
|
rlm@1
|
98 };
|
rlm@1
|
99
|
rlm@1
|
100 public:
|
rlm@1
|
101 CBZip2CombinedCrc CombinedCrc;
|
rlm@1
|
102
|
rlm@1
|
103 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
104 ICompressProgressInfo *Progress;
|
rlm@1
|
105 CState *m_States;
|
rlm@1
|
106
|
rlm@1
|
107 NWindows::NSynchronization::CManualResetEvent CanProcessEvent;
|
rlm@1
|
108 NWindows::NSynchronization::CCriticalSection CS;
|
rlm@1
|
109 UInt32 NumThreads;
|
rlm@1
|
110 bool MtMode;
|
rlm@1
|
111 UInt32 NextBlockIndex;
|
rlm@1
|
112 bool CloseThreads;
|
rlm@1
|
113 bool StreamWasFinished1;
|
rlm@1
|
114 bool StreamWasFinished2;
|
rlm@1
|
115 NWindows::NSynchronization::CManualResetEvent CanStartWaitingEvent;
|
rlm@1
|
116
|
rlm@1
|
117 HRESULT Result1;
|
rlm@1
|
118 HRESULT Result2;
|
rlm@1
|
119
|
rlm@1
|
120 UInt32 BlockSizeMax;
|
rlm@1
|
121 CDecoder();
|
rlm@1
|
122 ~CDecoder();
|
rlm@1
|
123 HRESULT Create();
|
rlm@1
|
124 void Free();
|
rlm@1
|
125
|
rlm@1
|
126 #else
|
rlm@1
|
127 CState m_States[1];
|
rlm@1
|
128 #endif
|
rlm@1
|
129
|
rlm@1
|
130 HRESULT ReadSignatures(bool &wasFinished, UInt32 &crc);
|
rlm@1
|
131
|
rlm@1
|
132
|
rlm@1
|
133 HRESULT Flush() { return m_OutStream.Flush(); }
|
rlm@1
|
134 void ReleaseStreams()
|
rlm@1
|
135 {
|
rlm@1
|
136 m_InStream.ReleaseStream();
|
rlm@1
|
137 m_OutStream.ReleaseStream();
|
rlm@1
|
138 }
|
rlm@1
|
139
|
rlm@1
|
140 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
141 MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressGetInStreamProcessedSize)
|
rlm@1
|
142 #else
|
rlm@1
|
143 MY_UNKNOWN_IMP1(ICompressGetInStreamProcessedSize)
|
rlm@1
|
144 #endif
|
rlm@1
|
145
|
rlm@1
|
146
|
rlm@1
|
147 STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
|
rlm@1
|
148 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
|
rlm@1
|
149
|
rlm@1
|
150 STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
|
rlm@1
|
151
|
rlm@1
|
152 #ifdef COMPRESS_BZIP2_MT
|
rlm@1
|
153 STDMETHOD(SetNumberOfThreads)(UInt32 numThreads);
|
rlm@1
|
154 #endif
|
rlm@1
|
155 };
|
rlm@1
|
156
|
rlm@1
|
157 }}
|
rlm@1
|
158
|
rlm@1
|
159 #endif
|