From 36fa3fc2b13356f20ed58c37cdeb68c830c59829 Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 16 May 2003 00:02:31 +0000 Subject: misc optimizations git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@68 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- zinflate.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 19 deletions(-) (limited to 'zinflate.cpp') diff --git a/zinflate.cpp b/zinflate.cpp index fccbf83..2582cf1 100644 --- a/zinflate.cpp +++ b/zinflate.cpp @@ -210,8 +210,7 @@ bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation) : AutoSignaling(attachment, propagation) - , m_state(PRE_STREAM), m_repeat(repeat) - , m_decodersInitializedWithFixedCodes(false), m_reader(m_inQueue) + , m_state(PRE_STREAM), m_repeat(repeat), m_reader(m_inQueue) { } @@ -366,23 +365,10 @@ void Inflator::DecodeHeader() break; } case 1: // fixed codes - if (!m_decodersInitializedWithFixedCodes) - { - unsigned int codeLengths[288]; - std::fill(codeLengths + 0, codeLengths + 144, 8); - std::fill(codeLengths + 144, codeLengths + 256, 9); - std::fill(codeLengths + 256, codeLengths + 280, 7); - std::fill(codeLengths + 280, codeLengths + 288, 8); - m_literalDecoder.Initialize(codeLengths, 288); - std::fill(codeLengths + 0, codeLengths + 32, 5); - m_distanceDecoder.Initialize(codeLengths, 32); - m_decodersInitializedWithFixedCodes = true; - } m_nextDecode = LITERAL; break; case 2: // dynamic codes { - m_decodersInitializedWithFixedCodes = false; if (!m_reader.FillBuffer(5+5+4)) throw UnexpectedEndErr(); unsigned int hlit = m_reader.GetBits(5); @@ -439,14 +425,14 @@ void Inflator::DecodeHeader() std::fill(codeLengths + i, codeLengths + i + count, repeater); i += count; } - m_literalDecoder.Initialize(codeLengths, hlit+257); + m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257); if (hdist == 0 && codeLengths[hlit+257] == 0) { if (hlit != 0) // a single zero distance code length means all literals throw BadBlockErr(); } else - m_distanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); + m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); m_nextDecode = LITERAL; } catch (HuffmanDecoder::Err &) @@ -497,12 +483,15 @@ bool Inflator::DecodeBody() 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + const HuffmanDecoder* pLiteralDecoder = GetLiteralDecoder(); + const HuffmanDecoder* pDistanceDecoder = GetDistanceDecoder(); + switch (m_nextDecode) { while (true) { case LITERAL: - if (!m_literalDecoder.Decode(m_reader, m_literal)) + if (!pLiteralDecoder->Decode(m_reader, m_literal)) { m_nextDecode = LITERAL; break; @@ -528,7 +517,7 @@ bool Inflator::DecodeBody() } m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257]; case DISTANCE: - if (!m_distanceDecoder.Decode(m_reader, m_distance)) + if (!pDistanceDecoder->Decode(m_reader, m_distance)) { m_nextDecode = DISTANCE; break; @@ -578,4 +567,45 @@ void Inflator::FlushOutput() } } +const HuffmanDecoder *Inflator::FixedLiteralDecoder() +{ + static simple_ptr s_pDecoder; + if (!s_pDecoder.m_p) + { + unsigned int codeLengths[288]; + std::fill(codeLengths + 0, codeLengths + 144, 8); + std::fill(codeLengths + 144, codeLengths + 256, 9); + std::fill(codeLengths + 256, codeLengths + 280, 7); + std::fill(codeLengths + 280, codeLengths + 288, 8); + HuffmanDecoder *pDecoder = new HuffmanDecoder; + pDecoder->Initialize(codeLengths, 288); + s_pDecoder.m_p = pDecoder; + } + return s_pDecoder.m_p; +} + +const HuffmanDecoder *Inflator::FixedDistanceDecoder() +{ + static simple_ptr s_pDecoder; + if (!s_pDecoder.m_p) + { + unsigned int codeLengths[32]; + std::fill(codeLengths + 0, codeLengths + 32, 5); + HuffmanDecoder *pDecoder = new HuffmanDecoder; + pDecoder->Initialize(codeLengths, 32); + s_pDecoder.m_p = pDecoder; + } + return s_pDecoder.m_p; +} + +const HuffmanDecoder *Inflator::GetLiteralDecoder() const +{ + return m_blockType == 1 ? FixedLiteralDecoder() : &m_dynamicLiteralDecoder; +} + +const HuffmanDecoder *Inflator::GetDistanceDecoder() const +{ + return m_blockType == 1 ? FixedDistanceDecoder() : &m_dynamicDistanceDecoder; +} + NAMESPACE_END -- cgit v1.2.1