changeset 2453:11151bc8d056

Implement functionality for converting the supported palette formats to another. This is quite simplistic currently.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 15 Apr 2020 13:52:28 +0300
parents 0fdc14005e43
children 375da267d994
files tools/gfxconv.c
diffstat 1 files changed, 151 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/tools/gfxconv.c	Wed Apr 15 13:51:22 2020 +0300
+++ b/tools/gfxconv.c	Wed Apr 15 13:52:28 2020 +0300
@@ -34,6 +34,7 @@
 
     FFMT_IMAGE,
     FFMT_DUMP,
+    FFMT_PALETTE,
 
     FFMT_LAST
 };
@@ -56,6 +57,7 @@
     "C64 sprite data",
     "Image",
     "CDump",
+    "Palette",
 };
 
 
@@ -88,12 +90,13 @@
 
 static const DMConvFormat baseFormatList[] =
 {
-    { "ASCII text"                           , "asc"   , DM_FMT_WR   , FFMT_ASCII  , 0  , NULL },
-    { "ANSI colored text"                    , "ansi"  , DM_FMT_WR   , FFMT_ANSI   , 0  , NULL },
-    { "C64 bitmap image"                     , "bitmap", DM_FMT_RDWR , FFMT_BITMAP , -1 , NULL  },
-    { "C64 character/font data"              , "chr"   , DM_FMT_RDWR , FFMT_CHAR   , 0  , " (chr:mc/chr:sc for multi/singlecolor)" },
-    { "C64 sprite data"                      , "spr"   , DM_FMT_RDWR , FFMT_SPRITE , 0  , " (spr:mc/spr:sc for multi/singlecolor)" },
-    { "C64 bitmap image dump"                , "dump"  , DM_FMT_WR   , FFMT_DUMP   , 0  , NULL },
+    { "ASCII text"                           , "asc"   , DM_FMT_WR   , FFMT_ASCII   , 0  , NULL },
+    { "ANSI colored text"                    , "ansi"  , DM_FMT_WR   , FFMT_ANSI    , 0  , NULL },
+    { "C64 bitmap image"                     , "bitmap", DM_FMT_RDWR , FFMT_BITMAP  , -1 , NULL },
+    { "C64 character/font data"              , "chr"   , DM_FMT_RDWR , FFMT_CHAR    , 0  , " (chr:mc/chr:sc for multi/singlecolor)" },
+    { "C64 sprite data"                      , "spr"   , DM_FMT_RDWR , FFMT_SPRITE  , 0  , " (spr:mc/spr:sc for multi/singlecolor)" },
+    { "C64 bitmap image dump"                , "dump"  , DM_FMT_WR   , FFMT_DUMP    , 0  , NULL },
+    { "Palette data"                         , "pal"   , DM_FMT_RDWR , FFMT_PALETTE , -1 , NULL },
 };
 
 static const int nbaseFormatList = sizeof(baseFormatList) / sizeof(baseFormatList[0]);
@@ -141,6 +144,7 @@
 char    *optCharROMFilename = NULL;
 DMC64Palette *optC64Palette = NULL;
 char    *optPaletteFile = NULL;
+DMPalette *optPaletteData = NULL;
 
 
 DMImageWriteSpec optSpec =
@@ -1605,6 +1609,38 @@
 }
 
 
+int dmWritePalette(const char *filename, const DMPalette *palette, const DMPaletteFormat *fmt)
+{
+    DMResource *fp = NULL;
+    int res;
+
+    // Check if writing is even supported
+    if (fmt->write == NULL || (fmt->flags & DM_FMT_WR) == 0)
+    {
+        return dmError(DMERR_NOT_SUPPORTED,
+            "Writing of '%s' format is not supported.\n",
+            fmt->name);
+    }
+
+    dmMsg(1, "Outputting '%s' format palette of %d entries.\n",
+        fmt->name, palette->ncolors);
+
+    if ((res = dmf_open_stdio(filename, "wb", &fp)) != DMERR_OK)
+    {
+        dmErrorMsg("Could not open file '%s' for writing.\n",
+            filename);
+        goto err;
+    }
+
+    res = fmt->write(fp, palette);
+
+err:
+    dmf_close(fp);
+
+    return res;
+}
+
+
 static Uint8 dmConvertByte(const Uint8 *sp, const BOOL multicolor)
 {
     Uint8 byte = 0;
@@ -1987,7 +2023,7 @@
         goto exit;
     }
 
-    nconvFormatList = ndmImageFormatList + nbaseFormatList;
+    nconvFormatList = ndmImageFormatList + ndmPaletteFormatList + nbaseFormatList;
     convFormatList = dmCalloc(nconvFormatList, sizeof(DMConvFormat));
 
     for (n = i = 0; i < ndmImageFormatList; i++)
@@ -2001,6 +2037,18 @@
         dfmt->format = sfmt->fmtid;
     }
 
+    for (i = 0; i < ndmPaletteFormatList; i++)
+    {
+        const DMPaletteFormat *sfmt = &dmPaletteFormatList[i];
+        DMConvFormat *dfmt = &convFormatList[n++];
+        dfmt->name   = sfmt->name;
+        dfmt->fext   = sfmt->fext;
+        dfmt->flags  = sfmt->flags;
+        dfmt->type   = FFMT_PALETTE;
+        dfmt->format = sfmt->fmtid;
+    }
+
+
     for (i = 0; i < nbaseFormatList; i++)
         memcpy(&convFormatList[n++], &baseFormatList[i], sizeof(DMConvFormat));
 
@@ -2160,6 +2208,20 @@
         }
     }
 
+    if (optInType == FFMT_AUTO || optInType == FFMT_PALETTE)
+    {
+        const DMPaletteFormat *pfmt = NULL;
+        int index;
+        dmMsg(4, "Trying to probe palette formats.\n");
+        if (dmPaletteProbeGeneric(dataBuf, dataSize, &pfmt, &index) > 0 &&
+            pfmt->read != NULL)
+        {
+            optInType = FFMT_PALETTE;
+            optInFormat = index;
+            dmMsg(1, "Probed '%s' format palette.\n", pfmt->name);
+        }
+    }
+
     if (optInType == FFMT_AUTO)
     {
         dmErrorMsg("No input format specified, and could not be determined automatically.\n");
@@ -2199,35 +2261,48 @@
         }
     }
 
-    if (optPaletteFile != NULL)
-    {
-        if ((res = dmHandleExternalPalette(optPaletteFile, &optC64Spec.pal)) != DMERR_OK)
-            goto exit;
-
-        if (optC64Spec.pal->ncolors < D64_NCOLORS)
-        {
-            dmErrorMsg("Palette does not have enough colors (%d < %d)\n",
-                optC64Spec.pal->ncolors, D64_NCOLORS);
-            goto exit;
-        }
-    }
-    else
+    // Handle palette stuff that is generic for different operation modes
+    if (optPaletteFile != NULL &&
+        (res = dmHandleExternalPalette(optPaletteFile, &optPaletteData)) != DMERR_OK)
+        goto exit;
+
+    switch (optInType)
     {
-        // No palette file specified, use internal palette
-        if (optC64Palette == NULL)
-            optC64Palette = &dmC64DefaultPalettes[0];
-
-        dmMsg(1, "Using internal palette '%s' (%s).\n",
-            optC64Palette->name, optC64Palette->desc);
-
-        optC64Spec.cpal = optC64Palette;
-
-        if ((res = dmC64PaletteFromC64Palette(&optC64Spec.pal, optC64Palette, FALSE)) != DMERR_OK)
-        {
-            dmErrorMsg("Could not setup palette: %s.\n",
-                dmErrorStr(res));
-            goto exit;
-        }
+        case FFMT_SPRITE:
+        case FFMT_CHAR:
+        case FFMT_BITMAP:
+            if (optPaletteData == NULL)
+            {
+                // No palette file specified, use internal palette
+                if (optC64Palette == NULL)
+                    optC64Palette = &dmC64DefaultPalettes[0];
+
+                dmMsg(1, "Using internal palette '%s' (%s).\n",
+                    optC64Palette->name, optC64Palette->desc);
+
+                if ((res = dmC64PaletteFromC64Palette(&optPaletteData, optC64Palette, FALSE)) != DMERR_OK)
+                {
+                    dmErrorMsg("Could not set up palette: %s.\n",
+                        dmErrorStr(res));
+                    goto exit;
+                }
+            }
+
+            if (optPaletteData->ncolors < D64_NCOLORS)
+            {
+                dmErrorMsg("Palette does not have enough colors (%d < %d)\n",
+                    optPaletteData->ncolors, D64_NCOLORS);
+                goto exit;
+            }
+
+            if (optPaletteData->ncolors > D64_NCOLORS)
+            {
+                dmMsg(1, "Palette has %d colors, using only first %d.\n",
+                    optPaletteData->ncolors, D64_NCOLORS);
+            }
+
+            optC64Spec.pal = optPaletteData;
+            break;
     }
 
     switch (optInType)
@@ -2237,6 +2312,39 @@
             dmDumpSpritesAndChars(dataBuf, dataSize, dataRealOffs);
             break;
 
+        case FFMT_PALETTE:
+            {
+                const DMPaletteFormat *pfmt = &dmPaletteFormatList[optInFormat];
+                DMResource *fp;
+
+                if (optOutFilename == NULL)
+                {
+                    dmErrorMsg("Output filename not set, required for palette formats.\n");
+                    goto exit;
+                }
+
+                // Read palette file
+                if ((res = dmf_open_memio(NULL, optInFilename, dataBuf, dataSize, &fp)) != DMERR_OK)
+                {
+                    dmErrorMsg("Could not create MemIO handle for input.\n");
+                    goto exit;
+                }
+
+                // Read input
+                if (pfmt->read != NULL)
+                    res = pfmt->read(fp, &optPaletteData);
+                else
+                    dmErrorMsg("Unsupported input palette format.\n");
+
+                dmf_close(fp);
+
+                if (res != DMERR_OK || optPaletteData == NULL)
+                    goto exit;
+
+                res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]);
+            }
+            break;
+
         case FFMT_BITMAP:
             if (optOutFilename == NULL)
             {
@@ -2296,6 +2404,10 @@
                     }
                     break;
 
+                case FFMT_PALETTE:
+                    res = dmWritePalette(optOutFilename, optPaletteData, &dmPaletteFormatList[optOutFormat]);
+                    break;
+
                 case FFMT_DUMP:
                     dmDumpC64Bitmap(optOutFilename, inC64Image);
                     break;
@@ -2356,6 +2468,10 @@
                             &dmImageFormatList[optOutFormat], TRUE);
                         break;
 
+                    case FFMT_PALETTE:
+                        res = dmWritePalette(optOutFilename, inImage->pal, &dmPaletteFormatList[optOutFormat]);
+                        break;
+
                     case FFMT_CHAR:
                     case FFMT_SPRITE:
                         res = dmWriteSpritesAndChars(optOutFilename, inImage,