# HG changeset patch # User Matti Hamalainen # Date 1503058844 -10800 # Node ID b812fad6f33ecfc7129696ce1334cb904d1564d8 # Parent e4bda4909d72fe6191ae8efc6ac92dadda41e8e6 Work on libgfx. diff -r e4bda4909d72 -r b812fad6f33e src/libgfx.c --- a/src/libgfx.c Fri Aug 18 14:08:08 2017 +0300 +++ b/src/libgfx.c Fri Aug 18 15:20:44 2017 +0300 @@ -30,17 +30,36 @@ } -DMImage * dmImageAlloc(int width, int height) +int dmImageGetBytesPerPixel(const int format) +{ + switch (format) + { + case DM_IFMT_PALETTE : return 1; + + case DM_IFMT_RGB_PLANE : + case DM_IFMT_RGB : return 3; + + case DM_IFMT_RGBA : return 4; + + default: return -1; + } +} + + +DMImage * dmImageAlloc(const int width, const int height, const int format, const int bpp) { DMImage *img = dmMalloc0(sizeof(DMImage)); if (img == NULL) return NULL; - img->width = width; - img->height = height; - img->pitch = width * sizeof(Uint8); + img->width = width; + img->height = height; + img->format = format; + img->bpp = (bpp <= 0) ? dmImageGetBytesPerPixel(format) * 8 : bpp; + img->pitch = width * img->bpp; + img->size = img->pitch * img->height; + img->ctransp = -1; - img->size = img->pitch * img->height; if ((img->data = dmMalloc(img->size)) == NULL) { dmFree(img); @@ -97,22 +116,6 @@ } -int dmImageGetBytesPerPixel(int format) -{ - switch (format) - { - case DM_IFMT_PALETTE : return 1; - - case DM_IFMT_RGB_PLANE : - case DM_IFMT_RGB : return 3; - - case DM_IFMT_RGBA : return 4; - - default: return 0; - } -} - - static BOOL dmReadPaletteData(FILE *fp, DMColor *pal, int ncolors) { int i; @@ -158,7 +161,7 @@ for (x = 0; x < img->width; x++) { - Uint8 c = img->data[(y * img->pitch) + x], qr, qg, qb, qa; + Uint8 c = img->data[(y * img->pitch) + (x * img->bpp)], qr, qg, qb, qa; switch (spec->format) { case DM_IFMT_PALETTE: @@ -584,7 +587,7 @@ dmMsg(3, "PNG: %d x %d, depth=%d, type=%d\n", width, height, bit_depth, color_type); - if ((*pimg = img = dmImageAlloc(width, height)) == NULL) + if ((*pimg = img = dmImageAlloc(width, height, DM_IFMT_PALETTE, bit_depth)) == NULL) { res = dmError(DMERR_MALLOC, "PNG: Could not allocate image data.\n"); @@ -1016,6 +1019,7 @@ DMPCXData pcx; DMPCXHeader hdr; int res = 0; + BOOL isPaletted; pcx.buf = NULL; @@ -1082,8 +1086,18 @@ dmMsg(3, "PCX: nplanes=%d, bpp=%d, bpl=%d\n", hdr.nplanes, hdr.bitsPerPlane, hdr.bpl); + isPaletted = (hdr.bitsPerPlane * hdr.nplanes) < 8; + if (!isPaletted) + { + res = dmError(DMERR_NOT_SUPPORTED, + "PCX: Non-indexed (truecolour) PCX images not supported for loading.\n"); + goto error; + } + // Allocate image - if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1)) == NULL) + if ((*pimg = img = dmImageAlloc(hdr.xmax - hdr.xmin + 1, hdr.ymax - hdr.ymin + 1, + isPaletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA, + isPaletted ? (hdr.bitsPerPlane * hdr.nplanes) : -1)) == NULL) { res = dmError(DMERR_MALLOC, "PCX: Could not allocate image structure.\n"); @@ -1122,13 +1136,17 @@ switch (hdr.bitsPerPlane) { case 8: - for (int nplane = 0; nplane < hdr.nplanes; nplane++) { - Uint8 *dptr = dp + nplane, - *sptr = pcx.buf + (hdr.bpl * nplane); + // Actually bytes and bits per plane per pixel .. + const int bytesPerPlane = hdr.bitsPerPlane / 8; - for (int xc = 0; xc < img->width; xc += hdr.nplanes, dptr += hdr.nplanes, sptr++) - *dptr = *sptr; + for (int nplane = 0; nplane < hdr.nplanes; nplane++) + { + Uint8 *dptr = dp + (nplane * bytesPerPlane), + *sptr = pcx.buf + (hdr.bpl * nplane); + + memcpy(dptr, sptr, img->width * bytesPerPlane); + } } break; @@ -1155,6 +1173,7 @@ } // Read additional VGA palette, if available + if (isPaletted) { int ncolors; Uint8 tmpb; @@ -1276,7 +1295,7 @@ Uint32 camg; int ncolors; DMColor *pal; - BOOL paletted, planar; + BOOL planar; } DMIFF; @@ -1417,7 +1436,9 @@ *read = 0; // Allocate image - if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL) + if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h, + iff->bmhd.nplanes < 8 ? DM_IFMT_PALETTE : DM_IFMT_RGBA, + iff->bmhd.nplanes < 8 ? iff->bmhd.nplanes : -1)) == NULL) return DMERR_MALLOC; // Allocate planar decoding buffer @@ -1494,7 +1515,9 @@ *read = 0; // Allocate image - if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL) + if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h, + iff->bmhd.nplanes < 8 ? DM_IFMT_PALETTE : DM_IFMT_RGBA, + iff->bmhd.nplanes < 8 ? iff->bmhd.nplanes : -1)) == NULL) return DMERR_MALLOC; // Decode the chunk diff -r e4bda4909d72 -r b812fad6f33e src/libgfx.h --- a/src/libgfx.h Fri Aug 18 14:08:08 2017 +0300 +++ b/src/libgfx.h Fri Aug 18 15:20:44 2017 +0300 @@ -46,13 +46,19 @@ }; -// Bitmapped image struct (can be one of types specified by DM_IFMT_*) +// Bitmapped image struct typedef struct { - int width, height, pitch; - BOOL constpal; - int ncolors, ctransp; - DMColor *pal; + int format; // one of types specified by DM_IFMT_* + int width, height; + int pitch; // bytes per scanline + int bpp; // bits per pixel + + int ncolors; // number of colors in palette, if any + int ctransp; // transparency color index + BOOL constpal; // is the palette a const? + DMColor *pal; // pointer to palette struct, NULL if no palette + size_t size; Uint8 *data; } DMImage; @@ -89,9 +95,9 @@ extern int dmGFXErrorMode; -DMImage * dmImageAlloc(int width, int height); +DMImage * dmImageAlloc(const int width, const int height, const int format, const int bpp); void dmImageFree(DMImage *img); -int dmImageGetBytesPerPixel(int format); +int dmImageGetBytesPerPixel(const int format); int dmImageProbeGeneric(const Uint8 *buf, const size_t len, DMImageFormat **fmt, int *index); BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, BOOL alpha);