Merge branch 'master' into add-libnsgif

This commit is contained in:
John Cupitt 2021-03-07 14:37:14 +00:00
commit f74d6c795d
30 changed files with 641 additions and 608 deletions

View File

@ -24,12 +24,15 @@
22/12/20 start 8.10.6
- don't seek on bad file descriptors [kleisauke]
- check for null memory sources [kleisauke]
- revise ppmload, fixing a couple of small bugs
- signal error on EOF in jpegload more reliably [bozaro]
- better error detection in spngload [randy408]
- improve ppmload, fixing a couple of small bugs
- improve EOF detection in jpegload [bozaro]
- improve error detection in spngload [randy408]
- fix includes of glib headers in C++ [lovell]
- fix build with more modern librsvg [lovell]
- fix a possible segv with very wide images [f1ac]
- fix issue thumbnailing RGBA images in linear mode [jjonesrs]
- improve vipsthumbnail profile handling
- fix tiff deflate predictor setting [Adios]
18/12/20 started 8.10.5
- fix potential /0 in animated webp load [lovell]

View File

@ -26,7 +26,12 @@ VIPS_MAJOR_VERSION=vips_major_version()
VIPS_MINOR_VERSION=vips_minor_version()
VIPS_MICRO_VERSION=vips_micro_version()
VIPS_VERSION=vips_version()
VIPS_VERSION_STRING=$VIPS_VERSION-`date -u -r $srcdir/ChangeLog`
VIPS_VERSION_STRING="$VIPS_VERSION-$(date -u -r $srcdir/ChangeLog)"
# packages add to these as we find them
VIPS_CFLAGS=""
VIPS_INCLUDES=""
VIPS_LIBS=""
# libtool library versioning ... not user-visible (except as part of the
# library file name) and does not correspond to major/minor/micro above
@ -74,31 +79,31 @@ done
# add headers that form the public vips8 API .. don't do a find and exclude,
# we end up excluding almost everything argh
headers="\
basic.h \
vips.h \
object.h \
image.h \
error.h \
foreign.h \
freqfilt.h \
interpolate.h \
header.h \
histogram.h \
operation.h \
enumtypes.h \
conversion.h \
arithmetic.h \
colour.h \
convolution.h \
create.h \
draw.h \
morphology.h \
mosaicing.h \
type.h \
rect.h \
resample.h \
memory.h \
region.h"
basic.h \
vips.h \
object.h \
image.h \
error.h \
foreign.h \
freqfilt.h \
interpolate.h \
header.h \
histogram.h \
operation.h \
enumtypes.h \
conversion.h \
arithmetic.h \
colour.h \
convolution.h \
create.h \
draw.h \
morphology.h \
mosaicing.h \
type.h \
rect.h \
resample.h \
memory.h \
region.h"
for name in $headers; do
vips_introspection_sources="$vips_introspection_sources include/vips/$name"
@ -141,69 +146,35 @@ AM_CONDITIONAL(ENABLE_DEPRECATED, [test x"$enable_deprecated" = x"yes"])
# this gets pasted into version.h as a #define
AC_SUBST(VIPS_ENABLE_DEPRECATED)
AC_MSG_CHECKING([for native Win32])
case "$host" in
*-*-mingw*)
vips_os_win32=yes
;;
*)
vips_os_win32=no
;;
esac
AC_MSG_RESULT([$vips_os_win32])
if test x"$vips_os_win32" = x"yes"; then
AC_DEFINE(OS_WIN32,1,[native win32])
# makes gcc use win native alignment
VIPS_CFLAGS="-mms-bitfields $VIPS_CFLAGS"
fi
# CImg needs flags changed on win32
AM_CONDITIONAL(OS_WIN32, [test x"$vips_os_win32" = x"yes"])
# Cygwin/mingw need binary open to avoid CR/LF madness
# ... should be a better way to test for this
AC_MSG_CHECKING([for binary open needed])
AC_MSG_CHECKING([for -mms-bitfields support])
case "$host_os" in
cygwin* | mingw*)
vips_binary_open=yes
mingw*)
# makes gcc use win native alignment
# GCC >= 4.7 and Clang >= 11 does this automatically, see:
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1510#note_841637
VIPS_CFLAGS="-mms-bitfields $VIPS_CFLAGS"
AC_MSG_RESULT([yes])
;;
*)
vips_binary_open=no
AC_MSG_RESULT([no])
;;
esac
AC_MSG_RESULT([$vips_binary_open])
if test x"$vips_binary_open" = x"yes"; then
AC_DEFINE(BINARY_OPEN,1,[define to open non-text files in binary mode])
fi
AC_MSG_CHECKING([for Mac OS X])
case "$host" in
*-*-darwin*)
vips_os_darwin=yes
;;
*)
vips_os_darwin=no
;;
esac
AC_MSG_RESULT([$vips_os_darwin])
if test x"$vips_os_darwin" = x"yes"; then
AC_DEFINE(VIPS_OS_DARWIN,1,[native Mac OS X])
fi
# set the default directory for ICC profiles
if test x"$vips_os_darwin" = x"yes"; then
profile_dir="/Library/ColorSync/Profiles"
elif test x"$vips_os_win32" = x"yes"; then
# need double escapes since this will get pasted into a #define in a C
# header ... the C:\Windows is usually overrwritten with the result of
# GetWindowsDirectoryW()
profile_dir="C:\\\\Windows\\\\System32\\\\spool\\\\drivers\\\\color"
else
profile_dir="/usr/share/color/icc"
fi
case "$host_os" in
darwin*)
profile_dir="/Library/ColorSync/Profiles"
;;
mingw*)
# need double escapes since this will get pasted into a #define in a C
# header ... the C:\Windows is usually overwritten with the result of
# GetWindowsDirectoryW()
profile_dir="C:\\\\Windows\\\\System32\\\\spool\\\\drivers\\\\color"
;;
*)
profile_dir="/usr/share/color/icc"
;;
esac
AC_DEFINE_UNQUOTED(VIPS_ICC_DIR,"$profile_dir",[default directory for ICC profiles])
# we want largefile support, if possible
@ -435,20 +406,23 @@ PACKAGES_USED="$PACKAGES_USED glib-2.0 gmodule-2.0 gobject-2.0 gio-2.0"
# from 2.62 we have datetime
PKG_CHECK_MODULES(DATE_TIME_FORMAT_ISO8601, glib-2.0 >= 2.62,
[AC_DEFINE(HAVE_DATE_TIME_FORMAT_ISO8601,1,
[define if your glib has g_date_time_format_iso8601().]
[define if your glib has g_date_time_format_iso8601().]
)
],
[:
]
)
VIPS_CFLAGS="$VIPS_CFLAGS $GIO_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $GIO_LIBS"
# if available, we use pthread_setattr_default_np() to raise the per-thread
# stack size ... musl (libc on Alpine), for example, has a very small stack per
# thread by default
save_pthread_LIBS="$LIBS"
save_pthread_CFLAGS="$CFLAGS"
LIBS="$LIBS $GTHREAD_LIBS"
CFLAGS="$CFLAGS $GTHREAD_CFLAGS"
LIBS="$LIBS $REQUIRED_LIBS"
CFLAGS="$CFLAGS $REQUIRED_CFLAGS"
AC_CHECK_FUNC(pthread_setattr_default_np,
[AC_DEFINE(HAVE_PTHREAD_DEFAULT_NP,1,[have pthread_setattr_default_np().])
]
@ -456,11 +430,6 @@ AC_CHECK_FUNC(pthread_setattr_default_np,
LIBS="$save_pthread_LIBS"
CFLAGS="$save_pthread_CFLAGS"
if test x"$vips_os_win32" = x"yes"; then
AC_DEFINE(HAVE_G_WIN32_GET_COMMAND_LINE,1,[define if your glib has g_win32_get_command_line().])
have_g_win32_get_command_line=yes
fi
# from 2.48 we have g_uint_checked_mul() etc.
PKG_CHECK_MODULES(HAVE_CHECKED_MUL, glib-2.0 >= 2.48,
[AC_DEFINE(HAVE_CHECKED_MUL,1,[define if your glib has checked multiply.])
@ -486,6 +455,9 @@ if test x"$expat_found" = x"no"; then
exit 1
fi
VIPS_CFLAGS="$VIPS_CFLAGS $EXPAT_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $EXPAT_LIBS"
# optional supporting libraries
AC_ARG_WITH([gsf],
@ -510,13 +482,16 @@ if test x"$with_gsf" != x"no"; then
PKG_CHECK_MODULES(GSF_ZIP64, libgsf-1 >= 1.14.31,
[AC_DEFINE(HAVE_GSF_ZIP64,1,[define if your libgsf supports zip64.])
AC_DEFINE(HAVE_GSF_DEFLATE_LEVEL,1,
[define if your libgsf supports deflate-level.])
[define if your libgsf supports deflate-level.])
],
[:
]
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $GSF_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $GSF_LIBS"
AC_ARG_WITH([fftw],
AS_HELP_STRING([--without-fftw], [build without fftw (default: test)]))
@ -532,6 +507,9 @@ if test x"$with_fftw" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $FFTW_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $FFTW_LIBS"
# ImageMagick
AC_ARG_WITH([magick],
AS_HELP_STRING([--without-magick], [build without libMagic (default: test)]))
@ -595,7 +573,7 @@ if test x"$magick6" = x"yes"; then
CFLAGS="$CFLAGS $MAGICK_CFLAGS"
AC_CHECK_MEMBER([struct _ImageInfo.number_scenes],
AC_DEFINE(HAVE_NUMBER_SCENES,1,
[define if your magick has ImageInfo.number_scenes.]),
[define if your magick has ImageInfo.number_scenes.]),
[],
[#include <magick/api.h>])
CFLAGS="$save_CFLAGS"
@ -653,11 +631,11 @@ fi
# save but not load, for example
AC_ARG_ENABLE([magickload],
AS_HELP_STRING([--disable-magickload],
[disable libMagic load (default: enabled)]))
[disable libMagic load (default: enabled)]))
AC_ARG_ENABLE([magicksave],
AS_HELP_STRING([--disable-magicksave],
[disable libMagic save (default: enabled)]))
[disable libMagic save (default: enabled)]))
if test x"$enable_magicksave" != x"yes"; then
# we need ImportImagePixels ... GM is missing this sadly
@ -665,12 +643,12 @@ if test x"$enable_magicksave" != x"yes"; then
LIBS="$LIBS $MAGICK_LIBS"
AC_CHECK_FUNCS(ImportImagePixels,[
AC_DEFINE(HAVE_IMPORTIMAGEPIXELS,1,
[define if you have ImportImagePixels.])
[define if you have ImportImagePixels.])
],[]
)
AC_CHECK_FUNCS(ImagesToBlob,[
AC_DEFINE(HAVE_IMAGESTOBLOB,1,
[define if you have ImagesToBlob.])
[define if you have ImagesToBlob.])
],[]
)
LIBS="$save_LIBS"
@ -691,6 +669,9 @@ else
enable_magicksave=no
fi
VIPS_CFLAGS="$VIPS_CFLAGS $MAGICK_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $MAGICK_LIBS"
# orc
AC_ARG_WITH([orc],
AS_HELP_STRING([--without-orc], [build without orc (default: test)]))
@ -705,7 +686,7 @@ if test x"$with_orc" != x"no"; then
LIBS="$LIBS $ORC_LIBS"
AC_CHECK_FUNCS(orc_program_get_error,
AC_DEFINE(HAVE_ORC_PROGRAM_GET_ERROR,1,
[define if your orc has orc_program_get_error.]))
[define if your orc has orc_program_get_error.]))
LIBS="$save_LIBS"
],
[AC_MSG_WARN([orc-0.4.11 or later not found; disabling orc support])
@ -719,7 +700,7 @@ fi
if test x"$with_orc" = x"yes"; then
PKG_CHECK_MODULES(ORC_CF_PROTECTION, orc-0.4 >= 0.4.31,
[AC_DEFINE(HAVE_ORC_CF_PROTECTION,1,
[define if your orc works with cf-protection.]
[define if your orc works with cf-protection.]
)
],
[:
@ -727,6 +708,9 @@ if test x"$with_orc" = x"yes"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $ORC_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $ORC_LIBS"
# lcms ... refuse to use lcms1
AC_ARG_WITH([lcms],
AS_HELP_STRING([--without-lcms], [build without lcms (default: test)]))
@ -747,6 +731,9 @@ fi
# is detected
AM_CONDITIONAL(ENABLE_LCMS, [test x"$with_lcms" != x"no"])
VIPS_CFLAGS="$VIPS_CFLAGS $LCMS_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $LCMS_LIBS"
# OpenEXR
AC_ARG_WITH([OpenEXR],
AS_HELP_STRING([--without-OpenEXR], [build without OpenEXR (default: test)]))
@ -764,6 +751,9 @@ if test x"$with_OpenEXR" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $OPENEXR_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $OPENEXR_LIBS"
# nifti
AC_ARG_WITH([nifti],
AS_HELP_STRING([--without-nifti], [build without nifti (default: test)]))
@ -777,6 +767,10 @@ if test x"$with_nifti" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $NIFTI_CFLAGS"
VIPS_INCLUDES="$VIPS_INCLUDES $NIFTI_INCLUDES"
VIPS_LIBS="$VIPS_LIBS $NIFTI_LIBS"
# libheif
AC_ARG_WITH([heif],
AS_HELP_STRING([--without-heif], [build without libheif (default: test)]))
@ -790,13 +784,13 @@ if test x"$with_heif" != x"no"; then
# this variable
if test x"$have_h265_decoder" != x"no" -o x"$have_avif_decoder" = x"yes"; then
AC_DEFINE(HAVE_HEIF_DECODER,1,
[define if your libheif has decode support.])
[define if your libheif has decode support.])
fi
have_h265_encoder=`$PKG_CONFIG libheif --variable builtin_h265_encoder`
have_avif_encoder=`$PKG_CONFIG libheif --variable builtin_avif_encoder`
if test x"$have_h265_encoder" != x"no" -o x"$have_avif_encoder" = x"yes"; then
AC_DEFINE(HAVE_HEIF_ENCODER,1,
[define if your libheif has encode support.])
[define if your libheif has encode support.])
fi
PACKAGES_USED="$PACKAGES_USED libheif"
],
@ -817,7 +811,7 @@ if test x"$with_heif" = x"yes"; then
LIBS="$LIBS $HEIF_LIBS"
AC_CHECK_FUNCS(heif_image_handle_get_raw_color_profile,[
AC_DEFINE(HAVE_HEIF_COLOR_PROFILE,1,
[define if you have heif_image_handle_get_raw_color_profile.])
[define if you have heif_image_handle_get_raw_color_profile.])
],[]
)
LIBS="$save_LIBS"
@ -838,12 +832,15 @@ if test x"$with_heif" = x"yes"; then
CFLAGS="$CFLAGS $HEIF_CFLAGS"
AC_CHECK_MEMBER([struct heif_decoding_options.convert_hdr_to_8bit],[
AC_DEFINE(HAVE_HEIF_DECODING_OPTIONS_CONVERT_HDR_TO_8BIT,1,
[define if you have heif_decoding_options.convert_hdr_to_8bit])
[define if you have heif_decoding_options.convert_hdr_to_8bit])
],[],
[#include <libheif/heif.h>])
CFLAGS="$save_CFLAGS"
fi
VIPS_CFLAGS="$VIPS_CFLAGS $HEIF_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $HEIF_LIBS"
# pdfium
AC_ARG_WITH([pdfium],
AS_HELP_STRING([--without-pdfium], [build without pdfium (default: test)]))
@ -864,6 +861,9 @@ if test x"$with_pdfium" != x"no"; then
])
fi
VIPS_CFLAGS="$VIPS_CFLAGS $PDFIUM_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $PDFIUM_LIBS"
# poppler
AC_ARG_WITH([poppler],
AS_HELP_STRING([--without-poppler], [build without poppler (default: test)]))
@ -879,6 +879,9 @@ if test x"$with_poppler" != x"no"; then
])
fi
VIPS_CFLAGS="$VIPS_CFLAGS $POPPLER_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $POPPLER_LIBS"
# librsvg
AC_ARG_WITH([rsvg],
AS_HELP_STRING([--without-rsvg], [build without rsvg (default: test)]))
@ -895,6 +898,9 @@ if test x"$with_rsvg" != x"no"; then
])
fi
VIPS_CFLAGS="$VIPS_CFLAGS $RSVG_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $RSVG_LIBS"
# zlib
# some platforms, like macosx, are missing the .pc files for zlib, so
# we fall back to FIND_ZLIB
@ -918,6 +924,10 @@ if test x"$with_zlib" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $ZLIB_CFLAGS"
VIPS_INCLUDES="$VIPS_INCLUDES $ZLIB_INCLUDES"
VIPS_LIBS="$VIPS_LIBS $ZLIB_LIBS"
# OpenSlide
AC_ARG_WITH([openslide],
AS_HELP_STRING([--without-openslide],
@ -945,6 +955,9 @@ if test x"$with_openslide" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $OPENSLIDE_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $OPENSLIDE_LIBS"
# matio
AC_ARG_WITH([matio],
AS_HELP_STRING([--without-matio], [build without matio (default: test)]))
@ -961,6 +974,9 @@ if test x"$with_matio" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $MATIO_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $MATIO_LIBS"
# not external libraries, but have options to disable them, helps to
# reduce attack surface
@ -1014,6 +1030,9 @@ if test x"$with_cfitsio" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $CFITSIO_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $CFITSIO_LIBS"
# libwebp ... target 0.6+ to reduce complication
# webp has the stuff for handling metadata in two separate libraries -- we
# insit on having all of them
@ -1032,6 +1051,9 @@ if test x"$with_libwebp" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $LIBWEBP_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $LIBWEBP_LIBS"
# pangoft2
AC_ARG_WITH([pangoft2],
AS_HELP_STRING([--without-pangoft2],
@ -1049,6 +1071,9 @@ if test x"$with_pangoft2" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $PANGOFT2_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $PANGOFT2_LIBS"
# look for TIFF with pkg-config ... fall back to our tester
# pkgconfig support for libtiff starts with libtiff-4
AC_ARG_WITH([tiff],
@ -1070,7 +1095,7 @@ if test x"$with_tiff" != x"no"; then
)
fi
# WEBP in TIFF added in libtiff 4.0.10
# ZSTD and WEBP in TIFF added in libtiff 4.0.10
if test x"$with_tiff" != x"no"; then
save_INCLUDES="$INCLUDES"
INCLUDES="$INCLUDES $TIFF_INCLUDES"
@ -1084,6 +1109,10 @@ if test x"$with_tiff" != x"no"; then
INCLUDES="$save_INCLUDES"
fi
VIPS_CFLAGS="$VIPS_CFLAGS $TIFF_CFLAGS"
VIPS_INCLUDES="$VIPS_INCLUDES $TIFF_INCLUDES"
VIPS_LIBS="$VIPS_LIBS $TIFF_LIBS"
# Look for libspng first
# 0.6.1 uses "libspng.pc", git master libspng uses "spng.pc"
AC_ARG_WITH([libspng],
@ -1107,6 +1136,9 @@ if test x"$with_libspng" != x"no"; then
)
fi
VIPS_CFLAGS="$VIPS_CFLAGS $SPNG_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $SPNG_LIBS"
# look for PNG with pkg-config ... fall back to our tester
# we can have both PNG and SPNG enabled, with SPNG for read and PNG for
# write
@ -1137,11 +1169,15 @@ if test x"$with_png" != x"no"; then
CFLAGS="$PNG_INCLUDES $CFLAGS"
AC_CHECK_FUNCS(png_set_chunk_malloc_max,
AC_DEFINE(HAVE_PNG_SET_CHUNK_MALLOC_MAX,1,
[define if your libpng has png_set_chunk_malloc_max.]))
[define if your libpng has png_set_chunk_malloc_max.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
VIPS_CFLAGS="$VIPS_CFLAGS $PNG_CFLAGS"
VIPS_INCLUDES="$VIPS_INCLUDES $PNG_INCLUDES"
VIPS_LIBS="$VIPS_LIBS $PNG_LIBS"
# look for libimagequant with pkg-config (only if libpng is enabled)
AC_ARG_WITH([imagequant],
AS_HELP_STRING([--without-imagequant], [build without imagequant (default: test)]))
@ -1160,6 +1196,9 @@ else
with_imagequant=no
fi
VIPS_CFLAGS="$VIPS_CFLAGS $IMAGEQUANT_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $IMAGEQUANT_LIBS"
# look for libjpeg with pkg-config ... fall back to our tester
AC_ARG_WITH([jpeg],
AS_HELP_STRING([--without-jpeg], [build without libjpeg (default: test)]))
@ -1192,11 +1231,15 @@ if test x"$with_jpeg" != x"no"; then
CFLAGS="$JPEG_INCLUDES $CFLAGS"
AC_CHECK_FUNCS(jpeg_c_bool_param_supported,
AC_DEFINE(HAVE_JPEG_EXT_PARAMS,1,
[define if your libjpeg has extension parameters.]))
[define if your libjpeg has extension parameters.]))
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
VIPS_CFLAGS="$VIPS_CFLAGS $JPEG_CFLAGS"
VIPS_INCLUDES="$VIPS_INCLUDES $JPEG_INCLUDES"
VIPS_LIBS="$VIPS_LIBS $JPEG_LIBS"
# libexif
AC_ARG_WITH([libexif],
AS_HELP_STRING([--without-libexif], [build without libexif (default: test)]))
@ -1224,6 +1267,9 @@ if test x"$with_libexif" != x"no"; then
CPPFLAGS="$save_CPPFLAGS"
fi
VIPS_CFLAGS="$VIPS_CFLAGS $EXIF_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $EXIF_LIBS"
# fuzzing
AC_ARG_VAR([LIB_FUZZING_ENGINE],
[fuzzing library, e.g. /path/to/libFuzzer.a])
@ -1231,71 +1277,47 @@ if test x"$LIB_FUZZING_ENGINE" = x; then
LIB_FUZZING_ENGINE="libstandaloneengine.a"
fi
# Gather all up for VIPS_CFLAGS, VIPS_INCLUDES, VIPS_LIBS
VIPS_CFLAGS="$VIPS_CFLAGS \
$GTHREAD_CFLAGS \
$GIO_CFLAGS \
$REQUIRED_CFLAGS \
$EXPAT_CFLAGS \
$ZLIB_CFLAGS \
$PANGOFT2_CFLAGS \
$GSF_CFLAGS \
$FFTW_CFLAGS \
$MAGICK_CFLAGS \
$JPEG_CFLAGS \
$SPNG_CFLAGS \
$PNG_CFLAGS \
$IMAGEQUANT_CFLAGS \
$EXIF_CFLAGS \
$MATIO_CFLAGS \
$CFITSIO_CFLAGS \
$LIBWEBP_CFLAGS \
$LIBWEBPMUX_CFLAGS \
$RSVG_CFLAGS \
$PDFIUM_CFLAGS \
$POPPLER_CFLAGS \
$OPENEXR_CFLAGS \
$OPENSLIDE_CFLAGS \
$ORC_CFLAGS \
$TIFF_CFLAGS \
$LCMS_CFLAGS \
$HEIF_CFLAGS"
VIPS_CFLAGS="$VIPS_DEBUG_FLAGS $VIPS_CFLAGS"
VIPS_INCLUDES="$ZLIB_INCLUDES $PNG_INCLUDES $TIFF_INCLUDES $JPEG_INCLUDES $NIFTI_INCLUDES"
VIPS_LIBS="$ZLIB_LIBS \
$HEIF_LIBS \
$MAGICK_LIBS \
$SPNG_LIBS \
$PNG_LIBS \
$IMAGEQUANT_LIBS \
$TIFF_LIBS \
$JPEG_LIBS \
$GTHREAD_LIBS \
$GIO_LIBS \
$REQUIRED_LIBS \
$EXPAT_LIBS \
$PANGOFT2_LIBS \
$GSF_LIBS \
$FFTW_LIBS \
$ORC_LIBS \
$LCMS_LIBS \
$RSVG_LIBS \
$NIFTI_LIBS \
$PDFIUM_LIBS \
$POPPLER_LIBS \
$OPENEXR_LIBS \
$OPENSLIDE_LIBS \
$CFITSIO_LIBS \
$LIBWEBP_LIBS \
$LIBWEBPMUX_LIBS \
$MATIO_LIBS \
$EXIF_LIBS \
-lm"
VIPS_CFLAGS="$VIPS_CFLAGS $VIPS_DEBUG_FLAGS $REQUIRED_CFLAGS"
VIPS_LIBS="$VIPS_LIBS $REQUIRED_LIBS -lm"
# autoconf hates multi-line AC_SUBST so we have to have another copy of this
# thing
VIPS_CONFIG="native win32: $vips_os_win32, native OS X: $vips_os_darwin, open files in binary mode: $vips_binary_open, enable debug: $enable_debug, enable deprecated library components: $enable_deprecated, enable docs with gtkdoc: $enable_gtk_doc, gobject introspection: $found_introspection, enable radiance support: $with_radiance, enable analyze support: $with_analyze, enable PPM load/save: $with_ppm, enable GIF load: $with_nsgif, generate C++ docs: $with_doxygen, use fftw3 for FFT: $with_fftw, Magick package: $with_magickpackage, Magick API version: $magick_version, load with libMagick: $enable_magickload, save with libMagick: $enable_magicksave, accelerate loops with orc: $with_orc, ICC profile support with lcms: $with_lcms, NIfTI load/save with niftiio: $with_nifti, HEIC/AVIF load/save with libheif: $with_heif, EXR load/save with OpenEXR: $with_OpenEXR, slide load with OpenSlide: $with_openslide, Matlab load with matio: $with_matio, PDF load with PDFium: $with_pdfium, PDF load with poppler-glib: $with_poppler, SVG load with librsvg-2.0: $with_rsvg, zlib: $with_zlib, FITS load with cfitsio: $with_cfitsio, WebP load/save with libwebp: $with_libwebp, text rendering with pangoft2: $with_pangoft2, PNG load with libspng: $with_libspng, PNG load/save with libpng: $with_png, support 8bpp PNG quantisation: $with_imagequant, TIFF load/save with libtiff: $with_tiff, JPEG load/save with libjpeg: $with_jpeg, image pyramid export: $with_gsf, use libexif to load/save JPEG metadata: $with_libexif"
VIPS_CONFIG="\
enable debug: $enable_debug, \
enable deprecated library components: $enable_deprecated, \
enable docs with gtkdoc: $enable_gtk_doc, \
gobject introspection: $found_introspection, \
RAD load/save: $with_radiance, \
Analyze7 load/save: $with_analyze, \
PPM load/save: $with_ppm, \
GIF load: $with_nsgif, \
generate C++ docs: $with_doxygen, \
use fftw3 for FFT: $with_fftw, \
accelerate loops with orc: $with_orc, \
ICC profile support with lcms: $with_lcms, \
zlib: $with_zlib, \
text rendering with pangoft2: $with_pangoft2, \
EXIF metadata support with libexif: $with_libexif, \
JPEG load/save with libjpeg: $with_jpeg, \
PNG load with libspng: $with_libspng, \
PNG load/save with libpng: $with_png, \
8bpp PNG quantisation: $with_imagequant, \
TIFF load/save with libtiff: $with_tiff, \
image pyramid save: $with_gsf, \
HEIC/AVIF load/save with libheif: $with_heif, \
WebP load/save with libwebp: $with_libwebp, \
PDF load with PDFium: $with_pdfium, \
PDF load with poppler-glib: $with_poppler, \
SVG load with librsvg-2.0: $with_rsvg, \
EXR load with OpenEXR: $with_OpenEXR, \
slide load with OpenSlide: $with_openslide, \
Matlab load with matio: $with_matio, \
NIfTI load/save with niftiio: $with_nifti, \
FITS load/save with cfitsio: $with_cfitsio, \
Magick package: $with_magickpackage, \
Magick API version: $magick_version, \
load with libMagickCore: $enable_magickload, \
save with libMagickCore: $enable_magicksave"
AC_SUBST(VIPS_LIBDIR)
@ -1312,109 +1334,99 @@ TOP_SRCDIR=$ac_pwd
AC_SUBST(TOP_SRCDIR)
AC_CONFIG_FILES([
vips.pc
vips-cpp.pc
Makefile
$srcdir/libvips/include/vips/version.h
libvips/include/Makefile
libvips/include/vips/Makefile
libvips/Makefile
libvips/arithmetic/Makefile
libvips/colour/Makefile
libvips/colour/profiles/Makefile
libvips/conversion/Makefile
libvips/convolution/Makefile
libvips/deprecated/Makefile
libvips/foreign/Makefile
libvips/foreign/libnsgif/Makefile
libvips/freqfilt/Makefile
libvips/histogram/Makefile
libvips/draw/Makefile
libvips/iofuncs/Makefile
libvips/morphology/Makefile
libvips/mosaicing/Makefile
libvips/create/Makefile
libvips/resample/Makefile
cplusplus/Doxyfile
cplusplus/include/Makefile
cplusplus/include/vips/Makefile
cplusplus/Makefile
tools/Makefile
tools/batch_crop
tools/batch_image_convert
tools/batch_rubber_sheet
tools/light_correct
tools/shrink_width
test/Makefile
test/variables.sh
test/test-suite/Makefile
test/test-suite/helpers/Makefile
man/Makefile
doc/Makefile
doc/libvips-docs.xml
po/Makefile.in
fuzz/Makefile
vips.pc
vips-cpp.pc
Makefile
$srcdir/libvips/include/vips/version.h
libvips/include/Makefile
libvips/include/vips/Makefile
libvips/Makefile
libvips/arithmetic/Makefile
libvips/colour/Makefile
libvips/colour/profiles/Makefile
libvips/conversion/Makefile
libvips/convolution/Makefile
libvips/deprecated/Makefile
libvips/foreign/Makefile
libvips/freqfilt/Makefile
libvips/histogram/Makefile
libvips/draw/Makefile
libvips/iofuncs/Makefile
libvips/morphology/Makefile
libvips/mosaicing/Makefile
libvips/create/Makefile
libvips/resample/Makefile
cplusplus/Doxyfile
cplusplus/include/Makefile
cplusplus/include/vips/Makefile
cplusplus/Makefile
tools/Makefile
tools/batch_crop
tools/batch_image_convert
tools/batch_rubber_sheet
tools/light_correct
tools/shrink_width
test/Makefile
test/variables.sh
test/test-suite/Makefile
test/test-suite/helpers/Makefile
man/Makefile
doc/Makefile
doc/libvips-docs.xml
po/Makefile.in
fuzz/Makefile
])
AC_OUTPUT
# also add any new items to VIPS_CONFIG above
AC_MSG_RESULT([dnl
* build options
native win32: $vips_os_win32
native OS X: $vips_os_darwin
open files in binary mode: $vips_binary_open
enable debug: $enable_debug
enable deprecated library components: $enable_deprecated
enable docs with gtkdoc: $enable_gtk_doc
gobject introspection: $found_introspection
enable radiance load/save: $with_radiance
enable analyze load/save: $with_analyze
enable PPM load/save: $with_ppm
enable GIF load: $with_nsgif
## Build options
enable debug: $enable_debug
enable deprecated library components: $enable_deprecated
enable docs with gtkdoc: $enable_gtk_doc
gobject introspection: $found_introspection
RAD load/save: $with_radiance
Analyze7 load/save: $with_analyze
PPM load/save: $with_ppm
GIF load: $with_nsgif
generate C++ docs: $with_doxygen
* optional dependencies
use fftw3 for FFT: $with_fftw
Magick package: $with_magickpackage
Magick API version: $magick_version
load with libMagick: $enable_magickload
save with libMagick: $enable_magicksave
accelerate loops with orc: $with_orc
(requires orc-0.4.11 or later)
ICC profile support with lcms: $with_lcms
NIfTI load/save with niftiio: $with_nifti
HEIC/AVIF load/save with libheif: $with_heif
EXR load/save with OpenEXR: $with_OpenEXR
slide load with OpenSlide: $with_openslide
(requires openslide-3.3.0 or later)
Matlab load with matio: $with_matio
PDF load with PDFium: $with_pdfium
PDF load with poppler-glib: $with_poppler
(requires poppler-glib 0.16.0 or later)
SVG load with librsvg-2.0: $with_rsvg
(requires librsvg-2.0 2.34.0 or later)
zlib: $with_zlib
FITS load/save with cfitsio: $with_cfitsio
WebP load/save with libwebp: $with_libwebp
(requires libwebp, libwebpmux, libwebpdemux 0.6.0 or later)
text rendering with pangoft2: $with_pangoft2
PNG load with libspng: $with_libspng
(requires libspng-0.6 or later)
PNG load/save with libpng: $with_png
(requires libpng-1.2.9 or later)
support 8bpp PNG quantisation: $with_imagequant
(requires libimagequant)
TIFF load/save with libtiff: $with_tiff
JPEG load/save with libjpeg: $with_jpeg
image pyramid export: $with_gsf
(requires libgsf-1 1.14.26 or later)
use libexif to load/save JPEG metadata: $with_libexif
])
## Optional dependencies
use fftw3 for FFT: $with_fftw
accelerate loops with orc: $with_orc
(requires orc-0.4.11 or later)
ICC profile support with lcms: $with_lcms
zlib: $with_zlib
text rendering with pangoft2: $with_pangoft2
EXIF metadata support with libexif: $with_libexif
if test x"$vips_os_win32" = x"yes"; then
if test x"$have_g_win32_get_command_line" != x"yes"; then
AC_MSG_RESULT([dnl
Your glib is too old, vips will not support unicode command-line arguments.
])
fi
fi
## File format support
JPEG load/save with libjpeg: $with_jpeg
PNG load with libspng: $with_libspng
(requires libspng-0.6 or later)
PNG load/save with libpng: $with_png
(requires libpng-1.2.9 or later)
8bpp PNG quantisation: $with_imagequant
(requires libimagequant)
TIFF load/save with libtiff: $with_tiff
image pyramid save: $with_gsf
(requires libgsf-1 1.14.26 or later)
HEIC/AVIF load/save with libheif: $with_heif
WebP load/save with libwebp: $with_libwebp
(requires libwebp, libwebpmux, libwebpdemux 0.6.0 or later)
PDF load with PDFium: $with_pdfium
PDF load with poppler-glib: $with_poppler
(requires poppler-glib 0.16.0 or later)
SVG load with librsvg-2.0: $with_rsvg
(requires librsvg-2.0 2.34.0 or later)
EXR load with OpenEXR: $with_OpenEXR
slide load with OpenSlide: $with_openslide
(requires openslide-3.3.0 or later)
Matlab load with matio: $with_matio
NIfTI load/save with niftiio: $with_nifti
FITS load/save with cfitsio: $with_cfitsio
Magick package: $with_magickpackage
Magick API version: $magick_version
load with libMagickCore: $enable_magickload
save with libMagickCore: $enable_magicksave
])

View File

@ -127,7 +127,7 @@ HTML_IMAGES = \
# we have some files in markdown ... convert to docbook for gtk-doc
# pandoc makes section headers, we want refsect3 for gtk-doc
.md.xml:
pandoc -s --template="$(realpath pandoc-docbook-template.docbook)" --wrap=none -V title="$<" -f markdown+smart -t docbook-smart -o $@ $<
pandoc -s --template="$(realpath pandoc-docbook-template.docbook)" --wrap=none -V title="$<" -f markdown+smart -t docbook -o $@ $<
sed -e s/section/refsect3/g < $@ > x && mv x $@
# Our markdown source files

View File

@ -19,10 +19,35 @@
<refsect3 xml:id="dont-bind-the-top-level-c-api">
<title>Dont bind the top-level C API</title>
<para>
The libvips C API (vips_add() and so on) is very inconvenient and dangerous to use from other languages due to its heavy use of varargs.
The libvips C API (vips_add() and so on) was designed to be easy for humans to write. It is inconvenient and dangerous to use from other languages due to its heavy use of varargs.
</para>
<para>
Its much better to use the layer below. This lower layer is structured as create operator, set parameters, execute, extract results. For example, you can execute vips_invert() like this:
Its much better to use the layer below. This lower layer is structured as:
</para>
<itemizedlist>
<listitem>
<para>
Create operator. You can use vips_operation_new() to make a new <literal>VipsOperation</literal> object from an operator nickname, like <literal>&quot;add&quot;</literal>.
</para>
</listitem>
<listitem>
<para>
Set parameters. You can loop over the operation with vips_argument_map() to get the name and type of each input argument. For each argument, you need to get the value from your language, convert to a <literal>GValue</literal>, then use g_object_set_property() to set that value on the operator.
</para>
</listitem>
<listitem>
<para>
Execute with vips_cache_operation_build().
</para>
</listitem>
<listitem>
<para>
Extract results. Again, you loop over the operator arguments with vips_argument_map(), but instead of inputs, this time you look for output arguments. You extract their value with g_object_get_property(), and pass the value back to your language.
</para>
</listitem>
</itemizedlist>
<para>
For example, you can execute vips_invert() like this:
</para>
<programlisting language="c">
/* compile with
@ -111,17 +136,11 @@ main( int argc, char **argv )
return( 0 );
}
</programlisting>
<para>
libvips has a couple of extra things to let you examine the arguments and types of an operator at runtime. Use vips_argument_map() to loop over all the arguments of an operator, and vips_object_get_argument() to fetch the type and flags of a specific argument.
</para>
<para>
Use vips_operation_get_flags() to get general information about an operator.
</para>
</refsect3>
<refsect3 xml:id="compiled-language-which-can-call-c">
<title>Compiled language which can call C</title>
<para>
The C++ binding uses this lower layer to define a function called <literal>VImage::call()</literal> which can call any libvips operator with a not-varargs set of variable arguments.
The C++ binding uses this lower layer to define a function called <literal>VImage::call()</literal> which can call any libvips operator with a set of variable arguments.
</para>
<para>
A small Python program walks the set of all libvips operators and generates a set of static bindings. For example:
@ -139,7 +158,7 @@ VImage VImage::invert( VOption *options )
}
</programlisting>
<para>
So from C++ you can call any libvips operator (though without type-safety) with <literal>VImage::call()</literal>, or use the member functions on <literal>VImage</literal> to get type-safe calls for at least the required operator arguments.
So from C++ you can call any libvips operator (though without static typechecking) with <literal>VImage::call()</literal>, or use the member functions on <literal>VImage</literal> to get type-checked calls for at least the required operator arguments.
</para>
<para>
The <literal>VImage</literal> class also adds automatic reference counting, constant expansion, operator overloads, and various other useful features.
@ -151,13 +170,13 @@ VImage VImage::invert( VOption *options )
Languages like Ruby, Python, JavaScript and LuaJIT cant call C directly, but they do support FFI. The bindings for these languages work rather like C++, but use FFI to call into libvips and run operations.
</para>
<para>
Since these languages are dynamic, they can add another trick: they intercept the method-missing hook and attempt to run any method calls not implemented by the <literal>Image</literal> class as libvips operators. This makes these bindings self-writing: they only contain a small amount of code and just expose everything they find in the libvips class hierarchy.
Since these languages are dynamic, they can add another trick: they intercept the method-missing hook and attempt to run any method calls not implemented by the <literal>Image</literal> class as libvips operators. In effect, the binding is generated at runtime.
</para>
</refsect3>
<refsect3 xml:id="dynamic-langauge-without-ffi">
<title>Dynamic langauge without FFI</title>
<para>
PHP does not have FFI, unfortunately, so for this language a small native module implements the general <literal>vips_call()</literal> function for PHP language types, and a larger pure PHP layer makes it convenient to use.
PHP does not have a useful FFI, unfortunately, so for this language a small C module implements the general <literal>vips_call()</literal> function for PHP language types, and a larger pure PHP layer makes it convenient to use.
</para>
</refsect3>
<refsect3 xml:id="gobject-introspection">

View File

@ -67,7 +67,7 @@ typedef struct _VipsFlatten {
*/
VipsArrayDouble *background;
/* The [double] converted to the input image format.
/* The [double] background converted to the input image format.
*/
VipsPel *ink;

View File

@ -7,6 +7,8 @@
* - max_alpha defaults to 65535 for RGB16/GREY16
* 24/11/17 lovell
* - match normalised alpha to output type
* 27/2/21 jjonesrs
* - revise range clipping and 1/x, again
*/
/*
@ -70,7 +72,8 @@ typedef VipsConversionClass VipsUnpremultiplyClass;
G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
/* Unpremultiply an N-band image.
/* Unpremultiply an N-band image. Don't use clip_alpha to calculate factor: we
* want over and undershoots on alpha and RGB to cancel.
*/
#define UNPRE_MANY( IN, OUT ) { \
IN * restrict p = (IN *) in; \
@ -78,18 +81,11 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
\
for( x = 0; x < width; x++ ) { \
IN alpha = p[alpha_band]; \
OUT factor = alpha == 0 ? 0 : max_alpha / alpha; \
\
if( alpha != 0 ) { \
OUT factor = max_alpha / alpha; \
\
for( i = 0; i < alpha_band; i++ ) \
q[i] = factor * p[i]; \
q[alpha_band] = alpha; \
} \
else \
for( i = 0; i < alpha_band + 1; i++ ) \
q[i] = 0; \
\
for( i = 0; i < alpha_band; i++ ) \
q[i] = factor * p[i]; \
q[alpha_band] = VIPS_CLIP( 0, alpha, max_alpha ); \
for( i = alpha_band + 1; i < bands; i++ ) \
q[i] = p[i]; \
\
@ -106,21 +102,12 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION );
\
for( x = 0; x < width; x++ ) { \
IN alpha = p[3]; \
OUT factor = alpha == 0 ? 0 : max_alpha / alpha; \
\
if( alpha != 0 ) { \
OUT factor = max_alpha / alpha; \
\
q[0] = factor * p[0]; \
q[1] = factor * p[1]; \
q[2] = factor * p[2]; \
q[3] = alpha; \
} \
else { \
q[0] = 0; \
q[1] = 0; \
q[2] = 0; \
q[3] = 0; \
} \
q[0] = factor * p[0]; \
q[1] = factor * p[1]; \
q[2] = factor * p[2]; \
q[3] = VIPS_CLIP( 0, alpha, max_alpha ); \
\
p += 4; \
q += 4; \

View File

@ -104,7 +104,7 @@ vips__tiff_openout( const char *path, gboolean bigtiff )
/* Need the utf-16 version on Windows.
*/
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
GError *error = NULL;
wchar_t *path16;
@ -119,9 +119,9 @@ vips__tiff_openout( const char *path, gboolean bigtiff )
g_free( path16 );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
tif = TIFFOpen( path, mode );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
if( !tif ) {
vips_error( "tiff",

View File

@ -590,8 +590,8 @@ vips_foreign_save_tiff_buffer_init( VipsForeignSaveTiffBuffer *buffer )
* User @level to set the ZSTD compression level. Use @lossless to
* set WEBP lossless mode on. Use @Q to set the WEBP compression level.
*
* Use @predictor to set the predictor for lzw and deflate compression. It
* defaults to #VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL, meaning horizontal
* Use @predictor to set the predictor for lzw, deflate and zstd compression.
* It defaults to #VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL, meaning horizontal
* differencing. Please refer to the libtiff
* specifications for further discussion of various predictors.
*

View File

@ -333,9 +333,9 @@ struct _Wtiff {
VipsPel *tbuf; /* TIFF output buffer */
int tls; /* Tile line size */
int compression; /* Compression type */
int compression; /* libtiff compression type */
int Q; /* JPEG q-factor, webp level */
int predictor; /* Predictor value */
int predictor; /* libtiff predictor type */
int tile; /* Tile or not */
int tilew, tileh; /* Tile size */
int pyramid; /* Wtiff pyramid */
@ -659,12 +659,16 @@ wtiff_write_header( Wtiff *wtiff, Layer *layer )
TIFFSetField( tif, TIFFTAG_WEBP_LEVEL, wtiff->Q );
TIFFSetField( tif, TIFFTAG_WEBP_LOSSLESS, wtiff->lossless );
}
if( wtiff->compression == COMPRESSION_ZSTD )
if( wtiff->compression == COMPRESSION_ZSTD ) {
TIFFSetField( tif, TIFFTAG_ZSTD_LEVEL, wtiff->level );
if( wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE )
TIFFSetField( tif,
TIFFTAG_PREDICTOR, wtiff->predictor );
}
#endif /*HAVE_TIFF_COMPRESSION_WEBP*/
if( (wtiff->compression == VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE ||
wtiff->compression == VIPS_FOREIGN_TIFF_COMPRESSION_LZW) &&
if( (wtiff->compression == COMPRESSION_ADOBE_DEFLATE ||
wtiff->compression == COMPRESSION_LZW) &&
wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE )
TIFFSetField( tif, TIFFTAG_PREDICTOR, wtiff->predictor );
@ -1862,10 +1866,19 @@ wtiff_copy_tiff( Wtiff *wtiff, TIFF *out, TIFF *in )
TIFFSetField( out, TIFFTAG_WEBP_LEVEL, wtiff->Q );
TIFFSetField( out, TIFFTAG_WEBP_LOSSLESS, wtiff->lossless );
}
if( wtiff->compression == COMPRESSION_ZSTD )
if( wtiff->compression == COMPRESSION_ZSTD ) {
TIFFSetField( out, TIFFTAG_ZSTD_LEVEL, wtiff->level );
if( wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE )
TIFFSetField( out,
TIFFTAG_PREDICTOR, wtiff->predictor );
}
#endif /*HAVE_TIFF_COMPRESSION_WEBP*/
if( (wtiff->compression == COMPRESSION_ADOBE_DEFLATE ||
wtiff->compression == COMPRESSION_LZW) &&
wtiff->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE )
TIFFSetField( out, TIFFTAG_PREDICTOR, wtiff->predictor );
/* We can't copy profiles or xmp :( Set again from wtiff.
*/
if( !wtiff->strip )

View File

@ -365,7 +365,6 @@ int vips_object_get_argument_priority( VipsObject *object, const char *name );
VIPS_ARGUMENT_COLLECT_END
*/
#if GLIB_CHECK_VERSION( 2, 24, 0 )
#define VIPS_ARGUMENT_COLLECT_SET( PSPEC, ARG_CLASS, AP ) \
if( (ARG_CLASS->flags & VIPS_ARGUMENT_INPUT) ) { \
GValue value = { 0, }; \
@ -383,25 +382,6 @@ int vips_object_get_argument_priority( VipsObject *object, const char *name );
VIPS_DEBUG_MSG( "VIPS_OBJECT_COLLECT_SET: err\n" ); \
g_free( error ); \
}
#else
#define VIPS_ARGUMENT_COLLECT_SET( PSPEC, ARG_CLASS, AP ) \
if( (ARG_CLASS->flags & VIPS_ARGUMENT_INPUT) ) { \
GValue value = { 0, }; \
gchar *error = NULL; \
\
/* Input args are given inline, eg. ("factor", 12.0) \
* and must be collected. \
*/ \
g_value_init( &value, G_PARAM_SPEC_VALUE_TYPE( PSPEC ) ); \
G_VALUE_COLLECT( &value, AP, 0, &error ); \
\
/* Don't bother with the error message. \
*/ \
if( error ) { \
VIPS_DEBUG_MSG( "VIPS_OBJECT_COLLECT_SET: err\n" ); \
g_free( error ); \
}
#endif
#define VIPS_ARGUMENT_COLLECT_GET( PSPEC, ARG_CLASS, AP ) \
g_value_unset( &value ); \

View File

@ -65,10 +65,10 @@
#include <vips/thread.h>
#include <vips/debug.h>
#ifdef OS_WIN32
#ifdef G_OS_WIN32
#include <windows.h>
#include <lmerr.h>
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
/**
* SECTION: errors
@ -294,7 +294,7 @@ vips_verror_system( int err, const char *domain, const char *fmt, va_list ap )
{
vips_verror( domain, fmt, ap );
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
char *buf;
@ -310,7 +310,7 @@ vips_verror_system( int err, const char *domain, const char *fmt, va_list ap )
LocalFree( buf );
}
}
#else /*OS_WIN32*/
#else /*!G_OS_WIN32*/
{
char *buf;
@ -318,7 +318,7 @@ vips_verror_system( int err, const char *domain, const char *fmt, va_list ap )
vips_error( _( "unix error" ), "%s", buf );
g_free( buf );
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
}
/**

View File

@ -1676,14 +1676,7 @@ vips_image_temp_name( char *name, int size )
{
static int global_serial = 0;
/* Old glibs named this differently.
*/
int serial =
#if GLIB_CHECK_VERSION( 2, 30, 0 )
g_atomic_int_add( &global_serial, 1 );
#else
g_atomic_int_exchange_and_add( &global_serial, 1 );
#endif
int serial = g_atomic_int_add( &global_serial, 1 );
vips_snprintf( name, size, "temp-%d", serial );
}

View File

@ -290,24 +290,6 @@ empty_log_handler( const gchar *log_domain, GLogLevelFlags log_level,
{
}
#if !GLIB_CHECK_VERSION( 2, 31, 0 )
static void
default_log_handler( const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data )
{
if( log_level & (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) ) {
const char *domains = g_getenv( "G_MESSAGES_DEBUG" );
if( !domains ||
(!g_str_equal( domains, "all" ) &&
!g_strrstr( domains, log_domain )) )
return;
}
g_log_default_handler( log_domain, log_level, message, user_data );
}
#endif /*!GLIB_CHECK_VERSION( 2, 31, 0 )*/
/* Attempt to set a minimum stacksize. This can be important on systems with a
* very low default, like musl.
*/
@ -407,7 +389,7 @@ vips_init( const char *argv0 )
return( 0 );
started = TRUE;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
/* Windows has a limit of 512 files open at once for the fopen() family
* of functions, and 2048 for the _open() family. This raises the limit
* of fopen() to the same level as _open().
@ -415,7 +397,7 @@ vips_init( const char *argv0 )
* It will not go any higher than this, unfortunately.
*/
(void) _setmaxstdio( 2048 );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
vips__threadpool_init();
vips__buffer_init();
@ -595,18 +577,6 @@ vips_init( const char *argv0 )
g_log_set_handler( G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
empty_log_handler, NULL );
#if !GLIB_CHECK_VERSION( 2, 31, 0 )
/* Older glibs can sometimes show G_LOG_LEVEL_{INFO,DEBUG} messages.
* Block them ourselves. We test the env var inside the handler since
* vips_verbose() can be toggled at runtime.
*
* Again, we should not call g_log_set_handler(), but this is the only
* convenient way to fix this behaviour.
*/
g_log_set_handler( G_LOG_DOMAIN, G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG,
default_log_handler, NULL );
#endif /*!GLIB_CHECK_VERSION( 2, 31, 0 )*/
/* Set a minimum stacksize, if we can.
*/
if( (vips_min_stack_size = g_getenv( "VIPS_MIN_STACK_SIZE" )) )
@ -1057,7 +1027,7 @@ find_file( const char *name )
printf( "vips_guess_prefix: g_getenv( \"PATH\" ) == \"%s\"\n", path );
#endif /*DEBUG*/
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
char *dir;
@ -1068,9 +1038,9 @@ find_file( const char *name )
"%s" G_SEARCHPATH_SEPARATOR_S "%s", dir, path );
g_free( dir );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
vips_strncpy( full_path, path, VIPS_PATH_MAX );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
if( (prefix = scan_path( full_path, name )) )
return( prefix );
@ -1177,9 +1147,9 @@ vips_guess_prefix( const char *argv0, const char *env_name )
return( prefix );
}
#ifdef OS_WIN32
#ifdef G_OS_WIN32
prefix = vips__windows_prefix();
#else
#else /*!G_OS_WIN32*/
{
char *basename;
@ -1187,7 +1157,7 @@ vips_guess_prefix( const char *argv0, const char *env_name )
prefix = guess_prefix( argv0, basename );
g_free( basename );
}
#endif
#endif /*G_OS_WIN32*/
g_setenv( env_name, prefix, TRUE );

View File

@ -77,18 +77,16 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /*HAVE_UNISTD_H*/
#ifdef OS_WIN32
#ifndef S_ISREG
#define S_ISREG(m) (!!(m & _S_IFREG))
#endif
#endif /*OS_WIN32*/
#include <vips/vips.h>
#ifdef OS_WIN32
#ifdef G_OS_WIN32
#ifndef S_ISREG
#define S_ISREG(m) (!!(m & _S_IFREG))
#endif
#include <windows.h>
#include <io.h>
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
/* Does this fd support mmap. Pipes won't, for example.
*/
@ -99,7 +97,7 @@ vips__mmap_supported( int fd )
size_t length = 4096;
off_t offset = 0;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
HANDLE hFile = (HANDLE) _get_osfhandle( fd );
@ -128,7 +126,7 @@ vips__mmap_supported( int fd )
CloseHandle( hMMFile );
UnmapViewOfFile( baseaddr );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
{
int prot = PROT_READ;
int flags = MAP_SHARED;
@ -138,7 +136,7 @@ vips__mmap_supported( int fd )
return( FALSE );
munmap( baseaddr, length );
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( TRUE );
}
@ -153,7 +151,7 @@ vips__mmap( int fd, int writeable, size_t length, gint64 offset )
length, offset );
#endif /*DEBUG*/
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
HANDLE hFile = (HANDLE) _get_osfhandle( fd );
@ -203,7 +201,7 @@ vips__mmap( int fd, int writeable, size_t length, gint64 offset )
*/
CloseHandle( hMMFile );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
{
int prot;
int flags;
@ -237,7 +235,7 @@ vips__mmap( int fd, int writeable, size_t length, gint64 offset )
return( NULL );
}
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( baseaddr );
}
@ -245,19 +243,19 @@ vips__mmap( int fd, int writeable, size_t length, gint64 offset )
int
vips__munmap( const void *start, size_t length )
{
#ifdef OS_WIN32
#ifdef G_OS_WIN32
if( !UnmapViewOfFile( (void *) start ) ) {
vips_error_system( GetLastError(), "vips_mapfile",
"%s", _( "unable to UnmapViewOfFile" ) );
return( -1 );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
if( munmap( (void *) start, length ) < 0 ) {
vips_error_system( errno, "vips_mapfile",
"%s", _( "unable to munmap file" ) );
return( -1 );
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( 0 );
}
@ -345,7 +343,7 @@ vips_remapfilerw( VipsImage *image )
printf( "vips_remapfilerw:\n" );
#endif /*DEBUG*/
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
HANDLE hFile = (HANDLE) _get_osfhandle( image->fd );
HANDLE hMMFile;
@ -377,7 +375,7 @@ vips_remapfilerw( VipsImage *image )
*/
CloseHandle( hMMFile );
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
{
assert( image->dtype == VIPS_IMAGE_MMAPIN );
@ -390,7 +388,7 @@ vips_remapfilerw( VipsImage *image )
return( -1 );
}
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
image->dtype = VIPS_IMAGE_MMAPINRW;

View File

@ -65,23 +65,24 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef OS_WIN32
#include <io.h>
#endif /*OS_WIN32*/
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/debug.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif /*G_OS_WIN32*/
/* Try to make an O_BINARY ... sometimes need the leading '_'.
*/
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#endif /*_O_BINARY*/
#endif /*!O_BINARY*/
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
/* If we have O_BINARY, add it to a mode flags set.
*/
@ -307,12 +308,12 @@ vips_source_build( VipsObject *object )
connection->descriptor = dup( connection->descriptor );
connection->close_descriptor = connection->descriptor;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
/* Windows will create eg. stdin and stdout in text mode.
* We always read in binary mode.
*/
_setmode( connection->descriptor, _O_BINARY );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
}
if( vips_object_argument_isset( object, "blob" ) ) {

View File

@ -55,23 +55,24 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef OS_WIN32
#include <io.h>
#endif /*OS_WIN32*/
#include <vips/vips.h>
#include <vips/internal.h>
#include <vips/debug.h>
#ifdef G_OS_WIN32
#include <io.h>
#endif /*G_OS_WIN32*/
/* Try to make an O_BINARY ... sometimes need the leading '_'.
*/
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#endif /*_O_BINARY*/
#endif /*!O_BINARY*/
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
/* If we have O_BINARY, add it to a mode flags set.
*/
@ -143,12 +144,12 @@ vips_target_build( VipsObject *object )
connection->descriptor = dup( connection->descriptor );
connection->close_descriptor = connection->descriptor;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
/* Windows will create eg. stdin and stdout in text mode.
* We always write in binary mode.
*/
_setmode( connection->descriptor, _O_BINARY );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
}
else if( target->memory )
target->memory_buffer = g_byte_array_new();

View File

@ -75,9 +75,9 @@
#include <vips/thread.h>
#include <vips/debug.h>
#ifdef OS_WIN32
#ifdef G_OS_WIN32
#include <windows.h>
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
/**
* SECTION: threadpool
@ -338,7 +338,7 @@ get_num_processors( void )
#endif /*G_OS_UNIX*/
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
/* Count the CPUs currently available to this process.
*/
@ -365,7 +365,7 @@ get_num_processors( void )
nproc = af_count;
}
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( nproc );
#endif /*!GLIB_CHECK_VERSION( 2, 48, 1 )*/

View File

@ -53,27 +53,27 @@
#endif /*HAVE_IO_H*/
#include <fcntl.h>
#ifdef OS_WIN32
#include <windows.h>
#endif /*OS_WIN32*/
#include <vips/vips.h>
#include <vips/debug.h>
#include <vips/internal.h>
#ifdef G_OS_WIN32
#include <windows.h>
#endif /*G_OS_WIN32*/
/* Temp buffer for snprintf() layer on old systems.
*/
#define MAX_BUF (100000)
/* Try to make an O_BINARY ... sometimes need the leading '_'.
*/
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#endif /*_O_BINARY*/
#endif /*!O_BINARY*/
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
/* If we have O_BINARY, add it to a mode flags set.
*/
@ -562,15 +562,15 @@ vips_filename_suffix_match( const char *path, const char *suffixes[] )
gint64
vips_file_length( int fd )
{
#ifdef OS_WIN32
#ifdef G_OS_WIN32
struct _stati64 st;
if( _fstati64( fd, &st ) == -1 ) {
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
struct stat st;
if( fstat( fd, &st ) == -1 ) {
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
vips_error_system( errno, "vips_file_length",
"%s", _( "unable to get file stats" ) );
return( -1 );
@ -600,7 +600,7 @@ vips__write( int fd, const void *buf, size_t count )
return( 0 );
}
#ifdef OS_WIN32
#ifdef G_OS_WIN32
/* Set the create date on a file. On Windows, the create date may be copied
* over from an existing file of the same name, unless you reset it.
*
@ -619,7 +619,7 @@ vips__set_create_time( int fd )
SystemTimeToFileTime( &st, &ft );
SetFileTime( handle, &ft, &ft, &ft );
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
/* open() with a utf8 filename, setting errno.
*/
@ -638,10 +638,10 @@ vips__open( const char *filename, int flags, int mode )
fd = g_open( filename, flags, mode );
#ifdef OS_WIN32
#ifdef G_OS_WIN32
if( mode & O_CREAT )
vips__set_create_time( fd );
#endif
#endif /*G_OS_WIN32*/
return( fd );
}
@ -661,10 +661,10 @@ vips__fopen( const char *filename, const char *mode )
fp = g_fopen( filename, mode );
#ifdef OS_WIN32
#ifdef G_OS_WIN32
if( mode[0] == 'w' )
vips__set_create_time( _fileno( fp ) );
#endif
#endif /*G_OS_WIN32*/
return( fp );
}
@ -698,14 +698,14 @@ vips__file_open_read( const char *filename, const char *fallback_dir,
char *mode;
FILE *fp;
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
if( text_mode )
mode = "r";
else
mode = "rb";
#else /*BINARY_OPEN*/
#else /*!G_PLATFORM_WIN32*/
mode = "r";
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
if( (fp = vips__fopen( filename, mode )) )
return( fp );
@ -734,14 +734,14 @@ vips__file_open_write( const char *filename, gboolean text_mode )
char *mode;
FILE *fp;
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
if( text_mode )
mode = "w";
else
mode = "wb";
#else /*BINARY_OPEN*/
#else /*!G_PLATFORM_WIN32*/
mode = "w";
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
if( !(fp = vips__fopen( filename, mode )) ) {
vips_error_system( errno, "vips__file_open_write",
@ -1089,15 +1089,15 @@ vips__seek_no_error( int fd, gint64 pos, int whence )
{
gint64 new_pos;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
new_pos = _lseeki64( fd, pos, whence );
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
/* On error, eg. opening a directory and seeking to the end, lseek()
* on linux seems to return 9223372036854775807 ((1 << 63) - 1)
* rather than (off_t) -1 for reasons I don't understand.
*/
new_pos = lseek( fd, pos, whence );
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( new_pos );
}
@ -1128,7 +1128,7 @@ vips__seek( int fd, gint64 pos, int whence )
int
vips__ftruncate( int fd, gint64 pos )
{
#ifdef OS_WIN32
#ifdef G_OS_WIN32
{
HANDLE hFile = (HANDLE) _get_osfhandle( fd );
@ -1140,13 +1140,13 @@ vips__ftruncate( int fd, gint64 pos )
return( -1 );
}
}
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
if( ftruncate( fd, pos ) ) {
vips_error_system( errno, "vips__ftruncate",
"%s", _( "unable to truncate" ) );
return( -1 );
}
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
return( 0 );
}
@ -1620,7 +1620,7 @@ vips__temp_dir( void )
const char *tmpd;
if( !(tmpd = g_getenv( "TMPDIR" )) ) {
#ifdef OS_WIN32
#ifdef G_OS_WIN32
static gboolean done = FALSE;
static char buf[256];
@ -1629,9 +1629,9 @@ vips__temp_dir( void )
strcpy( buf, "C:\\temp" );
}
tmpd = buf;
#else /*!OS_WIN32*/
#else /*!G_OS_WIN32*/
tmpd = "/tmp";
#endif /*!OS_WIN32*/
#endif /*!G_OS_WIN32*/
}
return( tmpd );
@ -1651,14 +1651,7 @@ vips__temp_name( const char *format )
char file2[FILENAME_MAX];
char *name;
/* Old glibs named this differently.
*/
int serial =
#if GLIB_CHECK_VERSION( 2, 30, 0 )
g_atomic_int_add( &global_serial, 1 );
#else
g_atomic_int_exchange_and_add( &global_serial, 1 );
#endif
int serial = g_atomic_int_add( &global_serial, 1 );
vips_snprintf( file, FILENAME_MAX, "vips-%d-%u",
serial, g_random_int() );
@ -1961,7 +1954,7 @@ vips__random_add( guint32 seed, int value )
static void *
vips_icc_dir_once( void *null )
{
#ifdef OS_WIN32
#ifdef G_OS_WIN32
/* From glib get_windows_directory_root()
*/
wchar_t wwindowsdir[MAX_PATH];
@ -1983,7 +1976,7 @@ vips_icc_dir_once( void *null )
return( (void *) full_path );
}
}
#endif
#endif /*G_OS_WIN32*/
return( (void *) VIPS_ICC_DIR );
}
@ -1997,7 +1990,7 @@ vips__icc_dir( void )
vips_icc_dir_once, NULL ) );
}
#ifdef OS_WIN32
#ifdef G_OS_WIN32
static HMODULE vips__dll = NULL;
#ifdef DLL_EXPORT
BOOL WINAPI
@ -2009,19 +2002,19 @@ DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
return( TRUE );
}
#endif
#endif
#endif /*G_OS_WIN32*/
static void *
vips__windows_prefix_once( void *null )
{
char *prefix;
#ifdef OS_WIN32
#ifdef G_OS_WIN32
prefix = g_win32_get_package_installation_directory_of_module(
vips__dll );
#else
#else /*!G_OS_WIN32*/
prefix = (char *) g_getenv( "VIPSHOME" );
#endif
#endif /*G_OS_WIN32*/
return( (void *) prefix );
}

View File

@ -115,13 +115,13 @@
/* Try to make an O_BINARY ... sometimes need the leading '_'.
*/
#ifdef BINARY_OPEN
#ifdef G_PLATFORM_WIN32
#ifndef O_BINARY
#ifdef _O_BINARY
#define O_BINARY _O_BINARY
#endif /*_O_BINARY*/
#endif /*!O_BINARY*/
#endif /*BINARY_OPEN*/
#endif /*G_PLATFORM_WIN32*/
/* If we have O_BINARY, add it to a mode flags set.
*/

View File

@ -58,9 +58,9 @@
#include <vips/internal.h>
#include <vips/thread.h>
#ifdef OS_WIN32
#ifdef G_OS_WIN32
#include <windows.h>
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
/* Sanity checking ... write to this during read tests to make sure we don't
* get optimized out.
@ -189,15 +189,15 @@ vips_getpagesize( void )
static int pagesize = 0;
if( !pagesize ) {
#ifdef OS_WIN32
#ifdef G_OS_WIN32
SYSTEM_INFO si;
GetSystemInfo( &si );
pagesize = si.dwAllocationGranularity;
#else /*OS_WIN32*/
#else /*!G_OS_WIN32*/
pagesize = getpagesize();
#endif /*OS_WIN32*/
#endif /*G_OS_WIN32*/
#ifdef DEBUG_TOTAL
printf( "vips_getpagesize: 0x%x\n", pagesize );

View File

@ -1123,16 +1123,9 @@ vips__add_mosaic_name( VipsImage *image )
{
static int global_serial = 0;
/* Old glibs named this differently.
*
* TODO(kleisauke): Could we call vips_image_temp_name instead?
/* TODO(kleisauke): Could we call vips_image_temp_name instead?
*/
int serial =
#if GLIB_CHECK_VERSION( 2, 30, 0 )
g_atomic_int_add( &global_serial, 1 );
#else
g_atomic_int_exchange_and_add( &global_serial, 1 );
#endif
int serial = g_atomic_int_add( &global_serial, 1 );
char name[256];

View File

@ -30,6 +30,9 @@
* - add thumbnail_source
* 2/6/20
* - add subifd pyr support
* 27/2/21
* - simplify rules re. processing space, colour management and linear
* mode
*/
/*
@ -624,16 +627,19 @@ vips_thumbnail_build( VipsObject *object )
int preshrunk_page_height;
double hshrink;
double vshrink;
VipsInterpretation interpretation;
/* TRUE if we've done the import of an ICC transform and still need to
* export.
*/
gboolean have_imported;
/* TRUE if we've premultiplied and need to unpremultiply.
/* If we shrink in linear space, we need to return to the input
* colourspace after the shrink.
*/
VipsInterpretation input_interpretation;
/* The format we need to revert to after unpremultiply.
*/
gboolean have_premultiplied;
VipsBandFormat unpremultiplied_format;
#ifdef DEBUG
@ -679,60 +685,78 @@ vips_thumbnail_build( VipsObject *object )
in = t[12];
}
/* In linear mode, we import right at the start.
*
* We also have to import the whole image if it's CMYK, since
* vips_colourspace() (see below) doesn't let you specify the fallback
* profile.
*
* This is only going to work for images in device space. If you have
* an image in PCS which also has an attached profile, strange things
* will happen.
/* In linear mode, we need to transform to a linear space before
* vips_resize().
*/
have_imported = FALSE;
if( thumbnail->linear &&
in->Coding == VIPS_CODING_NONE &&
(in->BandFmt == VIPS_FORMAT_UCHAR ||
in->BandFmt == VIPS_FORMAT_USHORT) &&
(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ||
thumbnail->import_profile) ) {
g_info( "importing to XYZ PCS" );
if( thumbnail->import_profile )
g_info( "fallback input profile %s",
thumbnail->import_profile );
if( thumbnail->linear ) {
/* If we are doing colour management (there's an import
* profile), then we can use XYZ PCS as the resize space.
*/
if( in->Coding == VIPS_CODING_NONE &&
(in->BandFmt == VIPS_FORMAT_UCHAR ||
in->BandFmt == VIPS_FORMAT_USHORT) &&
(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ||
thumbnail->import_profile) ) {
g_info( "importing to XYZ PCS" );
if( thumbnail->import_profile )
g_info( "fallback input profile %s",
thumbnail->import_profile );
if( vips_icc_import( in, &t[1],
"input_profile", thumbnail->import_profile,
"embedded", TRUE,
"intent", thumbnail->intent,
"pcs", VIPS_PCS_XYZ,
NULL ) )
return( -1 );
if( vips_icc_import( in, &t[1],
"input_profile", thumbnail->import_profile,
"embedded", TRUE,
"intent", thumbnail->intent,
"pcs", VIPS_PCS_XYZ,
NULL ) )
return( -1 );
in = t[1];
in = t[1];
have_imported = TRUE;
}
else {
/* Otherwise, use scRGB or GREY16 for linear shrink.
*/
VipsInterpretation interpretation;
have_imported = TRUE;
/* Note the interpretation we will revert to after
* linear.
*/
input_interpretation = in->Type;
if( in->Bands < 3 )
interpretation = VIPS_INTERPRETATION_GREY16;
else
interpretation = VIPS_INTERPRETATION_scRGB;
g_info( "converting to processing space %s",
vips_enum_nick( VIPS_TYPE_INTERPRETATION,
interpretation ) );
if( vips_colourspace( in, &t[2], interpretation,
NULL ) )
return( -1 );
in = t[2];
}
}
else {
/* In non-linear mode, use sRGB or B_W as the processing
* space.
*/
VipsInterpretation interpretation;
/* To the processing colourspace. This will unpack LABQ, import CMYK,
* etc.
*
* If this is a CMYK image, we need to set have_imported since we only
* want to export at the end.
*/
if( in->Type == VIPS_INTERPRETATION_CMYK )
have_imported = TRUE;
if( thumbnail->linear )
interpretation = VIPS_INTERPRETATION_scRGB;
else if( in->Bands < 3 )
interpretation = VIPS_INTERPRETATION_B_W;
else
interpretation = VIPS_INTERPRETATION_sRGB;
g_info( "converting to processing space %s",
vips_enum_nick( VIPS_TYPE_INTERPRETATION, interpretation ) );
if( vips_colourspace( in, &t[2], interpretation, NULL ) )
return( -1 );
in = t[2];
if( in->Bands < 3 )
interpretation = VIPS_INTERPRETATION_B_W;
else
interpretation = VIPS_INTERPRETATION_sRGB;
g_info( "converting to processing space %s",
vips_enum_nick( VIPS_TYPE_INTERPRETATION,
interpretation ) );
if( vips_colourspace( in, &t[2], interpretation,
NULL ) )
return( -1 );
in = t[2];
}
/* Shrink to preshrunk_page_height, so we work for multi-page images.
*/
@ -751,23 +775,23 @@ vips_thumbnail_build( VipsObject *object )
vshrink = (double) in->Ysize / target_image_height;
}
/* vips_premultiply() makes a float image, so when we unpremultiply
* below we must cast back to the original format. Use NOTSET to
* meran no pre/unmultiply.
*/
unpremultiplied_format = VIPS_FORMAT_NOTSET;
/* If there's an alpha, we have to premultiply before shrinking. See
* https://github.com/libvips/libvips/issues/291
*/
have_premultiplied = FALSE;
if( vips_image_hasalpha( in ) &&
hshrink != 1.0 &&
vshrink != 1.0 ) {
g_info( "premultiplying alpha" );
unpremultiplied_format = in->BandFmt;
if( vips_premultiply( in, &t[3], NULL ) )
return( -1 );
have_premultiplied = TRUE;
/* vips_premultiply() makes a float image. When we
* vips_unpremultiply() below, we need to cast back to the
* pre-premultiply format.
*/
unpremultiplied_format = in->BandFmt;
in = t[3];
}
@ -777,6 +801,14 @@ vips_thumbnail_build( VipsObject *object )
return( -1 );
in = t[4];
if( unpremultiplied_format != VIPS_FORMAT_NOTSET ) {
g_info( "unpremultiplying alpha" );
if( vips_unpremultiply( in, &t[5], NULL ) ||
vips_cast( t[5], &t[6], unpremultiplied_format, NULL ) )
return( -1 );
in = t[6];
}
/* Only set page-height if we have more than one page, or this could
* accidentally turn into an animated image later.
*/
@ -792,21 +824,12 @@ vips_thumbnail_build( VipsObject *object )
VIPS_META_PAGE_HEIGHT, output_page_height );
}
if( have_premultiplied ) {
g_info( "unpremultiplying alpha" );
if( vips_unpremultiply( in, &t[5], NULL ) ||
vips_cast( t[5], &t[6], unpremultiplied_format, NULL ) )
return( -1 );
in = t[6];
}
/* Colour management.
*
* If we've already imported, just export. Otherwise, we're in
* device space and we need a combined import/export to transform to
* the target space.
*/
if( have_imported ) {
/* We've already imported, just export. Go to sRGB if there's
* no export profile.
*/
if( thumbnail->export_profile ||
vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
g_info( "exporting to device space with a profile" );
@ -825,21 +848,54 @@ vips_thumbnail_build( VipsObject *object )
in = t[7];
}
}
else if( thumbnail->export_profile &&
(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ||
thumbnail->import_profile) ) {
else if( thumbnail->export_profile ) {
/* Not imported, but we are doing colour management. Transform
* to the output space.
*/
g_info( "transforming to %s", thumbnail->export_profile );
if( thumbnail->import_profile )
g_info( "fallback input profile %s",
thumbnail->import_profile );
if( vips_icc_transform( in, &t[7],
thumbnail->export_profile,
"input_profile", thumbnail->import_profile,
"intent", thumbnail->intent,
"embedded", TRUE,
NULL ) )
return( -1 );
/* If there's some kind of import profile, we can transform to
* the output. Otherwise we have to convert to PCS and then
* export.
*/
if( thumbnail->import_profile ||
(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ||
thumbnail->import_profile) ) {
g_info( "transforming with supplied profiles" );
if( vips_icc_transform( in, &t[7],
thumbnail->export_profile,
"input_profile", thumbnail->import_profile,
"intent", thumbnail->intent,
"embedded", TRUE,
NULL ) )
return( -1 );
in = t[7];
}
else {
g_info( "exporting with %s",
thumbnail->export_profile );
if( vips_colourspace( in, &t[7],
VIPS_INTERPRETATION_XYZ, NULL ) ||
vips_icc_export( t[7], &t[10],
"output_profile",
thumbnail->export_profile,
"intent", thumbnail->intent,
NULL ) )
return( -1 );
in = t[10];
}
}
else if( thumbnail->linear ) {
/* Linear mode, no colour management. We went to scRGB for
* processing, so we now revert to the input colourspace.
*/
g_info( "reverting to input space %s",
vips_enum_nick( VIPS_TYPE_INTERPRETATION,
input_interpretation ) );
if( vips_colourspace( in, &t[7],
input_interpretation, NULL ) )
return( -1 );
in = t[7];
}
@ -1368,7 +1424,7 @@ vips_thumbnail_buffer_init( VipsThumbnailBuffer *buffer )
* * @intent: #VipsIntent, rendering intent
* * @option_string: %gchararray, extra loader options
*
* Exacty as vips_thumbnail(), but read from a memory buffer. One extra
* Exactly as vips_thumbnail(), but read from a memory buffer. One extra
* optional argument, @option_string, lets you pass options to the underlying
* loader.
*
@ -1564,7 +1620,7 @@ vips_thumbnail_source_init( VipsThumbnailSource *source )
* * @intent: #VipsIntent, rendering intent
* * @option_string: %gchararray, extra loader options
*
* Exacty as vips_thumbnail(), but read from a source. One extra
* Exactly as vips_thumbnail(), but read from a source. One extra
* optional argument, @option_string, lets you pass options to the underlying
* loader.
*
@ -1671,7 +1727,7 @@ vips_thumbnail_image_init( VipsThumbnailImage *image )
* * @export_profile: %gchararray, export ICC profile
* * @intent: #VipsIntent, rendering intent
*
* Exacty as vips_thumbnail(), but read from an existing image.
* Exactly as vips_thumbnail(), but read from an existing image.
*
* This operation
* is not able to exploit shrink-on-load features of image load libraries, so

View File

@ -42,6 +42,9 @@ BMP_FILE = os.path.join(IMAGES, "MARBLES.BMP")
NIFTI_FILE = os.path.join(IMAGES, "avg152T1_LR_nifti.nii.gz")
ICO_FILE = os.path.join(IMAGES, "favicon.ico")
AVIF_FILE = os.path.join(IMAGES, "avif-orientation-6.avif")
HEIC_FILE = os.path.join(IMAGES, "heic-orientation-6.heic")
RGBA_FILE = os.path.join(IMAGES, "rgba.png")
RGBA_CORRECT_FILE = os.path.join(IMAGES, "rgba-correct.ppm")
MOSAIC_FILES = [os.path.join(IMAGES, "cd1.1.jpg"), os.path.join(IMAGES, "cd1.2.jpg"),
os.path.join(IMAGES, "cd2.1.jpg"), os.path.join(IMAGES, "cd2.2.jpg"),
os.path.join(IMAGES, "cd3.1.jpg"), os.path.join(IMAGES, "cd3.2.jpg"),

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -2,7 +2,8 @@
import pytest
import pyvips
from helpers import JPEG_FILE, OME_FILE, AVIF_FILE, TIF_FILE, all_formats, have
from helpers import JPEG_FILE, OME_FILE, HEIC_FILE, TIF_FILE, all_formats, \
have, RGBA_FILE, RGBA_CORRECT_FILE, AVIF_FILE
# Run a function expecting a complex image on a two-band image
@ -193,6 +194,11 @@ class TestResample:
im2 = pyvips.Image.thumbnail_buffer(buf, 100)
assert abs(im1.avg() - im2.avg()) < 1
# linear shrink should work on rgba images
im1 = pyvips.Image.thumbnail(RGBA_FILE, 64, linear=True)
im2 = pyvips.Image.new_from_file(RGBA_CORRECT_FILE)
assert abs(im1.flatten(background=255).avg() - im2.avg()) < 1
if have("heifload"):
# this image is orientation 6 ... thumbnail should flip it
im = pyvips.Image.new_from_file(AVIF_FILE)

View File

@ -101,9 +101,9 @@
#include <vips/vips7compat.h>
#endif
#ifdef OS_WIN32
#ifdef G_OS_WIN32
#define strcasecmp(a,b) _stricmp(a,b)
#endif
#endif /*G_OS_WIN32*/
static char *main_option_plugin = NULL;
static gboolean main_option_version;
@ -458,11 +458,11 @@ parse_options( GOptionContext *context, int *argc, char **argv )
"OPER", _( "execute vips operation OPER" ) );
g_option_context_set_summary( context, vips_buf_all( &buf ) );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
if( !g_option_context_parse_strv( context, &argv, &error ) )
#else /*!HAVE_G_WIN32_GET_COMMAND_LINE*/
#else /*!G_OS_WIN32*/
if( !g_option_context_parse( context, argc, &argv, &error ) )
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
{
if( error ) {
fprintf( stderr, "%s\n", error->message );
@ -531,9 +531,9 @@ main( int argc, char **argv )
/* On Windows, argv is ascii-only .. use this to get a utf-8 version of
* the args.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
argv = g_win32_get_command_line();
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
#ifdef DEBUG_FATAL
/* Set masks for debugging ... stop on any problem.
@ -582,11 +582,11 @@ main( int argc, char **argv )
*/
g_option_context_set_help_enabled( context, FALSE );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
if( !g_option_context_parse_strv( context, &argv, &error ) )
#else /*!HAVE_G_WIN32_GET_COMMAND_LINE*/
#else /*!G_OS_WIN32*/
if( !g_option_context_parse( context, &argc, &argv, &error ) )
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
{
if( error ) {
fprintf( stderr, "%s\n", error->message );
@ -753,9 +753,9 @@ main( int argc, char **argv )
g_option_context_free( context );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
g_strfreev( argv );
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
vips_shutdown();

View File

@ -141,9 +141,9 @@ main( int argc, char **argv )
/* On Windows, argv is ascii-only .. use this to get a utf-8 version of
* the args.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
argv = g_win32_get_command_line();
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
context = g_option_context_new(
_( "vipsedit - edit vips file header" ) );
@ -153,11 +153,11 @@ main( int argc, char **argv )
g_option_group_set_translation_domain( main_group, GETTEXT_PACKAGE );
g_option_context_set_main_group( context, main_group );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
if( !g_option_context_parse_strv( context, &argv, &error ) )
#else /*!HAVE_G_WIN32_GET_COMMAND_LINE*/
#else /*!G_OS_WIN32*/
if( !g_option_context_parse( context, &argc, &argv, &error ) )
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
{
vips_g_error( &error );
@ -272,9 +272,9 @@ main( int argc, char **argv )
g_option_context_free( context );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
g_strfreev( argv );
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
vips_shutdown();

View File

@ -180,9 +180,9 @@ main( int argc, char *argv[] )
/* On Windows, argv is ascii-only .. use this to get a utf-8 version of
* the args.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
argv = g_win32_get_command_line();
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
context = g_option_context_new( _( "- print image header" ) );
main_group = g_option_group_new( NULL, NULL, NULL, NULL, NULL );
@ -191,11 +191,11 @@ main( int argc, char *argv[] )
g_option_group_set_translation_domain( main_group, GETTEXT_PACKAGE );
g_option_context_set_main_group( context, main_group );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
if( !g_option_context_parse_strv( context, &argv, &error ) )
#else /*!HAVE_G_WIN32_GET_COMMAND_LINE*/
#else /*!G_OS_WIN32*/
if( !g_option_context_parse( context, &argc, &argv, &error ) )
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
{
if( error ) {
fprintf( stderr, "%s\n", error->message );
@ -247,9 +247,9 @@ main( int argc, char *argv[] )
/* We don't free this on error exit, sadly.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
g_strfreev( argv );
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
vips_shutdown();

View File

@ -500,9 +500,9 @@ main( int argc, char **argv )
/* On Windows, argv is ascii-only .. use this to get a utf-8 version of
* the args.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
argv = g_win32_get_command_line();
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
context = g_option_context_new( _( "- thumbnail generator" ) );
@ -512,11 +512,11 @@ main( int argc, char **argv )
g_option_group_set_translation_domain( main_group, GETTEXT_PACKAGE );
g_option_context_set_main_group( context, main_group );
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
if( !g_option_context_parse_strv( context, &argv, &error ) )
#else /*!HAVE_G_WIN32_GET_COMMAND_LINE*/
#else /*!G_OS_WIN32*/
if( !g_option_context_parse( context, &argc, &argv, &error ) )
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
{
if( error ) {
fprintf( stderr, "%s\n", error->message );
@ -563,9 +563,9 @@ main( int argc, char **argv )
/* We don't free this on error exit, sadly.
*/
#ifdef HAVE_G_WIN32_GET_COMMAND_LINE
#ifdef G_OS_WIN32
g_strfreev( argv );
#endif /*HAVE_G_WIN32_GET_COMMAND_LINE*/
#endif /*G_OS_WIN32*/
vips_shutdown();