[gtk/gamma-shenanigans] Use our png loader for content (de)serialization
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gamma-shenanigans] Use our png loader for content (de)serialization
- Date: Fri, 10 Sep 2021 02:30:44 +0000 (UTC)
commit 6798fcdafcd2cffdc4663ef986e985bd65d437b8
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Sep 9 22:23:37 2021 -0400
Use our png loader for content (de)serialization
We still fall back to gdk-pixbuf for handling all
the other image formats. But with this in place,
we no longer need to tweak the pixbuf formats to
ensure that png comes first.
gdk/gdkcontentdeserializer.c | 64 ++++++++++++++++++++---------
gdk/gdkcontentserializer.c | 96 +++++++++++++++++++++++++++++++++++---------
2 files changed, 120 insertions(+), 40 deletions(-)
---
diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c
index 4959b5af4d..68c6ae2553 100644
--- a/gdk/gdkcontentdeserializer.c
+++ b/gdk/gdkcontentdeserializer.c
@@ -25,6 +25,7 @@
#include "filetransferportalprivate.h"
#include "gdktexture.h"
#include "gdkrgbaprivate.h"
+#include "gdkpng.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -655,6 +656,43 @@ pixbuf_deserializer (GdkContentDeserializer *deserializer)
deserializer);
}
+static void
+png_deserializer_finish (GObject *source,
+ GAsyncResult *res,
+ gpointer deserializer)
+{
+ GdkTexture *texture;
+ GValue *value;
+ GError *error = NULL;
+
+ texture = gdk_load_png_finish (res, &error);
+ if (texture == NULL)
+ {
+ gdk_content_deserializer_return_error (deserializer, error);
+ return;
+ }
+
+ value = gdk_content_deserializer_get_value (deserializer);
+ if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
+ {
+ g_value_take_object (value, texture);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+ gdk_content_deserializer_return_success (deserializer);
+}
+
+static void
+png_deserializer (GdkContentDeserializer *deserializer)
+{
+ gdk_load_png_async (gdk_content_deserializer_get_input_stream (deserializer),
+ gdk_content_deserializer_get_cancellable (deserializer),
+ png_deserializer_finish,
+ deserializer);
+}
+
static void
string_deserializer_finish (GObject *source,
GAsyncResult *result,
@@ -863,27 +901,13 @@ init (void)
initialized = TRUE;
- formats = gdk_pixbuf_get_formats ();
-
- /* Make sure png comes first */
- for (f = formats; f; f = f->next)
- {
- GdkPixbufFormat *fmt = f->data;
- char *name;
-
- name = gdk_pixbuf_format_get_name (fmt);
- if (g_str_equal (name, "png"))
- {
- formats = g_slist_delete_link (formats, f);
- formats = g_slist_prepend (formats, fmt);
-
- g_free (name);
-
- break;
- }
+ gdk_content_register_deserializer ("image/png",
+ GDK_TYPE_TEXTURE,
+ png_deserializer,
+ NULL,
+ NULL);
- g_free (name);
- }
+ formats = gdk_pixbuf_get_formats ();
for (f = formats; f; f = f->next)
{
diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c
index bc9deeb8d5..bf29c5cf0b 100644
--- a/gdk/gdkcontentserializer.c
+++ b/gdk/gdkcontentserializer.c
@@ -26,6 +26,7 @@
#include "filetransferportalprivate.h"
#include "gdktextureprivate.h"
#include "gdkrgba.h"
+#include "gdkpng.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <string.h>
@@ -606,6 +607,7 @@ gdk_content_serialize_finish (GAsyncResult *result,
/*** SERIALIZERS ***/
+
static void
pixbuf_serializer_finish (GObject *source,
GAsyncResult *res,
@@ -658,6 +660,75 @@ pixbuf_serializer (GdkContentSerializer *serializer)
g_object_unref (pixbuf);
}
+typedef struct {
+ GdkContentSerializer *serializer;
+ GBytes *bytes;
+} PngSerializerData;
+
+static void
+png_serializer_finish (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ PngSerializerData *data = user_data;
+ GError *error = NULL;
+
+ if (!gdk_save_png_finish (res, &error))
+ gdk_content_serializer_return_error (data->serializer, error);
+ else
+ gdk_content_serializer_return_success (data->serializer);
+
+ g_bytes_unref (data->bytes);
+ g_free (data);
+}
+
+static void
+png_serializer (GdkContentSerializer *serializer)
+{
+ const GValue *value;
+ GdkTexture *texture;
+ GdkMemoryFormat format;
+ GBytes *bytes = NULL;
+ PngSerializerData *data;
+
+ value = gdk_content_serializer_get_value (serializer);
+
+ if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE))
+ {
+ texture = g_value_get_object (value);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ for (int i = 0; i < GDK_MEMORY_N_FORMATS; i++)
+ {
+ bytes = gdk_texture_download_format (texture, i);
+ if (bytes)
+ {
+ format = i;
+ break;
+ }
+ }
+
+ g_assert (bytes != NULL);
+
+ data = g_new0 (PngSerializerData, 1);
+ data->serializer = serializer;
+ data->bytes = bytes;
+
+ gdk_save_png_async (gdk_content_serializer_get_output_stream (serializer),
+ g_bytes_get_data (bytes, NULL),
+ gdk_texture_get_width (texture),
+ gdk_texture_get_height (texture),
+ format,
+ gdk_content_serializer_get_cancellable (serializer),
+ png_serializer_finish,
+ data);
+ g_object_unref (texture);
+}
+
static void
string_serializer_finish (GObject *source,
GAsyncResult *result,
@@ -877,27 +948,12 @@ init (void)
initialized = TRUE;
- formats = gdk_pixbuf_get_formats ();
-
- /* Make sure png comes first */
- for (f = formats; f; f = f->next)
- {
- GdkPixbufFormat *fmt = f->data;
- char *name;
-
- name = gdk_pixbuf_format_get_name (fmt);
- if (g_str_equal (name, "png"))
- {
- formats = g_slist_delete_link (formats, f);
- formats = g_slist_prepend (formats, fmt);
-
- g_free (name);
+ gdk_content_register_serializer (GDK_TYPE_TEXTURE,
+ "image/png",
+ png_serializer,
+ NULL, NULL);
- break;
- }
-
- g_free (name);
- }
+ formats = gdk_pixbuf_get_formats ();
for (f = formats; f; f = f->next)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]