[librsvg] Use GZlibDecompressor for SVGZ support
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] Use GZlibDecompressor for SVGZ support
- Date: Tue, 22 Jun 2010 15:55:39 +0000 (UTC)
commit af8dc1feb3e38e06be5865d93ee6d266514c16af
Author: Christian Persch <chpe gnome org>
Date: Tue Jun 22 17:54:50 2010 +0200
Use GZlibDecompressor for SVGZ support
On gio >= 2.24, use GZlibDecompressor for SVGZ. Otherwise use libgsf.
Bug #621699.
configure.in | 76 +++++++++++++++++++++++---------------
rsvg-base.c | 112 ++++++++++++++++++++++++++++++++++++--------------------
rsvg-gobject.c | 19 +++++++--
rsvg-private.h | 8 +++-
4 files changed, 138 insertions(+), 77 deletions(-)
---
diff --git a/configure.in b/configure.in
index 8e7a377..e2d063f 100644
--- a/configure.in
+++ b/configure.in
@@ -133,38 +133,54 @@ PKG_CHECK_MODULES(LIBRSVG, \
dnl ===========================================================================
-LIBGSF_CFLAGS=""
-LIBGSF_LIBS=""
+# Using GIO 2.24 we support reading .svg.gz data
-LIBGSFPKG=""
-test_gsf=true
-AC_ARG_WITH(svgz,[ --with-svgz Use libgsf for run-time decompression],[
- if test "x$withval" = "xno"; then
- test_gsf=false
- fi
-])
-if test "x$test_gsf" = "xtrue"; then
- PKG_CHECK_MODULES(LIBGSF,[libgsf-1 >= 1.6.0], test_gsf=true, test_gsf=false)
-fi
+svgz_warning=
-if test "x$test_gsf" = "xtrue"; then
- svgz_define=1
- LIBGSF_CFLAGS="$LIBGSF_CFLAGS -DHAVE_SVGZ=1"
- LIBGSFPKG="libgsf-1"
-else
- svgz_define=0
- AC_MSG_WARN([SVGZ support disabled, as requested (Use --with-svgz to enable)])
- gsf_warning="
- You are building without libgsf support. LibRSVG will not be able to handle GZipped SVGs, as is required per the SVG specification. If you are a library vendor or distributor, you are doing the world a disservice and should strongly consider shipping libgsf."
-fi
-AM_CONDITIONAL(WITH_LIBGSF,[test "$LIBGSFPKG" != ""])
+AC_MSG_CHECKING([whether gio 2.24 is available])
+PKG_CHECK_EXISTS([gio-2.0 >= 2.24.0],[have_gio_2_24=yes],[have_gio_2_24=no])
+AC_MSG_RESULT([$have_gio_2_24])
-AC_SUBST(LIBGSFPKG)
+AC_SUBST([HAVE_GIO_2_24],[$have_gio_2_24])
-AC_SUBST(LIBGSF_CFLAGS)
-AC_SUBST(LIBGSF_LIBS)
+if test "$have_gio_2_24" = "yes"; then
+ svgz_define=1
+ test_svgz=true
+else
+ LIBGSF_CFLAGS=""
+ LIBGSF_LIBS=""
+
+ LIBGSFPKG=""
+ test_svgz=true
+ AC_ARG_WITH(svgz,[ --with-svgz Use libgsf for run-time decompression],[
+ if test "x$withval" = "xno"; then
+ test_svgz=false
+ fi
+ ])
+ if test "x$test_svgz" = "xtrue"; then
+ PKG_CHECK_MODULES(LIBGSF,[libgsf-1 >= 1.6.0], test_svgz=true, test_svgz=false)
+ fi
+
+ if test "x$test_svgz" = "xtrue"; then
+ svgz_define=1
+ AC_DEFINE([HAVE_GSF],[1],[Define if using libgsf])
+ LIBGSFPKG="libgsf-1"
+ else
+ svgz_define=0
+ AC_MSG_WARN([SVGZ support disabled, as requested (Use --with-svgz to enable)])
+ fi
+
+ AC_SUBST(LIBGSFPKG)
+
+ AC_SUBST(LIBGSF_CFLAGS)
+ AC_SUBST(LIBGSF_LIBS)
+fi # have_gio_2_24
+
+if test "$test_svgz" != "true"; then
+ svgz_warning="You are building without libgsf support. LibRSVG will not be able to handle GZipped SVGs, as is required per the SVG specification. If you are a library vendor or distributor, you are doing the world a disservice and should strongly consider shipping libgsf."
+fi
-AC_SUBST([SVGZ_SUPPORTED],[$test_gsf])
+AC_SUBST([SVGZ_SUPPORTED],[$test_svgz])
AC_SUBST([LIBRSVG_HAVE_SVGZ],[$svgz_define])
dnl ===========================================================================
@@ -376,7 +392,7 @@ librsvg-$VERSION for gtk+-$GTK_API_VERSION
Build GdkPixbuf loader: ${enable_pixbuf_loader}
Build theme engine: ${enable_gtk_theme}
Build miscellaenous tools: ${build_misc_tools}
- Handle svgz files: ${test_gsf}
+ Handle svgz files: ${test_svgz}
Use libcroco for css parsing: ${test_croco}
"
@@ -384,6 +400,6 @@ if test "x$croco_warning" != "x"; then
AC_MSG_RESULT([$croco_warning]);
fi
-if test "x$gsf_warning" != "x"; then
- AC_MSG_RESULT([$gsf_warning]);
+if test "x$svgz_warning" != "x"; then
+ AC_MSG_NOTICE([$svgz_warning]);
fi
diff --git a/rsvg-base.c b/rsvg-base.c
index 85ce8e5..b60261d 100644
--- a/rsvg-base.c
+++ b/rsvg-base.c
@@ -26,13 +26,6 @@
#include "config.h"
-#ifdef HAVE_SVGZ
-#include <gsf/gsf-input-gzip.h>
-#include <gsf/gsf-input-memory.h>
-#include <gsf/gsf-output-memory.h>
-#include <gsf/gsf-utils.h>
-#endif
-
#include "rsvg.h"
#include "rsvg-private.h"
#include "rsvg-css.h"
@@ -54,6 +47,13 @@
#include <string.h>
#include <stdarg.h>
+#ifdef HAVE_GSF
+#include <gsf/gsf-input-gzip.h>
+#include <gsf/gsf-input-memory.h>
+#include <gsf/gsf-output-memory.h>
+#include <gsf/gsf-utils.h>
+#endif
+
#include "rsvg-bpath-util.h"
#include "rsvg-path.h"
#include "rsvg-paint-server.h"
@@ -1682,79 +1682,109 @@ rsvg_handle_set_size_callback (RsvgHandle * handle,
/**
* rsvg_handle_write:
- * @handle: An #RsvgHandle
- * @buf: Pointer to svg data
+ * @handle: an #RsvgHandle
+ * @buf: (array length=count) (element-type uint8): pointer to svg data
* @count: length of the @buf buffer in bytes
- * @error: return location for errors
+ * @error: (allow-none): a location to store a #GError, or %NULL
*
* Loads the next @count bytes of the image. This will return #TRUE if the data
* was loaded successful, and #FALSE if an error occurred. In the latter case,
* the loader will be closed, and will not accept further writes. If FALSE is
- * returned, @error will be set to an error from the #RSVG_ERROR domain.
+ * returned, @error will be set to an error from the #RsvgError domain. Errors
+ * from #GIOErrorEnum are also possible.
*
- * Returns: #TRUE if the write was successful, or #FALSE if there was an
- * error.
+ * Returns: %TRUE on success, or %FALSE on error
**/
gboolean
rsvg_handle_write (RsvgHandle * handle, const guchar * buf, gsize count, GError ** error)
{
+ RsvgHandlePrivate *priv;
+
rsvg_return_val_if_fail (handle, FALSE, error);
- rsvg_return_val_if_fail (!handle->priv->is_closed, FALSE, error);
+ priv = handle->priv;
- if (handle->priv->first_write) {
- handle->priv->first_write = FALSE;
+ rsvg_return_val_if_fail (!priv->is_closed, FALSE, error);
+
+ if (priv->first_write) {
+ priv->first_write = FALSE;
/* test for GZ marker. todo: store the first 2 bytes in the odd circumstance that someone calls
* write() in 1 byte increments */
if ((count >= 2) && (buf[0] == (guchar) 0x1f) && (buf[1] == (guchar) 0x8b)) {
- handle->priv->is_gzipped = TRUE;
-
-#ifdef HAVE_SVGZ
- handle->priv->gzipped_data = GSF_OUTPUT (gsf_output_memory_new ());
+#if GLIB_CHECK_VERSION (2, 24, 0)
+ priv->data_input_stream = g_memory_input_stream_new ();
+#elif defined (HAVE_GSF)
+ priv->gzipped_data = GSF_OUTPUT (gsf_output_memory_new ());
+#else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ "GZip compressed SVG not supported");
+ return FALSE;
#endif
}
}
- if (handle->priv->is_gzipped) {
-#ifdef HAVE_SVGZ
+#if GLIB_CHECK_VERSION (2, 24, 0)
+ if (priv->data_input_stream) {
+ g_memory_input_stream_add_data ((GMemoryInputStream *) priv->data_input_stream,
+ g_memdup (buf, count), count, (GDestroyNotify) g_free);
+ return TRUE;
+ }
+#elif defined (HAVE_GSF)
+ if (priv->gzipped_data)
return gsf_output_write (handle->priv->gzipped_data, count, buf);
-#else
- return FALSE;
#endif
- }
return rsvg_handle_write_impl (handle, buf, count, error);
}
/**
* rsvg_handle_close:
- * @handle: A #RsvgHandle
- * @error: A #GError
+ * @handle: a #RsvgHandle
+ * @error: (allow-none): a location to store a #GError, or %NULL
*
* Closes @handle, to indicate that loading the image is complete. This will
- * return #TRUE if the loader closed successfully. Note that @handle isn't
+ * return %TRUE if the loader closed successfully. Note that @handle isn't
* freed until @g_object_unref is called.
*
- * Returns: #TRUE if the loader closed successfully, or #FALSE if there was
- * an error.
+ * Returns: %TRUE on success, or %FALSE on error
**/
gboolean
rsvg_handle_close (RsvgHandle * handle, GError ** error)
{
+ RsvgHandlePrivate *priv;
+ gboolean ret;
+
rsvg_return_val_if_fail (handle, FALSE, error);
+ priv = handle->priv;
+
+ if (priv->is_closed)
+ return TRUE;
- if (handle->priv->is_closed)
- return TRUE;
+#if GLIB_CHECK_VERSION (2, 24, 0)
+ if (priv->data_input_stream) {
+ GConverter *converter;
+ GInputStream *stream;
-#if HAVE_SVGZ
- if (handle->priv->is_gzipped) {
+ converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
+ stream = g_converter_input_stream_new (priv->data_input_stream, converter);
+ g_object_unref (converter);
+ g_object_unref (priv->data_input_stream);
+ priv->data_input_stream = NULL;
+
+ ret = rsvg_handle_read_stream_sync (handle, stream, NULL, error);
+ g_object_unref (stream);
+
+ return ret;
+ }
+#elif defined(HAVE_GSF)
+ if (priv->gzipped_data) {
GsfInput *gzip;
const guchar *bytes;
gsize size;
gsize remaining;
- bytes = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (handle->priv->gzipped_data));
- size = gsf_output_size (handle->priv->gzipped_data);
+ bytes = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (priv->gzipped_data));
+ size = gsf_output_size (priv->gzipped_data);
gzip =
GSF_INPUT (gsf_input_gzip_new
@@ -1784,9 +1814,11 @@ rsvg_handle_close (RsvgHandle * handle, GError ** error)
g_object_unref (gzip);
/* close parent */
- gsf_output_close (handle->priv->gzipped_data);
+ gsf_output_close (priv->gzipped_data);
+ g_object_unref (priv->gzipped_data);
+ priv->gzipped_data = NULL;
}
-#endif
+#endif /* GIO >= 2.24.0 */
return rsvg_handle_close_impl (handle, error);
}
@@ -1978,7 +2010,7 @@ rsvg_init (void)
{
g_type_init ();
-#ifdef HAVE_SVGZ
+#ifdef HAVE_GSF
gsf_init ();
#endif
@@ -1994,7 +2026,7 @@ rsvg_init (void)
void
rsvg_term (void)
{
-#ifdef HAVE_SVGZ
+#ifdef HAVE_GSF
gsf_shutdown ();
#endif
diff --git a/rsvg-gobject.c b/rsvg-gobject.c
index 358f690..37bbde2 100644
--- a/rsvg-gobject.c
+++ b/rsvg-gobject.c
@@ -21,6 +21,8 @@
Boston, MA 02111-1307, USA.
*/
+#include "config.h"
+
#include "rsvg-private.h"
#include "rsvg-defs.h"
@@ -64,6 +66,11 @@ instance_init (RsvgHandle * self)
self->priv->treebase = NULL;
self->priv->finished = 0;
+#if GLIB_CHECK_VERSION (2, 24, 0)
+ self->priv->data_input_stream = NULL;
+#elif defined(HAVE_GSF)
+ self->priv->gzipped_data = NULL;
+#endif
self->priv->first_write = TRUE;
self->priv->is_disposed = FALSE;
@@ -96,11 +103,6 @@ instance_dispose (GObject * instance)
self->priv->is_disposed = TRUE;
-#if HAVE_SVGZ
- if (self->priv->is_gzipped)
- g_object_unref (self->priv->gzipped_data);
-#endif
-
g_hash_table_foreach (self->priv->entities, rsvg_ctx_free_helper, NULL);
g_hash_table_destroy (self->priv->entities);
rsvg_defs_free (self->priv->defs);
@@ -120,10 +122,17 @@ instance_dispose (GObject * instance)
g_free (self->priv);
+#if GLIB_CHECK_VERSION (2, 24, 0)
if (self->priv->base_gfile) {
g_object_unref (self->priv->base_gfile);
self->priv->base_gfile = NULL;
}
+#elif defined(HAVE_GSF)
+ if (self->priv->gzipped_data) {
+ g_object_unref (self->priv->gzipped_data);
+ self->priv->gzipped_data = NULL;
+ }
+#endif
rsvg_parent_class->dispose (instance);
}
diff --git a/rsvg-private.h b/rsvg-private.h
index d18b922..85bd7ac 100644
--- a/rsvg-private.h
+++ b/rsvg-private.h
@@ -166,10 +166,14 @@ struct RsvgHandlePrivate {
gboolean finished;
+ gboolean in_loop; /* see get_dimension() */
+
gboolean first_write;
- gboolean is_gzipped;
+#if GLIB_CHECK_VERSION (2, 24, 0)
+ GInputStream *data_input_stream; /* for rsvg_handle_write of svgz data */
+#elif defined(HAVE_GSF)
void *gzipped_data; /* really a GsfOutput */
- gboolean in_loop; /* see get_dimension() */
+#endif
};
typedef struct {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]