X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Fbocfel%2Fiff.c;fp=interpreters%2Fbocfel%2Fiff.c;h=e7fe4e15ee843879276dbd0249ace2af118b1173;hb=3c59ba5eef5cb4d39c06eb7f523b9c3b026bdc9b;hp=0000000000000000000000000000000000000000;hpb=ed91d840318ed6ebfe3a5a77fa17114ddbf56640;p=projects%2Fchimara%2Fchimara.git diff --git a/interpreters/bocfel/iff.c b/interpreters/bocfel/iff.c new file mode 100644 index 0000000..e7fe4e1 --- /dev/null +++ b/interpreters/bocfel/iff.c @@ -0,0 +1,112 @@ +/*- + * Copyright 2010-2012 Chris Spiegel. + * + * This file is part of Bocfel. + * + * Bocfel is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version + * 2 or 3, as published by the Free Software Foundation. + * + * Bocfel is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bocfel. If not, see . + */ + +#include +#include +#include + +#include "iff.h" +#include "io.h" + +struct zterp_iff +{ + zterp_io *io; + uint32_t tag; + long offset; + uint32_t size; + + struct zterp_iff *next; +}; + +void zterp_iff_free(zterp_iff *iff) +{ + while(iff != NULL) + { + zterp_iff *tmp = iff->next; + free(iff); + iff = tmp; + } +} + +zterp_iff *zterp_iff_parse(zterp_io *io, const char type[4]) +{ + uint32_t tag; + + zterp_iff *iff = NULL, *tail = NULL; + + if(zterp_io_seek(io, 0, SEEK_SET) == -1) goto err; + + if(!zterp_io_read32(io, &tag) || tag != STRID("FORM")) goto err; + + if(zterp_io_seek(io, 4, SEEK_CUR) == -1) goto err; + + if(!zterp_io_read32(io, &tag) || tag != STRID(type)) goto err; + + while(zterp_io_read32(io, &tag)) + { + uint32_t size; + zterp_iff *new; + + if(!zterp_io_read32(io, &size)) goto err; + + new = malloc(sizeof *new); + if(new == NULL) goto err; + + new->tag = tag; + new->io = io; + new->offset = zterp_io_tell(io); + new->size = size; + new->next = NULL; + + if(iff == NULL) iff = new; + else tail->next = new; + + tail = new; + + if(new->offset == -1) goto err; + + if(size & 1) size++; + + if(zterp_io_seek(io, size, SEEK_CUR) == -1) goto err; + } + + return iff; + +err: + zterp_iff_free(iff); + + return NULL; +} + +int zterp_iff_find(zterp_iff *iff, const char tag[4], uint32_t *size) +{ + while(iff != NULL) + { + if(iff->tag == STRID(tag)) + { + if(zterp_io_seek(iff->io, iff->offset, SEEK_SET) == -1) return 0; + *size = iff->size; + + return 1; + } + + iff = iff->next; + } + + return 0; +}