mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 05:31:07 +00:00
Add an image tool
This is meant to provide a convenient way to produce images in specific color states and memory formats.
This commit is contained in:
parent
cc8fa39110
commit
5ae225fe52
82
docs/reference/gtk/gtk4-image-tool.rst
Normal file
82
docs/reference/gtk/gtk4-image-tool.rst
Normal file
@ -0,0 +1,82 @@
|
||||
.. _gtk4-image-tool(1):
|
||||
|
||||
====================
|
||||
gtk4-image-tool
|
||||
====================
|
||||
|
||||
-----------------------
|
||||
Image Utility
|
||||
-----------------------
|
||||
|
||||
:Version: GTK
|
||||
:Manual section: 1
|
||||
:Manual group: GTK commands
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
| **gtk4-image-tool** <COMMAND> [OPTIONS...] <FILE>...
|
||||
|
|
||||
| **gtk4-image-tool** compare [OPTIONS...] <FILE1> <FILE2>
|
||||
| **gtk4-image-tool** convert [OPTIONS...] <FILE1> <FILE2>
|
||||
| **gtk4-image-tool** info [OPTIONS...] <FILE>
|
||||
| **gtk4-image-tool** relabel [OPTIONS...] <FILE1> <FILE2>
|
||||
| **gtk4-image-tool** show [OPTIONS...] <FILE>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
``gtk4-image-tool`` can perform various operations on images.
|
||||
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
Information
|
||||
^^^^^^^^^^^
|
||||
|
||||
The ``info`` command shows general information about the image, such
|
||||
as its format and color state.
|
||||
|
||||
Showing
|
||||
^^^^^^^
|
||||
|
||||
The ``show`` command displays the image.
|
||||
|
||||
Compare
|
||||
^^^^^^^
|
||||
|
||||
The ``compare`` command compares two images. If any differences are found,
|
||||
the exit code is 1. If the images are identical, it is 0.
|
||||
|
||||
``--output=FILE``
|
||||
|
||||
Save the differences as a png image in ``FILE``.
|
||||
|
||||
``--quiet``
|
||||
|
||||
Don't write results to stdout.
|
||||
|
||||
Conversion
|
||||
^^^^^^^^^^
|
||||
|
||||
The ``convert`` command converts the image to a different format or color state.
|
||||
|
||||
``--format=FORMAT``
|
||||
|
||||
Convert to the given format. The supported formats can be listed
|
||||
with ``--format=list``.
|
||||
|
||||
``--color-state=COLORSTATE``
|
||||
|
||||
Convert to the given color state. The supported color states can be
|
||||
listed with ``--format=list``.
|
||||
|
||||
Relabeling
|
||||
^^^^^^^^^^
|
||||
|
||||
The ``relabel`` command changes the color state of an image without conversion.
|
||||
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
|
||||
listed with ``--format=list``.
|
@ -85,6 +85,7 @@ rst_files = [
|
||||
[ 'gtk4-broadwayd', '1' ],
|
||||
[ 'gtk4-builder-tool', '1' ],
|
||||
[ 'gtk4-encode-symbolic-svg', '1', ],
|
||||
[ 'gtk4-image-tool', '1' ],
|
||||
[ 'gtk4-launch', '1', ],
|
||||
[ 'gtk4-query-settings', '1', ],
|
||||
[ 'gtk4-rendernode-tool', '1' ],
|
||||
|
121
tools/gtk-image-tool-compare.c
Normal file
121
tools/gtk-image-tool-compare.c
Normal file
@ -0,0 +1,121 @@
|
||||
/* 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"
|
||||
|
||||
#include "testsuite/reftests/reftest-compare.h"
|
||||
|
||||
void
|
||||
do_compare (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
gboolean opt_quiet = FALSE;
|
||||
char **filenames = NULL;
|
||||
char *opt_filename = NULL;
|
||||
const GOptionEntry entries[] = {
|
||||
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &opt_filename, N_("Output file"), N_("FILE") },
|
||||
{ "quiet", 'q', 0, G_OPTION_ARG_NONE, &opt_quiet, "Don't talk", NULL },
|
||||
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE…") },
|
||||
{ NULL, }
|
||||
};
|
||||
GdkTexture *texture[2];
|
||||
GdkTexture *diff;
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_prgname ("gtk4-image-tool compare");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Compare two images"));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No image file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) != 2)
|
||||
{
|
||||
g_printerr (_("Can only accept two image files\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
texture[i] = gdk_texture_new_from_filename (filenames[i], &error);
|
||||
if (texture[i] == NULL)
|
||||
{
|
||||
g_printerr (_("Failed to load %s: %s\n"), filenames[i], error->message);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
diff = reftest_compare_textures (texture[0], texture[1]);
|
||||
|
||||
if (opt_filename && diff)
|
||||
{
|
||||
if (!gdk_texture_save_to_png (diff, opt_filename))
|
||||
{
|
||||
g_printerr (_("Could not save diff image to %s\n"), opt_filename);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!opt_quiet)
|
||||
{
|
||||
if (diff)
|
||||
{
|
||||
if (opt_filename)
|
||||
g_print (_("Differences witten to %s.\n"), opt_filename);
|
||||
else
|
||||
g_print (_("The images are different.\n"));
|
||||
}
|
||||
else
|
||||
g_print (_("No differences.\n"));
|
||||
}
|
||||
|
||||
if (diff)
|
||||
exit (1);
|
||||
|
||||
g_strfreev (filenames);
|
||||
g_free (opt_filename);
|
||||
g_object_unref (texture[0]);
|
||||
g_object_unref (texture[1]);
|
||||
}
|
157
tools/gtk-image-tool-convert.c
Normal file
157
tools/gtk-image-tool-convert.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* 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"
|
||||
|
||||
|
||||
static void
|
||||
save_image (const char *filename,
|
||||
const char *output,
|
||||
GdkMemoryFormat format,
|
||||
GdkColorState *color_state)
|
||||
{
|
||||
GdkTexture *orig;
|
||||
GdkTextureDownloader *downloader;
|
||||
GBytes *bytes;
|
||||
gsize stride;
|
||||
GdkTexture *texture;
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
|
||||
orig = load_image_file (filename);
|
||||
downloader = gdk_texture_downloader_new (orig);
|
||||
|
||||
gdk_texture_downloader_set_format (downloader, format);
|
||||
gdk_texture_downloader_set_color_state (downloader, color_state);
|
||||
|
||||
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
|
||||
|
||||
builder = gdk_memory_texture_builder_new ();
|
||||
gdk_memory_texture_builder_set_bytes (builder, bytes);
|
||||
gdk_memory_texture_builder_set_stride (builder, stride);
|
||||
gdk_memory_texture_builder_set_format (builder, format);
|
||||
gdk_memory_texture_builder_set_color_state (builder, color_state);
|
||||
gdk_memory_texture_builder_set_width (builder, gdk_texture_get_width (orig));
|
||||
gdk_memory_texture_builder_set_height (builder, gdk_texture_get_height (orig));
|
||||
|
||||
texture = gdk_memory_texture_builder_build (builder);
|
||||
|
||||
if (g_str_has_suffix (output, ".tiff"))
|
||||
gdk_texture_save_to_tiff (texture, output);
|
||||
else
|
||||
gdk_texture_save_to_png (texture, output);
|
||||
|
||||
g_object_unref (texture);
|
||||
g_bytes_unref (bytes);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
g_object_unref (orig);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
void
|
||||
do_convert (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
char **filenames = NULL;
|
||||
char *format_name = NULL;
|
||||
char *colorstate_name = 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") },
|
||||
{ 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 ();
|
||||
|
||||
g_set_prgname ("gtk4-image-tool convert");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Convert the image to a different format or color state."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No image file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) != 2)
|
||||
{
|
||||
g_printerr (_("Can only accept a single image file and output file\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (format_name)
|
||||
{
|
||||
if (!find_format_by_name (format_name, &format))
|
||||
{
|
||||
char **names;
|
||||
char *suggestion;
|
||||
|
||||
names = get_format_names ();
|
||||
suggestion = g_strjoinv ("\n ", names);
|
||||
|
||||
g_printerr (_("Not a memory format: %s\nPossible values:\n %s\n"),
|
||||
format_name, suggestion);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (colorstate_name)
|
||||
{
|
||||
color_state = find_color_state_by_name (colorstate_name);
|
||||
if (!color_state)
|
||||
{
|
||||
char **names;
|
||||
char *suggestion;
|
||||
|
||||
names = get_color_state_names ();
|
||||
suggestion = g_strjoinv ("\n ", names);
|
||||
|
||||
g_printerr (_("Not a color state: %s\nPossible values:\n %s\n"),
|
||||
colorstate_name, suggestion);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
save_image (filenames[0], filenames[1], format, color_state);
|
||||
|
||||
g_strfreev (filenames);
|
||||
}
|
103
tools/gtk-image-tool-info.c
Normal file
103
tools/gtk-image-tool-info.c
Normal file
@ -0,0 +1,103 @@
|
||||
/* 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"
|
||||
|
||||
static const char *
|
||||
get_format_name (GdkMemoryFormat format)
|
||||
{
|
||||
GEnumClass *class;
|
||||
GEnumValue *value;
|
||||
const char *name;
|
||||
|
||||
class = g_type_class_ref (GDK_TYPE_MEMORY_FORMAT);
|
||||
value = g_enum_get_value (class, format);
|
||||
name = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static void
|
||||
file_info (const char *filename)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
|
||||
texture = load_image_file (filename);
|
||||
|
||||
g_print ("%s %dx%d\n", _("Size:"), gdk_texture_get_width (texture), gdk_texture_get_height (texture));
|
||||
g_print ("%s %s\n", _("Format:"), get_format_name (gdk_texture_get_format (texture)));
|
||||
g_print ("%s %s\n", _("Color state:"), get_color_state_name (gdk_texture_get_color_state (texture)));
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
void
|
||||
do_info (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
char **filenames = NULL;
|
||||
const GOptionEntry entries[] = {
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") },
|
||||
{ NULL, }
|
||||
};
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_prgname ("gtk4-image-tool info");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Provide information about the image."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No image file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) > 1)
|
||||
{
|
||||
g_printerr (_("Can only accept a single image file\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
file_info (filenames[0]);
|
||||
|
||||
g_strfreev (filenames);
|
||||
}
|
137
tools/gtk-image-tool-relabel.c
Normal file
137
tools/gtk-image-tool-relabel.c
Normal file
@ -0,0 +1,137 @@
|
||||
/* 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"
|
||||
|
||||
|
||||
static void
|
||||
relabel_image (const char *filename,
|
||||
const char *output,
|
||||
GdkColorState *color_state)
|
||||
{
|
||||
GdkTexture *orig;
|
||||
GdkTextureDownloader *downloader;
|
||||
GBytes *bytes;
|
||||
gsize stride;
|
||||
GdkTexture *texture;
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
|
||||
orig = load_image_file (filename);
|
||||
downloader = gdk_texture_downloader_new (orig);
|
||||
|
||||
gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (orig));
|
||||
gdk_texture_downloader_set_color_state (downloader, gdk_texture_get_color_state (orig));
|
||||
|
||||
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
|
||||
|
||||
builder = gdk_memory_texture_builder_new ();
|
||||
gdk_memory_texture_builder_set_bytes (builder, bytes);
|
||||
gdk_memory_texture_builder_set_stride (builder, stride);
|
||||
gdk_memory_texture_builder_set_width (builder, gdk_texture_get_width (orig));
|
||||
gdk_memory_texture_builder_set_height (builder, gdk_texture_get_height (orig));
|
||||
gdk_memory_texture_builder_set_format (builder, gdk_texture_get_format (orig));
|
||||
gdk_memory_texture_builder_set_color_state (builder, color_state);
|
||||
|
||||
texture = gdk_memory_texture_builder_build (builder);
|
||||
|
||||
if (g_str_has_suffix (output, ".tiff"))
|
||||
gdk_texture_save_to_tiff (texture, output);
|
||||
else
|
||||
gdk_texture_save_to_png (texture, output);
|
||||
|
||||
g_object_unref (texture);
|
||||
g_bytes_unref (bytes);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
g_object_unref (orig);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
void
|
||||
do_relabel (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
char **filenames = NULL;
|
||||
char *colorstate_name = NULL;
|
||||
const GOptionEntry entries[] = {
|
||||
{ "color-state", 0, 0, G_OPTION_ARG_STRING, &colorstate_name, N_("Color state to use"), N_("COLORSTATE") },
|
||||
{ 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 ();
|
||||
|
||||
g_set_prgname ("gtk4-image-tool relabel");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Change the color state of the image without conversion."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No image file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) != 2)
|
||||
{
|
||||
g_printerr (_("Can only accept a single image file and output file\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (colorstate_name)
|
||||
{
|
||||
color_state = find_color_state_by_name (colorstate_name);
|
||||
if (!color_state)
|
||||
{
|
||||
char **names;
|
||||
char *suggestion;
|
||||
|
||||
names = get_color_state_names ();
|
||||
suggestion = g_strjoinv (", ", names);
|
||||
|
||||
g_printerr (_("Not a color state: %s\nPossible values: %s\n"),
|
||||
colorstate_name, suggestion);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
relabel_image (filenames[0], filenames[1], color_state);
|
||||
|
||||
g_strfreev (filenames);
|
||||
}
|
129
tools/gtk-image-tool-show.c
Normal file
129
tools/gtk-image-tool-show.c
Normal file
@ -0,0 +1,129 @@
|
||||
/* 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"
|
||||
|
||||
static void
|
||||
set_window_title (GtkWindow *window,
|
||||
const char *filename)
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = g_path_get_basename (filename);
|
||||
gtk_window_set_title (window, name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
quit_cb (GtkWidget *widget,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean *is_done = user_data;
|
||||
|
||||
*is_done = TRUE;
|
||||
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
show_file (const char *filename)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *window;
|
||||
gboolean done = FALSE;
|
||||
GtkWidget *picture;
|
||||
|
||||
texture = load_image_file (filename);
|
||||
|
||||
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
|
||||
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_SCALE_DOWN);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), picture);
|
||||
|
||||
window = gtk_window_new ();
|
||||
set_window_title (GTK_WINDOW (window), filename);
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
void
|
||||
do_show (int *argc,
|
||||
const char ***argv)
|
||||
{
|
||||
GOptionContext *context;
|
||||
char **filenames = NULL;
|
||||
const GOptionEntry entries[] = {
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, N_("FILE") },
|
||||
{ NULL, }
|
||||
};
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_prgname ("gtk4-image-tool show");
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Show the image."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (filenames == NULL)
|
||||
{
|
||||
g_printerr (_("No image file specified\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (g_strv_length (filenames) > 1)
|
||||
{
|
||||
g_printerr (_("Can only accept a single image file\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
show_file (filenames[0]);
|
||||
|
||||
g_strfreev (filenames);
|
||||
}
|
223
tools/gtk-image-tool-utils.c
Normal file
223
tools/gtk-image-tool-utils.c
Normal file
@ -0,0 +1,223 @@
|
||||
/* 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;
|
||||
}
|
127
tools/gtk-image-tool.c
Normal file
127
tools/gtk-image-tool.c
Normal file
@ -0,0 +1,127 @@
|
||||
/* 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"
|
||||
|
||||
|
||||
static void G_GNUC_NORETURN
|
||||
usage (void)
|
||||
{
|
||||
g_print (_("Usage:\n"
|
||||
" gtk4-image-tool [COMMAND] [OPTION…] FILE…\n"
|
||||
"\n"
|
||||
"Perform various tasks on images.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" compare Show differences between two images\n"
|
||||
" convert Convert the image to a different format or color state\n"
|
||||
" info Show general information about the image\n"
|
||||
" relabel Change the color state of the image without conversion\n"
|
||||
" show Show the image\n"
|
||||
"\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
static GLogWriterOutput
|
||||
log_writer_func (GLogLevelFlags level,
|
||||
const GLogField *fields,
|
||||
gsize n_fields,
|
||||
gpointer user_data)
|
||||
{
|
||||
gsize i;
|
||||
const char *domain = NULL;
|
||||
const char *message = NULL;
|
||||
|
||||
for (i = 0; i < n_fields; i++)
|
||||
{
|
||||
if (g_strcmp0 (fields[i].key, "GLIB_DOMAIN") == 0)
|
||||
domain = fields[i].value;
|
||||
else if (g_strcmp0 (fields[i].key, "MESSAGE") == 0)
|
||||
message = fields[i].value;
|
||||
}
|
||||
|
||||
if (message != NULL && !g_log_writer_default_would_drop (level, domain))
|
||||
{
|
||||
const char *prefix;
|
||||
switch (level & G_LOG_LEVEL_MASK)
|
||||
{
|
||||
case G_LOG_LEVEL_ERROR:
|
||||
prefix = "ERROR";
|
||||
break;
|
||||
case G_LOG_LEVEL_CRITICAL:
|
||||
prefix = "CRITICAL";
|
||||
break;
|
||||
case G_LOG_LEVEL_WARNING:
|
||||
prefix = "WARNING";
|
||||
break;
|
||||
default:
|
||||
prefix = "INFO";
|
||||
break;
|
||||
}
|
||||
g_printerr ("%s-%s: %s\n", domain, prefix, message);
|
||||
}
|
||||
|
||||
return G_LOG_WRITER_HANDLED;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, const char *argv[])
|
||||
{
|
||||
g_set_prgname ("gtk-image-tool");
|
||||
|
||||
g_log_set_writer_func (log_writer_func, NULL, NULL);
|
||||
|
||||
gtk_init_check ();
|
||||
|
||||
gtk_test_register_all_types ();
|
||||
|
||||
if (argc < 2)
|
||||
usage ();
|
||||
|
||||
if (strcmp (argv[1], "--help") == 0)
|
||||
usage ();
|
||||
|
||||
argv++;
|
||||
argc--;
|
||||
|
||||
if (strcmp (argv[0], "compare") == 0)
|
||||
do_compare (&argc, &argv);
|
||||
else if (strcmp (argv[0], "convert") == 0)
|
||||
do_convert (&argc, &argv);
|
||||
else if (strcmp (argv[0], "info") == 0)
|
||||
do_info (&argc, &argv);
|
||||
else if (strcmp (argv[0], "relabel") == 0)
|
||||
do_relabel (&argc, &argv);
|
||||
else if (strcmp (argv[0], "show") == 0)
|
||||
do_show (&argc, &argv);
|
||||
else
|
||||
usage ();
|
||||
|
||||
return 0;
|
||||
}
|
19
tools/gtk-image-tool.h
Normal file
19
tools/gtk-image-tool.h
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
void do_compare (int *argc, const char ***argv);
|
||||
void do_convert (int *argc, const char ***argv);
|
||||
void do_info (int *argc, const char ***argv);
|
||||
void do_relabel (int *argc, const char ***argv);
|
||||
void do_show (int *argc, const char ***argv);
|
||||
|
||||
GdkTexture * load_image_file (const char *filename);
|
||||
|
||||
|
||||
gboolean find_format_by_name (const char *name,
|
||||
GdkMemoryFormat *format);
|
||||
char ** get_format_names (void);
|
||||
GdkColorState * find_color_state_by_name (const char *name);
|
||||
|
||||
char ** get_color_state_names (void);
|
||||
char * get_color_state_name (GdkColorState *color_state);
|
@ -49,6 +49,14 @@ gtk_tools = [
|
||||
'gtk-rendernode-tool-show.c',
|
||||
'gtk-rendernode-tool-utils.c',
|
||||
'../testsuite/reftests/reftest-compare.c'], [libgtk_dep] ],
|
||||
['gtk4-image-tool', ['gtk-image-tool.c',
|
||||
'gtk-image-tool-info.c',
|
||||
'gtk-image-tool-compare.c',
|
||||
'gtk-image-tool-convert.c',
|
||||
'gtk-image-tool-relabel.c',
|
||||
'gtk-image-tool-show.c',
|
||||
'gtk-image-tool-utils.c',
|
||||
'../testsuite/reftests/reftest-compare.c'], [libgtk_dep] ],
|
||||
['gtk4-update-icon-cache', ['updateiconcache.c', '../gtk/gtkiconcachevalidator.c' ] + extra_update_icon_cache_objs, [ libgtk_dep ] ],
|
||||
['gtk4-encode-symbolic-svg', ['encodesymbolic.c'], [ libgtk_static_dep ] ],
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user