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