| // 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 { |
| |
| class CCoder: |
| public ICompressCoder, |
| public ICompressGetInStreamProcessedSize, |
| #ifndef NO_READ_FROM_CODER |
| public ICompressSetInStream, |
| public ICompressSetOutStreamSize, |
| public ISequentialInStream, |
| #endif |
| public CMyUnknownImp |
| { |
| CLzOutWindow m_OutWindowStream; |
| NBitl::CDecoder<CInBuffer> m_InBitStream; |
| NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedMainTableSize> m_MainDecoder; |
| NCompress::NHuffman::CDecoder<kNumHuffmanBits, kFixedDistTableSize> m_DistDecoder; |
| NCompress::NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; |
| |
| UInt32 m_StoredBlockSize; |
| |
| bool m_FinalBlock; |
| bool m_StoredMode; |
| UInt32 _numDistLevels; |
| |
| |
| bool _deflateNSIS; |
| bool _deflate64Mode; |
| bool _keepHistory; |
| bool _needInitInStream; |
| Int32 _remainLen; |
| UInt32 _rep0; |
| bool _needReadTable; |
| |
| UInt32 ReadBits(int numBits); |
| |
| bool DeCodeLevelTable(Byte *values, int 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(); |
| _coder->ReleaseOutStream(); |
| } |
| }; |
| friend class CCoderReleaser; |
| |
| HRESULT CodeSpec(UInt32 curSize); |
| public: |
| bool ZlibMode; |
| Byte ZlibFooter[4]; |
| |
| CCoder(bool deflate64Mode, bool deflateNSIS = false); |
| virtual ~CCoder() {}; |
| |
| void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; } |
| |
| void ReleaseOutStream() |
| { |
| m_OutWindowStream.ReleaseStream(); |
| } |
| |
| HRESULT CodeReal(ISequentialOutStream *outStream, |
| const UInt64 *outSize, ICompressProgressInfo *progress); |
| |
| #ifndef NO_READ_FROM_CODER |
| MY_UNKNOWN_IMP4( |
| ICompressGetInStreamProcessedSize, |
| ICompressSetInStream, |
| ICompressSetOutStreamSize, |
| ISequentialInStream |
| ) |
| #else |
| MY_UNKNOWN_IMP1( |
| ICompressGetInStreamProcessedSize) |
| #endif |
| |
| STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, |
| const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); |
| |
| 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 |
| |
| STDMETHOD(CodeResume)(ISequentialOutStream *outStream, const UInt64 *outSize, ICompressProgressInfo *progress); |
| |
| HRESULT InitInStream(bool needInit) |
| { |
| if (!m_InBitStream.Create(1 << 17)) |
| return E_OUTOFMEMORY; |
| if (needInit) |
| { |
| m_InBitStream.Init(); |
| _needInitInStream = false; |
| } |
| return S_OK; |
| } |
| |
| void AlignToByte() { m_InBitStream.AlignToByte(); } |
| Byte ReadByte() { return (Byte)m_InBitStream.ReadBits(8); } |
| bool InputEofError() const { return m_InBitStream.ExtraBitsWereRead(); } |
| UInt64 GetInputProcessedSize() const { return m_InBitStream.GetProcessedSize(); } |
| |
| // IGetInStreamProcessedSize |
| STDMETHOD(GetInStreamProcessedSize)(UInt64 *value); |
| }; |
| |
| class CCOMCoder : public CCoder |
| { |
| public: |
| CCOMCoder(): CCoder(false) {} |
| }; |
| |
| class CNsisCOMCoder : public CCoder |
| { |
| public: |
| CNsisCOMCoder(): CCoder(false, true) {} |
| }; |
| |
| class CCOMCoder64 : public CCoder |
| { |
| public: |
| CCOMCoder64(): CCoder(true) {} |
| }; |
| |
| }}} |
| |
| #endif |