5
#include "QuantumDecoder.h"
6
#include "../../../Common/Defs.h"
11
// const UInt32 kDictionarySizeMax = (1 << 21);
13
const int kLenIdNeedInit = -2;
17
m_Selector.Init(kNumSelectors);
18
for (unsigned int i = 0; i < kNumLitSelectors; i++)
19
m_Literals[i].Init(kNumLitSymbols);
20
unsigned int numItems = _numDictBits << 1;
21
m_PosSlot[0].Init(MyMin(numItems, kNumLen3PosSymbolsMax));
22
m_PosSlot[1].Init(MyMin(numItems, kNumLen4PosSymbolsMax));
23
m_PosSlot[2].Init(MyMin(numItems, kNumLen5PosSymbolsMax));
24
m_LenSlot.Init(kNumLenSymbols);
27
HRESULT CDecoder::CodeSpec(UInt32 curSize)
29
if (_remainLen == kLenIdNeedInit)
33
if (!_outWindowStream.Create(_dictionarySize))
37
if (!_rangeDecoder.Create(1 << 20))
45
while(_remainLen > 0 && curSize > 0)
48
Byte b = _outWindowStream.GetByte(_rep0);
49
_outWindowStream.PutByte(b);
55
if (_rangeDecoder.Stream.WasFinished())
58
unsigned int selector = m_Selector.Decode(&_rangeDecoder);
59
if (selector < kNumLitSelectors)
61
Byte b = (Byte)((selector << (8 - kNumLitSelectorBits)) + m_Literals[selector].Decode(&_rangeDecoder));
62
_outWindowStream.PutByte(b);
67
selector -= kNumLitSelectors;
68
unsigned int len = selector + kMatchMinLen;
71
unsigned int lenSlot = m_LenSlot.Decode(&_rangeDecoder);;
72
if (lenSlot >= kNumSimpleLenSlots)
75
int numDirectBits = (int)(lenSlot >> 2);
76
len += ((4 | (lenSlot & 3)) << numDirectBits) - 2;
77
if (numDirectBits < 6)
78
len += _rangeDecoder.Stream.ReadBits(numDirectBits);
83
UInt32 rep0 = m_PosSlot[selector].Decode(&_rangeDecoder);;
84
if (rep0 >= kNumSimplePosSlots)
86
int numDirectBits = (int)((rep0 >> 1) - 1);
87
rep0 = ((2 | (rep0 & 1)) << numDirectBits) + _rangeDecoder.Stream.ReadBits(numDirectBits);
89
unsigned int locLen = len;
91
locLen = (unsigned int)curSize;
92
if (!_outWindowStream.CopyBlock(rep0, locLen))
98
_remainLen = (int)len;
104
return _rangeDecoder.Stream.WasFinished() ? S_FALSE : S_OK;
107
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream,
108
ISequentialOutStream *outStream,
109
const UInt64 *, const UInt64 *outSize,
110
ICompressProgressInfo *progress)
114
UInt64 size = *outSize;
116
SetInStream(inStream);
117
_outWindowStream.SetStream(outStream);
118
SetOutStreamSize(outSize);
119
CDecoderFlusher flusher(this);
121
const UInt64 start = _outWindowStream.GetProcessedSize();
124
UInt32 curSize = 1 << 18;
125
UInt64 rem = size - (_outWindowStream.GetProcessedSize() - start);
127
curSize = (UInt32)rem;
130
RINOK(CodeSpec(curSize));
131
if (progress != NULL)
133
UInt64 inSize = _rangeDecoder.GetProcessedSize();
134
UInt64 nowPos64 = _outWindowStream.GetProcessedSize() - start;
135
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
138
flusher.NeedFlush = false;
142
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
143
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
144
ICompressProgressInfo *progress)
146
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
147
catch(const CInBufferException &e) { return e.ErrorCode; }
148
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
149
catch(...) { return S_FALSE; }
152
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
154
_rangeDecoder.SetStream(inStream);
158
STDMETHODIMP CDecoder::ReleaseInStream()
160
_rangeDecoder.ReleaseStream();
164
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
168
_remainLen = kLenIdNeedInit;
169
_outWindowStream.Init(_keepHistory);