+
+ // Generate the lookup tables
+ for (unsigned i = 0; i < DEHUF_TABLE_SIZE; ++i) {
+ tbl->lookup_table_codes[i] = DEHUF_SLOW_PATH;
+ tbl->lookup_table_length[i] = DEHUF_SLOW_PATH;
+ }
+
+ unsigned k = 0;
+ for (unsigned i = 0; i < 16; ++i) {
+ for (unsigned j = 0; j < tbl->num_codes[i]; ++j, ++k) {
+ const unsigned code = tbl->huffcode[k];
+ const unsigned length = tbl->huffsize[k];
+ if (length > DEHUF_TABLE_BITS) {
+ continue;
+ }
+ const unsigned prefix_min = code << (DEHUF_TABLE_BITS - length);
+ const unsigned prefix_max = ((code + 1) << (DEHUF_TABLE_BITS - length));
+
+ for (unsigned elem = prefix_min; elem < prefix_max; ++elem) {
+ assert(tbl->lookup_table_codes[elem] == DEHUF_SLOW_PATH);
+ assert(tbl->lookup_table_length[elem] == DEHUF_SLOW_PATH);
+ tbl->lookup_table_codes[elem] = tbl->codes[k];
+ tbl->lookup_table_length[elem] = length;
+ }
+ }
+ }
+
+ // Generate the AC lookup tables.
+ for (unsigned i = 0; i < DEHUF_AC_TABLE_SIZE; ++i) {
+ tbl->ac_table_codes[i] = AC_DEHUF_SLOW_PATH;
+
+ int lookup = i >> (DEHUF_AC_TABLE_BITS - DEHUF_TABLE_BITS);
+ int rs = tbl->lookup_table_codes[lookup];
+ unsigned length = tbl->lookup_table_length[lookup];
+ if (rs == DEHUF_SLOW_PATH) {
+ // Not enough bits to decode even the length.
+ continue;
+ }
+ if (rs == 0x00) {
+ // End of block.
+ tbl->ac_table_codes[i] = 0;
+ tbl->ac_table_length[i] = length;
+ tbl->ac_table_skip[i] = 64;
+ continue;
+ }
+ if (rs == 0xf0) {
+ // 16 zero coefficients.
+ tbl->ac_table_codes[i] = 0;
+ tbl->ac_table_length[i] = length;
+ tbl->ac_table_skip[i] = 16;
+ continue;
+ }
+
+ unsigned r = rs >> 4;
+ unsigned s = rs & 0xf;
+ if (s > DEHUF_AC_TABLE_BITS - length) {
+ // Not enough bits to decode this coefficient.
+ continue;
+ }
+
+ unsigned bits = (i >> (DEHUF_AC_TABLE_BITS - length - s)) & ((1 << s) - 1);
+
+ tbl->ac_table_codes[i] = extend(bits, s);
+ tbl->ac_table_length[i] = length + s;
+ tbl->ac_table_skip[i] = r + 1;
+
+ assert(tbl->ac_table_length[i] <= DEHUF_AC_TABLE_BITS);
+ }