1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// DeflateDecoder.h
#ifndef __DEFLATE_DECODER_H
#define __DEFLATE_DECODER_H
#include "../../Common/MyCom.h"
#include "../ICoder.h"
#include "../Common/InBuffer.h"
#include "BitlDecoder.h"
#include "DeflateConst.h"
#include "HuffmanDecoder.h"
#include "LzOutWindow.h"
namespace NCompress {
namespace NDeflate {
namespace NDecoder {
const int kLenIdFinished = -1;
const int kLenIdNeedInit = -2;
class CCoder:
public ICompressCoder,
public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public ICompressReadUnusedFromInBuf,
#ifndef NO_READ_FROM_CODER
public ICompressSetInStream,
public ICompressSetOutStreamSize,
public ISequentialInStream,
#endif
public CMyUnknownImp
{
CLzOutWindow m_OutWindowStream;
CMyComPtr<ISequentialInStream> m_InStreamRef;
NBitl::CDecoder<CInBuffer> m_InBitStream;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder;
NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder;
NCompress::NHuffman::CDecoder7b<kLevelTableSize> m_LevelDecoder;
UInt32 m_StoredBlockSize;
UInt32 _numDistLevels;
bool m_FinalBlock;
bool m_StoredMode;
bool _deflateNSIS;
bool _deflate64Mode;
bool _keepHistory;
bool _needFinishInput;
bool _needInitInStream;
bool _needReadTable;
Int32 _remainLen;
UInt32 _rep0;
bool _outSizeDefined;
UInt64 _outSize;
UInt64 _outStartPos;
void SetOutStreamSizeResume(const UInt64 *outSize);
UInt64 GetOutProcessedCur() const { return m_OutWindowStream.GetProcessedSize() - _outStartPos; }
UInt32 ReadBits(unsigned numBits);
bool DecodeLevels(Byte *levels, unsigned numSymbols);
bool ReadTables();
HRESULT Flush() { return m_OutWindowStream.Flush(); }
class CCoderReleaser
{
CCoder *_coder;
public:
bool NeedFlush;
CCoderReleaser(CCoder *coder): _coder(coder), NeedFlush(true) {}
~CCoderReleaser()
{
if (NeedFlush)
_coder->Flush();
}
};
friend class CCoderReleaser;
HRESULT CodeSpec(UInt32 curSize, bool finishInputStream, UInt32 inputProgressLimit = 0);
public:
bool ZlibMode;
Byte ZlibFooter[4];
CCoder(bool deflate64Mode);
virtual ~CCoder() {};
void SetNsisMode(bool nsisMode) { _deflateNSIS = nsisMode; }
void Set_KeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
void Set_NeedFinishInput(bool needFinishInput) { _needFinishInput = needFinishInput; }
bool IsFinished() const { return _remainLen == kLenIdFinished;; }
bool IsFinalBlock() const { return m_FinalBlock; }
HRESULT CodeReal(ISequentialOutStream *outStream, ICompressProgressInfo *progress);
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetFinishMode)
MY_QUERYINTERFACE_ENTRY(ICompressGetInStreamProcessedSize)
MY_QUERYINTERFACE_ENTRY(ICompressReadUnusedFromInBuf)
#ifndef NO_READ_FROM_CODER
MY_QUERYINTERFACE_ENTRY(ICompressSetInStream)
MY_QUERYINTERFACE_ENTRY(ICompressSetOutStreamSize)
MY_QUERYINTERFACE_ENTRY(ISequentialInStream)
#endif
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
STDMETHOD(ReadUnusedFromInBuf)(void *data, UInt32 size, UInt32 *processedSize);
STDMETHOD(SetInStream)(ISequentialInStream *inStream);
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
#ifndef NO_READ_FROM_CODER
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
#endif
HRESULT CodeResume(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress);
HRESULT InitInStream(bool needInit);
void AlignToByte() { m_InBitStream.AlignToByte(); }
Byte ReadAlignedByte();
UInt32 ReadAligned_UInt16() // aligned for Byte range
{
UInt32 v = m_InBitStream.ReadAlignedByte();
return v | ((UInt32)m_InBitStream.ReadAlignedByte() << 8);
}
bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); }
// size of used real data from input stream
UInt64 GetStreamSize() const { return m_InBitStream.GetStreamSize(); }
// size of virtual input stream processed
UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); }
};
class CCOMCoder : public CCoder { public: CCOMCoder(): CCoder(false) {} };
class CCOMCoder64 : public CCoder { public: CCOMCoder64(): CCoder(true) {} };
}}}
#endif
|