From a60cda3daa879f9b2784158f01c1d12fbe2442ca Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 27 Jul 2024 18:42:39 -0400 Subject: [PATCH] image-tool: Allow specifying cicp tuples Accept --cicp=1/13/6/0 and similar to specify color states. --- docs/reference/gtk/gtk4-image-tool.rst | 12 +++++++- tools/gtk-image-tool-convert.c | 24 +++++++++++++++- tools/gtk-image-tool-relabel.c | 24 +++++++++++++++- tools/gtk-image-tool-utils.c | 39 ++++++++++++++++++++++++++ tools/gtk-image-tool.h | 3 ++ 5 files changed, 99 insertions(+), 3 deletions(-) diff --git a/docs/reference/gtk/gtk4-image-tool.rst b/docs/reference/gtk/gtk4-image-tool.rst index f0d79d2490..911ab9d9c8 100644 --- a/docs/reference/gtk/gtk4-image-tool.rst +++ b/docs/reference/gtk/gtk4-image-tool.rst @@ -70,6 +70,11 @@ The ``convert`` command converts the image to a different format or color state. Convert to the given color state. The supported color states can be listed with ``--format=list``. +``--cicp=CICP`` + + Convert to a color state that is specified as a cicp tuple. The cicp tuple + must be specified as four numbers, separated by /, e.g. 1/13/6/0. + Relabeling ^^^^^^^^^^ @@ -78,5 +83,10 @@ This can be useful to produce wrong color renderings for diagnostics. ``--color-state=COLORSTATE`` - Convert to the given color state. The supported color states can be + Relabel to the given color state. The supported color states can be listed with ``--format=list``. + +``--cicp=CICP`` + + Relabel to a color state that is specified as a cicp tuple. The cicp tuple + must be specified as four numbers, separated by /, e.g. 1/13/6/0. diff --git a/tools/gtk-image-tool-convert.c b/tools/gtk-image-tool-convert.c index adac555ce8..79e33050ff 100644 --- a/tools/gtk-image-tool-convert.c +++ b/tools/gtk-image-tool-convert.c @@ -81,15 +81,17 @@ do_convert (int *argc, char **filenames = NULL; char *format_name = NULL; char *colorstate_name = NULL; + char *cicp_tuple = NULL; const GOptionEntry entries[] = { { "format", 0, 0, G_OPTION_ARG_STRING, &format_name, N_("Format to use"), N_("FORMAT") }, { "color-state", 0, 0, G_OPTION_ARG_STRING, &colorstate_name, N_("Color state to use"), N_("COLORSTATE") }, + { "cicp", 0, 0, G_OPTION_ARG_STRING, &cicp_tuple, N_("Color state to use, as cicp tuple"), N_("CICP") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") }, { NULL, } }; GError *error = NULL; GdkMemoryFormat format = GDK_MEMORY_DEFAULT; - GdkColorState *color_state = gdk_color_state_get_srgb (); + GdkColorState *color_state = NULL; g_set_prgname ("gtk4-image-tool convert"); context = g_option_context_new (NULL); @@ -151,6 +153,26 @@ do_convert (int *argc, } } + if (cicp_tuple) + { + if (color_state) + { + g_printerr (_("Can't specify both --color-state and --cicp\n")); + exit (1); + } + + color_state = parse_cicp_tuple (cicp_tuple, &error); + + if (!color_state) + { + g_printerr (_("Not a supported cicp tuple: %s\n"), error->message); + exit (1); + } + } + + if (!color_state) + color_state = gdk_color_state_get_srgb (); + save_image (filenames[0], filenames[1], format, color_state); g_strfreev (filenames); diff --git a/tools/gtk-image-tool-relabel.c b/tools/gtk-image-tool-relabel.c index c068cddf03..3b872fb379 100644 --- a/tools/gtk-image-tool-relabel.c +++ b/tools/gtk-image-tool-relabel.c @@ -79,13 +79,15 @@ do_relabel (int *argc, GOptionContext *context; char **filenames = NULL; char *colorstate_name = NULL; + char *cicp_tuple = NULL; const GOptionEntry entries[] = { { "color-state", 0, 0, G_OPTION_ARG_STRING, &colorstate_name, N_("Color state to use"), N_("COLORSTATE") }, + { "cicp", 0, 0, G_OPTION_ARG_STRING, &cicp_tuple, N_("Color state to use, as cicp tuple"), N_("CICP") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") }, { NULL, } }; GError *error = NULL; - GdkColorState *color_state = gdk_color_state_get_srgb (); + GdkColorState *color_state = NULL; g_set_prgname ("gtk4-image-tool relabel"); context = g_option_context_new (NULL); @@ -131,6 +133,26 @@ do_relabel (int *argc, } } + if (cicp_tuple) + { + if (color_state) + { + g_printerr (_("Can't specify both --color-state and --cicp\n")); + exit (1); + } + + color_state = parse_cicp_tuple (cicp_tuple, &error); + + if (!color_state) + { + g_printerr (_("Not a supported cicp tuple: %s\n"), error->message); + exit (1); + } + } + + if (!color_state) + color_state = gdk_color_state_get_srgb (); + relabel_image (filenames[0], filenames[1], color_state); g_strfreev (filenames); diff --git a/tools/gtk-image-tool-utils.c b/tools/gtk-image-tool-utils.c index e4cae80934..d4795abc99 100644 --- a/tools/gtk-image-tool-utils.c +++ b/tools/gtk-image-tool-utils.c @@ -221,3 +221,42 @@ get_color_state_name (GdkColorState *color_state) return name; } + +GdkColorState * +parse_cicp_tuple (const char *cicp_tuple, + GError **error) +{ + char **tokens; + guint64 num[4]; + GdkCicpParams *params; + GdkColorState *color_state; + + tokens = g_strsplit (cicp_tuple, "/", 0); + + if (g_strv_length (tokens) != 4 || + !g_ascii_string_to_unsigned (tokens[0], 10, 0, 255, &num[0], NULL) || + !g_ascii_string_to_unsigned (tokens[1], 10, 0, 255, &num[1], NULL) || + !g_ascii_string_to_unsigned (tokens[2], 10, 0, 255, &num[2], NULL) || + !g_ascii_string_to_unsigned (tokens[3], 10, 0, 255, &num[3], NULL)) + { + g_strfreev (tokens); + g_set_error (error, + G_IO_ERROR, G_IO_ERROR_FAILED, + _("cicp must be 4 numbers, separated by /\n")); + return NULL; + } + + g_strfreev (tokens); + + params = gdk_cicp_params_new (); + + gdk_cicp_params_set_color_primaries (params, (guint) num[0]); + gdk_cicp_params_set_transfer_function (params, (guint) num[1]); + gdk_cicp_params_set_matrix_coefficients (params, (guint) num[2]); + gdk_cicp_params_set_range (params, num[3] == 0 ? GDK_CICP_RANGE_NARROW : GDK_CICP_RANGE_FULL); + color_state = gdk_cicp_params_build_color_state (params, error); + + g_object_unref (params); + + return color_state; +} diff --git a/tools/gtk-image-tool.h b/tools/gtk-image-tool.h index 9203d6e551..7ad1a61901 100644 --- a/tools/gtk-image-tool.h +++ b/tools/gtk-image-tool.h @@ -17,3 +17,6 @@ GdkColorState * find_color_state_by_name (const char *name); char ** get_color_state_names (void); char * get_color_state_name (GdkColorState *color_state); + +GdkColorState *parse_cicp_tuple (const char *cicp_tuple, + GError **error);