[dia] svg: embedded image support for import



commit a3596fe3a9cfae22219c7d259a541b390e22074f
Author: Hans Breuer <hans breuer org>
Date:   Sun Jun 26 22:14:13 2011 +0200

    svg: embedded image support for import
    
    Move helper function from vdx to lib. Make use of if
    in svg/svg-import.c

 lib/libdia.def            |    2 ++
 lib/prop_pixbuf.c         |   43 +++++++++++++++++++++++++++++++++++++++++++
 lib/prop_pixbuf.h         |    1 +
 plug-ins/svg/svg-import.c |   44 +++++++++++++++++++++++++++++++-------------
 plug-ins/vdx/vdx-import.c |   45 +--------------------------------------------
 5 files changed, 78 insertions(+), 57 deletions(-)
---
diff --git a/lib/libdia.def b/lib/libdia.def
index 19a7a29..f062c62 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -281,6 +281,8 @@ EXPORTS
  dia_image_new_from_pixbuf
 
  pixbuf_encode_base64
+ pixbuf_decode_base64
+
 
  dia_interactive_renderer_interface_get_type
  
diff --git a/lib/prop_pixbuf.c b/lib/prop_pixbuf.c
index ebfb516..07b8d1b 100644
--- a/lib/prop_pixbuf.c
+++ b/lib/prop_pixbuf.c
@@ -63,6 +63,49 @@ pixbufprop_copy(PixbufProperty *src)
   return prop;
 }
 
+/** Convert Base64 to pixbuf
+ * @param b64 Base64 encoded data
+ */
+GdkPixbuf *
+pixbuf_decode_base64 (const char *b64)
+{
+  /* see lib/prop_pixbuf.c(data_pixbuf) for a very similiar implementation */
+  GdkPixbuf *pixbuf = NULL;
+  GdkPixbufLoader *loader;
+  GError *error = NULL;
+
+  loader = gdk_pixbuf_loader_new ();
+  if (loader) {
+    gint state = 0;
+    guint save = 0;
+#   define BUF_SIZE 4096
+    guchar buf[BUF_SIZE];
+    gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */
+    gssize len = strlen (b64);
+	
+    do {
+      gsize step = g_base64_decode_step (in,
+					 len > BUF_SIZE ? BUF_SIZE : len,
+					 buf, &state, &save);
+      if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
+	break;
+
+      in += BUF_SIZE;
+      len -= BUF_SIZE;
+    } while (len > 0);
+    if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
+      pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
+    } else {
+      message_warning (_("Failed to load image form diagram:\n%s"), error->message);
+      g_error_free (error);
+    }
+
+    g_object_unref (loader);
+  }
+  return pixbuf;
+# undef BUF_SIZE
+}
+
 GdkPixbuf *
 data_pixbuf (DataNode data)
 {
diff --git a/lib/prop_pixbuf.h b/lib/prop_pixbuf.h
index 0506402..9750aa2 100644
--- a/lib/prop_pixbuf.h
+++ b/lib/prop_pixbuf.h
@@ -39,5 +39,6 @@ typedef struct {
 void prop_pixbuftypes_register(void);
 
 gchar *pixbuf_encode_base64 (const GdkPixbuf *);
+GdkPixbuf *pixbuf_decode_base64 (const char *b64);
 
 #endif /* PROP_PIXBUF_H */
diff --git a/plug-ins/svg/svg-import.c b/plug-ins/svg/svg-import.c
index 0ef1d5d..10328ae 100644
--- a/plug-ins/svg/svg-import.c
+++ b/plug-ins/svg/svg-import.c
@@ -676,7 +676,6 @@ read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list, const gc
   xmlChar *str;
   real x = 0, y = 0, width = 0, height = 0;
   DiaObject *new_obj;
-  gchar *filename = NULL;
 
   str = xmlGetProp(node, (const xmlChar *)"x");
   if (str) {
@@ -704,21 +703,40 @@ read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list, const gc
   if (!str) /* this doesn't look right but it appears to work w/o namespace --hb */
     str = xmlGetProp(node, (const xmlChar *)"href");
   if (str) {
-    filename = g_filename_from_uri((gchar *) str, NULL, NULL);
-    if (!filename || !g_path_is_absolute (filename)) {
-      /* if image file path is relative use the main path */
-      gchar *dir = g_path_get_dirname (filename_svg);
-      gchar *absfn = g_build_path (G_DIR_SEPARATOR_S, 
-	                           dir, filename ? filename : (gchar *)str, NULL);
-
-      g_free (filename);
-      g_free (dir);
-      filename = absfn;
+    if (strncmp ((char *)str, "data:image/", 11) == 0) {
+      /* inline data - skip format description like: data:image/png;base64, */
+      const char* data = strchr((char *)str, ',');
+      
+      if (data) {
+        GdkPixbuf *pixbuf = pixbuf_decode_base64 (data+1);
+
+	if (pixbuf) {
+	  ObjectChange *change;
+
+	  new_obj = create_standard_image(x, y, width, height, NULL);
+	  change = dia_object_set_pixbuf (new_obj, pixbuf);
+	  if (change) /* throw it away, noone needs it here  */
+	    change->free (change);
+	  g_object_unref (pixbuf);
+	}
+      }
+    } else {
+      gchar *filename = g_filename_from_uri((gchar *) str, NULL, NULL);
+      if (!filename || !g_path_is_absolute (filename)) {
+        /* if image file path is relative use the main path */
+        gchar *dir = g_path_get_dirname (filename_svg);
+        gchar *absfn = g_build_path (G_DIR_SEPARATOR_S, 
+	                             dir, filename ? filename : (gchar *)str, NULL);
+
+        g_free (filename);
+        g_free (dir);
+        filename = absfn;
+      }
+      new_obj = create_standard_image(x, y, width, height, filename ? filename : "<broken>");
+      g_free(filename);
     }
     xmlFree(str);
   }
-  new_obj = create_standard_image(x, y, width, height, filename ? filename : "<broken>");
-  g_free(filename);
 
   return g_list_append (list, new_obj);
 }
diff --git a/plug-ins/vdx/vdx-import.c b/plug-ins/vdx/vdx-import.c
index 69ebe6a..0c75b17 100644
--- a/plug-ins/vdx/vdx-import.c
+++ b/plug-ins/vdx/vdx-import.c
@@ -1925,49 +1925,6 @@ plot_nurbs(const struct vdx_Geom *Geom, const struct vdx_XForm *XForm,
     return newobj;
 }
 
-/** Convert Base64 to pixbuf
- * @param b64 Base64 encoded data
- */
-static GdkPixbuf *
-pixbuf_create_from_base64 (const char *b64)
-{
-  /* see lib/prop_pixbuf.c(data_pixbuf) for a very similiar implementation */
-  GdkPixbuf *pixbuf = NULL;
-  GdkPixbufLoader *loader;
-  GError *error = NULL;
-
-  loader = gdk_pixbuf_loader_new ();
-  if (loader) {
-    gint state = 0;
-    guint save = 0;
-#   define BUF_SIZE 4096
-    guchar buf[BUF_SIZE];
-    gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */
-    gssize len = strlen (b64);
-	
-    do {
-      gsize step = g_base64_decode_step (in,
-					 len > BUF_SIZE ? BUF_SIZE : len,
-					 buf, &state, &save);
-      if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
-	break;
-
-      in += BUF_SIZE;
-      len -= BUF_SIZE;
-    } while (len > 0);
-    if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
-      pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
-    } else {
-      message_warning (_("Failed to load image form diagram:\n%s"), error->message);
-      g_error_free (error);
-    }
-
-    g_object_unref (loader);
-  }
-  return pixbuf;
-# undef BUF_SIZE
-}
-
 /** Plots a bitmap
  * @param Geom the shape
  * @param XForm any transformations
@@ -2039,7 +1996,7 @@ plot_image(const struct vdx_Geom *Geom, const struct vdx_XForm *XForm,
 	PixbufProperty *prop = (PixbufProperty *)make_new_prop ("pixbuf", PROP_TYPE_PIXBUF, PROP_FLAG_DONT_SAVE);
 
 	/* In error prop->pixbuf is NULL, aka. broken image */
-	prop->pixbuf = pixbuf_create_from_base64 (base64_data);
+	prop->pixbuf = pixbuf_decode_base64 (base64_data);
 	g_ptr_array_add (props, prop);
 
 	newobj->ops->set_props(newobj, props);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]