diff src/win32/7zip/7z/C/HuffEnc.c @ 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/C/HuffEnc.c	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,148 @@
     1.4 +/* HuffEnc.c -- functions for Huffman encoding
     1.5 +2008-08-05
     1.6 +Igor Pavlov
     1.7 +Public domain */
     1.8 +
     1.9 +#include "HuffEnc.h"
    1.10 +#include "Sort.h"
    1.11 +
    1.12 +#define kMaxLen 16
    1.13 +#define NUM_BITS 10
    1.14 +#define MASK ((1 << NUM_BITS) - 1)
    1.15 +
    1.16 +#define NUM_COUNTERS 64
    1.17 +
    1.18 +#define HUFFMAN_SPEED_OPT
    1.19 +
    1.20 +void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 numSymbols, UInt32 maxLen)
    1.21 +{
    1.22 +  UInt32 num = 0;
    1.23 +  /* if (maxLen > 10) maxLen = 10; */
    1.24 +  {
    1.25 +    UInt32 i;
    1.26 +    
    1.27 +    #ifdef HUFFMAN_SPEED_OPT
    1.28 +    
    1.29 +    UInt32 counters[NUM_COUNTERS];
    1.30 +    for (i = 0; i < NUM_COUNTERS; i++)
    1.31 +      counters[i] = 0;
    1.32 +    for (i = 0; i < numSymbols; i++)
    1.33 +    {
    1.34 +      UInt32 freq = freqs[i];
    1.35 +      counters[(freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1]++;
    1.36 +    }
    1.37 + 
    1.38 +    for (i = 1; i < NUM_COUNTERS; i++)
    1.39 +    {
    1.40 +      UInt32 temp = counters[i];
    1.41 +      counters[i] = num;
    1.42 +      num += temp;
    1.43 +    }
    1.44 +
    1.45 +    for (i = 0; i < numSymbols; i++)
    1.46 +    {
    1.47 +      UInt32 freq = freqs[i];
    1.48 +      if (freq == 0)
    1.49 +        lens[i] = 0;
    1.50 +      else
    1.51 +        p[counters[((freq < NUM_COUNTERS - 1) ? freq : NUM_COUNTERS - 1)]++] = i | (freq << NUM_BITS);
    1.52 +    }
    1.53 +    counters[0] = 0;
    1.54 +    HeapSort(p + counters[NUM_COUNTERS - 2], counters[NUM_COUNTERS - 1] - counters[NUM_COUNTERS - 2]);
    1.55 +    
    1.56 +    #else
    1.57 +
    1.58 +    for (i = 0; i < numSymbols; i++)
    1.59 +    {
    1.60 +      UInt32 freq = freqs[i];
    1.61 +      if (freq == 0)
    1.62 +        lens[i] = 0;
    1.63 +      else
    1.64 +        p[num++] = i | (freq << NUM_BITS);
    1.65 +    }
    1.66 +    HeapSort(p, num);
    1.67 +
    1.68 +    #endif
    1.69 +  }
    1.70 +
    1.71 +  if (num < 2)
    1.72 +  {
    1.73 +    int minCode = 0;
    1.74 +    int maxCode = 1;
    1.75 +    if (num == 1)
    1.76 +    {
    1.77 +      maxCode = (int)(p[0] & MASK);
    1.78 +      if (maxCode == 0)
    1.79 +        maxCode++;
    1.80 +    }
    1.81 +    p[minCode] = 0;
    1.82 +    p[maxCode] = 1;
    1.83 +    lens[minCode] = lens[maxCode] = 1;
    1.84 +    return;
    1.85 +  }
    1.86 +  
    1.87 +  {
    1.88 +    UInt32 b, e, i;
    1.89 +  
    1.90 +    i = b = e = 0;
    1.91 +    do
    1.92 +    {
    1.93 +      UInt32 n, m, freq;
    1.94 +      n = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
    1.95 +      freq = (p[n] & ~MASK);
    1.96 +      p[n] = (p[n] & MASK) | (e << NUM_BITS);
    1.97 +      m = (i != num && (b == e || (p[i] >> NUM_BITS) <= (p[b] >> NUM_BITS))) ? i++ : b++;
    1.98 +      freq += (p[m] & ~MASK);
    1.99 +      p[m] = (p[m] & MASK) | (e << NUM_BITS);
   1.100 +      p[e] = (p[e] & MASK) | freq;
   1.101 +      e++;
   1.102 +    }
   1.103 +    while (num - e > 1);
   1.104 +    
   1.105 +    {
   1.106 +      UInt32 lenCounters[kMaxLen + 1];
   1.107 +      for (i = 0; i <= kMaxLen; i++)
   1.108 +        lenCounters[i] = 0;
   1.109 +      
   1.110 +      p[--e] &= MASK;
   1.111 +      lenCounters[1] = 2;
   1.112 +      while (e > 0)
   1.113 +      {
   1.114 +        UInt32 len = (p[p[--e] >> NUM_BITS] >> NUM_BITS) + 1;
   1.115 +        p[e] = (p[e] & MASK) | (len << NUM_BITS);
   1.116 +        if (len >= maxLen)
   1.117 +          for (len = maxLen - 1; lenCounters[len] == 0; len--);
   1.118 +        lenCounters[len]--;
   1.119 +        lenCounters[len + 1] += 2;
   1.120 +      }
   1.121 +      
   1.122 +      {
   1.123 +        UInt32 len;
   1.124 +        i = 0;
   1.125 +        for (len = maxLen; len != 0; len--)
   1.126 +        {
   1.127 +          UInt32 num;
   1.128 +          for (num = lenCounters[len]; num != 0; num--)
   1.129 +            lens[p[i++] & MASK] = (Byte)len;
   1.130 +        }
   1.131 +      }
   1.132 +      
   1.133 +      {
   1.134 +        UInt32 nextCodes[kMaxLen + 1];
   1.135 +        {
   1.136 +          UInt32 code = 0;
   1.137 +          UInt32 len;
   1.138 +          for (len = 1; len <= kMaxLen; len++)
   1.139 +            nextCodes[len] = code = (code + lenCounters[len - 1]) << 1;
   1.140 +        }
   1.141 +        /* if (code + lenCounters[kMaxLen] - 1 != (1 << kMaxLen) - 1) throw 1; */
   1.142 +
   1.143 +        {
   1.144 +          UInt32 i;
   1.145 +          for (i = 0; i < numSymbols; i++)
   1.146 +            p[i] = nextCodes[lens[i]]++;
   1.147 +        }
   1.148 +      }
   1.149 +    }
   1.150 +  }
   1.151 +}