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.
This commit is contained in:
Matthias Clasen
2021-09-09 22:23:37 -04:00
parent 5a9c81ab6f
commit 7725c8439c
2 changed files with 126 additions and 20 deletions

View File

@@ -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,36 @@ 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);
g_value_take_object (value, texture);
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 +894,32 @@ init (void)
initialized = TRUE;
gdk_content_register_deserializer ("image/png",
GDK_TYPE_TEXTURE,
png_deserializer,
NULL,
NULL);
formats = gdk_pixbuf_get_formats ();
/* Make sure png comes first */
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
char *name;
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);
{
formats = g_slist_delete_link (formats, f);
formats = g_slist_prepend (formats, fmt);
g_free (name);
break;
}
g_free (name);
break;
}
g_free (name);
}
}
for (f = formats; f; f = f->next)
{

View File

@@ -26,6 +26,8 @@
#include "filetransferportalprivate.h"
#include "gdktextureprivate.h"
#include "gdkrgba.h"
#include "gdkpng.h"
#include "gdkmemorytextureprivate.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <string.h>
@@ -606,6 +608,7 @@ gdk_content_serialize_finish (GAsyncResult *result,
/*** SERIALIZERS ***/
static void
pixbuf_serializer_finish (GObject *source,
GAsyncResult *res,
@@ -658,6 +661,69 @@ 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);
texture = g_value_get_object (value);
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),
gdk_texture_get_width (texture) * gdk_memory_format_bytes_per_pixel (format),
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 +943,31 @@ init (void)
initialized = TRUE;
gdk_content_register_serializer (GDK_TYPE_TEXTURE,
"image/png",
png_serializer,
NULL, NULL);
formats = gdk_pixbuf_get_formats ();
/* Make sure png comes first */
for (f = formats; f; f = f->next)
{
GdkPixbufFormat *fmt = f->data;
char *name;
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);
{
formats = g_slist_delete_link (formats, f);
formats = g_slist_prepend (formats, fmt);
g_free (name);
break;
}
g_free (name);
break;
}
g_free (name);
}
}
for (f = formats; f; f = f->next)
{