diff options
Diffstat (limited to 'tools/svg-contrast.c')
-rw-r--r-- | tools/svg-contrast.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/tools/svg-contrast.c b/tools/svg-contrast.c new file mode 100644 index 0000000..11cf136 --- /dev/null +++ b/tools/svg-contrast.c @@ -0,0 +1,117 @@ +/* svg-contrast.c + * Copyright (C) 2016 Jehan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include <gio/gio.h> +#include <glib/gprintf.h> +#include <math.h> +#include <stdlib.h> +#include <string.h> + +/* This tool inverts grey colors in a SVG image. + * Non-grey colors are not touched, since they are considered + * exceptions that we would want to keep the same (for instance + * Red, Blue or Green channel representations). + * + * It is not based off XML knowledge since colors could appear in + * various fields. Instead we just assume that a color has the XML + * format "#RRGGBB" and we use regular expression to update these. + */ +static gboolean +rgb_color_contrast (const GMatchInfo *info, + GString *res, + gpointer data) +{ + gchar *match; + gchar *adjusted; + gdouble contrast; + gdouble value; + gint value_u8; + + contrast = *(const gdouble *) data; + + /* We only adjust grey colors, so we just need the first channel. */ + match = g_match_info_fetch (info, 1); + value_u8 = strtol (match, NULL, 16); + value = value_u8 / 255.0; + value = 0.5 + contrast * (value - 0.5); + value = CLAMP (value, 0.0, 1.0); + value_u8 = floor (255.0 * value + 0.5); + adjusted = g_strdup_printf ("#%02x%02x%02x", + value_u8, value_u8, value_u8); + + g_string_append (res, adjusted); + g_free (adjusted); + g_free (match); + + return FALSE; +} + +int main (int argc, char **argv) +{ + gchar *input; + gchar *output; + gdouble contrast; + GFile *file; + gchar *contents; + gchar *replaced; + GRegex *regex; + gint retval = 0; + + if (argc != 4) + { + g_fprintf (stderr, "Usage: svg-contrast input output [contrast]\n"); + return 1; + } + input = argv[1]; + output = argv[2]; + contrast = atof (argv[3]); + + file = g_file_new_for_path (input); + if (! g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL)) + { + g_fprintf (stderr, + "Error: svg-contrast could not load contents of file %s.\n", + input); + g_object_unref (file); + return 1; + } + g_object_unref (file); + + /* Replace grey colors only. */ + regex = g_regex_new ("#([0-9a-fA-F]{2}){3}\\b", 0, 0, NULL); + replaced = g_regex_replace_eval (regex, contents, -1, 0, 0, + rgb_color_contrast, &contrast, NULL); + + file = g_file_new_for_path (output); + if (! g_file_replace_contents (file, replaced, strlen (replaced), + NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, NULL, NULL)) + { + g_fprintf (stderr, + "Error: svg-contrast could not save file %s.\n", + output); + retval = 1; + } + + g_object_unref (file); + g_free (contents); + g_free (replaced); + g_regex_unref (regex); + + return retval; +} |