diff --git a/README.md b/README.md index b4f4fed5..58dcbcbe 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Run the top-level [build script](build.sh) with the `--help` parameter for help. | [gdk-pixbuf] | 2.42.10 | LGPLv3 | | [glib] | 2.78.0 | LGPLv3 | | [harfbuzz] | 8.2.1 | MIT Licence | +| [highway] | 1.0.7 | Apache-2.0 License, BSD 3-Clause | | [lcms] | 2.15 | MIT Licence | | [libarchive] | 3.7.2 | BSD 2-Clause | | [libexif] | 0.6.24 | LGPLv3 | @@ -37,17 +38,18 @@ Run the top-level [build script](build.sh) with the `--help` parameter for help. | [librsvg] | 2.57.0 | LGPLv3 | | [libspng] | 0.7.4 | BSD 2-Clause | | [libtiff] | 4.6.0 | [libtiff License] (BSD-like) | -| [libvips] | 8.14.5 | LGPLv3 | +| [libvips] | 8.15.0² | LGPLv3 | | [libwebp] | 1.3.2 | New BSD License | | [libxml2] | 2.11.5 | MIT Licence | | [mozjpeg] | 4.1.5 | [zlib License, IJG License, BSD-3-Clause] | -| [orc] | 0.4.34 | [orc License] (BSD-like) | | [pango] | 1.51.0 | LGPLv3 | | [pixman] | 0.42.2 | MIT Licence | | [proxy-libintl] | 0.4 | LGPLv3 | | [zlib-ng] | 2.1.3 | [zlib-ng Licence] | ¹ [A fork](https://github.com/lovell/libimagequant) of the BSD 2-Clause licensed libimagequant v2.4.1 is used. +² libvips is built from the [`v8.15.0-rc1`](https://github.com/libvips/libvips/tree/v8.15.0-rc1) tag, see: +https://github.com/libvips/libvips/releases/tag/v8.15.0-rc1 [aom]: https://aomedia.googlesource.com/aom/ [Alliance for Open Media Patent License 1.0]: https://aomedia.org/license/patent-license/ @@ -62,6 +64,7 @@ Run the top-level [build script](build.sh) with the `--help` parameter for help. [gdk-pixbuf]: https://gitlab.gnome.org/GNOME/gdk-pixbuf [glib]: https://gitlab.gnome.org/GNOME/glib [harfbuzz]: https://github.com/harfbuzz/harfbuzz +[highway]: https://github.com/google/highway [lcms]: https://github.com/mm2/Little-CMS [libarchive]: https://github.com/libarchive/libarchive [libexif]: https://github.com/libexif/libexif @@ -79,8 +82,6 @@ Run the top-level [build script](build.sh) with the `--help` parameter for help. [libxml2]: https://gitlab.gnome.org/GNOME/libxml2 [mozjpeg]: https://github.com/mozilla/mozjpeg [zlib License, IJG License, BSD-3-Clause]: https://github.com/mozilla/mozjpeg/blob/master/LICENSE.md -[orc]: https://gitlab.freedesktop.org/gstreamer/orc -[orc License]: https://gitlab.freedesktop.org/gstreamer/orc/blob/master/COPYING [pango]: https://gitlab.gnome.org/GNOME/pango [pixman]: https://gitlab.freedesktop.org/pixman/pixman [proxy-libintl]: https://github.com/frida/proxy-libintl @@ -96,7 +97,6 @@ Same as libvips-web + these extra dependencies: | [brotli] | 1.1.0 | MIT Licence | | [cfitsio] | 4.3.0 | BSD-like | | [fftw] | 3.3.10 | GPLv2 | -| [highway] | 1.0.7 | Apache-2.0 License, BSD 3-Clause | | [imagemagick] | 6.9.12-98 | [ImageMagick License] (Apache-2.0-like) | | [imath] | 3.1.9 | BSD 3-Clause | | [libdicom] | 1.0.5 | MIT Licence | @@ -112,7 +112,6 @@ Same as libvips-web + these extra dependencies: [brotli]: https://github.com/google/brotli [cfitsio]: https://heasarc.gsfc.nasa.gov/fitsio/ [fftw]: https://github.com/FFTW/fftw3 -[highway]: https://github.com/google/highway [imagemagick]: https://github.com/ImageMagick/ImageMagick6 [ImageMagick License]: https://imagemagick.org/script/license.php [imath]: https://github.com/AcademySoftwareFoundation/Imath diff --git a/build/orc.mk b/build/orc.mk deleted file mode 100644 index e5fc4dcf..00000000 --- a/build/orc.mk +++ /dev/null @@ -1,30 +0,0 @@ -PKG := orc -$(PKG)_WEBSITE := https://gstreamer.freedesktop.org/modules/orc.html -$(PKG)_DESCR := Library and set of tools for compiling and executing SIMD assembly language-like programs that operate on arrays of data. -$(PKG)_IGNORE := -$(PKG)_VERSION := 0.4.34 -$(PKG)_CHECKSUM := 8f47abb3f097171e44eb807adcdabd860fba2effd37d8d3c4fbd5f341cadd41f -$(PKG)_PATCHES := $(realpath $(sort $(wildcard $(dir $(lastword $(MAKEFILE_LIST)))/patches/$(PKG)-[0-9]*.patch))) -$(PKG)_SUBDIR := $(PKG)-$($(PKG)_VERSION) -$(PKG)_FILE := $(PKG)-$($(PKG)_VERSION).tar.xz -$(PKG)_URL := https://gstreamer.freedesktop.org/src/$(PKG)/$($(PKG)_FILE) -$(PKG)_DEPS := cc meson-wrapper - -define $(PKG)_UPDATE - $(WGET) -q -O- 'https://gstreamer.freedesktop.org/src/orc/?C=M;O=D' | \ - $(SED) -n 's,.*orc-\([0-9][^>]*\)\.tar.*,\1,p' | \ - head -1 -endef - -define $(PKG)_BUILD - $(MXE_MESON_WRAPPER) \ - -Dorc-test=disabled \ - -Dbenchmarks=disabled \ - -Dexamples=disabled \ - -Dgtk_doc=disabled \ - -Dtests=disabled \ - '$(SOURCE_DIR)' \ - '$(BUILD_DIR)' - - $(MXE_NINJA) -C '$(BUILD_DIR)' -j '$(JOBS)' install -endef diff --git a/build/patches/orc-0.4-fixes.patch b/build/patches/orc-0.4-fixes.patch deleted file mode 100644 index bb04c41b..00000000 --- a/build/patches/orc-0.4-fixes.patch +++ /dev/null @@ -1,70 +0,0 @@ -This file is part of MXE. See LICENSE.md for licensing information. - -Contains ad hoc patches for cross building. - -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kleis Auke Wolthuizen -Date: Thu, 18 Apr 2019 16:00:00 +0200 -Subject: [PATCH 1/1] Fix symbol visibility with MinGW-w64 / static library - - -diff --git a/meson.build b/meson.build -index 1111111..2222222 100644 ---- a/meson.build -+++ b/meson.build -@@ -18,6 +18,7 @@ add_project_arguments('-DHAVE_CONFIG_H', language : 'c') - - orc_inc = include_directories('.') - -+host_os = host_machine.system() - cc = meson.get_compiler('c') - - cdata = configuration_data() # config.h -@@ -30,13 +31,19 @@ if meson.version().version_compare('>= 0.46.0') - endif - - # Symbol visibility --if cc.get_id() == 'msvc' -- export_define = '__declspec(dllexport) extern' --elif cc.has_argument('-fvisibility=hidden') -- add_project_arguments('-fvisibility=hidden', language: 'c') -- export_define = 'extern __attribute__ ((visibility ("default")))' --else -- export_define = 'extern' -+export_define = 'extern' -+if get_option('default_library') != 'static' -+ if host_os == 'windows' or host_os == 'cygwin' -+ if cc.get_id() == 'msvc' -+ export_define = '__declspec(dllexport) extern' -+ elif cc.has_argument('-fvisibility=hidden') -+ add_project_arguments('-fvisibility=hidden', language: 'c') -+ export_define = '__attribute__((visibility("default"))) __declspec(dllexport) extern' -+ endif -+ elif cc.has_argument('-fvisibility=hidden') -+ add_project_arguments('-fvisibility=hidden', language: 'c') -+ export_define = '__attribute__((visibility("default"))) extern' -+ endif - endif - # Passing this through the command line would be too messy - cdata.set('ORC_API_EXPORT', export_define) -@@ -96,7 +103,6 @@ if cc.has_header_symbol('android/log.h', '__android_log_print') - liblog = [cc.find_library('log', required : true)] - endif - --host_os = host_machine.system() - if host_os == 'windows' - cdata.set('HAVE_CODEMEM_VIRTUALALLOC', true) - cdata.set('HAVE_OS_WIN32', true) -diff --git a/orc/orcutils.h b/orc/orcutils.h -index 1111111..2222222 100644 ---- a/orc/orcutils.h -+++ b/orc/orcutils.h -@@ -210,7 +210,7 @@ typedef unsigned int orc_bool; - /* FIXME: unused, remove */ - #define ORC_EXPORT - --#if (defined(_MSC_VER) || defined(_WIN32)) && !defined(ORC_STATIC_COMPILATION) -+#if defined(_MSC_VER) && !defined(ORC_STATIC_COMPILATION) - #define ORC_API_IMPORT __declspec(dllimport) extern - #else - #define ORC_API_IMPORT extern diff --git a/build/patches/vips-8-dlldir-as-libdir.patch b/build/patches/vips-8-dlldir-as-libdir.patch index daa57387..6257b5fc 100644 --- a/build/patches/vips-8-dlldir-as-libdir.patch +++ b/build/patches/vips-8-dlldir-as-libdir.patch @@ -9,35 +9,35 @@ diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 1111111..2222222 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h -@@ -392,6 +392,7 @@ guint32 vips__random( guint32 seed ); - guint32 vips__random_add( guint32 seed, int value ); +@@ -437,6 +437,7 @@ guint32 vips__random(guint32 seed); + guint32 vips__random_add(guint32 seed, int value); - const char *vips__icc_dir( void ); -+const char *vips__dll_dir( void ); - const char *vips__windows_prefix( void ); + const char *vips__icc_dir(void); ++const char *vips__dll_dir(void); + const char *vips__windows_prefix(void); - char *vips__get_iso8601( void ); + char *vips__get_iso8601(void); diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 1111111..2222222 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c -@@ -1200,6 +1200,12 @@ vips_guess_prefix( const char *argv0, const char *env_name ) +@@ -1166,6 +1166,12 @@ vips_guess_prefix(const char *argv0, const char *env_name) const char * - vips_guess_libdir( const char *argv0, const char *env_name ) + vips_guess_libdir(const char *argv0, const char *env_name) { +#if defined(G_OS_WIN32) && defined(VIPS_DLLDIR_AS_LIBDIR) -+ /* Sometimes users want to use the DLL directory where the libvips DLL ++ /* Sometimes users want to use the DLL directory where the libvips DLL + * resides as libdir. + */ -+ return( vips__dll_dir() ); -+#else /*!G_OS_WIN32 || !VIPS_DLLDIR_AS_LIBDIR*/ - const char *prefix = vips_guess_prefix( argv0, env_name ); ++ return vips__dll_dir(); ++#else /*!G_OS_WIN32 || !VIPS_DLLDIR_AS_LIBDIR*/ + const char *prefix = vips_guess_prefix(argv0, env_name); static char *libdir = NULL; -@@ -1224,6 +1230,7 @@ vips_guess_libdir( const char *argv0, const char *env_name ) - libdir = g_strdup_printf( "%s/lib", prefix ); +@@ -1190,6 +1196,7 @@ vips_guess_libdir(const char *argv0, const char *env_name) + libdir = g_strdup_printf("%s/lib", prefix); - return( libdir ); + return libdir; +#endif /*G_OS_WIN32 && VIPS_DLLDIR_AS_LIBDIR*/ } @@ -46,14 +46,14 @@ diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 1111111..2222222 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c -@@ -1993,6 +1993,54 @@ DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) - return( TRUE ); +@@ -1999,6 +1999,54 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) + return TRUE; } #endif + +#ifdef VIPS_DLLDIR_AS_LIBDIR +static void * -+vips__dll_dir_once( void *null ) ++vips__dll_dir_once(void *null) +{ + /* From glib _glib_get_dll_directory() + */ @@ -62,7 +62,7 @@ index 1111111..2222222 100644 + wchar_t wc_fn[MAX_PATH]; + +#ifdef DLL_EXPORT -+ if( vips__dll == NULL ) ++ if (vips__dll == NULL) + return NULL; +#endif + @@ -75,27 +75,27 @@ index 1111111..2222222 100644 + * In a statically built libvips, vips__dll will be NULL and we will + * thus look up the application's .exe file's location. + */ -+ if( !GetModuleFileNameW( vips__dll, wc_fn, MAX_PATH ) ) ++ if (!GetModuleFileNameW(vips__dll, wc_fn, MAX_PATH)) + return NULL; + -+ dll_dir = g_utf16_to_utf8( wc_fn, -1, NULL, NULL, NULL ); ++ dll_dir = g_utf16_to_utf8(wc_fn, -1, NULL, NULL, NULL); + -+ p = strrchr( dll_dir, G_DIR_SEPARATOR ); -+ if( p == NULL ) ++ p = strrchr(dll_dir, G_DIR_SEPARATOR); ++ if (p == NULL) + return NULL; -+ ++ + *p = '\0'; + -+ return( (void *) dll_dir ); ++ return (void *) dll_dir; +} + +const char * -+vips__dll_dir( void ) ++vips__dll_dir(void) +{ + static GOnce once = G_ONCE_INIT; + -+ return( (const char *) g_once( &once, -+ vips__dll_dir_once, NULL ) ); ++ return (const char *) g_once(&once, ++ vips__dll_dir_once, NULL); +} +#endif /*VIPS_DLLDIR_AS_LIBDIR*/ #endif /*G_OS_WIN32*/ diff --git a/build/patches/vips-8-pr-3476.patch b/build/patches/vips-8-pr-3476.patch deleted file mode 100644 index 1faa1365..00000000 --- a/build/patches/vips-8-pr-3476.patch +++ /dev/null @@ -1,1750 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kleis Auke Wolthuizen -Date: Fri, 24 Feb 2023 11:09:35 +0100 -Subject: [PATCH 1/1] dzsave: remove libgsf in favor of libarchive - -Resolves: https://github.com/libvips/libvips/issues/3354 - -diff --git a/README.md b/README.md -index 1111111..2222222 100644 ---- a/README.md -+++ b/README.md -@@ -184,9 +184,9 @@ If available, libvips will save GIFs with - [cgif](https://github.com/dloebl/cgif). If this is not present, vips will - try to save gifs via imagemagick instead. - --### libgsf-1 -+### libarchive - --If available, libvips adds support for creating image pyramids with `dzsave`. -+If available, libvips adds support for creating image pyramids with `dzsave`. - - ### libtiff - -diff --git a/libvips/foreign/dzsave.c b/libvips/foreign/dzsave.c -index 1111111..2222222 100644 ---- a/libvips/foreign/dzsave.c -+++ b/libvips/foreign/dzsave.c -@@ -181,474 +181,33 @@ - #include - #include - --#ifdef HAVE_GSF -+#ifdef HAVE_LIBARCHIVE -+#include -+#include - --/* Disable deprecation warnings from gsf. There are loads, and still not -- * patched as of 12/2020. -- */ --#pragma GCC diagnostic push --#pragma GCC diagnostic ignored "-Wdeprecated-declarations" --#include --#pragma GCC diagnostic pop -- --/* A GSF output object that can write to a VipsTarget. -- */ -- --typedef struct _GsfOutputTarget { -- GsfOutput output; -- -- VipsTarget *target; -- --} GsfOutputTarget; -- --typedef struct { -- GsfOutputClass output_class; --} GsfOutputTargetClass; -- --G_DEFINE_TYPE( GsfOutputTarget, gsf_output_target, GSF_OUTPUT_TYPE ); -- --static gboolean --gsf_output_target_close( GsfOutput *output ) --{ -- GsfOutputTarget *output_target = (GsfOutputTarget *) output; -- -- if( output_target->target ) { -- /* No easy way to report errors here, sadly. -- */ -- (void) vips_target_end( output_target->target ); -- VIPS_UNREF( output_target->target ); -- -- return( TRUE ); -- } -- -- return( FALSE ); --} -- --static void --gsf_output_target_finalize( GObject *obj ) --{ -- GsfOutputTarget *output_target = (GsfOutputTarget *) obj; -- -- (void) gsf_output_target_close( GSF_OUTPUT( output_target ) ); -- -- G_OBJECT_CLASS( gsf_output_target_parent_class )->finalize( obj ); --} -- --static gboolean --gsf_output_target_write( GsfOutput *output, -- size_t num_bytes, guint8 const *buffer ) --{ -- GsfOutputTarget *output_target = (GsfOutputTarget *) output; -- -- if( vips_target_write( output_target->target, buffer, num_bytes ) ) -- return( FALSE ); -- -- return( TRUE ); --} -- --static gboolean --gsf_output_target_seek( GsfOutput *output, gsf_off_t offset, GSeekType whence ) --{ --#ifdef HAVE_GSF_ZIP64 -- /* No seek needed. -- */ -- return( FALSE ); --#else -- GsfOutputTarget *output_target = (GsfOutputTarget *) output; -- int stdio_whence; -- -- switch( whence ) { -- case G_SEEK_CUR: stdio_whence = SEEK_CUR; break; -- case G_SEEK_END: stdio_whence = SEEK_END; break; -- case G_SEEK_SET: stdio_whence = SEEK_SET; break; -- default: -- g_assert_not_reached(); -- } -- -- if( vips_target_seek( output_target->target, -- offset, stdio_whence ) == -1 ) -- return( FALSE ); -- -- /* This will make our parent class handle the seek. -- */ -- return( TRUE ); --#endif --} -- --static void --gsf_output_target_init( GsfOutputTarget *output ) --{ --} -- --static void --gsf_output_target_class_init( GsfOutputTargetClass *class ) --{ -- GObjectClass *gobject_class = G_OBJECT_CLASS( class ); -- GsfOutputClass *output_class = GSF_OUTPUT_CLASS( class ); -- -- gobject_class->finalize = gsf_output_target_finalize; -- -- output_class->Close = gsf_output_target_close; -- output_class->Write = gsf_output_target_write; -- output_class->Seek = gsf_output_target_seek; --} -- --static GsfOutput * --gsf_output_target_new( VipsTarget *target ) --{ -- GsfOutputTarget *output; -- -- output = g_object_new( gsf_output_target_get_type(), NULL ); -- output->target = target; -- g_object_ref( target ); -- -- return( GSF_OUTPUT( output ) ); --} -- --/* A GSF output object that can write to a directory. -- */ -- --typedef struct _GsfOutputDir { -- GsfOutfile output; -- -- char *root; -+static GMutex *vips_libarchive_mutex = NULL; - --} GsfOutputDir; -- --typedef struct { -- GsfOutfileClass output_class; --} GsfOutputDirClass; -- --G_DEFINE_TYPE( GsfOutputDir, gsf_output_dir, GSF_OUTFILE_TYPE ); -- --static gboolean --gsf_output_dir_close( GsfOutput *output ) -+static ssize_t -+zip_write_target_cb( struct archive *a, void *client_data, -+ const void *data, size_t length ) - { -- return( TRUE ); --} -+ VipsTarget *target = VIPS_TARGET( client_data ); - --static void --gsf_output_dir_finalize( GObject *obj ) --{ -- GsfOutputDir *output_dir = (GsfOutputDir *) obj; -- -- g_free( output_dir->root ); -- -- G_OBJECT_CLASS( gsf_output_dir_parent_class )->finalize( obj ); --} -- --static GsfOutfile * --gsf_output_dir_new_valist( char const *root, -- char const *first_property_name, va_list var_args ) --{ -- GsfOutputDir *output_dir; -- -- if( g_mkdir( root, 0777 ) != 0 && errno != EEXIST ) { -- int save_errno = errno; -- char *utf8name = g_filename_display_name( root ); -- vips_error( "dzsave", -- _( "unable to create directory \"%s\", %s" ), -- utf8name, g_strerror( save_errno ) ); -- g_free( utf8name ); -- return( NULL ); -- } -- -- output_dir = (GsfOutputDir *) g_object_new_valist( GSF_OUTFILE_STDIO_TYPE, -- first_property_name, var_args ); -- output_dir->root = g_strdup( root ); -- gsf_output_set_name_from_filename( GSF_OUTPUT( output_dir ), root ); -- -- return( GSF_OUTFILE( output_dir ) ); --} -- --static GsfOutput * --gsf_output_dir_new_child( GsfOutfile *parent, -- char const *name, gboolean is_dir, -- char const *first_property_name, -- va_list args ) --{ -- GsfOutputDir *output_dir = (GsfOutputDir *) parent; -- GsfOutput *child; -- char *path = g_build_filename( output_dir->root, name, NULL ); -- -- if( is_dir ) -- child = (GsfOutput *) gsf_output_dir_new_valist( path, -- first_property_name, args ); -- else -- child = gsf_output_stdio_new_valist( path, NULL, -- first_property_name, args ); -- g_free( path ); -- -- return( child ); --} -- --static void --gsf_output_dir_init( GsfOutputDir *output ) --{ -- output->root = NULL; --} -- --static void --gsf_output_dir_class_init( GsfOutputDirClass *class ) --{ -- GObjectClass *gobject_class = G_OBJECT_CLASS( class ); -- GsfOutputClass *output_class = GSF_OUTPUT_CLASS( class ); -- GsfOutfileClass *outfile_class = GSF_OUTFILE_CLASS( class ); -- -- gobject_class->finalize = gsf_output_dir_finalize; -- -- output_class->Close = gsf_output_dir_close; -- output_class->Seek = NULL; -- output_class->Write = NULL; -- output_class->Vprintf = NULL; -- -- outfile_class->new_child = gsf_output_dir_new_child; --} -- --static GsfOutput * --gsf_output_dir_new( char const *root, ... ) --{ -- GsfOutfile *output; -- va_list var_args; -- -- va_start( var_args, root ); -- output = gsf_output_dir_new_valist( root, NULL, var_args ); -- va_end( var_args ); -- -- return( GSF_OUTPUT( output ) ); --} -- --/* Simple wrapper around libgsf. -- * -- * We need to be able to do scattered writes to structured files. So while -- * building a zip (for example) we need to be able to write to file/a/b.jpg, -- * then to file/c/d.jpg, then back to file/a/e.jpg. This is tricky with the -- * libgsf API which is happier doing writes in order. -- * -- * Put an API over libgsf to track refs to all directories and finish/close -- * them. -- */ -- --/* Need to track the directory tree we are writing, with a ref for each -- * GsfOutput. -- */ --typedef struct _VipsGsfDirectory { -- struct _VipsGsfDirectory *parent; -- char *name; -- -- /* List of child directories, if any. -- */ -- GSList *children; -- -- /* The GsfOutput we use for this object. -- */ -- GsfOutput *out; -- -- /* The root node holds the enclosing zip file or FS root ... finish -- * this on cleanup. -- */ -- GsfOutput *container; -- -- /* Track number of files in tree and total length of filenames. We use -- * this to estimate zip size to spot a >4gb write. -- */ -- size_t file_count; -- size_t filename_lengths; -- -- /* Set deflate compression level for zip container. -- */ -- gint deflate_level; -- --} VipsGsfDirectory; -- --static void *vips_gsf_tree_close( VipsGsfDirectory *tree ); -- --static void * --vips_gsf_tree_close_cb( void *item, void *a, void *b ) --{ -- VipsGsfDirectory *tree = (VipsGsfDirectory *) item; -- -- return( vips_gsf_tree_close( tree ) ); --} -- --/* Close all dirs, non-NULL on error. -- */ --static void * --vips_gsf_tree_close( VipsGsfDirectory *tree ) --{ -- vips_slist_map2( tree->children, vips_gsf_tree_close_cb, NULL, NULL ); -- -- if( tree->out ) { -- if( !gsf_output_is_closed( tree->out ) && -- !gsf_output_close( tree->out ) ) { -- vips_error( "vips_gsf", -- "%s", _( "unable to close stream" ) ); -- return( tree ); -- } -- -- VIPS_UNREF( tree->out ); -- } -- -- if( tree->container ) { -- if( !gsf_output_is_closed( tree->container ) && -- !gsf_output_close( tree->container ) ) { -- vips_error( "vips_gsf", -- "%s", _( "unable to close stream" ) ); -- return( tree ); -- } -- -- VIPS_UNREF( tree->container ); -- } -- -- VIPS_FREEF( g_slist_free, tree->children ); -- VIPS_FREE( tree->name ); -- VIPS_FREE( tree ); -- -- return( NULL ); --} -- --/* Make a new tree root. -- */ --static VipsGsfDirectory * --vips_gsf_tree_new( GsfOutput *out, gint deflate_level ) --{ -- VipsGsfDirectory *tree = g_new( VipsGsfDirectory, 1 ); -- -- tree->parent = NULL; -- tree->name = NULL; -- tree->children = NULL; -- tree->out = out; -- tree->container = NULL; -- tree->file_count = 0; -- tree->filename_lengths = 0; -- tree->deflate_level = deflate_level; -- -- return( tree ); --} -- --static void * --vips_gsf_child_by_name_sub( VipsGsfDirectory *dir, const char *name, void *b ) --{ -- if( strcmp( dir->name, name ) == 0 ) -- return( dir ); -- -- return( NULL ); --} -- --/* Look up a child by name. -- */ --static VipsGsfDirectory * --vips_gsf_child_by_name( VipsGsfDirectory *dir, const char *name ) --{ -- return( vips_slist_map2( dir->children, -- (VipsSListMap2Fn) vips_gsf_child_by_name_sub, -- (char *) name, NULL ) ); --} -- --/* Make a new directory. -- */ --static VipsGsfDirectory * --vips_gsf_dir_new( VipsGsfDirectory *parent, const char *name ) --{ -- VipsGsfDirectory *dir = g_new( VipsGsfDirectory, 1 ); -- -- g_assert( !vips_gsf_child_by_name( parent, name ) ); -- -- dir->parent = parent; -- dir->name = g_strdup( name ); -- dir->children = NULL; -- dir->container = NULL; -- dir->file_count = 0; -- dir->filename_lengths = 0; -- dir->deflate_level = parent->deflate_level; -- -- if( GSF_IS_OUTFILE_ZIP( parent->out ) ) -- dir->out = gsf_outfile_new_child_full( -- (GsfOutfile *) parent->out, -- name, TRUE, -- "compression-level", GSF_ZIP_STORED, -- NULL ); -- else -- dir->out = gsf_outfile_new_child( -- (GsfOutfile *) parent->out, -- name, TRUE ); -- -- g_assert( dir->out ); -- -- parent->children = g_slist_prepend( parent->children, dir ); -+ if( vips_target_write( target, data, length ) ) -+ return( -1 ); - -- return( dir ); -+ return( length ); - } - --/* Return a GsfOutput or %NULL for writing to a path. Paths are object name first, -- * then path components with least-specific first, NULL-terminated. For example: -- * -- * GsfOutput *obj = vips_gsf_path( tree, "fred.jpg", "a", "b", NULL ); -- * -- * Returns an obj you can use to write to a/b/fred.jpg, or %NULL when it exceeds -- * the path limits. -- * -- * You must write, close and unref obj. -- */ --static GsfOutput * --vips_gsf_path( VipsGsfDirectory *tree, const char *name, ... ) -+static int -+zip_close_target_cb( struct archive *a, void *client_data ) - { -- va_list ap; -- VipsGsfDirectory *dir; -- VipsGsfDirectory *child; -- char *dir_name; -- GsfOutput *obj; -- -- /* vips_gsf_path() always makes a new file, though it may add to an -- * existing directory. Note the file, and note the length of the full -- * path we are creating. -- */ -- tree->file_count += 1; -- tree->filename_lengths += -- strlen( tree->out->name ) + strlen( name ) + 1; -- -- dir = tree; -- va_start( ap, name ); -- while( (dir_name = va_arg( ap, char * )) ) { -- if( (child = vips_gsf_child_by_name( dir, dir_name )) ) -- dir = child; -- else -- dir = vips_gsf_dir_new( dir, dir_name ); -+ VipsTarget *target = VIPS_TARGET( client_data ); - -- tree->filename_lengths += strlen( dir_name ) + 1; -- } -- va_end( ap ); -+ if( vips_target_end( target ) ) -+ return( ARCHIVE_FATAL ); - -- if( GSF_IS_OUTFILE_ZIP( dir->out ) ) { -- /* Confusingly, libgsf compression-level really means -- * compression-method. They have a separate deflate-level -- * property for the deflate compression level. -- */ -- if( dir->deflate_level == 0 ) -- obj = gsf_outfile_new_child_full( -- (GsfOutfile *) dir->out, -- name, FALSE, -- "compression-level", GSF_ZIP_STORED, -- NULL ); -- else if( dir->deflate_level == -1 ) -- obj = gsf_outfile_new_child_full( -- (GsfOutfile *) dir->out, -- name, FALSE, -- "compression-level", GSF_ZIP_DEFLATED, -- NULL ); -- else -- obj = gsf_outfile_new_child_full( -- (GsfOutfile *) dir->out, -- name, FALSE, -- "compression-level", GSF_ZIP_DEFLATED, -- "deflate-level", dir->deflate_level, -- NULL ); -- } -- else -- obj = gsf_outfile_new_child( (GsfOutfile *) dir->out, -- name, FALSE ); -- -- return( obj ); -+ return( ARCHIVE_OK ); - } - - typedef struct _VipsForeignSaveDz VipsForeignSaveDz; -@@ -762,21 +321,16 @@ struct _VipsForeignSaveDz { - */ - int tile_count; - -- /* The tree structure we are writing tiles to. Can be filesystem, a -- * zipfile, etc. -- */ -- VipsGsfDirectory *tree; -- -- /* The actual output object our zip (or whatever) is writing to. -+ /* The zipfile we are writing tiles to. - */ -- GsfOutput *out; -+ struct archive *archive; - - /* The name to save as, eg. deepzoom tiles go into ${basename}_files. - * No suffix, no path at the start. - */ - char *basename; - -- /* The directory we write the output to, or NULL for memory output. -+ /* The directory we write the output to, or "" (empty) for memory output. - */ - char *dirname; - -@@ -790,11 +344,6 @@ struct _VipsForeignSaveDz { - */ - char *file_suffix; - -- /* libgsf before 1.14.31 can't write zip files larger than 4gb. -- * Track bytes written here and try to guess when we'll go over. -- */ -- size_t bytes_written; -- - /* save->background turned into a pixel that matches the image we are - * saving .. used to test for blank tiles. - */ -@@ -807,11 +356,6 @@ typedef VipsForeignSaveClass VipsForeignSaveDzClass; - G_DEFINE_ABSTRACT_TYPE( VipsForeignSaveDz, vips_foreign_save_dz, - VIPS_TYPE_FOREIGN_SAVE ); - --#define VIPS_ZIP_FIXED_LH_SIZE (30 + 29) --#define VIPS_ZIP_FIXED_CD_SIZE (46 + 9) --#define VIPS_ZIP_EOCD_SIZE 22 -- --#ifndef HAVE_GSF_ZIP64 - /* ZIP and SZI are both written as zip files. - */ - static gboolean -@@ -827,100 +371,179 @@ iszip( VipsForeignDzContainer container ) - } - } - --static size_t --estimate_zip_size( VipsForeignSaveDz *dz ) -+static inline int -+vips_mkdir_zip( VipsForeignSaveDz *dz, const char *dirname ) - { -- size_t estimated_zip_size = dz->bytes_written + -- dz->tree->file_count * VIPS_ZIP_FIXED_LH_SIZE + -- dz->tree->filename_lengths + -- dz->tree->file_count * VIPS_ZIP_FIXED_CD_SIZE + -- dz->tree->filename_lengths + -- VIPS_ZIP_EOCD_SIZE; -+ struct archive_entry *entry; - --#ifdef DEBUG_VERBOSE -- printf( "estimate_zip_size: %zd\n", estimated_zip_size ); --#endif /*DEBUG_VERBOSE*/ -+ vips__worker_lock( vips_libarchive_mutex ); -+ -+ if( !(entry = archive_entry_new()) ) { -+ g_mutex_unlock( vips_libarchive_mutex ); -+ return( -1 ); -+ } -+ -+ archive_entry_set_pathname( entry, dirname ); -+ archive_entry_set_mode( entry, S_IFDIR | 0755 ); -+ -+ if( archive_write_header( dz->archive, entry ) != ARCHIVE_OK ) { -+ char *utf8name = g_filename_display_name( dirname ); -+ vips_error( "dzsave", -+ _( "unable to add directory \"%s\", %s" ), -+ utf8name, archive_error_string( dz->archive ) ); -+ g_free( utf8name ); -+ archive_entry_free( entry ); -+ g_mutex_unlock( vips_libarchive_mutex ); -+ return( -1 ); -+ } -+ -+ archive_entry_free( entry ); -+ g_mutex_unlock( vips_libarchive_mutex ); - -- return( estimated_zip_size ); -+ return( 0 ); -+} -+ -+static inline int -+vips_mkdir_file( const char *dirname ) -+{ -+ if( g_mkdir_with_parents( dirname, 0777 ) && -+ errno != EEXIST ) { -+ int save_errno = errno; -+ char *utf8name = g_filename_display_name( dirname ); -+ vips_error( "dzsave", -+ _( "unable to create directory \"%s\", %s" ), -+ utf8name, g_strerror( save_errno ) ); -+ g_free( utf8name ); -+ return( -1 ); -+ } -+ -+ return( 0 ); - } --#endif /*HAVE_GSF_ZIP64*/ - - static int --write_image( VipsForeignSaveDz *dz, -- GsfOutput *out, VipsImage *image, const char *format ) -+vips_mkdir( VipsForeignSaveDz *dz, const char *dirname ) - { -- VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( dz ); -+ if( iszip( dz->container ) ) -+ return( vips_mkdir_zip( dz, dirname ) ); -+ else -+ return( vips_mkdir_file( dirname ) ); -+} - -- VipsImage *t; -- void *buf; -- size_t len; -+static inline int -+vips_mkfile_zip( VipsForeignSaveDz *dz, const char *filename, -+ void *buf, size_t len ) -+{ -+ struct archive_entry *entry; - -- /* We need to block progress signalling on individual image write, so -- * we need a copy of the tile in case it's shared (eg. associated -- * images). -- */ -- if( vips_copy( image, &t, NULL ) ) -+ vips__worker_lock( vips_libarchive_mutex ); -+ -+ if( !(entry = archive_entry_new()) ) { -+ g_free( buf ); -+ g_mutex_unlock( vips_libarchive_mutex ); - return( -1 ); -+ } - -- /* We default to stripping all metadata. "no_strip" turns this -- * off. Most people don't want metadata on every tile. -- */ -- vips_image_set_int( t, "hide-progress", 1 ); -- if( vips_image_write_to_buffer( t, format, &buf, &len, -- "strip", !dz->no_strip, -- NULL ) ) { -- VIPS_UNREF( t ); -+ archive_entry_set_pathname( entry, filename ); -+ archive_entry_set_mode( entry, S_IFREG | 0664 ); -+ archive_entry_set_size( entry, len ); -+ -+ if( archive_write_header( dz->archive, entry ) != ARCHIVE_OK ) { -+ archive_entry_free( entry ); -+ g_free( buf ); -+ g_mutex_unlock( vips_libarchive_mutex ); - return( -1 ); - } -- VIPS_UNREF( t ); - -- /* gsf doesn't like more than one write active at once. -- */ -- g_mutex_lock( vips__global_lock ); -+ archive_entry_free( entry ); - -- if( !gsf_output_write( out, len, buf ) ) { -- gsf_output_close( out ); -- g_mutex_unlock( vips__global_lock ); -+ if( archive_write_data( dz->archive, buf, len ) != len ) { - g_free( buf ); -+ g_mutex_unlock( vips_libarchive_mutex ); -+ return( -1 ); -+ } - -- if( gsf_output_error( out ) ) -- vips_error( class->nickname, -- "%s", gsf_output_error( out )->message ); -+ g_free( buf ); -+ g_mutex_unlock( vips_libarchive_mutex ); - -+ return( 0 ); -+} -+ -+static inline int -+vips_mkfile_file( const char *filename, void *buf, size_t len ) -+{ -+ FILE *f; -+ -+ if( !(f = vips__file_open_write( filename, TRUE )) ) { -+ g_free( buf ); - return( -1 ); - } - -- dz->bytes_written += len; -+ if( fwrite( buf, sizeof( char ), len, f ) != len ) { -+ fclose( f ); -+ g_free( buf ); -+ return( -1 ); -+ } - -- gsf_output_close( out ); -+ fclose( f ); -+ g_free( buf ); - --#ifndef HAVE_GSF_ZIP64 -- if( iszip( dz->container ) ) { -- /* Leave 3 entry headroom for blank.png and metadata files. -- */ -- if( dz->tree->file_count + 3 >= (unsigned int) USHRT_MAX ) { -- g_mutex_unlock( vips__global_lock ); -+ return( 0 ); -+} - -- vips_error( class->nickname, -- "%s", _( "too many files in zip" ) ); -+static int -+vips_mkfile( VipsForeignSaveDz *dz, const char *filename, -+ void *buf, size_t len ) -+{ -+ if( iszip( dz->container ) ) -+ return( vips_mkfile_zip( dz, filename, buf, len ) ); -+ else -+ return( vips_mkfile_file( filename, buf, len ) ); -+} -+ -+static int -+write_image( VipsForeignSaveDz *dz, -+ VipsImage *image, const char *filename, const char *format ) -+{ -+ VipsImage *t; -+ -+ /* We need to block progress signalling on individual image write, so -+ * we need a copy of the tile in case it's shared (eg. associated -+ * images). -+ */ -+ if( vips_copy( image, &t, NULL ) ) -+ return( -1 ); -+ -+ /* We default to stripping all metadata. "no_strip" turns this -+ * off. Most people don't want metadata on every tile. -+ */ -+ vips_image_set_int( t, "hide-progress", 1 ); -+ -+ if( iszip( dz->container ) ) { -+ void *buf; -+ size_t len; -+ -+ if( vips_image_write_to_buffer( t, format, &buf, &len, -+ "strip", !dz->no_strip, -+ NULL ) ) { -+ VIPS_UNREF( t ); - return( -1 ); - } -+ VIPS_UNREF( t ); - -- /* Leave 16k headroom for blank.png and metadata files. -+ /* vips_mkfile_zip() takes the ownership of buf. - */ -- if( estimate_zip_size( dz ) > (size_t) UINT_MAX - 16384) { -- g_mutex_unlock( vips__global_lock ); -- -- vips_error( class->nickname, -- "%s", _( "output file too large" ) ); -- return( -1 ); -+ if( vips_mkfile_zip( dz, filename, buf, len ) ) -+ return( -1 ); -+ } -+ else { -+ if( vips_image_write_to_file( t, filename, -+ "strip", !dz->no_strip, -+ NULL ) ) { -+ VIPS_UNREF( t ); -+ return( -1 ); - } -+ VIPS_UNREF( t ); - } --#endif /*HAVE_GSF_ZIP64*/ -- -- g_mutex_unlock( vips__global_lock ); -- -- g_free( buf ); - - return( 0 ); - } -@@ -942,11 +565,11 @@ vips_foreign_save_dz_dispose( GObject *gobject ) - { - VipsForeignSaveDz *dz = (VipsForeignSaveDz *) gobject; - -+ VIPS_FREEF( archive_write_free, dz->archive ); -+ - VIPS_UNREF( dz->target ); - - VIPS_FREEF( layer_free, dz->layer ); -- VIPS_FREEF( vips_gsf_tree_close, dz->tree ); -- VIPS_FREEF( g_object_unref, dz->out ); - - VIPS_FREE( dz->basename ); - VIPS_FREE( dz->dirname ); -@@ -1110,34 +733,44 @@ pyramid_build( VipsForeignSaveDz *dz, Layer *above, - static int - write_dzi( VipsForeignSaveDz *dz ) - { -- GsfOutput *out; -- char buf[VIPS_PATH_MAX]; -+ VipsDbuf dbuf; -+ char suffix[VIPS_PATH_MAX]; -+ char *filename; - char *p; -+ void *buf; -+ size_t len; - -- vips_snprintf( buf, VIPS_PATH_MAX, "%s.dzi", dz->basename ); -- if( !(out = vips_gsf_path( dz->tree, buf, NULL ) )) -+ vips_snprintf( suffix, VIPS_PATH_MAX, "%s.dzi", dz->basename ); -+ -+ if( !(filename = g_build_filename( dz->dirname, suffix, NULL )) ) - return( -1 ); - -- vips_snprintf( buf, VIPS_PATH_MAX, "%s", dz->suffix + 1 ); -- if( (p = (char *) vips__find_rightmost_brackets( buf )) ) -+ vips_dbuf_init( &dbuf ); -+ -+ vips_snprintf( suffix, VIPS_PATH_MAX, "%s", dz->suffix + 1 ); -+ if( (p = (char *) vips__find_rightmost_brackets( suffix )) ) - *p = '\0'; - -- gsf_output_printf( out, "\n" ); -- gsf_output_printf( out, "\n" ); -+ vips_dbuf_writef( &dbuf, "overlap ); -- gsf_output_printf( out, " TileSize=\"%d\"\n", dz->tile_size ); -- gsf_output_printf( out, " >\n" ); -- gsf_output_printf( out, " layer->height ); -- gsf_output_printf( out, " Width=\"%d\"\n", dz->layer->width ); -- gsf_output_printf( out, " />\n" ); -- gsf_output_printf( out, "\n" ); -- -- (void) gsf_output_close( out ); -- g_object_unref( out ); -+ vips_dbuf_writef( &dbuf, " Format=\"%s\"\n", suffix ); -+ vips_dbuf_writef( &dbuf, " Overlap=\"%d\"\n", dz->overlap ); -+ vips_dbuf_writef( &dbuf, " TileSize=\"%d\"\n", dz->tile_size ); -+ vips_dbuf_writef( &dbuf, " >\n" ); -+ vips_dbuf_writef( &dbuf, " layer->height ); -+ vips_dbuf_writef( &dbuf, " Width=\"%d\"\n", dz->layer->width ); -+ vips_dbuf_writef( &dbuf, " />\n" ); -+ vips_dbuf_writef( &dbuf, "\n" ); -+ -+ if( !(buf = vips_dbuf_steal( &dbuf, &len )) || -+ vips_mkfile( dz, filename, buf, len ) ) { -+ g_free( filename ); -+ return( -1 ); -+ } -+ -+ g_free( filename ); - - return( 0 ); - } -@@ -1145,14 +778,18 @@ write_dzi( VipsForeignSaveDz *dz ) - static int - write_properties( VipsForeignSaveDz *dz ) - { -- GsfOutput *out; -+ VipsDbuf dbuf; -+ char *filename; -+ void *buf; -+ size_t len; - -- if( !(out = vips_gsf_path( dz->tree, -- "ImageProperties.xml", NULL ) )) { -+ if( !(filename = g_build_filename( dz->dirname, dz->root_name, -+ "ImageProperties.xml", NULL )) ) - return( -1 ); -- } - -- gsf_output_printf( out, "\n", - dz->layer->width, -@@ -1160,8 +797,13 @@ write_properties( VipsForeignSaveDz *dz ) - dz->tile_count, - dz->tile_size ); - -- (void) gsf_output_close( out ); -- g_object_unref( out ); -+ if( !(buf = vips_dbuf_steal( &dbuf, &len )) || -+ vips_mkfile( dz, filename, buf, len ) ) { -+ g_free( filename ); -+ return( -1 ); -+ } -+ -+ g_free( filename ); - - return( 0 ); - } -@@ -1177,7 +819,7 @@ write_blank( VipsForeignSaveDz *dz ) - double *d; - double *bg; - int i; -- GsfOutput *out; -+ char *filename; - - /* Number of bands we will end up making. We need to set this in - * vips_black() to make sure we set Type correctly, otherwise we can -@@ -1203,21 +845,21 @@ write_blank( VipsForeignSaveDz *dz ) - g_object_unref( x ); - x = t; - -- if( !(out = vips_gsf_path( dz->tree, "blank.png", NULL ) )) { -+ if( !(filename = g_build_filename( dz->dirname, dz->root_name, -+ "blank.png", NULL )) ) { - g_object_unref( x ); - - return( -1 ); - } - -- if( write_image( dz, out, x, ".png" ) ) { -- g_object_unref( out ); -+ if( write_image( dz, x, filename, ".png" ) ) { -+ g_free( filename ); - g_object_unref( x ); - - return( -1 ); - } - -- g_object_unref( out ); -- -+ g_free( filename ); - g_object_unref( x ); - - return( 0 ); -@@ -1237,14 +879,20 @@ write_json( VipsForeignSaveDz *dz ) - const char *suffix = dz->file_suffix[0] == '.' ? - dz->file_suffix + 1 : dz->file_suffix; - -- GsfOutput *out; -+ VipsDbuf dbuf; -+ char *filename; -+ void *buf; -+ size_t len; - int i; - -- if( !(out = vips_gsf_path( dz->tree, "info.json", NULL ) )) -+ if( !(filename = g_build_filename( dz->dirname, dz->root_name, -+ "info.json", NULL )) ) - return( -1 ); - -- if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_IIIF3 ) -- gsf_output_printf( out, -+ vips_dbuf_init( &dbuf ); -+ -+ if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_IIIF3 ) -+ vips_dbuf_writef( &dbuf, - "{\n" - " \"@context\": " - "\"http://iiif.io/api/image/3/context.json\",\n" -@@ -1255,7 +903,7 @@ write_json( VipsForeignSaveDz *dz ) - dz->id ? dz->id : "https://example.com/iiif", - name ); - else -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - "{\n" - " \"@context\": " - "\"http://iiif.io/api/image/2/context.json\",\n" -@@ -1279,59 +927,64 @@ write_json( VipsForeignSaveDz *dz ) - /* "sizes" is needed for the full/ set of untiled images, which we - * don't yet support. Leave this commented out for now. - -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " \"sizes\": [\n" ); - - for( i = 0; i < dz->layer->n + 5; i++ ) { -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " {\n" - " \"width\": %d,\n" - " \"height\": \"full\"\n" - " }", - 1 << (i + 4) ); - if( i != dz->layer->n - 4 ) -- gsf_output_printf( out, "," ); -- gsf_output_printf( out, "\n" ); -+ vips_dbuf_writef( &dbuf, "," ); -+ vips_dbuf_writef( &dbuf, "\n" ); - } - -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " ],\n" ); - - */ - - /* The set of pyramid layers we have written. - */ -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " \"tiles\": [\n" - " {\n" - " \"scaleFactors\": [\n" ); - - for( i = 0; i < dz->layer->n; i++ ) { -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " %d", - 1 << i ); - if( i != dz->layer->n - 1 ) -- gsf_output_printf( out, "," ); -- gsf_output_printf( out, "\n" ); -+ vips_dbuf_writef( &dbuf, "," ); -+ vips_dbuf_writef( &dbuf, "\n" ); - } - -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " ],\n" - " \"width\": %d\n" - " }\n" - " ],\n", dz->tile_size ); - -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - " \"width\": %d,\n" - " \"height\": %d\n", - dz->layer->width, - dz->layer->height ); - -- gsf_output_printf( out, -+ vips_dbuf_writef( &dbuf, - "}\n" ); - -- (void) gsf_output_close( out ); -- g_object_unref( out ); -+ if( !(buf = vips_dbuf_steal( &dbuf, &len )) || -+ vips_mkfile( dz, filename, buf, len ) ) { -+ g_free( filename ); -+ return( -1 ); -+ } -+ -+ g_free( filename ); - - return( 0 ); - } -@@ -1341,32 +994,35 @@ write_vips_meta( VipsForeignSaveDz *dz ) - { - VipsForeignSave *save = (VipsForeignSave *) dz; - -+ char *filename; - char *dump; -- GsfOutput *out; -- -- if( !(dump = vips__xml_properties( save->ready )) ) -- return( -1 ); - -- /* For deepzom the props must go inside the ${name}_files subdir, for -+ /* For deepzoom the props must go inside the ${name}_files subdir, for - * gm and zoomify it can sit in the main folder. - */ - if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_DZ ) -- out = vips_gsf_path( dz->tree, -- "vips-properties.xml", dz->root_name, NULL ); -+ filename = g_build_filename( dz->dirname, dz->root_name, -+ "vips-properties.xml", NULL ); - else -- out = vips_gsf_path( dz->tree, "vips-properties.xml", NULL ); -+ filename = g_build_filename( dz->dirname, -+ "vips-properties.xml", NULL ); - -- if( out == NULL ) { -- g_free( dump ); -+ if( filename == NULL ) -+ return( -1 ); - -+ if( !(dump = vips__xml_properties( save->ready )) ) { -+ g_free( filename ); - return( -1 ); - } - -- (void) gsf_output_write( out, strlen( dump ), (guchar *) dump ); -- (void) gsf_output_close( out ); -- g_object_unref( out ); -+ /* vips_mkfile() takes the ownership of dump. -+ */ -+ if( vips_mkfile( dz, filename, dump, strlen( dump ) ) ) { -+ g_free( filename ); -+ return( -1 ); -+ } - -- g_free( dump ); -+ g_free( filename ); - - return( 0 ); - } -@@ -1435,7 +1091,7 @@ static char *scan_property_names[][2] = { - * Free with g_free(). - */ - static char * --build_scan_properties( VipsImage *image ) -+build_scan_properties( VipsImage *image, size_t *len ) - { - VipsDbuf dbuf; - char *date; -@@ -1459,7 +1115,7 @@ build_scan_properties( VipsImage *image ) - vips_dbuf_writef( &dbuf, " \n" ); - vips_dbuf_writef( &dbuf, "\n" ); - -- return( (char *) vips_dbuf_steal( &dbuf, NULL ) ); -+ return( (char *) vips_dbuf_steal( &dbuf, len ) ); - } - - static int -@@ -1467,24 +1123,27 @@ write_scan_properties( VipsForeignSaveDz *dz ) - { - VipsForeignSave *save = (VipsForeignSave *) dz; - -+ char *filename; - char *dump; -- GsfOutput *out; -+ size_t len; - -- if( !(dump = build_scan_properties( save->ready )) ) -- return( -1 ); -- -- if( !(out = vips_gsf_path( dz->tree, -- "scan-properties.xml", NULL ) )) { -- g_free( dump ); -+ if( !(filename = g_build_filename( dz->dirname, -+ "scan-properties.xml", NULL )) ) -+ return( -1 ); - -+ if( !(dump = build_scan_properties( save->ready, &len )) ) { -+ g_free( filename ); - return( -1 ); - } - -- (void) gsf_output_write( out, strlen( dump ), (guchar *) dump ); -- (void) gsf_output_close( out ); -- g_object_unref( out ); -+ /* vips_mkfile() takes the ownership of dump. -+ */ -+ if( vips_mkfile( dz, filename, dump, len ) ) { -+ g_free( filename ); -+ return( -1 ); -+ } - -- g_free( dump ); -+ g_free( filename ); - - return( 0 ); - } -@@ -1499,7 +1158,8 @@ write_associated_images( VipsImage *image, - VipsImage *associated; - const char *p; - const char *q; -- GsfOutput *out; -+ char *dirname; -+ char *out; - char buf[VIPS_PATH_MAX]; - - p = field + strlen( "openslide.associated." ); -@@ -1512,23 +1172,33 @@ write_associated_images( VipsImage *image, - if( vips_image_get_image( image, field, &associated ) ) - return( image ); - -+ if( !(dirname = g_build_filename( dz->dirname, -+ "associated_images", NULL )) ) -+ return( image ); -+ -+ if( vips_mkdir( dz, dirname ) ) { -+ g_free( dirname ); -+ return( image ); -+ } -+ - vips_snprintf( buf, VIPS_PATH_MAX, "%s.jpg", p ); -- if( !(out = vips_gsf_path( dz->tree, buf, -- "associated_images", NULL ) )) { -+ -+ if( !(out = g_build_filename( dirname, buf, NULL )) ) { -+ g_free( dirname ); - g_object_unref( associated ); - - return( image ); - } -+ g_free( dirname ); - -- if( write_image( dz, out, associated, ".jpg" ) ) { -- g_object_unref( out ); -+ if( write_image( dz, associated, out, ".jpg" ) ) { -+ g_free( out ); - g_object_unref( associated ); - - return( image ); - } - -- g_object_unref( out ); -- -+ g_free( out ); - g_object_unref( associated ); - } - -@@ -1666,27 +1336,29 @@ strip_allocate( VipsThreadState *state, void *a, gboolean *stop ) - - /* Make an output object for a tile in the current layout. - */ --static GsfOutput * -+static char * - tile_name( Layer *layer, int x, int y ) - { - VipsForeignSaveDz *dz = layer->dz; - VipsForeignSave *save = (VipsForeignSave *) dz; - -- GsfOutput *out; -+ char *out; -+ char *dirname; - char name[VIPS_PATH_MAX]; -- char dirname[VIPS_PATH_MAX]; -- char dirname2[VIPS_PATH_MAX]; -+ char subdir[VIPS_PATH_MAX]; -+ char *suffix; - Layer *p; - int n; - -+ suffix = iszip( dz->container ) -+ ? dz->file_suffix -+ : dz->suffix; -+ - switch( dz->layout ) { - case VIPS_FOREIGN_DZ_LAYOUT_DZ: -- vips_snprintf( dirname, VIPS_PATH_MAX, "%d", layer->n ); -+ vips_snprintf( subdir, VIPS_PATH_MAX, "%d", layer->n ); - vips_snprintf( name, VIPS_PATH_MAX, -- "%d_%d%s", x, y, dz->file_suffix ); -- -- out = vips_gsf_path( dz->tree, name, -- dz->root_name, dirname, NULL ); -+ "%d_%d%s", x, y, suffix ); - - break; - -@@ -1707,25 +1379,21 @@ tile_name( Layer *layer, int x, int y ) - */ - n += y * layer->tiles_across + x; - -- vips_snprintf( dirname, VIPS_PATH_MAX, "TileGroup%d", n / 256 ); -+ vips_snprintf( subdir, VIPS_PATH_MAX, "TileGroup%d", n / 256 ); - vips_snprintf( name, VIPS_PATH_MAX, -- "%d-%d-%d%s", layer->n, x, y, dz->file_suffix ); -+ "%d-%d-%d%s", layer->n, x, y, suffix ); - - /* Used at the end in ImageProperties.xml - */ - dz->tile_count += 1; - -- out = vips_gsf_path( dz->tree, name, dirname, NULL ); -- - break; - - case VIPS_FOREIGN_DZ_LAYOUT_GOOGLE: -- vips_snprintf( dirname, VIPS_PATH_MAX, "%d", layer->n ); -- vips_snprintf( dirname2, VIPS_PATH_MAX, "%d", y ); -+ vips_snprintf( subdir, VIPS_PATH_MAX, -+ "%d" G_DIR_SEPARATOR_S "%d", layer->n, y ); - vips_snprintf( name, VIPS_PATH_MAX, -- "%d%s", x, dz->file_suffix ); -- -- out = vips_gsf_path( dz->tree, name, dirname, dirname2, NULL ); -+ "%d%s", x, suffix ); - - break; - -@@ -1747,8 +1415,10 @@ tile_name( Layer *layer, int x, int y ) - save->ready->Xsize - left ); - int height = VIPS_MIN( dz->tile_size * layer->sub, - save->ready->Ysize - top ); -- vips_snprintf( dirname, VIPS_PATH_MAX, "%d,%d,%d,%d", -- left, top, width, height ); -+ -+ /* Rotation is always 0. -+ */ -+ int rotation = 0; - - if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_IIIF3 ) { - int xsize = VIPS_MIN( dz->tile_size, -@@ -1756,8 +1426,11 @@ tile_name( Layer *layer, int x, int y ) - int ysize = VIPS_MIN( dz->tile_size, - layer->height - y * dz->tile_size ); - -- vips_snprintf( dirname2, VIPS_PATH_MAX, "%d,%d", -- xsize, ysize ); -+ vips_snprintf( subdir, VIPS_PATH_MAX, -+ "%d,%d,%d,%d" G_DIR_SEPARATOR_S "%d,%d" G_DIR_SEPARATOR_S "%d", -+ left, top, width, height, -+ xsize, ysize, -+ rotation ); - } - else { - /* IIIF2 "size" is just real tile width, I think. -@@ -1765,30 +1438,36 @@ tile_name( Layer *layer, int x, int y ) - int size = VIPS_MIN( dz->tile_size, - layer->width - x * dz->tile_size ); - -- vips_snprintf( dirname2, VIPS_PATH_MAX, "%d,", size ); -+ vips_snprintf( subdir, VIPS_PATH_MAX, -+ "%d,%d,%d,%d" G_DIR_SEPARATOR_S "%d," G_DIR_SEPARATOR_S "%d", -+ left, top, width, height, -+ size, -+ rotation ); - } - -- vips_snprintf( name, VIPS_PATH_MAX, "default%s", -- dz->file_suffix ); -- -- /* "0" is rotation and is always 0. -- */ -- out = vips_gsf_path( dz->tree, -- name, dirname, dirname2, "0", NULL ); -+ vips_snprintf( name, VIPS_PATH_MAX, "default%s", suffix ); - } - - break; - - default: - g_assert_not_reached(); -+ } - -- /* Stop compiler warnings. -- */ -- out = NULL; -+ if( !(dirname = g_build_filename( dz->dirname, dz->root_name, -+ subdir, NULL )) ) -+ return( NULL ); -+ -+ if( vips_mkdir( dz, dirname ) ) { -+ g_free( dirname ); -+ return( NULL ); - } - -+ out = g_build_filename( dirname, name, NULL ); -+ g_free( dirname ); -+ - #ifdef DEBUG_VERBOSE -- printf( "tile_name: writing to %s\n", name ); -+ printf( "tile_name: writing to %s\n", out ); - #endif /*DEBUG_VERBOSE*/ - - return( out ); -@@ -1851,7 +1530,7 @@ strip_work( VipsThreadState *state, void *a ) - - VipsImage *x; - VipsImage *t; -- GsfOutput *out; -+ char *out; - - #ifdef DEBUG_VERBOSE - printf( "strip_work\n" ); -@@ -1920,16 +1599,10 @@ strip_work( VipsThreadState *state, void *a ) - x = t; - } - -- /* we need to single-thread around calls to gsf. -- */ -- g_mutex_lock( vips__global_lock ); -- - out = tile_name( layer, - state->x / dz->tile_step, state->y / dz->tile_step ); - -- g_mutex_unlock( vips__global_lock ); -- -- /* vips_gsf_path() can return NULL when it exceeds the path limits. -+ /* g_build_filename() can return NULL when it exceeds the path limits. - */ - if( out == NULL ) { - g_object_unref( x ); -@@ -1937,16 +1610,16 @@ strip_work( VipsThreadState *state, void *a ) - return( -1 ); - } - -- vips_image_set_int( x, VIPS_META_CONCURRENCY, 1 ); -+ vips_image_set_int( x, VIPS_META_CONCURRENCY, 1 ); - -- if( write_image( dz, out, x, dz->suffix ) ) { -- g_object_unref( out ); -+ if( write_image( dz, x, out, dz->suffix ) ) { -+ g_free( out ); - g_object_unref( x ); - - return( -1 ); - } - -- g_object_unref( out ); -+ g_free( out ); - g_object_unref( x ); - - #ifdef DEBUG_VERBOSE -@@ -2023,7 +1696,7 @@ layer_generate_extras( Layer *layer ) - last.top = layer->image->Ysize - 2; - last.width = layer->image->Xsize; - last.height = 2; -- -+ - /* Do we have them both? Fill the last with the next-to-last. - */ - vips_rect_intersectrect( &last, &strip->valid, &last ); -@@ -2487,6 +2160,8 @@ vips_foreign_save_dz_build( VipsObject *object ) - if( !vips_object_argument_isset( object, "dirname" ) ) { - if( filename ) - dz->dirname = g_path_get_dirname( filename ); -+ else -+ dz->dirname = g_strdup( "." ); - } - } - -@@ -2532,87 +2207,74 @@ vips_foreign_save_dz_build( VipsObject *object ) - if( (p = (char *) vips__find_rightmost_brackets( dz->file_suffix )) ) - *p = '\0'; - -- /* Make the thing we write the tiles into. -+ /* Make the zip archive we write the tiles into. - */ -- switch( dz->container ) { -- case VIPS_FOREIGN_DZ_CONTAINER_FS: --{ -- GsfOutput *out; -- char name[VIPS_PATH_MAX]; -- -- /* For filesystem output of deepzoom, we write -- * dirname/basename_files/ and dirname/basename.dzi, ie. the -- * output does not go into a subdirectory. -+ if( iszip( dz->container ) ) { -+ /* Ignore the root directory name for zip output, it should only -+ * be set for filesystem output. - */ -- if( dz->layout == VIPS_FOREIGN_DZ_LAYOUT_DZ ) -- vips_snprintf( name, VIPS_PATH_MAX, -- "%s", dz->dirname ); -- else -- vips_snprintf( name, VIPS_PATH_MAX, -- "%s/%s", dz->dirname, dz->basename ); -- -- if( !(out = (GsfOutput *) -- gsf_output_dir_new( name, NULL )) ) { -- return( -1 ); -- } -- -- dz->tree = vips_gsf_tree_new( out, 0 ); --} -- break; -- -- case VIPS_FOREIGN_DZ_CONTAINER_ZIP: -- case VIPS_FOREIGN_DZ_CONTAINER_SZI: --{ -- GsfOutput *zip; -- GsfOutput *out2; -- GError *error = NULL; -+ VIPS_SETSTR( dz->dirname, "" ); - - /* We can have dzsave("x.zip", container="fs"), ie. zip output - * from write to file. Make a target if we need one. - */ - if( !dz->target ) { -- if( !(dz->target = -+ if( !(dz->target = - vips_target_new_to_file( dz->filename )) ) - return( -1 ); - } - -- /* Can be memory, a file (not a directory tree), pipe, etc. -+ /* Allocate and initialize a new archive. - */ -- dz->out = gsf_output_target_new( dz->target ); -+ if( !(dz->archive = archive_write_new()) ) -+ return( -1 ); - -- if( !(zip = (GsfOutput *) -- gsf_outfile_zip_new( dz->out, &error )) ) { -- vips_g_error( &error ); -+ /* Set format to zip. -+ */ -+ if( archive_write_set_format( dz->archive, -+ ARCHIVE_FORMAT_ZIP ) != ARCHIVE_OK ) { -+ archive_write_free( dz->archive ); - return( -1 ); - } - -- /* Make the base directory inside the zip. All stuff goes into -- * this. -+ /* Remap compression=-1 to compression=6. - */ -- out2 = gsf_outfile_new_child_full( (GsfOutfile *) zip, -- dz->basename, TRUE, -- "compression-level", GSF_ZIP_STORED, -- NULL ); -- --#ifndef HAVE_GSF_DEFLATE_LEVEL -- if( dz->compression > 0 ) { -- g_warning( "%s", -- _( "deflate-level not supported by libgsf, " -- "using default compression" ) ); -- dz->compression = -1; -- } --#endif /*HAVE_GSF_DEFLATE_LEVEL*/ -+ if( dz->compression == -1 ) -+ dz->compression = 6; /* Z_DEFAULT_COMPRESSION */ - -- dz->tree = vips_gsf_tree_new( out2, dz->compression ); -+ /* Deflate compression requires libarchive >= v3.2.0. -+ * https://github.com/libarchive/libarchive/pull/84 -+ */ -+#if ARCHIVE_VERSION_NUMBER >= 3002000 -+ /* Set deflate compression level. -+ */ -+ char compression_string[2] = { '0' + dz->compression, 0 }; -+ if( archive_write_set_format_option( dz->archive, "zip", -+ "compression-level", compression_string ) != ARCHIVE_OK ) { -+ archive_write_free( dz->archive ); -+ return( -1 ); -+ } -+#else -+ if( dz->compression > 0 ) -+ g_warning( -+ "%s: libarchive >= v3.2.0 required for Deflate compression", -+ class->nickname ); -+#endif - -- /* Note the thing that will need closing up on exit. -+ /* Do not pad last block. - */ -- dz->tree->container = zip; --} -- break; -+ if( archive_write_set_bytes_in_last_block( dz->archive, 1 ) ) { -+ archive_write_free( dz->archive ); -+ return( -1 ); -+ } - -- default: -- g_assert_not_reached(); -+ /* Register target callback functions. -+ */ -+ if( archive_write_open( dz->archive, dz->target, NULL, -+ zip_write_target_cb, zip_close_target_cb ) != ARCHIVE_OK ) { -+ archive_write_free( dz->archive ); -+ return( -1 ); -+ } - } - - if( vips_sink_disc( save->ready, pyramid_strip, dz ) ) -@@ -2657,13 +2319,9 @@ vips_foreign_save_dz_build( VipsObject *object ) - - /* Shut down the output to flush everything. - */ -- if( vips_gsf_tree_close( dz->tree ) ) -- return( -1 ); -- dz->tree = NULL; -- -- /* unref out to force flush in gsf_output_target_close(). -- */ -- VIPS_UNREF( dz->out ); -+ if( iszip( dz->container ) && -+ archive_write_close( dz->archive ) ) -+ return( -1 ); - - return( 0 ); - } -@@ -2688,14 +2346,26 @@ static VipsBandFormat bandfmt_dz[10] = { - - static const char *dz_suffs[] = { ".dz", ".szi", NULL }; - -+static void * -+vips_foreign_save_dz_once_init( void *client ) -+{ -+ vips_libarchive_mutex = vips_g_mutex_new(); -+ -+ return( NULL ); -+} -+ - static void - vips_foreign_save_dz_class_init( VipsForeignSaveDzClass *class ) - { -+ static GOnce once = G_ONCE_INIT; -+ - GObjectClass *gobject_class = G_OBJECT_CLASS( class ); - VipsObjectClass *object_class = (VipsObjectClass *) class; - VipsForeignClass *foreign_class = (VipsForeignClass *) class; - VipsForeignSaveClass *save_class = (VipsForeignSaveClass *) class; - -+ VIPS_ONCE( &once, vips_foreign_save_dz_once_init, NULL ); -+ - gobject_class->dispose = vips_foreign_save_dz_dispose; - gobject_class->set_property = vips_object_set_property; - gobject_class->get_property = vips_object_get_property; -@@ -3035,7 +2705,7 @@ vips_foreign_save_dz_buffer_init( VipsForeignSaveDzBuffer *buffer ) - dz->container = VIPS_FOREIGN_DZ_CONTAINER_ZIP; - } - --#endif /*HAVE_GSF*/ -+#endif /*HAVE_LIBARCHIVE*/ - - /** - * vips_dzsave: (method) -diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c -index 1111111..2222222 100644 ---- a/libvips/foreign/foreign.c -+++ b/libvips/foreign/foreign.c -@@ -3053,11 +3053,11 @@ vips_foreign_operation_init( void ) - vips_foreign_save_cgif_target_get_type(); - #endif /*HAVE_CGIF*/ - --#ifdef HAVE_GSF -+#ifdef HAVE_LIBARCHIVE - vips_foreign_save_dz_file_get_type(); - vips_foreign_save_dz_buffer_get_type(); - vips_foreign_save_dz_target_get_type(); --#endif /*HAVE_GSF*/ -+#endif /*HAVE_LIBARCHIVE*/ - - #ifdef HAVE_PNG - vips_foreign_load_png_file_get_type(); -diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c -index 1111111..2222222 100644 ---- a/libvips/iofuncs/init.c -+++ b/libvips/iofuncs/init.c -@@ -94,16 +94,6 @@ - #include - #include - --/* Disable deprecation warnings from gsf. There are loads, and still not -- * patched as of 12/2020. -- */ --#ifdef HAVE_GSF --#pragma GCC diagnostic push --#pragma GCC diagnostic ignored "-Wdeprecated-declarations" --#include --#pragma GCC diagnostic pop --#endif /*HAVE_GSF*/ -- - #define VIPS_DISABLE_DEPRECATION_WARNINGS - #include - #include -@@ -639,12 +629,6 @@ vips_init( const char *argv0 ) - */ - vips_vector_init(); - --#ifdef HAVE_GSF -- /* Use this for structured file write. -- */ -- gsf_init(); --#endif /*HAVE_GSF*/ -- - #ifdef DEBUG_LEAK - vips__image_pixels_quark = - g_quark_from_static_string( "vips-image-pixels" ); -@@ -757,10 +741,6 @@ vips_shutdown( void ) - vips__thread_profile_stop(); - vips__threadpool_shutdown(); - --#ifdef HAVE_GSF -- gsf_shutdown(); --#endif /*HAVE_GSF*/ -- - /* Don't free vips__global_lock -- we want to be able to use - * vips_error_buffer() after vips_shutdown(), since vips_leak() can - * call it. -diff --git a/meson.build b/meson.build -index 1111111..2222222 100644 ---- a/meson.build -+++ b/meson.build -@@ -150,14 +150,10 @@ if zlib_dep.found() - cfg_var.set('HAVE_ZLIB', '1') - endif - --gsf_dep = dependency('libgsf-1', version: '>=1.14.26', required: get_option('gsf')) --if gsf_dep.found() -- libvips_deps += gsf_dep -- cfg_var.set('HAVE_GSF', '1') -- if gsf_dep.version().version_compare('>=1.14.31') -- cfg_var.set('HAVE_GSF_ZIP64', '1') -- cfg_var.set('HAVE_GSF_DEFLATE_LEVEL', '1') -- endif -+libarchive_dep = dependency('libarchive', version: '>=3.0.0', required: get_option('archive')) -+if libarchive_dep.found() -+ libvips_deps += libarchive_dep -+ cfg_var.set('HAVE_LIBARCHIVE', '1') - endif - - fftw_dep = dependency('fftw3', required: get_option('fftw')) -@@ -658,7 +654,7 @@ build_summary = { - 'PNG load/save with libpng': [png_dep.found()], - 'selected quantisation package': [quantisation_package.found() ? quantisation_package.name() : 'none'], - 'TIFF load/save with libtiff': [libtiff_dep.found()], -- 'image pyramid save with libgsf': [gsf_dep.found()], -+ 'image pyramid save with libarchive': [libarchive_dep.found()], - 'HEIC/AVIF load/save with libheif': [libheif_dep.found(), ' (dynamic module: ', libheif_module, ')'], - 'WebP load/save with libwebp': [libwebp_dep.found()], - 'PDF load with PDFium': [pdfium_dep.found()], -diff --git a/meson_options.txt b/meson_options.txt -index 1111111..2222222 100644 ---- a/meson_options.txt -+++ b/meson_options.txt -@@ -67,10 +67,10 @@ option('fontconfig', - value: 'auto', - description: 'Build with fontconfig') - --option('gsf', -+option('archive', - type: 'feature', - value: 'auto', -- description: 'Build with libgsf-1') -+ description: 'Build with libarchive') - - option('heif', - type: 'feature', diff --git a/build/variables.sh b/build/variables.sh index 37ad67e8..7d61e3d7 100755 --- a/build/variables.sh +++ b/build/variables.sh @@ -1,9 +1,9 @@ # included by all scripts vips_package=vips -vips_version=8.14 -vips_patch_version=5 -#vips_pre_version=rc1 +vips_version=8.15 +vips_patch_version=0 +vips_pre_version=rc1 if [ -n "$GIT_COMMIT" ]; then vips_version=$GIT_COMMIT diff --git a/build/vips-all.mk b/build/vips-all.mk index 91fb8238..697b36fd 100644 --- a/build/vips-all.mk +++ b/build/vips-all.mk @@ -2,15 +2,15 @@ PKG := vips-all $(PKG)_WEBSITE := https://libvips.github.io/libvips/ $(PKG)_DESCR := A fast image processing library with low memory needs. $(PKG)_IGNORE := -$(PKG)_VERSION := 8.14.5 -$(PKG)_CHECKSUM := 90374e9f6fbd5657b5faf306cacda20658d6144d385316b59b865bc1a487b68d +$(PKG)_VERSION := 8.15.0 +$(PKG)_CHECKSUM := af5f2aac8e73bd4dad08f4e0d6a505a4e8441aedad53d6263ab6bc5bd8fc5bb7 $(PKG)_PATCHES := $(realpath $(sort $(wildcard $(dir $(lastword $(MAKEFILE_LIST)))/patches/vips-[0-9]*.patch))) -$(PKG)_GH_CONF := libvips/libvips/releases,v,,,,.tar.xz +$(PKG)_GH_CONF := libvips/libvips/releases,v,-rc1,,,.tar.xz $(PKG)_SUBDIR := vips-$($(PKG)_VERSION) $(PKG)_FILE := vips-$($(PKG)_VERSION).tar.xz $(PKG)_DEPS := cc meson-wrapper libwebp librsvg glib pango libarchive \ libjpeg-turbo tiff lcms libexif libheif libpng \ - libspng libimagequant orc imagemagick matio openexr \ + libspng libimagequant highway imagemagick matio openexr \ cfitsio nifticlib poppler fftw openslide libjxl cgif define $(PKG)_PRE_CONFIGURE @@ -41,7 +41,7 @@ define $(PKG)_PRE_CONFIGURE $(if $(findstring graphicsmagick,$($(PKG)_DEPS)),printf ' "graphicsmagick": "$(graphicsmagick_VERSION)"$(comma)\n';) \ printf ' "harfbuzz": "$(harfbuzz_VERSION)",\n'; \ printf ' "heif": "$(libheif_VERSION)",\n'; \ - $(if $(IS_LLVM),printf ' "highway": "$(highway_VERSION)"$(comma)\n';) \ + printf ' "highway": "$(highway_VERSION)",\n'; \ $(if $(findstring imagemagick,$($(PKG)_DEPS)),printf ' "imagemagick": "$(imagemagick_VERSION)"$(comma)\n';) \ printf ' "imagequant": "$(libimagequant_VERSION)",\n'; \ $(if $(IS_MOZJPEG),,printf ' "jpeg": "$(libjpeg-turbo_VERSION)"$(comma)\n';) \ @@ -53,7 +53,6 @@ define $(PKG)_PRE_CONFIGURE printf ' "openexr": "$(openexr_VERSION)",\n'; \ printf ' "openjpeg": "$(openjpeg_VERSION)",\n'; \ printf ' "openslide": "$(openslide_VERSION)",\n'; \ - printf ' "orc": "$(orc_VERSION)",\n'; \ printf ' "pango": "$(pango_VERSION)",\n'; \ printf ' "pixman": "$(pixman_VERSION)",\n'; \ printf ' "png": "$(libpng_VERSION)",\n'; \ @@ -83,7 +82,7 @@ define $(PKG)_BUILD $(MXE_MESON_WRAPPER) \ -Ddeprecated=false \ -Dexamples=false \ - -Dintrospection=false \ + -Dintrospection=disabled \ -Dmodules=enabled \ -Dheif-module=$(if $(IS_HEVC),enabled,disabled) \ -Djpeg-xl=$(if $(IS_LLVM),enabled,disabled) \ diff --git a/build/vips-web.mk b/build/vips-web.mk index 52440776..13f82891 100644 --- a/build/vips-web.mk +++ b/build/vips-web.mk @@ -2,15 +2,15 @@ PKG := vips-web $(PKG)_WEBSITE := https://libvips.github.io/libvips/ $(PKG)_DESCR := A fast image processing library with low memory needs. $(PKG)_IGNORE := -$(PKG)_VERSION := 8.14.5 -$(PKG)_CHECKSUM := 90374e9f6fbd5657b5faf306cacda20658d6144d385316b59b865bc1a487b68d +$(PKG)_VERSION := 8.15.0 +$(PKG)_CHECKSUM := af5f2aac8e73bd4dad08f4e0d6a505a4e8441aedad53d6263ab6bc5bd8fc5bb7 $(PKG)_PATCHES := $(realpath $(sort $(wildcard $(dir $(lastword $(MAKEFILE_LIST)))/patches/vips-[0-9]*.patch))) -$(PKG)_GH_CONF := libvips/libvips/releases,v,,,,.tar.xz +$(PKG)_GH_CONF := libvips/libvips/releases,v,-rc1,,,.tar.xz $(PKG)_SUBDIR := vips-$($(PKG)_VERSION) $(PKG)_FILE := vips-$($(PKG)_VERSION).tar.xz $(PKG)_DEPS := cc meson-wrapper libwebp librsvg glib pango libarchive \ libjpeg-turbo tiff lcms libexif libheif libpng \ - libspng libimagequant orc cgif + libspng libimagequant highway cgif define $(PKG)_PRE_CONFIGURE # Copy some files to the packaging directory @@ -34,11 +34,11 @@ define $(PKG)_PRE_CONFIGURE printf ' "glib": "$(glib_VERSION)",\n'; \ printf ' "harfbuzz": "$(harfbuzz_VERSION)",\n'; \ printf ' "heif": "$(libheif_VERSION)",\n'; \ + printf ' "highway": "$(highway_VERSION)",\n'; \ printf ' "imagequant": "$(libimagequant_VERSION)",\n'; \ $(if $(IS_MOZJPEG),,printf ' "jpeg": "$(libjpeg-turbo_VERSION)"$(comma)\n';) \ printf ' "lcms": "$(lcms_VERSION)",\n'; \ $(if $(IS_MOZJPEG),printf ' "mozjpeg": "$(mozjpeg_VERSION)"$(comma)\n';) \ - printf ' "orc": "$(orc_VERSION)",\n'; \ printf ' "pango": "$(pango_VERSION)",\n'; \ printf ' "pixman": "$(pixman_VERSION)",\n'; \ printf ' "png": "$(libpng_VERSION)",\n'; \ @@ -68,7 +68,7 @@ define $(PKG)_BUILD --default-library=shared \ -Ddeprecated=false \ -Dexamples=false \ - -Dintrospection=false \ + -Dintrospection=disabled \ -Dmodules=disabled \ -Dcfitsio=disabled \ -Dfftw=disabled \