--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "dehuff.h"
+
+struct custom_read_userdata {
+ uint8_t* bytes;
+ unsigned bytes_left;
+};
+
+ssize_t custom_read(void* userdata, uint8_t* buf, size_t count)
+{
+ struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata;
+ size_t num_to_read = (ud->bytes_left > count ? count : ud->bytes_left);
+ memcpy(buf, ud->bytes, num_to_read);
+ ud->bytes += num_to_read;
+ ud->bytes_left -= num_to_read;
+ return num_to_read;
+}
+
+// Uses the example from section K.3.1 from the JPEG standard.
+void test_table_gen()
+{
+ uint8_t bytes[] = {
+ // Chunk length: Chunk length (2) + coefficient class (1) +
+ // code lengths (16) + code words (12)
+ 0, 31,
+
+ // DC coefficient, table 0
+ 0x00,
+
+ // List of code lengths
+ 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ // Code words
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ };
+
+ // Expected results (table K.3)
+ struct {
+ unsigned code_length;
+ unsigned code_word;
+ } expected_table[12] = {
+ { 2, 0x0 },
+ { 3, 0x2 },
+ { 3, 0x3 },
+ { 3, 0x4 },
+ { 3, 0x5 },
+ { 3, 0x6 },
+ { 4, 0xe },
+ { 5, 0x1e },
+ { 6, 0x3e },
+ { 7, 0x7e },
+ { 8, 0xfe },
+ { 9, 0x1fe },
+ };
+
+ struct custom_read_userdata ud;
+ ud.bytes = bytes;
+ ud.bytes_left = sizeof(bytes);
+
+ huffman_tables_t tables;
+ read_huffman_tables(&tables, custom_read, &ud);
+
+ struct huffman_table* tbl = &tables[DC_CLASS][0];
+ for (unsigned i = 0; i < 12; ++i) {
+ assert(tbl->huffsize[i] == expected_table[i].code_length);
+ assert(tbl->huffcode[i] == expected_table[i].code_word);
+ }
+}
+
+int main(void)
+{
+ printf("test_table_gen()\n");
+ test_table_gen();
+
+ printf("All tests pass.\n");
+ return 0;
+}