Port some table-generating stuff from unjpeg.
[fjl] / dehuff_test.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4
5 #include "dehuff.h"
6
7 struct custom_read_userdata {
8         uint8_t* bytes;
9         unsigned bytes_left;
10 };
11
12 ssize_t custom_read(void* userdata, uint8_t* buf, size_t count)
13 {
14         struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata;
15         size_t num_to_read = (ud->bytes_left > count ? count : ud->bytes_left);
16         memcpy(buf, ud->bytes, num_to_read);
17         ud->bytes += num_to_read;
18         ud->bytes_left -= num_to_read;
19         return num_to_read;     
20 }
21
22 // Uses the example from section K.3.1 from the JPEG standard.
23 void test_table_gen()
24 {
25         uint8_t bytes[] = {
26                 // Chunk length: Chunk length (2) + coefficient class (1) + 
27                 // code lengths (16) + code words (12)
28                 0, 31, 
29
30                 // DC coefficient, table 0
31                 0x00,
32
33                 // List of code lengths
34                 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35
36                 // Code words
37                 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
38         };
39
40         // Expected results (table K.3)
41         struct {
42                 unsigned code_length;
43                 unsigned code_word;
44         } expected_table[12] = {
45                 { 2, 0x0 },
46                 { 3, 0x2 },
47                 { 3, 0x3 },
48                 { 3, 0x4 },
49                 { 3, 0x5 },
50                 { 3, 0x6 },
51                 { 4, 0xe },
52                 { 5, 0x1e },
53                 { 6, 0x3e },
54                 { 7, 0x7e },
55                 { 8, 0xfe },
56                 { 9, 0x1fe },
57         };
58
59         struct custom_read_userdata ud;
60         ud.bytes = bytes;
61         ud.bytes_left = sizeof(bytes);
62
63         huffman_tables_t tables;
64         read_huffman_tables(&tables, custom_read, &ud);
65                 
66         struct huffman_table* tbl = &tables[DC_CLASS][0];       
67         for (unsigned i = 0; i < 12; ++i) {
68                 assert(tbl->huffsize[i] == expected_table[i].code_length);
69                 assert(tbl->huffcode[i] == expected_table[i].code_word);
70         }
71 }
72
73 int main(void)
74 {
75         printf("test_table_gen()\n");
76         test_table_gen();
77         
78         printf("All tests pass.\n");
79         return 0;
80 }