changeset 2491:ed2f56abda22

Implement parsing of -R option suboptions.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 28 Apr 2020 19:16:19 +0300
parents 18ec4c092108
children 1bd7387984ed
files tools/gfxconv.c
diffstat 1 files changed, 81 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/tools/gfxconv.c	Tue Apr 28 18:38:38 2020 +0300
+++ b/tools/gfxconv.c	Tue Apr 28 19:16:19 2020 +0300
@@ -649,7 +649,7 @@
 }
 
 
-BOOL dmParseIntValWithSep(char **arg, unsigned int *value, char *last, const char *sep)
+char *dmParseValWithSep(char **arg, char *last, BOOL (*isok)(const int ch), const char *sep)
 {
     char *ptr = *arg, *end, *start;
 
@@ -660,8 +660,7 @@
     start = ptr;
 
     // Find next not-xdigit/separator
-    while (*ptr != 0 &&
-        (isxdigit(*ptr) || *ptr == 'x' || *ptr == '$') &&
+    while (*ptr != 0 && (isok == NULL || isok(*ptr)) &&
         strchr(sep, *ptr) == NULL)
         ptr++;
 
@@ -683,7 +682,25 @@
 
     *arg = ptr;
 
-    return dmGetIntVal(start, value, NULL);
+    return start;
+}
+
+
+BOOL dmParseIntValTok(const int ch)
+{
+    return isxdigit(ch) || ch == 'x' || ch == '$';
+}
+
+
+BOOL dmParseIntValWithSep(char **arg, unsigned int *value, char *last, const char *sep)
+{
+    return dmGetIntVal(dmParseValWithSep(arg, last, dmParseIntValTok, sep), value, NULL);
+}
+
+
+BOOL dmParseValTok(const int ch)
+{
+    return ch != '+';
 }
 
 
@@ -973,30 +990,58 @@
             break;
 
         case 42:
-            while ((tmpStr = strchr(optArg, '+')) != NULL)
+            if ((tmpStr = strchr(optArg, '+')) != NULL)
             {
-                char *topt = tmpStr + 1,
-                     *tend = strchr(topt, '+');
-
-                *tmpStr = 0;
-                if (tend != NULL)
+                *tmpStr++ = 0;
+                do
                 {
-                    *tend = 0;
-                    tmpStr = tend + 1;
-                }
-                else
-                    tmpStr = tend;
-
-                if (strcasecmp(topt, "remove") == 0)
-                    optRemapRemove = TRUE;
-                else
-                if (strcasecmp(topt, "alpha") == 0)
-                    optRemapMatchAlpha = TRUE;
-                else
-                {
-                    dmErrorMsg("Unknown -R option flag '%s'.\n", topt);
-                    return FALSE;
-                }
+                    char sep, *topt;
+                    topt = dmParseValWithSep(&tmpStr, &sep, NULL, "+");
+
+                    if (strcasecmp(topt, "remove") == 0)
+                        optRemapRemove = TRUE;
+                    else
+                    if (strcasecmp(topt, "alpha") == 0)
+                        optRemapMatchAlpha = TRUE;
+                    else
+                    if (dm_strncasecmp(topt, "max=", 4) == 0)
+                    {
+                        char *start = topt + 4, *end;
+                        optRemapMaxDist = strtof(start, &end);
+
+                        if (end == start)
+                        {
+                            dmErrorMsg("Invalid or missing value parameter for -R option flag: '%s'.\n",
+                                topt);
+                            return FALSE;
+                        }
+                    }
+                    else
+                    if (dm_strncasecmp(topt, "nomatch=", 8) == 0)
+                    {
+                        char *start = topt + 8, *end;
+                        optRemapNoMatchColor = strtol(start, &end, 10);
+
+                        if (end == start)
+                        {
+                            dmErrorMsg("Invalid or missing value parameter for -R option flag: '%s'.\n",
+                                topt);
+                            return FALSE;
+                        }
+
+                        if (optRemapNoMatchColor < -1 || optRemapNoMatchColor > 255)
+                        {
+                            dmErrorMsg("Invalid remap no-match color value %d. Should be [-1 .. 255].\n",
+                                optRemapNoMatchColor);
+                            return FALSE;
+                        }
+                    }
+                    else
+                    {
+                        dmErrorMsg("Unknown -R option flag '%s'.\n", topt);
+                        return FALSE;
+                    }
+                } while (*tmpStr != 0);
             }
 
             if (strcasecmp(optArg, "auto") == 0)
@@ -1380,9 +1425,14 @@
     // Remove unused colors if requested
     if (removeUnused)
     {
+        int nused;
+
+        if (noMatchColor >= 0)
+        {
+            dmErrorMsg("WARNING! Removing unused colors with 'no-match' color index set may have unintended results.\n");
+        }
+
         // Get the actually used colors
-        int nused;
-
         if ((res = dmScanUsedColors(src, TRUE, used, &nused)) != DMERR_OK)
             goto out;
 
@@ -1400,6 +1450,9 @@
             }
         }
 
+        if (noMatchColor >= 0)
+            used[noMatchColor] = TRUE;
+
         // Re-count number of actually used indices
         nused = 0;
         for (int index = 0; index < src->pal->ncolors; index++)