changeset 1286:b812fad6f33e

Work on libgfx.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 18 Aug 2017 15:20:44 +0300
parents e4bda4909d72
children 32051ad352c8
files src/libgfx.c src/libgfx.h
diffstat 2 files changed, 68 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);