diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6f727e1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +m4/** linguist-generated=true linguist-vendored=true diff --git a/.gitignore b/.gitignore index 78afb67..56a1eaa 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ config.status config.sub configure configure.in +configure.ac include install-sh libtool @@ -29,9 +30,13 @@ missing mkinstalldirs modules run-tests.php +gen_stub.php tests/*/*.diff tests/*/*.out tests/*/*.php tests/*/*.exp tests/*/*.log tests/*/*.sh + +# Used by gen_stub.php +PHP-Parser-* diff --git a/API-0.1.2 b/API-1.0.0 similarity index 100% rename from API-0.1.2 rename to API-1.0.0 diff --git a/ChangeLog b/ChangeLog index 68f6c4e..53a912a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,89 @@ vips extension changelog +Version 1.0.13 (2022-2-xx) +-------------------------- + * php8 compatibility [kleisauke] + * improve module linking [kleisauke] + * improve packaging [kleisauke] + * add type hints [jcupitt, kleisauke] + +Version 1.0.12 (2020-8-xx) +-------------------------- + * vips_image_set_type() can be passed a type name + https://github.com/libvips/php-vips-ext/issues/38 + +Version 1.0.11 (2020-1-xx) +-------------------------- + * More php_info() output [jcupitt] + https://github.com/libvips/php-vips/issues/97 + * add vips_image_set_type() + * add vips_type_from_name() + +Version 1.0.10 (2018-12-xx) +-------------------------- + * Fix win32 build [TBK] + https://github.com/libvips/php-vips-ext/pull/24 + * Update links for new home [jcupitt] + * Add vips_image_write_to_array() [jcupitt] + https://github.com/libvips/php-vips/issues/90 + +Version 1.0.9 (2017-11-28) +-------------------------- + * Add cache and concurrency controls [chregu] + https://github.com/libvips/php-vips-ext/pull/17 + +Version 1.0.8 (2017-11-21) +-------------------------- + * Add vips_version() [chregu] + https://github.com/libvips/php-vips-ext/pull/15 + * Add vips_new_from_memory() / vips_write_to_memory() [kleisauke] + https://github.com/libvips/php-vips-ext/pull/13 + +Version 1.0.7 (2017-6-5) +-------------------------- + * Add vips_interpolate_new() + +Version 1.0.6 (2017-4-15) +-------------------------- + * Add vips_image_copy_memory() + +Version 1.0.5 (2017-3-11) +-------------------------- + * Use VIPS_SONAME, if we can + * More stuff in php_info() + https://github.com/libvips/php-vips/issues/32 + * Add vips_foreign_find_load() and vips_foreign_find_load_buffer() + https://github.com/libvips/php-vips/issues/37 + +Version 1.0.4 (2016-12-30) +-------------------------- + * Improve graceful fix from 1.0.3 + https://github.com/libvips/php-vips/issues/27 + * Better notes section in package.xml + https://github.com/libvips/php-vips/issues/28 + +Version 1.0.3 (2016-12-27) +-------------------------- + * Lower min vips version to 8.2, see #4 + * Lock libvips to fix graceful + https://github.com/libvips/php-vips/issues/26 + +Version 1.0.2 (2016-12-06) +-------------------------- + * vips_image_write_to_file() was not setting options, see #3 + +Version 1.0.1 (2016-11-25) +-------------------------- + * Fix for 7.1rc6 + +Version 1.0.0 (2016-11-24) +-------------------------- + * Update package for pecl upload + +Version 0.1.3 (2016-11-04) +-------------------------- + * Fix memleak + Version 0.1.2 (2016-10-24) -------------------------- * Always dereference REFERENCE zvalues diff --git a/README.md b/README.md index e187e65..6904080 100644 --- a/README.md +++ b/README.md @@ -1,108 +1,98 @@ # Low-level PHP binding for libvips -This extension lets you use the libvips image processing library from PHP. It is -intentionally very low-level. Modules such as -https://github.com/jcupitt/php-vips try to layer a nice API on -top of this. - -libvips is fast and it can work without needing to have the -entire image loaded into memory. Programs that use libvips don't -manipulate images directly, instead they create pipelines of image processing -operations starting from a source image. When the end of the pipe is connected -to a destination, the whole pipeline executes at once, streaming the image -in parallel from source to destination in a set of small fragments. - -See the [benchmarks at the official libvips -website](http://www.vips.ecs.soton.ac.uk/index.php?title=Speed_and_Memory_Use). -There's a handy blog post explaining [how libvips opens -files](http://libvips.blogspot.co.uk/2012/06/how-libvips-opens-file.html) -which gives some more background. +**This extension is deprecated** php-vips 2.0+ has switched to FFI for calls +into the libvips binary, so this extension is no longer necessary. It will not +be updated again (though it might still be useful if for some reason you don't +/ can't update to php-vips 2.0). + +This extension lets you use the libvips image processing library +from PHP 7 and PHP 8. + +This is not supposed to be used directly! Install this, then use +[php-vips 1.x](https://github.com/libvips/php-vips) to layer a nice (and +documented!) API on top of this extension. + +libvips is fast and needs little memory. The [`vips-php-bench`]( +https://github.com/jcupitt/php-vips-bench) repository tests +`php-vips` against `imagick` and `gd`: on that test, and on my laptop, +`php-vips` is around four times faster than `imagick` and needs 10 times less +memory. ### Example ```php #!/usr/bin/env php ``` Almost all operations return an array of result values. Usually there is a single result called `"out"`. Use `vips_call()` to call any operation in the vips library. There are around -around 300 operations available, see the vips docs for an -introduction: +around 300 operations available, see the vips docs for an introduction: -http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/ +http://libvips.github.io/libvips/API/current/ Arguments can be long, double, image, array of long, array of double or array of image. The final argument to `vips_call()` is an array of operation options. -### Preparation +`php-vips` layers a nice API, including full docs, on top of this extension, +see: -PHP is normally built for speed and is missing a lot of debugging support you -need for extension development. For testing and dev, build your own php. -I used 7.0.11 and configured with: +https://github.com/libvips/php-vips -``` -$ ./configure --prefix=/home/john/vips --enable-debug --enable-maintainer-zts \ - --enable-cgi --enable-cli --with-readline --with-openssl --with-zlib \ - --with-gd --with-jpeg-dir=/usr --with-libxml-dir=/usr -``` +### Installing -You'll need libvips 8.0 or later, including all the headers for -development. On linux, install with your package manager. On OS X, -install with `brew` or MacPorts. For Windows, download a zip from the -libvips website, or build your own. +First install the libvips library. It will be in your package manager on linux, +it's in brew and MacPorts on macOS, or the vips website has Windows binaries. -### Installing +Next, install this extension: ``` -$ pear install vips-0.1.2.tgz +$ pecl install vips ``` -to install. - -Add: +And add: ``` extension=vips.so ``` -to your `php.ini`, perhaps in `~/vips/lib/php.ini`, if you configured php as -above. +to your `php.ini`. -### Using +Finally, add `vips` to your `composer.json` to pull in the high-level PHP API. -Try: +``` + "require": { + "jcupitt/vips" : "1.0.0" + } +``` -```php -#!/usr/bin/env php - -``` +https://github.com/libvips/php-vips + +### Development: preparation -And run with: +PHP is normally built for speed and is missing a lot of debugging support you +need for extension development. For testing and dev, build your own php. +I used 7.0.11 and configured with: ``` -$ ./try1.php ~/pics/k2.jpg x.tif +$ ./configure --prefix=/home/john/vips --enable-debug --enable-maintainer-zts \ + --enable-cgi --enable-cli --with-readline --with-openssl --with-zlib \ + --with-gd --with-jpeg-dir=/usr --with-libxml-dir=/usr --enable-mbstring ``` -See `examples/`. +You'll need libvips 8.2 or later, including all the headers for +development. On linux, install with your package manager. On macOS, +install with `brew` or MacPorts. For Windows, download a zip from the +libvips website, or build your own. ### Development: regenerate build system @@ -110,7 +100,7 @@ See `examples/`. $ pear package ``` -to make `vips-0.1.2.tgz`. +To make `vips-1.0.13.tgz`. To install by hand: @@ -159,6 +149,18 @@ Finally, install to your php extensions area with: $ make install ``` +Add `extension=vips.so` to `php.ini`, perhaps in `~/vips/lib/php.ini`, +if you configured php as above. + +### Development: regenerate `vips_arginfo.h` + +Run: + +``` +$ curl -LO https://github.com/php/php-src/raw/ffacda14b88be797a466f472359f306d626e698f/build/gen_stub.php +$ php gen_stub.php +``` + ### Links http://php.net/manual/en/internals2.php diff --git a/RELEASE-0.1.2 b/RELEASE-0.1.2 deleted file mode 100644 index e69de29..0000000 diff --git a/EXPERIMENTAL b/RELEASE-1.0.13 similarity index 100% rename from EXPERIMENTAL rename to RELEASE-1.0.13 diff --git a/config.m4 b/config.m4 index 2dc0b4a..b72931e 100644 --- a/config.m4 +++ b/config.m4 @@ -1,10 +1,16 @@ dnl $Id$ dnl config.m4 for extension vips +m4_include(m4/ax_require_defined.m4) +m4_include(m4/ax_append_flag.m4) +m4_include(m4/ax_check_link_flag.m4) +m4_include(m4/ax_append_link_flags.m4) + PHP_ARG_WITH(vips, for vips support, [ --with-vips Include vips support]) -VIPS_MIN_VERSION=8.3 +# 8.2 added vips_bandjoin_const(), which php-vips needs +VIPS_MIN_VERSION=8.2 if test x"$PHP_VIPS" != x"no"; then if ! pkg-config --atleast-pkgconfig-version 0.2; then @@ -15,7 +21,7 @@ fi if test x"$PHP_VIPS" != x"no"; then if ! pkg-config vips --atleast-version $VIPS_MIN_VERSION; then - AC_MSG_ERROR([you need at least vips $VIPS_MIN_VERSION for this module]) + AC_MSG_ERROR([you need at least libvips $VIPS_MIN_VERSION for this module]) PHP_VIPS=no fi fi @@ -34,6 +40,10 @@ if test x"$PHP_VIPS" != x"no"; then ],[$VIPS_LIBS] ) + # Mark DSO non-deletable at runtime. + # See: https://github.com/libvips/php-vips-ext/issues/43 + AX_APPEND_LINK_FLAGS([-Wl,-z,nodelete]) + AC_DEFINE(HAVE_VIPS, 1, [Whether you have vips]) PHP_NEW_EXTENSION(vips, vips.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $VIPS_CFLAGS) PHP_SUBST(VIPS_SHARED_LIBADD) diff --git a/config.w32 b/config.w32 index 38e9dfc..618fded 100644 --- a/config.w32 +++ b/config.w32 @@ -4,6 +4,6 @@ ARG_WITH("vips", "for vips support", "no"); if (PHP_VIPS != "no") { - EXTENSION("vips", "vips.c", PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + EXTENSION("vips", "vips.c", PHP_VIPS_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); } diff --git a/examples/leaktest.php b/examples/leaktest.php new file mode 100755 index 0000000..b87f18f --- /dev/null +++ b/examples/leaktest.php @@ -0,0 +1,27 @@ +#!/usr/bin/env php + "sequential"])["out"]; + + $width = vips_image_get($x, "width")["out"]; + $height = vips_image_get($x, "height")["out"]; + + $x = vips_call("crop", $x, 100, 100, $width - 200, $height - 200)["out"]; + + vips_image_write_to_file($x, $argv[2]); + + $x = NULL; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: expandtab sw=4 ts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 + */ + diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..dd6d8b6 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,50 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AC_DEFUN([AX_APPEND_FLAG], +[dnl +AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) +AS_VAR_SET_IF(FLAGS,[ + AS_CASE([" AS_VAR_GET(FLAGS) "], + [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], + [ + AS_VAR_APPEND(FLAGS,[" $1"]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) + ], + [ + AS_VAR_SET(FLAGS,[$1]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 new file mode 100644 index 0000000..99b9fa5 --- /dev/null +++ b/m4/ax_append_link_flags.m4 @@ -0,0 +1,44 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the linker works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is +# used. During the check the flag is always added to the linker's flags. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. +# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_APPEND_LINK_FLAGS], +[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4]) +done +])dnl AX_APPEND_LINK_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..03a30ce --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 new file mode 100644 index 0000000..17c3eab --- /dev/null +++ b/m4/ax_require_defined.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_REQUIRE_DEFINED(MACRO) +# +# DESCRIPTION +# +# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have +# been defined and thus are available for use. This avoids random issues +# where a macro isn't expanded. Instead the configure script emits a +# non-fatal: +# +# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found +# +# It's like AC_REQUIRE except it doesn't expand the required macro. +# +# Here's an example: +# +# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +# +# LICENSE +# +# Copyright (c) 2014 Mike Frysinger +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_REQUIRE_DEFINED], [dnl + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED diff --git a/package.xml b/package.xml index 5f4a68d..6910e94 100644 --- a/package.xml +++ b/package.xml @@ -11,37 +11,48 @@ http://pear.php.net/dtd/package-2.0.xsd"> John Cupitt - john - jcupitt@gmail.com + jcupitt + jcupitt@php.net yes - 2016-10-20 + 2022-02-16 - 0.1.2 - 0.1.2 + 1.0.13 + 1.0.0 - alpha - alpha + stable + stable MIT -- First release. + * php8 compatibility [kleisauke] + * improve module linking [kleisauke] + * improve packaging [kleisauke] + * add type hints [jcupitt, kleisauke] - + - - + + + + + + + + + + @@ -66,10 +77,23 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + + + + + + + + + + + - - - + + + + @@ -89,7 +113,153 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + stablestable + 1.0.131.0.0 + 2022-02-16 + + * php8 compatibility [kleisauke] + * improve module linking [kleisauke] + * improve packaging [kleisauke] + * add type hints [jcupitt, kleisauke] + + + + + stablestable + 1.0.121.0.0 + 2020-08-29 + + * vips_image_set_type() can be passed a type name + + + + + stablestable + 1.0.111.0.0 + 2020-08-28 + + * add vips_image_set_type() + * More php_info() output [jcupitt] + + + + + stablestable + 1.0.101.0.0 + 2018-12-12 + + * Add vips_image_write_to_array() [jcupitt] + * Update links for new home [jcupitt] + * Fix win32 build [TBK] + + + + + stablestable + 1.0.91.0.0 + 2017-11-28 + + * Add cache and concurrency controls [chregu] + + + + + stablestable + 1.0.81.0.0 + 2017-11-22 + + * Add vips_version() [chregu] + * Add vips_new_from_memory() / vips_write_to_memory() [kleisauke] + + + + + stablestable + 1.0.71.0.0 + 2017-06-05 + + * Add vips_interpolate_new() + + + + stablestable + 1.0.61.0.0 + 2017-04-17 + + * Add vips_image_copy_memory() + + + + + stablestable + 1.0.51.0.0 + 2017-03-11 + + * Use VIPS_SONAME, if we can + * More stuff in php_info(), see https://github.com/libvips/php-vips/issues/32 + * Add vips_foreign_find_load() and vips_foreign_find_load_buffer(), see https://github.com/libvips/php-vips/issues/37 + + + + + stablestable + 1.0.41.0.0 + 2016-12-30 + + * Improve graceful fix from 1.0.3, see https://github.com/libvips/php-vips/issues/27 + * Better notes section in package.xml, see https://github.com/libvips/php-vips/issues/28 + + + + + stablestable + 1.0.31.0.0 + 2016-12-27 + + * Lower min vips version to 8.2, see #4 + * Lock libvips to fix graceful, see https://github.com/libvips/php-vips/issues/26 + + + + + stablestable + 1.0.21.0.0 + 2016-12-06 + + * vips_image_write_to_file() was not setting options, see #3 + + + + + stablestable + 1.0.11.0.0 + 2016-11-25 + + * Fix with 7.1rc6 + + + + + stablestable + 1.0.01.0.0 + 2016-11-24 + + * Update package for pecl upload + + + + + alphaalpha + 0.1.30.1.3 + 2016-11-5 + + * Fix memleak + + + + alphaalpha 0.1.20.1.2 2016-10-24 @@ -99,7 +269,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + alphaalpha 0.1.10.1.1 2016-10-20 @@ -116,7 +286,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + alphaalpha 0.1.00.1.0 2016-09-20 diff --git a/php_vips.h b/php_vips.h index 0710717..7f55f2a 100644 --- a/php_vips.h +++ b/php_vips.h @@ -5,7 +5,7 @@ extern zend_module_entry vips_module_entry; #define phpext_vips_ptr &vips_module_entry -#define PHP_VIPS_VERSION "0.1.2" /* Replace with version number for your extension */ +#define PHP_VIPS_VERSION "1.0.13" #ifdef PHP_WIN32 # define PHP_VIPS_API __declspec(dllexport) diff --git a/tests/031.phpt b/tests/031.phpt new file mode 100644 index 0000000..bef2817 --- /dev/null +++ b/tests/031.phpt @@ -0,0 +1,31 @@ +--TEST-- +write_to_file can set options +--SKIPIF-- + +--FILE-- + 20]); + vips_image_write_to_file($image, $output_filename2, ["Q" => 90]); + + $buffer1 = file_get_contents($output_filename1); + $buffer2 = file_get_contents($output_filename2); + + if (strlen($buffer1) < strlen($buffer2)) { + echo "pass"; + } +?> +--EXPECT-- +pass +--CLEAN-- + + diff --git a/tests/032.phpt b/tests/032.phpt new file mode 100644 index 0000000..2327a00 --- /dev/null +++ b/tests/032.phpt @@ -0,0 +1,17 @@ +--TEST-- +foreign_find_load_buffer works +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/033.phpt b/tests/033.phpt new file mode 100644 index 0000000..794a4a9 --- /dev/null +++ b/tests/033.phpt @@ -0,0 +1,16 @@ +--TEST-- +foreign_find_load works +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/034.phpt b/tests/034.phpt new file mode 100644 index 0000000..efe97f9 --- /dev/null +++ b/tests/034.phpt @@ -0,0 +1,19 @@ +--TEST-- +can copy to memory +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/035.phpt b/tests/035.phpt new file mode 100644 index 0000000..6923393 --- /dev/null +++ b/tests/035.phpt @@ -0,0 +1,14 @@ +--TEST-- +can make an interpolator +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/036.phpt b/tests/036.phpt new file mode 100644 index 0000000..8760748 --- /dev/null +++ b/tests/036.phpt @@ -0,0 +1,21 @@ +--TEST-- +can enlarge with a bicubic interpolator +--SKIPIF-- + +--FILE-- + $interp])["out"]; + + $w1 = vips_image_get($image1, "width")["out"]; + $wr = vips_image_get($sz, "width")["out"]; + + if ($w1 * 2 == $wr) { + echo "pass"; + } +?> +--EXPECT-- +pass diff --git a/tests/037.phpt b/tests/037.phpt new file mode 100644 index 0000000..cae8867 --- /dev/null +++ b/tests/037.phpt @@ -0,0 +1,24 @@ +--TEST-- +can make an image from memory +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass \ No newline at end of file diff --git a/tests/038.phpt b/tests/038.phpt new file mode 100644 index 0000000..e6f97b5 --- /dev/null +++ b/tests/038.phpt @@ -0,0 +1,16 @@ +--TEST-- +can write to memory +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/039.phpt b/tests/039.phpt new file mode 100644 index 0000000..4af19a8 --- /dev/null +++ b/tests/039.phpt @@ -0,0 +1,14 @@ +--TEST-- +can get version +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass diff --git a/tests/040.phpt b/tests/040.phpt new file mode 100644 index 0000000..9360142 --- /dev/null +++ b/tests/040.phpt @@ -0,0 +1,43 @@ +--TEST-- +can get info about cache and concurrency +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass vips_cache_get_max_mem +pass vips_cache_get_max_files +pass vips_cache_get_max +pass vips_cache_get_size +pass vips_concurrency_get diff --git a/tests/041.phpt b/tests/041.phpt new file mode 100644 index 0000000..18cae00 --- /dev/null +++ b/tests/041.phpt @@ -0,0 +1,34 @@ +--TEST-- +write_to_array works +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass array_size +pass pixel_value diff --git a/tests/042.phpt b/tests/042.phpt new file mode 100644 index 0000000..6332c48 --- /dev/null +++ b/tests/042.phpt @@ -0,0 +1,39 @@ +--TEST-- +can set metadata +--SKIPIF-- + +--FILE-- + +--EXPECT-- +pass set_metadata +pass reload +pass get_metadata +--CLEAN-- + + diff --git a/tests/images/sRGB.icc b/tests/images/sRGB.icc new file mode 100644 index 0000000..1d8f741 Binary files /dev/null and b/tests/images/sRGB.icc differ diff --git a/vips-0.1.3.tgz b/vips-0.1.3.tgz new file mode 100644 index 0000000..272e264 Binary files /dev/null and b/vips-0.1.3.tgz differ diff --git a/vips-1.0.0.tgz b/vips-1.0.0.tgz new file mode 100644 index 0000000..f605432 Binary files /dev/null and b/vips-1.0.0.tgz differ diff --git a/vips-1.0.1.tgz b/vips-1.0.1.tgz new file mode 100644 index 0000000..16e2d57 Binary files /dev/null and b/vips-1.0.1.tgz differ diff --git a/vips-1.0.10.tgz b/vips-1.0.10.tgz new file mode 100644 index 0000000..5de002a Binary files /dev/null and b/vips-1.0.10.tgz differ diff --git a/vips-1.0.11.tgz b/vips-1.0.11.tgz new file mode 100644 index 0000000..d3b6783 Binary files /dev/null and b/vips-1.0.11.tgz differ diff --git a/vips-1.0.12.tgz b/vips-1.0.12.tgz new file mode 100644 index 0000000..e7ed1c7 Binary files /dev/null and b/vips-1.0.12.tgz differ diff --git a/vips-1.0.13.tgz b/vips-1.0.13.tgz new file mode 100644 index 0000000..ad6695f Binary files /dev/null and b/vips-1.0.13.tgz differ diff --git a/vips-1.0.2.tgz b/vips-1.0.2.tgz new file mode 100644 index 0000000..850bf07 Binary files /dev/null and b/vips-1.0.2.tgz differ diff --git a/vips-1.0.3.tgz b/vips-1.0.3.tgz new file mode 100644 index 0000000..25888b2 Binary files /dev/null and b/vips-1.0.3.tgz differ diff --git a/vips-1.0.4.tgz b/vips-1.0.4.tgz new file mode 100644 index 0000000..ece3c8d Binary files /dev/null and b/vips-1.0.4.tgz differ diff --git a/vips-1.0.5.tgz b/vips-1.0.5.tgz new file mode 100644 index 0000000..8990550 Binary files /dev/null and b/vips-1.0.5.tgz differ diff --git a/vips-1.0.6.tgz b/vips-1.0.6.tgz new file mode 100644 index 0000000..791ccfe Binary files /dev/null and b/vips-1.0.6.tgz differ diff --git a/vips-1.0.7.tgz b/vips-1.0.7.tgz new file mode 100644 index 0000000..5853d09 Binary files /dev/null and b/vips-1.0.7.tgz differ diff --git a/vips-1.0.8.tgz b/vips-1.0.8.tgz new file mode 100644 index 0000000..e50a48d Binary files /dev/null and b/vips-1.0.8.tgz differ diff --git a/vips-1.0.9.tgz b/vips-1.0.9.tgz new file mode 100644 index 0000000..0713759 Binary files /dev/null and b/vips-1.0.9.tgz differ diff --git a/vips.c b/vips.c index c101b4c..3048ce6 100644 --- a/vips.c +++ b/vips.c @@ -17,11 +17,50 @@ #include #include +#include /* If you declare any globals in php_vips.h uncomment this: ZEND_DECLARE_MODULE_GLOBALS(vips) */ +/* backward compat macros */ + +#ifndef IS_VOID +# define IS_VOID 0 +#endif /* !defined(IS_VOID) */ + +#ifndef IS_MIXED +# define IS_MIXED 0 +#endif /* !defined(IS_MIXED) */ + +#ifndef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX +# define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, num_args, type) \ + ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, num_args) +#endif /* !defined(ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX) */ + +#ifndef ZEND_ARG_TYPE_MASK +# define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \ + ZEND_ARG_TYPE_INFO(pass_by_ref, name, 0, 0) +#endif /* !defined(ZEND_ARG_TYPE_MASK) */ + +#ifndef ZEND_ARG_VARIADIC_TYPE_INFO +# define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, NULL, type_hint, pass_by_ref, allow_null, 1 }, +#endif /* !defined(ZEND_ARG_VARIADIC_TYPE_INFO) */ + +#ifndef ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE +# define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \ + ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) +#endif /* !defined(ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE) */ + +#if PHP_VERSION_ID < 70200 +# undef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX +# define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \ + static const zend_internal_arg_info name[] = { \ + { (const char*)(zend_uintptr_t)(required_num_args), ( #class_name ), 0, return_reference, allow_null, 0 }, +#endif /* PHP_VERSION_ID < 70200 */ + +#include "vips_arginfo.h" + /* True global resources - no need for thread safety here */ static int le_gobject; @@ -566,7 +605,8 @@ vips_php_zval_to_gval(VipsImage *match_image, zval *zvalue, GValue *gvalue) } static int -vips_php_set_value(VipsPhpCall *call, GParamSpec *pspec, zval *zvalue) +vips_php_set_value(VipsPhpCall *call, + GParamSpec *pspec, VipsArgumentFlags flags, zval *zvalue) { const char *name = g_param_spec_get_name(pspec); GType pspec_type = G_PARAM_SPEC_VALUE_TYPE(pspec); @@ -581,7 +621,8 @@ vips_php_set_value(VipsPhpCall *call, GParamSpec *pspec, zval *zvalue) /* If we are setting a MODIFY VipsArgument with an image, we need to take a * copy. */ - if (g_type_is_a(pspec_type, VIPS_TYPE_IMAGE)) { + if (g_type_is_a(pspec_type, VIPS_TYPE_IMAGE) && + (flags & VIPS_ARGUMENT_MODIFY)) { VipsImage *image; VipsImage *memory; @@ -647,7 +688,7 @@ vips_php_set_required_input(VipsObject *object, } if (arg && - vips_php_set_value(call, pspec, arg)) { + vips_php_set_value(call, pspec, argument_class->flags, arg)) { return call; } } @@ -686,7 +727,7 @@ vips_php_set_optional_input(VipsPhpCall *call, zval *options) if (!(argument_class->flags & VIPS_ARGUMENT_REQUIRED) && (argument_class->flags & VIPS_ARGUMENT_INPUT) && !(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) && - vips_php_set_value(call, pspec, value)) { + vips_php_set_value(call, pspec, argument_class->flags, value)) { return -1; } } ZEND_HASH_FOREACH_END(); @@ -891,6 +932,13 @@ vips_php_get_optional_output(VipsPhpCall *call, zval *options, continue; } + /* value should always be TRUE. + */ + value = zval_get_nonref(value); + if (Z_TYPE_P(value) != IS_TRUE) { + continue; + } + name = ZSTR_VAL(key); if (vips_object_get_argument(VIPS_OBJECT(call->operation), name, &pspec, &argument_class, &argument_instance)) { @@ -1036,7 +1084,7 @@ vips_php_call_array(const char *operation_name, zval *instance, /* }}} */ -/* {{{ proto mixed vips_php_call(string operation_name, resource instance [, more]) +/* {{{ proto array|long vips_call(string operation_name, resource instance [, mixed args]) Call any vips operation */ PHP_FUNCTION(vips_call) @@ -1046,7 +1094,6 @@ PHP_FUNCTION(vips_call) char *operation_name; size_t operation_name_len; zval *instance; - int i; VIPS_DEBUG_MSG("vips_call:\n"); @@ -1084,7 +1131,7 @@ PHP_FUNCTION(vips_call) } /* }}} */ -/* {{{ proto resource vips_image_new_from_file(string filename [, array options]) +/* {{{ proto array|long vips_image_new_from_file(string filename [, array options]) Open an image from a filename */ PHP_FUNCTION(vips_image_new_from_file) { @@ -1128,7 +1175,7 @@ PHP_FUNCTION(vips_image_new_from_file) } /* }}} */ -/* {{{ proto resource vips_image_new_from_buffer(string buffer [, string option_string, array options]) +/* {{{ proto array|long vips_image_new_from_buffer(string buffer [, string option_string, array options]) Open an image from a string */ PHP_FUNCTION(vips_image_new_from_buffer) { @@ -1182,7 +1229,7 @@ PHP_FUNCTION(vips_image_new_from_array) int width; int height; VipsImage *mat; - int x, y; + int x; zval *row; VIPS_DEBUG_MSG("vips_image_new_from_array:\n"); @@ -1227,7 +1274,30 @@ PHP_FUNCTION(vips_image_new_from_array) } /* }}} */ -/* {{{ proto long vips_image_write_to_file(resource image, string filename [, array options]) +/* {{{ proto resource vips_interpolate_new(string name) + make a new interpolator */ +PHP_FUNCTION(vips_interpolate_new) +{ + char *name; + size_t name_len; + VipsInterpolate *interp; + + VIPS_DEBUG_MSG("vips_interpolate_new:\n"); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p", + &name, &name_len) == FAILURE) { + return; + } + VIPS_DEBUG_MSG("vips_interpolate_new: name = %s\n", name); + + if (!(interp = vips_interpolate_new(name))) + return; + + RETURN_RES(zend_register_resource(interp, le_gobject)); +} +/* }}} */ + +/* {{{ proto array|long vips_image_write_to_file(resource image, string filename [, array options]) Write an image to a filename */ PHP_FUNCTION(vips_image_write_to_file) { @@ -1236,6 +1306,13 @@ PHP_FUNCTION(vips_image_write_to_file) size_t filename_len; zval *options = NULL; VipsImage *image; + char path_string[VIPS_PATH_MAX]; + char option_string[VIPS_PATH_MAX]; + const char *operation_name; + zval argv[2]; + int argc; + + VIPS_DEBUG_MSG("vips_image_write_to_file:\n"); if (zend_parse_parameters(ZEND_NUM_ARGS(), "rp|a", &IM, &filename, &filename_len, &options) == FAILURE) { @@ -1247,15 +1324,31 @@ PHP_FUNCTION(vips_image_write_to_file) RETURN_LONG(-1); } - if (vips_image_write_to_file(image, filename, NULL)) { + VIPS_DEBUG_MSG("\t%p -> %s\n", image, filename); + + vips__filename_split8(filename, path_string, option_string); + if (!(operation_name = vips_foreign_find_save(path_string))) { RETURN_LONG(-1); } - RETURN_LONG(0); + ZVAL_STRINGL(&argv[0], filename, filename_len); + argc = 1; + if (options) { + ZVAL_ARR(&argv[1], Z_ARR_P(options)); + argc += 1; + } + + if (vips_php_call_array(operation_name, IM, + option_string, argc, argv, return_value)) { + zval_dtor(&argv[0]); + RETURN_LONG(-1); + } + + zval_dtor(&argv[0]); } /* }}} */ -/* {{{ proto string|long vips_image_write_to_buffer(resource image, string suffix [, array options]) +/* {{{ proto array|long vips_image_write_to_buffer(resource image, string suffix [, array options]) Write an image to a string */ PHP_FUNCTION(vips_image_write_to_buffer) { @@ -1298,7 +1391,241 @@ PHP_FUNCTION(vips_image_write_to_buffer) } /* }}} */ -/* {{{ proto array vips_image_get(resource image, string field) +/* {{{ proto array|long vips_image_copy_memory(resource image) + Copy an image to a memory image */ +PHP_FUNCTION(vips_image_copy_memory) +{ + zval *IM; + VipsImage *image; + VipsImage *new_image; + zend_resource *resource; + zval zvalue; + + VIPS_DEBUG_MSG("vips_image_copy_memory:\n"); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) { + RETURN_LONG(-1); + } + + if ((image = (VipsImage *)zend_fetch_resource(Z_RES_P(IM), + "GObject", le_gobject)) == NULL) { + RETURN_LONG(-1); + } + + if (!(new_image = vips_image_copy_memory(image))) { + RETURN_LONG(-1); + } + + /* Return as an array for all OK, -1 for error. + */ + array_init(return_value); + resource = zend_register_resource(new_image, le_gobject); + ZVAL_RES(&zvalue, resource); + add_assoc_zval(return_value, "out", &zvalue); +} +/* }}} */ + +/* {{{ proto array|long vips_image_new_from_memory(string memory, integer width, integer height, integer bands, string format) + Wrap an image around a memory array. */ +PHP_FUNCTION(vips_image_new_from_memory) +{ + char *bstr; + size_t bstr_len; + long width; + long height; + long bands; + char *format; + size_t format_len; + int format_value; + VipsBandFormat band_format; + VipsImage *image; + zend_resource *resource; + zval zvalue; + + VIPS_DEBUG_MSG("vips_image_new_from_memory:\n"); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "slllp", + &bstr, &bstr_len, &width, &height, &bands, &format, &format_len) == FAILURE) { + RETURN_LONG(-1); + } + + if ((format_value = vips_enum_from_nick("php-vips", VIPS_TYPE_BAND_FORMAT, format)) < 0) { + RETURN_LONG(-1); + } + band_format = format_value; + + if (!(image = vips_image_new_from_memory_copy(bstr, bstr_len, width, height, bands, + band_format))) { + RETURN_LONG(-1); + } + + /* Return as an array for all OK, -1 for error. + */ + array_init(return_value); + resource = zend_register_resource(image, le_gobject); + ZVAL_RES(&zvalue, resource); + add_assoc_zval(return_value, "out", &zvalue); +} +/* }}} */ + +/* {{{ proto string|long vips_image_write_to_memory(resource image) + Write an image to a memory array. */ +PHP_FUNCTION(vips_image_write_to_memory) +{ + zval *IM; + VipsImage *image; + size_t arr_len; + uint8_t *arr; + + VIPS_DEBUG_MSG("vips_image_write_to_memory:\n"); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) { + RETURN_LONG(-1); + } + + if ((image = (VipsImage *)zend_fetch_resource(Z_RES_P(IM), + "GObject", le_gobject)) == NULL) { + RETURN_LONG(-1); + } + + if (!(arr = vips_image_write_to_memory(image, &arr_len))) { + RETURN_LONG(-1); + } + + RETVAL_STRINGL((char *)arr, arr_len); + + g_free(arr); +} +/* }}} */ + +#define ADD_ELEMENTS(TYPE, APPEND, N) { \ + TYPE *p = (TYPE *) arr; \ + size_t i; \ + \ + for (i = 0; i < (N); i++) \ + APPEND(return_value, p[i]); \ +} + +/* {{{ proto array|long vips_image_write_to_array(resource image) + Write an image to a PHP array. */ +PHP_FUNCTION(vips_image_write_to_array) +{ + zval *IM; + VipsImage *image; + size_t arr_len; + uint8_t *arr; + size_t n; + + VIPS_DEBUG_MSG("vips_image_write_to_array:\n"); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &IM) == FAILURE) { + RETURN_LONG(-1); + } + + if ((image = (VipsImage *)zend_fetch_resource(Z_RES_P(IM), + "GObject", le_gobject)) == NULL) { + RETURN_LONG(-1); + } + + if (!(arr = vips_image_write_to_memory(image, &arr_len))) { + RETURN_LONG(-1); + } + + array_init(return_value); + n = arr_len / vips_format_sizeof(image->BandFmt); + g_assert(arr_len % vips_format_sizeof(image->BandFmt) == 0); + switch (image->BandFmt) { + case VIPS_FORMAT_UCHAR: + ADD_ELEMENTS (unsigned char, add_next_index_long, n); + break; + + case VIPS_FORMAT_CHAR: + ADD_ELEMENTS (signed char, add_next_index_long, n); + break; + + case VIPS_FORMAT_USHORT: + ADD_ELEMENTS (unsigned short, add_next_index_long, n); + break; + + case VIPS_FORMAT_SHORT: + ADD_ELEMENTS (signed short, add_next_index_long, n); + break; + + case VIPS_FORMAT_UINT: + ADD_ELEMENTS (unsigned int, add_next_index_long, n); + break; + + case VIPS_FORMAT_INT: + ADD_ELEMENTS (signed int, add_next_index_long, n); + break; + + case VIPS_FORMAT_FLOAT: + ADD_ELEMENTS (float, add_next_index_double, n); + break; + + case VIPS_FORMAT_DOUBLE: + ADD_ELEMENTS (double, add_next_index_double, n); + break; + + case VIPS_FORMAT_COMPLEX: + ADD_ELEMENTS (float, add_next_index_double, n * 2); + break; + + case VIPS_FORMAT_DPCOMPLEX: + ADD_ELEMENTS (double, add_next_index_double, n * 2); + break; + + default: + break; + } + + g_free(arr); +} +/* }}} */ + +/* {{{ proto string|long vips_foreign_find_load(string filename) + Find a loader for a file */ +PHP_FUNCTION(vips_foreign_find_load) +{ + char *filename; + size_t filename_len; + const char *operation_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &filename, &filename_len) == FAILURE) { + RETURN_LONG(-1); + } + + if (!(operation_name = vips_foreign_find_load(filename))) { + RETURN_LONG(-1); + } + + RETVAL_STRING(strdup(operation_name)); +} +/* }}} */ + +/* {{{ proto string|long vips_foreign_find_load_buffer(string buffer) + Find a loader for a buffer */ +PHP_FUNCTION(vips_foreign_find_load_buffer) +{ + char *buffer; + size_t buffer_len; + const char *operation_name; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &buffer, &buffer_len) == FAILURE) { + RETURN_LONG(-1); + } + + if (!(operation_name = vips_foreign_find_load_buffer(buffer, buffer_len))) { + RETURN_LONG(-1); + } + + RETVAL_STRING(strdup(operation_name)); +} +/* }}} */ + +/* {{{ proto array|long vips_image_get(resource image, string field) Fetch field from image */ PHP_FUNCTION(vips_image_get) { @@ -1376,6 +1703,7 @@ PHP_FUNCTION(vips_image_get_typeof) } /* }}} */ + /* {{{ proto long vips_image_set(resource image, string field, mixed value) Set field on image */ PHP_FUNCTION(vips_image_set) @@ -1469,6 +1797,79 @@ PHP_FUNCTION(vips_image_set) } /* }}} */ +/* {{{ proto long vips_type_from_name(string name) + find the gtype for a type name */ +PHP_FUNCTION(vips_type_from_name) +{ + char *name; + size_t name_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &name, &name_len) == FAILURE) { + RETURN_LONG(-1); + } + + RETURN_LONG(g_type_from_name(name)); +} +/* }}} */ + +/* {{{ proto long vips_image_set_type(resource image, integer|string type, string field, mixed value) + Set field on image */ +PHP_FUNCTION(vips_image_set_type) +{ + zval *im; + zval *type; + char *field_name; + size_t field_name_len; + zval *zvalue; + VipsImage *image; + GType gtype; + GValue gvalue = { 0 }; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rzsz", + &im, &type, &field_name, &field_name_len, &zvalue) == FAILURE) { + RETURN_LONG(-1); + } + + if ((image = (VipsImage *)zend_fetch_resource(Z_RES_P(im), + "GObject", le_gobject)) == NULL) { + RETURN_LONG(-1); + } + + switch (Z_TYPE_P(type)) { + case IS_LONG: + /* On 32-bit platforms, PHP's long is only 32-bits, so it can't + * hold a GType. We need to be able accept string as well. + */ + gtype = zval_get_long(type); + break; + + case IS_STRING: + gtype = g_type_from_name(ZSTR_VAL(zval_get_string(type))); + break; + + default: + gtype = 0; + } + + if (gtype <= 0) { + RETURN_LONG(-1); + } + + g_value_init(&gvalue, gtype); + + if (vips_php_zval_to_gval(NULL, zvalue, &gvalue)) { + RETURN_LONG(-1); + } + + vips_image_set(image, field_name, &gvalue); + + g_value_unset(&gvalue); + + RETURN_LONG(0); +} +/* }}} */ + /* {{{ proto long vips_image_remove(resource image, string field) Remove field from image */ PHP_FUNCTION(vips_image_remove) @@ -1477,7 +1878,6 @@ PHP_FUNCTION(vips_image_remove) char *field_name; size_t field_name_len; VipsImage *image; - GType type; if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs", &im, &field_name, &field_name_len) == FAILURE) { @@ -1566,6 +1966,58 @@ PHP_FUNCTION(vips_concurrency_set) } /* }}} */ +/* {{{ proto string vips_version() + Returns the version number of the vips library */ +PHP_FUNCTION(vips_version) +{ + char digits[256]; + + g_snprintf(digits, 256, "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2)); + + RETVAL_STRING(digits); +} +/* }}} */ + +/* {{{ proto integer vips_cache_get_max_mem() + Get max memory to use for operation cache */ +PHP_FUNCTION(vips_cache_get_max_mem) +{ + RETURN_LONG(vips_cache_get_max_mem()); +} +/* }}} */ + +/* {{{ proto integer vips_cache_get_max_files() + Get max number of open files for operation cache */ +PHP_FUNCTION(vips_cache_get_max_files) +{ + RETURN_LONG(vips_cache_get_max_files()); +} +/* }}} */ + +/* {{{ proto integer vips_cache_get_max() + Get max number of operations to cache */ +PHP_FUNCTION(vips_cache_get_max) +{ + RETURN_LONG(vips_cache_get_max()); +} +/* }}} */ + +/* {{{ proto integer vips_cache_get_size() + Get current cached operations */ +PHP_FUNCTION(vips_cache_get_size) +{ + RETURN_LONG(vips_cache_get_size()); +} +/* }}} */ + +/* {{{ proto integer vips_concurrency_get() + Get number of workers per threadpool */ +PHP_FUNCTION(vips_concurrency_get) +{ + RETURN_LONG(vips_concurrency_get()); +} +/* }}} */ + /* {{{ php_vips_init_globals */ /* Uncomment this function if you have INI entries @@ -1606,6 +2058,12 @@ PHP_MINIT_FUNCTION(vips) le_gobject = zend_register_list_destructors_ex(php_free_gobject, NULL, "GObject", module_number); +#ifdef VIPS_DEBUG + printf( "php-vips-ext init\n" ); + printf( "enabling vips leak testing ...\n" ); + vips_leak_set( TRUE ); +#endif /*VIPS_DEBUG*/ + return SUCCESS; } /* }}} */ @@ -1618,7 +2076,13 @@ PHP_MSHUTDOWN_FUNCTION(vips) UNREGISTER_INI_ENTRIES(); */ - vips_shutdown(); +#ifdef VIPS_DEBUG + printf( "php-vips-ext shutdown\n" ); +#endif /*VIPS_DEBUG*/ + + /* We must not call vips_shutdown() since we've locked libvips in memory + * and will need to reuse it if we restart via graceful. + */ return SUCCESS; } @@ -1649,8 +2113,81 @@ PHP_RSHUTDOWN_FUNCTION(vips) */ PHP_MINFO_FUNCTION(vips) { + char digits[256]; + php_info_print_table_start(); - php_info_print_table_header(2, "vips support", "enabled"); + php_info_print_table_header(2, "vips property", "value"); + + g_snprintf(digits, 256, "%d.%d.%d", VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION, VIPS_MICRO_VERSION); + php_info_print_table_row(2, "Vips headers version", digits); + g_snprintf(digits, 256, "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2)); + php_info_print_table_row(2, "Vips library version", digits); + g_snprintf(digits, 256, "%d.%d.%d", vips_version(3), vips_version(4), vips_version(5)); + php_info_print_table_row(2, "Vips ABI version", digits); + + g_snprintf(digits, 256, "%d", vips_version(0)); + php_info_print_table_row(2, "Major version", digits); + g_snprintf(digits, 256, "%d", vips_version(1)); + php_info_print_table_row(2, "Minor version", digits); + g_snprintf(digits, 256, "%d", vips_version(2)); + php_info_print_table_row(2, "Micro version", digits); + + g_snprintf(digits, 256, "%zd", vips_cache_get_max_mem()); + php_info_print_table_row(2, "Cache max mem", digits); + g_snprintf(digits, 256, "%d", vips_cache_get_max()); + php_info_print_table_row(2, "Cache max operations", digits); + g_snprintf(digits, 256, "%d", vips_cache_get_size()); + php_info_print_table_row(2, "Cache current operations", digits); + g_snprintf(digits, 256, "%d", vips_cache_get_max_files()); + php_info_print_table_row(2, "Cache max open files", digits); + + g_snprintf(digits, 256, "%d", vips_tracked_get_allocs()); + php_info_print_table_row(2, "Memory allocations", digits); + g_snprintf(digits, 256, "%zd", vips_tracked_get_mem()); + php_info_print_table_row(2, "Memory currently allocated", digits); + g_snprintf(digits, 256, "%zd", vips_tracked_get_mem_highwater()); + php_info_print_table_row(2, "Memory high water", digits); + + g_snprintf(digits, 256, "%d", vips_concurrency_get()); + php_info_print_table_row(2, "Concurrency", digits); + + php_info_print_table_row(2, "SIMD support with liborc", + vips_vector_isenabled() ? "yes" : "no" ); + + php_info_print_table_row(2, "JPEG support", + vips_type_find("VipsOperation", "jpegload") ? "yes" : "no" ); + php_info_print_table_row(2, "PNG support", + vips_type_find("VipsOperation", "pngload") ? "yes" : "no" ); + php_info_print_table_row(2, "TIFF support", + vips_type_find("VipsOperation", "tiffload") ? "yes" : "no" ); + php_info_print_table_row(2, "GIF support", + vips_type_find("VipsOperation", "gifload") ? "yes" : "no" ); + php_info_print_table_row(2, "OpenEXR support", + vips_type_find("VipsOperation", "openexrload") ? "yes" : "no" ); + php_info_print_table_row(2, "load OpenSlide", + vips_type_find("VipsOperation", "openslideload") ? "yes" : "no" ); + php_info_print_table_row(2, "load Matlab", + vips_type_find("VipsOperation", "matload") ? "yes" : "no" ); + php_info_print_table_row(2, "load PDF", + vips_type_find("VipsOperation", "pdfload") ? "yes" : "no" ); + php_info_print_table_row(2, "load SVG", + vips_type_find("VipsOperation", "svgload") ? "yes" : "no" ); + php_info_print_table_row(2, "FITS support", + vips_type_find("VipsOperation", "fitsload") ? "yes" : "no" ); + php_info_print_table_row(2, "WebP support", + vips_type_find("VipsOperation", "webpload") ? "yes" : "no" ); + php_info_print_table_row(2, "HEIF support", + vips_type_find("VipsOperation", "heifload") ? "yes" : "no" ); + + php_info_print_table_row(2, "load with libMagick", + vips_type_find("VipsOperation", "magickload") ? "yes" : "no" ); + + php_info_print_table_row(2, "Text rendering support", + vips_type_find("VipsOperation", "text") ? "yes" : "no" ); + + php_info_print_table_row(2, "ICC profile support with lcms", + vips_icc_present() ? "yes" : "no" ); + php_info_print_table_end(); /* Remove comments if you have entries in php.ini @@ -1659,110 +2196,12 @@ PHP_MINFO_FUNCTION(vips) } /* }}} */ -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_new_from_file, 0) - ZEND_ARG_INFO(0, filename) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_new_from_buffer, 0) - ZEND_ARG_INFO(0, buffer) - ZEND_ARG_INFO(0, option_string) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_new_from_array, 0) - ZEND_ARG_INFO(0, array) - ZEND_ARG_INFO(0, scale) - ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_write_to_file, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, filename) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_write_to_buffer, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_call, 0) - ZEND_ARG_INFO(0, operation_name) - ZEND_ARG_INFO(0, instance) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_get, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, field) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_get_typeof, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, field) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_set, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, field) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_image_remove, 0) - ZEND_ARG_INFO(0, image) - ZEND_ARG_INFO(0, field) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_error_buffer, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_cache_set_max, 0) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_cache_set_max_mem, 0) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_cache_set_max_files, 0) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_vips_concurrency_set, 0) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -/* {{{ vips_functions[] - * - * Every user visible function must have an entry in vips_functions[]. - */ -const zend_function_entry vips_functions[] = { - PHP_FE(vips_image_new_from_file, arginfo_vips_image_new_from_file) - PHP_FE(vips_image_new_from_buffer, arginfo_vips_image_new_from_buffer) - PHP_FE(vips_image_new_from_array, arginfo_vips_image_new_from_array) - PHP_FE(vips_image_write_to_file, arginfo_vips_image_write_to_file) - PHP_FE(vips_image_write_to_buffer, arginfo_vips_image_write_to_buffer) - PHP_FE(vips_call, arginfo_vips_call) - PHP_FE(vips_image_get, arginfo_vips_image_get) - PHP_FE(vips_image_get_typeof, arginfo_vips_image_get_typeof) - PHP_FE(vips_image_set, arginfo_vips_image_set) - PHP_FE(vips_image_remove, arginfo_vips_image_remove) - PHP_FE(vips_error_buffer, arginfo_vips_error_buffer) - PHP_FE(vips_cache_set_max, arginfo_vips_cache_set_max) - PHP_FE(vips_cache_set_max_mem, arginfo_vips_cache_set_max_mem) - PHP_FE(vips_cache_set_max_files, arginfo_vips_cache_set_max_files) - PHP_FE(vips_concurrency_set, arginfo_vips_concurrency_set) - - PHP_FE_END /* Must be the last line in vips_functions[] */ -}; -/* }}} */ - /* {{{ vips_module_entry */ zend_module_entry vips_module_entry = { STANDARD_MODULE_HEADER, "vips", - vips_functions, + ext_functions, PHP_MINIT(vips), PHP_MSHUTDOWN(vips), PHP_RINIT(vips), /* Replace with NULL if there's nothing to do at request start */ diff --git a/vips.stub.php b/vips.stub.php new file mode 100644 index 0000000..2638f0f --- /dev/null +++ b/vips.stub.php @@ -0,0 +1,117 @@ +|int + */ +function vips_image_new_from_file(string $filename, ?array $options = []): array|int {} + +/** + * @return array|int + */ +function vips_image_new_from_buffer(string $buffer, ?string $option_string = "", ?array $options = []): array|int {} + +/** + * @return resource + */ +function vips_image_new_from_array(array $array, ?float $scale = 1.0, ?float $offset = 0.0) {} + +/** + * @param resource $image + * @return array|int + */ +function vips_image_write_to_file($image, string $filename, ?array $options = []): array|int {} + +/** + * @param resource $image + * @return array|int + */ +function vips_image_write_to_buffer($image, string $suffix, ?array $options = []): array|int {} + +/** + * @param resource $image + * @return array|int + */ +function vips_image_copy_memory($image): array|int {} + +/** + * @return array|int + */ +function vips_image_new_from_memory(string $memory, int $width, int $height, int $bands, string $format): array|int {} + +/** + * @param resource $image + */ +function vips_image_write_to_memory($image): string|int {} + +/** + * @param resource $image + * @return array|int + */ +function vips_image_write_to_array($image): array|int {} + +function vips_foreign_find_load(string $filename): string|int {} + +function vips_foreign_find_load_buffer(string $buffer): string|int {} + +/** + * @return resource + */ +function vips_interpolate_new(string $name) {} + +/** + * @param resource $instance + * @return array|int + */ +function vips_call(string $operation_name, $instance, mixed ...$args): array|int {} + +/** + * @param resource $image + * @return array|int + */ +function vips_image_get($image, string $field): array|int {} + +/** + * @param resource $image + */ +function vips_image_get_typeof($image, string $field): int {} + +/** + * @param resource $image + */ +function vips_image_set($image, string $field, mixed $value): int {} + +function vips_type_from_name(string $name): int {} + +/** + * @param resource $image + */ +function vips_image_set_type($image, string|int $type, string $field, mixed $value): int {} + +/** + * @param resource $image + */ +function vips_image_remove($image, string $field): int {} + +function vips_error_buffer(): string {} + +function vips_cache_set_max(int $value): void {} + +function vips_cache_set_max_mem(int $value): void {} + +function vips_cache_set_max_files(int $value): void {} + +function vips_concurrency_set(int $value): void {} + +function vips_cache_get_max(): int {} + +function vips_cache_get_max_mem(): int {} + +function vips_cache_get_max_files(): int {} + +function vips_cache_get_size(): int {} + +function vips_concurrency_get(): int {} + +function vips_version(): string {} diff --git a/vips_arginfo.h b/vips_arginfo.h new file mode 100644 index 0000000..4d17580 --- /dev/null +++ b/vips_arginfo.h @@ -0,0 +1,189 @@ +/* This is a generated file, edit the .stub.php file instead. + * Stub hash: b0a895aa400527f647c2f9bd728c4e8a94cb0c9b */ + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_new_from_file, 0, 1, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "[]") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_new_from_buffer, 0, 1, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, buffer, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, option_string, IS_STRING, 1, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "[]") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_vips_image_new_from_array, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, scale, IS_DOUBLE, 1, "1.0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_DOUBLE, 1, "0.0") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_write_to_file, 0, 2, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "[]") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_write_to_buffer, 0, 2, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_INFO(0, suffix, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "[]") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_copy_memory, 0, 1, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_INFO(0, image) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_new_from_memory, 0, 5, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, memory, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, width, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, height, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, bands, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_write_to_memory, 0, 1, MAY_BE_STRING|MAY_BE_LONG) + ZEND_ARG_INFO(0, image) +ZEND_END_ARG_INFO() + +#define arginfo_vips_image_write_to_array arginfo_vips_image_copy_memory + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_foreign_find_load, 0, 1, MAY_BE_STRING|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_foreign_find_load_buffer, 0, 1, MAY_BE_STRING|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, buffer, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_vips_interpolate_new, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_call, 0, 2, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_TYPE_INFO(0, operation_name, IS_STRING, 0) + ZEND_ARG_INFO(0, instance) + ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_vips_image_get, 0, 2, MAY_BE_ARRAY|MAY_BE_LONG) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_image_get_typeof, 0, 2, IS_LONG, 0) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_image_set, 0, 3, IS_LONG, 0) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_type_from_name, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_image_set_type, 0, 4, IS_LONG, 0) + ZEND_ARG_INFO(0, image) + ZEND_ARG_TYPE_MASK(0, type, MAY_BE_STRING|MAY_BE_LONG, NULL) + ZEND_ARG_TYPE_INFO(0, field, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) +ZEND_END_ARG_INFO() + +#define arginfo_vips_image_remove arginfo_vips_image_get_typeof + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_error_buffer, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_cache_set_max, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_vips_cache_set_max_mem arginfo_vips_cache_set_max + +#define arginfo_vips_cache_set_max_files arginfo_vips_cache_set_max + +#define arginfo_vips_concurrency_set arginfo_vips_cache_set_max + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vips_cache_get_max, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_vips_cache_get_max_mem arginfo_vips_cache_get_max + +#define arginfo_vips_cache_get_max_files arginfo_vips_cache_get_max + +#define arginfo_vips_cache_get_size arginfo_vips_cache_get_max + +#define arginfo_vips_concurrency_get arginfo_vips_cache_get_max + +#define arginfo_vips_version arginfo_vips_error_buffer + + +ZEND_FUNCTION(vips_image_new_from_file); +ZEND_FUNCTION(vips_image_new_from_buffer); +ZEND_FUNCTION(vips_image_new_from_array); +ZEND_FUNCTION(vips_image_write_to_file); +ZEND_FUNCTION(vips_image_write_to_buffer); +ZEND_FUNCTION(vips_image_copy_memory); +ZEND_FUNCTION(vips_image_new_from_memory); +ZEND_FUNCTION(vips_image_write_to_memory); +ZEND_FUNCTION(vips_image_write_to_array); +ZEND_FUNCTION(vips_foreign_find_load); +ZEND_FUNCTION(vips_foreign_find_load_buffer); +ZEND_FUNCTION(vips_interpolate_new); +ZEND_FUNCTION(vips_call); +ZEND_FUNCTION(vips_image_get); +ZEND_FUNCTION(vips_image_get_typeof); +ZEND_FUNCTION(vips_image_set); +ZEND_FUNCTION(vips_type_from_name); +ZEND_FUNCTION(vips_image_set_type); +ZEND_FUNCTION(vips_image_remove); +ZEND_FUNCTION(vips_error_buffer); +ZEND_FUNCTION(vips_cache_set_max); +ZEND_FUNCTION(vips_cache_set_max_mem); +ZEND_FUNCTION(vips_cache_set_max_files); +ZEND_FUNCTION(vips_concurrency_set); +ZEND_FUNCTION(vips_cache_get_max); +ZEND_FUNCTION(vips_cache_get_max_mem); +ZEND_FUNCTION(vips_cache_get_max_files); +ZEND_FUNCTION(vips_cache_get_size); +ZEND_FUNCTION(vips_concurrency_get); +ZEND_FUNCTION(vips_version); + + +static const zend_function_entry ext_functions[] = { + ZEND_FE(vips_image_new_from_file, arginfo_vips_image_new_from_file) + ZEND_FE(vips_image_new_from_buffer, arginfo_vips_image_new_from_buffer) + ZEND_FE(vips_image_new_from_array, arginfo_vips_image_new_from_array) + ZEND_FE(vips_image_write_to_file, arginfo_vips_image_write_to_file) + ZEND_FE(vips_image_write_to_buffer, arginfo_vips_image_write_to_buffer) + ZEND_FE(vips_image_copy_memory, arginfo_vips_image_copy_memory) + ZEND_FE(vips_image_new_from_memory, arginfo_vips_image_new_from_memory) + ZEND_FE(vips_image_write_to_memory, arginfo_vips_image_write_to_memory) + ZEND_FE(vips_image_write_to_array, arginfo_vips_image_write_to_array) + ZEND_FE(vips_foreign_find_load, arginfo_vips_foreign_find_load) + ZEND_FE(vips_foreign_find_load_buffer, arginfo_vips_foreign_find_load_buffer) + ZEND_FE(vips_interpolate_new, arginfo_vips_interpolate_new) + ZEND_FE(vips_call, arginfo_vips_call) + ZEND_FE(vips_image_get, arginfo_vips_image_get) + ZEND_FE(vips_image_get_typeof, arginfo_vips_image_get_typeof) + ZEND_FE(vips_image_set, arginfo_vips_image_set) + ZEND_FE(vips_type_from_name, arginfo_vips_type_from_name) + ZEND_FE(vips_image_set_type, arginfo_vips_image_set_type) + ZEND_FE(vips_image_remove, arginfo_vips_image_remove) + ZEND_FE(vips_error_buffer, arginfo_vips_error_buffer) + ZEND_FE(vips_cache_set_max, arginfo_vips_cache_set_max) + ZEND_FE(vips_cache_set_max_mem, arginfo_vips_cache_set_max_mem) + ZEND_FE(vips_cache_set_max_files, arginfo_vips_cache_set_max_files) + ZEND_FE(vips_concurrency_set, arginfo_vips_concurrency_set) + ZEND_FE(vips_cache_get_max, arginfo_vips_cache_get_max) + ZEND_FE(vips_cache_get_max_mem, arginfo_vips_cache_get_max_mem) + ZEND_FE(vips_cache_get_max_files, arginfo_vips_cache_get_max_files) + ZEND_FE(vips_cache_get_size, arginfo_vips_cache_get_size) + ZEND_FE(vips_concurrency_get, arginfo_vips_concurrency_get) + ZEND_FE(vips_version, arginfo_vips_version) + ZEND_FE_END +};