[gegl] Add support for dataURI to gegl:load
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] Add support for dataURI to gegl:load
- Date: Mon, 5 Jan 2015 17:10:12 +0000 (UTC)
commit 993e4ba16cbc5085ea21f6deb2aeb3d862ed39ee
Author: Jon Nordby <jononor gmail com>
Date: Mon Jan 5 18:09:10 2015 +0100
Add support for dataURI to gegl:load
Peeks inside at the content-type to determine loader to use.
Tested for png and jpg files.
gegl/gegl-gio-private.h | 6 ++++++
gegl/gegl-gio.c | 35 +++++++++++++++++++++++++++++++----
operations/common/load.c | 27 +++++++++++++++++++++++++--
3 files changed, 62 insertions(+), 6 deletions(-)
---
diff --git a/gegl/gegl-gio-private.h b/gegl/gegl-gio-private.h
index d918e4d..354f545 100644
--- a/gegl/gegl-gio-private.h
+++ b/gegl/gegl-gio-private.h
@@ -27,6 +27,12 @@ G_BEGIN_DECLS
GInputStream *
gegl_gio_open_input_stream(const gchar *uri, const gchar *path, GFile **out_file, GError **err);
+gboolean
+gegl_gio_uri_is_datauri(const gchar *uri);
+
+gchar *
+gegl_gio_datauri_get_content_type(const gchar *uri);
+
#endif // __GEGL_GIO_PRIVATE_H__
G_END_DECLS
diff --git a/gegl/gegl-gio.c b/gegl/gegl-gio.c
index b920eb4..39b3d72 100644
--- a/gegl/gegl-gio.c
+++ b/gegl/gegl-gio.c
@@ -27,9 +27,18 @@
#include <gio/gunixinputstream.h>
#endif
-// Note: header_item[0] is content-type, header_items[1] is encoding
+/**
+ * datauri_parse_header:
+ * @uri: URI to parse
+ * @raw_data_out: (out) (transfer full): return location for pointer to raw data, following header
+ * @header_items_no_out: (out) (transfer none): return location for number of items parsed from header
+ *
+ * Return value: (transfer full): header_item[0] is content-type, header_items[1] is encoding, free with
g_strfreev()
+ *
+ * Note: currently private API
+ */
static gchar **
-parse_datauri_header(const gchar *uri, gchar **raw_data_out, gint *header_items_no_out)
+datauri_parse_header(const gchar *uri, gchar **raw_data_out, gint *header_items_no_out)
{
// Determine data format
const gchar * header_end = g_strstr_len (uri, -1, ",");
@@ -65,7 +74,7 @@ input_stream_datauri(const gchar *uri)
GInputStream *stream = NULL;
gchar * raw_data = NULL;
gint header_items_no = 0;
- gchar **header_items = parse_datauri_header(uri, &raw_data, &header_items_no);
+ gchar **header_items = datauri_parse_header(uri, &raw_data, &header_items_no);
const gboolean is_base64 = header_items_no > 1 && g_strcmp0(header_items[1], "base64") == 0;
if (is_base64) {
@@ -82,6 +91,24 @@ input_stream_datauri(const gchar *uri)
return stream;
}
+gchar *
+gegl_gio_datauri_get_content_type(const gchar *uri)
+{
+ gchar *content_type = NULL;
+ gint header_items_no = 0;
+ gchar **header_items = datauri_parse_header(uri, NULL, &header_items_no);
+ if (header_items_no)
+ content_type = g_strdup(header_items[0]);
+ g_strfreev(header_items);
+ return content_type;
+}
+
+gboolean
+gegl_gio_uri_is_datauri(const gchar *uri)
+{
+ return g_str_has_prefix(uri, "data:");
+}
+
/**
* gegl_gio_open_input_stream:
* @uri: (allow none) URI to open. @uri is preferred over @path if both are set
@@ -112,7 +139,7 @@ gegl_gio_open_input_stream(const gchar *uri, const gchar *path, GFile **out_file
}
else if (uri && strlen(uri) > 0)
{
- if (g_str_has_prefix(uri, "data:"))
+ if (gegl_gio_uri_is_datauri(uri))
{
fis = input_stream_datauri(uri);
}
diff --git a/operations/common/load.c b/operations/common/load.c
index 2794658..da39cdd 100644
--- a/operations/common/load.c
+++ b/operations/common/load.c
@@ -18,7 +18,7 @@
#include "config.h"
#include <glib/gi18n-lib.h>
-
+#include <gegl-gio-private.h>
#ifdef GEGL_PROPERTIES
@@ -52,6 +52,17 @@ GEGL_DEFINE_DYNAMIC_OPERATION(GEGL_TYPE_OPERATION_META)
#include <stdio.h>
+static gchar * const
+extension_from_mimetype(const gchar *mime)
+{
+ // XXX: maybe file loader opts should register mimetypes also?
+ static const gchar * const mime_prefix = "image/";
+ if (g_str_has_prefix(mime, mime_prefix)) {
+ return g_strdup_printf(".%s", mime+strlen(mime_prefix));
+ }
+ return NULL;
+}
+
static void
do_setup (GeglOperation *operation, const gchar *new_path, const gchar *new_uri)
{
@@ -59,12 +70,24 @@ do_setup (GeglOperation *operation, const gchar *new_path, const gchar *new_uri)
if (new_uri && strlen (new_uri) > 0)
{
- const gchar *extension = strrchr (new_uri, '.');
+ gchar *extension = NULL;
const gchar *handler = NULL;
+
+ if (gegl_gio_uri_is_datauri(new_uri))
+ {
+ gchar *mime = gegl_gio_datauri_get_content_type(new_uri);
+ extension = extension_from_mimetype(mime);
+ g_free(mime);
+ }
+ else
+ extension = g_strdup(strrchr (new_uri, '.'));
+
if (extension)
handler = gegl_extension_handler_get (extension);
gegl_node_set (self->load, "operation", handler, NULL);
gegl_node_set (self->load, "uri", new_uri, NULL);
+
+ g_free(extension);
}
else if (new_path && strlen (new_path) > 0)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]