#include <stdlib.h>
#include <assert.h>
+#include "bytesource.h"
#include "dehuff.h"
+#include "input.h"
-void reliable_read(raw_input_func_t* input_func, void* userdata, uint8_t* buf, size_t len)
+void read_huffman_tables(huffman_tables_t* dst, input_func_t* input_func, void* userdata)
{
- while (len > 0) {
- ssize_t bytes_read = input_func(userdata, buf, len);
- assert(bytes_read <= len);
-
- // TODO: We need better error handling here. setjmp()/longjmp()
- // should hopefully do the trick, but we need to take care for
- // suspension.
- if (bytes_read == (ssize_t)-1) {
- fprintf(stderr, "Input function returned error\n");
- exit(1);
- }
- if (bytes_read == 0) {
- fprintf(stderr, "Premature EOF\n");
- exit(1);
- }
-
- buf += bytes_read;
- len -= bytes_read;
- }
-}
-
-uint16_t read_length(raw_input_func_t* input_func, void* userdata)
-{
- uint8_t buf[2];
- reliable_read(input_func, userdata, buf, 2);
- return (buf[0] << 8) | buf[1];
-}
-
-void read_huffman_tables(huffman_tables_t* dst, raw_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;
exit(1);
}
- struct huffman_table* tbl = dst[table_class][table_dest];
+ struct huffman_table* tbl = &((*dst)[table_class][table_dest]);
if (len < 16) {
fprintf(stderr, "Short read for num_codes\n");
exit(1);
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;
}
}
unsigned code = read_bits(source, 1);
int i = 0;
- while (code > table->maxcode[i] || table->maxcode[i] == -1) {
+ while (table->maxcode[i] == -1 || code > (unsigned)table->maxcode[i]) {
possibly_refill(source, 1);
code = (code << 1) | read_bits(source, 1);
++i;