From b0e3035590beebbf8e8951247631f09209eccd4a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 1 Aug 2016 14:28:35 +0100 Subject: [PATCH] small cleanups to svgz support --- ChangeLog | 1 + TODO | 2 + configure.ac | 1 + libvips/foreign/svgload.c | 94 ++++++++++++++++++++++++--------------- 4 files changed, 62 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b5debe04..e31d008e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,7 @@ - added vips_perlin(), generate Perlin noise - gif loader can write 1, 2, 3, or 4 bands depending on file contents - support --strip for pngsave +- add svgz support [Felix Bünemann] 30/7/16 started 8.3.3 - fix performance regression in 8.3.2, thanks Lovell diff --git a/TODO b/TODO index c9790b1c..a20ae074 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +- can we hjave .svg.gz as a suffix? should be possible + - try: $ vips avg broken.jpg[fail] diff --git a/configure.ac b/configure.ac index 0a199762..c77b7a9c 100644 --- a/configure.ac +++ b/configure.ac @@ -1061,6 +1061,7 @@ PDF import with poppler-glib: $with_poppler (requires poppler-glib 0.16.0 or later) SVG import with librsvg-2.0: $with_rsvg (requires librsvg-2.0 2.34.0 or later) +zlib: $with_zlib file import with cfitsio: $with_cfitsio file import/export with libwebp: $with_libwebp (requires libwebp-0.1.3 or later) diff --git a/libvips/foreign/svgload.c b/libvips/foreign/svgload.c index a0d1606a..9fd813c9 100644 --- a/libvips/foreign/svgload.c +++ b/libvips/foreign/svgload.c @@ -2,6 +2,8 @@ * * 7/2/16 * - from svgload.c + * 1/8/16 felixbuenemann + * - add svgz support */ /* @@ -54,14 +56,21 @@ #include #include -/* Old librsvg versions don't include librsvg-features.h by default, - * while newer versions deprecate direct inclusion. + +/* Old librsvg versions don't include librsvg-features.h by default. + * Newer versions deprecate direct inclusion. */ #ifndef LIBRSVG_FEATURES_H #include #endif +/* A handy #define for we-will-handle-svgz. + */ #if LIBRSVG_CHECK_FEATURE(SVGZ) && defined(HAVE_ZLIB) +#define HANDLE_SVGZ +#endif + +#ifdef HANDLE_SVGZ #include #endif @@ -325,6 +334,8 @@ vips_foreign_load_svg_file_header( VipsForeignLoad *load ) static const char *vips_foreign_svg_suffs[] = { ".svg", + /* librsvg supports svgz directly, no need to check for zlib here. + */ #if LIBRSVG_CHECK_FEATURE(SVGZ) ".svgz", #endif @@ -377,65 +388,77 @@ typedef VipsForeignLoadSvgClass VipsForeignLoadSvgBufferClass; G_DEFINE_TYPE( VipsForeignLoadSvgBuffer, vips_foreign_load_svg_buffer, vips_foreign_load_svg_get_type() ); -#if LIBRSVG_CHECK_FEATURE(SVGZ) && defined(HAVE_ZLIB) +#ifdef HANDLE_SVGZ static void * -vips_zalloc( void *opaque, unsigned items, unsigned size ) +vips_foreign_load_svg_zalloc( void *opaque, unsigned items, unsigned size ) { return( g_malloc0_n( items, size ) ); } static void -vips_zfree( void *opaque, void *ptr ) +vips_foreign_load_svg_zfree( void *opaque, void *ptr ) { return( g_free( ptr ) ); } -#endif +#endif /*HANDLE_SVGZ*/ static gboolean vips_foreign_load_svg_is_a_buffer( const void *buf, size_t len ) { - unsigned char *str = (unsigned char *) buf; + char *str; + +#ifdef HANDLE_SVGZ + /* If the buffer looks like a zip, deflate to here and then search + * that for = 18 && str[0] == 0x1f && str[1] == 0x8b ) { + if( len >= 18 && + str[0] == '\037' && + str[1] == '\213' ) { z_stream zs; - size_t opos = 0; - unsigned char obuf[224]; + size_t opos; - zs.zalloc = (alloc_func) vips_zalloc; - zs.zfree = (free_func) vips_zfree; + zs.zalloc = (alloc_func) vips_foreign_load_svg_zalloc; + zs.zfree = (free_func) vips_foreign_load_svg_zfree; zs.opaque = Z_NULL; - zs.next_in = str; + zs.next_in = (unsigned char *) str; zs.avail_in = len; - if( inflateInit2(&zs, 15 | 32) != Z_OK ) { - vips_error( "svgload", - "%s", _( "Zlib init failed" ) ); - return( -1 ); - } + /* There isn't really an error return from is_a_buffer() + */ + if( inflateInit2( &zs, 15 | 32 ) != Z_OK ) + return( FALSE ); + opos = 0; do { - zs.avail_out = sizeof(obuf) - opos; - zs.next_out = obuf + opos; - if( inflate(&zs, Z_NO_FLUSH) < Z_OK ) { - vips_error( "svgload", - "%s", _( "Zlib inflate failed" ) ); - return( -1 ); - } - opos = sizeof(obuf) - zs.avail_out; - } while( opos < sizeof(obuf) && zs.avail_out == 0 ); + zs.avail_out = sizeof( obuf ) - opos; + zs.next_out = (unsigned char *) obuf + opos; + if( inflate( &zs, Z_NO_FLUSH ) < Z_OK ) + return( FALSE ); + opos = sizeof( obuf ) - zs.avail_out; + } while( opos < sizeof( obuf ) && + zs.avail_in > 0 ); - inflateEnd(&zs); + inflateEnd( &zs ); str = obuf; len = opos; } -#endif +#endif /*HANDLE_SVGZ*/ /* SVG documents are very freeform. They normally look like: * @@ -456,14 +479,13 @@ vips_foreign_load_svg_is_a_buffer( const void *buf, size_t len ) return( 0 ); for( i = 0; i < 24; i++ ) if( !isascii( str[i] ) ) - return( 0 ); + return( FALSE ); - for( i = 0; i < 200 && i < len - 5; i++ ) { - if( strncmp( (const char *) str + i, "