Mercurial > vba-linux
diff src/win32/7zip/7z/CPP/7zip/Compress/HuffmanDecoder.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/HuffmanDecoder.h Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,89 @@ 1.4 +// Compress/HuffmanDecoder.h 1.5 + 1.6 +#ifndef __COMPRESS_HUFFMAN_DECODER_H 1.7 +#define __COMPRESS_HUFFMAN_DECODER_H 1.8 + 1.9 +#include "../../Common/Types.h" 1.10 + 1.11 +namespace NCompress { 1.12 +namespace NHuffman { 1.13 + 1.14 +const int kNumTableBits = 9; 1.15 + 1.16 +template <int kNumBitsMax, UInt32 m_NumSymbols> 1.17 +class CDecoder 1.18 +{ 1.19 + UInt32 m_Limits[kNumBitsMax + 1]; // m_Limits[i] = value limit for symbols with length = i 1.20 + UInt32 m_Positions[kNumBitsMax + 1]; // m_Positions[i] = index in m_Symbols[] of first symbol with length = i 1.21 + UInt32 m_Symbols[m_NumSymbols]; 1.22 + Byte m_Lengths[1 << kNumTableBits]; // Table oh length for short codes. 1.23 + 1.24 +public: 1.25 + 1.26 + bool SetCodeLengths(const Byte *codeLengths) 1.27 + { 1.28 + int lenCounts[kNumBitsMax + 1]; 1.29 + UInt32 tmpPositions[kNumBitsMax + 1]; 1.30 + int i; 1.31 + for(i = 1; i <= kNumBitsMax; i++) 1.32 + lenCounts[i] = 0; 1.33 + UInt32 symbol; 1.34 + for (symbol = 0; symbol < m_NumSymbols; symbol++) 1.35 + { 1.36 + int len = codeLengths[symbol]; 1.37 + if (len > kNumBitsMax) 1.38 + return false; 1.39 + lenCounts[len]++; 1.40 + m_Symbols[symbol] = 0xFFFFFFFF; 1.41 + } 1.42 + lenCounts[0] = 0; 1.43 + m_Positions[0] = m_Limits[0] = 0; 1.44 + UInt32 startPos = 0; 1.45 + UInt32 index = 0; 1.46 + const UInt32 kMaxValue = (1 << kNumBitsMax); 1.47 + for (i = 1; i <= kNumBitsMax; i++) 1.48 + { 1.49 + startPos += lenCounts[i] << (kNumBitsMax - i); 1.50 + if (startPos > kMaxValue) 1.51 + return false; 1.52 + m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos; 1.53 + m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1]; 1.54 + tmpPositions[i] = m_Positions[i]; 1.55 + if(i <= kNumTableBits) 1.56 + { 1.57 + UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits)); 1.58 + for (; index < limit; index++) 1.59 + m_Lengths[index] = (Byte)i; 1.60 + } 1.61 + } 1.62 + for (symbol = 0; symbol < m_NumSymbols; symbol++) 1.63 + { 1.64 + int len = codeLengths[symbol]; 1.65 + if (len != 0) 1.66 + m_Symbols[tmpPositions[len]++] = symbol; 1.67 + } 1.68 + return true; 1.69 + } 1.70 + 1.71 + template <class TBitDecoder> 1.72 + UInt32 DecodeSymbol(TBitDecoder *bitStream) 1.73 + { 1.74 + int numBits; 1.75 + UInt32 value = bitStream->GetValue(kNumBitsMax); 1.76 + if (value < m_Limits[kNumTableBits]) 1.77 + numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)]; 1.78 + else 1.79 + for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++); 1.80 + bitStream->MovePos(numBits); 1.81 + UInt32 index = m_Positions[numBits] + 1.82 + ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits)); 1.83 + if (index >= m_NumSymbols) 1.84 + // throw CDecoderException(); // test it 1.85 + return 0xFFFFFFFF; 1.86 + return m_Symbols[index]; 1.87 + } 1.88 +}; 1.89 + 1.90 +}} 1.91 + 1.92 +#endif