[gegl] png-load: Port to GIO, add 'uri' property
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] png-load: Port to GIO, add 'uri' property
- Date: Sun, 9 Nov 2014 19:12:00 +0000 (UTC)
commit d13869f34a66e9cb6ec66cfe637e5fce5d049270
Author: Jon Nordby <jononor gmail com>
Date: Sun Nov 9 17:45:14 2014 +0100
png-load: Port to GIO, add 'uri' property
Allows loading PNG files from any uri scheme supported by GIO/GVFS,
including HTTP, SMB, FTP etc.
Note: Currently does not support stdin (path='-')
operations/external/png-load.c | 150 +++++++++++++++++++++++++---------------
1 files changed, 95 insertions(+), 55 deletions(-)
---
diff --git a/operations/external/png-load.c b/operations/external/png-load.c
index 93a1dfc..d3b34c6 100644
--- a/operations/external/png-load.c
+++ b/operations/external/png-load.c
@@ -20,12 +20,15 @@
#include "config.h"
#include <glib/gi18n-lib.h>
-
+#include <gio/gio.h>
#ifdef GEGL_PROPERTIES
property_file_path (path, _("File"), "")
description (_("Path of file to load."))
+// TODO: use dedicated property spec for URI
+property_string (uri, _("URI"), "")
+ description (_("URI for file to load."))
#else
@@ -35,46 +38,86 @@ property_file_path (path, _("File"), "")
#include "gegl-op.h"
#include <png.h>
-static FILE * open_png(const gchar *path)
+static void
+read_fn(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ GError *err = NULL;
+ GInputStream *stream = G_INPUT_STREAM(png_get_io_ptr(png_ptr));
+ gboolean success = FALSE;
+ gsize bytes_read = 0;
+ g_assert(stream);
+
+ success = g_input_stream_read_all(stream, buffer, length, &bytes_read, NULL, &err);
+ if (!success) {
+ g_printerr("gegl:load-png %s: %s\n", __PRETTY_FUNCTION__, err->message);
+ }
+}
+
+static void
+error_fn(png_structp png_ptr, png_const_charp msg)
{
- FILE *infile;
+ g_printerr("LIBPNG ERROR: %s", msg);
+}
+
+static GFile * open_png(const gchar *uri, const gchar *path)
+{
+ GError *err = NULL;
+ GFile *infile = NULL;
+ GInputStream *fis = NULL;
const size_t hdr_size=8;
- size_t hdr_read_size;
+ gssize hdr_read_size;
unsigned char header[hdr_size];
- if (!strcmp (path, "-"))
+ g_return_val_if_fail(uri || path, NULL);
+
+ if (strlen(uri) > 0)
{
- infile = stdin;
+ infile = g_file_new_for_uri(uri);
}
- else
+ else if (g_strcmp0 (path, "-") == 0)
{
- infile = fopen (path, "rb");
+ //infile = stdin; // FIXME: implement
+ g_assert(FALSE);
}
- if (!infile)
+ else
{
- return infile;
+ infile = g_file_new_for_path(path);
}
+ g_return_val_if_fail(infile, NULL);
- if((hdr_read_size=fread(header, 1, hdr_size, infile))!=hdr_size)
+ fis = G_INPUT_STREAM(g_file_read(infile, NULL, &err));
+ hdr_read_size = g_input_stream_read(G_INPUT_STREAM(fis), header, hdr_size, NULL, &err);
+ if (hdr_read_size != hdr_size)
{
- fclose(infile);
- g_warning ("%s is too short for a png file, only %lu bytes.",
- path, (unsigned long)hdr_read_size);
+ g_input_stream_close(fis, NULL, NULL);
+ g_object_unref(fis);
+
+ if (err) {
+ g_printerr("%s", err->message);
+ } else {
+ g_warning ("%s is too short for a png file, only %lu bytes.",
+ path, (unsigned long)hdr_read_size);
+ }
+
return NULL;
}
if (png_sig_cmp (header, 0, hdr_size))
{
- fclose (infile);
+ g_input_stream_close(fis, NULL, NULL);
+ g_object_unref(fis);
g_warning ("%s is not a png file", path);
return NULL;
}
+
+ g_input_stream_close(fis, NULL, NULL); // consumer should open new
+ g_object_unref(fis);
return infile;
}
static gint
gegl_buffer_import_png (GeglBuffer *gegl_buffer,
- const gchar *path,
+ GInputStream *stream,
gint dest_x,
gint dest_y,
gint *ret_width,
@@ -87,7 +130,6 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
gint number_of_passes=1;
png_uint_32 w;
png_uint_32 h;
- FILE *infile;
png_structp load_png_ptr;
png_infop load_info_ptr;
guchar *pixels;
@@ -97,18 +139,12 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
unsigned int i;
png_bytep *row_p = NULL;
- infile = open_png (path);
+ g_return_val_if_fail(stream, -1);
- if (!infile)
- {
- return -1;
- }
-
- load_png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ load_png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, error_fn, NULL);
if (!load_png_ptr)
{
- fclose (infile);
return -1;
}
@@ -116,7 +152,6 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
if (!load_info_ptr)
{
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return -1;
}
@@ -125,12 +160,12 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
if (row_p)
g_free (row_p);
- fclose (infile);
return -1;
}
- png_init_io (load_png_ptr, infile);
- png_set_sig_bytes (load_png_ptr, 8);
+ png_set_read_fn(load_png_ptr, stream, read_fn);
+
+// png_set_sig_bytes (load_png_ptr, 8);
png_read_info (load_png_ptr, load_info_ptr);
{
int color_type;
@@ -184,7 +219,6 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
default:
g_warning ("color type mismatch");
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return -1;
}
@@ -244,36 +278,26 @@ gegl_buffer_import_png (GeglBuffer *gegl_buffer,
g_free (pixels);
- if (infile!=stdin)
- fclose (infile);
-
return 0;
}
-static gint query_png (const gchar *path,
+static gint query_png (GInputStream *stream,
gint *width,
gint *height,
gpointer *format)
{
png_uint_32 w;
png_uint_32 h;
- FILE *infile;
png_structp load_png_ptr;
png_infop load_info_ptr;
png_bytep *row_p = NULL;
- infile = open_png (path);
+ g_return_val_if_fail(stream, -1);
- if (!infile)
- {
- return -1;
- }
-
- load_png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ load_png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, error_fn, NULL);
if (!load_png_ptr)
{
- fclose (infile);
return -1;
}
@@ -281,7 +305,6 @@ static gint query_png (const gchar *path,
if (!load_info_ptr)
{
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return -1;
}
@@ -290,12 +313,11 @@ static gint query_png (const gchar *path,
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
if (row_p)
g_free (row_p);
- fclose (infile);
return -1;
}
- png_init_io (load_png_ptr, infile);
- png_set_sig_bytes (load_png_ptr, 8);
+ png_set_read_fn(load_png_ptr, stream, read_fn);
+// png_set_sig_bytes (load_png_ptr, 8);
png_read_info (load_png_ptr, load_info_ptr);
{
int bit_depth;
@@ -339,7 +361,6 @@ static gint query_png (const gchar *path,
{
g_warning ("color type mismatch");
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return -1;
}
@@ -355,14 +376,12 @@ static gint query_png (const gchar *path,
{
g_warning ("bit depth mismatch");
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return -1;
}
*format = (void*)babl_format (format_string);
}
png_destroy_read_struct (&load_png_ptr, &load_info_ptr, NULL);
- fclose (infile);
return 0;
}
@@ -374,8 +393,12 @@ get_bounding_box (GeglOperation *operation)
gint width, height;
gint status;
gpointer format;
+ GError *err = NULL;
- status = query_png (o->path, &width, &height, &format);
+ GFile *infile = open_png(o->uri, o->path);
+ GInputStream *stream = G_INPUT_STREAM(g_file_read(infile, NULL, &err));
+ status = query_png (stream, &width, &height, &format);
+ g_input_stream_close(stream, NULL, NULL);
if (status)
{
@@ -386,6 +409,9 @@ get_bounding_box (GeglOperation *operation)
gegl_operation_set_format (operation, "output", format);
result.width = width;
result.height = height;
+
+ g_object_unref(infile);
+ g_object_unref(stream);
return result;
}
@@ -399,26 +425,40 @@ process (GeglOperation *operation,
gint problem;
gpointer format;
gint width, height;
+ GFile *infile = open_png(o->uri, o->path);
+ GError *err = NULL;
+
+ GInputStream *stream = G_INPUT_STREAM(g_file_read(infile, NULL, &err));
- problem = query_png (o->path, &width, &height, &format);
+ problem = query_png (stream, &width, &height, &format);
if (problem)
{
+ g_object_unref(infile);
+ g_object_unref(stream);
g_warning ("%s is %s really a PNG file?",
G_OBJECT_TYPE_NAME (operation), o->path);
return FALSE;
}
- problem = gegl_buffer_import_png (output, o->path, 0, 0,
+ // TEMP: avoding having to recreate stream. import_png should do query??
+ g_input_stream_close(stream, NULL, NULL);
+ g_object_unref(stream);
+ stream = G_INPUT_STREAM(g_file_read(infile, NULL, &err));
+
+ problem = gegl_buffer_import_png (output, stream, 0, 0,
&width, &height, format);
if (problem)
{
+ g_object_unref(infile);
+ g_object_unref(stream);
g_warning ("%s failed to open file %s for reading.",
G_OBJECT_TYPE_NAME (operation), o->path);
return FALSE;
}
-
- return TRUE;
+ g_object_unref(infile);
+ g_object_unref(stream);
+ return TRUE;
}
static GeglRectangle
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]