# HG changeset patch # User Matti Hamalainen # Date 1588090579 -10800 # Node ID ed2f56abda222492a8faf645fe2aba56280c0d5f # Parent 18ec4c092108ac392c8bc59cdef4820ab96ff30e Implement parsing of -R option suboptions. diff -r 18ec4c092108 -r ed2f56abda22 tools/gfxconv.c --- 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++)