Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/ShrinkDecoder.cpp @ 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/ShrinkDecoder.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,148 @@ 1.4 +// ShrinkDecoder.cpp 1.5 + 1.6 +#include "StdAfx.h" 1.7 + 1.8 +extern "C" 1.9 +{ 1.10 +#include "../../../C/Alloc.h" 1.11 +} 1.12 + 1.13 +#include "../Common/InBuffer.h" 1.14 +#include "../Common/OutBuffer.h" 1.15 + 1.16 +#include "BitlDecoder.h" 1.17 +#include "ShrinkDecoder.h" 1.18 + 1.19 +namespace NCompress { 1.20 +namespace NShrink { 1.21 + 1.22 +static const UInt32 kBufferSize = (1 << 20); 1.23 +static const int kNumMinBits = 9; 1.24 + 1.25 +HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, 1.26 + const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) 1.27 +{ 1.28 + NBitl::CBaseDecoder<CInBuffer> inBuffer; 1.29 + COutBuffer outBuffer; 1.30 + 1.31 + if (!inBuffer.Create(kBufferSize)) 1.32 + return E_OUTOFMEMORY; 1.33 + inBuffer.SetStream(inStream); 1.34 + inBuffer.Init(); 1.35 + 1.36 + if (!outBuffer.Create(kBufferSize)) 1.37 + return E_OUTOFMEMORY; 1.38 + outBuffer.SetStream(outStream); 1.39 + outBuffer.Init(); 1.40 + 1.41 + UInt64 prevPos = 0; 1.42 + int numBits = kNumMinBits; 1.43 + UInt32 head = 257; 1.44 + bool needPrev = false; 1.45 + UInt32 lastSymbol = 0; 1.46 + 1.47 + int i; 1.48 + for (i = 0; i < kNumItems; i++) 1.49 + _parents[i] = 0; 1.50 + for (i = 0; i < kNumItems; i++) 1.51 + _suffixes[i] = 0; 1.52 + for (i = 0; i < 257; i++) 1.53 + _isFree[i] = false; 1.54 + for (; i < kNumItems; i++) 1.55 + _isFree[i] = true; 1.56 + 1.57 + for (;;) 1.58 + { 1.59 + UInt32 symbol = inBuffer.ReadBits(numBits); 1.60 + if (inBuffer.ExtraBitsWereRead()) 1.61 + break; 1.62 + if (_isFree[symbol]) 1.63 + return S_FALSE; 1.64 + if (symbol == 256) 1.65 + { 1.66 + UInt32 symbol = inBuffer.ReadBits(numBits); 1.67 + if (symbol == 1) 1.68 + { 1.69 + if (numBits < kNumMaxBits) 1.70 + numBits++; 1.71 + } 1.72 + else if (symbol == 2) 1.73 + { 1.74 + if (needPrev) 1.75 + _isFree[head - 1] = true; 1.76 + for (i = 257; i < kNumItems; i++) 1.77 + _isParent[i] = false; 1.78 + for (i = 257; i < kNumItems; i++) 1.79 + if (!_isFree[i]) 1.80 + _isParent[_parents[i]] = true; 1.81 + for (i = 257; i < kNumItems; i++) 1.82 + if (!_isParent[i]) 1.83 + _isFree[i] = true; 1.84 + head = 257; 1.85 + while (head < kNumItems && !_isFree[head]) 1.86 + head++; 1.87 + if (head < kNumItems) 1.88 + { 1.89 + needPrev = true; 1.90 + _isFree[head] = false; 1.91 + _parents[head] = (UInt16)lastSymbol; 1.92 + head++; 1.93 + } 1.94 + } 1.95 + else 1.96 + return S_FALSE; 1.97 + continue; 1.98 + } 1.99 + UInt32 cur = symbol; 1.100 + i = 0; 1.101 + int corectionIndex = -1; 1.102 + while (cur >= 256) 1.103 + { 1.104 + if (cur == head - 1) 1.105 + corectionIndex = i; 1.106 + _stack[i++] = _suffixes[cur]; 1.107 + cur = _parents[cur]; 1.108 + } 1.109 + _stack[i++] = (Byte)cur; 1.110 + if (needPrev) 1.111 + { 1.112 + _suffixes[head - 1] = (Byte)cur; 1.113 + if (corectionIndex >= 0) 1.114 + _stack[corectionIndex] = (Byte)cur; 1.115 + } 1.116 + while (i > 0) 1.117 + outBuffer.WriteByte((_stack[--i])); 1.118 + while (head < kNumItems && !_isFree[head]) 1.119 + head++; 1.120 + if (head < kNumItems) 1.121 + { 1.122 + needPrev = true; 1.123 + _isFree[head] = false; 1.124 + _parents[head] = (UInt16)symbol; 1.125 + head++; 1.126 + } 1.127 + else 1.128 + needPrev = false; 1.129 + lastSymbol = symbol; 1.130 + 1.131 + UInt64 nowPos = outBuffer.GetProcessedSize(); 1.132 + if (progress != NULL && nowPos - prevPos > (1 << 18)) 1.133 + { 1.134 + prevPos = nowPos; 1.135 + UInt64 packSize = inBuffer.GetProcessedSize(); 1.136 + RINOK(progress->SetRatioInfo(&packSize, &nowPos)); 1.137 + } 1.138 + } 1.139 + return outBuffer.Flush(); 1.140 +} 1.141 + 1.142 +STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, 1.143 + const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) 1.144 +{ 1.145 + try { return CodeReal(inStream, outStream, inSize, outSize, progress); } 1.146 + catch(const CInBufferException &e) { return e.ErrorCode; } 1.147 + catch(const COutBufferException &e) { return e.ErrorCode; } 1.148 + catch(...) { return S_FALSE; } 1.149 +} 1.150 + 1.151 +}}