image-tool: Allow specifying cicp tuples

Accept --cicp=1/13/6/0 and similar to specify color states.
This commit is contained in:
Matthias Clasen
2024-07-27 18:42:39 -04:00
parent d301d16aee
commit a60cda3daa
5 changed files with 99 additions and 3 deletions

View File

@@ -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 Convert to the given color state. The supported color states can be
listed with ``--format=list``. 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 Relabeling
^^^^^^^^^^ ^^^^^^^^^^
@@ -78,5 +83,10 @@ This can be useful to produce wrong color renderings for diagnostics.
``--color-state=COLORSTATE`` ``--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``. 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.

View File

@@ -81,15 +81,17 @@ do_convert (int *argc,
char **filenames = NULL; char **filenames = NULL;
char *format_name = NULL; char *format_name = NULL;
char *colorstate_name = NULL; char *colorstate_name = NULL;
char *cicp_tuple = NULL;
const GOptionEntry entries[] = { const GOptionEntry entries[] = {
{ "format", 0, 0, G_OPTION_ARG_STRING, &format_name, N_("Format to use"), N_("FORMAT") }, { "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") }, { "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…") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") },
{ NULL, } { NULL, }
}; };
GError *error = NULL; GError *error = NULL;
GdkMemoryFormat format = GDK_MEMORY_DEFAULT; GdkMemoryFormat format = GDK_MEMORY_DEFAULT;
GdkColorState *color_state = gdk_color_state_get_srgb (); GdkColorState *color_state = NULL;
g_set_prgname ("gtk4-image-tool convert"); g_set_prgname ("gtk4-image-tool convert");
context = g_option_context_new (NULL); 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); save_image (filenames[0], filenames[1], format, color_state);
g_strfreev (filenames); g_strfreev (filenames);

View File

@@ -79,13 +79,15 @@ do_relabel (int *argc,
GOptionContext *context; GOptionContext *context;
char **filenames = NULL; char **filenames = NULL;
char *colorstate_name = NULL; char *colorstate_name = NULL;
char *cicp_tuple = NULL;
const GOptionEntry entries[] = { const GOptionEntry entries[] = {
{ "color-state", 0, 0, G_OPTION_ARG_STRING, &colorstate_name, N_("Color state to use"), N_("COLORSTATE") }, { "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…") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") },
{ NULL, } { NULL, }
}; };
GError *error = NULL; GError *error = NULL;
GdkColorState *color_state = gdk_color_state_get_srgb (); GdkColorState *color_state = NULL;
g_set_prgname ("gtk4-image-tool relabel"); g_set_prgname ("gtk4-image-tool relabel");
context = g_option_context_new (NULL); 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); relabel_image (filenames[0], filenames[1], color_state);
g_strfreev (filenames); g_strfreev (filenames);

View File

@@ -221,3 +221,42 @@ get_color_state_name (GdkColorState *color_state)
return name; 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;
}

View File

@@ -17,3 +17,6 @@ GdkColorState * find_color_state_by_name (const char *name);
char ** get_color_state_names (void); char ** get_color_state_names (void);
char * get_color_state_name (GdkColorState *color_state); char * get_color_state_name (GdkColorState *color_state);
GdkColorState *parse_cicp_tuple (const char *cicp_tuple,
GError **error);