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 UInt32 kNumRepDists = 4;
22 const UInt32 kDistTableSize = 48;
23 
24 const int 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 
InitCFilter88   void Init() { memset(this, 0, sizeof(*this)); }
89 
90 };
91 
92 const int kNumChanelsMax = 4;
93 
94 class CFilter2
95 {
96 public:
97   CFilter  m_Filters[kNumChanelsMax];
98   int m_ChannelDelta;
99   int CurrentChannel;
100 
Init()101   void Init() { memset(this, 0, sizeof(*this)); }
Decode(Byte delta)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 int 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   NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;
123   NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;
124   NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;
125   NHuffman::CDecoder<kNumHuffmanBits, kMMTableSize> m_MMDecoders[NMultimedia::kNumChanelsMax];
126   NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;
127 
128   bool m_AudioMode;
129 
130   NMultimedia::CFilter2 m_MmFilter;
131   int m_NumChannels;
132 
133   UInt32 m_RepDists[kNumRepDists];
134   UInt32 m_RepDistPtr;
135 
136   UInt32 m_LastLength;
137 
138   Byte m_LastLevels[kMaxTableSize];
139 
140   UInt64 m_PackSize;
141   bool m_IsSolid;
142 
143   void InitStructures();
144   UInt32 ReadBits(int numBits);
145   bool ReadTables();
146   bool ReadLastTables();
147 
148   bool DecodeMm(UInt32 pos);
149   bool DecodeLz(Int32 pos);
150 
151   HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
152       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
153 
154 public:
155   CDecoder();
156 
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)157   MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)
158 
159   void ReleaseStreams()
160   {
161     m_OutWindowStream.ReleaseStream();
162     m_InBitStream.ReleaseStream();
163   }
164 
165   STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
166       const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
167 
168   STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
169 
170 };
171 
172 }}
173 
174 #endif
175