Skip to content

Commit 6664327

Browse files
committed
add main source file for decoder
1 parent 350bc57 commit 6664327

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

decoder.c

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* decoder.c
3+
* @date 2016-02-03
4+
* @author Fabjan Sukalia <[email protected]>
5+
* @brief Tool to decode huffman encoded data in JPEG format
6+
*/
7+
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <string.h>
10+
#include <errno.h>
11+
#include <stdint.h>
12+
#include "bit_reader.h"
13+
#include "huff_dec.h"
14+
15+
#define JPG_DHT (0xC4)
16+
17+
static const char *prog_name = "hufdec";
18+
19+
void usage(void)
20+
{
21+
fprintf(stderr, "USAGE: %s FILE_IN FILE_OUT\n", prog_name);
22+
exit(EXIT_FAILURE);
23+
}
24+
25+
26+
void decode(FILE *in, FILE *out)
27+
{
28+
uint8_t header[21];
29+
if (fread(header, sizeof(header), 1, in) != 1) {
30+
fprintf(stderr, "Couldn't read header\n");
31+
exit(EXIT_FAILURE);
32+
}
33+
34+
if (header[0] != 0xFF || header[1] != JPG_DHT) {
35+
fprintf(stderr, "Invalid header\n");
36+
exit(EXIT_FAILURE);
37+
}
38+
39+
uint16_t header_length = (header[2] << 8) | header[3];
40+
if (header_length < 19 || header_length > (19 + 256)) {
41+
fprintf(stderr, "Invalid header length\n");
42+
exit(EXIT_FAILURE);
43+
}
44+
45+
/* table class and destination index - must be zero */
46+
if (header[4] != 0) {
47+
fprintf(stderr, "Invalid table class and destination index\n");
48+
exit(EXIT_FAILURE);
49+
}
50+
51+
uint16_t sum_symbol = 0;
52+
for (int i = 0; i < 16; i++)
53+
sum_symbol += header[5 + i];
54+
55+
if (sum_symbol == 0 || header_length == 19)
56+
return; /* nothing to do */
57+
58+
uint8_t symbols[sum_symbol];
59+
if (fread(symbols, sizeof(symbols), 1, in) != 1) {
60+
fprintf(stderr, "Couldn't read symbol table\n");
61+
exit(EXIT_FAILURE);
62+
}
63+
64+
/* how many bytes for the output or how many symbols to read */
65+
uint8_t tmp[sizeof(uint32_t)];
66+
if (fread(tmp, sizeof(uint32_t), 1, in) != 1) {
67+
fprintf(stderr, "Couldn't read number of data\n");
68+
exit(EXIT_FAILURE);
69+
}
70+
71+
uint32_t num_sym = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
72+
73+
struct huff_dec *dec = huff_gen_dec(&header[5], symbols);
74+
struct bit_reader *reader = bit_reader_create(in);
75+
76+
huff_decode_all(dec, reader, out, num_sym);
77+
78+
bit_reader_destroy(reader);
79+
huff_destroy(dec);
80+
}
81+
82+
int main(int argc, char *argv[])
83+
{
84+
errno = 0;
85+
86+
if (argc > 1)
87+
prog_name = argv[0];
88+
89+
if (argc != 3)
90+
usage();
91+
92+
FILE *in = fopen(argv[1], "rb");
93+
if (in == NULL) {
94+
perror("Couldn't open input file");
95+
return EXIT_FAILURE;
96+
}
97+
98+
FILE *out = fopen(argv[2], "wb");
99+
if (out == NULL) {
100+
perror("Couldn't open output file");
101+
return EXIT_FAILURE;
102+
}
103+
104+
decode(in, out);
105+
106+
107+
fclose(in);
108+
fclose(out);
109+
110+
return 0;
111+
}
112+

0 commit comments

Comments
 (0)