+ unsigned short nframes = unpack_16_le(hdr+6);
+ struct lbx_image *img;
+
+ img = malloc(sizeof *img + sizeof img->offsets[0] * (nframes+1));
+ if (!img) {
+ lbx_errno = -errno;
+ return NULL;
+ }
+
+ *img = (struct lbx_image) {
+ .width = unpack_16_le(hdr+0),
+ .height = unpack_16_le(hdr+2),
+ .wtf = unpack_16_le(hdr+4),
+ .frames = hdr[6],
+ .wtf2 = hdr[7],
+ .leadin = hdr[8],
+ .chunk = hdr[9],
+ .flags = unpack_16_le(hdr+10),
+
+ .currentframe = -1,
+ };
+
+ return img;
+}
+
+struct lbx_image *lbximg_open(void *f, const struct lbx_file_ops *fops,
+ int (*destructor)(void *))
+{
+ unsigned char hdr_buf[HDR_LEN];
+ struct lbx_image *img;
+
+ if (fops->read(hdr_buf, sizeof hdr_buf, f) != sizeof hdr_buf) {
+ lbx_errno = -errno;
+ if (fops->eof(f))
+ lbx_errno = LBX_EEOF;
+ return NULL;
+ }