]> git.draconx.ca Git - liblbx.git/blob - src/image.c
Start adding image support to liblbx.
[liblbx.git] / src / image.c
1 #ifdef HAVE_CONFIG_H
2 #       include "config.h"
3 #endif
4
5 #include <stdlib.h>
6 #include <stdint.h>
7 #include <assert.h>
8 #include <errno.h>
9
10 #include "lbx.h"
11 #include "byteorder.h"
12
13 struct lbx_image {
14         FILE *f;
15         uint16_t width, height;
16         uint16_t wtf1, wtf2;
17         uint16_t offs, frames;
18         uint32_t offsets[];
19 };
20
21 struct lbx_image *lbximg_fopen(FILE *f)
22 {
23         struct lbx_image tmp = {.f = f}, *new;
24
25         if (fread(&tmp.width,  sizeof tmp.width,   1, f) != 1) goto readerr;
26         if (fread(&tmp.height, sizeof tmp.height,  1, f) != 1) goto readerr;
27         if (fread(&tmp.wtf1,   sizeof tmp.wtf1,    1, f) != 1) goto readerr;
28         if (fread(&tmp.offs,   sizeof tmp.offs,    1, f) != 1) goto readerr;
29         if (fread(&tmp.frames, sizeof tmp.frames,  1, f) != 1) goto readerr;
30         if (fread(&tmp.wtf2,   sizeof tmp.wtf2,    1, f) != 1) goto readerr;
31
32         tmp.width  = letohs(tmp.width);
33         tmp.height = letohs(tmp.height);
34         tmp.wtf1   = letohs(tmp.wtf1);
35         tmp.offs   = letohs(tmp.offs);
36         tmp.frames = letohs(tmp.frames);
37         tmp.wtf2   = letohs(tmp.wtf2);
38
39         /*
40          * DEBUG ONLY.  These assertions exist to catch otherwise valid image
41          * files which differ from what I believe to be true of all LBX images.
42          * If we never find any exceptions, we can replace the assertions with
43          * assumptions.
44          */
45         assert(tmp.wtf1 == 0);
46         assert(tmp.offs == tmp.frames + 1);
47
48         new = malloc(sizeof *new + tmp.offs * sizeof *new->offsets);
49         if (!new) {
50                 lbx_errno = -errno;
51                 return NULL;
52         }
53
54         *new = tmp;
55
56         if (fread(new->offsets, sizeof *new->offsets, new->offs, f) != new->offs)
57                 goto readerr;
58
59         return new;
60 readerr:
61         if (feof(f)) {
62                 lbx_errno = LBX_EEOF;
63         } else {
64                 lbx_errno = -errno;
65         }
66
67         free(new);
68         return NULL;
69 }
70
71 void lbximg_close(struct lbx_image *img)
72 {
73         if (!img) return;
74
75         if (img->f) {
76                 fclose(img->f);
77         }
78
79         free(img);
80 }