give source files a directory of their own
[blorb-thumbnailer.git] / src / minblorb.c
blob8c978a9fea3b448f7b5b2fdcb1754b2ec4fc7889
1 /* minblorb.c: only those portions of the blorb spec needed for cover art
3 Copyright 2011 Lewis Gentry.
5 This program is free software: you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation, either version 3 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <stdio.h>
19 #include <string.h>
21 /* File format reference: <http://www.eblong.com/zarf/blorb/>. */
23 /* Important offsets: */
25 #define RESOURCE_INDEX 0x0C /* Beginning of resource index. */
26 #define RESOURCE_COUNT 0x14 /* Number of resources. */
28 /* Does this file look like a blorb? */
30 int verify(FILE *blorb)
32 char signature[12];
34 rewind(blorb);
35 return fread(signature, sizeof(char), 12, blorb) == 12
36 && memcmp(signature + 0, "FORM", 4) == 0
37 && memcmp(signature + 8, "IFRS", 4) == 0;
40 /* Convert a four-byte word (big-endian) to an integer. */
42 unsigned int int32_read(unsigned char *word)
44 return word[0] * 16777216 + word[1] * 65536 + word[2] * 256 + word[3];
47 /* As above, but rounded up to an even number per the IFF spec. */
49 unsigned int int32_padded(unsigned char *word)
51 unsigned int i;
53 i = int32_read(word);
54 return i % 2 ? i + 1 : i;
57 /* Does the stream contain a frontispiece chunk? If so, store its
58 resource number in the provided pointer. */
60 int fspc(FILE *blorb, unsigned int *resource)
62 unsigned char buffer[8] = { 0, 0, 0, 0, 0, 0, 0, RESOURCE_INDEX };
63 unsigned char target[4];
65 rewind(blorb);
66 while (fseek(blorb, int32_padded(buffer + 4), SEEK_CUR) == 0
67 && fread(buffer, sizeof(char), 8, blorb) == 8) {
68 if (memcmp(buffer, "Fspc", 4) == 0
69 && fread(target, sizeof(char), 4, blorb) == 4) {
70 *resource = int32_read(target);
71 return 1;
74 return 0;
77 /* Does the picture with this resource number exist? If so, return its
78 address. */
80 unsigned int findpict(FILE *blorb, unsigned int id)
82 unsigned char buffer[12];
83 int resources;
85 if (fseek(blorb, RESOURCE_COUNT, SEEK_SET) == 0
86 && fread(buffer, sizeof(char), 4, blorb) == 4) {
87 resources = int32_read(buffer);
88 while (resources-- && fread(buffer, sizeof(char), 12, blorb) == 12)
89 if (memcmp(buffer, "Pict", 4) == 0 && int32_read(buffer + 4) == id)
90 return int32_read(buffer + 8);
92 return 0;
95 /* How long is the chunk at this offset? (As a useful side effect, the
96 stream is now positioned at the beginning of the chunk data.) */
98 unsigned int chunklength(FILE *blorb, unsigned int offset)
100 unsigned char buffer[8];
102 return fseek(blorb, offset, SEEK_SET) == 0
103 && fread(buffer, sizeof(char), 8, blorb) == 8
104 ? int32_read(buffer + 4) : 0;