mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-14 16:11:38 -06:00
4.27 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
31e7b924e8
commit
d66cf2fcf3
@@ -74,7 +74,7 @@ void CCoder::ReleaseStreams()
|
||||
m_InBitStream.ReleaseStream();
|
||||
}
|
||||
|
||||
void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
|
||||
bool CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
|
||||
Byte *levels, int numLevelItems)
|
||||
{
|
||||
int numCodedStructures = m_InBitStream.ReadBits(kNumBitsInByte) +
|
||||
@@ -92,32 +92,26 @@ void CCoder::ReadLevelItems(NImplode::NHuffman::CDecoder &decoder,
|
||||
levels[currentIndex++] = level;
|
||||
}
|
||||
if (currentIndex != numLevelItems)
|
||||
throw CException(CException::kData);
|
||||
try
|
||||
{
|
||||
decoder.SetCodeLengths(levels);
|
||||
}
|
||||
catch(const NImplode::NHuffman::CDecoderException &)
|
||||
{
|
||||
throw CException(CException::kData);
|
||||
}
|
||||
return false;
|
||||
return decoder.SetCodeLengths(levels);
|
||||
}
|
||||
|
||||
|
||||
void CCoder::ReadTables(void)
|
||||
bool CCoder::ReadTables(void)
|
||||
{
|
||||
if (m_LiteralsOn)
|
||||
{
|
||||
Byte literalLevels[kLiteralTableSize];
|
||||
ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize);
|
||||
if (!ReadLevelItems(m_LiteralDecoder, literalLevels, kLiteralTableSize))
|
||||
return false;
|
||||
}
|
||||
|
||||
Byte lengthLevels[kLengthTableSize];
|
||||
ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize);
|
||||
if (!ReadLevelItems(m_LengthDecoder, lengthLevels, kLengthTableSize))
|
||||
return false;
|
||||
|
||||
Byte distanceLevels[kDistanceTableSize];
|
||||
ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
|
||||
|
||||
return ReadLevelItems(m_DistanceDecoder, distanceLevels, kDistanceTableSize);
|
||||
}
|
||||
|
||||
class CCoderReleaser
|
||||
@@ -146,7 +140,8 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
m_InBitStream.Init();
|
||||
CCoderReleaser coderReleaser(this);
|
||||
|
||||
ReadTables();
|
||||
if (!ReadTables())
|
||||
return S_FALSE;
|
||||
|
||||
while(pos < unPackSize)
|
||||
{
|
||||
@@ -158,10 +153,13 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
if(m_InBitStream.ReadBits(1) == kMatchId) // match
|
||||
{
|
||||
UInt32 lowDistBits = m_InBitStream.ReadBits(m_NumDistanceLowDirectBits);
|
||||
UInt32 distance = (m_DistanceDecoder.DecodeSymbol(&m_InBitStream) <<
|
||||
m_NumDistanceLowDirectBits) + lowDistBits;
|
||||
|
||||
UInt32 distance = m_DistanceDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (distance >= kDistanceTableSize)
|
||||
return S_FALSE;
|
||||
distance = (distance << m_NumDistanceLowDirectBits) + lowDistBits;
|
||||
UInt32 lengthSymbol = m_LengthDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (lengthSymbol >= kLengthTableSize)
|
||||
return S_FALSE;
|
||||
UInt32 length = lengthSymbol + m_MinMatchLength;
|
||||
if (lengthSymbol == kLengthTableSize - 1) // special symbol = 63
|
||||
length += m_InBitStream.ReadBits(kNumAdditionalLengthBits);
|
||||
@@ -177,8 +175,16 @@ STDMETHODIMP CCoder::CodeReal(ISequentialInStream *inStream,
|
||||
}
|
||||
else
|
||||
{
|
||||
Byte b = Byte(m_LiteralsOn ? m_LiteralDecoder.DecodeSymbol(&m_InBitStream) :
|
||||
m_InBitStream.ReadBits(kNumBitsInByte));
|
||||
Byte b;
|
||||
if (m_LiteralsOn)
|
||||
{
|
||||
UInt32 temp = m_LiteralDecoder.DecodeSymbol(&m_InBitStream);
|
||||
if (temp >= kLiteralTableSize)
|
||||
return S_FALSE;
|
||||
b = (Byte)temp;
|
||||
}
|
||||
else
|
||||
b = (Byte)m_InBitStream.ReadBits(kNumBitsInByte);
|
||||
m_OutWindowStream.PutByte(b);
|
||||
pos++;
|
||||
}
|
||||
|
||||
@@ -32,9 +32,8 @@ class CCoder :
|
||||
int m_NumDistanceLowDirectBits;
|
||||
UInt32 m_MinMatchLength;
|
||||
|
||||
void ReadLevelItems(NImplode::NHuffman::CDecoder &table,
|
||||
Byte *levels, int numLevelItems);
|
||||
void ReadTables();
|
||||
bool ReadLevelItems(NImplode::NHuffman::CDecoder &table, Byte *levels, int numLevelItems);
|
||||
bool ReadTables();
|
||||
void DeCodeLevelTable(Byte *newLevels, int numLevels);
|
||||
public:
|
||||
CCoder();
|
||||
|
||||
@@ -19,7 +19,7 @@ CDecoder::~CDecoder()
|
||||
delete []m_Symbols;
|
||||
}
|
||||
|
||||
void CDecoder::SetCodeLengths(const Byte *codeLengths)
|
||||
bool CDecoder::SetCodeLengths(const Byte *codeLengths)
|
||||
{
|
||||
// int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
|
||||
int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
|
||||
@@ -44,7 +44,7 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths)
|
||||
{
|
||||
startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
|
||||
if (startPos > kMaxValue)
|
||||
throw CDecoderException();
|
||||
return false;
|
||||
m_Limitits[i] = startPos;
|
||||
m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
|
||||
tmpPositions[i] = m_Positions[i] + lenCounts[i];
|
||||
@@ -54,12 +54,13 @@ void CDecoder::SetCodeLengths(const Byte *codeLengths)
|
||||
// if _ZIP_MODE do not throw exception for trees containing only one node
|
||||
// #ifndef _ZIP_MODE
|
||||
if (startPos != kMaxValue)
|
||||
throw CDecoderException();
|
||||
return false;
|
||||
// #endif
|
||||
|
||||
for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
|
||||
if (codeLengths[symbolIndex] != 0)
|
||||
m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
|
||||
return true;
|
||||
}
|
||||
|
||||
UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
|
||||
@@ -76,12 +77,12 @@ UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
throw CDecoderException();
|
||||
return 0xFFFFFFFF;
|
||||
inStream->MovePos(numBits);
|
||||
UInt32 index = m_Positions[numBits] +
|
||||
((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
|
||||
if (index >= m_NumSymbols)
|
||||
throw CDecoderException(); // test it
|
||||
return 0xFFFFFFFF;
|
||||
return m_Symbols[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace NImplode {
|
||||
namespace NHuffman {
|
||||
|
||||
const int kNumBitsInLongestCode = 16;
|
||||
class CDecoderException{};
|
||||
|
||||
typedef NStream::NLSBF::CDecoder<CInBuffer> CInBit;
|
||||
|
||||
@@ -25,7 +24,7 @@ public:
|
||||
CDecoder(UInt32 numSymbols);
|
||||
~CDecoder();
|
||||
|
||||
void SetCodeLengths(const Byte *codeLengths);
|
||||
bool SetCodeLengths(const Byte *codeLengths);
|
||||
UInt32 DecodeSymbol(CInBit *inStream);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user