-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathheader.c
83 lines (70 loc) · 2.96 KB
/
header.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <stdlib.h>
#include <string.h>
#include "header.h"
#include "constant.h"
#include "tool.h"
void read_gif_header(BinData *bytesp, GIFHeader *hp) {
int i;
unsigned char bits;
for (i = 0; i < 3; ++i) {
hp->signature[i] = bytesp->buf[bytesp->idx++];
}
hp->signature[3] = '\0';
if (strcmp(hp->signature, "GIF") != 0) die("[ERROR] not supported file");
for (i = 0; i < 3; ++i) {
hp->version[i] = bytesp->buf[bytesp->idx++];
}
hp->version[3] = '\0';
if (strcmp(hp->version, "89a") != 0 && strcmp(hp->version, "87a") != 0) {
die("[ERROR] not supported gif version: %s", hp->version);
}
hp->logical_screen_width = extract_data(&bytesp->buf[bytesp->idx], 2);
bytesp->idx += 2;
if (hp->logical_screen_width < GIF_LGTM_IMG_WIDTH) {
die("[ERROR] not supported size of width (>= %d)", GIF_LGTM_IMG_WIDTH);
}
hp->logical_screen_height = extract_data(&bytesp->buf[bytesp->idx], 2);
bytesp->idx += 2;
if (hp->logical_screen_height < GIF_LGTM_IMG_HEIGHT) {
die("[ERROR] not supported size of height (>= %d)", GIF_LGTM_IMG_HEIGHT);
}
bits = bytesp->buf[bytesp->idx++];
hp->global_color_table_flag = (bits & (1 << 7)) >> 7;
hp->color_resolution = ((bits & ((1 << 6) | (1 << 5) | (1 << 4))) >> 4) + 1;
hp->sort_flag = (bits & (1 << 3)) >> 3;
hp->size_of_global_color_table = 1 << ((bits & ((1 << 2) | (1 << 1) | 1)) + 1);
hp->background_color_index = bytesp->buf[bytesp->idx++];
hp->pixel_aspect_ratio = bytesp->buf[bytesp->idx++];
if (hp->global_color_table_flag) {
hp->global_color_table = (unsigned int *) malloc(sizeof(unsigned int) * hp->size_of_global_color_table);
if (hp->global_color_table == NULL) {
die("[ERROR] could not allocate memory for global color table of gif header");
}
for (i = 0; i < hp->size_of_global_color_table; ++i) {
hp->global_color_table[i] = extract_data(&bytesp->buf[bytesp->idx], 3);
bytesp->idx += 3;
}
}
}
void write_gif_header(FILE *fp, const GIFHeader *hp) {
fprintf(fp, "Headers\n");
fprintf(fp, " Signature: %s\n", hp->signature);
fprintf(fp, " Version: %s\n", hp->version);
fprintf(fp, " Logical Screen Width: %u\n", hp->logical_screen_width);
fprintf(fp, " Logical Screen Height: %u\n", hp->logical_screen_height);
fprintf(fp, " Global Color Table Flag: %u\n", hp->global_color_table_flag);
fprintf(fp, " Color Resolution: %u\n", hp->color_resolution);
fprintf(fp, " Sort Flag: %u\n", hp->sort_flag);
fprintf(fp, " Size of Global Color Table: %u\n", hp->size_of_global_color_table);
fprintf(fp, " Background Color Index: %u\n", hp->background_color_index);
fprintf(fp, " Pixel Aspect Ratio: %u\n", hp->pixel_aspect_ratio);
if (hp->global_color_table_flag) {
print_color_table(fp,
hp->size_of_global_color_table,
hp->global_color_table,
"Global Color Table");
}
}
void free_gif_header(GIFHeader *hp) {
if (hp->global_color_table_flag) free(hp->global_color_table);
}