[librsvg] all: Add flag to keep image data



commit a35216a93b1db4973056426edc282c4decc2538a
Author: Suzuki Toshiya <mpsuzuki hiroshima-u ac jp>
Date:   Sun Aug 17 18:41:54 2014 +0200

    all: Add flag to keep image data
    
    And use it when converting to a PDF in rsvg-convert.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=721354

 rsvg-convert.c |   12 ++++++++++++
 rsvg-image.c   |   56 +++++++++++++++++++++++++++++++++++---------------------
 rsvg.h         |    9 +++++++--
 3 files changed, 54 insertions(+), 23 deletions(-)
---
diff --git a/rsvg-convert.c b/rsvg-convert.c
index 276e789..b3d3575 100644
--- a/rsvg-convert.c
+++ b/rsvg-convert.c
@@ -102,6 +102,8 @@ main (int argc, char **argv)
     char *background_color_str = NULL;
     gboolean using_stdin = FALSE;
     gboolean unlimited = FALSE;
+    gboolean keep_image_data = FALSE;
+    gboolean no_keep_image_data = FALSE;
     GError *error = NULL;
 
     int i;
@@ -138,6 +140,8 @@ main (int argc, char **argv)
         {"background-color", 'b', 0, G_OPTION_ARG_STRING, &background_color_str,
          N_("set the background color [optional; defaults to None]"), N_("[black, white, #abccee, 
#aaa...]")},
         {"unlimited", 'u', 0, G_OPTION_ARG_NONE, &unlimited, N_("Allow huge SVG files"), NULL},
+        {"keep-image-data", 0, 0, G_OPTION_ARG_NONE, &keep_image_data, N_("Keep image data"), NULL},
+        {"no-keep-image-data", 0, 0, G_OPTION_ARG_NONE, &no_keep_image_data, N_("Don't keep image data"), 
NULL},
         {"version", 'v', 0, G_OPTION_ARG_NONE, &bVersion, N_("show version information"), NULL},
         {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("[FILE...]")},
         {NULL}
@@ -187,6 +191,11 @@ main (int argc, char **argv)
         exit (1);
     }
 
+    if (format != NULL &&
+        (g_str_equal (format, "ps") || g_str_equal (format, "eps") || g_str_equal (format, "pdf")) &&
+        !no_keep_image_data)
+        keep_image_data = TRUE;
+
     if (zoom != 1.0)
         x_zoom = y_zoom = zoom;
 
@@ -195,6 +204,9 @@ main (int argc, char **argv)
     if (unlimited)
         flags |= RSVG_HANDLE_FLAG_UNLIMITED;
 
+    if (keep_image_data)
+        flags |= RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA;
+
     for (i = 0; i < n_args; i++) {
         GFile *file;
         GInputStream *stream;
diff --git a/rsvg-image.c b/rsvg-image.c
index e225a47..a304898 100644
--- a/rsvg-image.c
+++ b/rsvg-image.c
@@ -44,10 +44,9 @@ rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
     guint8 *data;
     gsize data_len;
     char *mime_type = NULL;
-    GdkPixbufLoader *loader;
+    GdkPixbufLoader *loader = NULL;
     GdkPixbuf *pixbuf = NULL;
-    int res;
-    cairo_surface_t *surface;
+    cairo_surface_t *surface = NULL;
 
     data = _rsvg_handle_acquire_data (handle, href, &mime_type, &data_len, error);
     if (data == NULL)
@@ -55,45 +54,60 @@ rsvg_cairo_surface_new_from_href (RsvgHandle *handle,
 
     if (mime_type) {
         loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
-        g_free (mime_type);
     } else {
         loader = gdk_pixbuf_loader_new ();
     }
 
-    if (loader == NULL) {
-        g_free (data);
-        return NULL;
-    }
+    if (loader == NULL)
+        goto out;
 
-    res = gdk_pixbuf_loader_write (loader, data, data_len, error);
-    g_free (data);
-
-    if (!res) {
+    if (!gdk_pixbuf_loader_write (loader, data, data_len, error)) {
         gdk_pixbuf_loader_close (loader, NULL);
-        g_object_unref (loader);
-        return NULL;
+        goto out;
     }
 
-    if (!gdk_pixbuf_loader_close (loader, error)) {
-        g_object_unref (loader);
-        return NULL;
-    }
+    if (!gdk_pixbuf_loader_close (loader, error))
+        goto out;
 
     pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
 
     if (!pixbuf) {
-        g_object_unref (loader);
         g_set_error (error,
                      GDK_PIXBUF_ERROR,
                      GDK_PIXBUF_ERROR_FAILED,
                       _("Failed to load image '%s': reason not known, probably a corrupt image file"),
                       href);
-        return NULL;
+        goto out;
     }
 
     surface = rsvg_cairo_surface_from_pixbuf (pixbuf);
 
-    g_object_unref (loader);
+    if (mime_type == NULL) {
+        /* Try to get the information from the loader */
+        GdkPixbufFormat *format;
+        char **mime_types;
+
+        if ((format = gdk_pixbuf_loader_get_format (loader)) != NULL) {
+            mime_types = gdk_pixbuf_format_get_mime_types (format);
+
+            if (mime_types != NULL)
+                mime_type = g_strdup (mime_types[0]);
+            g_strfreev (mime_types);
+        }
+    }
+
+    if ((handle->priv->flags & RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA) != 0 &&
+        mime_type != NULL &&
+        cairo_surface_set_mime_data (surface, mime_type, data,
+                                     data_len, g_free, data) == CAIRO_STATUS_SUCCESS) {
+        data = NULL; /* transferred to the surface */
+    }
+
+  out:
+    if (loader)
+        g_object_unref (loader);
+    g_free (mime_type);
+    g_free (data);
 
     return surface;
 }
diff --git a/rsvg.h b/rsvg.h
index 801008b..b8a6f8c 100644
--- a/rsvg.h
+++ b/rsvg.h
@@ -158,11 +158,16 @@ gboolean rsvg_handle_has_sub (RsvgHandle * handle, const char *id);
  * @RSVG_HANDLE_FLAG_UNLIMITED: Allow any SVG XML without size limitations.
  *   For security reasons, this should only be used for trusted input!
  *   Since: 2.40.3
+ * @RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA: Keeps the image data when loading images,
+ *  for use by cairo when painting to e.g. a PDF surface. This will make the
+ *  resulting PDF file smaller and faster.
+ *  Since: 2.40.3
  */
 typedef enum /*< flags >*/ 
 {
-    RSVG_HANDLE_FLAGS_NONE        = 0,
-    RSVG_HANDLE_FLAG_UNLIMITED    = 1 << 0
+    RSVG_HANDLE_FLAGS_NONE           = 0,
+    RSVG_HANDLE_FLAG_UNLIMITED       = 1 << 0,
+    RSVG_HANDLE_FLAG_KEEP_IMAGE_DATA = 1 << 1
 } RsvgHandleFlags;
 
 RsvgHandle *rsvg_handle_new_with_flags (RsvgHandleFlags flags);


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