changeset 464:358776103ceb

Add support for IFF PBMs.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 04 Nov 2012 16:36:21 +0200
parents 4204e9ea8ae1
children ffd5e730d313
files libgfx.c
diffstat 1 files changed, 51 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libgfx.c	Sun Nov 04 16:35:38 2012 +0200
+++ b/libgfx.c	Sun Nov 04 16:36:21 2012 +0200
@@ -1149,6 +1149,7 @@
 
 #define IFF_ID_FORM        0x464F524D // "FORM"
 #define IFF_ID_ILBM        0x494C424D // "ILBM"
+#define IFF_ID_PBM         0x50424D20 // "PBM "
 #define IFF_ID_BMHD        0x424D4844 // "BMHD"
 #define IFF_ID_CMAP        0x434D4150 // "CMAP"
 #define IFF_ID_BODY        0x424F4459 // "BODY"
@@ -1196,7 +1197,7 @@
     Uint32 camg;
     int ncolors;
     DMColor *pal;
-    BOOL paletted;
+    BOOL paletted, planar;
 } DMIFF;
 
 
@@ -1350,7 +1351,7 @@
             // Decompress or read data
             if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
             {
-                dmError("ILBM: Error in reading image plane #%d.\n", plane);
+                dmError("ILBM: Error in reading image plane #%d @ %d.\n", plane, yc);
                 res = DMERR_FREAD;
                 goto error;
             }
@@ -1394,6 +1395,37 @@
 }
 
 
+int dmDecodePBMBody(FILE *fp, DMIFF *iff, DMImage **pimg, Uint32 *read)
+{
+    DMImage *img;
+    int yc, res = DMERR_OK;
+
+    *read = 0;
+
+    // Allocate image
+    if ((*pimg = img = dmImageAlloc(iff->bmhd.w, iff->bmhd.h)) == NULL)
+        return DMERR_MALLOC;
+
+    // Decode the chunk
+    for (yc = 0; yc < img->height; yc++)
+    {
+        Uint8 *dp = img->data + (yc * img->pitch);
+
+        if (!dmIFFReadOneRow(fp, iff, dp, img->width))
+        {
+            dmError("ILBM: Error in reading image row #%d.\n", yc);
+            res = DMERR_FREAD;
+            goto error;
+        }
+
+        *read += img->width;
+    }
+
+error:
+    return res;
+}
+
+
 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg)
 {
     Uint32 idILBM;
@@ -1416,12 +1448,14 @@
     
     // Check IFF ILBM signature
     if (!dm_fread_be32(fp, &idILBM) ||
-        idILBM != IFF_ID_ILBM)
+        (idILBM != IFF_ID_ILBM && idILBM != IFF_ID_PBM))
     {
         dmError("ILBM: Not a ILBM file.\n");
         return DMERR_INVALID_DATA;
     }
 
+    iff.planar = (idILBM == IFF_ID_ILBM);
+
     while (!parsed && !feof(fp))
     {
         if (!dmReadIFFChunk(fp, &chunk))
@@ -1527,8 +1561,16 @@
                 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size);
                 
                 // Decode the body
-                if ((res = dmDecodeILBMBody(fp, &iff, pimg, &read)) != DMERR_OK)
-                    return res;
+                if (iff.planar)
+                {
+                    if ((res = dmDecodeILBMBody(fp, &iff, pimg, &read)) != DMERR_OK)
+                        return res;
+                }
+                else
+                {
+                    if ((res = dmDecodePBMBody(fp, &iff, pimg, &read)) != DMERR_OK)
+                        return res;
+                }
 
                 if (!dmSkipIFFChunkRest(fp, &chunk, read))
                     return DMERR_FREAD;
@@ -1663,9 +1705,10 @@
 {
     if (len > 32 &&
         buf[ 0] == 'F' && buf[ 1] == 'O' &&
-        buf[ 2] == 'R' && buf[ 3] == 'M' &&
-        buf[ 8] == 'I' && buf[ 9] == 'L' &&
-        buf[10] == 'B' && buf[11] == 'M')
+        buf[ 2] == 'R' && buf[ 3] == 'M' && (
+        (buf[ 8] == 'I' && buf[ 9] == 'L' && buf[10] == 'B' && buf[11] == 'M') ||
+        (buf[ 8] == 'P' && buf[ 9] == 'B' && buf[10] == 'M' && buf[11] == 0x20)
+        ))
     {
         if (buf[12] == 'B' && buf[13] == 'M' &&
             buf[14] == 'H' && buf[15] == 'D')