/*
* 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
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;
.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,
/*
* 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 */
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)
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);
.width = img->width,
.height = img->height,
.nframes = img->frames,
+ .chunk = img->chunk,
.palettesz = (img->flags & FLAG_PALETTE) ? img->palcount : 0,
};