Mercurial > vba-linux
view 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 source
1 // Rar3Decoder.h2 // According to unRAR license, this code may not be used to develop3 // a program that creates RAR archives5 #ifndef __COMPRESS_RAR3_DECODER_H6 #define __COMPRESS_RAR3_DECODER_H8 #include "../../Common/MyCom.h"10 #include "../ICoder.h"12 #include "../Common/InBuffer.h"14 #include "BitmDecoder.h"15 #include "HuffmanDecoder.h"16 #include "PpmdDecode.h"17 #include "Rar3Vm.h"19 namespace NCompress {20 namespace NRar3 {22 const UInt32 kWindowSize = 1 << 22;23 const UInt32 kWindowMask = (kWindowSize - 1);25 const UInt32 kNumReps = 4;26 const UInt32 kNumLen2Symbols = 8;27 const UInt32 kLenTableSize = 28;28 const UInt32 kMainTableSize = 256 + 1 + 1 + 1 + kNumReps + kNumLen2Symbols + kLenTableSize;29 const UInt32 kDistTableSize = 60;31 const int kNumAlignBits = 4;32 const UInt32 kAlignTableSize = (1 << kNumAlignBits) + 1;34 const UInt32 kLevelTableSize = 20;36 const UInt32 kTablesSizesSum = kMainTableSize + kDistTableSize + kAlignTableSize + kLenTableSize;38 class CBitDecoder39 {40 UInt32 m_Value;41 public:42 UInt32 m_BitPos;43 CInBuffer m_Stream;44 bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }45 void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream);}46 void ReleaseStream() { m_Stream.ReleaseStream();}48 void Init()49 {50 m_Stream.Init();51 m_BitPos = 0;52 m_Value = 0;53 // m_BitPos = kNumBigValueBits;54 // Normalize();55 }57 UInt64 GetProcessedSize() const58 { return m_Stream.GetProcessedSize() - (m_BitPos) / 8; }59 UInt32 GetBitPosition() const { return ((8 - m_BitPos) & 7); }61 /*62 void Normalize()63 {64 for (;m_BitPos >= 8; m_BitPos -= 8)65 m_Value = (m_Value << 8) | m_Stream.ReadByte();66 }67 */69 UInt32 GetValue(UInt32 numBits)70 {71 // return (m_Value << m_BitPos) >> (kNumBigValueBits - numBits);72 // return ((m_Value >> (8 - m_BitPos)) & kMask) >> (kNumValueBits - numBits);73 if (m_BitPos < numBits)74 {75 m_BitPos += 8;76 m_Value = (m_Value << 8) | m_Stream.ReadByte();77 if (m_BitPos < numBits)78 {79 m_BitPos += 8;80 m_Value = (m_Value << 8) | m_Stream.ReadByte();81 }82 }83 return m_Value >> (m_BitPos - numBits);84 }86 void MovePos(UInt32 numBits)87 {88 m_BitPos -= numBits;89 m_Value = m_Value & ((1 << m_BitPos) - 1);90 }92 UInt32 ReadBits(UInt32 numBits)93 {94 UInt32 res = GetValue(numBits);95 MovePos(numBits);96 return res;97 }98 };100 const int kNumTopBits = 24;101 const UInt32 kTopValue = (1 << kNumTopBits);102 const UInt32 kBot = (1 << 15);104 class CRangeDecoder:public NPpmd::CRangeDecoderVirt, public CBitDecoder105 {106 public:107 UInt32 Range;108 UInt32 Low;109 UInt32 Code;111 void Normalize()112 {113 while ((Low ^ (Low + Range)) < kTopValue ||114 Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1))115 {116 Code = (Code << 8) | m_Stream.ReadByte();117 Range <<= 8;118 Low <<= 8;119 }120 }122 void InitRangeCoder()123 {124 Code = 0;125 Low = 0;126 Range = 0xFFFFFFFF;127 for(int i = 0; i < 4; i++)128 Code = (Code << 8) | ReadBits(8);129 }131 virtual UInt32 GetThreshold(UInt32 total)132 {133 return (Code - Low) / ( Range /= total);134 }136 virtual void Decode(UInt32 start, UInt32 size)137 {138 Low += start * Range;139 Range *= size;140 Normalize();141 }143 virtual UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)144 {145 if (((Code - Low) / (Range >>= numTotalBits)) < size0)146 {147 Decode(0, size0);148 return 0;149 }150 else151 {152 Decode(size0, (1 << numTotalBits) - size0);153 return 1;154 }155 }157 // UInt64 GetProcessedSizeRangeCoder() {return Stream.GetProcessedSize(); }158 };161 struct CFilter: public NVm::CProgram162 {163 CRecordVector<Byte> GlobalData;164 UInt32 BlockStart;165 UInt32 BlockSize;166 UInt32 ExecCount;167 CFilter(): BlockStart(0), BlockSize(0), ExecCount(0) {}168 };170 struct CTempFilter: public NVm::CProgramInitState171 {172 UInt32 BlockStart;173 UInt32 BlockSize;174 UInt32 ExecCount;175 bool NextWindow;177 UInt32 FilterIndex;178 };180 const int kNumHuffmanBits = 15;182 class CDecoder:183 public ICompressCoder,184 public ICompressSetDecoderProperties2,185 public CMyUnknownImp186 {187 CRangeDecoder m_InBitStream;188 Byte *_window;189 UInt32 _winPos;190 UInt32 _wrPtr;191 UInt64 _lzSize;192 UInt64 _unpackSize;193 UInt64 _writtenFileSize; // if it's > _unpackSize, then _unpackSize only written194 CMyComPtr<ISequentialOutStream> _outStream;195 NHuffman::CDecoder<kNumHuffmanBits, kMainTableSize> m_MainDecoder;196 NHuffman::CDecoder<kNumHuffmanBits, kDistTableSize> m_DistDecoder;197 NHuffman::CDecoder<kNumHuffmanBits, kAlignTableSize> m_AlignDecoder;198 NHuffman::CDecoder<kNumHuffmanBits, kLenTableSize> m_LenDecoder;199 NHuffman::CDecoder<kNumHuffmanBits, kLevelTableSize> m_LevelDecoder;201 UInt32 _reps[kNumReps];202 UInt32 _lastLength;204 Byte m_LastLevels[kTablesSizesSum];206 Byte *_vmData;207 Byte *_vmCode;208 NVm::CVm _vm;209 CRecordVector<CFilter *> _filters;210 CRecordVector<CTempFilter *> _tempFilters;211 UInt32 _lastFilter;213 bool m_IsSolid;215 bool _lzMode;217 UInt32 PrevAlignBits;218 UInt32 PrevAlignCount;220 bool TablesRead;222 NPpmd::CDecodeInfo _ppm;223 int PpmEscChar;225 HRESULT WriteDataToStream(const Byte *data, UInt32 size);226 HRESULT WriteData(const Byte *data, UInt32 size);227 HRESULT WriteArea(UInt32 startPtr, UInt32 endPtr);228 void ExecuteFilter(int tempFilterIndex, NVm::CBlockRef &outBlockRef);229 HRESULT WriteBuf();231 void InitFilters();232 bool AddVmCode(UInt32 firstByte, UInt32 codeSize);233 bool ReadVmCodeLZ();234 bool ReadVmCodePPM();236 UInt32 ReadBits(int numBits);238 HRESULT InitPPM();239 int DecodePpmSymbol();240 HRESULT DecodePPM(Int32 num, bool &keepDecompressing);242 HRESULT ReadTables(bool &keepDecompressing);243 HRESULT ReadEndOfBlock(bool &keepDecompressing);244 HRESULT DecodeLZ(bool &keepDecompressing);245 HRESULT CodeReal(ICompressProgressInfo *progress);246 public:247 CDecoder();248 ~CDecoder();250 MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2)252 void ReleaseStreams()253 {254 _outStream.Release();255 m_InBitStream.ReleaseStream();256 }258 STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,259 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);261 STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);263 void CopyBlock(UInt32 distance, UInt32 len)264 {265 _lzSize += len;266 UInt32 pos = (_winPos - distance - 1) & kWindowMask;267 Byte *window = _window;268 UInt32 winPos = _winPos;269 if (kWindowSize - winPos > len && kWindowSize - pos > len)270 {271 const Byte *src = window + pos;272 Byte *dest = window + winPos;273 _winPos += len;274 do275 *dest++ = *src++;276 while(--len != 0);277 return;278 }279 do280 {281 window[winPos] = window[pos];282 winPos = (winPos + 1) & kWindowMask;283 pos = (pos + 1) & kWindowMask;284 }285 while(--len != 0);286 _winPos = winPos;287 }289 void PutByte(Byte b)290 {291 _window[_winPos] = b;292 _winPos = (_winPos + 1) & kWindowMask;293 _lzSize++;294 }297 };299 }}301 #endif