From: John Tsiombikas Date: Tue, 14 Dec 2021 09:45:19 +0000 (+0200) Subject: started adding indexed color support to imago2 X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dos_imgv;a=commitdiff_plain;h=HEAD started adding indexed color support to imago2 --- diff --git a/imago/src/byteord.h b/imago/src/byteord.h index c3c3858..6ac5f30 100644 --- a/imago/src/byteord.h +++ b/imago/src/byteord.h @@ -18,7 +18,9 @@ along with this program. If not, see . #ifndef IMAGO_BYTEORD_H_ #define IMAGO_BYTEORD_H_ -#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900) || (defined(_MSC_VER) && _MSC_VER >= 1600) +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900) || \ + (defined(_MSC_VER) && _MSC_VER >= 1600) || \ + (defined(__WATCOMC__) && __WATCOMC__ >= 1200) #include #else #include @@ -31,6 +33,7 @@ typedef short int16_t; typedef unsigned short uint16_t; typedef long int32_t; typedef unsigned long uint32_t; +typedef unsigned long uintptr_t; #endif #include "imago2.h" diff --git a/imago/src/filetga.c b/imago/src/filetga.c index 49f8f66..c92e396 100644 --- a/imago/src/filetga.c +++ b/imago/src/filetga.c @@ -71,7 +71,7 @@ struct tga_footer { static int check(struct img_io *io); static int read_tga(struct img_pixmap *img, struct img_io *io); static int write_tga(struct img_pixmap *img, struct img_io *io); -static int read_pixel(struct img_io *io, int rdalpha, unsigned char *pix); +static int read_pixel(struct img_io *io, int fmt, unsigned char *pix); int img_register_tga(void) { @@ -109,10 +109,11 @@ static int read_tga(struct img_pixmap *img, struct img_io *io) { struct tga_header hdr; unsigned long x, y; - int i, c; + int i, idx, c, r, g, b; int rle_mode = 0, rle_pix_left = 0; - int rdalpha; int pixel_bytes; + int fmt; + struct img_colormap cmap; /* read header */ hdr.idlen = iofgetc(io); @@ -131,24 +132,61 @@ static int read_tga(struct img_pixmap *img, struct img_io *io) } hdr.img_desc = c; - if(!IS_RGBA(hdr.img_type)) { - fprintf(stderr, "libimago: only true color tga images are supported\n"); - return -1; - } - io->seek(hdr.idlen, SEEK_CUR, io->uptr); /* skip the image ID */ - /* skip the color map if it exists */ + /* read the color map if it exists */ if(hdr.cmap_type == 1) { - io->seek(hdr.cmap_len * hdr.cmap_entry_sz / 8, SEEK_CUR, io->uptr); + cmap.ncolors = hdr.cmap_len; + + for(i=0; i> 7; + g = (c & 0x03e0) >> 2; + b = (c & 0x001f) << 3; + break; + + case 24: + b = iofgetc(io); + g = iofgetc(io); + r = iofgetc(io); + break; + + case 32: + b = iofgetc(io); + g = iofgetc(io); + r = iofgetc(io); + iofgetc(io); /* ignore attribute byte */ + } + + idx = i + hdr.cmap_first; + if(idx < 256) { + cmap.color[idx].r = r; + cmap.color[idx].g = g; + cmap.color[idx].b = b; + if(cmap.ncolors <= idx) cmap.ncolors = idx + 1; + } + } } x = hdr.img_width; y = hdr.img_height; - rdalpha = hdr.img_desc & 0xf; - pixel_bytes = rdalpha ? 4 : 3; - if(img_set_pixels(img, x, y, rdalpha ? IMG_FMT_RGBA32 : IMG_FMT_RGB24, 0) == -1) { + if(hdr.img_type == IMG_CMAP || hdr.img_type == IMG_RLE_CMAP) { + if(hdr.img_bpp != 8) { + fprintf(stderr, "read_tga: indexed images with more than 8bpp not supported\n"); + return -1; + } + pixel_bytes = 1; + fmt = IMG_FMT_IDX8; + } else { + int alpha = hdr.img_desc & 0xf; + pixel_bytes = alpha ? 4 : 3; + fmt = alpha ? IMG_FMT_RGBA32 : IMG_FMT_RGB24; + } + + if(img_set_pixels(img, x, y, fmt, 0) == -1) { return -1; } @@ -161,7 +199,7 @@ static int read_tga(struct img_pixmap *img, struct img_io *io) for(j=0; j. #include #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); static size_t def_write(void *buf, size_t bytes, void *uptr); @@ -94,15 +99,21 @@ 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 = chk_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); } chk_free(img->pixels); @@ -397,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; @@ -422,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; diff --git a/imago/src/imago2.h b/imago/src/imago2.h index b6b5269..48bda1b 100644 --- a/imago/src/imago2.h +++ b/imago/src/imago2.h @@ -37,6 +37,7 @@ enum img_fmt { IMG_FMT_RGBAF, IMG_FMT_BGRA32, IMG_FMT_RGB565, + IMG_FMT_IDX8, NUM_IMG_FMT }; @@ -49,6 +50,13 @@ struct img_pixmap { char *name; }; +struct img_colormap { + int ncolors; + struct { + unsigned char r, g, b; + } color[256]; +}; + struct img_io { void *uptr; /* user-data */ @@ -160,6 +168,9 @@ void img_getpixel1f(struct img_pixmap *img, int x, int y, float *pix); void img_getpixel4i(struct img_pixmap *img, int x, int y, int *r, int *g, int *b, int *a); void img_getpixel4f(struct img_pixmap *img, int x, int y, float *r, float *g, float *b, float *a); +/* For IMG_FMT_IDX8 pixmaps, returns a pointer to the colormap, null otherwise */ +struct img_colormap *img_colormap(struct img_pixmap *img); + /* OpenGL helper functions */