rlm@1
|
1 // LzhDecoder.h
|
rlm@1
|
2
|
rlm@1
|
3 #ifndef __COMPRESS_LZH_DECODER_H
|
rlm@1
|
4 #define __COMPRESS_LZH_DECODER_H
|
rlm@1
|
5
|
rlm@1
|
6 #include "../../Common/MyCom.h"
|
rlm@1
|
7
|
rlm@1
|
8 #include "../ICoder.h"
|
rlm@1
|
9
|
rlm@1
|
10 #include "../Common/InBuffer.h"
|
rlm@1
|
11
|
rlm@1
|
12 #include "BitmDecoder.h"
|
rlm@1
|
13 #include "HuffmanDecoder.h"
|
rlm@1
|
14 #include "LzOutWindow.h"
|
rlm@1
|
15
|
rlm@1
|
16 namespace NCompress {
|
rlm@1
|
17 namespace NLzh {
|
rlm@1
|
18 namespace NDecoder {
|
rlm@1
|
19
|
rlm@1
|
20 const int kMaxHuffmanLen = 16; // Check it
|
rlm@1
|
21
|
rlm@1
|
22 const int kNumSpecLevelSymbols = 3;
|
rlm@1
|
23 const int kNumLevelSymbols = kNumSpecLevelSymbols + kMaxHuffmanLen;
|
rlm@1
|
24
|
rlm@1
|
25 const int kDictBitsMax = 16;
|
rlm@1
|
26 const int kNumDistanceSymbols = kDictBitsMax + 1;
|
rlm@1
|
27
|
rlm@1
|
28 const int kMaxMatch = 256;
|
rlm@1
|
29 const int kMinMatch = 3;
|
rlm@1
|
30 const int kNumCSymbols = 256 + kMaxMatch + 2 - kMinMatch;
|
rlm@1
|
31
|
rlm@1
|
32 template <UInt32 m_NumSymbols>
|
rlm@1
|
33 class CHuffmanDecoder:public NCompress::NHuffman::CDecoder<kMaxHuffmanLen, m_NumSymbols>
|
rlm@1
|
34 {
|
rlm@1
|
35 public:
|
rlm@1
|
36 int Symbol;
|
rlm@1
|
37 template <class TBitDecoder>
|
rlm@1
|
38 UInt32 Decode(TBitDecoder *bitStream)
|
rlm@1
|
39 {
|
rlm@1
|
40 if (Symbol >= 0)
|
rlm@1
|
41 return (UInt32)Symbol;
|
rlm@1
|
42 return DecodeSymbol(bitStream);
|
rlm@1
|
43 }
|
rlm@1
|
44 };
|
rlm@1
|
45
|
rlm@1
|
46 class CCoder :
|
rlm@1
|
47 public ICompressCoder,
|
rlm@1
|
48 public CMyUnknownImp
|
rlm@1
|
49 {
|
rlm@1
|
50 CLzOutWindow m_OutWindowStream;
|
rlm@1
|
51 NBitm::CDecoder<CInBuffer> m_InBitStream;
|
rlm@1
|
52
|
rlm@1
|
53 int m_NumDictBits;
|
rlm@1
|
54
|
rlm@1
|
55 CHuffmanDecoder<kNumLevelSymbols> m_LevelHuffman;
|
rlm@1
|
56 CHuffmanDecoder<kNumDistanceSymbols> m_PHuffmanDecoder;
|
rlm@1
|
57 CHuffmanDecoder<kNumCSymbols> m_CHuffmanDecoder;
|
rlm@1
|
58
|
rlm@1
|
59 void ReleaseStreams()
|
rlm@1
|
60 {
|
rlm@1
|
61 m_OutWindowStream.ReleaseStream();
|
rlm@1
|
62 m_InBitStream.ReleaseStream();
|
rlm@1
|
63 }
|
rlm@1
|
64
|
rlm@1
|
65 class CCoderReleaser
|
rlm@1
|
66 {
|
rlm@1
|
67 CCoder *m_Coder;
|
rlm@1
|
68 public:
|
rlm@1
|
69 bool NeedFlush;
|
rlm@1
|
70 CCoderReleaser(CCoder *coder): m_Coder(coder), NeedFlush(true) {}
|
rlm@1
|
71 ~CCoderReleaser()
|
rlm@1
|
72 {
|
rlm@1
|
73 if (NeedFlush)
|
rlm@1
|
74 m_Coder->m_OutWindowStream.Flush();
|
rlm@1
|
75 m_Coder->ReleaseStreams();
|
rlm@1
|
76 }
|
rlm@1
|
77 };
|
rlm@1
|
78 friend class CCoderReleaser;
|
rlm@1
|
79
|
rlm@1
|
80 void MakeTable(int nchar, Byte *bitlen, int tablebits,
|
rlm@1
|
81 UInt32 *table, int tablesize);
|
rlm@1
|
82
|
rlm@1
|
83 UInt32 ReadBits(int numBits);
|
rlm@1
|
84 HRESULT ReadLevelTable();
|
rlm@1
|
85 HRESULT ReadPTable(int numBits);
|
rlm@1
|
86 HRESULT ReadCTable();
|
rlm@1
|
87
|
rlm@1
|
88 public:
|
rlm@1
|
89
|
rlm@1
|
90 MY_UNKNOWN_IMP
|
rlm@1
|
91
|
rlm@1
|
92 STDMETHOD(CodeReal)(ISequentialInStream *inStream,
|
rlm@1
|
93 ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
rlm@1
|
94 ICompressProgressInfo *progress);
|
rlm@1
|
95
|
rlm@1
|
96 STDMETHOD(Code)(ISequentialInStream *inStream,
|
rlm@1
|
97 ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
rlm@1
|
98 ICompressProgressInfo *progress);
|
rlm@1
|
99
|
rlm@1
|
100 void SetDictionary(int numDictBits) { m_NumDictBits = numDictBits; }
|
rlm@1
|
101 CCoder(): m_NumDictBits(0) {}
|
rlm@1
|
102 };
|
rlm@1
|
103
|
rlm@1
|
104 }}}
|
rlm@1
|
105
|
rlm@1
|
106 #endif
|