Initial commit
[aaf.git] / aaf.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdint.h>
5 #include <assert.h>
6 #include <endian.h>
7
8 #include "aaf.h"
9
10 int read_aaf(FILE * in, struct aaf * _aaf)
11 {
12         size_t elements = 0;
13         int i;
14         
15         assert(in != NULL);
16         assert(_aaf != NULL);
17
18         elements = fread(_aaf, sizeof(struct aaf), 1, in);
19         if (elements == 0) {
20                 perror("Unable to correctly read input file");
21                 return 1;
22         }
23
24         if (strncmp("AAFF", _aaf->signature, 4) != 0) {
25                 fprintf(stderr, "Invalid sigature of input file\n");
26                 return 2;
27         }
28
29         _aaf->max_h = be16toh(_aaf->max_h);
30         _aaf->gap_h = be16toh(_aaf->gap_h);
31         _aaf->space_width = be16toh(_aaf->space_width);
32         _aaf->gap_v = be16toh(_aaf->gap_v);
33         
34         for (i = 0; i < AAF_GLYPH_MAX; i++) {
35                 _aaf->glyphs[i].w = be16toh(_aaf->glyphs[i].w);
36                 _aaf->glyphs[i].h = be16toh(_aaf->glyphs[i].h);
37                 _aaf->glyphs[i].off = be32toh(_aaf->glyphs[i].off);
38         }
39
40         return 0;
41 }
42
43 void free_aaf_glyph_data(struct aaf_glyph_data ** data)
44 {
45         int i;
46
47         assert(data);
48
49         for (i = 0; i < AAF_GLYPH_MAX; i++) {
50                 if (data[i]) {
51                         free(data[i]->pixels);
52                         free(data[i]);
53                         data[i] = NULL;
54                 }
55         }
56
57         free(data);
58         data = NULL;
59 }
60
61 struct aaf_glyph_data ** read_aaf_glyph_data(FILE * in, struct aaf * _aaf)
62 {
63         struct aaf_glyph_data ** data = NULL;
64         long offset;
65         int i;
66
67         assert(in != NULL);
68         assert(_aaf != NULL);
69         
70         offset = ftell(in);
71
72         data = malloc(sizeof(struct aaf_glyph_data*) * AAF_GLYPH_MAX);
73         
74         for (i = 0; i < AAF_GLYPH_MAX; i++) {
75                 const struct aaf_glyph * glyph = &(_aaf->glyphs[i]);
76
77                 data[i] = NULL;
78                 
79                 if ((glyph->w * glyph->h) == 0) {
80                         continue;
81                 }
82
83                 data[i] = malloc(sizeof(struct aaf_glyph_data));
84                 if (data[i] == NULL) {
85                         perror("Unable to allocate memory for glyph data");
86                         free_aaf_glyph_data(data);
87                         fseek(in, offset, SEEK_SET);
88                         return NULL;
89                 }
90
91                 data[i]->pixels = malloc(sizeof(uint8_t) * glyph->w * glyph->h);
92                 if (data[i]->pixels == NULL) {
93                         perror("Unable to allocate memory for glyph pixel data");
94                         free_aaf_glyph_data(data);
95                         fseek(in, offset, SEEK_SET);
96                         return NULL;
97                 }
98                 
99                 fseek(in, sizeof(struct aaf) + glyph->off, SEEK_SET);
100                 fread(data[i]->pixels, sizeof(uint8_t), glyph->w * glyph->h, in);
101         }
102
103         fseek(in, offset, SEEK_SET);
104
105         return data;
106 }
107
108 int write_aaf_glyph_as_pgm(FILE * out, const struct aaf_glyph * glyph, const struct aaf_glyph_data * data)
109 {
110         int w = 0;
111         int h = 0;
112         int error = 0;
113
114         assert(out != NULL);
115         assert(glyph != NULL);
116         assert(data != NULL);
117
118         error = fprintf(out, "%s\n%d %d\n%d\n",
119                 "P2",
120                 glyph->w,
121                 glyph->h,
122                 9
123         );
124
125         if (error < 0) {
126                 perror("Unable to write PGM header");
127                 return error;
128         }
129
130         for (h = 0; h < glyph->h; h++) {
131                 for (w = 0; w < glyph->w; w++) {
132                         error = fprintf(out, "%d",
133                                 data->pixels[h * glyph->w + w]
134                         );
135                         
136                         if (error < 0) {
137                                 perror("Unabe to write PGM image data");
138                                 return error;
139                         }
140
141                         if (w + 1 < glyph->w) {
142                                 fputc(' ', out);
143                         }
144                 }
145
146                 fputc('\n', out);
147         }
148
149         return 0;
150 }