X-Git-Url: https://git.draconx.ca/gitweb/liblbx.git/blobdiff_plain/bdad20799885211ac4c76bdaef5b027552d6241d..f8295b32a98df79caee16a25a1dcf3a7a678e409:/src/image.c diff --git a/src/image.c b/src/image.c index 21f5a8e..cc8d54b 100644 --- a/src/image.c +++ b/src/image.c @@ -1,7 +1,7 @@ /* * 2ooM: The Master of Orion II Reverse Engineering Project * Library for working with LBX image files. - * Copyright (C) 2006-2008 Nick Bowler + * Copyright (C) 2006-2010 Nick Bowler * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,7 +43,7 @@ struct lbx_image { unsigned short width, height; unsigned short wtf, flags; - unsigned short frames, leadin; + unsigned char frames, wtf2, leadin, chunk; unsigned short palstart, palcount; const struct lbx_file_ops *fops; @@ -75,8 +75,10 @@ static struct lbx_image *lbximg_init(unsigned char hdr[static HDR_LEN]) .width = unpack_16_le(hdr+0), .height = unpack_16_le(hdr+2), .wtf = unpack_16_le(hdr+4), - .frames = unpack_16_le(hdr+6), - .leadin = unpack_16_le(hdr+8), + .frames = hdr[6], + .wtf2 = hdr[7], + .leadin = hdr[8], + .chunk = hdr[9], .flags = unpack_16_le(hdr+10), .currentframe = -1, @@ -109,11 +111,12 @@ struct lbx_image *lbximg_open(void *f, const struct lbx_file_ops *fops, /* * DEBUG ONLY. These assertions exist to catch otherwise valid image * files which differ from what I believe to be true of all LBX images. - * If we never find any exceptions, we can replace the assertions with - * assumptions. + * When we can decode every image, then these assertions should be + * replaced with constraints. */ - _lbx_assert(img->wtf == 0); /* version? */ - _lbx_assert(img->frames > img->leadin); /* cmbtshp.lbx breaks this. */ + _lbx_assert(img->wtf == 0); /* version? */ + _lbx_assert(img->wtf2 == 0); /* very likely is simply reserved. */ + _lbx_assert(img->frames > img->leadin); _lbx_assert(!(img->flags & ~FLAG_ALL)); /* Read all offsets. Should be merged with identical code in lbx.c */ @@ -156,9 +159,41 @@ struct lbx_image *lbximg_open(void *f, const struct lbx_file_ops *fops, return img; } -struct lbx_image *lbximg_fopen(FILE *f) +static int pipe_close(void *f) { - return lbximg_open(f, &lbx_default_fops, NULL); + struct lbx_pipe_state *p = f; + int rc; + + rc = fclose(p->f); + free(p); + return rc; +} + +static int file_close(void *f) +{ + return fclose((FILE *)f); +} + +struct lbx_image *lbximg_fopen(const char *file) +{ + struct lbx_pipe_state *p; + FILE *f; + + f = fopen(file, "rb"); + if (!f) + return NULL; + + if (fseek(f, 0, SEEK_CUR) == 0) + return lbximg_open(f, &lbx_default_fops, file_close); + + p = malloc(sizeof *p); + if (!p) { + fclose(f); + return NULL; + } + + *p = (struct lbx_pipe_state) { .f = f }; + return lbximg_open(p, &lbx_pipe_fops, pipe_close); } static int _lbx_drawrow(int first, struct lbx_image *img) @@ -315,7 +350,8 @@ unsigned char **lbximg_getframe(struct lbx_image *img, int frame) if (img->flags & FLAG_RAW) return read_raw_frame(img, frame); - if (img->flags & FLAG_OVERWRITE) { + if ((img->flags & FLAG_OVERWRITE) + || (img->chunk && !(frame % img->chunk))) { /* Clear the slate. */ img->currentframe = -1; memset(img->framedata[0], 0, img->width * img->height); @@ -435,6 +471,7 @@ void lbximg_getinfo(struct lbx_image *img, struct lbx_imginfo *info) .width = img->width, .height = img->height, .nframes = img->frames, + .chunk = img->chunk, .palettesz = (img->flags & FLAG_PALETTE) ? img->palcount : 0, };