+ for (i = 0; i < img->palcount; i++) {
+ rc = img->fops->read(entry, sizeof entry, img->f);
+ if (rc < sizeof entry) {
+ goto readerr;
+ }
+
+ if (entry[0] != 0) {
+ lbx_error_raise(LBX_EFORMAT);
+ return -1;
+ }
+
+ palette[img->palstart + i] = (struct lbx_colour){
+ .red = entry[1] << 2,
+ .green = entry[2] << 2,
+ .blue = entry[3] << 2,
+ .active = 1,
+ };
+ }
+
+ return 0;
+readerr:
+ if (img->fops->eof(img->f))
+ lbx_error_raise(LBX_EEOF);
+ return -1;
+}
+
+void lbx_img_getinfo(struct lbx_image *pub, struct lbx_imginfo *info)
+{
+ struct lbx_image_priv *img = (struct lbx_image_priv *)pub;
+
+ *info = (struct lbx_imginfo) {
+ .palettesz = (img->flags & FLAG_PALETTE) ? img->palcount : 0,
+ };
+
+ /* There seems to be two ways of specifying that an image loops. */
+ if (img->flags & FLAG_LOOPING) {
+ info->loopstart = 0;
+ info->looping = 1;
+ } else if (img->leadin != pub->frames - 1) {
+ info->loopstart = img->leadin;
+ info->looping = 1;
+ }
+}
+
+unsigned char **lbx_img_getmask(struct lbx_image *pub)
+{
+ struct lbx_image_priv *img = (struct lbx_image_priv *)pub;
+
+ return img->mask;
+}
+
+int lbx_img_close(struct lbx_image *pub)
+{
+ struct lbx_image_priv *img = (struct lbx_image_priv *)pub;
+ int rc = 0;
+
+ if (img) {
+ if (img->framedata) {
+ free(img->framedata[0]);
+ free(img->framedata);
+ }
+
+ if (img->mask) {
+ free(img->mask[0]);
+ free(img->mask);
+ }
+
+ if (img && img->dtor) {
+ rc = img->dtor(img->f);
+ }
+
+ free(img);