16296d357SDmitri Tikhonov/* Generate table for fast Huffman decoding */
26296d357SDmitri Tikhonov
36296d357SDmitri Tikhonov#include <inttypes.h>
46296d357SDmitri Tikhonov#include <stdint.h>
56296d357SDmitri Tikhonov#include <stdio.h>
66296d357SDmitri Tikhonov#include <stdlib.h>
76296d357SDmitri Tikhonov
86296d357SDmitri Tikhonov
96296d357SDmitri Tikhonovstruct el
106296d357SDmitri Tikhonov{
116296d357SDmitri Tikhonov    uint16_t    code;
126296d357SDmitri Tikhonov    unsigned    bits;
136296d357SDmitri Tikhonov    uint8_t     out;
146296d357SDmitri Tikhonov};
156296d357SDmitri Tikhonov
166296d357SDmitri Tikhonovstatic const struct el els[] =
176296d357SDmitri Tikhonov{
186296d357SDmitri Tikhonov    {        0x0,     5,  48, },
196296d357SDmitri Tikhonov    {        0x1,     5,  49, },
206296d357SDmitri Tikhonov    {        0x2,     5,  50, },
216296d357SDmitri Tikhonov    {        0x3,     5,  97, },
226296d357SDmitri Tikhonov    {        0x4,     5,  99, },
236296d357SDmitri Tikhonov    {        0x5,     5, 101, },
246296d357SDmitri Tikhonov    {        0x6,     5, 105, },
256296d357SDmitri Tikhonov    {        0x7,     5, 111, },
266296d357SDmitri Tikhonov    {        0x8,     5, 115, },
276296d357SDmitri Tikhonov    {        0x9,     5, 116, },
286296d357SDmitri Tikhonov    {       0x14,     6,  32, },
296296d357SDmitri Tikhonov    {       0x15,     6,  37, },
306296d357SDmitri Tikhonov    {       0x16,     6,  45, },
316296d357SDmitri Tikhonov    {       0x17,     6,  46, },
326296d357SDmitri Tikhonov    {       0x18,     6,  47, },
336296d357SDmitri Tikhonov    {       0x19,     6,  51, },
346296d357SDmitri Tikhonov    {       0x1a,     6,  52, },
356296d357SDmitri Tikhonov    {       0x1b,     6,  53, },
366296d357SDmitri Tikhonov    {       0x1c,     6,  54, },
376296d357SDmitri Tikhonov    {       0x1d,     6,  55, },
386296d357SDmitri Tikhonov    {       0x1e,     6,  56, },
396296d357SDmitri Tikhonov    {       0x1f,     6,  57, },
406296d357SDmitri Tikhonov    {       0x20,     6,  61, },
416296d357SDmitri Tikhonov    {       0x21,     6,  65, },
426296d357SDmitri Tikhonov    {       0x22,     6,  95, },
436296d357SDmitri Tikhonov    {       0x23,     6,  98, },
446296d357SDmitri Tikhonov    {       0x24,     6, 100, },
456296d357SDmitri Tikhonov    {       0x25,     6, 102, },
466296d357SDmitri Tikhonov    {       0x26,     6, 103, },
476296d357SDmitri Tikhonov    {       0x27,     6, 104, },
486296d357SDmitri Tikhonov    {       0x28,     6, 108, },
496296d357SDmitri Tikhonov    {       0x29,     6, 109, },
506296d357SDmitri Tikhonov    {       0x2a,     6, 110, },
516296d357SDmitri Tikhonov    {       0x2b,     6, 112, },
526296d357SDmitri Tikhonov    {       0x2c,     6, 114, },
536296d357SDmitri Tikhonov    {       0x2d,     6, 117, },
546296d357SDmitri Tikhonov    {       0x5c,     7,  58, },
556296d357SDmitri Tikhonov    {       0x5d,     7,  66, },
566296d357SDmitri Tikhonov    {       0x5e,     7,  67, },
576296d357SDmitri Tikhonov    {       0x5f,     7,  68, },
586296d357SDmitri Tikhonov    {       0x60,     7,  69, },
596296d357SDmitri Tikhonov    {       0x61,     7,  70, },
606296d357SDmitri Tikhonov    {       0x62,     7,  71, },
616296d357SDmitri Tikhonov    {       0x63,     7,  72, },
626296d357SDmitri Tikhonov    {       0x64,     7,  73, },
636296d357SDmitri Tikhonov    {       0x65,     7,  74, },
646296d357SDmitri Tikhonov    {       0x66,     7,  75, },
656296d357SDmitri Tikhonov    {       0x67,     7,  76, },
666296d357SDmitri Tikhonov    {       0x68,     7,  77, },
676296d357SDmitri Tikhonov    {       0x69,     7,  78, },
686296d357SDmitri Tikhonov    {       0x6a,     7,  79, },
696296d357SDmitri Tikhonov    {       0x6b,     7,  80, },
706296d357SDmitri Tikhonov    {       0x6c,     7,  81, },
716296d357SDmitri Tikhonov    {       0x6d,     7,  82, },
726296d357SDmitri Tikhonov    {       0x6e,     7,  83, },
736296d357SDmitri Tikhonov    {       0x6f,     7,  84, },
746296d357SDmitri Tikhonov    {       0x70,     7,  85, },
756296d357SDmitri Tikhonov    {       0x71,     7,  86, },
766296d357SDmitri Tikhonov    {       0x72,     7,  87, },
776296d357SDmitri Tikhonov    {       0x73,     7,  89, },
786296d357SDmitri Tikhonov    {       0x74,     7, 106, },
796296d357SDmitri Tikhonov    {       0x75,     7, 107, },
806296d357SDmitri Tikhonov    {       0x76,     7, 113, },
816296d357SDmitri Tikhonov    {       0x77,     7, 118, },
826296d357SDmitri Tikhonov    {       0x78,     7, 119, },
836296d357SDmitri Tikhonov    {       0x79,     7, 120, },
846296d357SDmitri Tikhonov    {       0x7a,     7, 121, },
856296d357SDmitri Tikhonov    {       0x7b,     7, 122, },
866296d357SDmitri Tikhonov    {       0xf8,     8,  38, },
876296d357SDmitri Tikhonov    {       0xf9,     8,  42, },
886296d357SDmitri Tikhonov    {       0xfa,     8,  44, },
896296d357SDmitri Tikhonov    {       0xfb,     8,  59, },
906296d357SDmitri Tikhonov    {       0xfc,     8,  88, },
916296d357SDmitri Tikhonov    {       0xfd,     8,  90, },
926296d357SDmitri Tikhonov    {      0x3f8,    10,  33, },
936296d357SDmitri Tikhonov    {      0x3f9,    10,  34, },
946296d357SDmitri Tikhonov    {      0x3fa,    10,  40, },
956296d357SDmitri Tikhonov    {      0x3fb,    10,  41, },
966296d357SDmitri Tikhonov    {      0x3fc,    10,  63, },
976296d357SDmitri Tikhonov    {      0x7fa,    11,  39, },
986296d357SDmitri Tikhonov    {      0x7fb,    11,  43, },
996296d357SDmitri Tikhonov    {      0x7fc,    11, 124, },
1006296d357SDmitri Tikhonov    {      0xffa,    12,  35, },
1016296d357SDmitri Tikhonov    {      0xffb,    12,  62, },
1026296d357SDmitri Tikhonov    {     0x1ff8,    13,   0, },
1036296d357SDmitri Tikhonov    {     0x1ff9,    13,  36, },
1046296d357SDmitri Tikhonov    {     0x1ffa,    13,  64, },
1056296d357SDmitri Tikhonov    {     0x1ffb,    13,  91, },
1066296d357SDmitri Tikhonov    {     0x1ffc,    13,  93, },
1076296d357SDmitri Tikhonov    {     0x1ffd,    13, 126, },
1086296d357SDmitri Tikhonov    {     0x3ffc,    14,  94, },
1096296d357SDmitri Tikhonov    {     0x3ffd,    14, 125, },
1106296d357SDmitri Tikhonov    {     0x7ffc,    15,  60, },
1116296d357SDmitri Tikhonov    {     0x7ffd,    15,  96, },
1126296d357SDmitri Tikhonov    {     0x7ffe,    15, 123, },
1136296d357SDmitri Tikhonov};
1146296d357SDmitri Tikhonov
1156296d357SDmitri Tikhonov
1166296d357SDmitri Tikhonovstatic void
1176296d357SDmitri Tikhonovgenerate_entry (uint16_t idx)
1186296d357SDmitri Tikhonov{
1196296d357SDmitri Tikhonov    unsigned int bits_left, n_outs;
1206296d357SDmitri Tikhonov    const struct el *el;
1216296d357SDmitri Tikhonov    uint8_t outs[3];
1226296d357SDmitri Tikhonov
1236296d357SDmitri Tikhonov    bits_left = 16;
1246296d357SDmitri Tikhonov    n_outs = 0;
1256296d357SDmitri Tikhonov    do
1266296d357SDmitri Tikhonov    {
1276296d357SDmitri Tikhonov        for (el = els; el < els + sizeof(els)
1286296d357SDmitri Tikhonov                        / sizeof(els[0]) && el->bits <= bits_left; ++el)
1296296d357SDmitri Tikhonov            if (el->code == (uint32_t) ((idx >> (bits_left - el->bits)) & ((1 << el->bits) - 1)))
1306296d357SDmitri Tikhonov                break;
1316296d357SDmitri Tikhonov        if (el >= els + sizeof(els) / sizeof(els[0]) || el->bits > bits_left)
1326296d357SDmitri Tikhonov            break;
1336296d357SDmitri Tikhonov        outs[n_outs++] = el->out;
1346296d357SDmitri Tikhonov        bits_left -= el->bits;
1356296d357SDmitri Tikhonov    }
1366296d357SDmitri Tikhonov    while (bits_left >= 5 /* shortest code */);
1376296d357SDmitri Tikhonov
1386296d357SDmitri Tikhonov    printf("/* %"PRIu16" */ ", idx);
1396296d357SDmitri Tikhonov    if (n_outs)
1406296d357SDmitri Tikhonov    {
1416296d357SDmitri Tikhonov        printf("{(%u<<2)|%u,{", 16 - bits_left, n_outs);
1426296d357SDmitri Tikhonov        switch (n_outs)
1436296d357SDmitri Tikhonov        {
1446296d357SDmitri Tikhonov        case 3:
1456296d357SDmitri Tikhonov            printf("%u,%u,%u", outs[0], outs[1], outs[2]);
1466296d357SDmitri Tikhonov            break;
1476296d357SDmitri Tikhonov        case 2:
1486296d357SDmitri Tikhonov            printf("%u,%u,0", outs[0], outs[1]);
1496296d357SDmitri Tikhonov            break;
1506296d357SDmitri Tikhonov        case 1:
1516296d357SDmitri Tikhonov            printf("%u,0,0", outs[0]);
1526296d357SDmitri Tikhonov            break;
1536296d357SDmitri Tikhonov        default:    exit(EXIT_FAILURE);
1546296d357SDmitri Tikhonov        }
1556296d357SDmitri Tikhonov        printf("}}");
1566296d357SDmitri Tikhonov    }
1576296d357SDmitri Tikhonov    else
1586296d357SDmitri Tikhonov        printf("{0,0,0,0,}");
1596296d357SDmitri Tikhonov    printf(",\n");
1606296d357SDmitri Tikhonov}
1616296d357SDmitri Tikhonov
1626296d357SDmitri Tikhonov
1636296d357SDmitri Tikhonovint
1646296d357SDmitri Tikhonovmain (void)
1656296d357SDmitri Tikhonov{
1666296d357SDmitri Tikhonov    unsigned idx;
1676296d357SDmitri Tikhonov
1686296d357SDmitri Tikhonov    printf("static const struct hdec { uint8_t lens; uint8_t out[3]; } "
1696296d357SDmitri Tikhonov                                                            "hdecs[] =\n{\n");
1706296d357SDmitri Tikhonov    for (idx = 0; idx <= UINT16_MAX; ++idx)
1716296d357SDmitri Tikhonov        generate_entry(idx);
1726296d357SDmitri Tikhonov    printf("};\n");
1736296d357SDmitri Tikhonov
1746296d357SDmitri Tikhonov    return 0;
1756296d357SDmitri Tikhonov}
176