changeset 2069:83a3d05b5c1d

Fixes to ACBM support.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 05 Dec 2018 14:41:19 +0200
parents e4dc8fbaa5ad
children 41df24d1dfb6
files tools/libgfx.c
diffstat 1 files changed, 49 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/tools/libgfx.c	Wed Dec 05 13:38:53 2018 +0200
+++ b/tools/libgfx.c	Wed Dec 05 14:41:19 2018 +0200
@@ -1702,10 +1702,11 @@
     {
         for (int plane = 0; plane < nplanes; plane++)
         {
-            if (!dmf_read_str(fp, buf, bufLen))
+            // Decompress or read data
+            if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
             {
                 res = dmError(DMERR_FREAD,
-                    "IFF: Error in reading image plane #%d.\n",
+                    "IFF: Error in reading ACBM image plane #%d.\n",
                     plane);
                 goto out;
             }
@@ -1737,7 +1738,7 @@
                 if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
                 {
                     res = dmError(DMERR_FREAD,
-                        "IFF: Error in reading image plane #%d @ %d.\n",
+                        "IFF: Error in reading ILBM image plane #%d @ %d.\n",
                         plane, yc);
                     goto out;
                 }
@@ -1754,7 +1755,7 @@
                 if (!dmIFFReadOneRow(fp, iff, buf, bufLen))
                 {
                     res = dmError(DMERR_FREAD,
-                        "IFF: Error in reading mask plane.\n");
+                        "IFF: Error in reading ILBM mask plane.\n");
                     goto out;
                 }
 
@@ -1870,6 +1871,15 @@
                     return dmError(DMERR_NOT_SUPPORTED,
                         "IFF: Unsupported features, refusing to load.\n");
                 }
+
+                if (iff.idsig == IFF_ID_ACBM &&
+                    iff.bmhd.compression != IFF_COMP_NONE)
+                {
+                    dmMsg(1, "IFF: ACBM image with compression != none (%d). Ignoring.\n",
+                        iff.bmhd.compression);
+
+                    iff.bmhd.compression = IFF_COMP_NONE;
+                }
                 break;
 
 
@@ -2245,10 +2255,14 @@
 
     iff.camg             = 0; // XXX TODO: when/if HAM support
     iff.bmhd.masking     = (img->ctransp < 0) ? IFF_MASK_NONE : spec->mask;
-    iff.bmhd.compression = spec->compression ? IFF_COMP_BYTERUN1 : IFF_COMP_NONE;
     iff.bmhd.transp      = (img->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->ctransp : 0xffff;
     iff.bmhd.nplanes     = (iff.idsig == IFF_ID_PBM && spec->nplanes < 8) ? 8 : spec->nplanes;
 
+    // Apparently ACBM can't/should not use compression .. even though
+    // some files in the wild have bmhd.compression != 0 (but are not
+    // actually compressed.) To be more compliant with the spec,
+    iff.bmhd.compression = (spec->compression && iff.idsig != IFF_ID_ACBM) ? IFF_COMP_BYTERUN1 : IFF_COMP_NONE;
+
     dmMsg(2, "IFF: nplanes=%d, comp=%d, mask=%d\n",
         iff.bmhd.nplanes, iff.bmhd.compression, iff.bmhd.masking);
 
@@ -2336,13 +2350,17 @@
     //
     // Encode the body
     //
-    if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY, IFF_ID_BODY)) != DMERR_OK)
+    if ((res = dmWriteIFFChunkHdr(fp, &iff.chBODY,
+        (iff.idsig == IFF_ID_ACBM) ? IFF_ID_ABIT : IFF_ID_BODY)) != DMERR_OK)
         goto out;
 
     // Allocate encoding buffer
     if (iff.idsig == IFF_ID_ILBM)
         bufLen = (((img->width * spec->scaleX) + 15) / 16) * 2;
     else
+    if (iff.idsig == IFF_ID_ACBM)
+        bufLen = (img->width * spec->scaleX * img->height * spec->scaleY) / 8;
+    else
         bufLen = img->width * spec->scaleX;
 
     dmMsg(2, "IFF: Line/plane row size %d bytes.\n", bufLen);
@@ -2351,6 +2369,31 @@
         return DMERR_MALLOC;
 
     // Encode the body
+    if (iff.idsig == IFF_ID_ACBM)
+    {
+        for (int plane = 0; plane < iff.bmhd.nplanes; plane++)
+        {
+            // Encode bitplane
+            dmMemset(buf, 0, bufLen);
+
+            for (int yc = 0; yc < img->height * spec->scaleY; yc++)
+            {
+                Uint8 *sp = img->data + (yc * img->pitch);
+                Uint8 *dp = buf + (yc * img->width * spec->scaleX) / 8;
+                for (int xc = 0; xc < img->width * spec->scaleX; xc++)
+                    dp[xc / 8] |= ((sp[xc / spec->scaleX] >> plane) & 1) << (7 - (xc & 7));
+            }
+
+            if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen))
+            {
+                res = dmError(DMERR_FWRITE,
+                    "IFF: Error writing ACBM image plane %d.\n",
+                    plane);
+                goto out;
+            }
+        }
+    }
+    else
     {
         for (int yc = 0; yc < img->height; yc++)
         for (int yscale = 0; yscale < spec->scaleY; yscale++)