started adding indexed color support to imago2
[dos_imgv] / imago / src / imago2.c
index 77bf7f0..2480f82 100644 (file)
@@ -21,6 +21,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <string.h>
 #include "imago2.h"
 #include "ftmodule.h"
+#include "byteord.h"
+#include "chkalloc.h"
+
+/* calculate int-aligned offset to colormap, right after the end of the pixel data */
+#define CMAPPTR(fb, fbsz)      \
+       (struct img_colormap*)((((uintptr_t)fb) + (fbsz) + sizeof(int) - 1) & ~(sizeof(int) - 1))
 
 static int pixel_size(enum img_fmt fmt);
 static size_t def_read(void *buf, size_t bytes, void *uptr);
@@ -40,17 +46,17 @@ void img_init(struct img_pixmap *img)
 
 void img_destroy(struct img_pixmap *img)
 {
-       free(img->pixels);
+       chk_free(img->pixels);
        img->pixels = 0;        /* just in case... */
        img->width = img->height = 0xbadbeef;
-       free(img->name);
+       chk_free(img->name);
 }
 
 struct img_pixmap *img_create(void)
 {
        struct img_pixmap *p;
 
-       if(!(p = malloc(sizeof *p))) {
+       if(!(p = chk_malloc(sizeof *p))) {
                return 0;
        }
        img_init(p);
@@ -60,14 +66,14 @@ struct img_pixmap *img_create(void)
 void img_free(struct img_pixmap *img)
 {
        img_destroy(img);
-       free(img);
+       chk_free(img);
 }
 
 int img_set_name(struct img_pixmap *img, const char *name)
 {
        char *tmp;
 
-       if(!(tmp = malloc(strlen(name) + 1))) {
+       if(!(tmp = chk_malloc(strlen(name) + 1))) {
                return -1;
        }
        strcpy(tmp, name);
@@ -93,18 +99,24 @@ int img_set_pixels(struct img_pixmap *img, int w, int h, enum img_fmt fmt, void
 {
        void *newpix;
        int pixsz = pixel_size(fmt);
+       int bsz = w * h * pixsz;
+
+       if(fmt == IMG_FMT_IDX8) {
+               /* add space for the colormap, and space to align it to sizeof(int) */
+               bsz += sizeof(struct img_colormap) + sizeof(int) - 1;
+       }
 
-       if(!(newpix = malloc(w * h * pixsz))) {
+       if(!(newpix = chk_malloc(bsz))) {
                return -1;
        }
 
        if(pix) {
                memcpy(newpix, pix, w * h * pixsz);
        } else {
-               memset(newpix, 0, w * h * pixsz);
+               memset(newpix, 0, bsz);
        }
 
-       free(img->pixels);
+       chk_free(img->pixels);
        img->pixels = newpix;
        img->width = w;
        img->height = h;
@@ -154,7 +166,7 @@ int img_save_pixels(const char *fname, void *pix, int xsz, int ysz, enum img_fmt
 
 void img_free_pixels(void *pix)
 {
-       free(pix);
+       chk_free(pix);
 }
 
 int img_load(struct img_pixmap *img, const char *fname)
@@ -396,6 +408,17 @@ void img_getpixel4f(struct img_pixmap *img, int x, int y, float *r, float *g, fl
        }
 }
 
+struct img_colormap *img_colormap(struct img_pixmap *img)
+{
+       int cmap_offs;
+
+       if(img->fmt != IMG_FMT_IDX8 || !img->pixels) {
+               return 0;
+       }
+
+       return CMAPPTR(img->pixels, img->width * img->height * img->pixelsz);
+}
+
 void img_io_set_user_data(struct img_io *io, void *uptr)
 {
        io->uptr = uptr;
@@ -421,6 +444,7 @@ static int pixel_size(enum img_fmt fmt)
 {
        switch(fmt) {
        case IMG_FMT_GREY8:
+       case IMG_FMT_IDX8:
                return 1;
        case IMG_FMT_RGB24:
                return 3;