]> git.draconx.ca Git - liblbx.git/blobdiff - src/image.c
liblbx: Update lbximg_fopen to work like lbx_fopen.
[liblbx.git] / src / image.c
index 21f5a8eb79de5f8bda4c44b951e6af51f219f8de..78cb8a5d38c50ce41fae3c778a6daab0d0bdc7d2 100644 (file)
@@ -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,
        };