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