1 /* HuffEnc.c -- functions for Huffman encoding
\r
2 2009-09-02 : Igor Pavlov : Public domain */
\r
9 #define MASK ((1 << NUM_BITS) - 1)
\r
11 #define NUM_COUNTERS 64
\r
13 #define HUFFMAN_SPEED_OPT
\r
15 void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
\r
18 /* if (maxLen > 10) maxLen = 10; */
\r
22 #ifdef HUFFMAN_SPEED_OPT
\r
24 UInt32 counters[NUM_COUNTERS];
\r
25 for (i = 0; i < NUM_COUNTERS; i++)
\r
27 for (i = 0; i < numSymbols; i++)
\r
29 UInt32 freq = freqs[i];
\r
30 counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
\r
33 for (i = 1; i < NUM_COUNTERS; i++)
\r
35 UInt32 temp = counters[i];
\r
40 for (i = 0; i < numSymbols; i++)
\r
42 UInt32 freq = freqs[i];
\r
46 p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
\r
49 HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
\r
53 for (i = 0; i < numSymbols; i++)
\r
55 UInt32 freq = freqs[i];
\r
59 p[num++] = i | (freq << NUM_BITS);
\r
68 unsigned minCode = 0;
\r
69 unsigned maxCode = 1;
\r
72 maxCode = (unsigned)p[0] & MASK;
\r
78 lens[minCode] = lens[maxCode] = 1;
\r
89 n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
\r
90 freq = (p[n] & ~MASK);
\r
91 p[n] = (p[n] & MASK) | (e << NUM_BITS);
\r
92 m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
\r
93 freq += (p[m] & ~MASK);
\r
94 p[m] = (p[m] & MASK) | (e << NUM_BITS);
\r
95 p[e] = (p[e] & MASK) | freq;
\r
98 while (num - e > 1);
\r
101 UInt32 lenCounters[kMaxLen + 1];
\r
102 for (i = 0; i <= kMaxLen; i++)
\r
103 lenCounters[i] = 0;
\r
106 lenCounters[1] = 2;
\r
109 UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
\r
110 p[e] = (p[e] & MASK) | (len << NUM_BITS);
\r
112 for (len = maxLen - 1; lenCounters[len] == 0; len--);
\r
113 lenCounters[len]--;
\r
114 lenCounters[len + 1] += 2;
\r
120 for (len = maxLen; len != 0; len--)
\r
123 for (num = lenCounters[len]; num != 0; num--)
\r
124 lens[p[i++] & MASK] = (Byte)len;
\r
129 UInt32 nextCodes[kMaxLen + 1];
\r
133 for (len = 1; len <= kMaxLen; len++)
\r
134 nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
\r
136 /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
\r
140 for (i = 0; i < numSymbols; i++)
\r
141 p[i] = nextCodes[lens[i]]++;
\r