+ tmp = calloc(height, width);
+ if (!tmp) {
+ lbx_error_raise(LBX_ENOMEM);
+ return NULL;
+ }
+
+ new = malloc(height * sizeof *new);
+ if (!new) {
+ lbx_error_raise(LBX_ENOMEM);
+ free(tmp);
+ return NULL;
+ }
+
+ for (i = 0; i < height; i++) {
+ new[i] = tmp + i * width;
+ }
+
+ return new;
+}
+
+static unsigned char **read_raw_frame(struct lbx_image_priv *img, int frame)
+{
+ unsigned long size = img->pub.width * img->pub.height;
+
+ assert(img->flags & FLAG_RAW);
+
+ if (img->fops->seek(img->f, img->offsets[frame], SEEK_SET)) {
+ return NULL;
+ }
+
+ if (img->fops->read(img->framedata[0], size, img->f) != size) {
+ if (img->fops->eof(img->f))
+ lbx_error_raise(LBX_EEOF);
+ return NULL;
+ }
+ memset(img->mask[0], 1, size);
+
+ if (img->fops->tell(img->f) > img->offsets[frame+1]) {
+ lbx_error_raise(LBX_EFORMAT);
+ return NULL;
+ }
+
+ return img->framedata;
+}
+
+unsigned char **lbx_img_getframe(struct lbx_image *pub, int frame)
+{
+ struct lbx_image_priv *img = (struct lbx_image_priv *)pub;
+ unsigned char buf[4];
+
+ if (frame >= pub->frames || frame < 0) {
+ lbx_error_raise(LBX_ENOENT);
+ return NULL;
+ }
+
+ if (!img->framedata) {
+ img->framedata = allocframebuffer(pub->width, pub->height);
+ if (!img->framedata)