void read_huffman_tables(huffman_tables_t* dst, input_func_t* input_func, void* userdata)
{
- size_t len = read_length(input_func, userdata);
+ size_t len = read_uint16(input_func, userdata);
assert(len > 2);
len -= 2;
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] = k;
+ 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);
+ }
}
free(buf);