1 // ImplodeHuffmanDecoder.cpp
\r
5 #include "ImplodeHuffmanDecoder.h"
\r
7 namespace NCompress {
\r
11 CDecoder::CDecoder(UInt32 numSymbols):
\r
12 m_NumSymbols(numSymbols)
\r
14 m_Symbols = new UInt32[m_NumSymbols];
\r
17 CDecoder::~CDecoder()
\r
22 bool CDecoder::SetCodeLengths(const Byte *codeLengths)
\r
24 // int lenCounts[kNumBitsInLongestCode + 1], tmpPositions[kNumBitsInLongestCode + 1];
\r
25 int lenCounts[kNumBitsInLongestCode + 2], tmpPositions[kNumBitsInLongestCode + 1];
\r
27 for(i = 0; i <= kNumBitsInLongestCode; i++)
\r
30 for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
\r
31 lenCounts[codeLengths[symbolIndex]]++;
\r
32 // lenCounts[0] = 0;
\r
34 // tmpPositions[0] = m_Positions[0] = m_Limitits[0] = 0;
\r
35 m_Limitits[kNumBitsInLongestCode + 1] = 0;
\r
36 m_Positions[kNumBitsInLongestCode + 1] = 0;
\r
37 lenCounts[kNumBitsInLongestCode + 1] = 0;
\r
40 UInt32 startPos = 0;
\r
41 static const UInt32 kMaxValue = (1 << kNumBitsInLongestCode);
\r
43 for (i = kNumBitsInLongestCode; i > 0; i--)
\r
45 startPos += lenCounts[i] << (kNumBitsInLongestCode - i);
\r
46 if (startPos > kMaxValue)
\r
48 m_Limitits[i] = startPos;
\r
49 m_Positions[i] = m_Positions[i + 1] + lenCounts[i + 1];
\r
50 tmpPositions[i] = m_Positions[i] + lenCounts[i];
\r
54 // if _ZIP_MODE do not throw exception for trees containing only one node
\r
55 // #ifndef _ZIP_MODE
\r
56 if (startPos != kMaxValue)
\r
60 for (symbolIndex = 0; symbolIndex < m_NumSymbols; symbolIndex++)
\r
61 if (codeLengths[symbolIndex] != 0)
\r
62 m_Symbols[--tmpPositions[codeLengths[symbolIndex]]] = symbolIndex;
\r
66 UInt32 CDecoder::DecodeSymbol(CInBit *inStream)
\r
69 UInt32 value = inStream->GetValue(kNumBitsInLongestCode);
\r
71 for(i = kNumBitsInLongestCode; i > 0; i--)
\r
73 if (value < m_Limitits[i])
\r
81 inStream->MovePos(numBits);
\r
82 UInt32 index = m_Positions[numBits] +
\r
83 ((value - m_Limitits[numBits + 1]) >> (kNumBitsInLongestCode - numBits));
\r
84 if (index >= m_NumSymbols)
\r
86 return m_Symbols[index];
\r