Merge branch 'felixbuenemann-add-svgload-svgz-detection'

This commit is contained in:
John Cupitt 2016-08-01 14:30:32 +01:00
commit 9c75fc709b
8 changed files with 253 additions and 141 deletions

View File

@ -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

2
TODO
View File

@ -1,3 +1,5 @@
- can we hjave .svg.gz as a suffix? should be possible
- try:
$ vips avg broken.jpg[fail]

View File

@ -627,6 +627,29 @@ if test x"$with_rsvg" != x"no"; then
)
fi
# zlib
# some platforms, like macosx, are missing the .pc files for zlib, so
# we fall back to FIND_ZLIB
AC_ARG_WITH([zlib],
AS_HELP_STRING([--without-zlib], [build without zlib (default: test)]))
if test x"$with_zlib" != "xno"; then
PKG_CHECK_MODULES(ZLIB, zlib >= 0.4,
[AC_DEFINE(HAVE_ZLIB,1,[define if you have zlib installed.])
with_zlib=yes
PACKAGES_USED="$PACKAGES_USED zlib"
],
[FIND_ZLIB(
[with_zlib="yes (found by search)"
],
[AC_MSG_WARN([zlib not found; disabling SVGZ buffer support])
with_zlib=no
]
)
]
)
fi
# OpenSlide
AC_ARG_WITH([openslide],
AS_HELP_STRING([--without-openslide],
@ -787,15 +810,6 @@ fi
AM_CONDITIONAL(ENABLE_PYVIPS8, test x"$enable_pyvips8" = x"yes")
# hmm, these don't have .pc files on ubuntu 5.10, how odd
FIND_ZIP(
[with_zip=yes
],
[AC_MSG_WARN([libz not found; disabling ZIP support])
with_zip=no
]
)
# look for TIFF with pkg-config ... fall back to our tester
# pkgconfig support for libtiff starts with libtiff-4
AC_ARG_WITH([tiff],
@ -944,14 +958,14 @@ fi
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
# sort includes to get longer, more specific dirs first
# helps, for example, selecting graphicsmagick over imagemagick
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $GIFLIB_INCLUDES $RSVG_CFLAGS $POPPLER_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS
VIPS_CFLAGS=`for i in $VIPS_CFLAGS $GTHREAD_CFLAGS $REQUIRED_CFLAGS $ZLIB_CFLAGS $PANGOFT2_CFLAGS $GSF_CFLAGS $FFTW_CFLAGS $MAGICK_CFLAGS $PNG_CFLAGS $EXIF_CFLAGS $MATIO_CFLAGS $CFITSIO_CFLAGS $LIBWEBP_CFLAGS $GIFLIB_INCLUDES $RSVG_CFLAGS $POPPLER_CFLAGS $OPENEXR_CFLAGS $OPENSLIDE_CFLAGS $ORC_CFLAGS $TIFF_CFLAGS $LCMS_CFLAGS
do
echo $i
done | sort -ru`
VIPS_CFLAGS=`echo $VIPS_CFLAGS`
VIPS_CFLAGS="$VIPS_DEBUG_FLAGS $VIPS_CFLAGS"
VIPS_INCLUDES="$PNG_INCLUDES $TIFF_INCLUDES $ZIP_INCLUDES $JPEG_INCLUDES"
VIPS_LIBS="$MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $ZIP_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $GIFLIB_LIBS $RSVG_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
VIPS_INCLUDES="$ZLIB_INCLUDES $PNG_INCLUDES $TIFF_INCLUDES $JPEG_INCLUDES"
VIPS_LIBS="$ZLIB_LIBS $MAGICK_LIBS $PNG_LIBS $TIFF_LIBS $JPEG_LIBS $GTHREAD_LIBS $REQUIRED_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $GIFLIB_LIBS $RSVG_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_LIBS $MATIO_LIBS $EXIF_LIBS -lm"
AC_SUBST(VIPS_LIBDIR)
@ -1047,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)

View File

@ -2,6 +2,8 @@
*
* 7/2/16
* - from svgload.c
* 1/8/16 felixbuenemann
* - add svgz support
*/
/*
@ -55,6 +57,23 @@
#include <cairo.h>
#include <librsvg/rsvg.h>
/* Old librsvg versions don't include librsvg-features.h by default.
* Newer versions deprecate direct inclusion.
*/
#ifndef LIBRSVG_FEATURES_H
#include <librsvg/librsvg-features.h>
#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 <zlib.h>
#endif
typedef struct _VipsForeignLoadSvg {
VipsForeignLoad parent_object;
@ -315,6 +334,11 @@ 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
NULL
};
@ -364,13 +388,78 @@ typedef VipsForeignLoadSvgClass VipsForeignLoadSvgBufferClass;
G_DEFINE_TYPE( VipsForeignLoadSvgBuffer, vips_foreign_load_svg_buffer,
vips_foreign_load_svg_get_type() );
#ifdef HANDLE_SVGZ
static void *
vips_foreign_load_svg_zalloc( void *opaque, unsigned items, unsigned size )
{
return( g_malloc0_n( items, size ) );
}
static void
vips_foreign_load_svg_zfree( void *opaque, void *ptr )
{
return( g_free( ptr ) );
}
#endif /*HANDLE_SVGZ*/
static gboolean
vips_foreign_load_svg_is_a_buffer( const void *buf, size_t len )
{
char *str = (char *) buf;
char *str;
#ifdef HANDLE_SVGZ
/* If the buffer looks like a zip, deflate to here and then search
* that for <svg.
*/
char obuf[224];
#endif /*HANDLE_SVGZ*/
int i;
/* Start with str pointing at the argument buffer, swap to it pointing
* into obuf if we see zip data.
*/
str = (char *) buf;
#ifdef HANDLE_SVGZ
/* Check for SVGZ gzip signature and inflate.
*
* Minimum gzip size is 18 bytes, starting with 1F 8B.
*/
if( len >= 18 &&
str[0] == '\037' &&
str[1] == '\213' ) {
z_stream zs;
size_t opos;
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 = (unsigned char *) str;
zs.avail_in = len;
/* 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 = (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 );
str = obuf;
len = opos;
}
#endif /*HANDLE_SVGZ*/
/* SVG documents are very freeform. They normally look like:
*
* <?xml version="1.0" encoding="UTF-8"?>
@ -390,19 +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++ ) {
char txt[5];
for( i = 0; i < 200 && i < len - 5; i++ )
if( strncasecmp( str + i, "<svg", 4 ) == 0 )
return( TRUE );
/* 5, since we include the \0 at the end.
*/
vips_strncpy( txt, buf + i, 5 );
if( strcasecmp( txt, "<svg" ) == 0 )
return( 1 );
}
return( 0 );
return( FALSE );
}
static int

117
m4/zip.m4
View File

@ -1,117 +0,0 @@
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_ZIP[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find ZIP libraries and headers
dnl
dnl Put includes stuff in ZIP_INCLUDES
dnl Put link stuff in ZIP_LIBS
dnl Define HAVE_ZIP if found
dnl
AC_DEFUN([FIND_ZIP], [
AC_REQUIRE([AC_PATH_XTRA])
ZIP_INCLUDES=""
ZIP_LIBS=""
AC_ARG_WITH(zip,
AS_HELP_STRING([--without-zip], [build without libx (default: test)]))
# Treat --without-zip like --without-zip-includes --without-zip-libraries.
if test "$with_zip" = "no"; then
ZIP_INCLUDES=no
ZIP_LIBS=no
fi
AC_ARG_WITH(zip-includes,
AS_HELP_STRING([--with-zip-includes=DIR], [libz includes are in DIR]),
ZIP_INCLUDES="-I$withval")
AC_ARG_WITH(zip-libraries,
AS_HELP_STRING([--with-zip-libraries=DIR], [libz libraries are in DIR]),
ZIP_LIBS="-L$withval -lz")
AC_MSG_CHECKING(for ZIP)
# Look for zlib.h
if test "$ZIP_INCLUDES" = ""; then
# Check the standard search path
AC_TRY_COMPILE([#include <zlib.h>],[int a;],[
ZIP_INCLUDES=""
], [
# zlib.h is not in the standard search path, try
# $prefix
zip_save_INCLUDES="$INCLUDES"
INCLUDES="-I${prefix}/include $INCLUDES"
AC_TRY_COMPILE([#include <zlib.h>],[int a;],[
ZIP_INCLUDES="-I${prefix}/include"
], [
ZIP_INCLUDES="no"
])
INCLUDES=$zip_save_INCLUDES
])
fi
# Now for the libraries
if test "$ZIP_LIBS" = ""; then
zip_save_LIBS="$LIBS"
zip_save_INCLUDES="$INCLUDES"
LIBS="-lz $LIBS"
INCLUDES="$ZIP_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([#include <zlib.h>],[zlibVersion()], [
ZIP_LIBS="-lz"
], [
# libz is not in the standard search path, try $prefix
LIBS="-L${prefix}/lib $LIBS"
AC_TRY_LINK([#include <zlib.h>],[zlibVersion()], [
ZIP_LIBS="-L${prefix}/lib -lz"
], [
ZIP_LIBS=no
])
])
LIBS="$zip_save_LIBS"
INCLUDES="$zip_save_INCLUDES"
fi
AC_SUBST(ZIP_LIBS)
AC_SUBST(ZIP_INCLUDES)
# Print a helpful message
zip_libraries_result="$ZIP_LIBS"
zip_includes_result="$ZIP_INCLUDES"
if test x"$zip_libraries_result" = x""; then
zip_libraries_result="in default path"
fi
if test x"$zip_includes_result" = x""; then
zip_includes_result="in default path"
fi
if test "$zip_libraries_result" = "no"; then
zip_libraries_result="(none)"
fi
if test "$zip_includes_result" = "no"; then
zip_includes_result="(none)"
fi
AC_MSG_RESULT([libraries $zip_libraries_result, headers $zip_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$ZIP_INCLUDES" != "no" && test "$ZIP_LIBS" != "no"; then
AC_DEFINE(HAVE_ZIP,1,[Define if you have libz libraries and header files.])
$1
else
ZIP_LIBS=""
ZIP_INCLUDES=""
$2
fi
])dnl

124
m4/zlib.m4 Normal file
View File

@ -0,0 +1,124 @@
dnl From FIND_MOTIF and ACX_PTHREAD, without much understanding
dnl
dnl FIND_ZLIB[ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]
dnl ------------------------------------------------
dnl
dnl Find zlib libraries and headers ... useful for platforms which are missing
dnl the zlib .pc file
dnl
dnl Put compile stuff in ZLIB_INCLUDES
dnl Put link stuff in ZLIB_LIBS
dnl Define HAVE_ZLIB if found
dnl
AC_DEFUN([FIND_ZLIB], [
AC_REQUIRE([AC_PATH_XTRA])
ZLIB_INCLUDES=""
ZLIB_LIBS=""
AC_ARG_WITH(zlib,
AS_HELP_STRING([--without-zlib], [build without zlib (default: test)]))
# Treat --without-zlib like --without-zlib-includes --without-zlib-libraries.
if test "$with_zlib" = "no"; then
ZLIB_INCLUDES=no
ZLIB_LIBS=no
fi
AC_ARG_WITH(zlib-includes,
AS_HELP_STRING([--with-zlib-includes=DIR], [libz includes are in DIR]),
ZLIB_INCLUDES="-I$withval")
AC_ARG_WITH(zlib-libraries,
AS_HELP_STRING([--with-zlib-libraries=DIR], [libz libraries are in DIR]),
ZLIB_LIBS="-L$withval -lz")
AC_MSG_CHECKING(for ZLIB)
# Look for zlib.h
if test "$ZLIB_INCLUDES" = ""; then
# Check the standard search path
AC_TRY_COMPILE([#include <stdio.h>
#include <zlib.h>],[int a;],[
ZLIB_INCLUDES=""
], [
# zlib.h is not in the standard search path, try
# $prefix
zlib_save_INCLUDES="$INCLUDES"
INCLUDES="-I${prefix}/include $INCLUDES"
AC_TRY_COMPILE([#include <stdio.h>
#include <zlib.h>],[int a;],[
ZLIB_INCLUDES="-I${prefix}/include"
], [
ZLIB_INCLUDES="no"
])
INCLUDES=$zlib_save_INCLUDES
])
fi
# Now for the libraries
if test "$ZLIB_LIBS" = ""; then
zlib_save_LIBS="$LIBS"
zlib_save_INCLUDES="$INCLUDES"
LIBS="-lz $LIBS"
INCLUDES="$ZLIB_INCLUDES $INCLUDES"
# Try the standard search path first
AC_TRY_LINK([#include <stdio.h>
#include <zlib.h>
],[z_stream zs;inflateInit2(&zs, 15 | 32)], [
ZLIB_LIBS="-lz"
], [
# libz is not in the standard search path, try $prefix
LIBS="-L${prefix}/lib $LIBS"
AC_TRY_LINK([#include <stdio.h>
#include <zlib.h>
],[z_stream zs;inflateInit2(&zs, 15 | 32)], [
ZLIB_LIBS="-L${prefix}/lib -lz"
], [
ZLIB_LIBS=no
])
])
LIBS="$zlib_save_LIBS"
INCLUDES="$zlib_save_INCLUDES"
fi
AC_SUBST(ZLIB_LIBS)
AC_SUBST(ZLIB_INCLUDES)
# Print a helpful message
zlib_libraries_result="$ZLIB_LIBS"
zlib_includes_result="$ZLIB_INCLUDES"
if test x"$zlib_libraries_result" = x""; then
zlib_libraries_result="in default path"
fi
if test x"$zlib_includes_result" = x""; then
zlib_includes_result="in default path"
fi
if test "$zlib_libraries_result" = "no"; then
zlib_libraries_result="(none)"
fi
if test "$zlib_includes_result" = "no"; then
zlib_includes_result="(none)"
fi
AC_MSG_RESULT([libraries $zlib_libraries_result, headers $zlib_includes_result])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "$ZLIB_INCLUDES" != "no" && test "$ZLIB_LIBS" != "no"; then
AC_DEFINE(HAVE_ZLIB,1,[Define if you have zlib libraries and header files.])
$1
else
ZLIB_INCLUDES=""
ZLIB_LIBS=""
$2
fi
])dnl

Binary file not shown.

View File

@ -50,6 +50,7 @@ class TestForeign(unittest.TestCase):
self.pdf_file = "images/ISO_12233-reschart.pdf"
self.cmyk_pdf_file = "images/cmyktest.pdf"
self.svg_file = "images/vips-profile.svg"
self.svgz_file = "images/vips-profile.svgz"
self.colour = Vips.Image.jpegload(self.jpeg_file)
self.mono = self.colour.extract_band(1)
@ -497,6 +498,9 @@ class TestForeign(unittest.TestCase):
self.file_loader("svgload", self.svg_file, svg_valid)
self.buffer_loader("svgload_buffer", self.svg_file, svg_valid)
self.file_loader("svgload", self.svgz_file, svg_valid)
self.buffer_loader("svgload_buffer", self.svgz_file, svg_valid)
im = Vips.Image.new_from_file(self.svg_file)
x = Vips.Image.new_from_file(self.svg_file, scale = 2)
self.assertLess(abs(im.width * 2 - x.width), 2)