2 * Copyright 2010-2012 Chris Spiegel.
4 * This file is part of Bocfel.
6 * Bocfel is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version
8 * 2 or 3, as published by the Free Software Foundation.
10 * Bocfel is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Bocfel. If not, see <http://www.gnu.org/licenses/>.
30 struct zterp_iff *iff;
33 zterp_blorb_chunk *chunks;
36 struct zterp_blorb *zterp_blorb_parse(zterp_io *io)
41 struct zterp_blorb *blorb = NULL;
43 iff = zterp_iff_parse(io, "IFRS");
44 if(!zterp_iff_find(iff, "RIdx", &size)) goto err;
47 if(!zterp_io_read32(io, &nresources)) goto err;
49 if((nresources * 12) + 4 != size) goto err;
51 blorb = malloc(sizeof *blorb);
52 if(blorb == NULL) goto err;
58 for(uint32_t i = 0; i < nresources; i++)
60 uint32_t usage, number, start, type;
61 zterp_blorb_chunk *new;
65 if(!zterp_io_read32(io, &usage) || !zterp_io_read32(io, &number) || !zterp_io_read32(io, &start)) goto err;
67 if(usage != BLORB_PICT && usage != BLORB_SND && usage != BLORB_EXEC) goto err;
69 saved = zterp_io_tell(io);
70 if(saved == -1) goto err;
72 if(zterp_io_seek(io, start, SEEK_SET) == -1) goto err;
74 if(!zterp_io_read32(io, &type) || !zterp_io_read32(io, &size)) goto err;
76 if(zterp_io_seek(io, saved, SEEK_SET) == -1) goto err;
78 if(type == STRID("FORM"))
84 /* Not really efficient, but does it matter? */
85 new = realloc(blorb->chunks, sizeof *new * ++blorb->nchunks);
86 if(new == NULL) goto err;
89 idx = blorb->nchunks - 1;
91 new[idx].usage = usage;
92 new[idx].number = number;
94 memcpy(new[idx].name, IDSTR(type), 5);
95 new[idx].offset = start + 8;
102 zterp_blorb_free(blorb);
107 void zterp_blorb_free(struct zterp_blorb *blorb)
109 if(blorb != NULL) free(blorb->chunks);
113 const zterp_blorb_chunk *zterp_blorb_find(struct zterp_blorb *blorb, uint32_t usage, int number)
115 for(size_t i = 0; i < blorb->nchunks; i++)
117 if(blorb->chunks[i].usage == usage && blorb->chunks[i].number == number) return &blorb->chunks[i];