diff libgfx.c @ 444:7d588807f91d

Clean up the IFF parser a bit.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 04 Nov 2012 06:52:42 +0200
parents f7c9d1619c74
children 1d65efb29986
line wrap: on
line diff
--- a/libgfx.c	Sun Nov 04 06:41:51 2012 +0200
+++ b/libgfx.c	Sun Nov 04 06:52:42 2012 +0200
@@ -957,6 +957,17 @@
 } DMIFFBMHD;
 
 
+typedef struct
+{
+    DMIFFChunk chBMHD, chCMAP, chBODY;
+    DMIFFBMHD bmhd;
+    int ncolors;
+    DMColor *pal;
+    DMImage *img;
+    BOOL paletted;
+} DMIFF;
+
+
 static BOOL dmReadIFFChunk(FILE *fp, DMIFFChunk *chunk)
 {
     if (!dm_fread_be32(fp, &chunk->id) ||
@@ -969,7 +980,7 @@
         return TRUE;
 }
 
-static char * dmGetIFFChunkID(DMIFFChunk *chunk, char *buf)
+static char * dmGetIFFChunkID(const DMIFFChunk *chunk, char *buf)
 {
     buf[0] = (chunk->id >> 24) & 0xff;
     buf[1] = (chunk->id >> 16) & 0xff;
@@ -979,7 +990,15 @@
     return buf;
 }
 
-static BOOL dmCheckIFFChunk(DMIFFChunk *dest, DMIFFChunk *chunk, BOOL multi, Uint32 minSize)
+static BOOL dmSkipIFFChunkRest(FILE *fp, const DMIFFChunk *chunk, const Uint32 used)
+{
+    if (chunk->size > used)
+        return fseeko(fp, chunk->size - used, SEEK_CUR) == 0;
+    else
+        return TRUE;
+}
+
+static BOOL dmCheckIFFChunk(DMIFFChunk *dest, const DMIFFChunk *chunk, const BOOL multi, const Uint32 minSize)
 {
     if (dest->count > 0 && !multi)
     {
@@ -998,21 +1017,21 @@
 }
 
 
+int dmDecodeILBMBody(FILE *fp, DMIFF *iff)
+{
+    return DMERR_OK;
+}
+
+
 int dmReadILBMImageFILE(FILE *fp, DMImage **pimg)
 {
     Uint32 idILBM;
-    DMIFFChunk chunk, chBMHD, chCMAP, chBODY;
-    DMIFFBMHD bmhd;
-    int ncolors, i;
-    DMColor *pal = NULL;
-    DMImage *img = NULL;
-    BOOL paletted = FALSE, parsed = FALSE;
-    int res = DMERR_OK;
+    DMIFFChunk chunk;
+    DMIFF iff;
+    BOOL parsed = FALSE;
+    int i, res = DMERR_OK;
 
-    memset(&chBMHD, 0, sizeof(DMIFFChunk));
-    memset(&chCMAP, 0, sizeof(DMIFFChunk));
-    memset(&chBODY, 0, sizeof(DMIFFChunk));
-    memset(&bmhd, 0, sizeof(bmhd));
+    memset(&iff, 0, sizeof(iff));
 
     // Read IFF FORM header
     if (!dmReadIFFChunk(fp, &chunk) ||
@@ -1042,59 +1061,62 @@
         switch (chunk.id)
         {
             case IFF_ID_BMHD:
-                if (!dmCheckIFFChunk(&chBMHD, &chunk, FALSE, sizeof(bmhd)))
+                if (!dmCheckIFFChunk(&iff.chBMHD, &chunk, FALSE, sizeof(iff.bmhd)))
                     return DMERR_FREAD;
 
-                if (!dm_fread_be16(fp, &bmhd.w) ||
-                    !dm_fread_be16(fp, &bmhd.h) ||
-                    !dm_fread_be16(fp, (Uint16 *) &bmhd.x) ||
-                    !dm_fread_be16(fp, (Uint16 *) &bmhd.y) ||
-                    !dm_fread_byte(fp, &bmhd.nplanes) ||
-                    !dm_fread_byte(fp, &bmhd.masking) ||
-                    !dm_fread_byte(fp, &bmhd.compression) ||
-                    !dm_fread_byte(fp, &bmhd.pad1) ||
-                    !dm_fread_be16(fp, &bmhd.transp) ||
-                    !dm_fread_byte(fp, &bmhd.xasp) ||
-                    !dm_fread_byte(fp, &bmhd.yasp) ||
-                    !dm_fread_be16(fp, (Uint16 *) &bmhd.pagew) ||
-                    !dm_fread_be16(fp, (Uint16 *) &bmhd.pageh))
+                if (!dm_fread_be16(fp, &iff.bmhd.w) ||
+                    !dm_fread_be16(fp, &iff.bmhd.h) ||
+                    !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.x) ||
+                    !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.y) ||
+                    !dm_fread_byte(fp, &iff.bmhd.nplanes) ||
+                    !dm_fread_byte(fp, &iff.bmhd.masking) ||
+                    !dm_fread_byte(fp, &iff.bmhd.compression) ||
+                    !dm_fread_byte(fp, &iff.bmhd.pad1) ||
+                    !dm_fread_be16(fp, &iff.bmhd.transp) ||
+                    !dm_fread_byte(fp, &iff.bmhd.xasp) ||
+                    !dm_fread_byte(fp, &iff.bmhd.yasp) ||
+                    !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pagew) ||
+                    !dm_fread_be16(fp, (Uint16 *) &iff.bmhd.pageh))
                 {
                     dmError("ILBM: Error reading BMHD chunk.\n");
                     return DMERR_FREAD;
                 }
                 dmMsg(2, "ILBM: BMHD %d x %d @ %d, %d : nplanes=%d, comp=%d, mask=%d\n",
-                    bmhd.w, bmhd.h, bmhd.x, bmhd.y, bmhd.nplanes, bmhd.compression, bmhd.masking);
+                    iff.bmhd.w, iff.bmhd.h, iff.bmhd.x, iff.bmhd.y, iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking);
+                
+                if (!dmSkipIFFChunkRest(fp, &chunk, sizeof(iff.bmhd)))
+                    return DMERR_FREAD;
                 break;
-            
+
 
             case IFF_ID_CMAP:
                 // Check for multiple occurences of CMAP
-                if (!dmCheckIFFChunk(&chCMAP, &chunk, FALSE, 3))
+                if (!dmCheckIFFChunk(&iff.chCMAP, &chunk, FALSE, 3))
                     return DMERR_FREAD;
 
                 // Check for sanity
                 if (chunk.size % 3 != 0)
                     dmError("ILBM: CMAP chunk size not divisible by 3, possibly broken file.\n");
 
-                ncolors = chunk.size / 3;
+                iff.ncolors = chunk.size / 3;
                 dmMsg(2, "ILBM: CMAP %d entries (%d bytes)\n",
-                    ncolors, chunk.size, 1 << bmhd.nplanes);
+                    iff.ncolors, chunk.size, 1 << iff.bmhd.nplanes);
 
-                if (bmhd.nplanes > 0 && ncolors != 1 << bmhd.nplanes)
-                    dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << bmhd.nplanes);
+                if (iff.bmhd.nplanes > 0 && iff.ncolors != 1 << iff.bmhd.nplanes)
+                    dmMsg(2, "ILBM: Expected %d entries in CMAP.\n", 1 << iff.bmhd.nplanes);
                 
-                if (ncolors == 0)
+                if (iff.ncolors == 0)
                     break;
                 
                 // Allocate palette
-                if ((pal = dmMalloc(sizeof(DMColor) * ncolors)) == NULL)
+                if ((iff.pal = dmMalloc(sizeof(DMColor) * iff.ncolors)) == NULL)
                 {
                     dmError("ILBM: Could not allocate memory for palette.\n");
                     return DMERR_MALLOC;
                 }
                 
                 // Read palette
-                for (i = 0; i < ncolors; i++)
+                for (i = 0; i < iff.ncolors; i++)
                 {
                     Uint8 colR, colG, colB;
                     if (!dm_fread_byte(fp, &colR) ||
@@ -1104,34 +1126,35 @@
                         dmError("ILBM: Error reading CMAP entry #%d, broken file.\n", i);
                         return DMERR_FREAD;
                     }
-                    
-                    pal[i].r = colR;
-                    pal[i].g = colG;
-                    pal[i].b = colB;
+
+                    iff.pal[i].r = colR;
+                    iff.pal[i].g = colG;
+                    iff.pal[i].b = colB;
                 }
 
-                if (chBMHD.count && chBODY.count)
+                if (iff.chBMHD.count && iff.chBODY.count)
                     parsed = TRUE;
                 break;
             
             case IFF_ID_BODY:
-                if (!dmCheckIFFChunk(&chBODY, &chunk, FALSE, 1))
+                if (!dmCheckIFFChunk(&iff.chBODY, &chunk, FALSE, 1))
                     return DMERR_FREAD;
 
-                if (!chBMHD.count)
+                if (!iff.chBMHD.count)
                 {
                     dmError("ILBM: BODY chunk before BMHD?\n");
                     return DMERR_INVALID_DATA;
                 }
 
                 dmMsg(2, "ILBM: BODY chunk size %d bytes\n", chunk.size);
+
                 if (fseeko(fp, chunk.size, SEEK_CUR) != 0)
                 {
                     dmError("ILBM: Error skipping in file.");
                     return DMERR_FREAD;
                 }
                  
-                if (chCMAP.count)
+                if (iff.chCMAP.count)
                     parsed = TRUE;
                 break;