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
|
// 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
|