+struct lbx_image_priv {
+ struct lbx_image pub;
+
+ unsigned short wtf, flags;
+ unsigned char wtf2;
+ unsigned short palstart, palcount;
+
+ const struct lbx_file_ops *fops;
+ int (*dtor)(void *handle);
+ void *f;
+
+ long paloff;
+
+ /* State of frame readout */
+ unsigned currentx, currenty, currentn;
+ int read_state;
+
+ unsigned long offsets[];
+};
+
+static struct lbx_image_priv *lbx_img_init(unsigned char hdr[static HDR_LEN])
+{
+ unsigned short nframes = unpack_16_le(hdr+6);
+ struct lbx_image_priv *img;
+
+ img = malloc(sizeof *img + sizeof img->offsets[0] * (nframes+1));
+ if (!img) {
+ lbx_error_raise(LBX_ENOMEM);
+ return NULL;
+ }
+
+ *img = (struct lbx_image_priv) {
+ .pub.width = unpack_16_le(hdr+0),
+ .pub.height = unpack_16_le(hdr+2),
+ .wtf = unpack_16_le(hdr+4),
+ .pub.frames = hdr[6],
+ .wtf2 = hdr[7],
+ .pub.leadin = hdr[8],
+ .pub.chunk = hdr[9],
+ .flags = unpack_16_le(hdr+10),
+ };
+
+ if (img->flags & FLAG_OVERWRITE)
+ img->pub.chunk = 1;
+
+ if (img->flags & FLAG_LOOPING)
+ img->pub.leadin = 0;
+
+ return img;
+}
+
+struct lbx_image *lbx_img_open(void *f, const struct lbx_file_ops *fops,
+ int (*destructor)(void *))