⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shrinkdecoder.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// ShrinkDecoder.cpp#include "StdAfx.h"#include "ShrinkDecoder.h"#include "../../../Common/Alloc.h"#include "../../Common/InBuffer.h"#include "../../Common/OutBuffer.h"#include "../../Common/LSBFDecoder.h"namespace NCompress {namespace NShrink {static const UInt32 kBufferSize = (1 << 20);static const int kNumMinBits = 9;   STDMETHODIMP CDecoder ::CodeReal(ISequentialInStream *inStream,    ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,    ICompressProgressInfo *progress){  NStream::NLSBF::CBaseDecoder<CInBuffer> inBuffer;  COutBuffer outBuffer;  if (!inBuffer.Create(kBufferSize))    return E_OUTOFMEMORY;  inBuffer.SetStream(inStream);  inBuffer.Init();  if (!outBuffer.Create(kBufferSize))    return E_OUTOFMEMORY;  outBuffer.SetStream(outStream);  outBuffer.Init();  UInt64 prevPos = 0;  int numBits = kNumMinBits;  UInt32 head = 257;  bool needPrev = false;  _parents[256] = 0; // virus protection  _suffixes[256] = 0;  int i;  for (i = 0; i < 257; i++)    _isFree[i] = false;  for (; i < kNumItems; i++)    _isFree[i] = true;  UInt32 lastSymbol = 0;  while (true)  {    outBuffer.Flush();    UInt32 symbol = inBuffer.ReadBits(numBits);    if (inBuffer.ExtraBitsWereRead())      break;    if (_isFree[symbol])      return S_FALSE;    if (symbol == 256)    {      // fix it;      UInt32 symbol = inBuffer.ReadBits(numBits);      if (symbol == 1)      {        if (numBits < kNumMaxBits)          numBits++;      }      else if (symbol == 2)      {        /*         maybe need delete prev also ?        if (needPrev)          _isFree[head - 1] = true;        */        for (i = 257; i < kNumItems; i++)          _isParent[i] = false;        for (i = 257; i < kNumItems; i++)          if (!_isFree[i])            _isParent[_parents[i]] = true;        for (i = 257; i < kNumItems; i++)          if (!_isParent[i])            _isFree[i] = true;        head = 257;        while(head < ((UInt32)1 << numBits) && !_isFree[head])          head++;        if (head < ((UInt32)1 << numBits))        {          needPrev = true;          _isFree[head] = false;          _parents[head] = (UInt16)lastSymbol;          head++;        }      }      else         return S_FALSE;      continue;    }    UInt32 cur = symbol;    i = 0;    while (cur >= 256)    {      _stack[i++] = _suffixes[cur];      cur = _parents[cur];    }    _stack[i++] = (Byte)cur;    if (needPrev)    {      _suffixes[head - 1] = (Byte)cur;      if (symbol == head - 1)        _stack[0] = (Byte)cur;    }    while (i > 0)      outBuffer.WriteByte((_stack[--i]));    while(head < ((UInt32)1 << numBits) && !_isFree[head])      head++;    if (head < ((UInt32)1 << numBits))    {      needPrev = true;      _isFree[head] = false;      _parents[head] = (UInt16)symbol;      head++;    }    else      needPrev = false;    lastSymbol = symbol;    UInt64 nowPos = outBuffer.GetProcessedSize();    if (progress != NULL && nowPos - prevPos > (1 << 18))    {      prevPos = nowPos;      UInt64 packSize = inBuffer.GetProcessedSize();      RINOK(progress->SetRatioInfo(&packSize, &nowPos));    }  }  return outBuffer.Flush();}STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream,    ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,    ICompressProgressInfo *progress){  try { return CodeReal(inStream, outStream, inSize, outSize, progress); }  catch(const CInBufferException &e) { return e.ErrorCode; }  catch(const COutBufferException &e) { return e.ErrorCode; }  catch(...) { return S_FALSE; }}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -