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