mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-29 06:51:10 +00:00
a60cda3daa
Accept --cicp=1/13/6/0 and similar to specify color states.
263 lines
7.1 KiB
C
263 lines
7.1 KiB
C
/* Copyright 2024 Red Hat, Inc.
|
|
*
|
|
* GTK is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* GTK 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with GTK; see the file COPYING. If not,
|
|
* see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Matthias Clasen
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <glib/gi18n-lib.h>
|
|
#include <glib/gprintf.h>
|
|
#include <glib/gstdio.h>
|
|
#include <gtk/gtk.h>
|
|
#include "gtk-image-tool.h"
|
|
|
|
|
|
GdkTexture *
|
|
load_image_file (const char *filename)
|
|
{
|
|
GError *error = NULL;
|
|
GdkTexture *texture;
|
|
|
|
texture = gdk_texture_new_from_filename (filename, &error);
|
|
if (!texture)
|
|
{
|
|
g_printerr ("%s\n", error->message);
|
|
g_error_free (error);
|
|
exit (1);
|
|
}
|
|
|
|
return texture;
|
|
}
|
|
|
|
gboolean
|
|
find_format_by_name (const char *name,
|
|
GdkMemoryFormat *format)
|
|
{
|
|
GEnumClass *class;
|
|
GEnumValue *value;
|
|
|
|
class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT);
|
|
|
|
value = g_enum_get_value_by_nick (class, name);
|
|
if (value)
|
|
*format = value->value;
|
|
|
|
g_type_class_unref (class);
|
|
|
|
return value != NULL;
|
|
}
|
|
|
|
char **
|
|
get_format_names (void)
|
|
{
|
|
GEnumClass *class;
|
|
GStrvBuilder *builder;
|
|
char **res;
|
|
|
|
builder = g_strv_builder_new ();
|
|
class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT);
|
|
|
|
for (int i = 0; i < class->n_values; i++)
|
|
{
|
|
if (class->values[i].value == GDK_MEMORY_N_FORMATS)
|
|
continue;
|
|
g_strv_builder_add (builder, class->values[i].value_nick);
|
|
}
|
|
|
|
g_type_class_unref (class);
|
|
|
|
res = g_strv_builder_end (builder);
|
|
|
|
g_strv_builder_unref (builder);
|
|
|
|
return res;
|
|
}
|
|
|
|
GdkColorState *
|
|
find_color_state_by_name (const char *name)
|
|
{
|
|
GdkCicpParams *params = NULL;
|
|
GdkColorState *color_state = NULL;
|
|
GError *error = NULL;
|
|
|
|
if (g_strcmp0 (name, "srgb") == 0)
|
|
color_state = gdk_color_state_get_srgb ();
|
|
else if (g_strcmp0 (name, "srgb-linear") == 0)
|
|
color_state = gdk_color_state_get_srgb_linear ();
|
|
else if (g_strcmp0 (name, "rec2100-pq") == 0)
|
|
color_state = gdk_color_state_get_rec2100_pq ();
|
|
else if (g_strcmp0 (name, "rec2100-linear") == 0)
|
|
color_state = gdk_color_state_get_rec2100_linear ();
|
|
else if (g_strcmp0 (name, "display-p3") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 12);
|
|
gdk_cicp_params_set_transfer_function (params, 13);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 0);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
else if (g_strcmp0 (name, "xyz") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 10);
|
|
gdk_cicp_params_set_transfer_function (params, 8);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 0);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
else if (g_strcmp0 (name, "rec2020") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 9);
|
|
gdk_cicp_params_set_transfer_function (params, 1);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 0);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
else if (g_strcmp0 (name, "rec2100-hlg") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 9);
|
|
gdk_cicp_params_set_transfer_function (params, 18);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 0);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
else if (g_strcmp0 (name, "yuv") == 0 ||
|
|
g_strcmp0 (name, "bt601") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 1);
|
|
gdk_cicp_params_set_transfer_function (params, 13);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 6);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_NARROW);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
else if (g_strcmp0 (name, "bt709") == 0)
|
|
{
|
|
params = gdk_cicp_params_new ();
|
|
|
|
gdk_cicp_params_set_color_primaries (params, 1);
|
|
gdk_cicp_params_set_transfer_function (params, 1);
|
|
gdk_cicp_params_set_matrix_coefficients (params, 6);
|
|
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_NARROW);
|
|
|
|
color_state = gdk_cicp_params_build_color_state (params, &error);
|
|
}
|
|
|
|
if (error)
|
|
{
|
|
g_printerr ("%s\n", error->message);
|
|
g_error_free (error);
|
|
exit (1);
|
|
}
|
|
|
|
g_clear_object (¶ms);
|
|
|
|
return color_state;
|
|
}
|
|
|
|
char **
|
|
get_color_state_names (void)
|
|
{
|
|
static const char *names[] = {
|
|
"srgb", "srgb-linear", "display-p3", "xyz", "rec2020",
|
|
"rec2100-pq", "rec2100-linear", "rec2100-hlg",
|
|
"yuv", "bt601", "bt709",
|
|
NULL,
|
|
};
|
|
|
|
return g_strdupv ((char **) names);
|
|
}
|
|
|
|
char *
|
|
get_color_state_name (GdkColorState *color_state)
|
|
{
|
|
char **names;
|
|
char *name = NULL;
|
|
|
|
names = get_color_state_names ();
|
|
|
|
for (int i = 0; names[i]; i++)
|
|
{
|
|
GdkColorState *cs = find_color_state_by_name (names[i]);
|
|
if (gdk_color_state_equal (cs, color_state))
|
|
{
|
|
name = g_strdup (names[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_strfreev (names);
|
|
|
|
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;
|
|
}
|