Here is a very quick attempt to wrap an gio outputstream around a pixbuf loader. This allows you to splice an input stream onto it, and pull a pixbuf out of the loader:
#include "gio.h"
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
typedef struct _GdkPixbufOutputStream GdkPixbufOutputStream;
typedef struct _GOutputStreamClass GdkPixbufOutputStreamClass;
struct _GdkPixbufOutputStream
{
GOutputStream parent;
GdkPixbufLoader *loader;
};
G_DEFINE_TYPE (GdkPixbufOutputStream, gdk_pixbuf_output_stream, G_TYPE_OUTPUT_STREAM)
static gssize
gdk_pixbuf_output_stream_write (GOutputStream *stream,
const void *buffer,
gsize count,
GCancellable *cancellable,
GError **error)
{
GdkPixbufOutputStream *pbos = (GdkPixbufOutputStream *)stream;
if (gdk_pixbuf_loader_write (pbos->loader, buffer, count, error))
return count;
else
return -1;
}
static gboolean
gdk_pixbuf_output_stream_flush (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
return TRUE;
}
static gboolean
gdk_pixbuf_output_stream_close (GOutputStream *stream,
GCancellable *cancellable,
GError **error)
{
GdkPixbufOutputStream *pbos = (GdkPixbufOutputStream *)stream;
return gdk_pixbuf_loader_close (pbos->loader, error);
}
static void
gdk_pixbuf_output_stream_finalize (GObject *object)
{
GdkPixbufOutputStream *stream = (GdkPixbufOutputStream *)object;
g_object_unref (stream->loader);
G_OBJECT_CLASS (gdk_pixbuf_output_stream_parent_class)->finalize (object);
}
static void
gdk_pixbuf_output_stream_class_init (GdkPixbufOutputStreamClass *class)
{
GObjectClass *object_class = (GObjectClass *)class;
GOutputStreamClass *osclass = class;
object_class->finalize = gdk_pixbuf_output_stream_finalize;
osclass->write = gdk_pixbuf_output_stream_write;
osclass->flush = gdk_pixbuf_output_stream_flush;
osclass->close = gdk_pixbuf_output_stream_close;
}
static void
gdk_pixbuf_output_stream_init (GdkPixbufOutputStream *stream)
{
stream->loader = gdk_pixbuf_loader_new ();
}
static GdkPixbufOutputStream *
gdk_pixbuf_output_stream_new (void)
{
return g_object_new (gdk_pixbuf_output_stream_get_type (), NULL);
}
int main (int argc, char *argv[])
{
GtkWidget *window, *image;
GFile *file;
GFileInputStream *in;
GdkPixbufOutputStream *out;
GdkPixbuf *pixbuf;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
image = gtk_image_new ();
file = g_file_new_for_commandline_arg (argv[1]);
in = g_file_read (file, NULL, NULL);
out = gdk_pixbuf_output_stream_new ();
g_output_stream_splice (G_OUTPUT_STREAM (out), G_INPUT_STREAM (in),
G_OUTPUT_STREAM_SPLICE_FLAGS_CLOSE_SOURCE|
G_OUTPUT_STREAM_SPLICE_FLAGS_CLOSE_TARGET,
NULL, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf (out->loader);
g_object_ref (pixbuf);
gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
gtk_container_add (GTK_CONTAINER (window), image);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}