speed up DEFLATE decompression
parent
c2f6c37e6d
commit
391a032791
33
zinflate.cpp
33
zinflate.cpp
|
|
@ -223,7 +223,7 @@ void Inflator::IsolatedInitialize(const NameValuePairs ¶meters)
|
||||||
m_reader.SkipBits(m_reader.BitsBuffered());
|
m_reader.SkipBits(m_reader.BitsBuffered());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Inflator::OutputByte(byte b)
|
void Inflator::OutputByte(byte b)
|
||||||
{
|
{
|
||||||
m_window[m_current++] = b;
|
m_window[m_current++] = b;
|
||||||
if (m_current == m_window.size())
|
if (m_current == m_window.size())
|
||||||
|
|
@ -231,26 +231,38 @@ inline void Inflator::OutputByte(byte b)
|
||||||
ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
|
ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
|
||||||
m_lastFlush = 0;
|
m_lastFlush = 0;
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
|
m_wrappedAround = true;
|
||||||
}
|
}
|
||||||
if (m_maxDistance < m_window.size())
|
|
||||||
m_maxDistance++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inflator::OutputString(const byte *string, unsigned int length)
|
void Inflator::OutputString(const byte *string, unsigned int length)
|
||||||
{
|
{
|
||||||
while (length--)
|
while (length)
|
||||||
OutputByte(*string++);
|
{
|
||||||
|
unsigned int len = STDMIN(length, m_window.size() - m_current);
|
||||||
|
memcpy(m_window + m_current, string, len);
|
||||||
|
m_current += len;
|
||||||
|
if (m_current == m_window.size())
|
||||||
|
{
|
||||||
|
ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush);
|
||||||
|
m_lastFlush = 0;
|
||||||
|
m_current = 0;
|
||||||
|
m_wrappedAround = true;
|
||||||
|
}
|
||||||
|
string += len;
|
||||||
|
length -= len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inflator::OutputPast(unsigned int length, unsigned int distance)
|
void Inflator::OutputPast(unsigned int length, unsigned int distance)
|
||||||
{
|
{
|
||||||
if (distance > m_maxDistance)
|
|
||||||
throw BadBlockErr();
|
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
if (m_current > distance)
|
if (distance <= m_current)
|
||||||
start = m_current - distance;
|
start = m_current - distance;
|
||||||
else
|
else if (m_wrappedAround && distance <= m_window.size())
|
||||||
start = m_current + m_window.size() - distance;
|
start = m_current + m_window.size() - distance;
|
||||||
|
else
|
||||||
|
throw BadBlockErr();
|
||||||
|
|
||||||
if (start + length > m_window.size())
|
if (start + length > m_window.size())
|
||||||
{
|
{
|
||||||
|
|
@ -268,7 +280,6 @@ void Inflator::OutputPast(unsigned int length, unsigned int distance)
|
||||||
{
|
{
|
||||||
memcpy(m_window + m_current, m_window + start, length);
|
memcpy(m_window + m_current, m_window + start, length);
|
||||||
m_current += length;
|
m_current += length;
|
||||||
m_maxDistance = STDMIN((unsigned int)m_window.size(), m_maxDistance + length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -311,7 +322,7 @@ void Inflator::ProcessInput(bool flush)
|
||||||
return;
|
return;
|
||||||
ProcessPrestreamHeader();
|
ProcessPrestreamHeader();
|
||||||
m_state = WAIT_HEADER;
|
m_state = WAIT_HEADER;
|
||||||
m_maxDistance = 0;
|
m_wrappedAround = false;
|
||||||
m_current = 0;
|
m_current = 0;
|
||||||
m_lastFlush = 0;
|
m_lastFlush = 0;
|
||||||
m_window.New(1 << GetLog2WindowSize());
|
m_window.New(1 << GetLog2WindowSize());
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ private:
|
||||||
|
|
||||||
enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
|
enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END};
|
||||||
State m_state;
|
State m_state;
|
||||||
bool m_repeat, m_eof;
|
bool m_repeat, m_eof, m_wrappedAround;
|
||||||
byte m_blockType;
|
byte m_blockType;
|
||||||
word16 m_storedLen;
|
word16 m_storedLen;
|
||||||
enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
|
enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS};
|
||||||
|
|
@ -141,7 +141,7 @@ private:
|
||||||
HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
|
HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder;
|
||||||
LowFirstBitReader m_reader;
|
LowFirstBitReader m_reader;
|
||||||
SecByteBlock m_window;
|
SecByteBlock m_window;
|
||||||
unsigned int m_maxDistance, m_current, m_lastFlush;
|
unsigned int m_current, m_lastFlush;
|
||||||
};
|
};
|
||||||
|
|
||||||
NAMESPACE_END
|
NAMESPACE_END
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue