xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/HuffmanDecoder.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Compress/HuffmanDecoder.h
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H
4*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_COMPRESS_HUFFMAN_DECODER_H
5*f6dc9357SAndroid Build Coastguard Worker 
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyTypes.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker namespace NCompress {
10*f6dc9357SAndroid Build Coastguard Worker namespace NHuffman {
11*f6dc9357SAndroid Build Coastguard Worker 
12*f6dc9357SAndroid Build Coastguard Worker // const unsigned kNumTableBits_Default = 9;
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #if 0 || 0 && defined(MY_CPU_64BIT)
15*f6dc9357SAndroid Build Coastguard Worker // for debug or optimization:
16*f6dc9357SAndroid Build Coastguard Worker // 64-BIT limit array can be faster for some compilers.
17*f6dc9357SAndroid Build Coastguard Worker // for debug or optimization:
18*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_USE_64BIT_LIMIT
19*f6dc9357SAndroid Build Coastguard Worker #else
20*f6dc9357SAndroid Build Coastguard Worker // sizet value variable allows to eliminate some move operation in some compilers.
21*f6dc9357SAndroid Build Coastguard Worker // for debug or optimization:
22*f6dc9357SAndroid Build Coastguard Worker // #define Z7_HUFF_USE_SIZET_VALUE
23*f6dc9357SAndroid Build Coastguard Worker #endif
24*f6dc9357SAndroid Build Coastguard Worker 
25*f6dc9357SAndroid Build Coastguard Worker // v0 must normalized to (32 bits) : (v0 < ((UInt64)1 << 32))
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_HUFF_USE_64BIT_LIMIT
28*f6dc9357SAndroid Build Coastguard Worker   typedef UInt64 CLimitInt;
29*f6dc9357SAndroid Build Coastguard Worker   typedef UInt64 CValueInt;
30*f6dc9357SAndroid Build Coastguard Worker   // all _limits[*] are normalized and limited by ((UInt64)1 << 32).
31*f6dc9357SAndroid Build Coastguard Worker   // we don't use (v1) in this branch
32*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax)  32
33*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \
34*f6dc9357SAndroid Build Coastguard Worker       ((NCompress::NHuffman::CLimitInt)v0 >= (huf)->_limits[0])
35*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits)  (v0)
36*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits)  ((v0) >> (32 - kNumTableBits))
37*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1)
38*f6dc9357SAndroid Build Coastguard Worker #else
39*f6dc9357SAndroid Build Coastguard Worker   typedef UInt32 CLimitInt;
40*f6dc9357SAndroid Build Coastguard Worker   typedef
41*f6dc9357SAndroid Build Coastguard Worker     #ifdef Z7_HUFF_USE_SIZET_VALUE
42*f6dc9357SAndroid Build Coastguard Worker       size_t
43*f6dc9357SAndroid Build Coastguard Worker     #else
44*f6dc9357SAndroid Build Coastguard Worker       UInt32
45*f6dc9357SAndroid Build Coastguard Worker     #endif
46*f6dc9357SAndroid Build Coastguard Worker       CValueInt;
47*f6dc9357SAndroid Build Coastguard Worker   // v1 must be precalculated from v0 in this branch
48*f6dc9357SAndroid Build Coastguard Worker   // _limits[0] and (v1) are normalized and limited by (1 << kNumTableBits).
49*f6dc9357SAndroid Build Coastguard Worker   // _limits[non_0]      are normalized and limited by (1 << kNumBitsMax).
50*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax)  (kNumBitsMax)
51*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1) \
52*f6dc9357SAndroid Build Coastguard Worker       ((NCompress::NHuffman::CLimitInt)v1 >= (huf)->_limits[0])
53*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_GET_VAL_FOR_LIMITS(v0, v1, kNumBitsMax, kNumTableBits)  ((v0) >> (32 - kNumBitsMax))
54*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_GET_VAL_FOR_TABLE( v0, v1, kNumBitsMax, kNumTableBits)  (v1)
55*f6dc9357SAndroid Build Coastguard Worker   #define Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1)  const UInt32 v1 = ((v0) >> (32 - kNumTableBits));
56*f6dc9357SAndroid Build Coastguard Worker #endif
57*f6dc9357SAndroid Build Coastguard Worker 
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker enum enum_BuildMode
60*f6dc9357SAndroid Build Coastguard Worker {
61*f6dc9357SAndroid Build Coastguard Worker   k_BuildMode_Partial       = 0,
62*f6dc9357SAndroid Build Coastguard Worker   k_BuildMode_Full          = 1,
63*f6dc9357SAndroid Build Coastguard Worker   k_BuildMode_Full_or_Empty = 2
64*f6dc9357SAndroid Build Coastguard Worker };
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker 
67*f6dc9357SAndroid Build Coastguard Worker template <class symType, class symType2, class symType4, unsigned kNumBitsMax, unsigned m_NumSymbols, unsigned kNumTableBits /* = kNumTableBits_Default */>
68*f6dc9357SAndroid Build Coastguard Worker struct CDecoderBase
69*f6dc9357SAndroid Build Coastguard Worker {
70*f6dc9357SAndroid Build Coastguard Worker   CLimitInt _limits[kNumBitsMax + 2 - kNumTableBits];
71*f6dc9357SAndroid Build Coastguard Worker   UInt32 _poses[kNumBitsMax - kNumTableBits]; // unsigned
72*f6dc9357SAndroid Build Coastguard Worker union
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker   // if  defined(MY_CPU_64BIT), we need 64-bit alignment for _symbols.
75*f6dc9357SAndroid Build Coastguard Worker   // if !defined(MY_CPU_64BIT), we need 32-bit alignment for _symbols
76*f6dc9357SAndroid Build Coastguard Worker   // but we provide alignment for _lens.
77*f6dc9357SAndroid Build Coastguard Worker   // _symbols also will be aligned, if _lens are aligned
78*f6dc9357SAndroid Build Coastguard Worker   #if defined(MY_CPU_64BIT)
79*f6dc9357SAndroid Build Coastguard Worker     UInt64
80*f6dc9357SAndroid Build Coastguard Worker   #else
81*f6dc9357SAndroid Build Coastguard Worker     UInt32
82*f6dc9357SAndroid Build Coastguard Worker   #endif
83*f6dc9357SAndroid Build Coastguard Worker     _pad_align[m_NumSymbols < (1u << sizeof(symType) * 8) ? 1 : -1];
84*f6dc9357SAndroid Build Coastguard Worker   /* if symType is Byte, we use 16-bytes padding to avoid cache
85*f6dc9357SAndroid Build Coastguard Worker      bank conflict between _lens and _symbols: */
86*f6dc9357SAndroid Build Coastguard Worker   Byte _lens[(1 << kNumTableBits) + (sizeof(symType) == 1 ? 16 : 0)];
87*f6dc9357SAndroid Build Coastguard Worker } _u;
88*f6dc9357SAndroid Build Coastguard Worker   symType _symbols[(1 << kNumTableBits) + m_NumSymbols - (kNumTableBits + 1)];
89*f6dc9357SAndroid Build Coastguard Worker 
90*f6dc9357SAndroid Build Coastguard Worker   /*
91*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
92*f6dc9357SAndroid Build Coastguard Worker   bool IsFull() const
93*f6dc9357SAndroid Build Coastguard Worker   {
94*f6dc9357SAndroid Build Coastguard Worker     return _limits[kNumBitsMax - kNumTableBits] ==
95*f6dc9357SAndroid Build Coastguard Worker         (CLimitInt)1u << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax);
96*f6dc9357SAndroid Build Coastguard Worker   }
97*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
98*f6dc9357SAndroid Build Coastguard Worker   bool IsEmpty() const
99*f6dc9357SAndroid Build Coastguard Worker   {
100*f6dc9357SAndroid Build Coastguard Worker     return _limits[kNumBitsMax - kNumTableBits] == 0;
101*f6dc9357SAndroid Build Coastguard Worker   }
102*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
103*f6dc9357SAndroid Build Coastguard Worker   bool Is_Full_or_Empty() const
104*f6dc9357SAndroid Build Coastguard Worker   {
105*f6dc9357SAndroid Build Coastguard Worker     return 0 == (_limits[kNumBitsMax - kNumTableBits] &
106*f6dc9357SAndroid Build Coastguard Worker         ~((CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax)));
107*f6dc9357SAndroid Build Coastguard Worker   }
108*f6dc9357SAndroid Build Coastguard Worker   */
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
throwCDecoderBase111*f6dc9357SAndroid Build Coastguard Worker   bool Build(const Byte *lens, enum_BuildMode buidMode = k_BuildMode_Partial) throw()
112*f6dc9357SAndroid Build Coastguard Worker   {
113*f6dc9357SAndroid Build Coastguard Worker     unsigned counts[kNumBitsMax + 1];
114*f6dc9357SAndroid Build Coastguard Worker     size_t i;
115*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i <= kNumBitsMax; i++)
116*f6dc9357SAndroid Build Coastguard Worker       counts[i] = 0;
117*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < m_NumSymbols; i++)
118*f6dc9357SAndroid Build Coastguard Worker       counts[lens[i]]++;
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker     UInt32 sum = 0;
121*f6dc9357SAndroid Build Coastguard Worker     for (i = 1; i <= kNumTableBits; i++)
122*f6dc9357SAndroid Build Coastguard Worker     {
123*f6dc9357SAndroid Build Coastguard Worker       sum <<= 1;
124*f6dc9357SAndroid Build Coastguard Worker       sum += counts[i];
125*f6dc9357SAndroid Build Coastguard Worker     }
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker     CLimitInt startPos = (CLimitInt)sum;
128*f6dc9357SAndroid Build Coastguard Worker     _limits[0] =
129*f6dc9357SAndroid Build Coastguard Worker       #ifdef Z7_HUFF_USE_64BIT_LIMIT
130*f6dc9357SAndroid Build Coastguard Worker           startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - kNumTableBits);
131*f6dc9357SAndroid Build Coastguard Worker       #else
132*f6dc9357SAndroid Build Coastguard Worker           startPos;
133*f6dc9357SAndroid Build Coastguard Worker       #endif
134*f6dc9357SAndroid Build Coastguard Worker 
135*f6dc9357SAndroid Build Coastguard Worker     for (i = kNumTableBits + 1; i <= kNumBitsMax; i++)
136*f6dc9357SAndroid Build Coastguard Worker     {
137*f6dc9357SAndroid Build Coastguard Worker       startPos <<= 1;
138*f6dc9357SAndroid Build Coastguard Worker       _poses[i - (kNumTableBits + 1)] = (UInt32)(startPos - sum);
139*f6dc9357SAndroid Build Coastguard Worker       const unsigned cnt = counts[i];
140*f6dc9357SAndroid Build Coastguard Worker       counts[i] = sum;
141*f6dc9357SAndroid Build Coastguard Worker       sum += cnt;
142*f6dc9357SAndroid Build Coastguard Worker       startPos += cnt;
143*f6dc9357SAndroid Build Coastguard Worker       _limits[i - kNumTableBits] = startPos << (Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - i);
144*f6dc9357SAndroid Build Coastguard Worker     }
145*f6dc9357SAndroid Build Coastguard Worker 
146*f6dc9357SAndroid Build Coastguard Worker     _limits[kNumBitsMax + 1 - kNumTableBits] =
147*f6dc9357SAndroid Build Coastguard Worker         (CLimitInt)1 << Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax);
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker     if (buidMode == k_BuildMode_Partial)
150*f6dc9357SAndroid Build Coastguard Worker     {
151*f6dc9357SAndroid Build Coastguard Worker       if (startPos > (1u << kNumBitsMax)) return false;
152*f6dc9357SAndroid Build Coastguard Worker     }
153*f6dc9357SAndroid Build Coastguard Worker     else
154*f6dc9357SAndroid Build Coastguard Worker     {
155*f6dc9357SAndroid Build Coastguard Worker       if (buidMode != k_BuildMode_Full && startPos == 0) return true;
156*f6dc9357SAndroid Build Coastguard Worker       if (startPos != (1u << kNumBitsMax)) return false;
157*f6dc9357SAndroid Build Coastguard Worker     }
158*f6dc9357SAndroid Build Coastguard Worker     size_t sum2 = 0;
159*f6dc9357SAndroid Build Coastguard Worker     for (i = 1; i <= kNumTableBits; i++)
160*f6dc9357SAndroid Build Coastguard Worker     {
161*f6dc9357SAndroid Build Coastguard Worker       const unsigned cnt = counts[i] << (kNumTableBits - i);
162*f6dc9357SAndroid Build Coastguard Worker       counts[i] = (unsigned)sum2 >> (kNumTableBits - i);
163*f6dc9357SAndroid Build Coastguard Worker       memset(_u._lens + sum2, (int)i, cnt);
164*f6dc9357SAndroid Build Coastguard Worker       sum2 += cnt;
165*f6dc9357SAndroid Build Coastguard Worker     }
166*f6dc9357SAndroid Build Coastguard Worker 
167*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_64BIT
168*f6dc9357SAndroid Build Coastguard Worker     symType4
169*f6dc9357SAndroid Build Coastguard Worker     // UInt64 // for symType = UInt16
170*f6dc9357SAndroid Build Coastguard Worker     // UInt32 // for symType = Byte
171*f6dc9357SAndroid Build Coastguard Worker #else
172*f6dc9357SAndroid Build Coastguard Worker     UInt32
173*f6dc9357SAndroid Build Coastguard Worker #endif
174*f6dc9357SAndroid Build Coastguard Worker     v = 0;
175*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < m_NumSymbols; i++,
176*f6dc9357SAndroid Build Coastguard Worker       v +=
177*f6dc9357SAndroid Build Coastguard Worker           1
178*f6dc9357SAndroid Build Coastguard Worker           + (  (UInt32)1 << (sizeof(symType) * 8 * 1))
179*f6dc9357SAndroid Build Coastguard Worker           // 0x00010001 // for symType = UInt16
180*f6dc9357SAndroid Build Coastguard Worker           // 0x00000101 // for symType = Byte
181*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_64BIT
182*f6dc9357SAndroid Build Coastguard Worker           + ((symType4)1 << (sizeof(symType) * 8 * 2))
183*f6dc9357SAndroid Build Coastguard Worker           + ((symType4)1 << (sizeof(symType) * 8 * 3))
184*f6dc9357SAndroid Build Coastguard Worker           // 0x0001000100010001 // for symType = UInt16
185*f6dc9357SAndroid Build Coastguard Worker           // 0x0000000001010101 // for symType = Byte
186*f6dc9357SAndroid Build Coastguard Worker #endif
187*f6dc9357SAndroid Build Coastguard Worker       )
188*f6dc9357SAndroid Build Coastguard Worker     {
189*f6dc9357SAndroid Build Coastguard Worker       const unsigned len = lens[i];
190*f6dc9357SAndroid Build Coastguard Worker       if (len == 0)
191*f6dc9357SAndroid Build Coastguard Worker         continue;
192*f6dc9357SAndroid Build Coastguard Worker       const size_t offset = counts[len];
193*f6dc9357SAndroid Build Coastguard Worker       counts[len] = (unsigned)offset + 1;
194*f6dc9357SAndroid Build Coastguard Worker       if (len >= kNumTableBits)
195*f6dc9357SAndroid Build Coastguard Worker         _symbols[offset] = (symType)v;
196*f6dc9357SAndroid Build Coastguard Worker       else
197*f6dc9357SAndroid Build Coastguard Worker       {
198*f6dc9357SAndroid Build Coastguard Worker         Byte *s2 = (Byte *)(void *)_symbols + (offset <<
199*f6dc9357SAndroid Build Coastguard Worker             (kNumTableBits + sizeof(symType) / 2 - len));
200*f6dc9357SAndroid Build Coastguard Worker         Byte *lim = s2 + ((size_t)1 <<
201*f6dc9357SAndroid Build Coastguard Worker             (kNumTableBits + sizeof(symType) / 2 - len));
202*f6dc9357SAndroid Build Coastguard Worker         if (len >= kNumTableBits - 2)
203*f6dc9357SAndroid Build Coastguard Worker         {
204*f6dc9357SAndroid Build Coastguard Worker           *(symType2 *)(void *)(s2                       ) = (symType2)v;
205*f6dc9357SAndroid Build Coastguard Worker           *(symType2 *)(void *)(lim - sizeof(symType) * 2) = (symType2)v;
206*f6dc9357SAndroid Build Coastguard Worker         }
207*f6dc9357SAndroid Build Coastguard Worker         else
208*f6dc9357SAndroid Build Coastguard Worker         {
209*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_64BIT
210*f6dc9357SAndroid Build Coastguard Worker           symType4 *s = (symType4 *)(void *)s2;
211*f6dc9357SAndroid Build Coastguard Worker           do
212*f6dc9357SAndroid Build Coastguard Worker           {
213*f6dc9357SAndroid Build Coastguard Worker             s[0] = v;  s[1] = v;  s += 2;
214*f6dc9357SAndroid Build Coastguard Worker           }
215*f6dc9357SAndroid Build Coastguard Worker           while (s != (const symType4 *)(const void *)lim);
216*f6dc9357SAndroid Build Coastguard Worker #else
217*f6dc9357SAndroid Build Coastguard Worker           symType2 *s = (symType2 *)(void *)s2;
218*f6dc9357SAndroid Build Coastguard Worker           do
219*f6dc9357SAndroid Build Coastguard Worker           {
220*f6dc9357SAndroid Build Coastguard Worker             s[0] = (symType2)v;  s[1] = (symType2)v;  s += 2;
221*f6dc9357SAndroid Build Coastguard Worker             s[0] = (symType2)v;  s[1] = (symType2)v;  s += 2;
222*f6dc9357SAndroid Build Coastguard Worker           }
223*f6dc9357SAndroid Build Coastguard Worker           while (s != (const symType2 *)(const void *)lim);
224*f6dc9357SAndroid Build Coastguard Worker #endif
225*f6dc9357SAndroid Build Coastguard Worker         }
226*f6dc9357SAndroid Build Coastguard Worker       }
227*f6dc9357SAndroid Build Coastguard Worker     }
228*f6dc9357SAndroid Build Coastguard Worker     return true;
229*f6dc9357SAndroid Build Coastguard Worker   }
230*f6dc9357SAndroid Build Coastguard Worker 
231*f6dc9357SAndroid Build Coastguard Worker 
232*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES(_numBits_, kNumBitsMax, error_op)  if (_numBits_ > kNumBitsMax) { error_op }
233*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO( _numBits_, kNumBitsMax, error_op)
234*f6dc9357SAndroid Build Coastguard Worker 
235*f6dc9357SAndroid Build Coastguard Worker 
236*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits,  \
237*f6dc9357SAndroid Build Coastguard Worker       v0, v1, \
238*f6dc9357SAndroid Build Coastguard Worker       get_val_for_limits, \
239*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, _numBits_) \
240*f6dc9357SAndroid Build Coastguard Worker { \
241*f6dc9357SAndroid Build Coastguard Worker     const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \
242*f6dc9357SAndroid Build Coastguard Worker     _numBits_ = kNumTableBits + 1; \
243*f6dc9357SAndroid Build Coastguard Worker     if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \
244*f6dc9357SAndroid Build Coastguard Worker     do { _numBits_++; } \
245*f6dc9357SAndroid Build Coastguard Worker     while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \
246*f6dc9357SAndroid Build Coastguard Worker     check_op(_numBits_, kNumBitsMax, error_op) \
247*f6dc9357SAndroid Build Coastguard Worker     sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \
248*f6dc9357SAndroid Build Coastguard Worker         - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \
249*f6dc9357SAndroid Build Coastguard Worker }
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker /*
252*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_BASE_TREE_BRANCH(sym, huf, kNumBitsMax, kNumTableBits,  \
253*f6dc9357SAndroid Build Coastguard Worker       v0, v1, \
254*f6dc9357SAndroid Build Coastguard Worker       get_val_for_limits, \
255*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, _numBits_) \
256*f6dc9357SAndroid Build Coastguard Worker 
257*f6dc9357SAndroid Build Coastguard Worker */
258*f6dc9357SAndroid Build Coastguard Worker 
259*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits,  \
260*f6dc9357SAndroid Build Coastguard Worker       v0, v1, \
261*f6dc9357SAndroid Build Coastguard Worker       get_val_for_table, get_val_for_limits, \
262*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, after_op, bs) \
263*f6dc9357SAndroid Build Coastguard Worker { \
264*f6dc9357SAndroid Build Coastguard Worker   if (Z7_HUFF_TABLE_COMPARE(huf, kNumTableBits, v0, v1)) \
265*f6dc9357SAndroid Build Coastguard Worker   { \
266*f6dc9357SAndroid Build Coastguard Worker     const NHuffman::CValueInt _val = get_val_for_limits(v0, v1, kNumBitsMax, kNumTableBits); \
267*f6dc9357SAndroid Build Coastguard Worker     size_t _numBits_ = kNumTableBits + 1; \
268*f6dc9357SAndroid Build Coastguard Worker     if ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[1]) \
269*f6dc9357SAndroid Build Coastguard Worker     do { _numBits_++; } \
270*f6dc9357SAndroid Build Coastguard Worker     while ((NCompress::NHuffman::CLimitInt)_val >= (huf)->_limits[_numBits_ - kNumTableBits]); \
271*f6dc9357SAndroid Build Coastguard Worker     check_op(_numBits_, kNumBitsMax, error_op) \
272*f6dc9357SAndroid Build Coastguard Worker     sym = (huf)->_symbols[(/* (UInt32) */ (_val >> ((Z7_HUFF_NUM_LIMIT_BITS(kNumBitsMax) - (unsigned)_numBits_)))) \
273*f6dc9357SAndroid Build Coastguard Worker         - (huf)->_poses[_numBits_ - (kNumTableBits + 1)]]; \
274*f6dc9357SAndroid Build Coastguard Worker     move_pos_op(bs, _numBits_); \
275*f6dc9357SAndroid Build Coastguard Worker   } \
276*f6dc9357SAndroid Build Coastguard Worker   else \
277*f6dc9357SAndroid Build Coastguard Worker   { \
278*f6dc9357SAndroid Build Coastguard Worker     const size_t _val = get_val_for_table(v0, v1, kNumBitsMax, kNumTableBits); \
279*f6dc9357SAndroid Build Coastguard Worker     const size_t _numBits_ = (huf)->_u._lens[_val]; \
280*f6dc9357SAndroid Build Coastguard Worker     sym = (huf)->_symbols[_val]; \
281*f6dc9357SAndroid Build Coastguard Worker     move_pos_op(bs, _numBits_); \
282*f6dc9357SAndroid Build Coastguard Worker   } \
283*f6dc9357SAndroid Build Coastguard Worker   after_op \
284*f6dc9357SAndroid Build Coastguard Worker }
285*f6dc9357SAndroid Build Coastguard Worker 
286*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits,  \
287*f6dc9357SAndroid Build Coastguard Worker       v0, v1, \
288*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, after_op, bs) \
289*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits,  \
290*f6dc9357SAndroid Build Coastguard Worker       v0, v1, \
291*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_TABLE, \
292*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_LIMITS, \
293*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, after_op, bs) \
294*f6dc9357SAndroid Build Coastguard Worker 
295*f6dc9357SAndroid Build Coastguard Worker 
296*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_VAL_IN_HIGH32(sym, huf, kNumBitsMax, kNumTableBits,  \
297*f6dc9357SAndroid Build Coastguard Worker       v0, \
298*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, after_op, bs) \
299*f6dc9357SAndroid Build Coastguard Worker { \
300*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_PRECALC_V1(kNumTableBits, v0, _v1_temp) \
301*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_10(sym, huf, kNumBitsMax, kNumTableBits,  \
302*f6dc9357SAndroid Build Coastguard Worker       v0, _v1_temp, \
303*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, after_op, bs) \
304*f6dc9357SAndroid Build Coastguard Worker }
305*f6dc9357SAndroid Build Coastguard Worker 
306*f6dc9357SAndroid Build Coastguard Worker #if 0 || defined(Z7_HUFF_USE_64BIT_LIMIT)
307*f6dc9357SAndroid Build Coastguard Worker // this branch uses bitStream->GetValue_InHigh32bits().
308*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, \
309*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op) \
310*f6dc9357SAndroid Build Coastguard Worker { \
311*f6dc9357SAndroid Build Coastguard Worker   const UInt32 v0 = (bitStream)->GetValue_InHigh32bits(); \
312*f6dc9357SAndroid Build Coastguard Worker   Z7_HUFF_PRECALC_V1(kNumTableBits, v0, v1); \
313*f6dc9357SAndroid Build Coastguard Worker   Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \
314*f6dc9357SAndroid Build Coastguard Worker       v0, v1,  \
315*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_TABLE, \
316*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_LIMITS, \
317*f6dc9357SAndroid Build Coastguard Worker        check_op, error_op, move_pos_op, {}, bitStream) \
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker #else
320*f6dc9357SAndroid Build Coastguard Worker /*
321*f6dc9357SAndroid Build Coastguard Worker this branch uses bitStream->GetValue().
322*f6dc9357SAndroid Build Coastguard Worker So we use SIMPLE versions for v0, v1 calculation:
323*f6dc9357SAndroid Build Coastguard Worker   v0 is normalized for kNumBitsMax
324*f6dc9357SAndroid Build Coastguard Worker   v1 is normalized for kNumTableBits
325*f6dc9357SAndroid Build Coastguard Worker */
326*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE(v0, v1, kNumBitsMax, kNumTableBits)  v0
327*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE( v0, v1, kNumBitsMax, kNumTableBits)  v1
328*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, move_pos_op) \
329*f6dc9357SAndroid Build Coastguard Worker { \
330*f6dc9357SAndroid Build Coastguard Worker   const UInt32 v0 = (bitStream)->GetValue(kNumBitsMax); \
331*f6dc9357SAndroid Build Coastguard Worker   const UInt32 v1 = v0 >> (kNumBitsMax - kNumTableBits); \
332*f6dc9357SAndroid Build Coastguard Worker   Z7_HUFF_DECODE_BASE(sym, huf, kNumBitsMax, kNumTableBits, \
333*f6dc9357SAndroid Build Coastguard Worker       v0, v1,  \
334*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_TABLE_SIMPLE, \
335*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_GET_VAL_FOR_LIMITS_SIMPLE, \
336*f6dc9357SAndroid Build Coastguard Worker       check_op, error_op, move_pos_op, {}, bitStream) \
337*f6dc9357SAndroid Build Coastguard Worker }
338*f6dc9357SAndroid Build Coastguard Worker #endif
339*f6dc9357SAndroid Build Coastguard Worker 
340*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_bitStream_MovePos(bitStream, numBits)  (bitStream)->MovePos((unsigned)(numBits))
341*f6dc9357SAndroid Build Coastguard Worker 
342*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_1(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \
343*f6dc9357SAndroid Build Coastguard Worker         Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \
344*f6dc9357SAndroid Build Coastguard Worker           Z7_HUFF_bitStream_MovePos)
345*f6dc9357SAndroid Build Coastguard Worker 
346*f6dc9357SAndroid Build Coastguard Worker // MovePosCheck
347*f6dc9357SAndroid Build Coastguard Worker 
348*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_2(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op) \
349*f6dc9357SAndroid Build Coastguard Worker         Z7_HUFF_DECODE_0(sym, huf, kNumBitsMax, kNumTableBits, bitStream, check_op, error_op, \
350*f6dc9357SAndroid Build Coastguard Worker           Z7_HUFF_bitStream_MovePos)
351*f6dc9357SAndroid Build Coastguard Worker 
352*f6dc9357SAndroid Build Coastguard Worker // MovePosCheck
353*f6dc9357SAndroid Build Coastguard Worker 
354*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODE_CHECK(sym, huf, kNumBitsMax, kNumTableBits, bitStream, error_op) \
355*f6dc9357SAndroid Build Coastguard Worker         Z7_HUFF_DECODE_1(    sym, huf, kNumBitsMax, kNumTableBits, bitStream, \
356*f6dc9357SAndroid Build Coastguard Worker         Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES, error_op)
357*f6dc9357SAndroid Build Coastguard Worker 
358*f6dc9357SAndroid Build Coastguard Worker   template <class TBitDecoder>
359*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
Decode2CDecoderBase360*f6dc9357SAndroid Build Coastguard Worker   bool Decode2(TBitDecoder *bitStream, unsigned &sym) const
361*f6dc9357SAndroid Build Coastguard Worker   {
362*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream,
363*f6dc9357SAndroid Build Coastguard Worker       { return false; }
364*f6dc9357SAndroid Build Coastguard Worker     )
365*f6dc9357SAndroid Build Coastguard Worker     return true;
366*f6dc9357SAndroid Build Coastguard Worker   }
367*f6dc9357SAndroid Build Coastguard Worker 
368*f6dc9357SAndroid Build Coastguard Worker   template <class TBitDecoder>
369*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
Decode_SymCheck_MovePosCheckCDecoderBase370*f6dc9357SAndroid Build Coastguard Worker   bool Decode_SymCheck_MovePosCheck(TBitDecoder *bitStream, unsigned &sym) const
371*f6dc9357SAndroid Build Coastguard Worker   {
372*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_0(sym, this, kNumBitsMax, kNumTableBits, bitStream,
373*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_DECODE_ERROR_SYM_CHECK_YES,
374*f6dc9357SAndroid Build Coastguard Worker       { return false; },
375*f6dc9357SAndroid Build Coastguard Worker       { return (bitStream)->MovePosCheck; }
376*f6dc9357SAndroid Build Coastguard Worker     )
377*f6dc9357SAndroid Build Coastguard Worker   }
378*f6dc9357SAndroid Build Coastguard Worker 
379*f6dc9357SAndroid Build Coastguard Worker   template <class TBitDecoder>
380*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
DecodeCDecoderBase381*f6dc9357SAndroid Build Coastguard Worker   unsigned Decode(TBitDecoder *bitStream) const
382*f6dc9357SAndroid Build Coastguard Worker   {
383*f6dc9357SAndroid Build Coastguard Worker     unsigned sym;
384*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_CHECK(sym, this, kNumBitsMax, kNumTableBits, bitStream,
385*f6dc9357SAndroid Build Coastguard Worker       { return (unsigned)(int)(Int32)0xffffffff; }
386*f6dc9357SAndroid Build Coastguard Worker     )
387*f6dc9357SAndroid Build Coastguard Worker     return sym;
388*f6dc9357SAndroid Build Coastguard Worker   }
389*f6dc9357SAndroid Build Coastguard Worker 
390*f6dc9357SAndroid Build Coastguard Worker 
391*f6dc9357SAndroid Build Coastguard Worker   template <class TBitDecoder>
392*f6dc9357SAndroid Build Coastguard Worker   Z7_FORCE_INLINE
DecodeFullCDecoderBase393*f6dc9357SAndroid Build Coastguard Worker   unsigned DecodeFull(TBitDecoder *bitStream) const
394*f6dc9357SAndroid Build Coastguard Worker   {
395*f6dc9357SAndroid Build Coastguard Worker     /*
396*f6dc9357SAndroid Build Coastguard Worker     const UInt32 val = bitStream->GetValue(kNumBitsMax);
397*f6dc9357SAndroid Build Coastguard Worker     if (val < _limits[kNumTableBits])
398*f6dc9357SAndroid Build Coastguard Worker     {
399*f6dc9357SAndroid Build Coastguard Worker       const unsigned pair = _u._lens[(size_t)(val >> (kNumBitsMax - kNumTableBits))];
400*f6dc9357SAndroid Build Coastguard Worker       bitStream->MovePos(pair & kPairLenMask);
401*f6dc9357SAndroid Build Coastguard Worker       return pair >> kNumPairLenBits;
402*f6dc9357SAndroid Build Coastguard Worker     }
403*f6dc9357SAndroid Build Coastguard Worker 
404*f6dc9357SAndroid Build Coastguard Worker     unsigned numBits;
405*f6dc9357SAndroid Build Coastguard Worker     for (numBits = kNumTableBits + 1; val >= _limits[numBits]; numBits++);
406*f6dc9357SAndroid Build Coastguard Worker 
407*f6dc9357SAndroid Build Coastguard Worker     bitStream->MovePos(numBits);
408*f6dc9357SAndroid Build Coastguard Worker     return _symbols[_poses[numBits] + (unsigned)
409*f6dc9357SAndroid Build Coastguard Worker         ((val - _limits[(size_t)numBits - 1]) >> (kNumBitsMax - numBits))];
410*f6dc9357SAndroid Build Coastguard Worker     */
411*f6dc9357SAndroid Build Coastguard Worker     unsigned sym;
412*f6dc9357SAndroid Build Coastguard Worker     Z7_HUFF_DECODE_2(sym, this, kNumBitsMax, kNumTableBits, bitStream,
413*f6dc9357SAndroid Build Coastguard Worker       Z7_HUFF_DECODE_ERROR_SYM_CHECK_NO, {}
414*f6dc9357SAndroid Build Coastguard Worker     )
415*f6dc9357SAndroid Build Coastguard Worker     return sym;
416*f6dc9357SAndroid Build Coastguard Worker   }
417*f6dc9357SAndroid Build Coastguard Worker };
418*f6dc9357SAndroid Build Coastguard Worker 
419*f6dc9357SAndroid Build Coastguard Worker 
420*f6dc9357SAndroid Build Coastguard Worker template <unsigned kNumBitsMax, unsigned m_NumSymbols, unsigned kNumTableBits /* = kNumTableBits_Default */>
421*f6dc9357SAndroid Build Coastguard Worker struct CDecoder: public CDecoderBase
422*f6dc9357SAndroid Build Coastguard Worker   <UInt16, UInt32, UInt64, kNumBitsMax, m_NumSymbols, kNumTableBits> {};
423*f6dc9357SAndroid Build Coastguard Worker 
424*f6dc9357SAndroid Build Coastguard Worker template <unsigned kNumBitsMax, unsigned m_NumSymbols, unsigned kNumTableBits /* = 7 */>
425*f6dc9357SAndroid Build Coastguard Worker struct CDecoder256: public CDecoderBase
426*f6dc9357SAndroid Build Coastguard Worker   <Byte, UInt16, UInt32, kNumBitsMax, m_NumSymbols, kNumTableBits> {};
427*f6dc9357SAndroid Build Coastguard Worker 
428*f6dc9357SAndroid Build Coastguard Worker 
429*f6dc9357SAndroid Build Coastguard Worker template <unsigned numSymbols>
430*f6dc9357SAndroid Build Coastguard Worker class CDecoder7b
431*f6dc9357SAndroid Build Coastguard Worker {
432*f6dc9357SAndroid Build Coastguard Worker public:
433*f6dc9357SAndroid Build Coastguard Worker   Byte _lens[1 << 7];
434*f6dc9357SAndroid Build Coastguard Worker 
Build(const Byte * lens,bool full)435*f6dc9357SAndroid Build Coastguard Worker   bool Build(const Byte *lens, bool full) throw()
436*f6dc9357SAndroid Build Coastguard Worker   {
437*f6dc9357SAndroid Build Coastguard Worker     const unsigned kNumBitsMax = 7;
438*f6dc9357SAndroid Build Coastguard Worker 
439*f6dc9357SAndroid Build Coastguard Worker     unsigned counts[kNumBitsMax + 1];
440*f6dc9357SAndroid Build Coastguard Worker     unsigned _poses[kNumBitsMax + 1];
441*f6dc9357SAndroid Build Coastguard Worker     unsigned _limits[kNumBitsMax + 1];
442*f6dc9357SAndroid Build Coastguard Worker     unsigned i;
443*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i <= kNumBitsMax; i++)
444*f6dc9357SAndroid Build Coastguard Worker       counts[i] = 0;
445*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numSymbols; i++)
446*f6dc9357SAndroid Build Coastguard Worker       counts[lens[i]]++;
447*f6dc9357SAndroid Build Coastguard Worker 
448*f6dc9357SAndroid Build Coastguard Worker     _limits[0] = 0;
449*f6dc9357SAndroid Build Coastguard Worker     const unsigned kMaxValue = 1u << kNumBitsMax;
450*f6dc9357SAndroid Build Coastguard Worker     unsigned startPos = 0;
451*f6dc9357SAndroid Build Coastguard Worker     unsigned sum = 0;
452*f6dc9357SAndroid Build Coastguard Worker 
453*f6dc9357SAndroid Build Coastguard Worker     for (i = 1; i <= kNumBitsMax; i++)
454*f6dc9357SAndroid Build Coastguard Worker     {
455*f6dc9357SAndroid Build Coastguard Worker       const unsigned cnt = counts[i];
456*f6dc9357SAndroid Build Coastguard Worker       startPos += cnt << (kNumBitsMax - i);
457*f6dc9357SAndroid Build Coastguard Worker       _limits[i] = startPos;
458*f6dc9357SAndroid Build Coastguard Worker       counts[i] = sum;
459*f6dc9357SAndroid Build Coastguard Worker       _poses[i] = sum;
460*f6dc9357SAndroid Build Coastguard Worker       sum += cnt;
461*f6dc9357SAndroid Build Coastguard Worker     }
462*f6dc9357SAndroid Build Coastguard Worker 
463*f6dc9357SAndroid Build Coastguard Worker     counts[0] = sum;
464*f6dc9357SAndroid Build Coastguard Worker     _poses[0] = sum;
465*f6dc9357SAndroid Build Coastguard Worker 
466*f6dc9357SAndroid Build Coastguard Worker     if (full)
467*f6dc9357SAndroid Build Coastguard Worker     {
468*f6dc9357SAndroid Build Coastguard Worker       if (startPos != kMaxValue)
469*f6dc9357SAndroid Build Coastguard Worker         return false;
470*f6dc9357SAndroid Build Coastguard Worker     }
471*f6dc9357SAndroid Build Coastguard Worker     else
472*f6dc9357SAndroid Build Coastguard Worker     {
473*f6dc9357SAndroid Build Coastguard Worker       if (startPos > kMaxValue)
474*f6dc9357SAndroid Build Coastguard Worker         return false;
475*f6dc9357SAndroid Build Coastguard Worker     }
476*f6dc9357SAndroid Build Coastguard Worker 
477*f6dc9357SAndroid Build Coastguard Worker 
478*f6dc9357SAndroid Build Coastguard Worker     for (i = 0; i < numSymbols; i++)
479*f6dc9357SAndroid Build Coastguard Worker     {
480*f6dc9357SAndroid Build Coastguard Worker       const unsigned len = lens[i];
481*f6dc9357SAndroid Build Coastguard Worker       if (len == 0)
482*f6dc9357SAndroid Build Coastguard Worker         continue;
483*f6dc9357SAndroid Build Coastguard Worker       const unsigned offset = counts[len]++;
484*f6dc9357SAndroid Build Coastguard Worker       {
485*f6dc9357SAndroid Build Coastguard Worker         Byte *dest = _lens + _limits[(size_t)len - 1]
486*f6dc9357SAndroid Build Coastguard Worker             + ((offset - _poses[len]) << (kNumBitsMax - len));
487*f6dc9357SAndroid Build Coastguard Worker         const unsigned num = (unsigned)1 << (kNumBitsMax - len);
488*f6dc9357SAndroid Build Coastguard Worker         const unsigned val = (i << 3) + len;
489*f6dc9357SAndroid Build Coastguard Worker         for (unsigned k = 0; k < num; k++)
490*f6dc9357SAndroid Build Coastguard Worker           dest[k] = (Byte)val;
491*f6dc9357SAndroid Build Coastguard Worker       }
492*f6dc9357SAndroid Build Coastguard Worker     }
493*f6dc9357SAndroid Build Coastguard Worker 
494*f6dc9357SAndroid Build Coastguard Worker     if (!full)
495*f6dc9357SAndroid Build Coastguard Worker     {
496*f6dc9357SAndroid Build Coastguard Worker       const unsigned limit = _limits[kNumBitsMax];
497*f6dc9357SAndroid Build Coastguard Worker       const unsigned num = ((unsigned)1 << kNumBitsMax) - limit;
498*f6dc9357SAndroid Build Coastguard Worker       Byte *dest = _lens + limit;
499*f6dc9357SAndroid Build Coastguard Worker       for (unsigned k = 0; k < num; k++)
500*f6dc9357SAndroid Build Coastguard Worker         dest[k] = (Byte)
501*f6dc9357SAndroid Build Coastguard Worker           // (0x1f << 3);
502*f6dc9357SAndroid Build Coastguard Worker           ((0x1f << 3) + 0x7);
503*f6dc9357SAndroid Build Coastguard Worker     }
504*f6dc9357SAndroid Build Coastguard Worker 
505*f6dc9357SAndroid Build Coastguard Worker     return true;
506*f6dc9357SAndroid Build Coastguard Worker   }
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker #define Z7_HUFF_DECODER_7B_DECODE(dest, huf, get_val, move_pos, bs) \
509*f6dc9357SAndroid Build Coastguard Worker   { \
510*f6dc9357SAndroid Build Coastguard Worker     const unsigned pair = huf->_lens[(size_t)get_val(7)]; \
511*f6dc9357SAndroid Build Coastguard Worker     const unsigned numBits = pair & 0x7; \
512*f6dc9357SAndroid Build Coastguard Worker     move_pos(bs, numBits); \
513*f6dc9357SAndroid Build Coastguard Worker     dest = pair >> 3; \
514*f6dc9357SAndroid Build Coastguard Worker   }
515*f6dc9357SAndroid Build Coastguard Worker 
516*f6dc9357SAndroid Build Coastguard Worker   template <class TBitDecoder>
Decode(TBitDecoder * bitStream)517*f6dc9357SAndroid Build Coastguard Worker   unsigned Decode(TBitDecoder *bitStream) const
518*f6dc9357SAndroid Build Coastguard Worker   {
519*f6dc9357SAndroid Build Coastguard Worker     const unsigned pair = _lens[(size_t)bitStream->GetValue(7)];
520*f6dc9357SAndroid Build Coastguard Worker     bitStream->MovePos(pair & 0x7);
521*f6dc9357SAndroid Build Coastguard Worker     return pair >> 3;
522*f6dc9357SAndroid Build Coastguard Worker   }
523*f6dc9357SAndroid Build Coastguard Worker };
524*f6dc9357SAndroid Build Coastguard Worker 
525*f6dc9357SAndroid Build Coastguard Worker }}
526*f6dc9357SAndroid Build Coastguard Worker 
527*f6dc9357SAndroid Build Coastguard Worker #endif
528