Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/Rar3Decoder.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/Rar3Decoder.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,301 @@ 1.4 +// Rar3Decoder.h 1.5 +// According to unRAR license, this code may not be used to develop 1.6 +// a program that creates RAR archives 1.7 + 1.8 +#ifndef __COMPRESS_RAR3_DECODER_H 1.9 +#define __COMPRESS_RAR3_DECODER_H 1.10 + 1.11 +#include "../../Common/MyCom.h" 1.12 + 1.13 +#include "../ICoder.h" 1.14 + 1.15 +#include "../Common/InBuffer.h" 1.16 + 1.17 +#include "BitmDecoder.h" 1.18 +#include "HuffmanDecoder.h" 1.19 +#include "PpmdDecode.h" 1.20 +#include "Rar3Vm.h" 1.21 + 1.22 +namespace NCompress { 1.23 +namespace NRar3 { 1.24 + 1.25 +const UInt32 kWindowSize = 1 << 22; 1.26 +const UInt32 kWindowMask = (kWindowSize - 1); 1.27 + 1.28 +const UInt32 kNumReps = 4; 1.29 +const UInt32 kNumLen2Symbols = 8; 1.30 +const UInt32 kLenTableSize = 28; 1.31 +const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize; 1.32 +const UInt32 kDistTableSize = 60; 1.33 + 1.34 +const int kNumAlignBits = 4; 1.35 +const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1; 1.36 + 1.37 +const UInt32 kLevelTableSize = 20; 1.38 + 1.39 +const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize; 1.40 + 1.41 +class CBitDecoder 1.42 +{ 1.43 + UInt32 m_Value; 1.44 +public: 1.45 + UInt32 m_BitPos; 1.46 + CInBuffer m_Stream; 1.47 + bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); } 1.48 + void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);} 1.49 + void ReleaseStream() { m_Stream.ReleaseStream();} 1.50 + 1.51 + void Init() 1.52 + { 1.53 + m_Stream.Init(); 1.54 + m_BitPos = 0; 1.55 + m_Value = 0; 1.56 + // m_BitPos = kNumBigValueBits; 1.57 + // Normalize(); 1.58 + } 1.59 + 1.60 + UInt64 GetProcessedSize() const 1.61 + { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; } 1.62 + UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); } 1.63 + 1.64 + /* 1.65 + void Normalize() 1.66 + { 1.67 + for (;m_BitPos >= 8; m_BitPos -= 8) 1.68 + m_Value = (m_Value << 8) | m_Stream.ReadByte(); 1.69 + } 1.70 + */ 1.71 + 1.72 + UInt32 GetValue(UInt32 numBits) 1.73 + { 1.74 + // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits); 1.75 + // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits); 1.76 + if (m_BitPos < numBits) 1.77 + { 1.78 + m_BitPos += 8; 1.79 + m_Value = (m_Value << 8) | m_Stream.ReadByte(); 1.80 + if (m_BitPos < numBits) 1.81 + { 1.82 + m_BitPos += 8; 1.83 + m_Value = (m_Value << 8) | m_Stream.ReadByte(); 1.84 + } 1.85 + } 1.86 + return m_Value >> (m_BitPos - numBits); 1.87 + } 1.88 + 1.89 + void MovePos(UInt32 numBits) 1.90 + { 1.91 + m_BitPos -= numBits; 1.92 + m_Value = m_Value & ((1 << m_BitPos) - 1); 1.93 + } 1.94 + 1.95 + UInt32 ReadBits(UInt32 numBits) 1.96 + { 1.97 + UInt32 res = GetValue(numBits); 1.98 + MovePos(numBits); 1.99 + return res; 1.100 + } 1.101 +}; 1.102 + 1.103 +const int kNumTopBits = 24; 1.104 +const UInt32 kTopValue = (1 << kNumTopBits); 1.105 +const UInt32 kBot = (1 << 15); 1.106 + 1.107 +class CRangeDecoder:public NPpmd::CRangeDecoderVirt, public CBitDecoder 1.108 +{ 1.109 +public: 1.110 + UInt32 Range; 1.111 + UInt32 Low; 1.112 + UInt32 Code; 1.113 + 1.114 + void Normalize() 1.115 + { 1.116 + while ((Low ^ (Low + Range)) < kTopValue || 1.117 + Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1)) 1.118 + { 1.119 + Code = (Code << 8) | m_Stream.ReadByte(); 1.120 + Range <<= 8; 1.121 + Low <<= 8; 1.122 + } 1.123 + } 1.124 + 1.125 + void InitRangeCoder() 1.126 + { 1.127 + Code = 0; 1.128 + Low = 0; 1.129 + Range = 0xFFFFFFFF; 1.130 + for(int i = 0; i < 4; i++) 1.131 + Code = (Code << 8) | ReadBits(8); 1.132 + } 1.133 + 1.134 + virtual UInt32 GetThreshold(UInt32 total) 1.135 + { 1.136 + return (Code - Low) / ( Range /= total); 1.137 + } 1.138 + 1.139 + virtual void Decode(UInt32 start, UInt32 size) 1.140 + { 1.141 + Low += start * Range; 1.142 + Range *= size; 1.143 + Normalize(); 1.144 + } 1.145 + 1.146 + virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits) 1.147 + { 1.148 + if (((Code - Low) / (Range >>= numTotalBits)) < size0) 1.149 + { 1.150 + Decode(0, size0); 1.151 + return 0; 1.152 + } 1.153 + else 1.154 + { 1.155 + Decode(size0, (1 << numTotalBits) - size0); 1.156 + return 1; 1.157 + } 1.158 + } 1.159 + 1.160 + // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); } 1.161 +}; 1.162 + 1.163 + 1.164 +struct CFilter: public NVm::CProgram 1.165 +{ 1.166 + CRecordVector<Byte> GlobalData; 1.167 + UInt32 BlockStart; 1.168 + UInt32 BlockSize; 1.169 + UInt32 ExecCount; 1.170 + CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {} 1.171 +}; 1.172 + 1.173 +struct CTempFilter: public NVm::CProgramInitState 1.174 +{ 1.175 + UInt32 BlockStart; 1.176 + UInt32 BlockSize; 1.177 + UInt32 ExecCount; 1.178 + bool NextWindow; 1.179 + 1.180 + UInt32 FilterIndex; 1.181 +}; 1.182 + 1.183 +const int kNumHuffmanBits = 15; 1.184 + 1.185 +class CDecoder: 1.186 + public ICompressCoder, 1.187 + public ICompressSetDecoderProperties2, 1.188 + public CMyUnknownImp 1.189 +{ 1.190 + CRangeDecoder m_InBitStream; 1.191 + Byte *_window; 1.192 + UInt32 _winPos; 1.193 + UInt32 _wrPtr; 1.194 + UInt64 _lzSize; 1.195 + UInt64 _unpackSize; 1.196 + UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written 1.197 + CMyComPtr<ISequentialOutStream> _outStream; 1.198 + NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder; 1.199 + NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder; 1.200 + NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder; 1.201 + NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder; 1.202 + NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder; 1.203 + 1.204 + UInt32 _reps[kNumReps]; 1.205 + UInt32 _lastLength; 1.206 + 1.207 + Byte m_LastLevels[kTablesSizesSum]; 1.208 + 1.209 + Byte *_vmData; 1.210 + Byte *_vmCode; 1.211 + NVm::CVm _vm; 1.212 + CRecordVector<CFilter *> _filters; 1.213 + CRecordVector<CTempFilter *> _tempFilters; 1.214 + UInt32 _lastFilter; 1.215 + 1.216 + bool m_IsSolid; 1.217 + 1.218 + bool _lzMode; 1.219 + 1.220 + UInt32 PrevAlignBits; 1.221 + UInt32 PrevAlignCount; 1.222 + 1.223 + bool TablesRead; 1.224 + 1.225 + NPpmd::CDecodeInfo _ppm; 1.226 + int PpmEscChar; 1.227 + 1.228 + HRESULT WriteDataToStream(const Byte *data, UInt32 size); 1.229 + HRESULT WriteData(const Byte *data, UInt32 size); 1.230 + HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr); 1.231 + void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef); 1.232 + HRESULT WriteBuf(); 1.233 + 1.234 + void InitFilters(); 1.235 + bool AddVmCode(UInt32 firstByte, UInt32 codeSize); 1.236 + bool ReadVmCodeLZ(); 1.237 + bool ReadVmCodePPM(); 1.238 + 1.239 + UInt32 ReadBits(int numBits); 1.240 + 1.241 + HRESULT InitPPM(); 1.242 + int DecodePpmSymbol(); 1.243 + HRESULT DecodePPM(Int32 num, bool &keepDecompressing); 1.244 + 1.245 + HRESULT ReadTables(bool &keepDecompressing); 1.246 + HRESULT ReadEndOfBlock(bool &keepDecompressing); 1.247 + HRESULT DecodeLZ(bool &keepDecompressing); 1.248 + HRESULT CodeReal(ICompressProgressInfo *progress); 1.249 +public: 1.250 + CDecoder(); 1.251 + ~CDecoder(); 1.252 + 1.253 + MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) 1.254 + 1.255 + void ReleaseStreams() 1.256 + { 1.257 + _outStream.Release(); 1.258 + m_InBitStream.ReleaseStream(); 1.259 + } 1.260 + 1.261 + STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, 1.262 + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); 1.263 + 1.264 + STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); 1.265 + 1.266 + void CopyBlock(UInt32 distance, UInt32 len) 1.267 + { 1.268 + _lzSize += len; 1.269 + UInt32 pos = (_winPos - distance - 1) & kWindowMask; 1.270 + Byte *window = _window; 1.271 + UInt32 winPos = _winPos; 1.272 + if (kWindowSize - winPos > len && kWindowSize - pos > len) 1.273 + { 1.274 + const Byte *src = window + pos; 1.275 + Byte *dest = window + winPos; 1.276 + _winPos += len; 1.277 + do 1.278 + *dest++ = *src++; 1.279 + while(--len != 0); 1.280 + return; 1.281 + } 1.282 + do 1.283 + { 1.284 + window[winPos] = window[pos]; 1.285 + winPos = (winPos + 1) & kWindowMask; 1.286 + pos = (pos + 1) & kWindowMask; 1.287 + } 1.288 + while(--len != 0); 1.289 + _winPos = winPos; 1.290 + } 1.291 + 1.292 + void PutByte(Byte b) 1.293 + { 1.294 + _window[_winPos] = b; 1.295 + _winPos = (_winPos + 1) & kWindowMask; 1.296 + _lzSize++; 1.297 + } 1.298 + 1.299 + 1.300 +}; 1.301 + 1.302 +}} 1.303 + 1.304 +#endif