[librsvg] all: Add flag to keep image data
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] all: Add flag to keep image data
- Date: Sun, 17 Aug 2014 16:45:01 +0000 (UTC)
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]