diff options
Diffstat (limited to 'CPP/7zip/Compress/Rar2Decoder.h')
-rw-r--r-- | CPP/7zip/Compress/Rar2Decoder.h | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/CPP/7zip/Compress/Rar2Decoder.h b/CPP/7zip/Compress/Rar2Decoder.h new file mode 100644 index 0000000..f42f228 --- /dev/null +++ b/CPP/7zip/Compress/Rar2Decoder.h | |||
@@ -0,0 +1,172 @@ | |||
1 | // Rar2Decoder.h | ||
2 | // According to unRAR license, this code may not be used to develop | ||
3 | // a program that creates RAR archives | ||
4 | |||
5 | #ifndef __COMPRESS_RAR2_DECODER_H | ||
6 | #define __COMPRESS_RAR2_DECODER_H | ||
7 | |||
8 | #include "../../Common/MyCom.h" | ||
9 | |||
10 | #include "../ICoder.h" | ||
11 | |||
12 | #include "../Common/InBuffer.h" | ||
13 | |||
14 | #include "BitmDecoder.h" | ||
15 | #include "HuffmanDecoder.h" | ||
16 | #include "LzOutWindow.h" | ||
17 | |||
18 | namespace NCompress { | ||
19 | namespace NRar2 { | ||
20 | |||
21 | const unsigned kNumRepDists = 4; | ||
22 | const unsigned kDistTableSize = 48; | ||
23 | |||
24 | const unsigned kMMTableSize = 256 + 1; | ||
25 | |||
26 | const UInt32 kMainTableSize = 298; | ||
27 | const UInt32 kLenTableSize = 28; | ||
28 | |||
29 | const UInt32 kDistTableStart = kMainTableSize; | ||
30 | const UInt32 kLenTableStart = kDistTableStart + kDistTableSize; | ||
31 | |||
32 | const UInt32 kHeapTablesSizesSum = kMainTableSize + kDistTableSize + kLenTableSize; | ||
33 | |||
34 | const UInt32 kLevelTableSize = 19; | ||
35 | |||
36 | const UInt32 kMMTablesSizesSum = kMMTableSize * 4; | ||
37 | |||
38 | const UInt32 kMaxTableSize = kMMTablesSizesSum; | ||
39 | |||
40 | const UInt32 kTableDirectLevels = 16; | ||
41 | const UInt32 kTableLevelRepNumber = kTableDirectLevels; | ||
42 | const UInt32 kTableLevel0Number = kTableLevelRepNumber + 1; | ||
43 | const UInt32 kTableLevel0Number2 = kTableLevel0Number + 1; | ||
44 | |||
45 | const UInt32 kLevelMask = 0xF; | ||
46 | |||
47 | |||
48 | const UInt32 kRepBothNumber = 256; | ||
49 | const UInt32 kRepNumber = kRepBothNumber + 1; | ||
50 | const UInt32 kLen2Number = kRepNumber + 4; | ||
51 | |||
52 | const UInt32 kLen2NumNumbers = 8; | ||
53 | const UInt32 kReadTableNumber = kLen2Number + kLen2NumNumbers; | ||
54 | const UInt32 kMatchNumber = kReadTableNumber + 1; | ||
55 | |||
56 | const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224}; | ||
57 | const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5}; | ||
58 | |||
59 | const UInt32 kDistStart [kDistTableSize] = {0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040}; | ||
60 | const Byte kDistDirectBits[kDistTableSize] = {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; | ||
61 | |||
62 | const Byte kLevelDirectBits[kLevelTableSize] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; | ||
63 | |||
64 | const Byte kLen2DistStarts[kLen2NumNumbers]={0,4,8,16,32,64,128,192}; | ||
65 | const Byte kLen2DistDirectBits[kLen2NumNumbers]={2,2,3, 4, 5, 6, 6, 6}; | ||
66 | |||
67 | const UInt32 kDistLimit2 = 0x101 - 1; | ||
68 | const UInt32 kDistLimit3 = 0x2000 - 1; | ||
69 | const UInt32 kDistLimit4 = 0x40000 - 1; | ||
70 | |||
71 | const UInt32 kMatchMaxLen = 255 + 2; | ||
72 | const UInt32 kMatchMaxLenMax = 255 + 5; | ||
73 | const UInt32 kNormalMatchMinLen = 3; | ||
74 | |||
75 | namespace NMultimedia { | ||
76 | |||
77 | struct CFilter | ||
78 | { | ||
79 | int K1,K2,K3,K4,K5; | ||
80 | int D1,D2,D3,D4; | ||
81 | int LastDelta; | ||
82 | UInt32 Dif[11]; | ||
83 | UInt32 ByteCount; | ||
84 | int LastChar; | ||
85 | |||
86 | Byte Decode(int &channelDelta, Byte delta); | ||
87 | |||
88 | void Init() { memset(this, 0, sizeof(*this)); } | ||
89 | |||
90 | }; | ||
91 | |||
92 | const unsigned kNumChanelsMax = 4; | ||
93 | |||
94 | class CFilter2 | ||
95 | { | ||
96 | public: | ||
97 | CFilter m_Filters[kNumChanelsMax]; | ||
98 | int m_ChannelDelta; | ||
99 | unsigned CurrentChannel; | ||
100 | |||
101 | void Init() { memset(this, 0, sizeof(*this)); } | ||
102 | Byte Decode(Byte delta) | ||
103 | { | ||
104 | return m_Filters[CurrentChannel].Decode(m_ChannelDelta, delta); | ||
105 | } | ||
106 | |||
107 | }; | ||
108 | |||
109 | } | ||
110 | |||
111 | typedef NBitm::CDecoder<CInBuffer> CBitDecoder; | ||
112 | |||
113 | const unsigned kNumHuffmanBits = 15; | ||
114 | |||
115 | class CDecoder : | ||
116 | public ICompressCoder, | ||
117 | public ICompressSetDecoderProperties2, | ||
118 | public CMyUnknownImp | ||
119 | { | ||
120 | CLzOutWindow m_OutWindowStream; | ||
121 | CBitDecoder m_InBitStream; | ||
122 | |||
123 | UInt32 m_RepDistPtr; | ||
124 | UInt32 m_RepDists[kNumRepDists]; | ||
125 | |||
126 | UInt32 m_LastLength; | ||
127 | |||
128 | bool _isSolid; | ||
129 | bool _solidAllowed; | ||
130 | bool m_TablesOK; | ||
131 | bool m_AudioMode; | ||
132 | |||
133 | NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; | ||
134 | NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder; | ||
135 | NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder; | ||
136 | NHuffman::CDecoder<kNumHuffmanBits, kMMTableSize> m_MMDecoders[NMultimedia::kNumChanelsMax]; | ||
137 | NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; | ||
138 | |||
139 | UInt64 m_PackSize; | ||
140 | |||
141 | unsigned m_NumChannels; | ||
142 | NMultimedia::CFilter2 m_MmFilter; | ||
143 | |||
144 | Byte m_LastLevels[kMaxTableSize]; | ||
145 | |||
146 | |||
147 | void InitStructures(); | ||
148 | UInt32 ReadBits(unsigned numBits); | ||
149 | bool ReadTables(); | ||
150 | bool ReadLastTables(); | ||
151 | |||
152 | bool DecodeMm(UInt32 pos); | ||
153 | bool DecodeLz(Int32 pos); | ||
154 | |||
155 | HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, | ||
156 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); | ||
157 | |||
158 | public: | ||
159 | CDecoder(); | ||
160 | |||
161 | MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) | ||
162 | |||
163 | STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, | ||
164 | const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); | ||
165 | |||
166 | STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); | ||
167 | |||
168 | }; | ||
169 | |||
170 | }} | ||
171 | |||
172 | #endif | ||