diff --git a/configure.ac b/configure.ac
index 918a50c1..d5c191ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
@@ -408,6 +413,9 @@ PKG_CHECK_MODULES(DATE_TIME_FORMAT_ISO8601, glib-2.0 >= 2.62,
]
)
+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
@@ -447,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],
@@ -478,6 +489,9 @@ if test x"$with_gsf" != x"no"; then
)
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)]))
@@ -493,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)]))
@@ -652,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)]))
@@ -688,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)]))
@@ -708,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)]))
@@ -725,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)]))
@@ -738,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)]))
@@ -805,6 +838,9 @@ if test x"$with_heif" = x"yes"; then
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)]))
@@ -825,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)]))
@@ -840,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)]))
@@ -856,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
@@ -879,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],
@@ -906,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)]))
@@ -922,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
@@ -965,6 +1020,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
@@ -983,6 +1041,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],
@@ -1000,6 +1061,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],
@@ -1035,6 +1099,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"
+
# giflib
FIND_GIFLIB(
[with_giflib="yes (found by search)"
@@ -1044,6 +1112,10 @@ FIND_GIFLIB(
]
)
+VIPS_CFLAGS="$VIPS_CFLAGS $GIFLIB_CFLAGS"
+VIPS_INCLUDES="$VIPS_INCLUDES $GIFLIB_INCLUDES"
+VIPS_LIBS="$VIPS_LIBS $GIFLIB_LIBS"
+
# Look for libspng first
# 0.6.1 uses "libspng.pc", git master libspng uses "spng.pc"
AC_ARG_WITH([libspng],
@@ -1067,6 +1139,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
@@ -1102,6 +1177,10 @@ if test x"$with_png" != x"no"; then
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)]))
@@ -1120,6 +1199,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)]))
@@ -1157,6 +1239,10 @@ if test x"$with_jpeg" != x"no"; then
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)]))
@@ -1184,6 +1270,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])
@@ -1191,14 +1280,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 $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 $GIFLIB_INCLUDES $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 $GIO_LIBS $REQUIRED_LIBS $EXPAT_LIBS $PANGOFT2_LIBS $GSF_LIBS $FFTW_LIBS $ORC_LIBS $LCMS_LIBS $GIFLIB_LIBS $RSVG_LIBS $NIFTI_LIBS $PDFIUM_LIBS $POPPLER_LIBS $OPENEXR_LIBS $OPENSLIDE_LIBS $CFITSIO_LIBS $LIBWEBP_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="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 support: $with_ppm, 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, file import with niftiio: $with_nifti, file import with libheif: $with_heif, file import with OpenEXR: $with_OpenEXR, file import with OpenSlide: $with_openslide, file import with matio: $with_matio, PDF import with PDFium: $with_pdfium, PDF import with poppler-glib: $with_poppler, SVG import with librsvg-2.0: $with_rsvg, zlib: $with_zlib, file import with cfitsio: $with_cfitsio, file import/export with libwebp: $with_libwebp, text rendering with pangoft2: $with_pangoft2, file import/export with libspng: $with_libspng, file import/export with libpng: $with_png, support 8bpp PNG quantisation: $with_imagequant, file import/export with libtiff: $with_tiff, file import/export with giflib: $with_giflib, file import/export 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, \
+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, \
+GIF load with giflib: $with_giflib, \
+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/save 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)
@@ -1261,51 +1383,53 @@ AC_OUTPUT
# also add any new items to VIPS_CONFIG above
AC_MSG_RESULT([dnl
-* build options
+## Build options
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 support: $with_ppm
-generate C++ docs: $with_doxygen
+gobject introspection: $found_introspection
+RAD load/save: $with_radiance
+Analyze7 load/save: $with_analyze
+PPM load/save: $with_ppm
+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
-file import with niftiio: $with_nifti
-file import with libheif: $with_heif
-file import with OpenEXR: $with_OpenEXR
-file import with OpenSlide: $with_openslide
- (requires openslide-3.3.0 or later)
-file import with matio: $with_matio
-PDF import with PDFium: $with_pdfium
-PDF import with poppler-glib: $with_poppler
- (requires poppler-glib 0.16.0 or later)
-SVG import with librsvg-2.0: $with_rsvg
- (requires librsvg-2.0 2.34.0 or later)
-zlib: $with_zlib
-file import with cfitsio: $with_cfitsio
-file import/export with libwebp: $with_libwebp
- (requires libwebp, libwebpmux, libwebpdemux 0.6.0 or later)
-text rendering with pangoft2: $with_pangoft2
-file import/export with libspng: $with_libspng
- (requires libspng-0.6 or later)
-file import/export with libpng: $with_png
- (requires libpng-1.2.9 or later)
-support 8bpp PNG quantisation: $with_imagequant
- (requires libimagequant)
-file import/export with libtiff: $with_tiff
-file import/export with giflib: $with_giflib
-file import/export 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
+
+## 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)
+GIF load with giflib: $with_giflib
+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/save 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
])
diff --git a/doc/binding.xml b/doc/binding.xml
index 956b0101..24e30f7b 100644
--- a/doc/binding.xml
+++ b/doc/binding.xml
@@ -19,10 +19,35 @@
Don’t bind the top-level C API
- 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.
- It’s 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:
+ It’s much better to use the layer below. This lower layer is structured as:
+
+
+
+
+ Create operator. You can use vips_operation_new() to make a new VipsOperation object from an operator nickname, like "add".
+
+
+
+
+ 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 GValue, then use g_object_set_property() to set that value on the operator.
+
+
+
+
+ Execute with vips_cache_operation_build().
+
+
+
+
+ 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.
+
+
+
+
+ For example, you can execute vips_invert() like this:
/* compile with
@@ -111,17 +136,11 @@ main( int argc, char **argv )
return( 0 );
}
-
- 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.
-
-
- Use vips_operation_get_flags() to get general information about an operator.
-
Compiled language which can call C
- The C++ binding uses this lower layer to define a function called VImage::call() 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 VImage::call() which can call any libvips operator with a set of variable arguments.
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 )
}
- So from C++ you can call any libvips operator (though without type-safety) with VImage::call(), or use the member functions on VImage 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 VImage::call(), or use the member functions on VImage to get type-checked calls for at least the required operator arguments.
The VImage 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 can’t 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.
- 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 Image 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 Image class as libvips operators. In effect, the binding is generated at runtime.
Dynamic langauge without FFI
- PHP does not have FFI, unfortunately, so for this language a small native module implements the general vips_call() 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 vips_call() function for PHP language types, and a larger pure PHP layer makes it convenient to use.