diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Compress/LzhDecoder.h')
-rw-r--r-- | src/libs/7zip/unix/CPP/7zip/Compress/LzhDecoder.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Compress/LzhDecoder.h b/src/libs/7zip/unix/CPP/7zip/Compress/LzhDecoder.h new file mode 100644 index 000000000..4c32d63da --- /dev/null +++ b/src/libs/7zip/unix/CPP/7zip/Compress/LzhDecoder.h @@ -0,0 +1,106 @@ +// LzhDecoder.h + +#ifndef __COMPRESS_LZH_DECODER_H +#define __COMPRESS_LZH_DECODER_H + +#include "../../Common/MyCom.h" + +#include "../ICoder.h" + +#include "../Common/InBuffer.h" + +#include "BitmDecoder.h" +#include "HuffmanDecoder.h" +#include "LzOutWindow.h" + +namespace NCompress { +namespace NLzh { +namespace NDecoder { + +const int kMaxHuffmanLen = 16; // Check it + +const int kNumSpecLevelSymbols = 3; +const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen; + +const int kDictBitsMax = 16; +const int kNumDistanceSymbols = kDictBitsMax + 1; + +const int kMaxMatch = 256; +const int kMinMatch = 3; +const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch; + +template <UInt32 m_NumSymbols> +class CHuffmanDecoder:public NCompress::NHuffman::CDecoder<kMaxHuffmanLen, m_NumSymbols> +{ +public: + int Symbol; + template <class TBitDecoder> + UInt32 Decode(TBitDecoder *bitStream) + { + if (Symbol >= 0) + return (UInt32)Symbol; + return this->DecodeSymbol(bitStream); + } +}; + +class CCoder : + public ICompressCoder, + public CMyUnknownImp +{ + CLzOutWindow m_OutWindowStream; + NBitm::CDecoder<CInBuffer> m_InBitStream; + + int m_NumDictBits; + + CHuffmanDecoder<kNumLevelSymbols> m_LevelHuffman; + CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder; + CHuffmanDecoder<kNumCSymbols> m_CHuffmanDecoder; + + void ReleaseStreams() + { + m_OutWindowStream.ReleaseStream(); + m_InBitStream.ReleaseStream(); + } + + class CCoderReleaser + { + CCoder *m_Coder; + public: + bool NeedFlush; + CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {} + ~CCoderReleaser() + { + if (NeedFlush) + m_Coder->m_OutWindowStream.Flush(); + m_Coder->ReleaseStreams(); + } + }; + friend class CCoderReleaser; + + void MakeTable(int nchar, Byte *bitlen, int tablebits, + UInt32 *table, int tablesize); + + UInt32 ReadBits(int numBits); + HRESULT ReadLevelTable(); + HRESULT ReadPTable(int numBits); + HRESULT ReadCTable(); + +public: + + MY_UNKNOWN_IMP + + STDMETHOD(CodeReal)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + STDMETHOD(Code)(ISequentialInStream *inStream, + ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize, + ICompressProgressInfo *progress); + + void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; } + CCoder(): m_NumDictBits(0) {} +}; + +}}} + +#endif |