mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 04:11:37 -06:00
4.20
This commit is contained in:
committed by
Kornel Lesiński
parent
8c1b5c7b7e
commit
3c510ba80b
@@ -4,353 +4,353 @@
|
||||
|
||||
#include "LZMADecoder.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
#include "../../../Common/ComTry.h"
|
||||
|
||||
/*
|
||||
#include "fstream.h"
|
||||
#include "iomanip.h"
|
||||
|
||||
ofstream ofs("res.dat");
|
||||
|
||||
const int kNumCounters = 3;
|
||||
UINT32 g_Counter[kNumCounters];
|
||||
class C1
|
||||
{
|
||||
public:
|
||||
~C1()
|
||||
{
|
||||
for (int i = 0; i < kNumCounters; i++)
|
||||
ofs << setw(10) << g_Counter[i] << endl;
|
||||
}
|
||||
} g_C1;
|
||||
*/
|
||||
|
||||
/*
|
||||
const UINT32 kLenTableMax = 20;
|
||||
const UINT32 kNumDists = NCompress::NLZMA::kDistTableSizeMax / 2;
|
||||
UINT32 g_Counts[kLenTableMax][kNumDists];
|
||||
class C1
|
||||
{
|
||||
public:
|
||||
~C1 ()
|
||||
{
|
||||
UINT32 sums[kLenTableMax];
|
||||
for (int len = 2; len < kLenTableMax; len++)
|
||||
{
|
||||
sums[len] = 0;
|
||||
for (int dist = 0; dist < kNumDists; dist++)
|
||||
sums[len] += g_Counts[len][dist];
|
||||
if (sums[len] == 0)
|
||||
sums[len] = 1;
|
||||
}
|
||||
for (int dist = 0; dist < kNumDists; dist++)
|
||||
{
|
||||
ofs << setw(4) << dist << " ";
|
||||
for (int len = 2; len < kLenTableMax; len++)
|
||||
{
|
||||
ofs << setw(4) << g_Counts[len][dist] * 1000 / sums[len];
|
||||
}
|
||||
ofs << endl;
|
||||
}
|
||||
}
|
||||
} g_Class;
|
||||
|
||||
void UpdateStat(UINT32 len, UINT32 dist)
|
||||
{
|
||||
if (len >= kLenTableMax)
|
||||
len = kLenTableMax - 1;
|
||||
g_Counts[len][dist / 2]++;
|
||||
}
|
||||
*/
|
||||
|
||||
namespace NCompress {
|
||||
namespace NLZMA {
|
||||
|
||||
HRESULT CDecoder::SetDictionarySize(UINT32 dictionarySize)
|
||||
void CDecoder::Init()
|
||||
{
|
||||
if (_dictionarySize != dictionarySize)
|
||||
{
|
||||
_dictionarySize = dictionarySize;
|
||||
_dictionarySizeCheck = MyMax(_dictionarySize, UINT32(1));
|
||||
UINT32 blockSize = MyMax(_dictionarySizeCheck, UINT32(1 << 12));
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < kNumStates; i++)
|
||||
{
|
||||
_outWindowStream.Create(blockSize /*, kMatchMaxLen */);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetLiteralProperties(
|
||||
UINT32 numLiteralPosStateBits, UINT32 numLiteralContextBits)
|
||||
{
|
||||
if (numLiteralPosStateBits > 8)
|
||||
return E_INVALIDARG;
|
||||
if (numLiteralContextBits > 8)
|
||||
return E_INVALIDARG;
|
||||
_literalDecoder.Create(numLiteralPosStateBits, numLiteralContextBits);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::SetPosBitsProperties(UINT32 numPosStateBits)
|
||||
{
|
||||
if (numPosStateBits > NLength::kNumPosStatesBitsMax)
|
||||
return E_INVALIDARG;
|
||||
UINT32 numPosStates = 1 << numPosStateBits;
|
||||
_lenDecoder.Create(numPosStates);
|
||||
_repMatchLenDecoder.Create(numPosStates);
|
||||
_posStateMask = numPosStates - 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
CDecoder::CDecoder():
|
||||
_dictionarySize((UINT32)-1)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
HRESULT CDecoder::Create()
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
for(int i = 0; i < kNumPosModels; i++)
|
||||
_posDecoders[i].Create(((kStartPosModelIndex + i) >> 1) - 1);
|
||||
COM_TRY_END
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CDecoder::Init(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream)
|
||||
{
|
||||
_rangeDecoder.Init(inStream);
|
||||
|
||||
_outWindowStream.Init(outStream);
|
||||
|
||||
int i;
|
||||
for(i = 0; i < kNumStates; i++)
|
||||
{
|
||||
for (UINT32 j = 0; j <= _posStateMask; j++)
|
||||
{
|
||||
_mainChoiceDecoders[i][j].Init();
|
||||
_matchRepShortChoiceDecoders[i][j].Init();
|
||||
}
|
||||
_matchChoiceDecoders[i].Init();
|
||||
_matchRepChoiceDecoders[i].Init();
|
||||
_matchRep1ChoiceDecoders[i].Init();
|
||||
_matchRep2ChoiceDecoders[i].Init();
|
||||
}
|
||||
|
||||
_literalDecoder.Init();
|
||||
|
||||
// _repMatchLenDecoder.Init();
|
||||
|
||||
for (i = 0; i < kNumLenToPosStates; i++)
|
||||
_posSlotDecoder[i].Init();
|
||||
|
||||
for(i = 0; i < kNumPosModels; i++)
|
||||
_posDecoders[i].Init();
|
||||
|
||||
_lenDecoder.Init();
|
||||
_repMatchLenDecoder.Init();
|
||||
|
||||
_posAlignDecoder.Init();
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UINT64 *inSize, const UINT64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
/*
|
||||
if (outSize == NULL)
|
||||
return E_INVALIDARG;
|
||||
*/
|
||||
|
||||
Init(inStream, outStream);
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
CState state;
|
||||
state.Init();
|
||||
bool peviousIsMatch = false;
|
||||
BYTE previousByte = 0;
|
||||
UINT32 repDistances[kNumRepDistances];
|
||||
for(int i = 0 ; i < kNumRepDistances; i++)
|
||||
repDistances[i] = 0;
|
||||
|
||||
UINT64 nowPos64 = 0;
|
||||
UINT64 size = (outSize == NULL) ? (UINT64)(INT64)(-1) : *outSize;
|
||||
while(nowPos64 < size)
|
||||
{
|
||||
UINT64 nextPos = MyMin(nowPos64 + (1 << 18), size);
|
||||
while(nowPos64 < nextPos)
|
||||
{
|
||||
UINT32 posState = UINT32(nowPos64) & _posStateMask;
|
||||
if (_mainChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == kMainChoiceLiteralIndex)
|
||||
for (UInt32 j = 0; j <= _posStateMask; j++)
|
||||
{
|
||||
state.UpdateChar();
|
||||
if(peviousIsMatch)
|
||||
{
|
||||
BYTE matchByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
|
||||
_isMatch[i][j].Init();
|
||||
_isRep0Long[i][j].Init();
|
||||
}
|
||||
_isRep[i].Init();
|
||||
_isRepG0[i].Init();
|
||||
_isRepG1[i].Init();
|
||||
_isRepG2[i].Init();
|
||||
}
|
||||
}
|
||||
{
|
||||
for (UInt32 i = 0; i < kNumLenToPosStates; i++)
|
||||
_posSlotDecoder[i].Init();
|
||||
}
|
||||
{
|
||||
for(UInt32 i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
|
||||
_posDecoders[i].Init();
|
||||
}
|
||||
_posAlignDecoder.Init();
|
||||
_lenDecoder.Init(_posStateMask + 1);
|
||||
_repMatchLenDecoder.Init(_posStateMask + 1);
|
||||
_literalDecoder.Init();
|
||||
|
||||
_state.Init();
|
||||
_reps[0] = _reps[1] = _reps[2] = _reps[3] = 0;
|
||||
}
|
||||
|
||||
HRESULT CDecoder::CodeSpec(Byte *buffer, UInt32 curSize)
|
||||
{
|
||||
if (_remainLen == -1)
|
||||
return S_OK;
|
||||
if (_remainLen == -2)
|
||||
{
|
||||
_rangeDecoder.Init();
|
||||
Init();
|
||||
_remainLen = 0;
|
||||
}
|
||||
if (curSize == 0)
|
||||
return S_OK;
|
||||
|
||||
UInt64 nowPos64 = _nowPos64;
|
||||
|
||||
UInt32 rep0 = _reps[0];
|
||||
UInt32 rep1 = _reps[1];
|
||||
UInt32 rep2 = _reps[2];
|
||||
UInt32 rep3 = _reps[3];
|
||||
CState state = _state;
|
||||
Byte previousByte;
|
||||
|
||||
while(_remainLen > 0 && curSize > 0)
|
||||
{
|
||||
previousByte = _outWindowStream.GetByte(rep0);
|
||||
_outWindowStream.PutByte(previousByte);
|
||||
if (buffer)
|
||||
*buffer++ = previousByte;
|
||||
nowPos64++;
|
||||
_remainLen--;
|
||||
curSize--;
|
||||
}
|
||||
if (nowPos64 == 0)
|
||||
previousByte = 0;
|
||||
else
|
||||
previousByte = _outWindowStream.GetByte(0);
|
||||
|
||||
while(curSize > 0)
|
||||
{
|
||||
{
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (_rangeDecoder.Stream.ErrorCode != S_OK)
|
||||
return _rangeDecoder.Stream.ErrorCode;
|
||||
#endif
|
||||
if (_rangeDecoder.Stream.WasFinished())
|
||||
return S_FALSE;
|
||||
UInt32 posState = UInt32(nowPos64) & _posStateMask;
|
||||
if (_isMatch[state.Index][posState].Decode(&_rangeDecoder) == 0)
|
||||
{
|
||||
if(!state.IsCharState())
|
||||
previousByte = _literalDecoder.DecodeWithMatchByte(&_rangeDecoder,
|
||||
UINT32(nowPos64), previousByte, matchByte);
|
||||
peviousIsMatch = false;
|
||||
}
|
||||
(UInt32)nowPos64, previousByte, _outWindowStream.GetByte(rep0));
|
||||
else
|
||||
previousByte = _literalDecoder.DecodeNormal(&_rangeDecoder,
|
||||
UINT32(nowPos64), previousByte);
|
||||
_outWindowStream.PutOneByte(previousByte);
|
||||
(UInt32)nowPos64, previousByte);
|
||||
_outWindowStream.PutByte(previousByte);
|
||||
if (buffer)
|
||||
*buffer++ = previousByte;
|
||||
state.UpdateChar();
|
||||
curSize--;
|
||||
nowPos64++;
|
||||
}
|
||||
else
|
||||
{
|
||||
peviousIsMatch = true;
|
||||
UINT32 distance, len;
|
||||
if(_matchChoiceDecoders[state.Index].Decode(&_rangeDecoder) ==
|
||||
kMatchChoiceRepetitionIndex)
|
||||
UInt32 len;
|
||||
if(_isRep[state.Index].Decode(&_rangeDecoder) == 1)
|
||||
{
|
||||
if(_matchRepChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
if(_isRepG0[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
{
|
||||
if(_matchRepShortChoiceDecoders[state.Index][posState].Decode(&_rangeDecoder) == 0)
|
||||
if(_isRep0Long[state.Index][posState].Decode(&_rangeDecoder) == 0)
|
||||
{
|
||||
if (nowPos64 == 0)
|
||||
return S_FALSE;
|
||||
state.UpdateShortRep();
|
||||
previousByte = _outWindowStream.GetOneByte(0 - repDistances[0] - 1);
|
||||
_outWindowStream.PutOneByte(previousByte);
|
||||
previousByte = _outWindowStream.GetByte(rep0);
|
||||
_outWindowStream.PutByte(previousByte);
|
||||
if (buffer)
|
||||
*buffer++ = previousByte;
|
||||
curSize--;
|
||||
nowPos64++;
|
||||
continue;
|
||||
}
|
||||
distance = repDistances[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_matchRep1ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = repDistances[1];
|
||||
UInt32 distance;
|
||||
if(_isRepG1[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = rep1;
|
||||
else
|
||||
{
|
||||
if (_matchRep2ChoiceDecoders[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = repDistances[2];
|
||||
if (_isRepG2[state.Index].Decode(&_rangeDecoder) == 0)
|
||||
distance = rep2;
|
||||
else
|
||||
{
|
||||
distance = repDistances[3];
|
||||
repDistances[3] = repDistances[2];
|
||||
distance = rep3;
|
||||
rep3 = rep2;
|
||||
}
|
||||
repDistances[2] = repDistances[1];
|
||||
rep2 = rep1;
|
||||
}
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
rep1 = rep0;
|
||||
rep0 = distance;
|
||||
}
|
||||
len = _repMatchLenDecoder.Decode(&_rangeDecoder, posState) + kMatchMinLen;
|
||||
state.UpdateRep();
|
||||
}
|
||||
else
|
||||
{
|
||||
rep3 = rep2;
|
||||
rep2 = rep1;
|
||||
rep1 = rep0;
|
||||
len = kMatchMinLen + _lenDecoder.Decode(&_rangeDecoder, posState);
|
||||
state.UpdateMatch();
|
||||
UINT32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
|
||||
UInt32 posSlot = _posSlotDecoder[GetLenToPosState(len)].Decode(&_rangeDecoder);
|
||||
if (posSlot >= kStartPosModelIndex)
|
||||
{
|
||||
UINT32 numDirectBits = (posSlot >> 1) - 1;
|
||||
distance = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
UInt32 numDirectBits = (posSlot >> 1) - 1;
|
||||
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
||||
|
||||
if (posSlot < kEndPosModelIndex)
|
||||
distance += _posDecoders[posSlot - kStartPosModelIndex].Decode(&_rangeDecoder);
|
||||
rep0 += NRangeCoder::ReverseBitTreeDecode(_posDecoders +
|
||||
rep0 - posSlot - 1, &_rangeDecoder, numDirectBits);
|
||||
else
|
||||
{
|
||||
distance += (_rangeDecoder.DecodeDirectBits(
|
||||
rep0 += (_rangeDecoder.DecodeDirectBits(
|
||||
numDirectBits - kNumAlignBits) << kNumAlignBits);
|
||||
distance += _posAlignDecoder.Decode(&_rangeDecoder);
|
||||
rep0 += _posAlignDecoder.ReverseDecode(&_rangeDecoder);
|
||||
}
|
||||
}
|
||||
else
|
||||
distance = posSlot;
|
||||
|
||||
repDistances[3] = repDistances[2];
|
||||
repDistances[2] = repDistances[1];
|
||||
repDistances[1] = repDistances[0];
|
||||
repDistances[0] = distance;
|
||||
// UpdateStat(len, posSlot);
|
||||
}
|
||||
if (distance >= nowPos64 || distance >= _dictionarySizeCheck)
|
||||
{
|
||||
if (distance == (UINT32)(-1) && size == (UINT64)(INT64)(-1))
|
||||
rep0 = posSlot;
|
||||
if (rep0 >= nowPos64 || rep0 >= _dictionarySizeCheck)
|
||||
{
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
if (rep0 != (UInt32)(Int32)(-1))
|
||||
return S_FALSE;
|
||||
_nowPos64 = nowPos64;
|
||||
_remainLen = -1;
|
||||
return S_OK;
|
||||
}
|
||||
throw "data error";
|
||||
}
|
||||
_outWindowStream.CopyBackBlock(distance, len);
|
||||
nowPos64 += len;
|
||||
previousByte = _outWindowStream.GetOneByte(0 - 1);
|
||||
UInt32 locLen = len;
|
||||
if (len > curSize)
|
||||
locLen = (UInt32)curSize;
|
||||
if (buffer)
|
||||
{
|
||||
for (UInt32 i = locLen; i != 0; i--)
|
||||
{
|
||||
previousByte = _outWindowStream.GetByte(rep0);
|
||||
*buffer++ = previousByte;
|
||||
_outWindowStream.PutByte(previousByte);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_outWindowStream.CopyBlock(rep0, locLen);
|
||||
previousByte = _outWindowStream.GetByte(0);
|
||||
}
|
||||
curSize -= locLen;
|
||||
nowPos64 += locLen;
|
||||
len -= locLen;
|
||||
if (len != 0)
|
||||
{
|
||||
_remainLen = (Int32)len;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _NO_EXCEPTIONS
|
||||
if (_outWindowStream.ErrorCode != S_OK)
|
||||
return _outWindowStream.ErrorCode;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_rangeDecoder.Stream.WasFinished())
|
||||
return S_FALSE;
|
||||
_nowPos64 = nowPos64;
|
||||
_reps[0] = rep0;
|
||||
_reps[1] = rep1;
|
||||
_reps[2] = rep2;
|
||||
_reps[3] = rep3;
|
||||
_state = state;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::CodeReal(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream,
|
||||
const UInt64 *, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
SetInStream(inStream);
|
||||
_outWindowStream.SetStream(outStream);
|
||||
SetOutStreamSize(outSize);
|
||||
CDecoderFlusher flusher(this);
|
||||
|
||||
while (true)
|
||||
{
|
||||
UInt32 curSize = 1 << 18;
|
||||
if (_outSize != (UInt64)(Int64)(-1))
|
||||
if (curSize > _outSize - _nowPos64)
|
||||
curSize = (UInt32)(_outSize - _nowPos64);
|
||||
RINOK(CodeSpec(0, curSize));
|
||||
if (_remainLen == -1)
|
||||
break;
|
||||
if (progress != NULL)
|
||||
{
|
||||
UINT64 inSize = _rangeDecoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &nowPos64));
|
||||
UInt64 inSize = _rangeDecoder.GetProcessedSize();
|
||||
RINOK(progress->SetRatioInfo(&inSize, &_nowPos64));
|
||||
}
|
||||
}
|
||||
if (_outSize != (UInt64)(Int64)(-1))
|
||||
if (_nowPos64 >= _outSize)
|
||||
break;
|
||||
}
|
||||
flusher.NeedFlush = false;
|
||||
return Flush();
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,
|
||||
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
|
||||
ISequentialOutStream *outStream, const UInt64 *inSize, const UInt64 *outSize,
|
||||
ICompressProgressInfo *progress)
|
||||
{
|
||||
try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
return CodeReal(inStream, outStream, inSize, outSize, progress);
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static HRESULT DecodeProperties(ISequentialInStream *inStream,
|
||||
UINT32 &numPosStateBits,
|
||||
UINT32 &numLiteralPosStateBits,
|
||||
UINT32 &numLiteralContextBits,
|
||||
UINT32 &dictionarySize)
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *properties, UInt32 size)
|
||||
{
|
||||
UINT32 processesedSize;
|
||||
|
||||
BYTE firstByte;
|
||||
RINOK(inStream->Read(&firstByte, sizeof(firstByte), &processesedSize));
|
||||
if (processesedSize != sizeof(firstByte))
|
||||
if (size < 5)
|
||||
return E_INVALIDARG;
|
||||
|
||||
numLiteralContextBits = firstByte % 9;
|
||||
BYTE remainder = firstByte / 9;
|
||||
numLiteralPosStateBits = remainder % 5;
|
||||
numPosStateBits = remainder / 5;
|
||||
|
||||
RINOK(inStream->Read(&dictionarySize, sizeof(dictionarySize), &processesedSize));
|
||||
if (processesedSize != sizeof(dictionarySize))
|
||||
int lc = properties[0] % 9;
|
||||
Byte remainder = (Byte)(properties[0] / 9);
|
||||
int lp = remainder % 5;
|
||||
int pb = remainder / 5;
|
||||
if (pb > NLength::kNumPosStatesBitsMax)
|
||||
return E_INVALIDARG;
|
||||
_posStateMask = (1 << pb) - 1;
|
||||
UInt32 dictionarySize = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8);
|
||||
_dictionarySizeCheck = MyMax(dictionarySize, UInt32(1));
|
||||
UInt32 blockSize = MyMax(_dictionarySizeCheck, UInt32(1 << 12));
|
||||
if (!_outWindowStream.Create(blockSize))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_literalDecoder.Create(lp, lc))
|
||||
return E_OUTOFMEMORY;
|
||||
if (!_rangeDecoder.Create(1 << 20))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetDecoderProperties(ISequentialInStream *inStream)
|
||||
STDMETHODIMP CDecoder::GetInStreamProcessedSize(UInt64 *value)
|
||||
{
|
||||
UINT32 numPosStateBits;
|
||||
UINT32 numLiteralPosStateBits;
|
||||
UINT32 numLiteralContextBits;
|
||||
UINT32 dictionarySize;
|
||||
RINOK(DecodeProperties(inStream,
|
||||
numPosStateBits,
|
||||
numLiteralPosStateBits,
|
||||
numLiteralContextBits,
|
||||
dictionarySize));
|
||||
RINOK(SetDictionarySize(dictionarySize));
|
||||
RINOK(SetLiteralProperties(numLiteralPosStateBits, numLiteralContextBits));
|
||||
RINOK(SetPosBitsProperties(numPosStateBits));
|
||||
*value = _rangeDecoder.GetProcessedSize();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetInStream(ISequentialInStream *inStream)
|
||||
{
|
||||
_rangeDecoder.SetStream(inStream);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::ReleaseInStream()
|
||||
{
|
||||
_rangeDecoder.ReleaseStream();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
|
||||
{
|
||||
_outSize = (outSize == NULL) ? (UInt64)(Int64)(-1) : *outSize;
|
||||
_nowPos64 = 0;
|
||||
_remainLen = -2; // -2 means need_init
|
||||
_outWindowStream.Init();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
UInt64 startPos = _nowPos64;
|
||||
if (_outSize != (UInt64)(Int64)(-1))
|
||||
if (size > _outSize - _nowPos64)
|
||||
size = (UInt32)(_outSize - _nowPos64);
|
||||
HRESULT res = CodeSpec((Byte *)data, size);
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)(_nowPos64 - startPos);
|
||||
return res;
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(const CLZOutWindowException &e) { return e.ErrorCode; }
|
||||
catch(...) { return S_FALSE; }
|
||||
#endif
|
||||
}
|
||||
|
||||
STDMETHODIMP CDecoder::ReadPart(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
return Read(data, size, processedSize);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user