From f4ad0fc8ace5fdf83d34a2098d8929af7af589e3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 7 Dec 2021 14:02:34 +0000 Subject: [PATCH 01/58] start an ffi experiment --- examples/vips-ffi.php | 505 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100755 examples/vips-ffi.php diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php new file mode 100755 index 0000000..c0d546f --- /dev/null +++ b/examples/vips-ffi.php @@ -0,0 +1,505 @@ +#!/usr/bin/env php +vips_error_buffer()"); +} + +$result = $base_ffi->vips_init($argv[0]); +if ($result != 0) { + error(); +} +trace("vips_init: $result"); + +# get the library version number, then we can build the API +$library_major = $base_ffi->vips_version(0); +$library_minor = $base_ffi->vips_version(1); +$library_micro = $base_ffi->vips_version(2); +trace("vips_version: $library_major.$library_minor.$library_micro"); + +function at_least($need_major, $need_minor) +{ + global $library_major, $library_minor; + + return $need_major < $library_major || + ($need_major == $library_major && $need_minor <= $library_minor); +} + +# largely copied from pyvips +$header = <<vips_shutdown(); From f38fb691e9ca0266e6a730668278805e54ab9a8c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 8 Jan 2022 11:11:28 +0000 Subject: [PATCH 02/58] fix syntax errors --- examples/vips-ffi.php | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php index c0d546f..7702dff 100755 --- a/examples/vips-ffi.php +++ b/examples/vips-ffi.php @@ -321,13 +321,12 @@ function at_least($need_major, $need_minor) const char* vips_object_get_description (VipsObject* object); -const char* g_param_spec_get_blurb (GParamSpec* psp +const char* g_param_spec_get_blurb (GParamSpec* psp); typedef struct _VipsImage { VipsObject parent_instance; // more } VipsImage; - const char* vips_foreign_find_load (const char* name); const char* vips_foreign_find_load_buffer (const void* data, size_t size); @@ -406,29 +405,28 @@ function at_least($need_major, $need_minor) EOS; if (at_least(8, 5)) { - $header = << Date: Sat, 8 Jan 2022 18:58:30 +0000 Subject: [PATCH 03/58] do the rest of introspection call an operation next --- examples/vips-ffi.php | 247 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 233 insertions(+), 14 deletions(-) diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php index 7702dff..eb09421 100755 --- a/examples/vips-ffi.php +++ b/examples/vips-ffi.php @@ -57,7 +57,7 @@ function error() { global $base_ffi; - throw new Exception("libvips error: $ffi->vips_error_buffer()"); + throw new Exception("libvips error: $base_ffi->vips_error_buffer()"); } $result = $base_ffi->vips_init($argv[0]); @@ -80,6 +80,11 @@ function at_least($need_major, $need_minor) ($need_major == $library_major && $need_minor <= $library_minor); } +if (!at_least(8, 7)) { + trace("your libvips is too old -- 8.7 or later required"); + exit(1); +} + # largely copied from pyvips $header = <<"); + exit(1); +} +$filename = $argv[1]; + +trace("attempting to open: $filename"); + +$loader = $ffi->vips_foreign_find_load($filename); +trace("selected loader: $loader"); + +$operation = $ffi->vips_operation_new($loader); +if (FFI::isNull($operation)) { + error(); +} + +$vipsObject = $ffi->type("VipsObject*"); +$description = $ffi->vips_object_get_description( + FFI::cast($vipsObject, $operation)); +trace("description: $description"); + +$operationFlags = [ + "NONE" => 0, + "SEQUENTIAL" => 1, + "NOCACHE" => 4, + "DEPRECATED" => 8 +]; +$flags = $ffi->vips_operation_get_flags($operation); +trace("flags: $flags"); +foreach ($operationFlags as $name => $flag) { + if ($flags & $flag) { + trace(" $name"); + } +} + +$argumentFlags = [ + "REQUIRED" => 1, + "CONSTRUCT" => 2, + "SET_ONCE" => 4, + "SET_ALWAYS" => 8, + "INPUT" => 16, + "OUTPUT" => 32, + "DEPRECATED" => 64, + "MODIFY" => 128 +]; +$p_names = $ffi->new("char**[1]"); +$p_flags = $ffi->new("int*[1]"); +$p_n_args = $ffi->new("int[1]"); +$result = $ffi->vips_object_get_args( + FFI::cast($vipsObject, $operation), + $p_names, + $p_flags, + $p_n_args +); +if ($result != 0) { + error(); +} +$p_names = $p_names[0]; +$p_flags = $p_flags[0]; +$n_args = $p_n_args[0]; + +trace("n_args: $n_args"); + +# make a hash from arg name to flags +$arguments = []; +for ($i = 0; $i < $n_args; $i++) { + if (($p_flags[$i] & $argumentFlags["CONSTRUCT"]) != 0) { + # libvips uses '-' to separate parts of arg names, but we + # need '_' for php + $name = FFI::string($p_names[$i]); + $name = str_replace("-", "_", $name); + $arguments[$name] = $p_flags[$i]; + } +} + +// get the pspec for a property from a VipsObject +// NULL for no such name +function get_pspec($object, $name) { + global $ffi; + global $vipsObject; + + $pspec = $ffi->new("GParamSpec*[1]"); + $argument_class = $ffi->new("VipsArgumentClass*[1]"); + $argument_instance = $ffi->new("VipsArgumentInstance*[1]"); + $result = $ffi->vips_object_get_argument( + FFI::cast($vipsObject, $object), + $name, + $pspec, + $argument_class, + $argument_instance + ); + + if ($result != 0) { + return FFI::NULL; + } + else { + return $pspec[0]; + } +} + +// get the type of a property from a VipsObject +// 0 if no such property +function get_typeof($object, $name) { + global $base_ffi; + + $pspec = get_pspec($object, $name); + if (FFI::isNULL($pspec)) { + # need to clear any error, this is horrible + $base_ffi->vips_error_clear(); + return 0; + } + else { + return $pspec->value_type; + } +} + +function get_blurb($object, $name) { + global $ffi; + + $pspec = get_pspec($object, $name); + return $ffi->g_param_spec_get_blurb($pspec); +} + +# make a hash from arg name to detailed arg info +$details = []; +foreach ($arguments as $name => $flags) { + $details[$name] = [ + "name" => $name, + "flags" => $flags, + "blurb" => get_blurb($operation, $name), + "type" => get_typeof($operation, $name) + ]; +} + +# split args into categories +$required_input = []; +$optional_input = []; +$required_output = []; +$optional_output = []; + +foreach ($details as $name => $detail) { + $flags = $detail["flags"]; + $blurb = $detail["blurb"]; + $type = $detail["type"]; + $typeName = $ffi->g_type_name($type); + + if (($flags & $argumentFlags["INPUT"]) && + ($flags & $argumentFlags["REQUIRED"]) && + !($flags & $argumentFlags["DEPRECATED"])) { + $required_input[] = $name; + + # required inputs which we MODIFY are also required outputs + if ($flags & $required_input["MODIFY"]) { + $required_output[] = $name; + } + } + + if (($flags & $argumentFlags["OUTPUT"]) && + ($flags & $argumentFlags["REQUIRED"]) && + !($flags & $argumentFlags["DEPRECATED"])) { + $required_output[] = $name; + } + + # we let deprecated optional args through, but warn about them + # if they get used, see below + if (($flags & $argumentFlags["INPUT"]) && + !($flags & $argumentFlags["REQUIRED"])) { + $optional_input[] = $name; + } + + if (($flags & $argumentFlags["OUTPUT"]) && + !($flags & $argumentFlags["REQUIRED"])) { + $optional_output[] = $name; + } +} + +# find the first required input image arg, if any ... that will be self +$imageType = $ffi->g_type_from_name("VipsImage"); +$member_x = null; +foreach ($required_input as $name) { + $type = $details[$name]["type"]; + if ($type == $imageType) { + $member_x = $name; + break; + } +} + +# method args are required args, but without the image they are a +# method on +$method_args = $required_input; +if ($member_x != null) { + $index = array_search($member_x, $method_args); + array_splice($method_args, $index); +} + + +# print! +foreach ($details as $name => $detail) { + $flags = $detail["flags"]; + $blurb = $detail["blurb"]; + $type = $detail["type"]; + $typeName = $ffi->g_type_name($type); + + trace(" $name:"); + + trace(" flags: $flags"); + foreach ($argumentFlags as $name => $flag) { + if ($flags & $flag) { + trace(" $name"); + } + } + + trace(" blurb: $blurb"); + trace(" type: $typeName"); +} + +$info = implode(", ", $required_input); +trace("required input: $info"); +$info = implode(", ", $required_output); +trace("required output: $info"); +$info = implode(", ", $optional_input); +trace("optional input: $info"); +$info = implode(", ", $optional_output); +trace("optional output: $info"); +trace("member_x: $member_x"); +$info = implode(", ", $method_args); +trace("method args: $info"); $base_ffi->vips_shutdown(); From 7284eeea20bfdd0b3257631773a43a3e2527521e Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 8 Jan 2022 20:36:10 +0000 Subject: [PATCH 04/58] oop typo --- examples/vips-ffi.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php index eb09421..db55297 100755 --- a/examples/vips-ffi.php +++ b/examples/vips-ffi.php @@ -644,7 +644,7 @@ function get_blurb($object, $name) { $required_input[] = $name; # required inputs which we MODIFY are also required outputs - if ($flags & $required_input["MODIFY"]) { + if ($flags & $argumentFlags["MODIFY"]) { $required_output[] = $name; } } From 4ae4cb5c6b69644b3d90c364462886651888d861 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 12 Jan 2022 12:34:11 +0000 Subject: [PATCH 05/58] add the rest of call operation next, need to have classes wrapping gobject, vipsobject, vipsoperation and vipsimage --- examples/vips-ffi.php | 188 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 3 deletions(-) diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php index db55297..d305a59 100755 --- a/examples/vips-ffi.php +++ b/examples/vips-ffi.php @@ -70,7 +70,7 @@ function error() $library_major = $base_ffi->vips_version(0); $library_minor = $base_ffi->vips_version(1); $library_micro = $base_ffi->vips_version(2); -trace("vips_version: $library_major.$library_minor.$library_micro"); +trace("found libvips version: $library_major.$library_minor.$library_micro"); function at_least($need_major, $need_minor) { @@ -85,6 +85,16 @@ function at_least($need_major, $need_minor) exit(1); } +if (PHP_INT_SIZE != 8) { + # we could maybe fix this if it's important ... it's mostly necessary since + # GType is the size of a pointer, and there's no easy way to discover if php + # is running on a 32 or 64-bit systems (as far as I can see) + trace("your php only supports 32-bit ints -- 64 bit ints required"); + exit(1); +} + +// bind the libvips API to the library binary + # largely copied from pyvips $header = <<"); exit(1); @@ -508,7 +521,11 @@ function at_least($need_major, $need_minor) error(); } +// now introspect $operation and show all the args it wants ... about the next +// 250 lines of code + $vipsObject = $ffi->type("VipsObject*"); +$gObject = $ffi->type("GObject*"); $description = $ffi->vips_object_get_description( FFI::cast($vipsObject, $operation)); trace("description: $description"); @@ -687,7 +704,6 @@ function get_blurb($object, $name) { array_splice($method_args, $index); } - # print! foreach ($details as $name => $detail) { $flags = $detail["flags"]; @@ -720,4 +736,170 @@ function get_blurb($object, $name) { $info = implode(", ", $method_args); trace("method args: $info"); +// look these up in advance +$gtypes = [ + "gboolean" => $ffi->g_type_from_name("gboolean"), + "gchararray" => $ffi->g_type_from_name("gchararray"), + "VipsRefString" => $ffi->g_type_from_name("VipsRefString"), + "GObject" => $ffi->g_type_from_name("GObject"), +]; + +// a tiny class to wrap GValue ... we need to be able to trigger g_value_unset +// when we are done with one of these, so we need to make a class + +class GValue +{ + private FFI\CData $struct; + public FFI\CData $pointer; + + function __construct() { + global $ffi; + + # allocate a gvalue on the heap, and make it persistent between requests + $this->struct = $ffi->new("GValue", true, true); + $this->pointer = FFI::addr($this->struct); + + # GValue needs to be inited to all zero + FFI::memset($this->pointer, 0, FFI::sizeof($this->struct)); + } + + function __destruct() { + global $ffi; + + $ffi->g_value_unset($this->pointer); + } + + function set_type(int $gtype) { + global $ffi; + + $ffi->g_value_init($this->pointer, $gtype); + } + + function get_type(): int { + return $this->pointer->g_type; + } + + function set($value) { + global $ffi, $gtypes; + + $gtype = $this->get_type(); + + switch ($gtype) { + case $gtypes["gboolean"]: + $ffi->g_value_set_boolean($this->pointer, $value); + break; + + case $gtypes["gchararray"]: + $ffi->g_value_set_string($this->pointer, $value); + break; + + case $gtypes["VipsRefString"]: + $ffi->vips_value_set_ref_string($this->pointer, $value); + break; + + default: + $fundamental = $ffi->g_type_fundamental($gtype); + switch ($fundamental) { + case $gtypes["GObject"]: + break; + + default: + trace("GValue::set(): gtype $gtype not implemented"); + exit(1); + } + } + } + + function get() { + global $ffi, $gtypes; + + $gtype = $this->get_type(); + $result = null; + + switch ($gtype) { + case $gtypes["gboolean"]: + $result = $ffi->g_value_get_boolean($this->pointer); + break; + + case $gtypes["gchararray"]: + $ffi->g_value_get_string($this->pointer); + break; + + case $gtypes["VipsRefString"]: + $psize = $ffi->new("size_t*"); + $result = $ffi->vips_value_get_ref_string($this->pointer, $psize); + # $psize[0] will be the string length, but assume it's null terminated + break; + + default: + $fundamental = $ffi->g_type_fundamental($gtype); + switch ($fundamental) { + case $gtypes["GObject"]: + # we need a class wrapping gobject before we can impement this + trace("in get() get object"); + break; + + default: + trace("GValue::get(): gtype $gtype not implemented"); + exit(1); + } + } + + return $result; + } + +} + +function gobject_set($object, $name, $value) { + global $ffi; + global $gObject; + + $gtype = get_typeof($object, $name); + + $gvalue = new GValue(); + $gvalue->set_type($gtype); + $gvalue->set($value); + + $gobject = FFI::cast($gObject, $object); + $ffi->g_object_set_property($gobject, $name, $gvalue->pointer); +} + +function gobject_get($object, $name) { + global $ffi; + global $gObject; + + $gtype = get_typeof($object, $name); + + $gvalue = new GValue(); + $gvalue->set_type($gtype); + + $gobject = FFI::cast($gObject, $object); + $ffi->g_object_get_property($gobject, $name, $gvalue->pointer); + + return $gvalue->get(); +} + +// now use the info from introspection to set some parameters on $operation + +trace("setting arguments ..."); +gobject_set($operation, "filename", $filename); + +// build the operation + +trace("building ..."); +$new_operation = $ffi->vips_cache_operation_build($operation); +if (FFI::isNull($new_operation)) { + $ffi->vips_object_unref_outputs($operation); + error(); +} +$operation = $new_operation; + +# need to attach input refs to output + +// fetch required output args + +$image = gobject_get($operation, "out"); +trace("result: " . print_r($image, true)); + +trace("shutting down ..."); $base_ffi->vips_shutdown(); From d6a9f6561e98020e2b0700fad474c850e9437ff3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 13 Jan 2022 12:20:02 +0000 Subject: [PATCH 06/58] start movinf ffi into php-vips --- src/GObject.php | 96 +++++++++++++++++++++++ src/GValue.php | 158 +++++++++++++++++++++++++++++++++++++ src/VipsObject.php | 177 ++++++++++++++++++++++++++++++++++++++++++ src/VipsOperation.php | 80 +++++++++++++++++++ 4 files changed, 511 insertions(+) create mode 100644 src/GObject.php create mode 100644 src/GValue.php create mode 100644 src/VipsObject.php create mode 100644 src/VipsOperation.php diff --git a/src/GObject.php b/src/GObject.php new file mode 100644 index 0000000..95e954e --- /dev/null +++ b/src/GObject.php @@ -0,0 +1,96 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * This class holds a pointer to a GObject and manages object lifetime. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ +abstract class GObject +{ + /** + * A pointer to the underlying GObject. + * + * @internal + */ + private FFI\CData $gObject; + + /** + * Wrap a GObject around an underlying vips resource. The GObject takes + * ownership of the pointer and will unref it on finalize. + * + * Don't call this yourself, users should stick to (for example) + * Image::newFromFile(). + * + * @param FFI\CData $pointer The underlying pointer that this + * object should wrap. + * + * @internal + */ + function __construct($pointer) + { + global $ctypes; + + $this->gObject = FFI::cast($ctypes["GObject"], $pointer), + } + + function __destruct() { + global $ffi; + + $ffi->g_object_unref($this->gObject); + } + + // TODO signal marshalling to go in + +} + +/* + * 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/src/GValue.php b/src/GValue.php new file mode 100644 index 0000000..454e99f --- /dev/null +++ b/src/GValue.php @@ -0,0 +1,158 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +// look these up in advance +$gtypes = [ + "gboolean" => $ffi->g_type_from_name("gboolean"), + "gchararray" => $ffi->g_type_from_name("gchararray"), + "VipsRefString" => $ffi->g_type_from_name("VipsRefString"), + "GObject" => $ffi->g_type_from_name("GObject"), +]; + +class GValue +{ + private FFI\CData $struct; + public FFI\CData $pointer; + + function __construct() { + global $ffi; + + # allocate a gvalue on the heap, and make it persistent between requests + $this->struct = $ffi->new("GValue", true, true); + $this->pointer = FFI::addr($this->struct); + + # GValue needs to be inited to all zero + FFI::memset($this->pointer, 0, FFI::sizeof($this->struct)); + } + + function __destruct() { + global $ffi; + + $ffi->g_value_unset($this->pointer); + } + + function setType(int $gtype) { + global $ffi; + + $ffi->g_value_init($this->pointer, $gtype); + } + + function getType(): int { + return $this->pointer->g_type; + } + + function set($value) { + global $ffi, $gtypes; + + $gtype = $this->get_type(); + + switch ($gtype) { + case $gtypes["gboolean"]: + $ffi->g_value_set_boolean($this->pointer, $value); + break; + + case $gtypes["gchararray"]: + $ffi->g_value_set_string($this->pointer, $value); + break; + + case $gtypes["VipsRefString"]: + $ffi->vips_value_set_ref_string($this->pointer, $value); + break; + + default: + $fundamental = $ffi->g_type_fundamental($gtype); + switch ($fundamental) { + case $gtypes["GObject"]: + break; + + default: + throw new \BadMethodCallException("gtype $gtype not implemented"); + break; + } + } + } + + function get() { + global $ffi, $gtypes; + + $gtype = $this->get_type(); + $result = null; + + switch ($gtype) { + case $gtypes["gboolean"]: + $result = $ffi->g_value_get_boolean($this->pointer); + break; + + case $gtypes["gchararray"]: + $ffi->g_value_get_string($this->pointer); + break; + + case $gtypes["VipsRefString"]: + $psize = $ffi->new("size_t*"); + $result = $ffi->vips_value_get_ref_string($this->pointer, $psize); + # $psize[0] will be the string length, but assume it's null + # terminated + break; + + default: + $fundamental = $ffi->g_type_fundamental($gtype); + switch ($fundamental) { + case $gtypes["GObject"]: + # we need a class wrapping gobject before we can impement this + break; + + default: + throw new \BadMethodCallException("gtype $gtype not implemented"); + break; + } + } + + return $result; + } +} + +/* +* 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/src/VipsObject.php b/src/VipsObject.php new file mode 100644 index 0000000..5a5b9d9 --- /dev/null +++ b/src/VipsObject.php @@ -0,0 +1,177 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * This class holds a pointer to a VipsObject (the libvips base class) and + * manages properties. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ +abstract class VipsObject extends GObject +{ + /** + * A pointer to the underlying VipsObject. This is the same as the + * GObject, just cast to VipsObject to help FFI. + * + * @internal + */ + private FFI\CData $vipsObject; + + function __construct($pointer) + { + global $ffi; + global $ctypes; + + $this->vipsObject = $ffi->cast($ctypes["VipsObject"], $pointer); + parent::__construct($pointer); + } + + // print a table of all active vipsobjects ... handy for debugging + static function printAll() { + global $ffi; + + $ffi->vips_object_print_all(); + } + + // get the pspec for a property + // NULL for no such name + // very slow! avoid if possible + // FIXME add a cache for this thing + function getPspec($name) { + global $ffi; + global $ctypes; + + $pspec = $ffi->new("GParamSpec*[1]"); + $argument_class = $ffi->new("VipsArgumentClass*[1]"); + $argument_instance = $ffi->new("VipsArgumentInstance*[1]"); + $result = $ffi->vips_object_get_argument( + $this->vipsObject, + $name, + $pspec, + $argument_class, + $argument_instance + ); + + if ($result != 0) { + return FFI::NULL; + } + else { + return $pspec[0]; + } + } + + // get the type of a property from a VipsObject + // 0 if no such property + function getType($name) { + global $base_ffi; + + $pspec = $this->getPspec($name); + if (FFI::isNULL($pspec)) { + # need to clear any error, this is horrible + $base_ffi->vips_error_clear(); + return 0; + } + else { + return $pspec->value_type; + } + } + + function getBlurb($name) { + global $ffi; + + $pspec = $this->getPspec($name); + return $ffi->g_param_spec_get_blurb($pspec); + } + + function getDescription($name) { + global $ffi; + + $pspec = $this->getPspec($name); + return $ffi->g_param_spec_get_description($pspec); + } + + function get($name) { + global $ffi; + global $ctypes; + + $gvalue = new GValue(); + $gvalue->setType($this->getType($name)); + + $ffi->g_object_get_property($this->gObject, $name, $gvalue->pointer); + + return $gvalue->get(); + } + + function set($name, $value) { + global $ffi; + + $gvalue = new GValue(); + $gvalue->setType($this->getType($name)); + $gvalue->set($value); + + $ffi->g_object_set_property($this->gObject, $name, $gvalue->pointer); + } + + function setString($string_options) { + global $ffi; + + $result = $ffi->vips_object_set_from_string( + $this->vipsObject, + $string_options + ); + + return $result == 0; + } + +} + +/* + * 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/src/VipsOperation.php b/src/VipsOperation.php new file mode 100644 index 0000000..387147b --- /dev/null +++ b/src/VipsOperation.php @@ -0,0 +1,80 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * This class holds a pointer to a VipsOperation (the libvips operation base + * class) and manages argument introspection and operation call. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ +abstract class VipsOperation extends VipsObject +{ + /** + * A pointer to the underlying VipsOperation. This is the same as the + * GObject, just cast to VipsOperation to help FFI. + * + * @internal + */ + private FFI\CData $vipsOperation; + + function __construct($pointer) + { + global $ffi; + global $ctypes; + + $this->vipsOperation = $ffi->cast($ctypes["VipsOperation"], $pointer); + parent::__construct($pointer); + } + +} + +/* + * 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 + */ From 3fecf0583ddf788e6caccd1a571cc13b415605f3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 15 Jan 2022 15:39:05 +0000 Subject: [PATCH 07/58] start pasting in startup code --- src/Init.php | 560 ++++++++++++++++++++++++++++++++++++++++++ src/Introspect.php | 118 +++++++++ src/VipsOperation.php | 3 + 3 files changed, 681 insertions(+) create mode 100644 src/Init.php create mode 100644 src/Introspect.php diff --git a/src/Init.php b/src/Init.php new file mode 100644 index 0000000..b79d470 --- /dev/null +++ b/src/Init.php @@ -0,0 +1,560 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/* This file does all the init we need to start up libvips and the binding. + */ + +# set TRUE for debug output +$trace = TRUE; + +function trace($message) +{ + global $trace; + + if ($trace) { + echo "$message\n"; + } +} + +$library_name = "libvips"; + +# PHP_OS_FAMILY added in php 7.2 +switch(PHP_OS_FAMILY) { +case "Windows": + $library_ext = ".dll"; + break; + +case "OSX": + $library_ext = ".dylib"; + break; + +default; + $library_ext = ".so"; + break; +} + +$vipshome = getenv("VIPSHOME"); +if ($vipshome) { + $library_location = $vipshome . "/lib/"; +} +else { + # rely on ffi's search + $library_location = ""; +} + +$library = "$library_location$library_name$library_ext"; + +$base_ffi = FFI::cdef(<<vips_error_clear(); + } + + throw new Exception($message); +} + +$result = $base_ffi->vips_init($argv[0]); +if ($result != 0) { + error(); +} +trace("vips_init: $result"); + +# get the library version number, then we can build the API +$library_major = $base_ffi->vips_version(0); +$library_minor = $base_ffi->vips_version(1); +$library_micro = $base_ffi->vips_version(2); +trace("found libvips version: $library_major.$library_minor.$library_micro"); + +function at_least($need_major, $need_minor) +{ + global $library_major, $library_minor; + + return $need_major < $library_major || + ($need_major == $library_major && $need_minor <= $library_minor); +} + +if (!at_least(8, 7)) { + error("your libvips is too old -- 8.7 or later required"); +} + +if (PHP_INT_SIZE != 8) { + # we could maybe fix this if it's important ... it's mostly necessary since + # GType is the size of a pointer, and there's no easy way to discover if php + # is running on a 32 or 64-bit systems (as far as I can see) + error("your php only supports 32-bit ints -- 64 bit ints required"); +} + +// bind the libvips API to the library binary + +# largely copied from pyvips +$header = << + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * Introspect a VIpsOperation and discover everything we can. This is called + * on demand once per operation and the results held in a cache. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ +class Introspection +{ + /** + * The operation nickname (eg. "add"). + */ + protected string $name; + + /** + * The operation description (eg. "add two images"). + */ + protected string $description; + + /** + * The operation flags (eg. SEQUENTIAL | DEPRECATED). + */ + protected int $flags; + + function __construct($name) + { + global $ffi; + global $ctypes; + + $this->name = $name; + + $operation = $ffi->vips_operation_new($name); + if (FFI::isNull($operation)) { + error(); + } + + $this->description = $ffi->vips_object_get_description( + FFI::cast($ctypes["VipsObject"], $operation)); + $flags = $ffi->vips_operation_get_flags($operation); + + $p_names = $ffi->new("char**[1]"); + $p_flags = $ffi->new("int*[1]"); + $p_n_args = $ffi->new("int[1]"); + $result = $ffi->vips_object_get_args( + FFI::cast($ctypes["VipsObject"], $operation), + $p_names, + $p_flags, + $p_n_args + ); + if ($result != 0) { + error(); + } + $p_names = $p_names[0]; + $p_flags = $p_flags[0]; + $n_args = $p_n_args[0]; + + + + $operation = new + } + + + + +} + +/* + * 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/src/VipsOperation.php b/src/VipsOperation.php index 387147b..c798262 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -68,6 +68,9 @@ function __construct($pointer) parent::__construct($pointer); } + + + } /* From 55036082527d98f103e86d1fa8c184b94b9a9ccd Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 19 Jan 2022 13:31:03 +0000 Subject: [PATCH 08/58] more pasting in --- src/GValue.php | 7 +- src/Introspect.php | 149 ++++++++++++++++++++++++++++++++++++++++-- src/VipsObject.php | 8 ++- src/VipsOperation.php | 143 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 299 insertions(+), 8 deletions(-) diff --git a/src/GValue.php b/src/GValue.php index 454e99f..fb46781 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -43,6 +43,7 @@ "gboolean" => $ffi->g_type_from_name("gboolean"), "gchararray" => $ffi->g_type_from_name("gchararray"), "VipsRefString" => $ffi->g_type_from_name("VipsRefString"), + "VipsImage" => $ffi->g_type_from_name("VipsImage"), "GObject" => $ffi->g_type_from_name("GObject"), ]; @@ -103,7 +104,8 @@ function set($value) { break; default: - throw new \BadMethodCallException("gtype $gtype not implemented"); + $typeName = $ffi->g_type_name($gtype) + throw new \BadMethodCallException("$typeName not implemented"); break; } } @@ -139,7 +141,8 @@ function get() { break; default: - throw new \BadMethodCallException("gtype $gtype not implemented"); + $typeName = $ffi->g_type_name($gtype) + throw new \BadMethodCallException("$typeName not implemented"); break; } } diff --git a/src/Introspect.php b/src/Introspect.php index 7464ffa..0473e1d 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -66,20 +66,45 @@ class Introspection */ protected int $flags; + /** + * A hash from arg name to a hash of details. + */ + protected mixed[] $arguments; + + /** + * Arrays of arg names, in order and by category, eg. $this->required_input + * = ["filename"]. + */ + protected string[] $required_input; + protected string[] $optional_input; + protected string[] $required_output; + protected string[] $optional_output; + + /** + * The name of the arg this operation uses as "this". + */ + protected string $member_this; + + /** + * And the required input args, without the "this". + */ + protected string[] $method_args; + function __construct($name) { global $ffi; global $ctypes; + global $gtypes; $this->name = $name; - $operation = $ffi->vips_operation_new($name); - if (FFI::isNull($operation)) { + $pointer = $ffi->vips_operation_new($name); + if (FFI::isNull($pointer)) { error(); } + $operation = new VipsOperation($pointer); - $this->description = $ffi->vips_object_get_description( - FFI::cast($ctypes["VipsObject"], $operation)); + $this->description = $operation->getDescription(); $flags = $ffi->vips_operation_get_flags($operation); $p_names = $ffi->new("char**[1]"); @@ -98,14 +123,128 @@ function __construct($name) $p_flags = $p_flags[0]; $n_args = $p_n_args[0]; + # make a hash from arg name to flags + $argumentFlags = []; + for ($i = 0; $i < $n_args; $i++) { + if (($p_flags[$i] & $argumentFlags["CONSTRUCT"]) != 0) { + # libvips uses '-' to separate parts of arg names, but we + # need '_' for php + $name = FFI::string($p_names[$i]); + $name = str_replace("-", "_", $name); + $argumentFlags[$name] = $p_flags[$i]; + } + } + + # make a hash from arg name to detailed arg info + $this->arguments = []; + foreach ($argumentFlags as $name => $flags) { + $this->arguments[$name] = [ + "name" => $name, + "flags" => $flags, + "blurb" => $operation->getBlurb($operation, $name), + "type" => $operation->getType($operation, $name) + ]; + } + + # split args into categories + $this->required_input = []; + $this->optional_input = []; + $this->required_output = []; + $this->optional_output = []; + + foreach ($this->arguments as $name => $details) { + $flags = $details["flags"]; + $blurb = $details["blurb"]; + $type = $details["type"]; + $typeName = $ffi->g_type_name($type); + + if (($flags & $argumentFlags["INPUT"]) && + ($flags & $argumentFlags["REQUIRED"]) && + !($flags & $argumentFlags["DEPRECATED"])) { + $this->required_input[] = $name; + + # required inputs which we MODIFY are also required outputs + if ($flags & $argumentFlags["MODIFY"]) { + $this->required_output[] = $name; + } + } + if (($flags & $argumentFlags["OUTPUT"]) && + ($flags & $argumentFlags["REQUIRED"]) && + !($flags & $argumentFlags["DEPRECATED"])) { + $this->required_output[] = $name; + } + + # we let deprecated optional args through, but warn about them + # if they get used, see below + if (($flags & $argumentFlags["INPUT"]) && + !($flags & $argumentFlags["REQUIRED"])) { + $this->optional_input[] = $name; + } + + if (($flags & $argumentFlags["OUTPUT"]) && + !($flags & $argumentFlags["REQUIRED"])) { + $this->optional_output[] = $name; + } + } + + # find the first required input image arg, if any ... that will be self + $this->member_this = null; + foreach ($required_input as $name) { + $type = $details[$name]["type"]; + if ($type == $gtypes["VipsImage"]) { + $this->member_this = $name; + break; + } + } - $operation = new + # method args are required args, but without the image they are a + # method on + $this->method_args = $this->required_input; + if ($this->member_this != null) { + $index = array_search($this->member_this, $this->method_args); + array_splice($this->method_args, $index); + } } + public function __toString() { + $result = ""; + + $result .= "$this->name:\n"; + foreach ($this->arguments as $name => $details) { + $flags = $details["flags"]; + $blurb = $details["blurb"]; + $type = $details["type"]; + $typeName = $ffi->g_type_name($type); + $result .= " $name:\n"; + $result .= " flags: $flags\n"; + foreach ($argumentFlags as $name => $flag) { + if ($flags & $flag) { + $resut .= " $name\n"; + } + } + + $result .= " blurb: $blurb\n"; + $result .= " type: $typeName\n"; + } + + $info = implode(", ", $this->required_input); + $result .= "required input: $info\n"; + $info = implode(", ", $this->required_output); + $result .= "required output: $info\n"; + $info = implode(", ", $this->optional_input); + $result .= "optional input: $info\n"; + $info = implode(", ", $this->optional_output); + $result .= "optional output: $info\n"; + $result .= "member_this: $this->member_this\n"; + $info = implode(", ", $this->method_args); + $result .= "method args: $info\n"; + + return $result; + } } /* diff --git a/src/VipsObject.php b/src/VipsObject.php index 5a5b9d9..9f14e2f 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -75,6 +75,12 @@ static function printAll() { $ffi->vips_object_print_all(); } + function getDescription() { + global $ffi; + + return $ffi->vips_object_get_description($this->vipsObject); + } + // get the pspec for a property // NULL for no such name // very slow! avoid if possible @@ -125,7 +131,7 @@ function getBlurb($name) { return $ffi->g_param_spec_get_blurb($pspec); } - function getDescription($name) { + function getArgumentDescription($name) { global $ffi; $pspec = $this->getPspec($name); diff --git a/src/VipsOperation.php b/src/VipsOperation.php index c798262..2fed6e1 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -59,6 +59,11 @@ abstract class VipsOperation extends VipsObject */ private FFI\CData $vipsOperation; + /** + * Cache introsection results here. + */ + private static $introspectionCache[] mixed = []; + function __construct($pointer) { global $ffi; @@ -68,6 +73,144 @@ function __construct($pointer) parent::__construct($pointer); } + function getIntrospection($name) { + if (!array_key_exists($introspectionCache, $name)) { + $introspectionCache[$name] = new VipsIntrospection($name); + } + + return $introspectionCache[$name]; + } + + /** + * Call any vips operation. The final element of $arguments can be + * (but doesn't have to be) an array of options to pass to the operation. + * + * We can't have a separate arg for the options since this will be run from + * __call(), which cannot know which args are required and which are + * optional. See call() below for a version with the options broken out. + * + * @param string $name The operation name. + * @param Image|null $instance The instance this operation is being invoked + * from. + * @param array $arguments An array of arguments to pass to the + * operation. + * + * @throws Exception + * + * @return mixed The result(s) of the operation. + */ + function callBase( + string $name, + ?Image $instance, + array $arguments + ) { + Utils::debugLog($name, [ + 'instance' => $instance, + 'arguments' => $arguments + ]); + + $introspection = $this->getIntrospection($name); + + $arguments = array_merge([$name, $instance], $arguments); + + $arguments = array_values(self::unwrap($arguments)); + $result = vips_call(...$arguments); + self::errorIsArray($result); + $result = self::wrapResult($result); + + Utils::debugLog($name, ['result' => $result]); + + return $result; + } + + /** + * Call any vips operation, with an explicit set of options. This is more + * convenient than callBase() if you have a set of known options. + * + * @param string $name The operation name. + * @param Image|null $instance The instance this operation is being invoked + * from. + * @param array $arguments An array of arguments to pass to the + * operation. + * @param array $options An array of optional arguments to pass to + * the operation. + * + * @throws Exception + * + * @return mixed The result(s) of the operation. + */ + public static function call( + string $name, + ?Image $instance, + array $arguments, + array $options = [] + ) { + /* + echo "call: $name \n"; + echo "instance = \n"; + var_dump($instance); + echo "arguments = \n"; + var_dump($arguments); + echo "options = \n"; + var_dump($options); + */ + + return self::callBase($name, $instance, + array_merge($arguments, [$options])); + } + + /** + * Handy for things like self::more. Call a 2-ary vips operator like + * 'more', but if the arg is not an image (ie. it's a constant), call + * 'more_const' instead. + * + * @param mixed $other The right-hand argument. + * @param string $base The base part of the operation name. + * @param string $op The action to invoke. + * @param array $options An array of options to pass to the operation. + * + * @throws Exception + * + * @return mixed The operation result. + * + * @internal + */ + private function callEnum( + $other, + string $base, + string $op, + array $options = [] + ) { + if (self::isImageish($other)) { + return self::call($base, $this, [$other, $op], $options); + } else { + return self::call($base . '_const', $this, [$op, $other], $options); + } + } + + + +// now use the info from introspection to set some parameters on $operation + +trace("setting arguments ..."); +gobject_set($operation, "filename", $filename); + +// build the operation + +trace("building ..."); +$new_operation = $ffi->vips_cache_operation_build($operation); +if (FFI::isNull($new_operation)) { + $ffi->vips_object_unref_outputs($operation); + error(); +} +$operation = $new_operation; + +# need to attach input refs to output + +// fetch required output args + +$image = gobject_get($operation, "out"); +trace("result: " . print_r($image, true)); From 2ebad551814691f16ce43f96a4771651a88a5edb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 28 Jan 2022 18:32:29 +0000 Subject: [PATCH 09/58] more hacking --- composer.json | 1 - src/GObject.php | 2 +- src/GValue.php | 4 +-- src/Image.php | 35 ++++++++++++++++++----- src/Init.php | 16 ++--------- src/Introspect.php | 18 +++++------- src/VipsOperation.php | 65 ++++++++++++++++++++++++------------------- 7 files changed, 77 insertions(+), 64 deletions(-) diff --git a/composer.json b/composer.json index b945a16..c779fe4 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,6 @@ ], "require": { "php": ">=7.1", - "ext-vips": ">=0.1.2", "psr/log": "^1.1.3" }, "require-dev": { diff --git a/src/GObject.php b/src/GObject.php index 95e954e..77f6324 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -73,7 +73,7 @@ function __construct($pointer) { global $ctypes; - $this->gObject = FFI::cast($ctypes["GObject"], $pointer), + $this->gObject = FFI::cast($ctypes["GObject"], $pointer); } function __destruct() { diff --git a/src/GValue.php b/src/GValue.php index fb46781..4432528 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -104,7 +104,7 @@ function set($value) { break; default: - $typeName = $ffi->g_type_name($gtype) + $typeName = $ffi->g_type_name($gtype); throw new \BadMethodCallException("$typeName not implemented"); break; } @@ -141,7 +141,7 @@ function get() { break; default: - $typeName = $ffi->g_type_name($gtype) + $typeName = $ffi->g_type_name($gtype); throw new \BadMethodCallException("$typeName not implemented"); break; } diff --git a/src/Image.php b/src/Image.php index 1f364bc..12a7df4 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1013,20 +1013,41 @@ public static function newFromArray( float $scale = 1.0, float $offset = 0.0 ): Image { + global $ffi; + Utils::debugLog('newFromArray', [ 'instance' => null, 'arguments' => [$array, $scale, $offset] ]); - $result = vips_image_new_from_array($array, $scale, $offset); - if ($result === -1) { + if (!self::is2D($array)) { + $array = [$array]; + } + + $height = count($array); + $width = count($array[0]); + + $n = $width * $height; + $a = $ffi->new("double[]", $n); + for($y = 0; $y < $height; $y++) { + for($x = 0; $x < $width; $x++) { + $a[$x + $y * $width] = $array[y][x]; + } + } + + $result = $ffi-> + vips_image_new_matrix_from_array($width, $height, $a, $n); + if (FFI::isNULL($result)) { self::errorVips(); } $result = self::wrapResult($result); + $image.set_type(GValue::gdouble_type, 'scale', $scale); + $image.set_type(GValue::gdouble_type, 'offset', $offset); + Utils::debugLog('newFromArray', ['result' => $result]); - return $result; + return image; } /** @@ -1054,8 +1075,9 @@ public static function newFromMemory( 'arguments' => [$data, $width, $height, $bands, $format] ]); - $result = vips_image_new_from_memory($data, $width, $height, $bands, $format); - if ($result === -1) { + $result = $ffi-> + vips_image_new_from_memory($data, $width, $height, $bands, $format); + if (FFI::isNULL($result)) { self::errorVips(); } $result = self::wrapResult($result); @@ -1086,8 +1108,7 @@ public static function newInterpolator(string $name) 'arguments' => [$name] ]); - // added in 1.0.7 of the binary module - return vips_interpolate_new($name); + return $ffi->vips_interpolate_new($name); } /** diff --git a/src/Init.php b/src/Init.php index b79d470..fa07891 100644 --- a/src/Init.php +++ b/src/Init.php @@ -41,18 +41,6 @@ /* This file does all the init we need to start up libvips and the binding. */ -# set TRUE for debug output -$trace = TRUE; - -function trace($message) -{ - global $trace; - - if ($trace) { - echo "$message\n"; - } -} - $library_name = "libvips"; # PHP_OS_FAMILY added in php 7.2 @@ -110,13 +98,13 @@ function error($message = "") if ($result != 0) { error(); } -trace("vips_init: $result"); +Utils::debugLog("vips_init: $result"); # get the library version number, then we can build the API $library_major = $base_ffi->vips_version(0); $library_minor = $base_ffi->vips_version(1); $library_micro = $base_ffi->vips_version(2); -trace("found libvips version: $library_major.$library_minor.$library_micro"); +Utils::debugLog("found libvips version: $library_major.$library_minor.$library_micro"); function at_least($need_major, $need_minor) { diff --git a/src/Introspect.php b/src/Introspect.php index 0473e1d..83ee732 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -69,16 +69,16 @@ class Introspection /** * A hash from arg name to a hash of details. */ - protected mixed[] $arguments; + protected array $arguments; /** * Arrays of arg names, in order and by category, eg. $this->required_input * = ["filename"]. */ - protected string[] $required_input; - protected string[] $optional_input; - protected string[] $required_output; - protected string[] $optional_output; + protected array $required_input; + protected array $optional_input; + protected array $required_output; + protected array $optional_output; /** * The name of the arg this operation uses as "this". @@ -88,7 +88,7 @@ class Introspection /** * And the required input args, without the "this". */ - protected string[] $method_args; + protected array $method_args; function __construct($name) { @@ -98,11 +98,7 @@ function __construct($name) $this->name = $name; - $pointer = $ffi->vips_operation_new($name); - if (FFI::isNull($pointer)) { - error(); - } - $operation = new VipsOperation($pointer); + $operation = new VipsOperation($name); $this->description = $operation->getDescription(); $flags = $ffi->vips_operation_get_flags($operation); diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 2fed6e1..1919680 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -62,18 +62,23 @@ abstract class VipsOperation extends VipsObject /** * Cache introsection results here. */ - private static $introspectionCache[] mixed = []; + private static $introspectionCache = []; - function __construct($pointer) + function __construct($name) { global $ffi; global $ctypes; + $pointer = $ffi->vips_operation_new($name); + if (FFI::isNull($pointer)) { + error(); + } + $this->vipsOperation = $ffi->cast($ctypes["VipsOperation"], $pointer); parent::__construct($pointer); } - function getIntrospection($name) { + static function getIntrospection($name) { if (!array_key_exists($introspectionCache, $name)) { $introspectionCache[$name] = new VipsIntrospection($name); } @@ -99,7 +104,7 @@ function getIntrospection($name) { * * @return mixed The result(s) of the operation. */ - function callBase( + static function callBase( string $name, ?Image $instance, array $arguments @@ -109,12 +114,38 @@ function callBase( 'arguments' => $arguments ]); + $arguments = array_merge([$name, $instance], $arguments); + $arguments = array_values(self::unwrap($arguments)); + $operation = new VipsOperation($name); $introspection = $this->getIntrospection($name); - $arguments = array_merge([$name, $instance], $arguments); + trace("setting arguments ..."); + + if (count($introspection->required_input) != count($arguments)) { + } + + + $operation->set("filename", $filename); + + // build the operation + + trace("building ..."); + $new_operation = $ffi->vips_cache_operation_build($operation); + if (FFI::isNull($new_operation)) { + $ffi->vips_object_unref_outputs($operation); + error(); + } + $operation = $new_operation; + + # need to attach input refs to output + + // fetch required output args + + $image = gobject_get($operation, "out"); + trace("result: " . print_r($image, true)); - $arguments = array_values(self::unwrap($arguments)); $result = vips_call(...$arguments); + self::errorIsArray($result); $result = self::wrapResult($result); @@ -190,28 +221,6 @@ private function callEnum( -// now use the info from introspection to set some parameters on $operation - -trace("setting arguments ..."); -gobject_set($operation, "filename", $filename); - -// build the operation - -trace("building ..."); -$new_operation = $ffi->vips_cache_operation_build($operation); -if (FFI::isNull($new_operation)) { - $ffi->vips_object_unref_outputs($operation); - error(); -} -$operation = $new_operation; - -# need to attach input refs to output - -// fetch required output args - -$image = gobject_get($operation, "out"); -trace("result: " . print_r($image, true)); - } From a2e36980cb57d681e2d7f729f61b604e35192172 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 29 Jan 2022 10:45:18 +0000 Subject: [PATCH 10/58] update README --- CHANGELOG.md | 11 ++++- README.md | 76 ++++++++++------------------------ RELEASE-1.0.8 => RELEASE-2.0.0 | 0 src/Init.php | 1 + 4 files changed, 31 insertions(+), 57 deletions(-) rename RELEASE-1.0.8 => RELEASE-2.0.0 (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index b798b57..2ef05be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog All notable changes to `:vips` will be documented in this file. +## 2.0.0 - 2022-1-20 + +Rewritten to use PHP FFI to call into the libvips library rather than a binary +extension. + +No API Changes. + ### 1.0.9 - 2021-11-20 ### Added @@ -18,7 +25,7 @@ All notable changes to `:vips` will be documented in this file. ### Security - Nothing -### 1.0.8 - 2020-08-29 +## 1.0.8 - 2020-08-29 ### Added - allow type names as type params to Image::setType() -- fixes issue with GType @@ -36,7 +43,7 @@ All notable changes to `:vips` will be documented in this file. ### Security - Nothing -### 1.0.7 - 2020-08-28 +## 1.0.7 - 2020-08-28 ### Added - use nullable types and void return type where possible diff --git a/README.md b/README.md index 447f4ef..456eede 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://travis-ci.org/libvips/php-vips.svg?branch=master)](https://travis-ci.org/libvips/php-vips) `php-vips` is a binding for [libvips](https://github.com/libvips/libvips) for -PHP 7. +PHP 7.4 and later. libvips is fast and needs little memory. The [`vips-php-bench`](https://github.com/jcupitt/php-vips-bench) repository @@ -17,54 +17,32 @@ image. When the pipe is connected to a destination, the whole pipeline executes at once and in parallel, streaming the image from source to destination in a set of small fragments. -This module builds upon the `vips` PHP extension: +### Install -https://github.com/libvips/php-vips-ext +You need to [install the libvips +library](https://libvips.github.io/libvips/install.html). It's in the linux +package managers, homebrew and MacPorts, and there are Windows binaries on +the vips website. For example, on Debian: -You'll need to install that first. It's tested on Linux and macOS --- -Windows would need some work, but should be possible. - -See the README there, but briefly: - -1. [Install the libvips library and - headers](https://libvips.github.io/libvips/install.html). It's in - the linux package managers, homebrew and MacPorts, and there are Windows - binaries on the vips website. For example, on Debian: - - ``` - sudo apt-get install libvips-dev - ``` - - Or macOS: - - ``` - brew install vips - ``` - -2. Install the binary PHP extension. You'll need a PHP development environment - for this, since it will download and build the sources for the extension. - For example, on Debian: - - ``` - sudo apt-get install php-pear - ``` - - Then to download and build the extension it's: +``` +sudo apt-get install libvips-dev +``` - ``` - pecl install vips - ``` +Or macOS: - You may need to add `extension=vips.so` or equivalent to `php.ini`, see the - output of pecl. +``` +brew install vips +``` -3. Add vips to your `composer.json`: +Then add vips to your `composer.json`: - ``` - "require": { - "jcupitt/vips" : "1.0.7" - } - ``` +``` +"require": { + "jcupitt/vips" : "dev-switch-to-php-ffi" + # once this is out of beta, switch to + # "jcupitt/vips" : "2.0.0" +} +``` ### Example @@ -156,18 +134,6 @@ introduction: https://libvips.github.io/libvips/API/current -### How it works - -The `vips` extension defines a simple but ugly way to call any libvips -operation from PHP. It uses libvips' own introspection facilities -and does not depend on anything else (so no gobject-introspection, -for example). It's a fairly short 1,600 lines of C. - -This module is a PHP layer over the ugly `vips` extension that -tries to make a nice interface for programmers. It uses `__call()` and -`__get()` to make all libvips operations appear as methods, and all -libvips properties as properties of the PHP `Vips\Image` class. - ### Test and install ``` diff --git a/RELEASE-1.0.8 b/RELEASE-2.0.0 similarity index 100% rename from RELEASE-1.0.8 rename to RELEASE-2.0.0 diff --git a/src/Init.php b/src/Init.php index fa07891..a62df43 100644 --- a/src/Init.php +++ b/src/Init.php @@ -69,6 +69,7 @@ $library = "$library_location$library_name$library_ext"; +# FFI added in 7.4 $base_ffi = FFI::cdef(<< Date: Sat, 29 Jan 2022 11:14:50 +0000 Subject: [PATCH 11/58] new_from_file etc. --- src/Image.php | 113 +++++++++++++------------------------------------- 1 file changed, 29 insertions(+), 84 deletions(-) diff --git a/src/Image.php b/src/Image.php index 12a7df4..ba00e9c 100644 --- a/src/Image.php +++ b/src/Image.php @@ -866,16 +866,27 @@ private static function runCmplx(\Closure $func, Image $image): Image * @return Image A new Image. */ public static function newFromFile( - string $filename, + string $name, array $options = [] ): Image { + global $ffi; + Utils::debugLog('newFromFile', [ 'instance' => null, - 'arguments' => [$filename, $options] + 'arguments' => [$name, $options] ]); + $filename = $ffi->vips_lib.vips_filename_get_filename($name); + $string_options = $ffi->vips_filename_get_options($name); $options = self::unwrap($options); - $result = vips_image_new_from_file($filename, $options); + + $loader = $ffi->vips_foreign_find_load($filename); + if (FFI::isNULL($loader)) { + self::errorVips(); + } + + $result = self::callBase($loader, $filename, + array_merge(["string_options" => $string_options], $options)); self::errorIsArray($result); $result = self::wrapResult($result); @@ -884,51 +895,13 @@ public static function newFromFile( return $result; } - /** - * Find the name of the load operation vips will use to load a file, for - * example "VipsForeignLoadJpegFile". You can use this to work out what - * options to pass to newFromFile(). - * - * @param string $filename The file to test. - * - * @return string|null The name of the load operation, or null. - */ - public static function findLoad(string $filename): ?string - { - Utils::debugLog('findLoad', [ - 'instance' => null, - 'arguments' => [$filename] - ]); - - // added in 1.0.5 of the binary module - if (function_exists('vips_foreign_find_load')) { - $result = vips_foreign_find_load($filename); - } else { - $result = null; - - // fallback: use the vips-loader property ... this can be much slower - try { - $image = self::newFromFile($filename); - // Unfortunately, vips-loader is the operation nickname, rather - // than the canonical name returned by vips_foreign_find_load(). - $loader = $image->get('vips-loader'); - $result = self::$nicknameToCanonical[$loader]; - } catch (Exception $ignored) { - } - } - - Utils::debugLog('findLoad', ['result' => [$result]]); - - return $result; - } - /** * Create a new Image from a compressed image held as a string. * * @param string $buffer The formatted image to open. - * @param string $option_string Any text-style options to pass to the + * @param string $string_options Any text-style options to pass to the * selected loader. - * @param array $options Any options to pass on to the load operation. + * @param array $options Options to pass on to the load operation. * * @throws Exception * @@ -936,16 +909,23 @@ public static function findLoad(string $filename): ?string */ public static function newFromBuffer( string $buffer, - string $option_string = '', + string $string_options = '', array $options = [] ): Image { + global $ffi; + Utils::debugLog('newFromBuffer', [ 'instance' => null, 'arguments' => [$buffer, $option_string, $options] ]); $options = self::unwrap($options); - $result = vips_image_new_from_buffer($buffer, $option_string, $options); + $loader = $ffi->vips_foreign_find_load_buffer($buffer); + if (FFI::isNULL($loader)) { + self::errorVips(); + } + $result = self::callBase($loader, $buffer, + array_merge(["string_options" => $string_options], $options)); self::errorIsArray($result); $result = self::wrapResult($result); @@ -954,45 +934,6 @@ public static function newFromBuffer( return $result; } - /** - * Find the name of the load operation vips will use to load a buffer, for - * example 'VipsForeignLoadJpegBuffer'. You can use this to work out what - * options to pass to newFromBuffer(). - * - * @param string $buffer The formatted image to test. - * - * @return string|null The name of the load operation, or null. - */ - public static function findLoadBuffer(string $buffer): ?string - { - Utils::debugLog('findLoadBuffer', [ - 'instance' => null, - 'arguments' => [$buffer] - ]); - - // added in 1.0.5 of the binary module - if (function_exists('vips_foreign_find_load_buffer')) { - $result = vips_foreign_find_load_buffer($buffer); - } else { - $result = null; - - // fallback: use the vips-loader property ... this can be much slower - try { - $image = self::newFromBuffer($buffer); - // Unfortunately, vips-loader is the operation nickname, rather - // than the canonical name returned by - // vips_foreign_find_load_buffer(). - $loader = $image->get('vips-loader'); - $result = self::$nicknameToCanonical[$loader]; - } catch (Exception $ignored) { - } - } - - Utils::debugLog('findLoadBuffer', ['result' => [$result]]); - - return $result; - } - /** * Create a new Image from a php array. * @@ -1070,6 +1011,8 @@ public static function newFromMemory( int $bands, string $format ): Image { + global $ffi; + Utils::debugLog('newFromMemory', [ 'instance' => null, 'arguments' => [$data, $width, $height, $bands, $format] @@ -1103,6 +1046,8 @@ public static function newFromMemory( */ public static function newInterpolator(string $name) { + global $ffi; + Utils::debugLog('newInterpolator', [ 'instance' => null, 'arguments' => [$name] From e495a75774346b31068bb004cb6799c7725d5ce0 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 29 Jan 2022 11:26:31 +0000 Subject: [PATCH 12/58] more fixes --- src/Image.php | 2 +- src/Init.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Image.php b/src/Image.php index ba00e9c..7e7d126 100644 --- a/src/Image.php +++ b/src/Image.php @@ -876,7 +876,7 @@ public static function newFromFile( 'arguments' => [$name, $options] ]); - $filename = $ffi->vips_lib.vips_filename_get_filename($name); + $filename = $ffi->vips_filename_get_filename($name); $string_options = $ffi->vips_filename_get_options($name); $options = self::unwrap($options); diff --git a/src/Init.php b/src/Init.php index a62df43..4434a36 100644 --- a/src/Init.php +++ b/src/Init.php @@ -41,6 +41,8 @@ /* This file does all the init we need to start up libvips and the binding. */ +echo "*** Init.php: startup\n"; + $library_name = "libvips"; # PHP_OS_FAMILY added in php 7.2 @@ -69,6 +71,8 @@ $library = "$library_location$library_name$library_ext"; +echo "*** Init.php: library = $library\n"; + # FFI added in 7.4 $base_ffi = FFI::cdef(<< Date: Sat, 29 Jan 2022 11:38:55 +0000 Subject: [PATCH 13/58] try to get it to init again --- README.md | 20 +++++++++++++++++--- composer.json | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 456eede..5ce98ce 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,25 @@ brew install vips Then add vips to your `composer.json`: +``` +{ + "repositories": [ + { + "type": "path", + "url": "/your/local/path/to/php-vips" + } + ], + "require": { + "jcupitt/vips": "*" + } +} +``` + +Once this is finished, switch to: + ``` "require": { - "jcupitt/vips" : "dev-switch-to-php-ffi" - # once this is out of beta, switch to - # "jcupitt/vips" : "2.0.0" + "jcupitt/vips" : "2.0.0" } ``` diff --git a/composer.json b/composer.json index c779fe4..e85049d 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ } ], "require": { - "php": ">=7.1", + "php": ">=7.4", "psr/log": "^1.1.3" }, "require-dev": { From 3951af822fb013927ecad686f49bec3a0e40799d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 29 Jan 2022 16:51:21 +0000 Subject: [PATCH 14/58] make init into a singleton class --- src/Image.php | 26 ++---- src/Init.php | 230 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 145 insertions(+), 111 deletions(-) diff --git a/src/Image.php b/src/Image.php index 7e7d126..e8a7dd8 100644 --- a/src/Image.php +++ b/src/Image.php @@ -869,18 +869,16 @@ public static function newFromFile( string $name, array $options = [] ): Image { - global $ffi; - Utils::debugLog('newFromFile', [ 'instance' => null, 'arguments' => [$name, $options] ]); - $filename = $ffi->vips_filename_get_filename($name); - $string_options = $ffi->vips_filename_get_options($name); + $filename = getFfi()->vips_filename_get_filename($name); + $string_options = getFfi()->vips_filename_get_options($name); $options = self::unwrap($options); - $loader = $ffi->vips_foreign_find_load($filename); + $loader = getFfi()->vips_foreign_find_load($filename); if (FFI::isNULL($loader)) { self::errorVips(); } @@ -912,15 +910,13 @@ public static function newFromBuffer( string $string_options = '', array $options = [] ): Image { - global $ffi; - Utils::debugLog('newFromBuffer', [ 'instance' => null, 'arguments' => [$buffer, $option_string, $options] ]); $options = self::unwrap($options); - $loader = $ffi->vips_foreign_find_load_buffer($buffer); + $loader = getFfi()->vips_foreign_find_load_buffer($buffer); if (FFI::isNULL($loader)) { self::errorVips(); } @@ -954,8 +950,6 @@ public static function newFromArray( float $scale = 1.0, float $offset = 0.0 ): Image { - global $ffi; - Utils::debugLog('newFromArray', [ 'instance' => null, 'arguments' => [$array, $scale, $offset] @@ -969,14 +963,14 @@ public static function newFromArray( $width = count($array[0]); $n = $width * $height; - $a = $ffi->new("double[]", $n); + $a = getFfi()->new("double[]", $n); for($y = 0; $y < $height; $y++) { for($x = 0; $x < $width; $x++) { $a[$x + $y * $width] = $array[y][x]; } } - $result = $ffi-> + $result = getFfi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); if (FFI::isNULL($result)) { self::errorVips(); @@ -1011,14 +1005,12 @@ public static function newFromMemory( int $bands, string $format ): Image { - global $ffi; - Utils::debugLog('newFromMemory', [ 'instance' => null, 'arguments' => [$data, $width, $height, $bands, $format] ]); - $result = $ffi-> + $result = getFfi()-> vips_image_new_from_memory($data, $width, $height, $bands, $format); if (FFI::isNULL($result)) { self::errorVips(); @@ -1046,14 +1038,12 @@ public static function newFromMemory( */ public static function newInterpolator(string $name) { - global $ffi; - Utils::debugLog('newInterpolator', [ 'instance' => null, 'arguments' => [$name] ]); - return $ffi->vips_interpolate_new($name); + return getFfi()->vips_interpolate_new($name); } /** diff --git a/src/Init.php b/src/Init.php index 4434a36..4bf0b6a 100644 --- a/src/Init.php +++ b/src/Init.php @@ -38,43 +38,98 @@ namespace Jcupitt\Vips; -/* This file does all the init we need to start up libvips and the binding. +/** + * This singleton class manages the connection to the libvips binary. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/jcupitt/php-vips */ -echo "*** Init.php: startup\n"; - -$library_name = "libvips"; - -# PHP_OS_FAMILY added in php 7.2 -switch(PHP_OS_FAMILY) { -case "Windows": - $library_ext = ".dll"; - break; +function getFfi() +{ + static $instance; -case "OSX": - $library_ext = ".dylib"; - break; + if (!$instance) { + $instance = new Init(); + $instance->init(); + } -default; - $library_ext = ".so"; - break; + return $instance; } -$vipshome = getenv("VIPSHOME"); -if ($vipshome) { - $library_location = $vipshome . "/lib/"; -} -else { - # rely on ffi's search - $library_location = ""; -} +class Init +{ + /** + * The FFI handle we use for the libvips binary. + * + * @internal + */ + private static $ffi; + + /** + * The library version number we detect. + * + * @internal + */ + private static int $library_major; + private static int $library_minor; + private static int $library_micro; + + public function __construct() + { + } -$library = "$library_location$library_name$library_ext"; + public function error($message = "") + { + if ($message == "") { + $message = "libvips error: $this->ffi->vips_error_buffer()"; + $this->ffi->vips_error_clear(); + } + throw new Exception($message); + } -echo "*** Init.php: library = $library\n"; + public function atLeast($need_major, $need_minor) + { + return $need_major < $this->library_major || + ($need_major == $this->library_major && + $need_minor <= $this->library_minor); + } -# FFI added in 7.4 -$base_ffi = FFI::cdef(<<ffi = FFI::cdef(<<vips_error_clear(); - } - - throw new Exception($message); -} - -$result = $base_ffi->vips_init($argv[0]); -if ($result != 0) { - error(); -} -Utils::debugLog("vips_init: $result"); - -# get the library version number, then we can build the API -$library_major = $base_ffi->vips_version(0); -$library_minor = $base_ffi->vips_version(1); -$library_micro = $base_ffi->vips_version(2); -Utils::debugLog("found libvips version: $library_major.$library_minor.$library_micro"); - -function at_least($need_major, $need_minor) -{ - global $library_major, $library_minor; - - return $need_major < $library_major || - ($need_major == $library_major && $need_minor <= $library_minor); -} - -if (!at_least(8, 7)) { - error("your libvips is too old -- 8.7 or later required"); -} - -if (PHP_INT_SIZE != 8) { - # we could maybe fix this if it's important ... it's mostly necessary since - # GType is the size of a pointer, and there's no easy way to discover if php - # is running on a 32 or 64-bit systems (as far as I can see) - error("your php only supports 32-bit ints -- 64 bit ints required"); -} - -// bind the libvips API to the library binary - -# largely copied from pyvips -$header = <<ffi->vips_init($argv[0]); + if ($result != 0) { + $this->error(); + } + Utils::debugLog("vips_init: $result"); + + # get the library version number, then we can build the API + $this->library_major = $this->ffi->vips_version(0); + $this->library_minor = $this->ffi->vips_version(1); + $this->library_micro = $this->ffi->vips_version(2); + Utils::debugLog("found libvips version: " . + "$this->library_major.$this->library_minor.$this->library_micro"); + + if (!$this->atLeast(8, 7)) { + $this->error("your libvips is too old -- 8.7 or later required"); + } + + if (PHP_INT_SIZE != 8) { + # we could maybe fix this if it's important ... it's mostly + # necessary since GType is the size of a pointer, and there's no + # easy way to discover if php is running on a 32 or 64-bit + # systems (as far as I can see) + $this->error("your php only supports 32-bit ints -- " . + "64 bit ints required"); + } + + # the whole libvips API, mostly adapted from pyvips + $header = <<atLeast(8, 8)) { + $header = $header . <<atLeast(8, 8)) { + $header = $header . <<cdef($header, $library); -$ffi = FFI::cdef($header, $library); + # FIXME make ctypes and gtypes -# FIXME make ctypes and gtypes + Utils::debugLog("done"); + } +} /* -* 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 -*/ - + * 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 + */ From 096cc4eb1dd3ed9086f3de79ba9045751d0ca480 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 30 Jan 2022 12:26:52 +0000 Subject: [PATCH 15/58] move the singleton to a static member --- src/Image.php | 16 ++++++++-------- src/Init.php | 24 ++++++++++++------------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Image.php b/src/Image.php index e8a7dd8..9921032 100644 --- a/src/Image.php +++ b/src/Image.php @@ -874,11 +874,11 @@ public static function newFromFile( 'arguments' => [$name, $options] ]); - $filename = getFfi()->vips_filename_get_filename($name); - $string_options = getFfi()->vips_filename_get_options($name); + $filename = Init::ffi()->vips_filename_get_filename($name); + $string_options = Init::ffi()->vips_filename_get_options($name); $options = self::unwrap($options); - $loader = getFfi()->vips_foreign_find_load($filename); + $loader = Init::ffi()->vips_foreign_find_load($filename); if (FFI::isNULL($loader)) { self::errorVips(); } @@ -916,7 +916,7 @@ public static function newFromBuffer( ]); $options = self::unwrap($options); - $loader = getFfi()->vips_foreign_find_load_buffer($buffer); + $loader = Init::ffi()->vips_foreign_find_load_buffer($buffer); if (FFI::isNULL($loader)) { self::errorVips(); } @@ -963,14 +963,14 @@ public static function newFromArray( $width = count($array[0]); $n = $width * $height; - $a = getFfi()->new("double[]", $n); + $a = Init::ffi()->new("double[]", $n); for($y = 0; $y < $height; $y++) { for($x = 0; $x < $width; $x++) { $a[$x + $y * $width] = $array[y][x]; } } - $result = getFfi()-> + $result = Init::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); if (FFI::isNULL($result)) { self::errorVips(); @@ -1010,7 +1010,7 @@ public static function newFromMemory( 'arguments' => [$data, $width, $height, $bands, $format] ]); - $result = getFfi()-> + $result = Init::ffi()-> vips_image_new_from_memory($data, $width, $height, $bands, $format); if (FFI::isNULL($result)) { self::errorVips(); @@ -1043,7 +1043,7 @@ public static function newInterpolator(string $name) 'arguments' => [$name] ]); - return getFfi()->vips_interpolate_new($name); + return Init::ffi()->vips_interpolate_new($name); } /** diff --git a/src/Init.php b/src/Init.php index 4bf0b6a..d8930e5 100644 --- a/src/Init.php +++ b/src/Init.php @@ -49,18 +49,6 @@ * @link https://github.com/jcupitt/php-vips */ -function getFfi() -{ - static $instance; - - if (!$instance) { - $instance = new Init(); - $instance->init(); - } - - return $instance; -} - class Init { /** @@ -79,6 +67,18 @@ class Init private static int $library_minor; private static int $library_micro; + public static function ffi() + { + static $instance; + + if (!$instance) { + $instance = new Init(); + $instance->init(); + } + + return $instance->ffi; + } + public function __construct() { } From d06e82f15bd98f7ea765e9988b99f686e2fb59b6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 30 Jan 2022 13:01:28 +0000 Subject: [PATCH 16/58] fixed up init get the ffi handle from a static method --- src/Image.php | 11 ++++--- src/Init.php | 84 +++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/src/Image.php b/src/Image.php index 9921032..b62d3e1 100644 --- a/src/Image.php +++ b/src/Image.php @@ -774,7 +774,8 @@ private static function wrapResult($result) */ private static function errorVips(): void { - $message = vips_error_buffer(); + $message = Init::ffi()->vips_error_buffer(); + Init::ffi()->vips_error_buffer_clear(); $exception = new Exception($message); Utils::errorLog($message, $exception); throw $exception; @@ -879,7 +880,7 @@ public static function newFromFile( $options = self::unwrap($options); $loader = Init::ffi()->vips_foreign_find_load($filename); - if (FFI::isNULL($loader)) { + if ($loader == "") { self::errorVips(); } @@ -917,7 +918,7 @@ public static function newFromBuffer( $options = self::unwrap($options); $loader = Init::ffi()->vips_foreign_find_load_buffer($buffer); - if (FFI::isNULL($loader)) { + if (\FFI::isNULL($loader)) { self::errorVips(); } $result = self::callBase($loader, $buffer, @@ -972,7 +973,7 @@ public static function newFromArray( $result = Init::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); - if (FFI::isNULL($result)) { + if (\FFI::isNULL($result)) { self::errorVips(); } $result = self::wrapResult($result); @@ -1012,7 +1013,7 @@ public static function newFromMemory( $result = Init::ffi()-> vips_image_new_from_memory($data, $width, $height, $bands, $format); - if (FFI::isNULL($result)) { + if (\FFI::isNULL($result)) { self::errorVips(); } $result = self::wrapResult($result); diff --git a/src/Init.php b/src/Init.php index d8930e5..7557ec7 100644 --- a/src/Init.php +++ b/src/Init.php @@ -48,7 +48,6 @@ * @license https://opensource.org/licenses/MIT MIT * @link https://github.com/jcupitt/php-vips */ - class Init { /** @@ -56,18 +55,18 @@ class Init * * @internal */ - private static $ffi; + private \FFI $ffi; /** * The library version number we detect. * * @internal */ - private static int $library_major; - private static int $library_minor; - private static int $library_micro; + private int $library_major; + private int $library_minor; + private int $library_micro; - public static function ffi() + public static function getInit() { static $instance; @@ -76,20 +75,16 @@ public static function ffi() $instance->init(); } - return $instance->ffi; + return $instance; } - public function __construct() + public static function ffi() { + return self::getInit()->ffi; } - public function error($message = "") + public function __construct() { - if ($message == "") { - $message = "libvips error: $this->ffi->vips_error_buffer()"; - $this->ffi->vips_error_clear(); - } - throw new Exception($message); } public function atLeast($need_major, $need_minor) @@ -127,42 +122,36 @@ private function init() } $library = "$library_location$library_name$library_ext"; + Utils::debugLog("init", ["libray", $library]); - try { - $this->ffi = FFI::cdef(<<ffi->vips_init($argv[0]); + $result = $ffi->vips_init(""); if ($result != 0) { - $this->error(); + throw new Exception("libvips error: $ffi->vips_error_buffer()"); } - Utils::debugLog("vips_init: $result"); + Utils::debugLog("init", ["vips_init", $result]); # get the library version number, then we can build the API - $this->library_major = $this->ffi->vips_version(0); - $this->library_minor = $this->ffi->vips_version(1); - $this->library_micro = $this->ffi->vips_version(2); - Utils::debugLog("found libvips version: " . - "$this->library_major.$this->library_minor.$this->library_micro"); + $this->library_major = $ffi->vips_version(0); + $this->library_minor = $ffi->vips_version(1); + $this->library_micro = $ffi->vips_version(2); + Utils::debugLog("init", [ + "libvips version", + $this->library_major, + $this->library_minor, + $this->library_micro + ]); if (!$this->atLeast(8, 7)) { - $this->error("your libvips is too old -- 8.7 or later required"); + throw new Exception("your libvips is too old -- " . + "8.7 or later required"); } if (PHP_INT_SIZE != 8) { @@ -170,7 +159,7 @@ private function init() # necessary since GType is the size of a pointer, and there's no # easy way to discover if php is running on a 32 or 64-bit # systems (as far as I can see) - $this->error("your php only supports 32-bit ints -- " . + throw new Exception("your php only supports 32-bit ints -- " . "64 bit ints required"); } @@ -190,6 +179,17 @@ private function init() typedef struct _VipsProgress VipsProgress; typedef struct _GValue GValue; +int vips_init (const char *argv0); +int vips_shutdown (void); + +const char *vips_error_buffer (void); +char *vips_error_buffer_copy (void); +void vips_error_clear (void); +void vips_error_freeze (void); +void vips_error_thaw (void); + +int vips_version(int flag); + void* g_malloc (size_t size); void g_free (void* data); @@ -580,12 +580,12 @@ private function init() EOS; } - Utils::debugLog("building binding ..."); - $ffi->cdef($header, $library); + Utils::debugLog("init", ["binding ..."]); + $this->ffi = \FFI::cdef($header, $library); # FIXME make ctypes and gtypes - Utils::debugLog("done"); + Utils::debugLog("init", ["done"]); } } From 0990d62b617a16ac99020f00eb646ecaa559179f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 4 Feb 2022 08:32:25 +0000 Subject: [PATCH 17/58] hack hack hack --- src/GObject.php | 8 +- src/GValue.php | 63 +++----- src/Image.php | 367 ++++++++---------------------------------- src/ImageAutodoc.php | 2 +- src/Init.php | 93 +++++++++-- src/VipsObject.php | 64 +++----- src/VipsOperation.php | 139 +++++++++++++--- 7 files changed, 309 insertions(+), 427 deletions(-) diff --git a/src/GObject.php b/src/GObject.php index 77f6324..08c524e 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -55,7 +55,7 @@ abstract class GObject * * @internal */ - private FFI\CData $gObject; + private \FFI\CData $gObject; /** * Wrap a GObject around an underlying vips resource. The GObject takes @@ -73,13 +73,11 @@ function __construct($pointer) { global $ctypes; - $this->gObject = FFI::cast($ctypes["GObject"], $pointer); + $this->gObject = \FFI::cast(Init::ctypes("GObject"), $pointer); } function __destruct() { - global $ffi; - - $ffi->g_object_unref($this->gObject); + Init::ffi()->g_object_unref($this->gObject); } // TODO signal marshalling to go in diff --git a/src/GValue.php b/src/GValue.php index 4432528..092ea0d 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -38,25 +38,14 @@ namespace Jcupitt\Vips; -// look these up in advance -$gtypes = [ - "gboolean" => $ffi->g_type_from_name("gboolean"), - "gchararray" => $ffi->g_type_from_name("gchararray"), - "VipsRefString" => $ffi->g_type_from_name("VipsRefString"), - "VipsImage" => $ffi->g_type_from_name("VipsImage"), - "GObject" => $ffi->g_type_from_name("GObject"), -]; - class GValue { private FFI\CData $struct; public FFI\CData $pointer; function __construct() { - global $ffi; - # allocate a gvalue on the heap, and make it persistent between requests - $this->struct = $ffi->new("GValue", true, true); + $this->struct = Init::ffi()->new("GValue", true, true); $this->pointer = FFI::addr($this->struct); # GValue needs to be inited to all zero @@ -64,15 +53,11 @@ function __construct() { } function __destruct() { - global $ffi; - - $ffi->g_value_unset($this->pointer); + Init::ffi()->g_value_unset($this->pointer); } function setType(int $gtype) { - global $ffi; - - $ffi->g_value_init($this->pointer, $gtype); + Init::ffi()->g_value_init($this->pointer, $gtype); } function getType(): int { @@ -80,31 +65,29 @@ function getType(): int { } function set($value) { - global $ffi, $gtypes; - $gtype = $this->get_type(); switch ($gtype) { - case $gtypes["gboolean"]: - $ffi->g_value_set_boolean($this->pointer, $value); + case Init::gtypes("gboolean"): + Init::ffi()->g_value_set_boolean($this->pointer, $value); break; - case $gtypes["gchararray"]: - $ffi->g_value_set_string($this->pointer, $value); + case Init::gtypes("gchararray"): + Init::ffi()->g_value_set_string($this->pointer, $value); break; - case $gtypes["VipsRefString"]: - $ffi->vips_value_set_ref_string($this->pointer, $value); + case Init::gtypes("VipsRefString"): + Init::ffi()->vips_value_set_ref_string($this->pointer, $value); break; default: - $fundamental = $ffi->g_type_fundamental($gtype); + $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case $gtypes["GObject"]: + case Init::gtypes("GObject"): break; default: - $typeName = $ffi->g_type_name($gtype); + $typeName = Init::ffi()->g_type_name($gtype); throw new \BadMethodCallException("$typeName not implemented"); break; } @@ -112,36 +95,34 @@ function set($value) { } function get() { - global $ffi, $gtypes; - $gtype = $this->get_type(); $result = null; switch ($gtype) { - case $gtypes["gboolean"]: - $result = $ffi->g_value_get_boolean($this->pointer); + case Init::gtypes("gboolean"): + $result = Init::ffi()->g_value_get_boolean($this->pointer); break; - case $gtypes["gchararray"]: - $ffi->g_value_get_string($this->pointer); + case Init::gtypes("gchararray"): + Init::ffi()->g_value_get_string($this->pointer); break; - case $gtypes["VipsRefString"]: - $psize = $ffi->new("size_t*"); - $result = $ffi->vips_value_get_ref_string($this->pointer, $psize); + case Init::gtypes("VipsRefString"): + $psize = Init::ffi()->new("size_t*"); + $result = Init::ffi()->vips_value_get_ref_string($this->pointer, $psize); # $psize[0] will be the string length, but assume it's null # terminated break; default: - $fundamental = $ffi->g_type_fundamental($gtype); + $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case $gtypes["GObject"]: + case Init::gtypes("GObject"): # we need a class wrapping gobject before we can impement this break; default: - $typeName = $ffi->g_type_name($gtype); + $typeName = Init::ffi()->g_type_name($gtype); throw new \BadMethodCallException("$typeName not implemented"); break; } diff --git a/src/Image.php b/src/Image.php index b62d3e1..3865919 100644 --- a/src/Image.php +++ b/src/Image.php @@ -576,26 +576,25 @@ class Image extends ImageAutodoc implements \ArrayAccess ]; /** - * The resource for the underlying VipsImage. + * A pointer to the underlying VipsImage. This is the same as the + * GObject, just cast to VipsImage to help FFI. * * @internal */ - private $image; + private FFI\CData $image; /** - * Wrap a Image around an underlying vips resource. + * Wrap an Image around an underlying CData pointer. * * Don't call this yourself, users should stick to (for example) * Image::newFromFile(). * - * @param resource $image The underlying vips image resource that this - * class should wrap. - * * @internal */ - public function __construct($image) + public function __construct($pointer) { - $this->image = $image; + $this->image = Init::ffi()->cast(Init::ctypes("VipsImage"), $pointer); + parent::__construct($pointer); } /** @@ -692,117 +691,6 @@ private static function imageize(Image $match_image, $value): Image return $result; } - /** - * Unwrap an array of stuff ready to pass down to the vips_ layer. We - * swap instances of the Image for the plain resource. - * - * @param array $result Unwrap this. - * - * @return array $result unwrapped, ready for vips. - * - * @internal - */ - private static function unwrap(array $result): array - { - array_walk_recursive($result, function (&$value) { - if ($value instanceof Image) { - $value = $value->image; - } - }); - - return $result; - } - - /** - * Is $value a VipsImage. - * - * @param mixed $value The thing to test. - * - * @return bool true if this is a vips image resource. - * - * @internal - */ - private static function isImage($value): bool - { - return is_resource($value) && - get_resource_type($value) === 'GObject'; - } - - /** - * Wrap up the result of a vips_ call ready to return it to PHP. We do - * two things: - * - * - If the array is a singleton, we strip it off. For example, many - * operations return a single result and there's no sense handling - * this as an array of values, so we transform ['out' => x] -> x. - * - * - Any VipsImage resources are rewrapped as instances of Image. - * - * @param mixed $result Wrap this up. - * - * @return mixed $result, but wrapped up as a php class. - * - * @internal - */ - private static function wrapResult($result) - { - if (!is_array($result)) { - $result = ['x' => $result]; - } - - array_walk_recursive($result, function (&$item) { - if (self::isImage($item)) { - $item = new self($item); - } - }); - - if (count($result) === 1) { - $result = array_shift($result); - } - - return $result; - } - - /** - * Throw a vips error as an exception. - * - * @throws Exception - * - * @return void - * - * @internal - */ - private static function errorVips(): void - { - $message = Init::ffi()->vips_error_buffer(); - Init::ffi()->vips_error_buffer_clear(); - $exception = new Exception($message); - Utils::errorLog($message, $exception); - throw $exception; - } - - /** - * Check the result of a vips_ call for an error, and throw an exception - * if we see one. - * - * This won't work for things like __get where a non-array return can be - * a valid return. - * - * @param mixed $result Test this. - * - * @throws Exception - * - * @return void - * - * @internal - */ - private static function errorIsArray($result): void - { - if (!is_array($result)) { - self::errorVips(); - } - } - /** * Run a function expecting a complex image. If the image is not in complex * format, try to make it complex by joining adjacant bands as real and @@ -875,19 +763,18 @@ public static function newFromFile( 'arguments' => [$name, $options] ]); - $filename = Init::ffi()->vips_filename_get_filename($name); - $string_options = Init::ffi()->vips_filename_get_options($name); - $options = self::unwrap($options); + $filename = Init::filename_get_filename($name); + $string_options = Init::filename_get_options($name); $loader = Init::ffi()->vips_foreign_find_load($filename); if ($loader == "") { - self::errorVips(); + Init::error(); } - $result = self::callBase($loader, $filename, - array_merge(["string_options" => $string_options], $options)); - self::errorIsArray($result); - $result = self::wrapResult($result); + $result = VipsOperation::callBase($loader, null, array_merge([ + "filename" => $filename, + "string_options" => $string_options, + ], $options)); Utils::debugLog('newFromFile', ['result' => $result]); @@ -916,15 +803,13 @@ public static function newFromBuffer( 'arguments' => [$buffer, $option_string, $options] ]); - $options = self::unwrap($options); $loader = Init::ffi()->vips_foreign_find_load_buffer($buffer); - if (\FFI::isNULL($loader)) { - self::errorVips(); + if (\FFI::isNull($loader)) { + Init::error(); } - $result = self::callBase($loader, $buffer, - array_merge(["string_options" => $string_options], $options)); - self::errorIsArray($result); - $result = self::wrapResult($result); + $result = VipsOperation::callBase($loader, $buffer, array_merge([ + "string_options" => $string_options + ], $options)); Utils::debugLog('newFromBuffer', ['result' => $result]); @@ -973,10 +858,9 @@ public static function newFromArray( $result = Init::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); - if (\FFI::isNULL($result)) { - self::errorVips(); + if (\FFI::isNull($result)) { + Init::error(); } - $result = self::wrapResult($result); $image.set_type(GValue::gdouble_type, 'scale', $scale); $image.set_type(GValue::gdouble_type, 'offset', $offset); @@ -1013,10 +897,9 @@ public static function newFromMemory( $result = Init::ffi()-> vips_image_new_from_memory($data, $width, $height, $bands, $format); - if (\FFI::isNULL($result)) { - self::errorVips(); + if (\FFI::isNull($result)) { + Init::error(); } - $result = self::wrapResult($result); Utils::debugLog('newFromMemory', ['result' => $result]); @@ -1109,10 +992,9 @@ public function writeToFile(string $filename, array $options = []): void 'arguments' => [$filename, $options] ]); - $options = self::unwrap($options); - $result = vips_image_write_to_file($this->image, $filename, $options); + $result = Init::ffi()->vips_image_write_to_file($this->image, $filename, $options); if ($result === -1) { - self::errorVips(); + Init::error(); } } @@ -1134,12 +1016,10 @@ public function writeToBuffer(string $suffix, array $options = []): string 'arguments' => [$suffix, $options] ]); - $options = self::unwrap($options); - $result = vips_image_write_to_buffer($this->image, $suffix, $options); + $result = Init::ffi()->vips_image_write_to_buffer($this->image, $suffix, $options); if ($result === -1) { - self::errorVips(); + Init::error(); } - $result = self::wrapResult($result); Utils::debugLog('writeToBuffer', ['result' => $result]); @@ -1160,9 +1040,9 @@ public function writeToMemory(): string 'arguments' => [] ]); - $result = vips_image_write_to_memory($this->image); + $result = Init::ffi()->vips_image_write_to_memory($this->image); if ($result === -1) { - self::errorVips(); + Init::error(); } Utils::debugLog('writeToMemory', ['result' => $result]); @@ -1200,9 +1080,9 @@ public function writeToArray(): array 'arguments' => [] ]); - $result = vips_image_write_to_array($this->image); + $result = Init::ffi()->vips_image_write_to_array($this->image); if ($result === -1) { - self::errorVips(); + Init::error(); } Utils::debugLog('writeToArray', ['result' => $result]); @@ -1231,11 +1111,10 @@ public function copyMemory(): Image 'arguments' => [] ]); - $result = vips_image_copy_memory($this->image); + $result = Init::ffi()->vips_image_copy_memory($this->image); if ($result === -1) { - self::errorVips(); + Init::error(); } - $result = self::wrapResult($result); Utils::debugLog('copyMemory', ['result' => $result]); @@ -1253,9 +1132,7 @@ public function copyMemory(): Image */ public function __get(string $name) { - $result = vips_image_get($this->image, $name); - self::errorIsArray($result); - return self::wrapResult($result); + return Init::ffi()->vips_image_get($this->image, $name); } /** @@ -1268,7 +1145,7 @@ public function __get(string $name) */ public function __set(string $name, $value): void { - vips_image_set($this->image, $name, $value); + Init::ffi()->vips_image_set($this->image, $name, $value); } /** @@ -1300,9 +1177,7 @@ public function __isset(string $name): bool */ public function get(string $name) { - $result = vips_image_get($this->image, $name); - self::errorIsArray($result); - return self::wrapResult($result); + return Init::ffi()->vips_image_get($this->image, $name); } /** @@ -1316,7 +1191,7 @@ public function get(string $name) */ public function typeof(string $name): int { - return vips_image_get_typeof($this->image, $name); + return Init::ffi()->vips_image_get_typeof($this->image, $name); } /** @@ -1334,9 +1209,9 @@ public function typeof(string $name): int */ public function set(string $name, $value): void { - $result = vips_image_set($this->image, $name, $value); + $result = Init::ffi()->vips_image_set($this->image, $name, $value); if ($result === -1) { - self::errorVips(); + Init::error(); } } @@ -1359,9 +1234,9 @@ public function set(string $name, $value): void */ public function setType($type, string $name, $value): void { - $result = vips_image_set_type($this->image, $type, $name, $value); + $result = Init::ffi()->vips_image_set_type($this->image, $type, $name, $value); if ($result === -1) { - self::errorVips(); + Init::error(); } } @@ -1376,9 +1251,9 @@ public function setType($type, string $name, $value): void */ public function remove(string $name): void { - $result = vips_image_remove($this->image, $name); + $result = Init::ffi()->vips_image_remove($this->image, $name); if ($result === -1) { - self::errorVips(); + Init::error(); } } @@ -1400,110 +1275,6 @@ public function __toString() return json_encode($array); } - /** - * Call any vips operation. The final element of $arguments can be - * (but doesn't have to be) an array of options to pass to the operation. - * - * We can't have a separate arg for the options since this will be run from - * __call(), which cannot know which args are required and which are - * optional. See call() below for a version with the options broken out. - * - * @param string $name The operation name. - * @param Image|null $instance The instance this operation is being invoked - * from. - * @param array $arguments An array of arguments to pass to the - * operation. - * - * @throws Exception - * - * @return mixed The result(s) of the operation. - */ - public static function callBase( - string $name, - ?Image $instance, - array $arguments - ) { - Utils::debugLog($name, [ - 'instance' => $instance, - 'arguments' => $arguments - ]); - - $arguments = array_merge([$name, $instance], $arguments); - - $arguments = array_values(self::unwrap($arguments)); - $result = vips_call(...$arguments); - self::errorIsArray($result); - $result = self::wrapResult($result); - - Utils::debugLog($name, ['result' => $result]); - - return $result; - } - - /** - * Call any vips operation, with an explicit set of options. This is more - * convenient than callBase() if you have a set of known options. - * - * @param string $name The operation name. - * @param Image|null $instance The instance this operation is being invoked - * from. - * @param array $arguments An array of arguments to pass to the - * operation. - * @param array $options An array of optional arguments to pass to - * the operation. - * - * @throws Exception - * - * @return mixed The result(s) of the operation. - */ - public static function call( - string $name, - ?Image $instance, - array $arguments, - array $options = [] - ) { - /* - echo "call: $name \n"; - echo "instance = \n"; - var_dump($instance); - echo "arguments = \n"; - var_dump($arguments); - echo "options = \n"; - var_dump($options); - */ - - return self::callBase($name, $instance, array_merge($arguments, [$options])); - } - - /** - * Handy for things like self::more. Call a 2-ary vips operator like - * 'more', but if the arg is not an image (ie. it's a constant), call - * 'more_const' instead. - * - * @param mixed $other The right-hand argument. - * @param string $base The base part of the operation name. - * @param string $op The action to invoke. - * @param array $options An array of options to pass to the operation. - * - * @throws Exception - * - * @return mixed The operation result. - * - * @internal - */ - private function callEnum( - $other, - string $base, - string $op, - array $options = [] - ) { - if (self::isImageish($other)) { - return self::call($base, $this, [$other, $op], $options); - } else { - return self::call($base . '_const', $this, [$op, $other], $options); - } - } - /** * Call any vips operation as an instance method. * @@ -1516,7 +1287,7 @@ private function callEnum( */ public function __call(string $name, array $arguments) { - return self::callBase($name, $this, $arguments); + return VipsOperation::callBase($name, $this, $arguments); } /** @@ -1531,7 +1302,7 @@ public function __call(string $name, array $arguments) */ public static function __callStatic(string $name, array $arguments) { - return self::callBase($name, null, $arguments); + return VipsOperation::callBase($name, null, $arguments); } /** @@ -1686,7 +1457,7 @@ public function offsetUnset($offset): void public function add($other, array $options = []): Image { if (self::isImageish($other)) { - return self::call('add', $this, [$other], $options); + return VipsOperation::call('add', $this, [$other], $options); } else { return $this->linear(1, $other, $options); } @@ -1705,7 +1476,7 @@ public function add($other, array $options = []): Image public function subtract($other, array $options = []): Image { if (self::isImageish($other)) { - return self::call('subtract', $this, [$other], $options); + return VipsOperation::call('subtract', $this, [$other], $options); } else { $other = self::mapNumeric($other, function ($value) { return -1 * $value; @@ -1727,7 +1498,7 @@ public function subtract($other, array $options = []): Image public function multiply($other, array $options = []): Image { if (self::isImageish($other)) { - return self::call('multiply', $this, [$other], $options); + return VipsOperation::call('multiply', $this, [$other], $options); } else { return $this->linear($other, 0, $options); } @@ -1746,7 +1517,7 @@ public function multiply($other, array $options = []): Image public function divide($other, array $options = []): Image { if (self::isImageish($other)) { - return self::call('divide', $this, [$other], $options); + return VipsOperation::call('divide', $this, [$other], $options); } else { $other = self::mapNumeric($other, function ($value) { return $value ** -1; @@ -1768,9 +1539,9 @@ public function divide($other, array $options = []): Image public function remainder($other, array $options = []): Image { if (self::isImageish($other)) { - return self::call('remainder', $this, [$other], $options); + return VipsOperation::call('remainder', $this, [$other], $options); } else { - return self::call('remainder_const', $this, [$other], $options); + return VipsOperation::call('remainder_const', $this, [$other], $options); } } @@ -1786,7 +1557,7 @@ public function remainder($other, array $options = []): Image */ public function pow($other, array $options = []): Image { - return $this->callEnum($other, 'math2', OperationMath2::POW, $options); + return VipsOperation::callEnum($other, 'math2', OperationMath2::POW, $options); } /** @@ -1801,7 +1572,7 @@ public function pow($other, array $options = []): Image */ public function wop($other, array $options = []): Image { - return $this->callEnum($other, 'math2', OperationMath2::WOP, $options); + return VipsOperation::callEnum($other, 'math2', OperationMath2::WOP, $options); } /** @@ -1816,7 +1587,7 @@ public function wop($other, array $options = []): Image */ public function lshift($other, array $options = []): Image { - return $this->callEnum($other, 'boolean', OperationBoolean::LSHIFT, $options); + return VipsOperation::callEnum($other, 'boolean', OperationBoolean::LSHIFT, $options); } /** @@ -1831,7 +1602,7 @@ public function lshift($other, array $options = []): Image */ public function rshift($other, array $options = []): Image { - return $this->callEnum($other, 'boolean', OperationBoolean::RSHIFT, $options); + return VipsOperation::callEnum($other, 'boolean', OperationBoolean::RSHIFT, $options); } /** @@ -1848,7 +1619,7 @@ public function rshift($other, array $options = []): Image public function andimage($other, array $options = []): Image { // phpdoc hates OperationBoolean::AND, so use the string form here - return $this->callEnum($other, 'boolean', 'and', $options); + return VipsOperation::callEnum($other, 'boolean', 'and', $options); } /** @@ -1864,7 +1635,7 @@ public function andimage($other, array $options = []): Image public function orimage($other, array $options = []): Image { // phpdoc hates OperationBoolean::OR, so use the string form here - return $this->callEnum($other, 'boolean', 'or', $options); + return VipsOperation::callEnum($other, 'boolean', 'or', $options); } /** @@ -1879,7 +1650,7 @@ public function orimage($other, array $options = []): Image */ public function eorimage($other, array $options = []): Image { - return $this->callEnum($other, 'boolean', OperationBoolean::EOR, $options); + return VipsOperation::callEnum($other, 'boolean', OperationBoolean::EOR, $options); } /** @@ -1894,7 +1665,7 @@ public function eorimage($other, array $options = []): Image */ public function more($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::MORE, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::MORE, $options); } /** @@ -1909,7 +1680,7 @@ public function more($other, array $options = []): Image */ public function moreEq($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::MOREEQ, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::MOREEQ, $options); } /** @@ -1924,7 +1695,7 @@ public function moreEq($other, array $options = []): Image */ public function less($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::LESS, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::LESS, $options); } /** @@ -1939,7 +1710,7 @@ public function less($other, array $options = []): Image */ public function lessEq($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::LESSEQ, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::LESSEQ, $options); } /** @@ -1954,7 +1725,7 @@ public function lessEq($other, array $options = []): Image */ public function equal($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::EQUAL, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::EQUAL, $options); } /** @@ -1969,7 +1740,7 @@ public function equal($other, array $options = []): Image */ public function notEq($other, array $options = []): Image { - return $this->callEnum($other, 'relational', OperationRelational::NOTEQ, $options); + return VipsOperation::callEnum($other, 'relational', OperationRelational::NOTEQ, $options); } /** @@ -2005,9 +1776,9 @@ public function bandjoin($other, array $options = []): Image /* We can't use self::bandjoin(), that would just recurse. */ if ($is_const) { - return self::call('bandjoin_const', $this, [$other], $options); + return VipsOperation::call('bandjoin_const', $this, [$other], $options); } else { - return self::call( + return VipsOperation::call( 'bandjoin', null, [array_merge([$this], $other)], @@ -2064,7 +1835,7 @@ public function bandrank($other, array $options = []): Image $other = (array) $other; } - return self::call('bandrank', $this, $other, $options); + return VipsOperation::call('bandrank', $this, $other, $options); } /** @@ -2096,7 +1867,7 @@ public function composite($other, $mode, array $options = []): Image return self::$blendModeToInt[$x] ?? BlendMode::OVER; }, $mode); - return self::call( + return VipsOperation::call( 'composite', null, [array_merge([$this], $other), $mode], @@ -2173,7 +1944,7 @@ public function ifthenelse($then, $else, array $options = []): Image $else = self::imageize($match_image, $else); } - return self::call('ifthenelse', $this, [$then, $else], $options); + return VipsOperation::call('ifthenelse', $this, [$then, $else], $options); } /** diff --git a/src/ImageAutodoc.php b/src/ImageAutodoc.php index e917baf..f9537ec 100644 --- a/src/ImageAutodoc.php +++ b/src/ImageAutodoc.php @@ -697,6 +697,6 @@ * @property float $yres Vertical resolution in pixels/mm * @property string $filename Image filename */ -abstract class ImageAutodoc +abstract class ImageAutodoc extends VipsObject { } diff --git a/src/Init.php b/src/Init.php index 7557ec7..de5481d 100644 --- a/src/Init.php +++ b/src/Init.php @@ -66,6 +66,14 @@ class Init private int $library_minor; private int $library_micro; + /** + * Look up these once. + * + * @internal + */ + private array $ctypes; + private array $gtypes; + public static function getInit() { static $instance; @@ -83,6 +91,54 @@ public static function ffi() return self::getInit()->ffi; } + public static function ctypes(string $name) + { + return self::getInit()->ctypes[$name]; + } + + public static function gtypes(string $name) + { + return self::getInit()->gtypes[$name]; + } + + /** + * Throw a vips error as an exception. + * + * @throws Exception + * + * @return void + * + * @internal + */ + public static function error(string $message = "") + { + if ($message == "") { + $message = Init::ffi()->vips_error_buffer(); + Init::ffi()->vips_error_buffer_clear(); + } + $exception = new Exception($message); + Utils::errorLog($message, $exception); + throw $exception; + } + + public static function filename_get_filename($name) + { + $pointer = Init::ffi()->vips_filename_get_filename($name); + $filename = \FFI::string($pointer); + \FFI::free($pointer); + + return $filename; + } + + public static function filename_get_options($name) + { + $pointer = Init::ffi()->vips_filename_get_options($name); + $options = \FFI::string($pointer); + \FFI::free($pointer); + + return $options; + } + public function __construct() { } @@ -122,7 +178,7 @@ private function init() } $library = "$library_location$library_name$library_ext"; - Utils::debugLog("init", ["libray", $library]); + Utils::debugLog("init", ["libray" => $library]); // TODO put a try/catch around this and generate a helpful message // since this is likely to be the main failure point @@ -136,17 +192,18 @@ private function init() if ($result != 0) { throw new Exception("libvips error: $ffi->vips_error_buffer()"); } - Utils::debugLog("init", ["vips_init", $result]); + Utils::debugLog("init", ["vips_init" => $result]); # get the library version number, then we can build the API $this->library_major = $ffi->vips_version(0); $this->library_minor = $ffi->vips_version(1); $this->library_micro = $ffi->vips_version(2); Utils::debugLog("init", [ - "libvips version", - $this->library_major, - $this->library_minor, - $this->library_micro + "libvips version" => [ + $this->library_major, + $this->library_minor, + $this->library_micro + ] ]); if (!$this->atLeast(8, 7)) { @@ -583,17 +640,23 @@ private function init() Utils::debugLog("init", ["binding ..."]); $this->ffi = \FFI::cdef($header, $library); - # FIXME make ctypes and gtypes + // look these up in advance + $this->ctypes = [ + "VipsObject" => $this->ffi->type("VipsObject*"), + "GObject" => $this->ffi->type("GObject*"), + "VipsOperation" => $this->ffi->type("VipsOperation*"), + ]; + + $this->gtypes = [ + "gboolean" => $this->ffi->g_type_from_name("gboolean"), + "gchararray" => $this->ffi->g_type_from_name("gchararray"), + "VipsRefString" => $this->ffi->g_type_from_name("VipsRefString"), + "VipsImage" => $this->ffi->g_type_from_name("VipsImage"), + "GObject" => $this->ffi->g_type_from_name("GObject"), + ]; Utils::debugLog("init", ["done"]); } + } -/* - * 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/src/VipsObject.php b/src/VipsObject.php index 9f14e2f..ade3558 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -57,28 +57,22 @@ abstract class VipsObject extends GObject * * @internal */ - private FFI\CData $vipsObject; + private \FFI\CData $vipsObject; function __construct($pointer) { - global $ffi; - global $ctypes; - - $this->vipsObject = $ffi->cast($ctypes["VipsObject"], $pointer); + $this->vipsObject = Init::ffi()-> + cast(Init::ctypes("VipsObject"), $pointer); parent::__construct($pointer); } // print a table of all active vipsobjects ... handy for debugging static function printAll() { - global $ffi; - - $ffi->vips_object_print_all(); + Init::ffi()->vips_object_print_all(); } function getDescription() { - global $ffi; - - return $ffi->vips_object_get_description($this->vipsObject); + return Init::ffi()->vips_object_get_description($this->vipsObject); } // get the pspec for a property @@ -86,13 +80,10 @@ function getDescription() { // very slow! avoid if possible // FIXME add a cache for this thing function getPspec($name) { - global $ffi; - global $ctypes; - - $pspec = $ffi->new("GParamSpec*[1]"); - $argument_class = $ffi->new("VipsArgumentClass*[1]"); - $argument_instance = $ffi->new("VipsArgumentInstance*[1]"); - $result = $ffi->vips_object_get_argument( + $pspec = Init::ffi()->new("GParamSpec*[1]"); + $argument_class = Init::ffi()->new("VipsArgumentClass*[1]"); + $argument_instance = Init::ffi()->new("VipsArgumentInstance*[1]"); + $result = Init::ffi()->vips_object_get_argument( $this->vipsObject, $name, $pspec, @@ -111,12 +102,10 @@ function getPspec($name) { // get the type of a property from a VipsObject // 0 if no such property function getType($name) { - global $base_ffi; - $pspec = $this->getPspec($name); - if (FFI::isNULL($pspec)) { + if (FFI::isNull($pspec)) { # need to clear any error, this is horrible - $base_ffi->vips_error_clear(); + Init::ffi()->vips_error_clear(); return 0; } else { @@ -124,46 +113,37 @@ function getType($name) { } } - function getBlurb($name) { - global $ffi; - + function getBlurb(string $name) { $pspec = $this->getPspec($name); - return $ffi->g_param_spec_get_blurb($pspec); + return Init::ffi()->g_param_spec_get_blurb($pspec); } - function getArgumentDescription($name) { - global $ffi; - + function getArgumentDescription(string $name) { $pspec = $this->getPspec($name); - return $ffi->g_param_spec_get_description($pspec); + return Init::ffi()->g_param_spec_get_description($pspec); } - function get($name) { - global $ffi; - global $ctypes; - + function get(string $name) { $gvalue = new GValue(); $gvalue->setType($this->getType($name)); - $ffi->g_object_get_property($this->gObject, $name, $gvalue->pointer); + Init::ffi()-> + g_object_get_property($this->gObject, $name, $gvalue->pointer); return $gvalue->get(); } - function set($name, $value) { - global $ffi; - + function set(string $name, $value) { $gvalue = new GValue(); $gvalue->setType($this->getType($name)); $gvalue->set($value); - $ffi->g_object_set_property($this->gObject, $name, $gvalue->pointer); + Init::ffi()-> + g_object_set_property($this->gObject, $name, $gvalue->pointer); } function setString($string_options) { - global $ffi; - - $result = $ffi->vips_object_set_from_string( + $result = Init::ffi()->vips_object_set_from_string( $this->vipsObject, $string_options ); diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 1919680..dd8f7e5 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -49,7 +49,7 @@ * @license https://opensource.org/licenses/MIT MIT * @link https://github.com/libvips/php-vips */ -abstract class VipsOperation extends VipsObject +class VipsOperation extends VipsObject { /** * A pointer to the underlying VipsOperation. This is the same as the @@ -57,33 +57,126 @@ abstract class VipsOperation extends VipsObject * * @internal */ - private FFI\CData $vipsOperation; + private \FFI\CData $vipsOperation; /** - * Cache introsection results here. + * Cache introspection results here. */ private static $introspectionCache = []; + static function getIntrospection($name) { + if (!array_key_exists(self::introspectionCache, $name)) { + self::introspectionCache[$name] = new VipsIntrospection($name); + } + + return self::introspectionCache[$name]; + } + function __construct($name) { - global $ffi; - global $ctypes; - - $pointer = $ffi->vips_operation_new($name); - if (FFI::isNull($pointer)) { - error(); + Utils::debugLog("VipsOperation", ["name" => $name]); + $this->vipsOperation = Init::ffi()->vips_operation_new($name); + if (\FFI::isNull($this->vipsOperation)) { + Init::error(); } - $this->vipsOperation = $ffi->cast($ctypes["VipsOperation"], $pointer); - parent::__construct($pointer); + parent::__construct($this->vipsOperation); } - static function getIntrospection($name) { - if (!array_key_exists($introspectionCache, $name)) { - $introspectionCache[$name] = new VipsIntrospection($name); + /** + * Unwrap an array of stuff ready to pass down to the vips_ layer. We + * swap instances of Image for the ffi pointer. + * + * @param array $result Unwrap this. + * + * @return array $result unwrapped, ready for vips. + * + * @internal + */ + private static function unwrap(array $result): array + { + array_walk_recursive($result, function (&$value) { + if ($value instanceof Image) { + $value = $value->image; + } + }); + + return $result; + } + + /** + * Is $value a VipsImage. + * + * @param mixed $value The thing to test. + * + * @return bool true if this is a ffi VipsImage*. + * + * @internal + */ + private static function isImagePointer($value): bool + { + # wat + # return $value instanceof \FFI::CData && + # \FFI::typeof($value) === Init::ctypes("VipsImage"); + + return \FFI::typeof($value) === Init::ctypes("VipsImage"); + } + + /** + * Wrap up the result of a vips_ call ready to return it to PHP. We do + * two things: + * + * - If the array is a singleton, we strip it off. For example, many + * operations return a single result and there's no sense handling + * this as an array of values, so we transform ['out' => x] -> x. + * + * - Any VipsImage resources are rewrapped as instances of Image. + * + * @param mixed $result Wrap this up. + * + * @return mixed $result, but wrapped up as a php class. + * + * @internal + */ + private static function wrapResult($result) + { + if (!is_array($result)) { + $result = ['x' => $result]; } - return $introspectionCache[$name]; + array_walk_recursive($result, function (&$item) { + if (self::isImagePointer($item)) { + $item = new Image($item); + } + }); + + if (count($result) === 1) { + $result = array_shift($result); + } + + return $result; + } + + /** + * Check the result of a vips_ call for an error, and throw an exception + * if we see one. + * + * This won't work for things like __get where a non-array return can be + * a valid return. + * + * @param mixed $result Test this. + * + * @throws Exception + * + * @return void + * + * @internal + */ + private static function errorIsArray($result): void + { + if (!is_array($result)) { + Init::error(); + } } /** @@ -117,9 +210,9 @@ static function callBase( $arguments = array_merge([$name, $instance], $arguments); $arguments = array_values(self::unwrap($arguments)); $operation = new VipsOperation($name); - $introspection = $this->getIntrospection($name); + $introspection = self::getIntrospection($name); - trace("setting arguments ..."); + Utils::debugLog("callBase", ["setting arguments ..."]); if (count($introspection->required_input) != count($arguments)) { } @@ -129,10 +222,10 @@ static function callBase( // build the operation - trace("building ..."); - $new_operation = $ffi->vips_cache_operation_build($operation); + Utils::debugLog("callBase", ["building ..."]); + $new_operation = Init::ffi()->vips_cache_operation_build($operation); if (FFI::isNull($new_operation)) { - $ffi->vips_object_unref_outputs($operation); + Init::ffi()->vips_object_unref_outputs($operation); error(); } $operation = $new_operation; @@ -141,11 +234,7 @@ static function callBase( // fetch required output args - $image = gobject_get($operation, "out"); - trace("result: " . print_r($image, true)); - - $result = vips_call(...$arguments); - + $result = $operation->get("out"); self::errorIsArray($result); $result = self::wrapResult($result); From 151b3f25b80cd69c171280c5e6f385474ff6aab9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 5 Feb 2022 14:01:09 +0000 Subject: [PATCH 18/58] introspect working operation call next --- src/ArgumentFlags.php | 69 +++++++++++++++++++++++++++++++++ src/Introspect.php | 90 +++++++++++++++++++++---------------------- src/VipsObject.php | 4 +- src/VipsOperation.php | 35 ++++++++--------- 4 files changed, 131 insertions(+), 67 deletions(-) create mode 100644 src/ArgumentFlags.php diff --git a/src/ArgumentFlags.php b/src/ArgumentFlags.php new file mode 100644 index 0000000..cb54e69 --- /dev/null +++ b/src/ArgumentFlags.php @@ -0,0 +1,69 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/jcupitt/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * The ArgumentFlags enum. + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/jcupitt/php-vips + */ +abstract class ArgumentFlags +{ + const REQUIRED = 1; + const CONSTRUCT = 2; + const SET_ONCE = 4; + const SET_ALWAYS = 8; + const INPUT = 16; + const OUTPUT = 32; + const DEPRECATED = 64; + const MODIFY = 128; + + const NAMES = [ + "REQUIRED" => self::REQUIRED, + "CONSTRUCT" => self::CONSTRUCT, + "SET_ONCE" => self::SET_ONCE, + "SET_ALWAYS" => self::SET_ALWAYS, + "INPUT" => self::INPUT, + "OUTPUT" => self::OUTPUT, + "DEPRECATED" => self::DEPRECATED, + "MODIFY" => self::MODIFY, + ]; +} diff --git a/src/Introspect.php b/src/Introspect.php index 83ee732..929db90 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -39,7 +39,7 @@ namespace Jcupitt\Vips; /** - * Introspect a VIpsOperation and discover everything we can. This is called + * Introspect a VipsOperation and discover everything we can. This is called * on demand once per operation and the results held in a cache. * * @category Images @@ -49,65 +49,61 @@ * @license https://opensource.org/licenses/MIT MIT * @link https://github.com/libvips/php-vips */ -class Introspection +class Introspect { /** * The operation nickname (eg. "add"). */ - protected string $name; + public string $name; /** * The operation description (eg. "add two images"). */ - protected string $description; + public string $description; /** * The operation flags (eg. SEQUENTIAL | DEPRECATED). */ - protected int $flags; + public int $flags; /** * A hash from arg name to a hash of details. */ - protected array $arguments; + public array $arguments; /** * Arrays of arg names, in order and by category, eg. $this->required_input * = ["filename"]. */ - protected array $required_input; - protected array $optional_input; - protected array $required_output; - protected array $optional_output; + public array $required_input; + public array $optional_input; + public array $required_output; + public array $optional_output; /** * The name of the arg this operation uses as "this". */ - protected string $member_this; + public string $member_this; /** * And the required input args, without the "this". */ - protected array $method_args; + public array $method_args; function __construct($name) { - global $ffi; - global $ctypes; - global $gtypes; - $this->name = $name; $operation = new VipsOperation($name); $this->description = $operation->getDescription(); - $flags = $ffi->vips_operation_get_flags($operation); + $flags = Init::ffi()->vips_operation_get_flags($operation->pointer); - $p_names = $ffi->new("char**[1]"); - $p_flags = $ffi->new("int*[1]"); - $p_n_args = $ffi->new("int[1]"); - $result = $ffi->vips_object_get_args( - FFI::cast($ctypes["VipsObject"], $operation), + $p_names = Init::ffi()->new("char**[1]"); + $p_flags = Init::ffi()->new("int*[1]"); + $p_n_args = Init::ffi()->new("int[1]"); + $result = Init::ffi()->vips_object_get_args( + \FFI::cast(Init::ctypes("VipsObject"), $operation->pointer), $p_names, $p_flags, $p_n_args @@ -122,10 +118,10 @@ function __construct($name) # make a hash from arg name to flags $argumentFlags = []; for ($i = 0; $i < $n_args; $i++) { - if (($p_flags[$i] & $argumentFlags["CONSTRUCT"]) != 0) { + if (($p_flags[$i] & ArgumentFlags::CONSTRUCT) != 0) { # libvips uses '-' to separate parts of arg names, but we # need '_' for php - $name = FFI::string($p_names[$i]); + $name = \FFI::string($p_names[$i]); $name = str_replace("-", "_", $name); $argumentFlags[$name] = $p_flags[$i]; } @@ -137,8 +133,8 @@ function __construct($name) $this->arguments[$name] = [ "name" => $name, "flags" => $flags, - "blurb" => $operation->getBlurb($operation, $name), - "type" => $operation->getType($operation, $name) + "blurb" => $operation->getBlurb($name), + "type" => $operation->getType($name) ]; } @@ -152,43 +148,43 @@ function __construct($name) $flags = $details["flags"]; $blurb = $details["blurb"]; $type = $details["type"]; - $typeName = $ffi->g_type_name($type); + $typeName = Init::ffi()->g_type_name($type); - if (($flags & $argumentFlags["INPUT"]) && - ($flags & $argumentFlags["REQUIRED"]) && - !($flags & $argumentFlags["DEPRECATED"])) { + if (($flags & ArgumentFlags::INPUT) && + ($flags & ArgumentFlags::REQUIRED) && + !($flags & ArgumentFlags::DEPRECATED)) { $this->required_input[] = $name; # required inputs which we MODIFY are also required outputs - if ($flags & $argumentFlags["MODIFY"]) { + if ($flags & ArgumentFlags::MODIFY) { $this->required_output[] = $name; } } - if (($flags & $argumentFlags["OUTPUT"]) && - ($flags & $argumentFlags["REQUIRED"]) && - !($flags & $argumentFlags["DEPRECATED"])) { + if (($flags & ArgumentFlags::OUTPUT) && + ($flags & ArgumentFlags::REQUIRED) && + !($flags & ArgumentFlags::DEPRECATED)) { $this->required_output[] = $name; } # we let deprecated optional args through, but warn about them # if they get used, see below - if (($flags & $argumentFlags["INPUT"]) && - !($flags & $argumentFlags["REQUIRED"])) { + if (($flags & ArgumentFlags::INPUT) && + !($flags & ArgumentFlags::REQUIRED)) { $this->optional_input[] = $name; } - if (($flags & $argumentFlags["OUTPUT"]) && - !($flags & $argumentFlags["REQUIRED"])) { + if (($flags & ArgumentFlags::OUTPUT) && + !($flags & ArgumentFlags::REQUIRED)) { $this->optional_output[] = $name; } } # find the first required input image arg, if any ... that will be self - $this->member_this = null; - foreach ($required_input as $name) { - $type = $details[$name]["type"]; - if ($type == $gtypes["VipsImage"]) { + $this->member_this = ""; + foreach ($this->required_input as $name) { + $type = $this->arguments[$name]["type"]; + if ($type == Init::gtypes("VipsImage")) { $this->member_this = $name; break; } @@ -197,10 +193,12 @@ function __construct($name) # method args are required args, but without the image they are a # method on $this->method_args = $this->required_input; - if ($this->member_this != null) { + if ($this->member_this != "") { $index = array_search($this->member_this, $this->method_args); array_splice($this->method_args, $index); } + + Utils::debugLog($name, ['introspect' => strval($this)]); } public function __toString() { @@ -212,14 +210,14 @@ public function __toString() { $flags = $details["flags"]; $blurb = $details["blurb"]; $type = $details["type"]; - $typeName = $ffi->g_type_name($type); + $typeName = Init::ffi()->g_type_name($type); $result .= " $name:\n"; $result .= " flags: $flags\n"; - foreach ($argumentFlags as $name => $flag) { + foreach (ArgumentFlags::NAMES as $name => $flag) { if ($flags & $flag) { - $resut .= " $name\n"; + $result .= " $name\n"; } } diff --git a/src/VipsObject.php b/src/VipsObject.php index ade3558..9c6a9b1 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -92,7 +92,7 @@ function getPspec($name) { ); if ($result != 0) { - return FFI::NULL; + return null; } else { return $pspec[0]; @@ -103,7 +103,7 @@ function getPspec($name) { // 0 if no such property function getType($name) { $pspec = $this->getPspec($name); - if (FFI::isNull($pspec)) { + if (\FFI::isNull($pspec)) { # need to clear any error, this is horrible Init::ffi()->vips_error_clear(); return 0; diff --git a/src/VipsOperation.php b/src/VipsOperation.php index dd8f7e5..c578c4c 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -57,30 +57,27 @@ class VipsOperation extends VipsObject * * @internal */ - private \FFI\CData $vipsOperation; - - /** - * Cache introspection results here. - */ - private static $introspectionCache = []; - - static function getIntrospection($name) { - if (!array_key_exists(self::introspectionCache, $name)) { - self::introspectionCache[$name] = new VipsIntrospection($name); - } - - return self::introspectionCache[$name]; - } + public \FFI\CData $pointer; function __construct($name) { Utils::debugLog("VipsOperation", ["name" => $name]); - $this->vipsOperation = Init::ffi()->vips_operation_new($name); - if (\FFI::isNull($this->vipsOperation)) { + $this->pointer = Init::ffi()->vips_operation_new($name); + if (\FFI::isNull($this->pointer)) { Init::error(); } - parent::__construct($this->vipsOperation); + parent::__construct($this->pointer); + } + + private static function introspect($name) { + static $cache = []; + + if (!array_key_exists($name, $cache)) { + $cache[$name] = new Introspect($name); + } + + return $cache[$name]; } /** @@ -210,11 +207,11 @@ static function callBase( $arguments = array_merge([$name, $instance], $arguments); $arguments = array_values(self::unwrap($arguments)); $operation = new VipsOperation($name); - $introspection = self::getIntrospection($name); + $introspect = self::introspect($name); Utils::debugLog("callBase", ["setting arguments ..."]); - if (count($introspection->required_input) != count($arguments)) { + if (count($introspect->required_input) != count($arguments)) { } From 36710a221d9d2fa822a69aa68a869656f2c53139 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 5 Feb 2022 19:45:21 +0000 Subject: [PATCH 19/58] almost there just getting a null for result for some reason --- src/GObject.php | 8 ++--- src/GValue.php | 12 +++---- src/Image.php | 9 ++--- src/Init.php | 2 +- src/Introspect.php | 2 +- src/VipsObject.php | 35 +++++++++++++------ src/VipsOperation.php | 81 +++++++++++++++++++++++++++++++++---------- 7 files changed, 103 insertions(+), 46 deletions(-) diff --git a/src/GObject.php b/src/GObject.php index 08c524e..e3ae97c 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -55,7 +55,7 @@ abstract class GObject * * @internal */ - private \FFI\CData $gObject; + private \FFI\CData $pointer; /** * Wrap a GObject around an underlying vips resource. The GObject takes @@ -71,13 +71,11 @@ abstract class GObject */ function __construct($pointer) { - global $ctypes; - - $this->gObject = \FFI::cast(Init::ctypes("GObject"), $pointer); + $this->pointer = \FFI::cast(Init::ctypes("GObject"), $pointer); } function __destruct() { - Init::ffi()->g_object_unref($this->gObject); + Init::ffi()->g_object_unref($this->pointer); } // TODO signal marshalling to go in diff --git a/src/GValue.php b/src/GValue.php index 092ea0d..74e5566 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -40,16 +40,16 @@ class GValue { - private FFI\CData $struct; - public FFI\CData $pointer; + private \FFI\CData $struct; + public \FFI\CData $pointer; function __construct() { # allocate a gvalue on the heap, and make it persistent between requests $this->struct = Init::ffi()->new("GValue", true, true); - $this->pointer = FFI::addr($this->struct); + $this->pointer = \FFI::addr($this->struct); # GValue needs to be inited to all zero - FFI::memset($this->pointer, 0, FFI::sizeof($this->struct)); + \FFI::memset($this->pointer, 0, \FFI::sizeof($this->struct)); } function __destruct() { @@ -65,7 +65,7 @@ function getType(): int { } function set($value) { - $gtype = $this->get_type(); + $gtype = $this->getType(); switch ($gtype) { case Init::gtypes("gboolean"): @@ -95,7 +95,7 @@ function set($value) { } function get() { - $gtype = $this->get_type(); + $gtype = $this->getType(); $result = null; switch ($gtype) { diff --git a/src/Image.php b/src/Image.php index 3865919..eda0894 100644 --- a/src/Image.php +++ b/src/Image.php @@ -771,10 +771,11 @@ public static function newFromFile( Init::error(); } - $result = VipsOperation::callBase($loader, null, array_merge([ - "filename" => $filename, - "string_options" => $string_options, - ], $options)); + $result = VipsOperation::callBase($loader, null, [$filename], + array_merge([ + "string_options" => $string_options, + ], $options + )); Utils::debugLog('newFromFile', ['result' => $result]); diff --git a/src/Init.php b/src/Init.php index de5481d..44df40b 100644 --- a/src/Init.php +++ b/src/Init.php @@ -114,7 +114,7 @@ public static function error(string $message = "") { if ($message == "") { $message = Init::ffi()->vips_error_buffer(); - Init::ffi()->vips_error_buffer_clear(); + Init::ffi()->vips_error_clear(); } $exception = new Exception($message); Utils::errorLog($message, $exception); diff --git a/src/Introspect.php b/src/Introspect.php index 929db90..679965f 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -94,7 +94,7 @@ function __construct($name) { $this->name = $name; - $operation = new VipsOperation($name); + $operation = VipsOperation::newFromName($name); $this->description = $operation->getDescription(); $flags = Init::ffi()->vips_operation_get_flags($operation->pointer); diff --git a/src/VipsObject.php b/src/VipsObject.php index 9c6a9b1..56f3077 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -52,17 +52,27 @@ abstract class VipsObject extends GObject { /** - * A pointer to the underlying VipsObject. This is the same as the - * GObject, just cast to VipsObject to help FFI. + * A pointer to the underlying VipsObject. * * @internal */ - private \FFI\CData $vipsObject; + private \FFI\CData $pointer; + + /** + * A pointer to the underlying GObject. This is the same as the + * VipsObject, just cast. + * + * @internal + */ + private \FFI\CData $gObject; function __construct($pointer) { - $this->vipsObject = Init::ffi()-> + $this->pointer = Init::ffi()-> cast(Init::ctypes("VipsObject"), $pointer); + $this->gObject = Init::ffi()-> + cast(Init::ctypes("GObject"), $pointer); + parent::__construct($pointer); } @@ -72,7 +82,7 @@ static function printAll() { } function getDescription() { - return Init::ffi()->vips_object_get_description($this->vipsObject); + return Init::ffi()->vips_object_get_description($this->pointer); } // get the pspec for a property @@ -84,7 +94,7 @@ function getPspec($name) { $argument_class = Init::ffi()->new("VipsArgumentClass*[1]"); $argument_instance = Init::ffi()->new("VipsArgumentInstance*[1]"); $result = Init::ffi()->vips_object_get_argument( - $this->vipsObject, + $this->pointer, $name, $pspec, $argument_class, @@ -129,11 +139,16 @@ function get(string $name) { Init::ffi()-> g_object_get_property($this->gObject, $name, $gvalue->pointer); + $value = $gvalue->get(); + + Utils::debugLog("get", [$name => $value]); - return $gvalue->get(); + return $value; } function set(string $name, $value) { + Utils::debugLog("set", [$name => $value]); + $gvalue = new GValue(); $gvalue->setType($this->getType($name)); $gvalue->set($value); @@ -143,10 +158,8 @@ function set(string $name, $value) { } function setString($string_options) { - $result = Init::ffi()->vips_object_set_from_string( - $this->vipsObject, - $string_options - ); + $result = Init::ffi()-> + vips_object_set_from_string($this->pointer, $string_options); return $result == 0; } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index c578c4c..df8b289 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -59,15 +59,23 @@ class VipsOperation extends VipsObject */ public \FFI\CData $pointer; - function __construct($name) + function __construct($pointer) + { + $this->pointer = Init::ffi()-> + cast(Init::ctypes("VipsOperation"), $pointer); + + parent::__construct($pointer); + } + + public static function newFromName($name) { Utils::debugLog("VipsOperation", ["name" => $name]); - $this->pointer = Init::ffi()->vips_operation_new($name); - if (\FFI::isNull($this->pointer)) { + $pointer = Init::ffi()->vips_operation_new($name); + if (\FFI::isNull($pointer)) { Init::error(); } - parent::__construct($this->pointer); + return new VipsOperation($pointer); } private static function introspect($name) { @@ -204,35 +212,72 @@ static function callBase( 'arguments' => $arguments ]); - $arguments = array_merge([$name, $instance], $arguments); - $arguments = array_values(self::unwrap($arguments)); - $operation = new VipsOperation($name); + $operation = self::newFromName($name); $introspect = self::introspect($name); + /* Take any optional args off the end. + */ + $n_required = count($introspect->required_input); + $n_supplied = count($arguments); + $options = []; + if ($instance) { + $n_supplied += 1; + } + if ($n_supplied - 1 == $n_required && + is_array(end(array_values($arguments)))) { + $options = array_pop($arguments); + $n_supplied -= 1; + } + if ($n_required != $n_supplied) { + Init::error("$n_required arguments required, " . + "but $n_supplied supplied"); + } + Utils::debugLog("callBase", ["setting arguments ..."]); - if (count($introspect->required_input) != count($arguments)) { - } + /* Set required. + */ + $i = 0; + foreach ($introspect->required_input as $name) { + if ($name == $introspect->member_this) { + if (!$instance) { + Init::error("instance argument not supplied"); + } + $operation->set($name, $instance); + } + else { + $operation->set($name, $arguments[$i]); + } + $i += 1; + } - $operation->set("filename", $filename); + /* Set optional. + */ + foreach ($options as $name => $value) { + if (!array_key_exists($name, $introspect->optional_input)) { + Init::error("optional argument $name does not exist"); + } - // build the operation + $operation->set($name, $value); + } + /* Build the operation + */ Utils::debugLog("callBase", ["building ..."]); - $new_operation = Init::ffi()->vips_cache_operation_build($operation); - if (FFI::isNull($new_operation)) { + $new_operation = Init::ffi()-> + vips_cache_operation_build($operation->pointer); + if (\FFI::isNull($new_operation)) { Init::ffi()->vips_object_unref_outputs($operation); - error(); + Init::error(); } - $operation = $new_operation; + $operation = new VipsOperation($new_operation); # need to attach input refs to output - // fetch required output args - + /* Fetch required output args. + */ $result = $operation->get("out"); - self::errorIsArray($result); $result = self::wrapResult($result); Utils::debugLog($name, ['result' => $result]); From f2203890b86a2d3ae53bed764d9bd6f64073c075 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 6 Feb 2022 12:36:22 +0000 Subject: [PATCH 20/58] working ... gvalue missing cases next or mostly working anyway --- src/GValue.php | 7 +- src/Image.php | 50 +++++---- src/Init.php | 233 +++++++++++++++++++++--------------------- src/VipsObject.php | 2 +- src/VipsOperation.php | 18 ++-- 5 files changed, 161 insertions(+), 149 deletions(-) diff --git a/src/GValue.php b/src/GValue.php index 74e5566..784dd39 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -104,12 +104,13 @@ function get() { break; case Init::gtypes("gchararray"): - Init::ffi()->g_value_get_string($this->pointer); + $result = Init::ffi()->g_value_get_string($this->pointer); break; case Init::gtypes("VipsRefString"): $psize = Init::ffi()->new("size_t*"); - $result = Init::ffi()->vips_value_get_ref_string($this->pointer, $psize); + $result = Init::ffi()-> + vips_value_get_ref_string($this->pointer, $psize); # $psize[0] will be the string length, but assume it's null # terminated break; @@ -118,7 +119,7 @@ function get() { $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { case Init::gtypes("GObject"): - # we need a class wrapping gobject before we can impement this + $result = Init::ffi()->g_value_get_object($this->pointer); break; default: diff --git a/src/Image.php b/src/Image.php index eda0894..d88cc50 100644 --- a/src/Image.php +++ b/src/Image.php @@ -581,7 +581,7 @@ class Image extends ImageAutodoc implements \ArrayAccess * * @internal */ - private FFI\CData $image; + private \FFI\CData $pointer; /** * Wrap an Image around an underlying CData pointer. @@ -593,7 +593,7 @@ class Image extends ImageAutodoc implements \ArrayAccess */ public function __construct($pointer) { - $this->image = Init::ffi()->cast(Init::ctypes("VipsImage"), $pointer); + $this->pointer = Init::ffi()->cast(Init::ctypes("VipsImage"), $pointer); parent::__construct($pointer); } @@ -993,7 +993,8 @@ public function writeToFile(string $filename, array $options = []): void 'arguments' => [$filename, $options] ]); - $result = Init::ffi()->vips_image_write_to_file($this->image, $filename, $options); + $result = Init::ffi()-> + vips_image_write_to_file($this->pointer, $filename, $options); if ($result === -1) { Init::error(); } @@ -1017,7 +1018,8 @@ public function writeToBuffer(string $suffix, array $options = []): string 'arguments' => [$suffix, $options] ]); - $result = Init::ffi()->vips_image_write_to_buffer($this->image, $suffix, $options); + $result = Init::ffi()-> + vips_image_write_to_buffer($this->pointer, $suffix, $options); if ($result === -1) { Init::error(); } @@ -1041,7 +1043,7 @@ public function writeToMemory(): string 'arguments' => [] ]); - $result = Init::ffi()->vips_image_write_to_memory($this->image); + $result = Init::ffi()->vips_image_write_to_memory($this->pointer); if ($result === -1) { Init::error(); } @@ -1081,7 +1083,7 @@ public function writeToArray(): array 'arguments' => [] ]); - $result = Init::ffi()->vips_image_write_to_array($this->image); + $result = Init::ffi()->vips_image_write_to_array($this->pointer); if ($result === -1) { Init::error(); } @@ -1112,7 +1114,7 @@ public function copyMemory(): Image 'arguments' => [] ]); - $result = Init::ffi()->vips_image_copy_memory($this->image); + $result = Init::ffi()->vips_image_copy_memory($this->pointer); if ($result === -1) { Init::error(); } @@ -1133,7 +1135,14 @@ public function copyMemory(): Image */ public function __get(string $name) { - return Init::ffi()->vips_image_get($this->image, $name); + $value = new GValue(); + $result = Init::ffi()-> + vips_image_get($this->pointer, $name, $value->pointer); + if ($result != 0) { + Init::error(); + } + + return $value->get(); } /** @@ -1146,7 +1155,7 @@ public function __get(string $name) */ public function __set(string $name, $value): void { - Init::ffi()->vips_image_set($this->image, $name, $value); + Init::ffi()->vips_image_set($this->pointer, $name, $value); } /** @@ -1178,7 +1187,7 @@ public function __isset(string $name): bool */ public function get(string $name) { - return Init::ffi()->vips_image_get($this->image, $name); + return Init::ffi()->vips_image_get($this->pointer, $name); } /** @@ -1192,7 +1201,7 @@ public function get(string $name) */ public function typeof(string $name): int { - return Init::ffi()->vips_image_get_typeof($this->image, $name); + return Init::ffi()->vips_image_get_typeof($this->pointer, $name); } /** @@ -1210,7 +1219,7 @@ public function typeof(string $name): int */ public function set(string $name, $value): void { - $result = Init::ffi()->vips_image_set($this->image, $name, $value); + $result = Init::ffi()->vips_image_set($this->pointer, $name, $value); if ($result === -1) { Init::error(); } @@ -1235,7 +1244,8 @@ public function set(string $name, $value): void */ public function setType($type, string $name, $value): void { - $result = Init::ffi()->vips_image_set_type($this->image, $type, $name, $value); + $result = Init::ffi()-> + vips_image_set_type($this->pointer, $type, $name, $value); if ($result === -1) { Init::error(); } @@ -1252,7 +1262,7 @@ public function setType($type, string $name, $value): void */ public function remove(string $name): void { - $result = Init::ffi()->vips_image_remove($this->image, $name); + $result = Init::ffi()->vips_image_remove($this->pointer, $name); if ($result === -1) { Init::error(); } @@ -1380,7 +1390,8 @@ public function offsetSet($offset, $value): void } if (!is_int($offset)) { - throw new \BadMethodCallException('Image::offsetSet: offset is not integer or null'); + throw new \BadMethodCallException('Image::offsetSet: ' . + 'offset is not integer or null'); } // number of bands to the left and right of $value @@ -1404,7 +1415,7 @@ public function offsetSet($offset, $value): void } $head = array_shift($components); - $this->image = $head->bandjoin($components)->image; + $this->pointer = $head->bandjoin($components)->pointer; } /** @@ -1422,7 +1433,8 @@ public function offsetUnset($offset): void { if (is_int($offset) && $offset >= 0 && $offset < $this->bands) { if ($this->bands === 1) { - throw new \BadMethodCallException('Image::offsetUnset: cannot delete final band'); + throw new \BadMethodCallException('Image::offsetUnset: ' . + 'cannot delete final band'); } $components = []; @@ -1438,9 +1450,9 @@ public function offsetUnset($offset): void $head = array_shift($components); if (empty($components)) { - $this->image = $head->image; + $this->pointer = $head->pointer; } else { - $this->image = $head->bandjoin($components)->image; + $this->pointer = $head->bandjoin($components)->pointer; } } } diff --git a/src/Init.php b/src/Init.php index 44df40b..3cafe54 100644 --- a/src/Init.php +++ b/src/Init.php @@ -265,8 +265,8 @@ private function init() void* vips_type_map (GType base, VipsTypeMap2Fn fn, void* a, void* b); typedef struct _GValue { -GType g_type; -guint64 data[2]; + GType g_type; + guint64 data[2]; } GValue; void g_value_init (GValue* value, GType gtype); @@ -293,7 +293,7 @@ private function init() void vips_value_set_array_image (GValue *value, int n); typedef void (*FreeFn)(void* a); void vips_value_set_blob (GValue* value, -FreeFn free_fn, void* data, size_t length); + FreeFn free_fn, void* data, size_t length); bool g_value_get_boolean (const GValue* value); int g_value_get_int (GValue* value); @@ -303,7 +303,7 @@ private function init() unsigned int g_value_get_flags (GValue* value); const char* g_value_get_string (GValue* value); const char* vips_value_get_ref_string (const GValue* value, -size_t* length); + size_t* length); void* g_value_get_object (GValue* value); double* vips_value_get_array_double (const GValue* value, int* n); int* vips_value_get_array_int (const GValue* value, int* n); @@ -323,61 +323,61 @@ private function init() typedef struct _GTypeClass GTypeClass; typedef struct _GTypeInstance { -GTypeClass *g_class; + GTypeClass *g_class; } GTypeInstance; typedef struct _GObject { -GTypeInstance g_type_instance; -unsigned int ref_count; -GData *qdata; + GTypeInstance g_type_instance; + unsigned int ref_count; + GData *qdata; } GObject; typedef struct _GParamSpec { -GTypeInstance g_type_instance; - -const char* name; -unsigned int flags; -GType value_type; -GType owner_type; - -// private, but cffi in API mode needs these to be able to get the -// offset of any member -char* _nick; -char* _blurb; -GData* qdata; -unsigned int ref_count; -unsigned int param_id; + GTypeInstance g_type_instance; + + const char* name; + unsigned int flags; + GType value_type; + GType owner_type; + + // private, but cffi in API mode needs these to be able to get the + // offset of any member + char* _nick; + char* _blurb; + GData* qdata; + unsigned int ref_count; + unsigned int param_id; } GParamSpec; typedef struct _GEnumValue { -int value; + int value; -const char *value_name; -const char *value_nick; + const char *value_name; + const char *value_nick; } GEnumValue; typedef struct _GEnumClass { -GTypeClass *g_type_class; + GTypeClass *g_type_class; -int minimum; -int maximum; -unsigned int n_values; -GEnumValue *values; + int minimum; + int maximum; + unsigned int n_values; + GEnumValue *values; } GEnumClass; typedef struct _GFlagsValue { -unsigned int value; + unsigned int value; -const char *value_name; -const char *value_nick; + const char *value_name; + const char *value_nick; } GFlagsValue; typedef struct _GFlagsClass { -GTypeClass *g_type_class; + GTypeClass *g_type_class; -unsigned int mask; -unsigned int n_values; -GFlagsValue *values; + unsigned int mask; + unsigned int n_values; + GFlagsValue *values; } GFlagsClass; void* g_type_class_ref (GType type); @@ -394,110 +394,111 @@ private function init() typedef void (*GCallback)(void); typedef void (*GClosureNotify)(void* data, struct _GClosure *); long g_signal_connect_data (GObject* object, -const char* detailed_signal, -GCallback c_handler, -void* data, -GClosureNotify destroy_data, -int connect_flags); + const char* detailed_signal, + GCallback c_handler, + void* data, + GClosureNotify destroy_data, + int connect_flags); void vips_image_set_progress (VipsImage* image, bool progress); void vips_image_set_kill (VipsImage* image, bool kill); typedef struct _VipsProgress { -VipsImage* im; - -int run; -int eta; -gint64 tpels; -gint64 npels; -int percent; -void* start; + VipsImage* im; + + int run; + int eta; + gint64 tpels; + gint64 npels; + int percent; + void* start; } VipsProgress; typedef struct _VipsObject { -GObject parent_instance; - -bool constructed; -bool static_object; -void *argument_table; -char *nickname; -char *description; -bool preclose; -bool close; -bool postclose; -size_t local_memory; + GObject parent_instance; + + bool constructed; + bool static_object; + void *argument_table; + char *nickname; + char *description; + bool preclose; + bool close; + bool postclose; + size_t local_memory; } VipsObject; typedef struct _VipsObjectClass VipsObjectClass; typedef struct _VipsArgument { -GParamSpec *pspec; + GParamSpec *pspec; } VipsArgument; typedef struct _VipsArgumentInstance { -VipsArgument parent; + VipsArgument parent; -// more + // more } VipsArgumentInstance; typedef enum _VipsArgumentFlags { -VIPS_ARGUMENT_NONE = 0, -VIPS_ARGUMENT_REQUIRED = 1, -VIPS_ARGUMENT_CONSTRUCT = 2, -VIPS_ARGUMENT_SET_ONCE = 4, -VIPS_ARGUMENT_SET_ALWAYS = 8, -VIPS_ARGUMENT_INPUT = 16, -VIPS_ARGUMENT_OUTPUT = 32, -VIPS_ARGUMENT_DEPRECATED = 64, -VIPS_ARGUMENT_MODIFY = 128 + VIPS_ARGUMENT_NONE = 0, + VIPS_ARGUMENT_REQUIRED = 1, + VIPS_ARGUMENT_CONSTRUCT = 2, + VIPS_ARGUMENT_SET_ONCE = 4, + VIPS_ARGUMENT_SET_ALWAYS = 8, + VIPS_ARGUMENT_INPUT = 16, + VIPS_ARGUMENT_OUTPUT = 32, + VIPS_ARGUMENT_DEPRECATED = 64, + VIPS_ARGUMENT_MODIFY = 128 } VipsArgumentFlags; typedef struct _VipsArgumentClass { -VipsArgument parent; + VipsArgument parent; -VipsObjectClass *object_class; -VipsArgumentFlags flags; -int priority; -unsigned int offset; + VipsObjectClass *object_class; + VipsArgumentFlags flags; + int priority; + unsigned int offset; } VipsArgumentClass; int vips_object_get_argument (VipsObject* object, -const char *name, GParamSpec** pspec, -VipsArgumentClass** argument_class, -VipsArgumentInstance** argument_instance); + const char *name, GParamSpec** pspec, + VipsArgumentClass** argument_class, + VipsArgumentInstance** argument_instance); void vips_object_print_all (void); int vips_object_set_from_string (VipsObject* object, -const char* options); + const char* options); const char* vips_object_get_description (VipsObject* object); const char* g_param_spec_get_blurb (GParamSpec* psp); typedef struct _VipsImage { -VipsObject parent_instance; -// more + VipsObject parent_instance; + // more } VipsImage; + const char* vips_foreign_find_load (const char* name); const char* vips_foreign_find_load_buffer (const void* data, -size_t size); + size_t size); const char* vips_foreign_find_save (const char* name); const char* vips_foreign_find_save_buffer (const char* suffix); VipsImage* vips_image_new_matrix_from_array (int width, int height, -const double* array, int size); + const double* array, int size); VipsImage* vips_image_new_from_memory (const void* data, size_t size, -int width, int height, int bands, int format); + int width, int height, int bands, int format); VipsImage* vips_image_copy_memory (VipsImage* image); GType vips_image_get_typeof (const VipsImage* image, -const char* name); + const char* name); int vips_image_get (const VipsImage* image, -const char* name, GValue* value_copy); + const char* name, GValue* value_copy); void vips_image_set (VipsImage* image, -const char* name, GValue* value); + const char* name, GValue* value); int vips_image_remove (VipsImage* image, const char* name); char* vips_filename_get_filename (const char* vips_filename); @@ -509,34 +510,34 @@ private function init() void* vips_image_write_to_memory (VipsImage* in, size_t* size_out); typedef struct _VipsInterpolate { -VipsObject parent_object; + VipsObject parent_object; -// more + // more } VipsInterpolate; VipsInterpolate* vips_interpolate_new (const char* name); typedef struct _VipsOperation { -VipsObject parent_instance; + VipsObject parent_instance; -// more + // more } VipsOperation; VipsOperation* vips_operation_new (const char* name); typedef void* (*VipsArgumentMapFn) (VipsObject* object, -GParamSpec* pspec, -VipsArgumentClass* argument_class, -VipsArgumentInstance* argument_instance, -void* a, void* b); + GParamSpec* pspec, + VipsArgumentClass* argument_class, + VipsArgumentInstance* argument_instance, + void* a, void* b); void* vips_argument_map (VipsObject* object, -VipsArgumentMapFn fn, void* a, void* b); + VipsArgumentMapFn fn, void* a, void* b); typedef struct _VipsRegion { -VipsObject parent_object; + VipsObject parent_object; -// more + // more } VipsRegion; VipsRegion* vips_region_new (VipsImage*); @@ -562,7 +563,7 @@ private function init() void vips_value_set_blob_free (GValue* value, void* data, size_t length); int vips_object_get_args (VipsObject* object, -const char*** names, int** flags, int* n_args); + const char*** names, int** flags, int* n_args); EOS; if ($this->atLeast(8, 8)) { @@ -570,7 +571,7 @@ private function init() char** vips_foreign_get_suffixes (void); void* vips_region_fetch (VipsRegion*, int, int, int, int, -size_t* length); + size_t* length); int vips_region_width (VipsRegion*); int vips_region_height (VipsRegion*); int vips_image_get_page_height (VipsImage*); @@ -581,29 +582,29 @@ private function init() if ($this->atLeast(8, 8)) { $header = $header . <<ctypes = [ - "VipsObject" => $this->ffi->type("VipsObject*"), "GObject" => $this->ffi->type("GObject*"), + "VipsObject" => $this->ffi->type("VipsObject*"), "VipsOperation" => $this->ffi->type("VipsOperation*"), + "VipsImage" => $this->ffi->type("VipsImage*"), ]; $this->gtypes = [ @@ -657,6 +659,5 @@ private function init() Utils::debugLog("init", ["done"]); } - } diff --git a/src/VipsObject.php b/src/VipsObject.php index 56f3077..5230347 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -141,7 +141,7 @@ function get(string $name) { g_object_get_property($this->gObject, $name, $gvalue->pointer); $value = $gvalue->get(); - Utils::debugLog("get", [$name => $value]); + Utils::debugLog("get", [$name => var_export($value, true)]); return $value; } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index df8b289..72cb275 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -120,11 +120,8 @@ private static function unwrap(array $result): array */ private static function isImagePointer($value): bool { - # wat - # return $value instanceof \FFI::CData && - # \FFI::typeof($value) === Init::ctypes("VipsImage"); - - return \FFI::typeof($value) === Init::ctypes("VipsImage"); + return $value instanceof \FFI\CData && + \FFI::typeof($value) == Init::ctypes("VipsImage"); } /** @@ -265,22 +262,23 @@ static function callBase( /* Build the operation */ Utils::debugLog("callBase", ["building ..."]); - $new_operation = Init::ffi()-> + $pointer = Init::ffi()-> vips_cache_operation_build($operation->pointer); - if (\FFI::isNull($new_operation)) { - Init::ffi()->vips_object_unref_outputs($operation); + if (\FFI::isNull($pointer)) { + Init::ffi()->vips_object_unref_outputs($operation->pointer); Init::error(); } - $operation = new VipsOperation($new_operation); + $operation = new VipsOperation($pointer); # need to attach input refs to output /* Fetch required output args. */ $result = $operation->get("out"); + $result = self::wrapResult($result); - Utils::debugLog($name, ['result' => $result]); + Utils::debugLog($name, ['result' => var_export($result, true)]); return $result; } From a46071005ad98762ade28ecb99db1a6cb61bae1f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 6 Feb 2022 18:54:06 +0000 Subject: [PATCH 21/58] start fleshing out get/set --- src/GValue.php | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Init.php | 20 +++++++- 2 files changed, 155 insertions(+), 2 deletions(-) diff --git a/src/GValue.php b/src/GValue.php index 784dd39..5e7d520 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -52,6 +52,32 @@ function __construct() { \FFI::memset($this->pointer, 0, \FFI::sizeof($this->struct)); } + /* Turn a string into an enum value, if possible + */ + static function toEnum($gtype, $value) { + if (is_string($value)) { + $enum_value = Init::ffi()-> + vips_enum_from_nick("php-vips", $gtype, $value); + if ($enum_value < 0) { + Init::error(); + } + } + else { + $enum_value = $value. + } + + return $enum_value; + } + + static function fromEnum($gtype, $value) { + $pointer = Init::ffi()->vips_enum_nick($gtype, $value); + if (\FFI::isNull($pointer)) { + Init::error("value not in enum"); + } + + return \FFI::string($pointer); + } + function __destruct() { Init::ffi()->g_value_unset($this->pointer); } @@ -72,6 +98,22 @@ function set($value) { Init::ffi()->g_value_set_boolean($this->pointer, $value); break; + case Init::gtypes("gint"): + Init::ffi()->g_value_set_int($this->pointer, $value); + break; + + case Init::gtypes("gint64"): + Init::ffi()->g_value_set_int64($this->pointer, $value); + break; + + case Init::gtypes("guint64"): + Init::ffi()->g_value_set_uint64($this->pointer, $value); + break; + + case Init::gtypes("gdouble"): + Init::ffi()->g_value_set_double($this->pointer, $value); + break; + case Init::gtypes("gchararray"): Init::ffi()->g_value_set_string($this->pointer, $value); break; @@ -80,10 +122,78 @@ function set($value) { Init::ffi()->vips_value_set_ref_string($this->pointer, $value); break; + case Init::gtypes("VipsArrayInt"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + $ctype = \FFI::arrayType(\FFI::type("int"), $n); + $array = \FFI::new($ctype, true, true); + for ($i = 0; $i < $n; $i++) { + $array[$i] = $value[$i]; + } + Init::ffi()->vips_value_set_array_int($this->pointer, $array, $n); + break; + + case Init::gtypes("VipsArrayDouble"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + $ctype = \FFI::arrayType(\FFI::type("double"), $n); + $array = \FFI::new($ctype, true, true); + for ($i = 0; $i < $n; $i++) { + $array[$i] = $value[$i]; + } + Init::ffi()-> + vips_value_set_array_double($this->pointer, $array, $n); + break; + + case Init::gtypes("VipsArrayImage"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + Init::ffi()->vips_value_set_array_image($this->pointer, $n); + $array = Init::ffi()-> + vips_value_get_array_image($this->pointer, NULL); + for ($i = 0; $i < $n; $i++) { + $image = $value[$i]->pointer; + $array[$i] = $pointer; + Init::ffi()->g_object_ref($pointer); + } + break; + + case Init::gtypes("VipsBlob"): + # we need to set the blob to a copy of the data that vips_lib + # can own + $n = strlen($value); + $ctype = \FFI::arrayType(\FFI::type("char"), $n); + $memory = \FFI::new($ctype, true, true); + for ($i = 0; $i < $n; $i++) { + $memory[$i] = $value[$i]; + } + Init::ffi()-> + vips_value_set_blob_free($this->pointer, $memory, $n) + break; + default: $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { case Init::gtypes("GObject"): + Init::ffi()-> + g_value_set_object($this->pointer, $value->pointer); + break; + + case Init::gtypes("GEnum"): + Init::ffi()->g_value_set_enum($this->pointer, + self::toEnum($gtype, $value)); + break; + + case Init::gtypes("GFlags"): + /* Just set as int. + */ + Init::ffi()->g_value_set_flags($this->pointer, $value); break; default: @@ -103,6 +213,22 @@ function get() { $result = Init::ffi()->g_value_get_boolean($this->pointer); break; + case Init::gtypes("gint"): + $result = Init::ffi()->g_value_get_int($this->pointer); + break; + + case Init::gtypes("gint64"): + $result = Init::ffi()->g_value_get_int64($this->pointer); + break; + + case Init::gtypes("guint64"): + $result = Init::ffi()->g_value_get_uint64($this->pointer); + break; + + case Init::gtypes("gdouble"): + $result = Init::ffi()->g_value_get_double($this->pointer); + break; + case Init::gtypes("gchararray"): $result = Init::ffi()->g_value_get_string($this->pointer); break; @@ -122,6 +248,17 @@ function get() { $result = Init::ffi()->g_value_get_object($this->pointer); break; + case Init::gtypes("GEnum"): + $result = Init::ffi()->g_value_get_enum($this->pointer); + $result = self::fromEnum($gtype, $result); + break; + + case Init::gtypes("GFlags"): + /* Just get as int. + */ + $result = Init::ffi()->g_value_get_flags($this->pointer); + break; + default: $typeName = Init::ffi()->g_type_name($gtype); throw new \BadMethodCallException("$typeName not implemented"); diff --git a/src/Init.php b/src/Init.php index 3cafe54..a6d042f 100644 --- a/src/Init.php +++ b/src/Init.php @@ -274,12 +274,13 @@ private function init() GType g_type_fundamental (GType gtype); int vips_enum_from_nick (const char* domain, -GType gtype, const char* str); + GType gtype, const char* str); const char *vips_enum_nick (GType gtype, int value); void g_value_set_boolean (GValue* value, bool v_boolean); void g_value_set_int (GValue* value, int i); void g_value_set_uint64 (GValue* value, guint64 ull); +void g_value_set_int64 (GValue* value, guint64 ull); void g_value_set_double (GValue* value, double d); void g_value_set_enum (GValue* value, int e); void g_value_set_flags (GValue* value, unsigned int f); @@ -298,6 +299,7 @@ private function init() bool g_value_get_boolean (const GValue* value); int g_value_get_int (GValue* value); guint64 g_value_get_uint64 (GValue* value); +gint64 g_value_get_int64 (GValue* value); double g_value_get_double (GValue* value); int g_value_get_enum (GValue* value); unsigned int g_value_get_flags (GValue* value); @@ -651,10 +653,24 @@ private function init() $this->gtypes = [ "gboolean" => $this->ffi->g_type_from_name("gboolean"), + "gint" => $this->ffi->g_type_from_name("gint"), + "gint64" => $this->ffi->g_type_from_name("gint64"), + "gdouble" => $this->ffi->g_type_from_name("gdouble"), "gchararray" => $this->ffi->g_type_from_name("gchararray"), "VipsRefString" => $this->ffi->g_type_from_name("VipsRefString"), - "VipsImage" => $this->ffi->g_type_from_name("VipsImage"), + + "GEnum" => $this->ffi->g_type_from_name("GEnum"), + "GFlags" => $this->ffi->g_type_from_name("GFlags"), + "VipsBandFormat" => $this->ffi->g_type_from_name("VipsBandFormat"), + "VipsBlendMode" => $this->ffi->g_type_from_name("VipsBlendMode"), + "VipsArrayInt" => $this->ffi->g_type_from_name("VipsArrayInt"), + "VipsArrayDouble" => + $this->ffi->g_type_from_name("VipsArrayDouble"), + "VipsArrayImage" => $this->ffi->g_type_from_name("VipsArrayImage"), + "VipsBlob" => $this->ffi->g_type_from_name("VipsBlob"), + "GObject" => $this->ffi->g_type_from_name("GObject"), + "VipsImage" => $this->ffi->g_type_from_name("VipsImage"), ]; Utils::debugLog("init", ["done"]); From bf561006ccf82ed0c6ac46860b24777a5cb445f8 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Feb 2022 22:09:22 +0000 Subject: [PATCH 22/58] small bugfixes writeToFile next --- src/GValue.php | 14 +++++++------- src/Image.php | 2 +- src/Init.php | 1 + src/VipsOperation.php | 11 +++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/GValue.php b/src/GValue.php index 5e7d520..d975ac2 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -63,19 +63,19 @@ static function toEnum($gtype, $value) { } } else { - $enum_value = $value. + $enum_value = $value; } return $enum_value; } static function fromEnum($gtype, $value) { - $pointer = Init::ffi()->vips_enum_nick($gtype, $value); - if (\FFI::isNull($pointer)) { + $result = Init::ffi()->vips_enum_nick($gtype, $value); + if ($result === null) { Init::error("value not in enum"); } - return \FFI::string($pointer); + return $result; } function __destruct() { @@ -140,7 +140,7 @@ function set($value) { $value = [$value]; } $n = count($value); - $ctype = \FFI::arrayType(\FFI::type("double"), $n); + $ctype = \FFI::arrayType(\FFI::type("double"), [$n]); $array = \FFI::new($ctype, true, true); for ($i = 0; $i < $n; $i++) { $array[$i] = $value[$i]; @@ -158,7 +158,7 @@ function set($value) { $array = Init::ffi()-> vips_value_get_array_image($this->pointer, NULL); for ($i = 0; $i < $n; $i++) { - $image = $value[$i]->pointer; + $pointer = $value[$i]->pointer; $array[$i] = $pointer; Init::ffi()->g_object_ref($pointer); } @@ -174,7 +174,7 @@ function set($value) { $memory[$i] = $value[$i]; } Init::ffi()-> - vips_value_set_blob_free($this->pointer, $memory, $n) + vips_value_set_blob_free($this->pointer, $memory, $n); break; default: diff --git a/src/Image.php b/src/Image.php index d88cc50..cb19277 100644 --- a/src/Image.php +++ b/src/Image.php @@ -581,7 +581,7 @@ class Image extends ImageAutodoc implements \ArrayAccess * * @internal */ - private \FFI\CData $pointer; + public \FFI\CData $pointer; /** * Wrap an Image around an underlying CData pointer. diff --git a/src/Init.php b/src/Init.php index a6d042f..b9e785b 100644 --- a/src/Init.php +++ b/src/Init.php @@ -655,6 +655,7 @@ private function init() "gboolean" => $this->ffi->g_type_from_name("gboolean"), "gint" => $this->ffi->g_type_from_name("gint"), "gint64" => $this->ffi->g_type_from_name("gint64"), + "guint64" => $this->ffi->g_type_from_name("guint64"), "gdouble" => $this->ffi->g_type_from_name("gdouble"), "gchararray" => $this->ffi->g_type_from_name("gchararray"), "VipsRefString" => $this->ffi->g_type_from_name("VipsRefString"), diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 72cb275..f6063f4 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -220,8 +220,8 @@ static function callBase( if ($instance) { $n_supplied += 1; } - if ($n_supplied - 1 == $n_required && - is_array(end(array_values($arguments)))) { + $values = array_values($arguments); + if ($n_supplied - 1 == $n_required && is_array(end($values))) { $options = array_pop($arguments); $n_supplied -= 1; } @@ -244,16 +244,15 @@ static function callBase( } else { $operation->set($name, $arguments[$i]); + $i += 1; } - - $i += 1; } /* Set optional. */ foreach ($options as $name => $value) { - if (!array_key_exists($name, $introspect->optional_input)) { - Init::error("optional argument $name does not exist"); + if (!in_array($name, $introspect->optional_input)) { + Init::error("optional argument '$name' does not exist"); } $operation->set($name, $value); From f8be77fbf79c4f782577b74b95987f382ec2bc2f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 13 Feb 2022 17:39:28 +0000 Subject: [PATCH 23/58] now executes a test program! add some tests, finish other methods in image --- src/Image.php | 20 +++++++++++++++++--- src/VipsObject.php | 4 ++++ src/VipsOperation.php | 26 +++++++++++++++++++++----- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Image.php b/src/Image.php index cb19277..614618a 100644 --- a/src/Image.php +++ b/src/Image.php @@ -986,15 +986,29 @@ public function newFromImage($value): Image * * @return void */ - public function writeToFile(string $filename, array $options = []): void + public function writeToFile(string $name, array $options = []): void { Utils::debugLog('writeToFile', [ 'instance' => $this, 'arguments' => [$filename, $options] ]); - $result = Init::ffi()-> - vips_image_write_to_file($this->pointer, $filename, $options); + $filename = Init::filename_get_filename($name); + $string_options = Init::filename_get_options($name); + + $saver = Init::ffi()->vips_foreign_find_save($filename); + if ($saver == "") { + Init::error(); + } + + $result = VipsOperation::callBase($saver, $this, [$filename], + array_merge([ + "string_options" => $string_options, + ], $options + )); + + Utils::debugLog('writeToFile', ['result' => $result]); + if ($result === -1) { Init::error(); } diff --git a/src/VipsObject.php b/src/VipsObject.php index 5230347..f180359 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -164,6 +164,10 @@ function setString($string_options) { return $result == 0; } + function unrefOutputs() + { + Init::ffi()->vips_object_unref_outputs($this->pointer); + } } /* diff --git a/src/VipsOperation.php b/src/VipsOperation.php index f6063f4..e4550fc 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -264,16 +264,32 @@ static function callBase( $pointer = Init::ffi()-> vips_cache_operation_build($operation->pointer); if (\FFI::isNull($pointer)) { - Init::ffi()->vips_object_unref_outputs($operation->pointer); - Init::error(); + $operation->unrefOutputs(); + Init::error(); } $operation = new VipsOperation($pointer); - # need to attach input refs to output + # TODO .. need to attach input refs to output, see _find_inside in + # pyvips + + /* Fetch required output args (and modified input args). + */ + $result = []; + foreach ($introspect->required_output as $name) { + $result[] = $operation->get($name); + } + + /* Any optional output args. + */ + foreach ($introspect->optional_output as $name) { + if (in_array($name, $options)) { + $result[$name] = $operation->get($name); + } + } - /* Fetch required output args. + /* Free any outputs we've not used. */ - $result = $operation->get("out"); + $operation->unrefOutputs(); $result = self::wrapResult($result); From da5cb08772bf210f07eccb4c64f5c4f97f3821f7 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 10:06:41 +0000 Subject: [PATCH 24/58] runs the watermark-image example successfully watermark-text next --- examples/composer.json | 12 ++++++++++++ examples/watermark-image.php | 38 ++++++++++++++++++++++++++++++++++++ examples/watermark-text.php | 4 +++- src/Image.php | 37 +++++++++++++++++++---------------- 4 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 examples/composer.json create mode 100755 examples/watermark-image.php diff --git a/examples/composer.json b/examples/composer.json new file mode 100644 index 0000000..40d7c46 --- /dev/null +++ b/examples/composer.json @@ -0,0 +1,12 @@ +{ + "minimum-stability": "dev", + "repositories": [ + { + "type": "path", + "url": "/home/john/GIT/php-vips" + } + ], + "require": { + "jcupitt/vips": "*" + } +} diff --git a/examples/watermark-image.php b/examples/watermark-image.php new file mode 100755 index 0000000..6e12384 --- /dev/null +++ b/examples/watermark-image.php @@ -0,0 +1,38 @@ +#!/usr/bin/env php + 'sequential']); + +// we'll read the watermark image many times, so we need random access for this +$watermark = Vips\Image::newFromFile($argv[3]); + +// the watermark image needs to have an alpha channel +if(!$watermark->hasAlpha() || $watermark->bands != 4) { + echo("watermark image is not RGBA\n"); + exit(1); +} + +// make the watermark semi-transparent +$watermark = $watermark->multiply([1, 1, 1, 0.3])->cast("uchar"); + +// repeat the watermark to the size of the image +$watermark = $watermark->replicate( + 1 + $image->width / $watermark->width, + 1 + $image->height / $watermark->height); +$watermark = $watermark->crop(0, 0, $image->width, $image->height); + +// composite the watermark over the main image +$image = $image->composite2($watermark, 'over'); + +$image->writeToFile($argv[2]); diff --git a/examples/watermark-text.php b/examples/watermark-text.php index 3a0377d..04d30e1 100755 --- a/examples/watermark-text.php +++ b/examples/watermark-text.php @@ -4,6 +4,8 @@ require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; +Vips\Config::setLogger(new Vips\DebugLogger()); + if (count($argv) != 4) { echo("usage: ./watermark-text.php input output \"some text\"\n"); exit(1); @@ -30,7 +32,7 @@ $foreground = [255, 255, 255, 50]; $background = [0, 0, 255, 50]; -// and a 10-pixel marghin +// and a 10-pixel margin $margin = 10; $overlay = $text_mask->ifthenelse($foreground, $background, [ diff --git a/src/Image.php b/src/Image.php index 614618a..21541e7 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1149,14 +1149,7 @@ public function copyMemory(): Image */ public function __get(string $name) { - $value = new GValue(); - $result = Init::ffi()-> - vips_image_get($this->pointer, $name, $value->pointer); - if ($result != 0) { - Init::error(); - } - - return $value->get(); + return $this->get($name); } /** @@ -1169,7 +1162,7 @@ public function __get(string $name) */ public function __set(string $name, $value): void { - Init::ffi()->vips_image_set($this->pointer, $name, $value); + $this->set($name, $value); } /** @@ -1201,7 +1194,13 @@ public function __isset(string $name): bool */ public function get(string $name) { - return Init::ffi()->vips_image_get($this->pointer, $name); + $gvalue = new GValue(); + if (Init::ffi()-> + vips_image_get($this->pointer, $name, $gvalue->pointer) != 0) { + Init::error(); + } + + return $gvalue.get(); } /** @@ -1233,8 +1232,11 @@ public function typeof(string $name): int */ public function set(string $name, $value): void { - $result = Init::ffi()->vips_image_set($this->pointer, $name, $value); - if ($result === -1) { + $gvalue = new GValue(); + $gvalue->setType($this->typeof($name)); + $gvalue->set($value); + if (Init::ffi()-> + vips_image_set($this->pointer, $name, $gvalue) != 0) { Init::error(); } } @@ -1258,9 +1260,11 @@ public function set(string $name, $value): void */ public function setType($type, string $name, $value): void { - $result = Init::ffi()-> - vips_image_set_type($this->pointer, $type, $name, $value); - if ($result === -1) { + $gvalue = new GValue(); + $gvalue->setType($type); + $gvalue->set($value); + if (Init::ffi()-> + vips_image_set($this->pointer, $name, $gvalue) != 0) { Init::error(); } } @@ -1276,8 +1280,7 @@ public function setType($type, string $name, $value): void */ public function remove(string $name): void { - $result = Init::ffi()->vips_image_remove($this->pointer, $name); - if ($result === -1) { + if (Init::ffi()->vips_image_remove($this->pointer, $name) != 0) { Init::error(); } } From 8c18365831813886f38db7de36871c9151a81e10 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 10:54:54 +0000 Subject: [PATCH 25/58] fix optional args on newFromFile --- src/Image.php | 33 +++++++++++++++++++++------------ src/VipsOperation.php | 3 ++- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Image.php b/src/Image.php index 21541e7..85a3f63 100644 --- a/src/Image.php +++ b/src/Image.php @@ -771,11 +771,13 @@ public static function newFromFile( Init::error(); } - $result = VipsOperation::callBase($loader, null, [$filename], - array_merge([ + if (strlen($string_options) != 0) { + $options = array_merge([ "string_options" => $string_options, - ], $options - )); + ], $options); + } + + $result = VipsOperation::call($loader, null, [$filename], $options); Utils::debugLog('newFromFile', ['result' => $result]); @@ -808,9 +810,14 @@ public static function newFromBuffer( if (\FFI::isNull($loader)) { Init::error(); } - $result = VipsOperation::callBase($loader, $buffer, array_merge([ - "string_options" => $string_options - ], $options)); + + if (strlen($string_options) != 0) { + $options = array_merge([ + "string_options" => $string_options, + ], $options); + } + + $result = VipsOperation::call($loader, null, [$buffer], $options); Utils::debugLog('newFromBuffer', ['result' => $result]); @@ -1001,11 +1008,13 @@ public function writeToFile(string $name, array $options = []): void Init::error(); } - $result = VipsOperation::callBase($saver, $this, [$filename], - array_merge([ + if (strlen($string_options) != 0) { + $options = array_merge([ "string_options" => $string_options, - ], $options - )); + ], $options); + } + + $result = VipsOperation::call($saver, $this, [$filename], $options); Utils::debugLog('writeToFile', ['result' => $result]); @@ -1200,7 +1209,7 @@ public function get(string $name) Init::error(); } - return $gvalue.get(); + return $gvalue->get(); } /** diff --git a/src/VipsOperation.php b/src/VipsOperation.php index e4550fc..e0f50aa 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -216,10 +216,11 @@ static function callBase( */ $n_required = count($introspect->required_input); $n_supplied = count($arguments); - $options = []; if ($instance) { $n_supplied += 1; } + + $options = []; $values = array_values($arguments); if ($n_supplied - 1 == $n_required && is_array(end($values))) { $options = array_pop($arguments); From 3f6516d7e96970a6ad1033d5180c4f788ae10683 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 12:56:18 +0000 Subject: [PATCH 26/58] add the rest of GValue get() --- examples/watermark-text.php | 10 +++++++ src/GValue.php | 57 ++++++++++++++++++++++++++++++++----- src/Image.php | 3 +- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/examples/watermark-text.php b/examples/watermark-text.php index 04d30e1..88d2c73 100755 --- a/examples/watermark-text.php +++ b/examples/watermark-text.php @@ -17,6 +17,16 @@ 'n' => -1 ]); +echo "width = $image->width \n"; +echo "height = $image->height \n"; +echo "page_height = $image->page_height \n"; + + +exit; + + +$image->writeToFile("x.v"); + $output_filename = $argv[2]; $text = $argv[3]; diff --git a/src/GValue.php b/src/GValue.php index d975ac2..b582986 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -180,6 +180,7 @@ function set($value) { default: $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { + case Init::gtypes("GObject"): Init::ffi()-> g_value_set_object($this->pointer, $value->pointer); @@ -234,20 +235,62 @@ function get() { break; case Init::gtypes("VipsRefString"): - $psize = Init::ffi()->new("size_t*"); + $p_size = Init::ffi()->new("size_t[1]"); $result = Init::ffi()-> - vips_value_get_ref_string($this->pointer, $psize); - # $psize[0] will be the string length, but assume it's null + vips_value_get_ref_string($this->pointer, $p_size); + # $p_size[0] will be the string length, but assume it's null # terminated break; + case Init::gtypes("VipsImage"): + $pointer = Init::ffi()->g_value_get_object($this->pointer); + // get_object does not increment the ref count + Init::ffi()->g_object_ref($pointer); + $result = new Image($pointer); + break; + + case Init::gtypes("VipsArrayInt"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_int($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $result[] = $pointer[$i]; + } + break; + + case Init::gtypes("VipsArrayDouble"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_double($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $result[] = $pointer[$i]; + } + break; + + case Init::gtypes("VipsArrayImage"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_image($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $image_pointer = $pointer[$i]; + Init::ffi()->g_object_ref($image_pointer); + $result[] = new Image($image_pointer); + } + break; + + case Init::gtypes("VipsBlob"): + $p_len = Init::ffi()->new("size_t[1]"); + $pointer = Init::ffi()-> + vips_value_get_blob($this->pointer, $p_len); + $result = \FFI::string($pointer, $p_len[0]); + break; + default: $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case Init::gtypes("GObject"): - $result = Init::ffi()->g_value_get_object($this->pointer); - break; - case Init::gtypes("GEnum"): $result = Init::ffi()->g_value_get_enum($this->pointer); $result = self::fromEnum($gtype, $result); diff --git a/src/Image.php b/src/Image.php index 85a3f63..a660df8 100644 --- a/src/Image.php +++ b/src/Image.php @@ -997,7 +997,8 @@ public function writeToFile(string $name, array $options = []): void { Utils::debugLog('writeToFile', [ 'instance' => $this, - 'arguments' => [$filename, $options] + 'name' => $name, + 'options' => $options ]); $filename = Init::filename_get_filename($name); From a0df2830e4ab00c74979c642fdb9b3180d5a000b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 15:20:40 +0000 Subject: [PATCH 27/58] can't get callStatic working from methods --- examples/watermark-text.php | 10 ---------- src/Image.php | 9 ++++++++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/examples/watermark-text.php b/examples/watermark-text.php index 88d2c73..04d30e1 100755 --- a/examples/watermark-text.php +++ b/examples/watermark-text.php @@ -17,16 +17,6 @@ 'n' => -1 ]); -echo "width = $image->width \n"; -echo "height = $image->height \n"; -echo "page_height = $image->page_height \n"; - - -exit; - - -$image->writeToFile("x.v"); - $output_filename = $argv[2]; $text = $argv[3]; diff --git a/src/Image.php b/src/Image.php index a660df8..0afbc04 100644 --- a/src/Image.php +++ b/src/Image.php @@ -961,7 +961,10 @@ public function newFromImage($value): Image 'arguments' => [$value] ]); - $pixel = self::black(1, 1)->add($value)->cast($this->format); + $pixel = static::black(1, 1)->add($value)->cast($this->format); + + exit; + $image = $pixel->embed( 0, 0, @@ -1325,6 +1328,8 @@ public function __toString() */ public function __call(string $name, array $arguments) { + echo "** Calling $name in object context\n"; + return VipsOperation::callBase($name, $this, $arguments); } @@ -1340,6 +1345,8 @@ public function __call(string $name, array $arguments) */ public static function __callStatic(string $name, array $arguments) { + echo "** Calling $name in static context\n"; + return VipsOperation::callBase($name, null, $arguments); } From 4b3e2b6f570448861a68e06bcaab59ac3a0a2ccb Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 17:16:47 +0000 Subject: [PATCH 28/58] watermark-test works! next: revise code, add new stuff to test suite --- examples/watermark-text.php | 2 +- src/Image.php | 7 ----- src/VipsOperation.php | 55 +++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/examples/watermark-text.php b/examples/watermark-text.php index 04d30e1..654cada 100755 --- a/examples/watermark-text.php +++ b/examples/watermark-text.php @@ -4,7 +4,7 @@ require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; -Vips\Config::setLogger(new Vips\DebugLogger()); +#Vips\Config::setLogger(new Vips\DebugLogger()); if (count($argv) != 4) { echo("usage: ./watermark-text.php input output \"some text\"\n"); diff --git a/src/Image.php b/src/Image.php index 0afbc04..aa400d5 100644 --- a/src/Image.php +++ b/src/Image.php @@ -962,9 +962,6 @@ public function newFromImage($value): Image ]); $pixel = static::black(1, 1)->add($value)->cast($this->format); - - exit; - $image = $pixel->embed( 0, 0, @@ -1328,8 +1325,6 @@ public function __toString() */ public function __call(string $name, array $arguments) { - echo "** Calling $name in object context\n"; - return VipsOperation::callBase($name, $this, $arguments); } @@ -1345,8 +1340,6 @@ public function __call(string $name, array $arguments) */ public static function __callStatic(string $name, array $arguments) { - echo "** Calling $name in static context\n"; - return VipsOperation::callBase($name, null, $arguments); } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index e0f50aa..9e5d0a3 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -212,47 +212,56 @@ static function callBase( $operation = self::newFromName($name); $introspect = self::introspect($name); - /* Take any optional args off the end. + /* Because of the way php callStatic works, we can sometimes be given + * an instance even when no instance was given. + * + * We must loop over the required args and set them from the supplied + * args, using instance if required, and only check the nargs after + * this pass. */ $n_required = count($introspect->required_input); $n_supplied = count($arguments); - if ($instance) { - $n_supplied += 1; - } - - $options = []; - $values = array_values($arguments); - if ($n_supplied - 1 == $n_required && is_array(end($values))) { - $options = array_pop($arguments); - $n_supplied -= 1; - } - if ($n_required != $n_supplied) { - Init::error("$n_required arguments required, " . - "but $n_supplied supplied"); - } - - Utils::debugLog("callBase", ["setting arguments ..."]); - - /* Set required. - */ - $i = 0; + $used_instance = false; + $n_used = 0; foreach ($introspect->required_input as $name) { if ($name == $introspect->member_this) { if (!$instance) { + $operation->unrefOutputs(); Init::error("instance argument not supplied"); } $operation->set($name, $instance); + $used_instance = true; + } + else if ($n_used < $n_supplied) { + $operation->set($name, $arguments[$n_used]); + $n_used += 1; } else { - $operation->set($name, $arguments[$i]); - $i += 1; + $operation->unrefOutputs(); + Init::error("$n_required arguments required, " . + "but $n_supplied supplied"); } } + /* If there's one extra arg and it's an array, use it as our options. + */ + $options = []; + if ($n_supplied == $n_used + 1 && is_array($arguments[$n_used])) { + $options = array_pop($arguments); + $n_supplied -= 1; + } + + if ($n_supplied != $n_used) { + $operation->unrefOutputs(); + Init::error("$n_required arguments required, " . + "but $n_supplied supplied"); + } + /* Set optional. */ foreach ($options as $name => $value) { if (!in_array($name, $introspect->optional_input)) { + $operation->unrefOutputs(); Init::error("optional argument '$name' does not exist"); } From 389c7d40436c10ebb95d78bf127f812456761959 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 14 Feb 2022 18:38:56 +0000 Subject: [PATCH 29/58] start fixing tests --- src/GValue.php | 1 - src/Image.php | 28 ++++++++++++---------------- src/Init.php | 8 ++++---- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/GValue.php b/src/GValue.php index b582986..f9ead8b 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -180,7 +180,6 @@ function set($value) { default: $fundamental = Init::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case Init::gtypes("GObject"): Init::ffi()-> g_value_set_object($this->pointer, $value->pointer); diff --git a/src/Image.php b/src/Image.php index aa400d5..682fce0 100644 --- a/src/Image.php +++ b/src/Image.php @@ -857,25 +857,27 @@ public static function newFromArray( $width = count($array[0]); $n = $width * $height; - $a = Init::ffi()->new("double[]", $n); + $ctype = \FFI::arrayType(\FFI::type("double"), [$n]); + $a = \FFI::new($ctype, true, true); for($y = 0; $y < $height; $y++) { for($x = 0; $x < $width; $x++) { - $a[$x + $y * $width] = $array[y][x]; + $a[$x + $y * $width] = $array[$y][$x]; } } - $result = Init::ffi()-> + $pointer = Init::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); - if (\FFI::isNull($result)) { + if (\FFI::isNull($pointer)) { Init::error(); } + $result = new Image($pointer); - $image.set_type(GValue::gdouble_type, 'scale', $scale); - $image.set_type(GValue::gdouble_type, 'offset', $offset); + $result->setType(Init::gtypes("gdouble"), 'scale', $scale); + $result->setType(Init::gtypes("gdouble"), 'offset', $offset); Utils::debugLog('newFromArray', ['result' => $result]); - return image; + return $result; } /** @@ -1184,7 +1186,7 @@ public function __set(string $name, $value): void */ public function __isset(string $name): bool { - return $this->typeof($name) !== 0; + return $this->typeof($name) != 0; } /** @@ -1245,10 +1247,7 @@ public function set(string $name, $value): void $gvalue = new GValue(); $gvalue->setType($this->typeof($name)); $gvalue->set($value); - if (Init::ffi()-> - vips_image_set($this->pointer, $name, $gvalue) != 0) { - Init::error(); - } + Init::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); } /** @@ -1273,10 +1272,7 @@ public function setType($type, string $name, $value): void $gvalue = new GValue(); $gvalue->setType($type); $gvalue->set($value); - if (Init::ffi()-> - vips_image_set($this->pointer, $name, $gvalue) != 0) { - Init::error(); - } + Init::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); } /** diff --git a/src/Init.php b/src/Init.php index b9e785b..968897c 100644 --- a/src/Init.php +++ b/src/Init.php @@ -116,7 +116,7 @@ public static function error(string $message = "") $message = Init::ffi()->vips_error_buffer(); Init::ffi()->vips_error_clear(); } - $exception = new Exception($message); + $exception = new Vips\Exception($message); Utils::errorLog($message, $exception); throw $exception; } @@ -190,7 +190,7 @@ private function init() $result = $ffi->vips_init(""); if ($result != 0) { - throw new Exception("libvips error: $ffi->vips_error_buffer()"); + throw new Vips\Exception("libvips error: $ffi->vips_error_buffer()"); } Utils::debugLog("init", ["vips_init" => $result]); @@ -207,7 +207,7 @@ private function init() ]); if (!$this->atLeast(8, 7)) { - throw new Exception("your libvips is too old -- " . + throw new Vips\Exception("your libvips is too old -- " . "8.7 or later required"); } @@ -216,7 +216,7 @@ private function init() # necessary since GType is the size of a pointer, and there's no # easy way to discover if php is running on a 32 or 64-bit # systems (as far as I can see) - throw new Exception("your php only supports 32-bit ints -- " . + throw new Vips\Exception("your php only supports 32-bit ints -- " . "64 bit ints required"); } From b4b9d6bff9fd5da4b9b9e6145123a0815502c389 Mon Sep 17 00:00:00 2001 From: Boris Glumpler Date: Thu, 3 Feb 2022 23:33:01 +0100 Subject: [PATCH 30/58] Allowed for psr/log 2.0 and 3.0 to be installed as well --- composer.json | 2 +- src/DebugLogger.php | 2 +- tests/LoggerTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index e85049d..3d5aa7f 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ ], "require": { "php": ">=7.4", - "psr/log": "^1.1.3" + "psr/log": "^1.1.3|^2.0|^3.0" }, "require-dev": { "php-parallel-lint/php-parallel-lint": "^1.2", diff --git a/src/DebugLogger.php b/src/DebugLogger.php index 4cfa6ee..ddf8373 100644 --- a/src/DebugLogger.php +++ b/src/DebugLogger.php @@ -69,7 +69,7 @@ class DebugLogger implements LoggerInterface * * @return void */ - public function log($level, $message, array $context = []) + public function log($level, $message, array $context = []): void { // `Vips\Image` to string convert array_walk_recursive($context, function (&$value) { diff --git a/tests/LoggerTest.php b/tests/LoggerTest.php index ea79e67..c7f1d37 100644 --- a/tests/LoggerTest.php +++ b/tests/LoggerTest.php @@ -33,7 +33,7 @@ public function testSetLoggerCall() * * @return void */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = array()): void { // Do logging logic here. } From 0fbb9e70a9755972b8bbf8fa01f6d7616a382c03 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Feb 2022 14:01:38 +0000 Subject: [PATCH 31/58] start adding constant imagazation --- examples/watermark-image.php | 6 ++++++ src/Image.php | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 6e12384..3d25923 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -6,6 +6,12 @@ Vips\Config::setLogger(new Vips\DebugLogger()); +$image = Vips\Image::black(2, 2); +$image = $image->add([[1, 2], [3, 4]]); + +exit; + + if(count($argv) != 4) { echo("usage: ./watermark.php input-image output-image watermark-image\n"); exit(1); diff --git a/src/Image.php b/src/Image.php index 682fce0..5c4484d 100644 --- a/src/Image.php +++ b/src/Image.php @@ -669,9 +669,8 @@ private static function isImageish($value): bool /** * Turn a constant (eg. 1, '12', [1, 2, 3], [[1]]) into an image using - * match_image as a guide. + * this as a guide. * - * @param Image $match_image Use this image as a guide. * @param mixed $value Turn this into an image. * * @throws Exception @@ -680,12 +679,12 @@ private static function isImageish($value): bool * * @internal */ - private static function imageize(Image $match_image, $value): Image + public function imageize($value): Image { if (self::is2D($value)) { $result = self::newFromArray($value); } else { - $result = $match_image->newFromImage($value); + $result = $this->newFromImage($value); } return $result; @@ -1425,7 +1424,7 @@ public function offsetSet($offset, $value): void // if we are setting a constant as the first element, we must expand it // to an image, since bandjoin must have an image as the first argument if ($n_left === 0 && !($value instanceof Image)) { - $value = self::imageize($this, $value); + $value = $this->imageize($value); } $components = []; @@ -1973,11 +1972,11 @@ public function ifthenelse($then, $else, array $options = []): Image } if (!($then instanceof Image)) { - $then = self::imageize($match_image, $then); + $then = $match_image->imageize($then); } if (!($else instanceof Image)) { - $else = self::imageize($match_image, $else); + $else = $match_image->imageize($else); } return VipsOperation::call('ifthenelse', $this, [$then, $else], $options); From 82f3b65dbc7db75e5dca0ecd638e282a4875312f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Feb 2022 16:09:07 +0000 Subject: [PATCH 32/58] down to 13 failures --- src/Image.php | 125 ++++++++++++++++++++++++++++----------- src/Init.php | 2 +- src/VipsOperation.php | 132 ++++++++++++++++++++++++++---------------- 3 files changed, 173 insertions(+), 86 deletions(-) diff --git a/src/Image.php b/src/Image.php index 5c4484d..5aca2e5 100644 --- a/src/Image.php +++ b/src/Image.php @@ -662,7 +662,7 @@ private static function is2D($value): bool * * @internal */ - private static function isImageish($value): bool + public static function isImageish($value): bool { return self::is2D($value) || $value instanceof Image; } @@ -682,12 +682,12 @@ private static function isImageish($value): bool public function imageize($value): Image { if (self::is2D($value)) { - $result = self::newFromArray($value); - } else { - $result = $this->newFromImage($value); + $value = self::newFromArray($value); + } else if (is_array($value)) { + $value = $this->newFromImage($value); } - return $result; + return $value; } /** @@ -743,6 +743,35 @@ private static function runCmplx(\Closure $func, Image $image): Image return $image; } + /** + * Handy for things like self::more. Call a 2-ary vips operator like + * 'more', but if the arg is not an image (ie. it's a constant), call + * 'more_const' instead. + * + * @param mixed $other The right-hand argument. + * @param string $base The base part of the operation name. + * @param string $op The action to invoke. + * @param array $options An array of options to pass to the operation. + * + * @throws Exception + * + * @return mixed The operation result. + * + * @internal + */ + private function callEnum( + $other, + string $base, + string $op, + array $options = [] + ) { + if (self::isImageish($other)) { + return VipsOperation::call($base, $this, [$other, $op], $options); + } else { + return VipsOperation::call($base . '_const', $this, [$op, $other], $options); + } + } + /** * Create a new Image from a file on disc. * @@ -802,11 +831,12 @@ public static function newFromBuffer( ): Image { Utils::debugLog('newFromBuffer', [ 'instance' => null, - 'arguments' => [$buffer, $option_string, $options] + 'arguments' => [$buffer, $string_options, $options] ]); - $loader = Init::ffi()->vips_foreign_find_load_buffer($buffer); - if (\FFI::isNull($loader)) { + $loader = Init::ffi()-> + vips_foreign_find_load_buffer($buffer, strlen($buffer)); + if ($loader == null) { Init::error(); } @@ -866,7 +896,7 @@ public static function newFromArray( $pointer = Init::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); - if (\FFI::isNull($pointer)) { + if ($pointer == null) { Init::error(); } $result = new Image($pointer); @@ -904,12 +934,20 @@ public static function newFromMemory( 'arguments' => [$data, $width, $height, $bands, $format] ]); - $result = Init::ffi()-> - vips_image_new_from_memory($data, $width, $height, $bands, $format); - if (\FFI::isNull($result)) { + $pointer = Init::ffi()->vips_image_new_from_memory( + $data, + strlen($data), + $width, + $height, + $bands, + $format + ); + if ($pointer == null) { Init::error(); } + $result = new Image($pointer); + Utils::debugLog('newFromMemory', ['result' => $result]); return $result; @@ -1043,12 +1081,22 @@ public function writeToBuffer(string $suffix, array $options = []): string 'arguments' => [$suffix, $options] ]); - $result = Init::ffi()-> - vips_image_write_to_buffer($this->pointer, $suffix, $options); - if ($result === -1) { + $filename = Init::filename_get_filename($suffix); + $string_options = Init::filename_get_options($suffix); + + $saver = Init::ffi()->vips_foreign_find_save_buffer($filename); + if ($saver == "") { Init::error(); } + if (strlen($string_options) != 0) { + $options = array_merge([ + "string_options" => $string_options, + ], $options); + } + + $result = VipsOperation::call($saver, $this, $options); + Utils::debugLog('writeToBuffer', ['result' => $result]); return $result; @@ -1068,11 +1116,17 @@ public function writeToMemory(): string 'arguments' => [] ]); - $result = Init::ffi()->vips_image_write_to_memory($this->pointer); - if ($result === -1) { + $ctype = \FFI::arrayType(\FFI::type("size_t"), [1]); + $p_size = \FFI::new($ctype); + + $pointer = Init::ffi()-> + vips_image_write_to_memory($this->pointer, $p_size); + if ($pointer == null) { Init::error(); } + $result = \FFI::string($pointer, $p_size[0]); + Utils::debugLog('writeToMemory', ['result' => $result]); return $result; @@ -1139,10 +1193,11 @@ public function copyMemory(): Image 'arguments' => [] ]); - $result = Init::ffi()->vips_image_copy_memory($this->pointer); - if ($result === -1) { + $pointer = Init::ffi()->vips_image_copy_memory($this->pointer); + if ($pointer == null) { Init::error(); } + $result = new Image($pointer); Utils::debugLog('copyMemory', ['result' => $result]); @@ -1592,7 +1647,7 @@ public function remainder($other, array $options = []): Image */ public function pow($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'math2', OperationMath2::POW, $options); + return self::callEnum($other, 'math2', OperationMath2::POW, $options); } /** @@ -1607,7 +1662,7 @@ public function pow($other, array $options = []): Image */ public function wop($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'math2', OperationMath2::WOP, $options); + return self::callEnum($other, 'math2', OperationMath2::WOP, $options); } /** @@ -1622,7 +1677,7 @@ public function wop($other, array $options = []): Image */ public function lshift($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'boolean', OperationBoolean::LSHIFT, $options); + return self::callEnum($other, 'boolean', OperationBoolean::LSHIFT, $options); } /** @@ -1637,7 +1692,7 @@ public function lshift($other, array $options = []): Image */ public function rshift($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'boolean', OperationBoolean::RSHIFT, $options); + return self::callEnum($other, 'boolean', OperationBoolean::RSHIFT, $options); } /** @@ -1654,7 +1709,7 @@ public function rshift($other, array $options = []): Image public function andimage($other, array $options = []): Image { // phpdoc hates OperationBoolean::AND, so use the string form here - return VipsOperation::callEnum($other, 'boolean', 'and', $options); + return self::callEnum($other, 'boolean', 'and', $options); } /** @@ -1670,7 +1725,7 @@ public function andimage($other, array $options = []): Image public function orimage($other, array $options = []): Image { // phpdoc hates OperationBoolean::OR, so use the string form here - return VipsOperation::callEnum($other, 'boolean', 'or', $options); + return self::callEnum($other, 'boolean', 'or', $options); } /** @@ -1685,7 +1740,7 @@ public function orimage($other, array $options = []): Image */ public function eorimage($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'boolean', OperationBoolean::EOR, $options); + return self::callEnum($other, 'boolean', OperationBoolean::EOR, $options); } /** @@ -1700,7 +1755,7 @@ public function eorimage($other, array $options = []): Image */ public function more($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::MORE, $options); + return self::callEnum($other, 'relational', OperationRelational::MORE, $options); } /** @@ -1715,7 +1770,7 @@ public function more($other, array $options = []): Image */ public function moreEq($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::MOREEQ, $options); + return self::callEnum($other, 'relational', OperationRelational::MOREEQ, $options); } /** @@ -1730,7 +1785,7 @@ public function moreEq($other, array $options = []): Image */ public function less($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::LESS, $options); + return self::callEnum($other, 'relational', OperationRelational::LESS, $options); } /** @@ -1745,7 +1800,7 @@ public function less($other, array $options = []): Image */ public function lessEq($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::LESSEQ, $options); + return self::callEnum($other, 'relational', OperationRelational::LESSEQ, $options); } /** @@ -1760,7 +1815,7 @@ public function lessEq($other, array $options = []): Image */ public function equal($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::EQUAL, $options); + return self::callEnum($other, 'relational', OperationRelational::EQUAL, $options); } /** @@ -1775,7 +1830,7 @@ public function equal($other, array $options = []): Image */ public function notEq($other, array $options = []): Image { - return VipsOperation::callEnum($other, 'relational', OperationRelational::NOTEQ, $options); + return self::callEnum($other, 'relational', OperationRelational::NOTEQ, $options); } /** @@ -1897,10 +1952,10 @@ public function composite($other, $mode, array $options = []): Image $mode = [$mode]; } - $mode = array_map(function ($x) { + $mode = array_map( // Use BlendMode::OVER if a non-existent value is given. - return self::$blendModeToInt[$x] ?? BlendMode::OVER; - }, $mode); + fn($x) => self::$blendModeToInt[$x] ?? BlendMode::OVER, + $mode); return VipsOperation::call( 'composite', diff --git a/src/Init.php b/src/Init.php index 968897c..c8468f9 100644 --- a/src/Init.php +++ b/src/Init.php @@ -116,7 +116,7 @@ public static function error(string $message = "") $message = Init::ffi()->vips_error_buffer(); Init::ffi()->vips_error_clear(); } - $exception = new Vips\Exception($message); + $exception = new Exception($message); Utils::errorLog($message, $exception); throw $exception; } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 9e5d0a3..0bb0494 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -59,6 +59,11 @@ class VipsOperation extends VipsObject */ public \FFI\CData $pointer; + /** + * Introspection data for this operation. + */ + public Introspect $introspect; + function __construct($pointer) { $this->pointer = Init::ffi()-> @@ -71,14 +76,37 @@ public static function newFromName($name) { Utils::debugLog("VipsOperation", ["name" => $name]); $pointer = Init::ffi()->vips_operation_new($name); - if (\FFI::isNull($pointer)) { + if ($pointer == null) { Init::error(); } return new VipsOperation($pointer); } - private static function introspect($name) { + public function setMatch($name, $match_image, $value) { + $flags = $this->introspect->arguments[$name]["flags"]; + $gtype = $this->introspect->arguments[$name]["type"]; + + if ($match_image != null) { + if ($gtype == Init::gtypes("VipsImage")) { + $value = $match_image->imageize($value); + } + else if ($gtype == Init::gtypes("VipsArrayImage")) { + array_map(fn($x) => $match_image->imageize($x), $value); + } + } + + # MODIFY args need to be copied before they are set + if (($flags & ArgumentFlags::MODIFY) != 0) { + # logger.debug('copying MODIFY arg %s', name) + # make sure we have a unique copy + $value = $value->copyMemory(); + } + + parent::set($name, $value); + } + + private static function introspect($name): Introspect { static $cache = []; if (!array_key_exists($name, $cache)) { @@ -88,6 +116,24 @@ private static function introspect($name) { return $cache[$name]; } + private static function findInside($predicate, $x) { + if ($predicate($x)) { + return $x; + } + + if (is_array($x)) { + foreach ($x as $y) { + $result = self::findInside($predicate, $y); + + if ($result != null) { + return $result; + } + } + } + + return null; + } + /** * Unwrap an array of stuff ready to pass down to the vips_ layer. We * swap instances of Image for the ffi pointer. @@ -189,7 +235,7 @@ private static function errorIsArray($result): void * __call(), which cannot know which args are required and which are * optional. See call() below for a version with the options broken out. * - * @param string $name The operation name. + * @param string $operation_name The operation name. * @param Image|null $instance The instance this operation is being invoked * from. * @param array $arguments An array of arguments to pass to the @@ -200,17 +246,35 @@ private static function errorIsArray($result): void * @return mixed The result(s) of the operation. */ static function callBase( - string $name, + string $operation_name, ?Image $instance, array $arguments ) { - Utils::debugLog($name, [ + Utils::debugLog($operation_name, [ 'instance' => $instance, 'arguments' => $arguments ]); - $operation = self::newFromName($name); - $introspect = self::introspect($name); + $operation = self::newFromName($operation_name); + $operation->introspect = self::introspect($operation_name); + + /* the first image argument is the thing we expand constants to + * match ... look inside tables for images, since we may be passing + * an array of images as a single param. + */ + if ($instance != null) { + $match_image = $instance; + } + else { + $match_image = self::findInside( + fn($x) => $x instanceof Image, + $arguments + ); + } + + Utils::debugLog($operation_name, [ + 'match_image' => $match_image + ]); /* Because of the way php callStatic works, we can sometimes be given * an instance even when no instance was given. @@ -219,21 +283,21 @@ static function callBase( * args, using instance if required, and only check the nargs after * this pass. */ - $n_required = count($introspect->required_input); + $n_required = count($operation->introspect->required_input); $n_supplied = count($arguments); $used_instance = false; $n_used = 0; - foreach ($introspect->required_input as $name) { - if ($name == $introspect->member_this) { + foreach ($operation->introspect->required_input as $name) { + if ($name == $operation->introspect->member_this) { if (!$instance) { $operation->unrefOutputs(); Init::error("instance argument not supplied"); } - $operation->set($name, $instance); + $operation->setMatch($name, $match_image, $instance); $used_instance = true; } else if ($n_used < $n_supplied) { - $operation->set($name, $arguments[$n_used]); + $operation->setMatch($name, $match_image, $arguments[$n_used]); $n_used += 1; } else { @@ -260,12 +324,12 @@ static function callBase( /* Set optional. */ foreach ($options as $name => $value) { - if (!in_array($name, $introspect->optional_input)) { + if (!in_array($name, $operation->introspect->optional_input)) { $operation->unrefOutputs(); Init::error("optional argument '$name' does not exist"); } - $operation->set($name, $value); + $operation->setMatch($name, $match_image, $value); } /* Build the operation @@ -273,11 +337,12 @@ static function callBase( Utils::debugLog("callBase", ["building ..."]); $pointer = Init::ffi()-> vips_cache_operation_build($operation->pointer); - if (\FFI::isNull($pointer)) { + if ($pointer == null) { $operation->unrefOutputs(); Init::error(); } $operation = new VipsOperation($pointer); + $operation->introspect = self::introspect($operation_name); # TODO .. need to attach input refs to output, see _find_inside in # pyvips @@ -285,13 +350,13 @@ static function callBase( /* Fetch required output args (and modified input args). */ $result = []; - foreach ($introspect->required_output as $name) { + foreach ($operation->introspect->required_output as $name) { $result[] = $operation->get($name); } /* Any optional output args. */ - foreach ($introspect->optional_output as $name) { + foreach ($operation->introspect->optional_output as $name) { if (in_array($name, $options)) { $result[$name] = $operation->get($name); } @@ -344,39 +409,6 @@ public static function call( array_merge($arguments, [$options])); } - /** - * Handy for things like self::more. Call a 2-ary vips operator like - * 'more', but if the arg is not an image (ie. it's a constant), call - * 'more_const' instead. - * - * @param mixed $other The right-hand argument. - * @param string $base The base part of the operation name. - * @param string $op The action to invoke. - * @param array $options An array of options to pass to the operation. - * - * @throws Exception - * - * @return mixed The operation result. - * - * @internal - */ - private function callEnum( - $other, - string $base, - string $op, - array $options = [] - ) { - if (self::isImageish($other)) { - return self::call($base, $this, [$other, $op], $options); - } else { - return self::call($base . '_const', $this, [$op, $other], $options); - } - } - - - - - } /* From 70538f0cdbadbfe1122faa403703e32aa57ea85f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 15 Feb 2022 17:07:01 +0000 Subject: [PATCH 33/58] 9 errors left --- examples/watermark-image.php | 7 +++++-- examples/x.jpg | Bin 0 -> 270685 bytes src/GValue.php | 14 +++++++------- src/Image.php | 5 +++-- src/VipsOperation.php | 9 +++------ 5 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 examples/x.jpg diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 3d25923..04767eb 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -6,8 +6,11 @@ Vips\Config::setLogger(new Vips\DebugLogger()); -$image = Vips\Image::black(2, 2); -$image = $image->add([[1, 2], [3, 4]]); +$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); +$overlay = $image->add(20)->bandjoin(128); +$overlay = $overlay->cast(Vips\BandFormat::UCHAR); +$comp = $image->composite($overlay, Vips\BlendMode::OVER); +$comp->writeToFile($argv[2]); exit; diff --git a/examples/x.jpg b/examples/x.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c4f2d375a5ee2a9f401485605cd7d3eba1b0f3bd GIT binary patch literal 270685 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 z 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

H@NXkT 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%0D3Tg)m&o|>6*AX_B5?#EGVojJwD_6C}G**IIx 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

SYS(GoFhW)sQ06We#~0hEN355@N4i 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 uml*F!z&I43g_type_name($gtype); - throw new \BadMethodCallException("$typeName not implemented"); + throw new \BadMethodCallException("gtype $gtype not implemented"); break; } } diff --git a/src/Image.php b/src/Image.php index 5aca2e5..b0511b4 100644 --- a/src/Image.php +++ b/src/Image.php @@ -683,9 +683,10 @@ public function imageize($value): Image { if (self::is2D($value)) { $value = self::newFromArray($value); - } else if (is_array($value)) { + } + else if (is_array($value)) { $value = $this->newFromImage($value); - } + } return $value; } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 0bb0494..0abbd23 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -74,7 +74,6 @@ function __construct($pointer) public static function newFromName($name) { - Utils::debugLog("VipsOperation", ["name" => $name]); $pointer = Init::ffi()->vips_operation_new($name); if ($pointer == null) { Init::error(); @@ -91,7 +90,8 @@ public function setMatch($name, $match_image, $value) { if ($gtype == Init::gtypes("VipsImage")) { $value = $match_image->imageize($value); } - else if ($gtype == Init::gtypes("VipsArrayImage")) { + else if ($gtype == Init::gtypes("VipsArrayImage") && + is_array($value)) { array_map(fn($x) => $match_image->imageize($x), $value); } } @@ -272,10 +272,6 @@ static function callBase( ); } - Utils::debugLog($operation_name, [ - 'match_image' => $match_image - ]); - /* Because of the way php callStatic works, we can sometimes be given * an instance even when no instance was given. * @@ -356,6 +352,7 @@ static function callBase( /* Any optional output args. */ + Utils::debugLog("callBase", ["fetching result ..."]); foreach ($operation->introspect->optional_output as $name) { if (in_array($name, $options)) { $result[$name] = $operation->get($name); From 5c21316a7f16c048dc82ff26b91893a7faa1028d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Feb 2022 13:57:40 +0000 Subject: [PATCH 34/58] nail a coupl;e more small errors --- src/Image.php | 13 +++++++------ tests/NewTest.php | 17 ----------------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/Image.php b/src/Image.php index b0511b4..5d6bc39 100644 --- a/src/Image.php +++ b/src/Image.php @@ -681,14 +681,15 @@ public static function isImageish($value): bool */ public function imageize($value): Image { + if ($value instanceof Image) { + return $value; + } if (self::is2D($value)) { - $value = self::newFromArray($value); + return self::newFromArray($value); } - else if (is_array($value)) { - $value = $this->newFromImage($value); + else { + return $this->newFromImage($value); } - - return $value; } /** @@ -1341,7 +1342,7 @@ public function setType($type, string $name, $value): void */ public function remove(string $name): void { - if (Init::ffi()->vips_image_remove($this->pointer, $name) != 0) { + if (!Init::ffi()->vips_image_remove($this->pointer, $name)) { Init::error(); } } diff --git a/tests/NewTest.php b/tests/NewTest.php index 3a97c6b..bf72426 100644 --- a/tests/NewTest.php +++ b/tests/NewTest.php @@ -57,14 +57,6 @@ public function testVipsNewFromImage() $this->assertEquals($image2->avg(), 2); } - public function testVipsFindLoad() - { - $filename = __DIR__ . '/images/img_0076.jpg'; - $loader = Vips\Image::findLoad($filename); - - $this->assertEquals($loader, 'VipsForeignLoadJpegFile'); - } - public function testVipsNewFromBuffer() { $filename = __DIR__ . '/images/img_0076.jpg'; @@ -76,15 +68,6 @@ public function testVipsNewFromBuffer() $this->assertEquals($image->bands, 3); } - public function testVipsFindLoadBuffer() - { - $filename = __DIR__ . '/images/img_0076.jpg'; - $buffer = file_get_contents($filename); - $loader = Vips\Image::findLoadBuffer($buffer); - - $this->assertEquals($loader, 'VipsForeignLoadJpegBuffer'); - } - public function testVipsCopyMemory() { $filename = __DIR__ . '/images/img_0076.jpg'; From 548e1e48f23fa2d7738b337cfe14e21bd4374c85 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Feb 2022 16:33:19 +0000 Subject: [PATCH 35/58] down to 3 test suite fails --- examples/watermark-image.php | 8 +++--- src/Image.php | 54 ++++++++++++++++++++++++++++++++---- src/VipsObject.php | 10 +++---- src/VipsOperation.php | 8 ++++-- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 04767eb..3edb2a7 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -7,10 +7,10 @@ Vips\Config::setLogger(new Vips\DebugLogger()); $image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); -$overlay = $image->add(20)->bandjoin(128); -$overlay = $overlay->cast(Vips\BandFormat::UCHAR); -$comp = $image->composite($overlay, Vips\BlendMode::OVER); -$comp->writeToFile($argv[2]); + +$result = $image->maxpos(); + + exit; diff --git a/src/Image.php b/src/Image.php index 5d6bc39..bdc4309 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1242,7 +1242,7 @@ public function __set(string $name, $value): void */ public function __isset(string $name): bool { - return $this->typeof($name) != 0; + return $this->getType($name) != 0; } /** @@ -1251,7 +1251,7 @@ public function __isset(string $name): bool * This is handy for fields whose name * does not match PHP's variable naming conventions, like `'exif-data'`. * - * It will throw an exception if $name does not exist. Use Image::typeof() + * It will throw an exception if $name does not exist. Use Image::getType() * to test for the existence of a field. * * @param string $name The property name. @@ -1280,11 +1280,23 @@ public function get(string $name) * * @return integer */ - public function typeof(string $name): int + public function getType(string $name): int { return Init::ffi()->vips_image_get_typeof($this->pointer, $name); } + /** + * A deprecated synonym for getType(). + * + * @param string $name The property name. + * + * @return integer + */ + public function typeOf(string $name): int + { + return $this->getType($name); + } + /** * Set any property on the underlying image. * @@ -1301,8 +1313,39 @@ public function typeof(string $name): int public function set(string $name, $value): void { $gvalue = new GValue(); - $gvalue->setType($this->typeof($name)); + $gtype = $this->getType($name); + + /* If this is not a known field, guess a sensible type from the value. + */ + if ($gtype == 0) { + if (is_array($value)) { + if (is_int($value[0])) { + $gtype = Init::gtypes("VipsArrayInt"); + } + else if (is_float($value[0])) { + $gtype = Init::gtypes("VipsArrayDouble"); + } + else { + $gtype = Init::gtypes("VipsArrayImage"); + } + } + else if (is_int($value)) { + $gtype = Init::gtypes("gint"); + } + else if (is_float($value)) { + $gtype = Init::gtypes("gdouble"); + } + else if (is_string($value)) { + $gtype = Init::gtypes("VipsRefString"); + } + else { + $gtype = Init::gtypes("VipsImage"); + } + } + + $gvalue->setType($gtype); $gvalue->set($value); + Init::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); } @@ -1434,7 +1477,8 @@ public function offsetExists($offset): bool */ public function offsetGet($offset): ?Image { - return $this->offsetExists($offset) ? $this->extract_band($offset) : null; + return $this->offsetExists($offset) ? + $this->extract_band($offset) : null; } /** diff --git a/src/VipsObject.php b/src/VipsObject.php index f180359..f4ee011 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -89,7 +89,7 @@ function getDescription() { // NULL for no such name // very slow! avoid if possible // FIXME add a cache for this thing - function getPspec($name) { + function getPspec(string $name) { $pspec = Init::ffi()->new("GParamSpec*[1]"); $argument_class = Init::ffi()->new("VipsArgumentClass*[1]"); $argument_instance = Init::ffi()->new("VipsArgumentInstance*[1]"); @@ -111,7 +111,7 @@ function getPspec($name) { // get the type of a property from a VipsObject // 0 if no such property - function getType($name) { + function getType(string $name) { $pspec = $this->getPspec($name); if (\FFI::isNull($pspec)) { # need to clear any error, this is horrible @@ -123,12 +123,12 @@ function getType($name) { } } - function getBlurb(string $name) { + function getBlurb(string $name): string { $pspec = $this->getPspec($name); return Init::ffi()->g_param_spec_get_blurb($pspec); } - function getArgumentDescription(string $name) { + function getArgumentDescription(string $name): string { $pspec = $this->getPspec($name); return Init::ffi()->g_param_spec_get_description($pspec); } @@ -157,7 +157,7 @@ function set(string $name, $value) { g_object_set_property($this->gObject, $name, $gvalue->pointer); } - function setString($string_options) { + function setString(string $string_options) { $result = Init::ffi()-> vips_object_set_from_string($this->pointer, $string_options); diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 0abbd23..3f39d70 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -320,7 +320,8 @@ static function callBase( /* Set optional. */ foreach ($options as $name => $value) { - if (!in_array($name, $operation->introspect->optional_input)) { + if (!in_array($name, $operation->introspect->optional_input) && + !in_array($name, $operation->introspect->optional_output)) { $operation->unrefOutputs(); Init::error("optional argument '$name' does not exist"); } @@ -347,14 +348,15 @@ static function callBase( */ $result = []; foreach ($operation->introspect->required_output as $name) { - $result[] = $operation->get($name); + $result[$name] = $operation->get($name); } /* Any optional output args. */ Utils::debugLog("callBase", ["fetching result ..."]); + $option_keys = array_keys($options); foreach ($operation->introspect->optional_output as $name) { - if (in_array($name, $options)) { + if (in_array($name, $option_keys)) { $result[$name] = $operation->get($name); } } From fefe62f12b5e8399844d9b93ae0108b01bdfccc9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Feb 2022 16:59:45 +0000 Subject: [PATCH 36/58] down to two fails --- examples/watermark-image.php | 5 +- src/Image.php | 20 +------ src/Init.php | 1 + src/Interpolate.php | 109 +++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 21 deletions(-) create mode 100644 src/Interpolate.php diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 3edb2a7..5c63832 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -6,10 +6,7 @@ Vips\Config::setLogger(new Vips\DebugLogger()); -$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); - -$result = $image->maxpos(); - +$inter = Vips\Interpolate::newFromName("bicubic"); exit; diff --git a/src/Image.php b/src/Image.php index bdc4309..2ff30ec 100644 --- a/src/Image.php +++ b/src/Image.php @@ -956,27 +956,13 @@ public static function newFromMemory( } /** - * Make an interpolator from a name. + * Deprecated thing to make an interpolator. * - * @param string $name Name of the interpolator. - * Possible interpolators are: - * - `'nearest'`: Use nearest neighbour interpolation. - * - `'bicubic'`: Use bicubic interpolation. - * - `'bilinear'`: Use bilinear interpolation (the default). - * - `'nohalo'`: Use Nohalo interpolation. - * - `'lbb'`: Use LBB interpolation. - * - `'vsqbs'`: Use the VSQBS interpolation. - * - * @return resource|null The interpolator, or null on error. + * See Interpolator::newFromName() for the new thing. */ public static function newInterpolator(string $name) { - Utils::debugLog('newInterpolator', [ - 'instance' => null, - 'arguments' => [$name] - ]); - - return Init::ffi()->vips_interpolate_new($name); + return Interpolate::newFromName($name); } /** diff --git a/src/Init.php b/src/Init.php index c8468f9..8053488 100644 --- a/src/Init.php +++ b/src/Init.php @@ -649,6 +649,7 @@ private function init() "VipsObject" => $this->ffi->type("VipsObject*"), "VipsOperation" => $this->ffi->type("VipsOperation*"), "VipsImage" => $this->ffi->type("VipsImage*"), + "VipsInterpolate" => $this->ffi->type("VipsInterpolate*"), ]; $this->gtypes = [ diff --git a/src/Interpolate.php b/src/Interpolate.php new file mode 100644 index 0000000..72fefa2 --- /dev/null +++ b/src/Interpolate.php @@ -0,0 +1,109 @@ + + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ + +namespace Jcupitt\Vips; + +/** + * This class holds a pointer to a VipsInterpolate (the libvips + * base class for interpolators) and manages argument introspection and + * operation call. + * + * @category Images + * @package Jcupitt\Vips + * @author John Cupitt + * @copyright 2016 John Cupitt + * @license https://opensource.org/licenses/MIT MIT + * @link https://github.com/libvips/php-vips + */ +class Interpolate extends VipsObject +{ + /** + * A pointer to the underlying Interpolate. This is the same as the + * GObject, just cast to Interpolate to help FFI. + * + * @internal + */ + public \FFI\CData $pointer; + + function __construct($pointer) + { + $this->pointer = Init::ffi()-> + cast(Init::ctypes("VipsInterpolate"), $pointer); + + parent::__construct($pointer); + } + + /** + * Make an interpolator from a name. + * + * @param string $name Name of the interpolator. + * + * Possible interpolators are: + * - `'nearest'`: Use nearest neighbour interpolation. + * - `'bicubic'`: Use bicubic interpolation. + * - `'bilinear'`: Use bilinear interpolation (the default). + * - `'nohalo'`: Use Nohalo interpolation. + * - `'lbb'`: Use LBB interpolation. + * - `'vsqbs'`: Use the VSQBS interpolation. + * + * @return resource|null The interpolator, or null on error. + */ + public static function newFromName($name) + { + Utils::debugLog('newFromName', [ + 'arguments' => [$name] + ]); + + $pointer = Init::ffi()->vips_interpolate_new($name); + if ($pointer == null) { + Init::error(); + } + + return new Interpolate($pointer); + } + +} + +/* + * 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 + */ From 7bd9c995f4e0618297398d78943388f5220000dc Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 16 Feb 2022 18:12:59 +0000 Subject: [PATCH 37/58] two errors left though I think it's actually fixed? mysterious --- examples/watermark-image.php | 8 +------- examples/x.jpg | Bin 270685 -> 0 bytes src/Image.php | 5 +++-- src/VipsOperation.php | 6 +++++- 4 files changed, 9 insertions(+), 10 deletions(-) delete mode 100644 examples/x.jpg diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 5c63832..91abdef 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -4,13 +4,7 @@ require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; -Vips\Config::setLogger(new Vips\DebugLogger()); - -$inter = Vips\Interpolate::newFromName("bicubic"); - - -exit; - +#Vips\Config::setLogger(new Vips\DebugLogger()); if(count($argv) != 4) { echo("usage: ./watermark.php input-image output-image watermark-image\n"); diff --git a/examples/x.jpg b/examples/x.jpg deleted file mode 100644 index c4f2d375a5ee2a9f401485605cd7d3eba1b0f3bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 270685 zcmbTdcT`hd*FBmLNa#g^1_(t#svspmD4|LVgp$w<$OD2(q9P#(5(Mcg#?TcbgqBc6 zM5zLgAksvNAt2I3IwGJH5k$Sb@Ar-S8{__U@7-gZoRwsaHO|~Q*=wD-=KeeO_cNfy z`Uc@50AO#g2H*t%0ARooAP4|FwElBQ0eSv=_Bgbq|JU|Cv{nAshwIQ5=lVbXgxlQz z^*;>w-(fEa1T2FNqyO(23;?7-0NjV)Y3XQd0n`7-1|CKL6#Vb!+FDw`g8zy5_b&jz zRq#I%D|i3^(Er;1z0kuLe->Kn zf7<|Jyu1LO3J~xFfJ+Pr5(EBy1CTqML>}OO$Nx;n;d?F+HxC%X%f~Np=ujsL-~xg` zT-+cY9`3_g0Y?94D!9dXjvUvv0E@f&Lr##OI&tZRyb6{z?Go7c-xPJvhsN{qA3X+> zlsc)TtfH!h(9<_S8X8%hv9__bvq$6H+&w(K&f)_CFI>D7L?DvGu7^k5h@>PWCMDm# zb2lX;Gb{VS!<GH4|7IFKa71G|2#W4 zzp%Kpyz=Gy=GOMkkKLbp`~SfO1c3er*5T{_Ap3vd54i1zd+W zULOK>LmOTG-7XM?6jq#TyXIVl1Vf(~?=a6(u%BEfEinp5oJ62AHX?O`5!8xd`?T@K z*lWi3!b+AP8yAz?XF>?tDS?x)rJp2whPFfRfojXeG#+RGJ>6xeBy*D6#rZ_ZeeDme zC%SI&KaUN7G@zLq1+P{9kn5|gr6ZX4wa5)sXU%QDU#u8E^2s&8JaS#_O%RTL#XfFx z=NkTbL7G|XzPsWR%-Ce$&8aB2dl?qjTBoU^d&W*G!4MQiFHpqg{IPk|ijIXmb}q&s zywDcmC6QceMc1Bq;o=n9dLRA`1uXn3eZMQlw}S;A&LO3bxx52NzsyH_aEMdpp+fR9 zgT!+=io#j3OY$R#L`IR;>CN}CA~M!UxYGLe2uzL=*BmA~|L@$8i@l-P4q~k;VM{|v zx@c{Z2lMidxv;5CpKE%&{@jOEhrfVRyQjgK+&e4ofycyQfXeSH4%96Rf!AwGHBiy; z8MkHA2Z9Nk;mrB_-3@3<2cgFywv=$~(R>TOOzLi_sCNGAOeCVv;N~kW6hW~;Cc(sS zi^hp-5Nwd;z*Cz?^X|`)esQ*=;wK$dkY9r)?G~Q%fJz{Ei?&Y9;%y0M2wdEOA^aE6 zI>xT|0dCG?1C)c-J|Monkw?lIAXK(}fNYu(zpt}L(VC!>U7x{ca{w(!QP^5i85q8X z3i9wT^Y>aqd^N+4aZy3TRfwgZ6;D7ZnZ3c*u#11x0I)&gvBKjOSH~!jU;Q@5>pe0m z?ea$|H*DpS@M8`Zx{cU{Tg^7cRj1{WFu%a@TxQKSR`&T87)|jFP5YIUkZ}lVMX&4} zuW(Qo4%%$D=UG^22jMEygzx}RJ}w-$^NI(Ghw&7AxW zYn(qS#VIdx5N!mfZD)*rr62^|a<8u1rwNbv0G$B8-w%(baY0b3T7t7wkmNrbE*K?V z`0sJzjEeEl%_-zTxq$F0U8l7?goM$5qX0Uz}!6Ey-mfB|T1s$E{kg zci6;=E+uua0}Oed2QAylQK(nJ;XG(*BKNr1XCcM&B zERLSkD3X?jTyg(sL-z0<-l`Zd>?X=|ShQ`xWFYvvZHno;6x;{1j-l%%T5}5PjBJhU zqA?IK&KVoZSHe}0FwGo@apis{O)h1AQUA!&IV57Oxp8O1t`rjdsVf;VGy}?S{>iBbKd9;{ z;c_9Zrli}6(2snHYd#7+q9qNr12R)J$=C~arX#GWyTJ>d@YMC;tU!1eE3K@(wh(201I zJJ791H*Mkt<~-Nhg~i*?p!>rorMraCZiT%iJqE&RUJ{BBq);6((0|vRs2T^l9IE>E zFMxb0Sc@n+nz(Lo>)2=alhW|Ib1uB6qTHi$c5l{BjdQgqEb+YJA5OX_YT!5Oi_Q)I zP5j-gIk3Gk~urBEu>#0O*(K(nZ z^Rs|$SSAcaGIuU8(?(sV>Btpl|G_CHR!H-qc({bqK;DX?&(>}k7HGIk_-NM7rhAHC z3oQ{?=!URPl*5$id9Pacadv<;88xh@(!8$F!H5CeZ!|$u*rxXI!Vx3e={=tClN?}v( zW8ZgQcz7?)kDLWhA1!)2uWfb2+A%eqvE%u!jl0@(1Q9Hv{$aXee;HJA=h@u)$XU_( zfPzY5#Q=N_wA2N;a`7I50sULhLmRa3tQ!$UbO=% z)-Uv|ScXqt4n5aaCfF3ymH!vORR$cCuGw(v*(p&t#dTxNAvagbacgtP+2n&*V^cSn z3bJ#;Xrff=3sj8Fq+IysB22R`nW?T}x?=n-zj7_fbvmS{XhC?&6Y0%o#ls;GGd;;3 znL7p4P1TZ&CKZy;_vy#Et|@%bZ6KKNRu^N+nc*uw!&Q+%yfGZYq-jyq-LsuP`z9xm z&T*4w{9lgb0xaBnHY{x$cnvq`k6a+*t;CFHPZQm)e4BLpUO}@3nGA^wtNsOOI#Jve zLC^S>);V7~jHBGI`<3ot6J9a0!o&jLYeIu88DSAbr=cV&3b&P-wNtcDJPKZ-WeKK0 zJ}qVm^GJ zf{hVvTU0yKX`kl_B3Dq##s$2A_Z8N5I&aa9w~u{yL6x%A0D*GpGX7-wF|x+GC0;KT zFt6l-UbC-GY#r_0E;wRz9Z_916xZ~t1sgUOfv5nJ?I#$u59S;Vv?O*llpvUn>wkPR`?uDo8iGOm43_P@`2G%+0kq zp+W-j{Obh|OoI0aBt~Aj($Mah?l?8By`;u)F-C*J85xRIB0v`g~ zICE8e@RN&>57oAN;&4@<^E9XwZy>(=kj7z9?X<{i_G!OwaAj&tuw+zL3bvPxk*k9& zkbL0QOFHmiexH(%`@2lD8`!{Y#G5J(5+pR8dhu6l*~C6OE;GfqKtUDMa`f;t>$I zx@H3aQ{y3Q`nn9alOamgw)MCIat&?jnmL^rA(Yq)`26yHvNFwssxq^~R1CvA`TtW6l01f(m z1EZLb`gx}`0CA6zZE3%rV49~AY;!bg9%nx&vwYPnTrT!j%Hvq1Ob`fUngwDI&It@T z@wLsoZ`>C8$Fr#MuuWvfZX++Rl9BzeqL@+ zb2@hCJs^qP{q2^Kzc!8QS*Kx~nRak%g;I#oh;`6$*uh5$X_>X;J!=J>%ubuZ)CaW= z7^~={v)=wPTixv3H;IFkr@Rp33ZH9olv-CVX09oUcsbN3ElMh&`W^X0ooH?}MXGao zTXy21onr7hv8CvVN>4Y-S}pft`5NhjP$@Nn6^w-Mr#J?1?+?EgTpE4;#Ul|N655wk z8XDUCa<@chNg)Cqx@q8krR(AO8$FI!{~_j=_24U7;3?0G6_is5g&))GY>*2Tg85pz zl{n4MaqiD8e%0wv;vH|E;_>ys4VS1Jn<-gi;J3LdG=#=q_s2VDP3}I~6Sf}=-k~`E zpp2+`Dog0-D)>6<>EzCtg}DJTd)9F38;(h{8FjDc?}U)YneAp#-^$$MUrp^1Lja$n zw%qbMIPQi#Q4uUNWts9{&-5#{(2{q?`%<39>cULEX?Ggl0A#OXTw+$%une2`qxX2a zRSdhnO4U4=IcO}?uIVx)GEBshD(rYmxWDynxYVpixz{VwC?hrl2e=`;unRL7Ubc!c zy9sOjhY|wp@{U#Im7HuN+Ds|O&+j>22}7m-i8R~)3T%Vt$A8q_C_aHnWzvYCU2 zm6k$K$(<&*%-qVGwexajWkqMW&p%4W@>g(n!0UKibKH=tydsHRZ28(bf4lrent4U* zo42}3hEt%=v*({F z5YONkws*?Qi%@jaokKO1%+!3FN|sV$bihU_LE!Tb1!n<^?Zc20=4m3>jcFSl17mE42jT_E9Q9TD3s zSB5iJe%f6f+g-bob$;YQnY?)Rm6VX=34|F=EO+k36x_||N3vUPfe3e37%H(h+o`Kt{F}-U}YYpXxxp1Z5;CcmM z$#9}yojg)wpE*t?ZMobob%jwvRqg&9AB{DaJB`*(CE4F`ET8#qWByqxD>P)v*riRF z$5{Tn7HDI4o7H_`HZuzeUm9ibLNo26mbLFfq(fC>mb<2FFA01h#GKcnjQsOV&mT}+ z+A2A*TRsN*ga|q+7!0q5`Uyi6I6s)&3H_>uh5GIH2L_Ji?jpX%>c7H6rWR@18&*SB zAq5LjLmvZbZ~nWz2)ZD*Irv~PW8~v~%_2V$vR#W{LzOX{G@8kvwh}%S93;tK0u{T2 zwp@qiw6!0ol2bnyUp3d>ycioD)V?Hy83dUG4&}Z60A6Al-rmrjfX0${%bm|nkCjLj zRsc+{m&(5C%x7n6ypX=JQ%sfzU3(kFUY1H`PkBRgP%CWPga1!HDZi|pm5eO?cV6^ z`C|Z6XS5`#XWpgzr+0##fJoN&X+{~)yj>|?$1pfcrdUo-MKyDalwt(P+gm~i%R%Un z{@uv!f~XzVRWN+x@E-snY}ggX^{$|A@T8h%DYcJT@*RRr0idF!Y~;x=bAa$mtpHMH zZ!yF;6|KXg;g#4kpwB*N^ZOQEu0s({&bBwx*L1R{=0T^5~K!x zKiI0y1;*2Xerpy2qS*7<@v+`0hOG#BuTQ0gkoSlhWn{=ziWfy=f(;8g_xg(Edmme`?<*akAxpJK1dvYB!5EjM0O)qEkL#mD-mZ3qv9| ze!tD8LB7#r0jUr6ytkMW*R0OmeMZ^V)6qr|0W(`KS+sZWZebeg#uS|e?1BEEtx>;fzkl?8=I@!?*6Nh`RkR@m1^4S76M9%$K3 zHPD}k^zi@DQ<0ZFThGWQHMkx{!i{I%58qy5r}+u;^q{_219rX`x$8yWjy|Qko-13Y zRvo+}tGgvz!b)YdxSSk2ml$fqNzeU-^P2nl!r8@$QRnbXWIW34NC7Ur|E%NzAw&M3 z99NZ(=YZ}uA}BQsvrwiSu(ar_hG{g!yKNAQebC=BCmL!(V?-Ut- zOf5Wq+gB3&RN4>b#6zUv!04nolWG@ZC1(%pJdibBQEbI zxn3Q+`t;9OcgKcRl`DJ#^4ijk-Rv<`n^n59uh73k6 z`!LLIkLFJ2*;4%WXvX{+VJBRocn%2f_~y!XO1Nx+MC%p0Jt0sA{f?`5bEhmtbPuKW zt{603sWZ3nO@xBAa&~>LWUJ?NCgjG7r?ZK$wP%|62+4&V6rmOxO07&p~#&*u!HL`qrw_Ipw6OELWQ-i@q5(r&A28xFMpyWm-b^WLAvfov83u!T_Fs;|JLrzMKR-z0k26=?P86z<(8%Cp zCmy#iu{3QjwmsD&U(^(K?q$2(oQi5*Pm4v+&j8E ziR{Op`D%z*E=D3(Js#-Th$nA&!isFTyNyFe0_8=Le{l+~0t{TSz@`SCrO_&Rp#-_` z$0vT^({BTgEyu&*%VqE=Civ?wVmhA*VWj;6uF2N6JyKqrWx2+sT(%7fi0$W2{2U3Ls`^;|{eDs2 zx;!qfn~MP)z$isra3=C8%N8-}W#gCVHthEh6a;O|yP*PIVv=U&|M%b94YG0kc{r-@ddsO9xvUQ@>lE^xuA#fU^C@{(QGL zxaEC3WvBy`a%7!L>r>koRfpIJITpV#|2{i_&|Wy*rUHopk?g5(*(~AYG;u0Vzq*!P zxXmAx0J>Ij-WX!Km|k@|3=kR<9IZOG{BG<7{iB)Inz_vGJcF}q=_mZ*NwmTVzmaX3TD;5St@|sdOlXya7L49Em0aUS7mIb+Rwc{KTKjo@gIGh zYS9<}2$7(?5uyt73n&Td4c1?R=37K2Xnk!$Bx<$87qh5g8@A6%qp!oFJz2+>eiA~> zJ7L|Zm6f5#U`aUv`#5R?o{y+yXIMVOdEwCN#QvTi59$G@nv06!l&BFG_JX+K z>7VM33*Nd12ru^6;|SZ$t+NAAxA@6`n2o6oJEkn;+b}-qsieY+g}mHDmgXe6xpb%G zlH6&Er#Xa!&CiKe+1MgEq#2PdpZPdGT~Lh#oQ(ZM8as=)<{`nLI~WY4U{p-o}t~N zTlEQ6p==U+O@_~o!LRyYYs@;>#i8c=L-nH6knsIsSVH$MAwyP2O=psf(VUG~R)>eE zLF99 z`!#wY*5x}pFCWcZH-6~3e!kL<_txWT;tQDRKU0IP79rYH{mX_=pJbP%)oALrOB58^ z?LJw4HR_S8U~+XyLR<5VQ{&b3rf#mvBW`KGzii+6%sbKP=7;vHR$%F~$1dBzfVwXB z&4%thyOrEWz^1z_3pH&yjWaDN*PaE2I}T^xS@496<^X+f-QH(s!2M%fSDn3m9(=qM zAt^^GNDDkNMR@xgdKG@X2zRGzJ^D+7N1#vT3ls&HEn#O|uIOQ=6XPyR8u;44(uh0e zUJT)D-*9cRwG;tFl+Dd=VYPg>Bkv@8hZN}iYf+}1uv_7A-Y9zfPBj^KkvE-`EAmp! zG2ZlA$BIi~@5FeCYksxA4UG z6&w4TjBNWLJ`sLxb7bi)5$K2vao_7q4P*N$aPMWx85Gx3;(7h=4GE)(*-!W;OKeTH zSyl`+dmCX19W_0eVY$;g;9VKjnsf%?cg#e z0Jw0rYjpQTlt}N^^+7rGg|=xeBTh>A4)Y4b<1ropAcst)yLaM%{i+9)Hl_Mp zFd>C?Sxmve*czW~{<^X!$&i)oMD&GQ$uP=D!^I(X#V&+@|t zbfs&F9Ad3p0jm$&sdOzgp-aRB6I}`d*iY3P0a!!Cy0hGCRdPe=iCEp<*@`wLNvF|6 zme_Cmi;$*)=K60{-MB%##~0HE>9|i-Hhr%)!hV$J1io)Dp%o=3x?eE4%Diw$^u;_S zjS%<)(s6$B0-tJ1fiFraG4HsnHQxa^BQIkU^$%pT0y7(awh}@e;#J=^w_9{YvFi%} z!Am7Z?`cb=#BySy8H!{xr=R!y55tM}vBKIfd)2n=}!; zrEUi{Y@z($*HE$Ct8;QyfUWy2LrnM&L;ypYZtqplJ21L2or#=lRS!HUZRIyhYU;MK z-g(CVW=89f0G~|J4^WN()gi=kHGo6mI>M@20NAQS{3|ppu3sAfYK6%JwGW_z#1`hhZPPZA( z9AYmu5PgDY*ju83J7!4=!dj*~s`CNt%-_|sMZaBm!8TEBnyTFdHKJrGHv&rR5@>E! zkq-@8YLy3-{SK;o1BgGUMw^G)vy^Gaz?q66gkC~Hb=mE5nX-Y<;%W+6G;*h8h8DG5 z-aN+CG+v)!r`h&n0J;)iRUn&C?{}b$gIC=)5c3u~Y;N(7nwIuv!#lN12aA&hmk6J| z*;G>ZG^-bMV+lool3zt2SeKKY#Mwd+mjL4I>}J|x`fc;+taH44I|r)LiQL#Zg*~in z!YKU(SVk%<&05)`7*yx%TCFtzfp#mxkFu0O(ASaO?=VNB?zWye5BQ-cexYab6Z*j! zpn=&x=p@qd$q15Lth2`5C6*O3kh{S&r?jp^)ZCZHhJA!f0+qiM(9=o3*BLJj?J!83d3i7a1SR$^Z~Kc2yq z2$&Re{B`PXyr)F-kI)kWO&0z3GK@`wtMYE;AHOJTmY8VOBPXr(Z}iHMxjoHKi9z1> z^;_#b&=DTC%G>7NG340rz$5eu#Z+&Pj~Lbh0;@k`BORgKxv$How?9Vw*R4^e8`W#GQTcn{$_sNdav0nZ35C~CR-PI>f%2grFs{QkG~SxH6E%O z$@pRnyZF8#|M9{a<}&WtLES4w7u(H>dCKsp3M_D>r0RU+$2f`SucRZ(FFX%3N9&JI z-qrYQT>l+A>HFIJA9aNl`(6#vrhKcsb0+_yi^;TTHT68C`6D@9sg>~`pMdV3kScAz z`0wAEEsDMxj!(}0J9vU7PEUK|x$zXW+7KFsloBhBwF%KOl45?1Q|Er9z*SkJyfD?UI$hPHRY2Q0mjyp$4N3+{_h){O zbk~&SfHteS-4dubC*R9M(ns^g0e2YpJ+c6=PUA~uEo65{p<~^_wMDy4_S)~v+f1{B zksIb6;tWn>&(w6qu7|aE6L$*V>+h~{sVyJ7C5YyHzv?_e%5`Uc42cf~0Cz1%t|K## zlXfbvH2F|=D>jv!4E$2=p*nIX8IjAz{I>$!voib73fpy!Gc%Q(790{4-QAI-70<;E zs&Ji+Me;ahr)Ydi6rZ$T6Rfr^k}Gj=Sw|iSiIAY2u!*|FLacWMsVd@f{P>ggyCIp_ zYO~18*8Tzwvy}3%}Lh}hI3FsK(_}rXg~z|o*E2|%$cdiJChy&xP#5Y3quZd zScJacQqX>IU)xZPIGHX*G1s2PlmgzUREIb4Fv*s)XUsvxGD^zW0 zJxeo5bC!3#T$ynYk9^c5qc(ZD`)#9XZF)&Z)`my%ox{9F8Fs+%1kYB4Pta?mX131Q zab0RGcLDaSZg^xiUf~zE`$~ADcJtrb3a=$&lEoOR-+dn-YQt5p;^%fSxk$abG@2=G zqjJT!Xj7yPd?@u|K9dx%H5XM94)Uo{ybh(>5Nt%y=ghU_7U5F9+9~Gty(kr*TgRr? zFvPFGHYB23axR$UY-nQOis@zvDYj{6Zq_49X3}ZNdF;G&24!fdYfd0;JYmq7Y=K0o z+Z?M{?>{!=(WpH~Q)PyTungm$NfsL-WmH~14yXmB2o0Qtux*yAhrqG?a!-7ZeuPq zned0({gL7YB%{iG_j%fB0A;#$jMK3yO~?f%w@Axa$!I~&B}vn)kjR3J8z^Iv<@em- z)r(sFz)->s1yCu)F`?~O(d|i#{KuwQY;Z(4qM%@4ngCH)T(Q^C1SJD{=Vdv!d%_H75MmnlS) zv6Zo4z#MRr`M9*hfe;6(8tcQ?c=5=vTk@m!C!P@*;8ul^!m+kQ$%>Ny`Vj z%)0Yq?gHlWvMR5)Wy*`!{~-Q32dwc*?V|B=rR^980XEuJ51+p!3I%#g5REYF%I|og zX4cKj@h2Vr{G#md_HW0MGcKc|<$Z+zl&G|e zjWxK}e6AWFNnW6S_x!5yaS#6fQqY^_H6AnJ~Tju<*2{i?)=)$O|$J zZ}sDeifbp!)$B8De%$X1B|M*gZR+Nnk=tSNf+xfv7jMjte01+2vrHGXJm8cbBLOc$LC^C?YX+NzDGBHlrIj?+w~<^RW=q|@^7&j@7H4~?)dS0^zM_- zNpk&cru4hB;|2WFoKp{k5bye9FXz>mhQf8_h<6n~lCs|)3EqXYg&Py!{84gTF%Y*4+N~HKD!r(L?54zD z7@V5uJUeeVHC%V*vt7^XbaMK!=W1a2xy61RuTA8y*DU$Fy5n?Gd^bJgTDZqXV??=2 z-I+JP=Y4B;3_p7>GIJR7dAE|weE_DxztxtFyPO5plv5>TYxPJvDZ%Jg@%Y>kgHzSJ zH_A`kyk3qMA`%tmcy9Fj^a`312WXA~5xyft-8jZ#m0kFmH!tiHhIUz+tRD^iv}Af| z>SLDtU%(|6VezPFdcvxWJ^V+pfWwg3szbO^rw0VKO3w)uCQ5V-QqtgYYnUVY7A=9_ z-I+YMWvtJUvMbgkLB?g5&3!N2TmY{ZJ<<^tGRcKYlmg%qsHSpnFHP6$K54|Gl5=(V z3qk`MkJ$x&ZVQ=<<-`uy6Y+$8l*0~O&$iWb5k;`rVLlefBpvuzAUr%@vO#GF2+v z6RZ<-XDgj+2Cw+?6c@Cze&R+@H#vy7WAG=6cDD)B``D-020^G-G{rr8Lcs z$Y5zIj_lkXgE8RBuo8(6o)Pf#q(X?B%4=N@}74ynCd#G=VJInRJZKSizTCBUjy^`;+L13xU2BPN! zLe%Y8{=A3lZBxIA;7;*6**@P_wQBvSNLKVZr0N7!JpUy{%INocmS4PCwq`MaZ*@E_ zvoAylFf*I%n&ylKIPv{p^$tMLm;x?au7{8?cxo&?8ah#+gA1Fc!@aq zfI20J$11wqmW4>xFs1*&>iPaQZB}}#@U$eA|}JvoZC!xnaXv>Jih<~e*qR4?zn`0W2Ee# ztRtmyhpI?`5GSX%eV&5-J?+f(m~o@DSR(0KT0pC+qL{_6PX>5EZ(neC9iJDW;4Lke zpSNew%5rUhGyaD1J|i@IX5S?ZtOZ7*R_y1vGWXsyZme1k8NmC8vRB6GS{)IN?2X{t zbjZ8I`kJ_Hj)?wpi^mSWm?;SlWA>P+`wf{sgxf)Vf|8ZSzzkROir|S@j9cwtL;-8uo9dyO7;MxS6 zDto)M%0TiagGW;>(IK!Pn?}cBX~&$1NTekxV9OW zb?J0u7XUKMW$>{DTNa=7s}-*^;bM&1V1Z|>hY_bH+4Cyh_{&Eq8fp)ggCIqM)OF}1 zmyakE!OJgw72^jDs8WxYX%1MwxF>=Jc3G_06^P_$I=Eoth6m~H&%7R-Viz&Rt)(yR_vx7Z83)^P=PsNjvGp<$2qyib@GjQ zz-*>l30^We0uI!jc~0Y=j$x@EaUPv0)Scj*B!CR=s5;xwu+_6&i97RPE_j;g^F&=o z=i6&g#CF9)DcWDa?27wB_Ee9I8gka72SxPBe(J2&*emR`zEsC6uv1wX#2>h|;ac_L z%0>4p{G_s%G-8Prk7pVV#V`52^tbII1jaFQ55f zuIvX!tyE|UQz*k-Z~$f4OV)heJ>F?<4z|i>T>u&$sKMGHLLN}cQ|n_NuwUKNjvOZ2 zE;IgTy$OxmYwm3)H;p_(gBLo%e5Mr?I}|x&b+IDl!Pw8H(NNz z|Ggr-BY!dmJIUA{K5Sdh?e?zOIpOF!THuYY*vXk~nJ>d9pYxeR7|F$Er}>-y!9TEI zIHMCA;ozRKh%Ziw*mB7H0>(NSqP{m$4~Pea5Sx!X&$9diYqGCZ874=<(_IUvc8R_6 zSN(@}3PE_uhbk6xt1jgofj=s@x|ANT{zYN=HADJLZ;?Mi_hxB1UuK+=Y5Kd$*FP``j`w{x-RFGwV+TkZnazXY!{yb z0DbRQYj{T*h$iG*Io!ea(F0}@(8}G)m!14hn2@Oqc(BCIHV~G)QL573-Iq$?+K1-i zprrd_vUTVE+BPd2MhnyYc$QIw%ONMOg7MBu5E`xL=+Ybf${39{gSS$G_XGS03(T^Jm0teQlzAb-F-SQT*H2QK0}pzoE|34XvE7hpvgxn z#(XhNXfm6nKvSKt_@ZQX_a*R7;k(r9-X_>>Hg3> z%EuZ8ccoruU2D#sr6zo+($E(jRu@DZ{VKq1s;zcZ%grcjhTB6`qw? z?Ln@Ly7lA+iRAf7BoiDTWpIKjbK5MISr>60j9jsmi5jNF8p&=q$v8tJV;{+2jLT-J ze*t2?LNF1k!9VOoL|fQi!@_o|F1Yy)lBoa!!^|CfF{p}WJ zDmlT6L2Z;R%C!ScXNgY{V452qCAH>~{JN9u3}ODm%}c;`<-@Ll*@>m#2$Cfy+}W=i z!JPR`(EZad38}_ktxaGhf$~~w&<3iX-G)PqT&dVCDLmM~kA@=HypB#%xY-dh69LtR z0YX%^MAr+JSOzGI6NR1mZK6NiSm-l>Pjm(*iNzFmVLy;h96WuU@Fwi|L3B1Gw66HV zWsP2-A+%r4G2gxMOq|!#5GNzgvK3#M1gARdYxID%vrZl#v(h`eOB}d;PWzJ2zKq+n zxO646Gh+Xp>=}(Z%8zQ}krT=a5jge>?6pJfHjsL_`RTgsM{#3My`1`_+~6x7RkTOY z#K?hmYh`sEDGpultd09E{wQywLWKpZ(b}w!-hyX7qQ10tZp(+XU_V9k1jzl;xDayo z1^&T4Rv4rr;knjm=swFlR%mnXJ00s>(AQfMZ;xq`pmZ&KW$sO|0xT+Rr4Ony$4gBw ztj=n5S?zOFK81SMeDazao9ezDsJK5G)5`J|)x0VLtv2yIi7F}dzqTk@-%wCib^X!g z9(Kbo3ft^VQu%~)UH@31-n=C7_6F_qLfvMzS3YrhL@`G$y~6D4u441VIv4#hUdURx zd?`FXDBk?F5EzT! zIx)UfjkoM$-0aJKkM;y#emWwS(dBquz&C6N^PAOpTDqdVd3tui?uX2YAIF|kQ?u)- zqy0P6ztya#4)ofWxAKpJ8csCOw_7tyzMR7OzO;{D;5Lp3!bX6=$toH1#`qqeE1`M&FO9bI~*iH6X>_=@p?)ev4EkLQ<3!;^3 zc+O2#wARg9>5l~0#r=4o9e<;ZnH;`l@Zhjqa2sM^oGojbPV=1`8Tfh6{g=rZ^_y?R zJZhWM>YsQ&RZsnJ+9EIECZ|w;zO$#gyw^c7pQxdreTsbU;cZR3Fxy}u(w1SQp%2Al zJ$ZpQ+$VdPI6Kvs;bA;+r?@Nppp-tZSE;fX`hQV$F8)kE-X9;s+%HA$mk>to_gr$x zZSLk4axXTKxtqu(>LV8BQo|54!(7T-QzS+rX5^mS?{Z5@eSiD?2YWo;+vB}+&g=Pn zZMQeH3O@c>3^@YvnbjvvZa$+QxDlLz6)bX#(_NVu5=nB*bhTpHu%z`AGGB0)267ttkT`v8EewE zxYyMB^3&zljnl#kB}?+dj%w`NfmtnvY62`P5INyZZznJ)zRBpiBzN}?Jb zPk3CZR~Pot)B))(^wy}NbH|)BBQLxh6Qkw(=0Qs*e899abh7+_3LRU{BS@x^`>K{4 zOfy^pgx+$}V)N?N?NRqvoSOI7>#IC= zJ+zcqzlh%)3#e*og` zEcBV@52Am6hkVKLB9_JPz~;*zo$}U$d`+#7V4Y>OUY!1V_LKd@{qstxI8n<=>xCzt zmn1LVt5YihNGe-eKZHv_Lpug|myz65!!p>X=rN#cu&ph)H6rtZ50NDl@+00W4XSgx z<9I5dkO$M)HN@nvdRP5OaMroHz4~%g>qx#?xSg$KDkdQ{@b+->TjylD(zi$oBVBWw z;mL`V?!lJ5uMD(93rpPp+t%%0Oum?7xQp0x44^O6+Q1-SAnPlv;fd$9>SiUG?;1OcC6)Tp*YopyvvkcT z(!C3=nE7A~-lp%kXt{Ed>Sdv;99$QpEQvY{+0mvuKttO@Cr5`XtIl5b>B)0ZynsxVwOrxWCz-}^@k z4Ms~orpZ0*&8jwj6{gGTa6mr(U6`q;_%F{5l~0dIF%@6(=~~Pfl8C8VXyHrdndp`* z`2n*evn{3%37p^&$*a33mDpG5{&chm18dR_!t7+s`&E#v>~kVmz$<-(A$0W!9ND!l z!s<#58H5?ujd0AQMOEt2RzX3sYu<7mjA?+9LT@BALOiXP*B9NcELl>{`F6a<9sYxP z+g6AD2do3ILMdvLB55{tPCJ-{%dLtoxMrmsi=Fsc_1;f#$mvo2J!YjJRhfI{nm)8+ zUJi&=v|GwLtD4KTq@zz?XLID2*w>%PKmLNW3ulHq7_U4qZ0TWT6&YQ+zIg@k+W5XTzpf9Ri%*ud~-5ANmkv29FOG;KHH~$4sdxcZ`MqQAs z4!m4QD;19UqxTRKmQ~7XSvMu;O_V5juKdnZ`_FVccK!>U7!|gx@e+2iS2%+!D6YF<)8eC4fI`9r&Gp(oY|Q)ecw+&S?y zsNTd_UjZ?q(8e2Krfg>`6A{aq z&$tiBS;g=c4AcJEKH_W%^PUM8!U+ zfq33PF*e^nW9IRSnISpi8>_VAo>z!(VAzuDyJzKhLf+H|*Eeqz?ZPljPa+$)=>^a{ z{{!$-y79IXiY*D!Z7I%tJ+h0h2`(15y!>abJg=AyZnfgIe)3Oh$5r|or&}ZO1}q|e zTS068Fvl;X6tcfoqXnHTOEPZYg0^yQi0%-&yK;|Mr!+r27zzU)Z);!4{VaS{aPbS| z>s6+Oy;dAmzxRw^b96zFZs@-1Hn_U;W&4|uy>YGrVZ>?8nbHZz|Z`I3LzJBG}I}+~a149!@pZw^Wu%Di}?A9I6J-nu3jB;|M z5jlIOb=J$kdu+Gr+M{G%2i=ymFYVC8_7wHrUndxt7Il1u{XY1aJ@BXX+yeggcYl^0 zkN?&LE<&r^SZu?KbJAnmRk~A?Ro-sbO5;TDY4lR#(H^<`!R@%b8HtZwYKe7&Q}M=h zw=*$q9P*ul=16z)v2ii6+ci!xtyJ5O<+pk$1WxgYwp5;vw%-k#R zy_#>|*_3?C2+nh~0_ z%FO_AwNM3_dmEhaRVbrS;hSguID*n7lU$iv%6NYSd}Tv1^OKtzLHM25)X)|}u4Om) zsw6e+z$!#Vv2A^D%kDomw?d0X7Yl3T%uP!zmrXVvZPOryM zZq(hVxz>c|*UyNAQbO6JB>7=Rmp<_GJ}H*Rqj|;GB2!2ya+I zXzS7+vC~B#pYz;@iv@$<N6wkM472@)N^gBQ zt>Q|NNRTO6f>-|&rs{zcNz97xyeGz$LBe4HJo~w*+1qhIo^jLo&q8gym6T+; zz!y#M%rk5EHbLpTtr&#O3Wwt@D^3IXsAZLb+O6$mX9?O!c8*s=wM_P|V|z-Fj$=ad zHfc$*PCNtlkT;URez$O4rV2&#E;T`JPBZCSC$lqzYiwy3wbyw*wSFVYkc4EjN<=24 z0mofA7ghCdqpj)0<6~2^f<6 ztQc~g{bcn|_`)P&SN{j#b2`49_zb@Kyf`yv9D76Tl=bEp+Sfccchf-rHwewnc<$1^ zV;cDdLN_?e|J(y1xbZp~-^oX6AMYiQcN~9!dn3Q@nC(>xyGetjG$?B7=4&@qw(JD9 z>^4gwN7bC$>CdA1{EZ7iB;%{+zqXtX+P@;Qv}uz*pIeT|(vQRhmlC=&*yF(O|Mnnm z^wlFJ`^!0;+i$6#%MDqZ#Yn`(fxC7qPwh-Svkj4HAGb(_;V(oeom{dVfDFZzHn-#!rUJIag^DX-Y_X(&~nwn0A%S;gzm-Gd&(pwh;KgOqBbRPAOVzLe134@ZexdhCLx?`*;ImOrZolWzEDMbg95S5H}Oamj2R%X$H!tXOmQy%yV8x8$wp=GVXQa?^K!VUL0 zm;;a#a|mFl#Og65=~Q}l{<`)W!=?AyNMT(1aGJAEUBPxcTWVZ58*&;t_$vSm5;ZqHQ47By#*R{xY}7MiFdSUcdDf^L@}BPgZVNDJ>P#aR!D zQ)q?;h5-CxrLMq%WyD);ACDN7i{B0{rk5EzM9qMI8^A^jCC~^KvJX-*Mk)2j4QM3# z3}y_-`G!muSS7Mw_OjbBXU2JAIX z7m|5U$O)7ERRjt)vxA~OzWg-{MfLGieTq*ggM`cK>{$)k;_;102P**Is$)_r^1pUe zg3|^_s+;2j-!5E#X@9{YN9HQI(D;-P>YFe}P30SI2293;N1i1gc&Gh1yCpnYAs?Q! zA94fj@ND0UUv=hJq{Z`FlyMigQ7Oz=kaQrWD_nh4zCQ2rM0umZaNUgn-WJoq2i^td z{w)3O{#NUl@x#)$)MFv(teJARq5TlUL^TT&v(QelYU~r1)D~S<>*l_1FlhWk#mF{{ zwZx~!k;U#XYqLT_*Nz3q5IvtbvR3Whr8{3V^5zEr)Q#AOd40DRBqo~7>bzO3xy#qb znbu5%h6-xl^MS3jl4jZ%&T4rYj4@SYtoF?X-Yu_qVMz}YwXmW%B_y_h0U^n*4ITVF z`7G^uP6SLc+n)2A+=juiOQ=#Bfju`*+u&9W1%+fCD^%P$D+;dpES;rHPcXPXr0y=R z?oXY|uKBh|B(v5X&y`H-%@`MDxASUG-&;(RdUv;su;uY#pEu{p>erhAH_=SXpAu`| zp6yAM)@5SvL|==!kw586m+=i3*jmLga~{r84^6&C6WF67QF!%^*6f%WFu zg*_0a6uw09$h{V0jJW?}E!MxH^^uH`O9xSwK2H11!-XBqe3qE>4HC!COLqi`_uWUu z+S(4DDb9Ax#j=Qt$GPrC_zxp?7V$L^FTZ}hC7RY9)atFCd6(LSyN+Z{RVYw$TknrD zBUKdt7i<4=MVQOf!{m{q0lwRx9KpS$=vC+v*B7nv`_l4_&AxEsu=e_qr-922HH+%4 zb)PS(cEuV_D)NhJfxp~$D6}JK<`dR(zjYggIo+B&`t71Ed~Lqlpf+sevPKnM2j68z zQBRDdztQy>v4vpYw}m^iU4GJEU%K(?ih4?stg!&m?amU!4wSIM2cOHE&QhHupdv4H z`M?0yfWw|GyIp&y4(7=8-kRx$J=Dkab}(FA&x281X0PDzu`6%M57O=Dx|;fdr(0I{ zogk~fWDm5(@-Jv4r#E%9O6-)j_a~zdoHJp-)D>AmErp%6?KxWNu=Ysq5su6MzMB;I z%=MLTW!`&5NWb&SgJBy#?E3=g&SszHOC_S+gg@_}kkoT8^um_ffGmGLGjClVf@(3U&8yDtcw5zA&JPDQZ9K$VyT2m4vrFOfjW)sLw=*#7`kK2chPMM)yTPkGeAYREvRJVXPaIg)z8a4g z$>Go_K`a)P_rk>kuQjX`vs)gxEO724UD6q{vfpQG=H%uMzWNJ#E&oH_uteLV$(fVH zpX8e7Yi_*hNiP2XB1=Dts%#%i*da4n9~TyV;6<%-O7(-HI7$?JFDd_mp=+|<^% zh^@LJD=6}tTC4789+|ROC6d=N5nx?j6)OrxRrH?6i*DbQsOHCav$qQ;oYlS-J(0H* z_}=-mpY<=Zw;5!(>}6cPxxIr9sM}tt?Y>7IJs#tQyH&-`8gr#~&@I44uW%`<4pIK+ z^Ly25d4Q^`Lx5m|GfDKL3-G2AhdwtGOf42;b5Ya$Mc4Pxoum{mLsWS9vAihnqkJ3c%YgRT&=am%uRyGB5)R zpNk|oSaZtx>QTS7-|;aD{np=t;aus9uEVBZY~+qjBuhW+h6xLPI^lggz(5Bvl3J^H7iK1v%mjo&mi;owqA(TE@VBY_v}7Rk zw%Q7ZDGaa-jL;#&jgxgNtZXQpFn0A^npR1dK7*m*N*0Zou(Z(UDKmd*~OpL zKgu+9L@PD&L|;$tCN8LTSFB4_Krg5f9@E8r$>OsdfagmRO#MP8OYB{K;S$4Y z#B{%KEXorQi*rg)RC%B)T3gUqL*^8h+8-}ToT>t#xZo}Vx*Em4j8}f=-kRa`Rbcspl9Y-GATX zsy9S$OcVnvo%jKXi~oN~_C0vW=dnf9HkkiSpL z0re_#D6rl5F~?jD;M604`^IU73SY4ST+;YEZE1kDHSdo%V5!=b_L?Ay{c%YB_JFfT z=w}@>)V?`mMu$~3bLk-nr!e^Sbt9|!{MV$7c*Duwrv+;P4f)sqvo1Suw!cc|4Xe&Y zqb5JkX+m6srNj@y*pYp&jS0+^NLc4$PCAy(oVO8*lNz(g&jLPOwx~C`Ch|k z1zJYKV&ju;-KmwoWp4QsYb*+%xUC8&2&?QL! z*S17?>UB{8r%*m1n&k3eTKEM%J)?aS&gy#e<~g&YzuVb9daH^fwx_SJDX0-Y)ALGb zA*fR~jDp%Fw9H_4>_%0}vRyOolzc4Hbh`6NCYM!aYG=>I#*;U-(&n;_1vl!WhQsg7flyx-Li} zzrV^?2JG9FA9`xVGBV%WPH+u{hlE@?l{gAD+k?)|)USMs9-^;6t$FW;ZMkj~eJZ_c z$9qcXT6-fidZzY3F`W?2mg4?{F@9LA?oLeI>ipb+U3sKebm#i7^04ZLOPx)c^OGcp znM4v2cF|?>p~AhDZcfw3y=>?W>y7277e-SVcRyA;*h3n_1lmL`JWz^9$)3q@&zG&- z&7oT(QI*1X9*@rbGaqqp%?UUo{&I{B-huC!Ih3RpvPW~2h>Hh=F)4;@Y#lD-m{D!F)6Ja3oqb8WGj3qr27#^%6mtVB_&B z{obu6@=fHa^rIiQizK26*F>D*UIAeX-P=NM+9~Z5U-V#~$T}4n2VFKpcD4!yfiFYt zA3<_1!I{4Z9zYd>(wtvtSy2cAY{2;lqq*xzio}2Ex&7qmW{Dh$evD`$FL&OENfX-qHoS(EZr#m z7FodKD2-;(G)?`wBNthQNGk>Z?a0BKQHPN6P=I(R_+vosh{Vte zQKnw>x<%8*TD9EA7Y6Wq&kcksefcvs7IDqQCqdGUHqKjl0MSlNiZQu~X0(z1?SSn} zQA;~}zJQZR{603u$+^&>@lWL80(_3+=}VpO5gf*nq2J%_dCs8{oRvCk2XY!?+@i<} z7ho-`zq1MS-(pFE8gvLZ1~HPHw0P2o93^h##LI34hWb;1^ufXCJ|PtvrDCotWdP=s zgRdO((os(<1*-tjy!-YVIq3kp5pCeT!!J|$nF2`%JGSNAS?q0Fmdpc>GSV3$rwTfR z3GPfsUcBBdBA|g;wFu^|i<(~Lv*2m})yw1Hf7lfD#zM81ep7>D;{O zv->)CKTVi4sOk30otrOq9N2;c${B|Ox*qVV_(48iZY!@|5?O2K#rAQ!Ef%HqE{zG( zG{t#I-nP>9bg3=(aivf%NXdJ2?U*GJb*&5`jjjX1|>n6L=}{7iJI4 z6j-9Cs_6YNP{+7-ay-74EZ|iJ;gaRW$2zalD01DCN>9d*3@5n3oq4B?)$GG-g8>HJn&?$AE-m#f%N<}lM0gH%wL%5bEPADx4cbjnQ&`>Edh_i zdMh2qf`QUVhmWZIUG|F+ny5mjy3G74%ZdR90BEZ8FE)ucKwnvm8lN0=Q*IfpvlQi_ zrX8v;_V?JS*ay`fd{CGHhZOfnTd3@!jsc@INnl+#g1-ccXe*r`&x`jysk-~G zz;$23Kb&Rx$$+UCZCRxCue;MpEaIdzM_P%kT71o*+4jqK>zt%Vlw1@@Lum;RD#7Zt zaIe*Bn>`$aRSl^xOwhSLf~uBtwks&w}sQGARt{^vg*nX@u6&sc?C>fCc4; zzra=0cOX?*3tnk@tytgFN&)?2BN6dp3`k!{s7XRU&t4KO@rct*)SQdK=|F0&D$Vb0 zK*oJ)U=HG|M!j*s(Xr!$LBp29WfN7#!+GeQU&x4w&gHxdUuVv>2oU_>g039&t;S0h zDCTVzFxRf0auwVpU^6v4|@gbnuZ_Vr=(f$bGs(p_&7^^Rw?)f^dj*XD7M2rH~**DT9Q z@ml1FGlt(j*DZIdbxz`YN6kIfC9u!H3(P$>&#a|Wf`2P#oXc{f)uoC*9ekJS|bZG?L|_m-K;aOc^*;+dY)E)}iURn`%kDT>Ef4|CB0i|Kee-f)dMW*9smU zRruM^HHIEvUyrXe(CPcd`C6@+&Cp;hUrV}0>H7;yllR6Id~Y)a+TQREdGE@6AC~&zTo6u-t(27zH8y4*@;1 zEIX!&+}Gw)Vp)v-5OzGm`Jx9OeRy4cJ|Nf`!*`7^9qv)^TLmd(V}6JUF=X+cz0%zVFw#4${E{2EMEAO{loeu<0YU9ZZ zTU*du=MtQ9*&lxMgN$hX2K;X#9WN?g>rsixbPH20_9h-vE7CS6wU<)03%~#IZ(ODA z^6IumVOEAI5k(_CHj_}A_DtczE@l6Edc(C`xvA6x!ElG zNSc|cq^*(HAjN=T^fIa?aUMt=Px+OpUL^Zq#TE$QM3`He6bEm{hF!>w9=u5W2C>CA zF_~TvC#F)3zsHdUt9t#p;9jZZ2N31)r|R=gDrAj$dL|h1(dkwfVBf-kprRM8@lv)C z;>B4>yylm3o-si?6=Z-sRMS$%D3{xpqEB%NU4R$LJ$rV87iJo{SnxN6=nB0}p!>l? zN7~2l31-9E3MW_IQz{QX4_Hj*+UQpX@h1QNxn+XP&Je~!R4hb;N6l?T%^CUWs)999OM#w&Z$HW3a zK*_9#VBfx9?d2)Yk*=}r`yh>)m{kgsRHMe#zLn-3yE`A*(7C_H)ECo^!n?P^F9TvL z^!Bd=IQy=bAot-mhrcMx1*HQtSlLaMB*VOhrv2+#67SBWlm1?0m_cy2Q3HwEioTwA ziv197;h~04qn_XtP)nR#3$&M#?m{NBL?~QEZ{kj}>S!>TDcSN75g@X9BH}Q6g(j=w zW>sO`c%yK;Tf@qW_`|DT`q2uPMsGE9s)|$ z)Y>F)4w_Lw{V2Drx$~i$oO*zp!bW9u_-rx>^H6c!h^}s z=H}v_jVy0g0`-2l>W-C{8&8>Z!H%Qeamv?ju+*=F=o;su#G1EQxsdk190vS$p+PPv z-c8Gqg!@`UcSAU;AQjx41;f8U7S^6pQCt66E_Y51`P)OilO*x#uV+M^1MWtMJa~x8 z|ABy*u^T89dCqSNV`9J^t(Fk_~hx4Ng6%sPBm3+ z*EWUSbohj|IORu~|XPR+H6OCXy7zyS7 zv|Rg{P7{F+Y=7Y-2jX&G%hZ;3T|JaKyzS=NA9($Sf5Y$0!2v84nCl{))`o+3s%5_; zdH5X#PP}`pNgd3!3zugp@Y?g{@O%+iqO9p$0nK$T7}t_NXD*A6fR`=@?IZewM;lS{ z&kH|WCgo3z*&2Ml*Q#6+2I>x;>2XdsFo09!@h)3dQtW(Y%QW?t>Ev{tRe+6oqWq;M z_BRn+aN_ah?rkaMV#6D9+c2f?p`iI2bUE#iPcJF)TIu~h9exr+tDLEI%n>P_LKNjD zgL?NjJRbor>-C=*o~$1@8efupaF6ivY{1gX8DG}{*2|G|9`Z=tKjS&K-m=FyT#i7X zNN8!?d=3d=RhRwhbL?m`_k8Aiv6?Rfiv`bFA0Vl%M=R)pFT7O+`yYO@WA;)w`9;2( zR&QTh0>*?$9@rPGEY=;h!BPDqmAm`$*LZ&_UFsP7#u&$jglcee{5auro{ukFjT#Z+ zVfy~#7hozh7=}YtIwRKd?PA@oMFzg?J6a@lfkXcLY1WZ^;67VbEz@_ar;*ROuuykf z3!BWjqs=G;(a5!B4q`goCT9n3a|+CfrWur4^_^;W}*$Bp%1Ji z=Hm(?w`_gF6`BFz)J6W3QTRQFo`M~R{{fii25yY~*CEIt@)Kt|qMPABGnS=muse0N ztIdb$QMZk25gl8uE=?-(6YWpf3Cp=X0jT`%DOPPcW?C(mr(X>k%Pyw$te{<`h5uu! zTj5GyuDZb?Z?E^B)$hKDGZ`ikTg~UN6gs5ge%S<|nm2u-L8&?koxJ|6DRi!2&jz^h zy(_BfWSSLfzM<>I5X5vX1&rumsS*#r_ZAk*TXX9JA$g0{9=`a-=J!Ntqk!>W(=av-K4B$Z+{aO9K+9 zmy|eXTi-_4tg_m(**3gtw)(XMZANh|;%|s~?mwrg){arO5W6KQuySi$DJ`3ast?mms9m?h4P^6W3Bl&Xc%-mwX~ z-8jLTAK*X7M;IGcMuJxS(2kJ^&5#*9x>z^Wabi;;z|-R`$I!mACRSZUdpSZ>QL%wY zhs9(Gfz?(sxnA0YD_-Ph`T0iZs>6%1#KZJ+`)--Bq?ToSJEE;D4JK(0tbp#_LnP(34Fj-*aLwxx@iRx-`6CgV1(_RQ^} zlmdzeyPkipHEpu>PLnClLpsd^P?24{9jt1)8ZSi!qVRNER$7ad@ZOvSm^w<&>5w`;q#s+|7w%Md;S3%%6Wcg<=o9%L zKwcBx+vJOq`_kwUMx$H7v+aA_H$U+1|%P=rUD(fJ0d# z5vJNcp4SH?aoq9Zrb|n)F4-^$-b#gmpar9_Yra%fRMM&3&}f{8iAvm#dAJrf5r*nB z<+(6`os)q$LBQ(Y2}*AAg@uNX^(7gjjr9>Z{m4a>y<~Rj7mwJnfCx?yPGG~ZWna}Q ztCdlLJ>VDOwCdV_J*(K0OSBCOL|8l$k1T3uDe>jBk2KyO(k1JPfXk0*@jazk0RHb{ zBCK5sTlFu$W8X8AnLWw1r&=MC1%x<%PSOAaGX{5zbpEuw6kJI&+E+5Rki;`r?xc(`XBNUt7q;K)yw-Lf3zwA_}L(G@2us|bB;lxm2tL)!Q!nrq%2)Xzdr z#Yb@3`#{FV!fx?blr?IqCGCi~;#)UsrCPEl4Z zJpP&%3xk^W5`ez6cY;kugNHvCBr_m4ldh*)o&AEk(1{M=HZ;2hzs+HqJC$qg$K0>_ zB0vU9&dO}~7=+l_vNh}t$${YYx`c?=6UdatrbTtIFbH!#Gw$Vl2HfEEK(;QxI((!jwmb6Y^X#Sp4N7^T&uq2Piv+iXuf$o z|A>_m*@mKi{ks~c5!L<@wX*sh{`l$2%>=%;{ykEm#)`E=U-<*W?0&YT|GcExK@Hb49X-?1JTpWw5K6SjcbB_8S0f+D{Hq{9?E z4ES=ic(U?vP4LtD!#R%qj)!NppOTM|)bU%=Ix#d^XbqyF@@2(sq%DKHu z-<6ZbDZEJp*M{qC-k4|}wE!;GXatwui3vh(Y&m&arI8XQ<9_B?D_I^mnSOl1cinY2 zYN|@u8##F!D#}k-$F=FSEn}ZNa@py5rPTrXDNoLi(o2}ClMC+VP~96i6-Gw7-Ubdt z_VUrr>kUD#pDSm0Q6Vbf@cTezQF$2#F$J8$w(VZ|el;3iNE0Bv)Fm+Kxe~T23>d@pl%Z~G!O*E0y-S0gs zQ6o+#%pUIKdTF|r)91m$nWjukgjN~yzn8a?)mDX)!V$CSO_bM?@m!|1>?|9^8#ebU zN0En4)Ag2%J7|}CPjey{>p^5-u5AvJfJQ0to?*4GqWqEOYu+}Hrq9B?MQ?SA! zz*Ho9Gq^2WEX$+nHl1F~a=8S`%t}!72IeyT@~MSzwMrG}p*xB`zyxqq zBDS3J!6UckxqRTZCro2&_m5|B7X2;*o}yehNcQ`+FhI3l;a6<%Pz}X+4Ej2_lW#mA zc&igFh4+HK*x-E(NFqJ6tc#*|ySKlNsZ6!iNjJu}_&Enm;bi*!0D??KGkjDw|41tFhH9v9eiC&7hq3n#$L7cTD$zNe6Z(L8UEe zk?fCY{eM*jRzjkK7X`aoN!GK@6=Z=BZ;3?oAJ0&FpKD)@dReT&8X9zUkp24$xT+o(*r)_F`I52MIa++Nxg;kF_J zyPjyv#3oqv&6@st(JVSvPFTV*d22*a;A)M7ishb(3HK2o%xKFRyFnD;+aQYVnWZ#$ zIBAQ1OP6C0kbir5LL+cPVeHUURzT6bZA|P#)W)xFu({UiDa{vpc;pmNg5?lmc1$B9 zO;}4DdeCjv3FBFh_*kk8dY{1QBoLN;vNHK9f_FD~4`PHt^5JjS)5r=#C)F#mqAcqr z9nu?_Zo5~6)Q9i^6?-OG?2U#kL7gY~y7^0-`8)%96UYI3WQ zG4etgo-(Wf9(7|?O<(i%J{{%K*gZ^s>qM7}TFx!$7=gqF094fN`WS|_EO6S=C8$!l zY2X?>j|%dA-fb%&-d8dfPA>e@a*27cf_OhIP>vxeG8_yb)2~Txt5)qkMvM`j*gC#Xh~9g-+YD zj*^hzc8?wr{_kc?kwDd;cWE%gF01LgzS(4eUbozkKDH&Q)^(eoH?_}zQI;fZbgms; z{%`|GvTR_W>w_W|+IcHW(q?lad#hFa|DN-f*N7<5Y;=1XwB`|97gPTxg7&C5uN3#_ z=-?x|-bSw1;l?~>lR-?FL^IvzKdx*!c1Udy zVw=1y9)`og;`)vXOJUpg@J4AIv%*=zI>z6B7_5`nUL*bRs6{4#T#cYM_z zRkJfa)j!_4iWbI~#C+sG1bljE%#_BXow^|s4 zJo_<~t&|&_t#qLI!_uIx8QM-C@|hrPRoWbz=^w2z(Qk+WX%^>oX9{LfmP>lhssJ&s zRy>$NyuKCq6W%F7-V8m&o|8ga?~Y4^nee9*TYmeOp~x2ILtxisCzT=x~; z6V-J^CalqeTQ)%&IphaD%N4%%8ezRv%0{l%{F9a zTDLY9k*Z*B=J3*ByNZy5ptNk>${oGapBi#~r1{V@7M7J!uTbS4@l6ws#c)rEC}~F% zu7=MH`>wxXZ`Y^R-FQyaXt_2$7UM^DbW9UqC^#qlr;9*M3Ukv*VmdtpAHP=iULoC^ zw{AyYco*o;=v?j4G)ljB0V>cNeNWbGUU2HJB^6^?H^z&7wjqgt&nbxWQ14JVo zibZop4nz?9bLiRH>Z7@tUm8PRZ(md?ry9spENz-MO4H5so-2oF8`R28-)sfvbtreW z`Aw8f*whoAYLogjD?hKKBh#$t z1JtZ!@329&nAN4%-#@sNV|LrGSuJ78wxwPmXdg3fL~_y{5;aXj^eajYQB zOq=x4#VLNiI}RTpf{Em53H$Q_qoS)((3{)TJO3<;A_ppM_jA%#?jo7601t6t%Qhq) z>9zJc$Wk>tE9fjuzl?&npcNTu1_gcD@IvSU4{ds|AJw@_J zN+VF_g<*_vJO1i?e03Ys$yfoWE}xpnq$Bnfo+}ILh{Qu9NNC&5^G}TNs?jl2?qomKw|>;y*YG+Nvw3Ew5~R8 zU;d##)T@7f5p?#ZDxm+VmE3#}dDe`sOUW#Xt9?p~MXy&K!xqwWUy%iVmUAbac?bj1 zloHMxvGoPNQ7ecP^kBK%4waR8Is%Dd&7wCvtlEF^6;V}qwRJh)??1AKlRM(51ZupH zgB&9v)23BGG;dUdN*r!TL|G;W8^8Q4#CKE49mUT(ABjELy*wBO1}#=Js<4-yB%^j9 z=C+#u0{UfI#*pq%vPPH=tsO&$_6)LCNG>N$k9|Rhj)Njf!5>Z)&FywsUFlSJjP&_L zIRrKes~pq5(4$@HnDqlldJ3ZlpU?&bLGs%wwDJywgk|`s!q78e8 zfN%@?(q7x{O<4_|_J?nU8Ui27uq^%DGVa+RRJke+d7A+O(epoXxDx@MTw1f}edtty zh5n)Ot4~X^41U=<0R9N^jbTI(8?aTUEth$%3)4JXB3A-d&G zm!%Cil4AeE^Lsp9>cIE6Q==fQCX1lPW$0~HE&L2kUa0aLQKA*AI#h|Z81z6KbY{V- zJJv0z(#>`WVV|7$D%ERN8!@m2huXi}YDNR|7$F!t5KL>$a|)_i_~qDk)5GR@*J66} zb*GQC2KRDt54zP%HG4<^H!5z&I=ks-*0D zIb9Z3uHX7tG$)IGtvjwF^$9Q*?i8WgS{d-~iwp*)0CeN|w1KiU`I46UEnT-5^xzQb z0uvU&wqR3&d><8Ivt3@c(cAN$yRXR9c43Eep?D*z>mz#`XaM^v(d0{R0lrru3`D6| zXbLeoadpz^@gX!c_7w7v>*6OGB}5WK%G$bImR>KDu4_8N5W)&k8<{a@_y2qLa4M+D zM*o9|)(w{`UE{@$zaTeTI|(*|*y(tv^SMj@bNEti8T4IAL%pIvzlOFBJ{;K#5U;z(A1hR$?@xbRbd+n=rbDATUA2 z(V@~cdh}?%f=DVgMu*7glospv+|Qq|*Y5k==bX>`eO;R=M*2oFVGt&RksCTX6wa%+ z%KH5^QD9SFsIo7Q<76~_8d`iIo(ik{Bew6p?(TevSD@n6!C#j7eypzS!bAf?M=bzr zeVSF(9+O!fyc}BM7CiuD5paQ}oRSyW1eLD)XOj6J+DhB$IE;U@Sx^_HI&N+dY^zNc z3&Xjdr%bn1ZOv{<_60UVHaB)3-mDjB#qggYxrcJdN7p9_wjS;(iWM5}{;HKXud;Yd zH^Dx14fKXYH(6);vX4DnU|6y4oCANi$&B;y|AR}y`B@t2XoutV#1`egg?A}FjznTo z&mf!6Ls_#DmfVsgIw##*Z7fn##YJ0rlbG$A>|JlMxBYi+QCLN9^xdlKKeq+a8>u7Q zDSw6?yjW;vU7-cT;y&4!({MDOg-)44m1(jX-l|tOyf-=jju))%4<#rt2MKy6{_TOX zAd{H`rmGdO&ckPwRhiE-2Nd=AUDXFh>_nTt@yG=o9-56E8eT-8KHb>9gr|A>O{FK~ zyqdMm_FSHe&-|1!UAh!~qNrvVufMQwxeys!($2|a?`mkZYvSb&a zAF^cSxRV5|Tv#*O7QXE=LjU78by&WgJ?X1#4xIU1>%k|9L~qBoZpRc$QtJaU(R)h^ zoe`F3NmqG;5)AoEnXgUN;r&@vS}W+45Jx{rCZoc7wk=Y6TeXM+>OX5*m*jZ41qW!d z5*+euD|>6gmTZR@BA=p&{twkE&=|HUQ3mcqOL1_qzbeNmDCf`Ol;^3=QtU$K8gNa$ zQJrcrtWGwSc`rF4Rv_m0GPwL9)g?Qpv`oMZM+tpIZ$;6?I0J{w?=Cvyl6QRu!`*r0 z%Ee8h$bJzuDJO8-0&+56U~sl#ld@KbKw|IBvD$rj7(L%5G0natWtySgPS(6158}_y zRriFnn3Ij-+rC69tb`O;jl&!G*RD}-f}^dDa+n$h{RWISN_CTjXXaeU67DRNWz=rEROsh zHXm=!MeMA30Cmh*poe;MstW^$2wXYO23>r zs_2*9LE@^xwM15A!E0@xJofj0pgqzRHoqBC@ggdSKW_3$u~uPR+wN1~EAytkd5O8YjEj-q)+ds=+}I5m zE)X(Ci^#G>iDWP6{AW%Sqejg+$=DgSdB^vC1O3Wj~63Jy46+ z*&>kA662zy!gdW+2T)W8x5_n z#Kp1xv^u$-+={r1kD0lt5SJKm;W?`E1iu3+Ing`d1{ap}8>yFXSzt_jZ7(s_E9FE>%B4G#kJmG$0CHbXkqdw>SS!GG&+&S(m>0F6vF^f5^ryg;?)5RE0`-4*t1EE)b$Hx7U#`yZwJ(cDgmeSUh5=cd^;U!wD?N|w{wS1;2H z(8GlT^Ch3ht39OzvNVJuc~S9MoZG3120MoE0UeQEd3VdF92x}sFOC<}ru~GM(*o<9 z!z``UEa^B@A-nMmFOsOw^qa=@`Y-r33+lvx0fc-K;f4cF&lqQOXU#n;`E;oK{dL%E z)zuEa#DBy`3!xPcR@_<$cFDN?r4h3MZ-%E*e-9)&uFq9IObi838Z|mzc~Lfm0~1q& zo;AOHgFW9)>rkmwat9V7Gjvw8b0G#dT5~z=L%eS0DBVbDrLMqY<4?8eLX90}6VB$n zOrIAd66N1Xv{@z0WfwkLnzvwi@*ce-IqUV7H+1&G%F#=U&tT@ttv_#aBGkw&klJUJ7E)pRLXf;t?*)R zwb*6bS}OYTY7kfXxnEW~mXr<9@4Ts$1|QN1g8ZQeI@^{VY~*LIDMH+vq)Ibo^#}=T zv7tko#cQyATmDbatkP6N|L#!xYN4A-Dm^wT8%@#&33lf~i|zxE^GbO8m+2DZ1vS1B z_mbvV%L0$&GcB=eOVEG1ct6qxvwW;h^aNXT~ z%R?KDlf0PN@>i^_rA-A?0jk{Z&+mgEinD>vG0OcbAqm85>x*N@}=Odvi3G_6{TGy#5yuXC!g;l{7YEV zBJg9HeahkWm%nW815q)k3WdN!Hz5i6K}d$G{6TgMmvQp1T1dfeS>KU_#O~Wo2eHSO zF+a7)#s%X&KI5Cc&kL)z2I~Je#A+F5wrr)+j33Qa{O_E1Eq;(*6 z>Hd)vZ#nN<{=Z)h(-}7(UJIBc;hRWx(?yv~*-5B;+MYI4BTJA|xJ`YVu*diSdElh>-gJSX{n}BUq{){1H2&Gk-tQROV9T&W`!!1epJBs_%0yhj zW{syQ?5Z<`W1U--uYxP!__SgbXzG;Ms77J_81MM7%j<6E zK7=RmwRLgCv*L=ox*w%g9GTo-Gh8BvS8@O&4ZI<-EWRuGb;vQDX~7EL6tm#BloQvS zq`X`(%5H})1Hftuv#Az9ep}ZMC>;6{T%H;*qE~V~F{ad| z)sIx@WkV#4*Sc)CCX`KA8|K*R1I}El{|um2?1fJr(0-9N6a8c#BvD6m+aI|D`^8gL zcq_dEm)us_P3{f;dxz2&1JEc!o;^@McD3PqXgxxmk6;WEmOt@e0 zoz^?Luwml!H1fJ6lxaUI6zo+rH#0Ne^4aQ)$NOFBQOBGS6jd)@A>wR?A<{_oy{LiF zMViU3hY3dsO+%~BKvT-fG~u<%w#k$7gAvdsH@fL8J-VaI*6!|1j!kx*e0%Qf2cHlw zzHLLuLAl#=;NW7MmYA!r@L2;`%AQvZqESj~e&%4*-^EExw4m>cSBet+ewLts+y#9j z6<_eCo)>fF8arMZwl?Mab97@H9`=ETkM&VEj6Twm=yWfAJ$&k`$HBiKNI4LHqK*H2 zMx8^CQB-W4&U%I0?>Q}6k#u*jJVt5O{+-WO9fI(fY7-=>3UMCu+1(ay=6qdS8bQB_ zucYy;{c8SD0J=z12MJUN+ISTx8*mIDDE;PhqavGf*7!eVAs)Sb$^whjI>bYiz!-Do z15K!m&eFEtG2idEt^aJEydFb1b=F!>Cm(&9sEehjEQ}~~ec^BVD8r>`#x*uFpUhx5 zly|DEgOvY&!~n#jzO?zuOAkDkNWlEN`SgUQCa!+1E~xB>tNM4H#Q7KwpwbkUH2}q$ ze+d5pJhGrqli>`e)o-|@$UyDa|5nAYh*2z+yWX*x|~ zf8QANyC@@yVOcqkmA|*5Sd2@-O{J`es&!U%=Y@nEo%*_Cepe!STz-roSrr?VvvR@V zPSY_%V4+eyEsWAg^fQZc6Qe4J(}!;)%suz+199w*lk134IA67i)^UbEp0rF?80cvD z4Czyn@Z4NwwL05=q5TJ^Q63u-r5QlDP0;+Zw6=qJ(X{28)Bs*u??0t8yxY|8rzx$J zF4lsZbcW^o@upAOc6B_=yP$LP=~+88Hh`RG<)SpUTkCXHDPf`Qv;dc?9JsId%vm>4 zb>C=_!W(sg7mEb_<8P9McpOafM#MEoZk2h2{C_{`O{^^Vw$i?AE&ci zS}S!2HJ&CE%Kmw5Y|t-{GxSwWj| z3;EOUgnxg~YI0t?>lk3{JJzZMHde&M&qs4_q&2JOrI(zStR$DU80$WjWWn*1CsMi# zVVfZU+`V+hhEc{9tnhY#GIH1A{b|Y2) zIVTrp>JrE@Z$qVKMXNTJT)#h@h2U$;Q05g9V8XFgBTWnqOY09oB;)71cG3jQ6%W zuYcc|Ar7vlyqF+w+&itsgbFn@I6Sb`D_XGwV-+}lY~W~0(IT{IXN1L@VlRmPxZUHmhsSrNBUeBHNjIOm9j~Kx|~HsYG;Meb;2R)bwD3xGG_- zUN!2q){ez?aJINqtAY4B$j1+)_XBDfQ&Nn2=?hvu#vA?Ig~MckN7b}x)(TA#ef|U0 zsI=U)@jMUJnHtdC(9u>TB2BeXh}0DuxA7LT8QQh|a)FMEn}c1GcPHQZvznb3>C<7^ zl&{SvJ`=38_lEmNWcnPRm9mW)VBAtzJDMjrUEE)$+|J+p2eG*Z1H8$ig2xg$4Gq}D zj1u(H*EL<$weR&0kH3ByCO4X!2iSoM*%sFKuVIeP-VV}5qDr4jg| z(XN&pHx+mNBd>jm-AaS*EA->}N`pO!chxqaNZaW6vz(s$nRqvv1GZsy96iaITaMcB ztLMEM|K%f@KOlGRv4wG=NXc3v7$ax_|uEp_md=R#j(*zcMzgZh^p3QJ|cQHun1loSTn1F*O~AuI4Y=g2crzkGy` z@3@~J%_7;2Z@b%jjifB5)x>~l1>i9WEPZRd+1kc9_oMk7HZIP6^Cbfdu`&MdJ)E^g z!wXaQp4LyBrU4(L(R{yi^`@s=nD}A8_PYDKXtuS>Z2AT$~^=Nu|KdVZgSo6uUwFDc#;mh;x^+AwQIQLCB2OxH)<`vSKyZX7+H1eh@u7z=V>_kZ9eFvQwukj>K z2X~T%b@qq)7?qkhrxNF`zq)PsSUO#G;CnTQIC$#_QE~yK`zq0j-y4jYP|_x&q=_ta_9DVm2Z#OLXQqb-5xoARub{}V6VMTMN-h%Wb^9bXuy@h7&q zatjS|$@MY3Y+M*e){Jh^HF>iX*~H7TG_2W~+kD1hLDPRF?yjY;DOs_}i6L$pq>2H$ za#+FL{(&S+cF2!BqPbky04kR)OmpY`wFc@BrE-^5k1x^T^@%Gig2e z9*KC(H>%I=)_;&r+Mz9M>v56@T@X8TW{ata@t0eY2$IY~7D#!BaC-5d3A3CWPX)S= z@U*_rr9k@EOEPoij6xRx@yVUdmzVRpeq8?|DTFFM;ESL6@c%$W)6r$7jWmCt7mzW_ z!##%3GvaODBuZXm71CDHch9QFF!;^*h^FVTiK}WO^wev`mfu-+u$CN$kE?70%1@P{ z5>Sh=YpW7v?8i7GIzPNilq=wuU-M4EcAJ8 zBg+@a=&O_R=+#M!JaxXI%qh!hf^7_){7@>vb<72xX+gd%Aj=u-MH}N17G6kJlSm{|FF}drTZ-DT?Q6b z1~8y2r_BQ^;9*3YK|%g%6S%+vmg7a&BthMA04A3Q^{3iAn21`uyKB(n*G7}K`YsJ9 zU6g|Ymg82E4#sCaX^+hQsf9U*B0L07?h(5k*=#OK1kWRH<^XjtUgSq<1G{%tB^t+6 zrD-?;1l&+p=kg6-pVC=fZhxxszSHTtP8nbM;8rkzL}Ia~eo3S%a6UNHQC0Y!`;Qzg z1LIg|?v51}<9II|ZD12r5VM#ECNixEgN(rCWe|SqNxf9yrmhp4GETzCoYHTmowz2m zX(1dzY|E$dp~VJ_GTevL?=&l@HpK|s!0{hs#+o+eIiw;?fYQF;RQM&dJ#I=ZbCUxS zv0U86Th13?p>vbvV@NctXLma5fm`qfg{Y2=3FU~NW5$l37IWn6^#+Y`K%Im0h%g5I zQGjZ_hwWoNVFUhq`Qh``)K)CGptPLU`R`7+vm1F_=k9jA^noU=AO%d|5^+|Ny$8AS z5Xrb0QNH9zHwfVz;SFzm8YMf4R{*J53CJwbfA0)FFY{&mbOHlmOmos9F_iXzGubRI0rD?*(e^P~%?v{j|0>|GJqT zBymL-9>%9ybNGGv)%l3^KB@A3@%C9w_`M%z%N@__x^ZqhW3%?{o;~V zrF8^_jLg-Sifsi~(h`>{yOU^cS5zN$GYCAlWzH^jIc}M5%|1XUZy)GgE5<(=(K?B? z$e637vluOz(09;HiP8NM0XOlFyDsr+&YPO`H8vO&_QtWCmR{2qr<^g|n-i2f8v?{l-stQMtQk&-aji4Agd zK41DtH$nLt>Reu^HEUFl`3Tg1X4QI$fG zU90hMq#L4cEOq;+l~F9>#fD0skfr56D?)FWag(%v5bxKLm32v_@16H0ZPz5|=?_9T zD#99->m?T}LG}cXMe~C{${a@8QRwdSR*3gTg^0*YG-e`$Cd&Y<5FI*nXxB1s7XO*{ z5~UO@rj<@emTigm(GCpM+;Z3v?JZC}G=_bmnt!jWeb>cc<)#lt<8$_vOzULw;TCYv5Uw%~ffn7))zc`qbwG#+JWJLf=bXQZ&hWIwK>=4 zTHE|LyrNjWwD^X|o0mC%TJgw8-`5L<0f=^dCT!r#cKq;-|AAy|F0%`(9u1~72xfVB z>?UFA@p7Vt+(E&-anJuVyL+xbd8H$CB#?)$8WFfM=F`=0?i<>Nteg^7zWvPcv`xdX zFp163&AVt(ucxhleT?!L?JPTP@~KmZciR6veXOdgUEZf37NJ!3q3lB) z#@3*;y;#wVfP3f`q#9|LDOVosJpvPcM|B+?u_I{yx0mSkp|rVCBpWHrJR&%ppO07m zN_&7d6TUvxcFtKjdoOw^r7cnIX?BeED+1Hs1Z~NjL}VJ{PAkct?F~06WbT9bwKR>IKwD=Dhuf8@7sYEQjuCREd zTZk(lhY3f+DU2Dv2eJ}g)gnv`ZiwK%f6Ak(GS=f)v%RgVaaJ+)n+;h8*m*>9evt{- zoP7ZussM=WuKG_^w4?RDGgB%;G`t_B7pEga01y{w#IA*N=XnL**WMlW? zRPCt;!?UHsFcA_>4z%i;v})zrIWs9Px+9HVx+9z^&i!8hGScmNP9UeYO`mAZ%df~H z^}!{a%|phEY{d!%-hado3hvkb%aD4&NHsWER;v4nXm8y_w{I;vZUB8;AoXR~_x;nM z;#*aczgoD<4na77Xw3?6xLSj6D&&S*Ovf;64^<)FI8+F#{<4XWH2c^)Ya?M133%=< zJMv`bGphMxGoC`w6~&viidN>m*g-`F)86Qw|36G;{?P7-=horo=yMH4rA48J(0#5^ zK3c?^=|m*?>b_}r$;~G@`~)+u!7>V?k&ea%=V&T0tXDbIy@Tb&ToklKbY`LDPcU$k zNA$5)*e`wt`va)+!lZk~=Aq0Zw)s}*&pSU^jbOhAfDMJ;a?WRv(&-`0+qup!VW~nk z&r`K$gw~zKiV#h&dQsBz`|sA8rkKczWp&1@r;_~ncSW;wzG1hG2Q)%BJlYQXr1S<& zgQc<_y;qgeRat>w9a!Fo%f51blzQ9%(9t{1X(Fiv4>cpi8)xah8-(~msfO216+B{= zbIbX_9~BN5(0+Z=y4%z5qR)!8-U7O|Tm0spB58?a_lsh#jdvytGQ3z)tj5YjviM-X zCv4WuMtmi(ERgF-0Z3I7D(4%4+!~J+7EswXdpdy7R}bSu`ZeaYl@OfkULn^jj3~l* zI$~nQzBW)A1KY5%N(~-)5qqSg^{z@vo>26%~#kF34*3JkH~1 zz1eQTB;Vk!$xQqcZBLd%9wUV}rs@f$>n$o+rmm=~clGQfD7pdk3;c zrLqHvQh99LUnp#FL?&PWYG)PiEB}<8 zlybU^?(ll?f4=5i2qt)kKKs<7b?d+W851B$B_#`l{>+#S@*Spxo0ASaE?x$6?$4w1 zz3~qSxs^3jG=2wWZtyaR6S>s?uz|VPCXI+Un(HN^aUThuV`}>ReLnr~NiJGWM7>~< zh@J0g-isVY($Z{y5>eT*0l8%37xN`=Y5(qI&JnBM*vcCK{g2!$ffYAc@}P^^v%=Vf zzOd@QCh)92<_70rej*96;3KGPJa%*=QS7zX7OSIIUioHPhsHPi8FbA-%J81!jBU}5 z?ASHY^}#;>_L0H_rTxp;r%1KVtcU}LD3zX?45Spxq+jq>xPJ9ZmzlWzhnUfG^&~A~ zalxaxJL%3ZwKTxb=ip6Ze&OYWUR0evA)m$v&;7hHeB{% z8b%%@z9u&Ey>J!nYZ7Iu+=1c!7MBj%Y$Qi(F zMSM*Q6A2QW{(Pk7o;B2}M@54>v8z6l%Y0or8j|&t@e&IkG@iDZb z!bd65K35%zCbS}i^8+k;)WX`d>M8xd3&rc7DKSk4H{1m$aweNsqf{ypuK`?HnYW;y z0h^pB83+xy5yUtO){cy>-f@@k2tvH+J@c}CFeCiTI>y&v&!%+|ANZx3`IzwOysU3v zx?%tdQC{LKN~M;mBHINcZ!8VZDD%<5p80ECpxh^Xd?O^Z8wRg4lPVOwbtQT3hHWHw zv{p?wUYe^XAvT4-(O{-ppQa?TN)h#xh>REPDYi+7Zif$o?RTufinXkZmJT1YzXVr{ zwmw9+oNmRYbI^Relk&7Jc@eO*ff2LEgN!v%WkX0cp zbg}8WzLoS!>BpQne1hHYx0yQNNlYnPV634p6o$=R=Nft16U0pvyinm}nU@>zd|>?f z*VDqrB=;x0+Yg70&5xv^1a7o&*Po(U;hgbEvpqFyn`*y(r$?=2j)o00zCQ2I3B}W&!Dlp5s7L2OZP6FG>etEug+rP$6wHu4hHg3BWG)<%t}%yc$g zHuA?L!cR-<#=h%ZyWjIuJ63}_>ToS9>WZ%gSA}hQE~R4MrdqOIM-W3sGd&-fv2md6WNrM0~Jk-$Lw#v26?5|FUAX=VfHS&WcT%(W%Sk9es!|H*wFErLcR;fk2xv~+nHJ#Ij}sJLHBGUCHU3Y z53*D5orYK1;q>K84p&oAe_jN7;0+Z}FyStztvjyGmVcL_wmpJ*bTEz3=eB;w`5#)V zvl?5~Pelh*mZtG`OUJcV(*?9?t^S|#5_N@U(v}l?;j_YJ=#40@zsniaz_q7!`DqoL ze(zR7(wCKJlVg*K+pP|(l9-etrom)0mu-D2qsKcByhhjYRGj0a<^4f%eJvxSz%Fo?G8lb2UL zh;~lTT&j-4RHq^}s8e>dmV-caKS; zB!n%jPf#p|FrqE=AlN_#Dg&aV7;ruB2|YAoK->O@kj{+arsR1J9*#gf6nufzhuL>n zAYI;L8W$6~Z=kd3qreiRVT~vVfAyRc0mYC6Q1%U1uI4ERm}!8(2)|Fqo`OLTl7*R} zuQS5{2C4EXb~XKnvcPb1Af>SMa9ojU0Gwh@(^f3en^=^kD>f0~*?5g_ATm8YJg8*p z-v|vNj%v5N3}k#X9$5Ng31evzXt$b$VPHDK>Nw}*>2s@mfnT9n`MU_Oqi2ikob-p` zhcs^<;Q>IPVkx%kC5<*F>ZZz4%AwAu-xEDRj&U}cdTa$ zm~lCQ3gc8kW?w~~*+C`+pD?RayeG3$G7Z0X8k!nkn; zpl1Pdsv5bmLw%g9IzqFq@}xvHGM#mHlb{$p)EY5i0LFkQbdAOZf1z?UqF|j70|sHq z0fO)~%nzvl$V7wqDM(eMyx8puFOfI=RKY!Ge+6Ty4t|_-3UN)yHej}j`V)9wP|N$) zYC{n6S6^BEzoxywTXFnv&Hug>jyQ^UvREp>URsA9e9K_%ctrpGBB^!PC?F3yM*|3S zbK69-=2y6wgvwBQp`B{EXm3f9wV!SB zo^%h^e5LfDgwz-i=OhbHZ42fp)S2BIXa!8ldvuRKBpKUXrmZ`!Rs$++cvO;;KKuRo z+g1F8m0WIxeX)HZ8w-g|%^%My9^3t%-G2Bhvd4`{(wBq9c57Awv)XxSyx;tU?DY}^ zTWyrS-S_CjNzSzX;wz$sNyfE|z8*1}cn61s(HrHC9S{oEYGH6N40Si~*|TCo3)L^X zmolf--fB)%Qdx`9CxaCh){K(!2DA+F`&NsfZR}v7`=z{<`jK6U$CrTgX$9Mqua%XO zBWKTUz=rOl)lx`ZMXQRr3~1ul9iZh^5cnn-+d~l2vNJ6TBj&%Z@e*N%RLgEZy8RKC z`kZmDao2IVxKOdHx9`RVGkLX9q#<-1+adg)WTljuV{hi@W~8D+cz*krMDmz|`o7(2 z=k{G`Vc(m+H1WF%NFHBi`D;4Wo4hFR8>5Mgi+l;663?EEs!&eKg`0;1#%e!x*D!I*Mq6~t|* zW)WX+Kq*~rU1AQ(Sgxm#5)@cpPirpPhQA)TG#*Un^WTrYooNqKOQ zS-C<8` z{av}nl=}46CNXo9Br}1ByzkP9l@#l0^v>`z^mGRM%`eX|Sm$s6p zLxO_3Yb$FDa8KuUfwE1f`t&0l13z$LEL0wsS}Yyho{ok857cMRZ}i)mSvYWIyyV=) zU3cx;Y=xM*|klgC{ z2Grg>G5@O`yM?t4TGS>zspCL`Ps{tK*+>&6r0ns6`G<^E_aqgne)e_q9JFcmo9}Iw z%4H&$DOin2?iY2LO26UH>5%ZrWm?&>qI>0-8h-1=v* zvFXIz?(&4p1M!bUc&e;SZ1G7WxFDycxt$GXrBHx=E0z;dN{f#A-b~hbC019ZZvwK= zwNlx!%ZR>8(b~uX6U4a3?pX-tVc-@zb;7unsf^o|m4F$+rUHjv(qHO#u#Rrd!>85W zvowHhlsOr&BT8PX6o~O=E7HDs1yo3&lUaN;0s8H9!)!{;dK);ZF-LNmsNt8s`=J~n zHFs}uUsv6epc(iwUz5R>L%u7(&D>{lPw3674^1b)f$2h1f>G;UR2y|JuN#4}pq`^{ zGr7t}#8kWDbl-u6=IGZHtN?U_59MCdJtFc_M9BiLX|8i;wolCl6mz3kWR0l5S4}%7 zf_~D?H-JbLV`CqQQYT9S28IHGYyiBR zqtV>%c)dA85aTa+58aHHTew7UxcmSp5dIP34Q|&}6-sEP)0T0m5#===! zevu=?F{2;J0b-DvPQ)HQeV17JGG;YkBHXfA)3e7Z-IvWFD|qK-UBUogML_g1aQWlk z(fG@^c%ecR=AQfBFx(fRD8(Rc*|>0@+s8K2g8kK)m2bbMbx^ z$u!Hf{|c0uR1qN>RHPW+{E#k{wLro(s9kCF6iySM6BcDlvEh=fRPSIW0}=>Q@(J@&1EkIGn~|yEoD|%U82L zT5kKX=?t!>KVL$8h*5nqSSIsmr#JpO*|?|IUmUE7>@L5oC}RoTHNW7Z3{cDlz8n4) ztHAec8&8wQ~4!c-hT$KDh>R$SUSnvDRIh#aa zQs(G)sM`N+IGhG`sPll@(BQsF6g{V3ym@DqLt)(h z$M8cQwE96|wt&j|D-K+6K+9oZiKDBS6SV9jk!xUi2gwG$1>`A}ard96v}bKbv0EEp zu9D9Rk^^?sY??h)Ld0B;M z4j4nMmvZcFn@F`0M&Zsbs(HULyh(%hKWh`@?}D=E{<0NaZIbtM;CE4uxevSGY6*ZN zv*hO&y@R^>BuOL9222(7@7n`u(ykqpjm|gnG|1SI!yYh?=#0CzBc*gqD_0w{I8PWV zQcwnv*I?>GS-&&~Z!}h03ZBK%!jV=t+4i9^$67>33;n*T!2nD{FgS|RiZo;0QS>im z=;c3^8B>%L1n-hQU~`nw>8eWc<7j}VFH1 z-jI#}Bk=BkdI*=Qbh>S2*eW!<5})>UjPAu!$)JY3OULwE@B1y+N8JVGr{1H-u^&?< zs&19(kD~ahQ~mT{TS|M+A`f)OFbUO`F}5F>%2*C^G30zt*EUwHWznI#WFcbu{@Q8z zyudkfKS~<}rKm2auiWb)JGX*-bm^9~idQW6&i0`s8xYhQzP;`$v z=cIDYtLOtwArg z)yB~&voDAcrT}7Fr7}p27m6P@t4jZsl?(-kpm6+==Mq7B_CeOcv(eN!E*P5${k$s6 zelD#Z`+YKdMm7-HqOp02<&&sxq!*OisC}%@W59HjNQ6&Gl|)Q-NF**d-HtFe-O{*S zyfeRCyuPi(>c2g-CK08+Hof_}Ae54)zC`d781|c;HppL{YkKW8Y5bz`GvyrsMnR;! z@d=byZ+;Xlr+y5psSGw6g)JYt#R_p`+Eo;*n01ZaGg=YUmWUpa)z$7hJ}H+s5JjO512d|r|B56&{ut1))?|S7oJM7*pzl?Vj zaTRP6{<)(8P?jq!DciP@F^ya1!?UA%@zJmOP?i)f*6E@rd~L-w*fSA07?Etl^f}^h ziEXUlB$ckp<^k#I5_GA)CEn3r3+1DuA8c=(+9VGDqiA#qj(4_X=lexMtth_YVvWC& zr-cfq_GdSrx&ps`RG8$tX!?1oq+8>xl3~q_R4YlN=i~AqyKu7<`acjfNwml+En!NT z>#~x_8Gme;RS8h0J?l=(ZzuiDnQ;E7*Ffb6c33(9s`-l9*NCc2xfw6;L=*R8hAuPK$v`_l%F_$^_WFzqZL)FXD`wVidZ4 zkq9b(RyRSNxozHW&-aV$PAj&tHkrJxy2EPr{z3AS><|~bRbPXf@fA^QhSt-0B~tMA zS^d5tMIjK2yz2*UIx0>rIhoyjV}g{616+}o1-*)QvfiLwX?`Y z`SjnNS!S)gA1eF}={!ZQjwwvFxUv}vXQ9o*c1`kn<1Hdj+qW3l*!i|?oR7#y2Frg( z#GJY+mXu_Jqw^7HHq|G;EQ?b;g~ezHlBX^O{t@*CY{5zC%5WqDg}05Pn$2Kiun^4} zz4ioSX~E^xB)8_L1GrcUXLaboUw%#ov{bHH*XQMK4S16Uc?$R~%*kz(0}>_Q#mLZU z_3bwu9+*N2NN$k?Y8$}#cB}40h?^1m_qZtZS;ci_*GCj;LW`v0dm94cc8%y6tw%&b zn?K8~aoFX&4lK)>%L^XaCMq2YXd-&4wdkCO1!!cbb}PIBV~q_ATk$n3-5%=UmSF(z zSy^+tS6t4MR=LJ#-vAQ0?Bvt``ufLtiBXOtyu0QlUm<{*5EQ?xn$W=kI8%&%Wu}9pA7_Ggexq48PcFK4~WjA zv|t*`9%vPZ)-mK@$8v;3gamLYO*-%^$oA}5ESHEyY3^)PnwL4qgXo2Wmkl{@mEULmqm};NL*#kyq!xKy z<$F6nkx_jv`*B5C;nrc*w>!+;8k_T7_NG6k^4?q#uOy`m)kuB<=_+S`1Z!$mP4GYO z;YIH|o{284dZ=g)9u&me^xn$C-^gVUyD*9GEa}oTP@7@NNuHio{XL=}d~kn&RFryC z*2CvkJ0sz1Q5CQ9tW8LH#}3?c6+M?G9ch*0+Fr}9u37W%L%+OfTJM_x!4qX~up*JQ z2+@7j-jhQyT){dO^*OsPV&}oAeO5Uy8|q0U1rHyOA@S7JzuW4xec+hZ=hTuTHXMPP zB)_>@&B88eTrV?vgUI>a7m6FNJ+gb(mX@M>Wpe|OjC;O-bXrvyT(S}E6vAyxb`e2P0Kz~s(K1ggp;&rFI{n3oZ{ z2>8v|;_w+g|0JT@%DkD3(8@GsUR3eHe}cBHRQZsSBI;o3qLh>FeO+Gz0F;pnpgzn3 zIiqqnLwBHDVD2r?(eKH#3QzO`M&K|ZO)KNoEAaZ7D}}=ZpN~ZAwl|O1)Ta9F4B!c) z{*jK~F;l@wVVm*e?aj{l`*s0rR!TD7dx-FJ5`opp&7GI&kg$LqM&+QK0vvQYu3lZ)iLSLMxcvBZMtLz)p+a;Pc zQ5oaTN_kV22&T_W9L`zo4Pq&|tz*WcW5#vIG4bFfj;s#O&-RjHnyik|T%#PyT^^DG z^0$Zz|DOB{v~a#f?)BkDje%Kr5m`mxWbYlxyUCIJ%+7ZV)>Je>H48?qiDpui5U;B_ zG>OmN!09<^5nBo$x-WzObU_1Dx|mz!>Ya8NrVUv>8W;U@$bHj|m?DG1%sB)0Nevot zFr}oLXGPLmeO2o0;<`gS5=INcVr6&(-g(->AN-#hIo`g&kw>>R z+rA6NJ%B(jp6KP|OhE(bHq2F5CVL};c$(P(EeOz_1hvw-pOw#E?+51kfQ1b7nXaOh zb-;P9FwS6V*K~MOI2d`kxxTxc*#a&fH|o|z4a?Bn{>W6L`+E}&wr`%Wjn$PNauczf#3R_$72;T#82e+`^mcNRAbXx1;BY?IQ-& zB_psLjldW3)I-5BPPBa5K1{^f15#ho^ZwYdQRpL+YduiW(M0V{)C62kd06AvIP8!p z#wF0;T1dG&u1>7Wv|9EbN41>nuDMl6tK(p*45s$0nhkILOwBX+>YYD@VU=e5jKe=9 zZu8Q8wr*X!>(umv{*R=eWff%}ZykN%?`dI)$Sm}YwCdsXRq}gSUng*AJ7^A87|)CC zr1_)ZCbn(D&9#x!O9D)}Dhh1?c>y!&@5%iP#MfI`aIm9#S|*otXiYV*QcZA2HgGuO zS`en*e>?>f4OI)0&Kn}2bbXEidE}hyS&r_{7vXL*1>5Go7~~%O0pyRpVPE#g07S>O zuE+~Ei*o#iR&*2wJZhYNWN4gxTW56}s*1KIL+H-VQ5V5ZVj` z`a_bS%7o;MQ?G3zOZr*G)!WcbQJLS{EvZjSM9zy7m&$2dMDxvbe9Uv;^RGa|vXR=#fjYG;}i z`^os4)uxb)tM9N}ynP);cvbpxI zkM5vpd=WTmUzI}pnH(!ZZ#h-t`VK4Y-K7NsU)Wgz`)X;;t71A4c9fbw#@fXDa`Ygy zjGIAF{&`s`@>#_F8(btuAJf5pFM2=H+e?l1#})2@S|Fy-Q9iW0|54?O>=6^r&=(L`k9^^_;q)w z&l}(EjtA!)f<<~pqoG*nT1m69w@BnFIURWG%~-g-Hi8+|awEqbxTL$(VAbFXtfF>a zmAZ|r&pM@P)Oxcb(se}I8|M|=*%&VLGUVlz2>ff!E+7^cMdq0jX{0L@Tk^zx1$4R= zul7>$Nys?JHPG);7Efc1u32BXJo=PjBZ+tJOlJcpn!9y&mfCBFh1It0-sAztdgHI} z{?+1VVSbiTAjk+Z$NEzx)GaP<iWK>{HNjOiE7D0ZPcZ)(x*nXGFK!lP~dLGM>FJc zM&>lh4h1bOWK!IRI3D!%Z<3-U4oyT{e|nK=7ZOqr6)2d4&1U)eqwNEsY8K*gxu$Pf zdNoGZtbdBLB)9^gYm?fqnd~J6b4~78{Kcxf-3J-n(zE2bW*Oa#RcD-$o!w}=A0kE8 zxbIOk;0zY34Jcl`)NL;R0F%;--Hjw#Y4Z4{GpIbZR%r)cN^3|Qs7qL{pxE=$)P4E zYm>aA?v4#Zypy+eLM6z-sKl6mla{LLEe#Su6$5qlsFqg=?Lcrr!&NOwdX?@I%+H{# z=Z}&$@ml*gf$vO`*#i<3v;HGQIaCkq!M zsxw6UH)EXhK*?&Z{2k%AHKje4!~4a@rBY~BIN!#5)~ZWl99rCq82O7+NMe3g{3<{W zan)(y>{3GU+MC}(U5M5v>Ra-uJjm1KW^9^kOC#gu!TyxhQpYV%Rj6rVM!Hb@k$9pZ zJkn?QPij<1z~w%FN|mlk50!9wRJ-m8yOtvnzz){=yNV%j_ZtT}s;Cbx-Rkv3vha3a9lhU-bqQdA#TL9HrAevjUki^7sSK!m8f^a5nxaZ!QjoJvE%)SGf zT_yFay-wQR*UK#&K#k16SDQ4fCCKP|8uY&oL#EHC&M%&60;%%yPTc(sdFHCI{{U!A z(fmjY_8&Urx0UKiys_RO~qQq?#zUtOZW5k%88zsloYr zRfNDFdy`a{%PL9w)VbS$oae1q1-L8LtO5&-zl~k=6^HEaP0oJ${VD24-5n?=0|tOV zr~9o>;B=@{txu3BOuUbW3DNoF3xb8yP zIbqU}VDf5K89z#ihkAZu0u+uqQok4jiX(H=Z9P;R=kHTa;3~EVQ&(ehMmtpnDo!^1 z-nC^P0~96?QtWNqRKt^##a4}lPNWlqRU4Dkn2p?as?tU?%T<*m0tb3--VW|)eVEFf z9D&l62|qXCOCn<%YCNzwJtiNPzjbgZ zLLY-xW`_gis>BpH+fjFYKtedPcJ=S}wr{UOItEoyTe86si?D9q9S9p42S^aX;Wxxg+HrDG4|^qya#t*d!|g zrvs5k9jO5;_|bwm^`Xdi1|2cpmn*m4kODKG!i>H^ZM3c-Gm1gaUT7mNiZDUpbBY$@ zW48A{l{X}wdYV@~F+&ngLebO&9CNogG$;Vz{{R>1KnDjrQYq_|=d~Ai(3A{FJ89iU zI#MtsZah)T^1ZuIm4+rU@{Y7A-SYnc6$EY^^`m$Dx#{mkm@A97oxO3^k$EI-#U?Sp z;M0x)!J)p0HxZ5v7yw|>;GetFn%tT%ZNVXM6M@K}jG9bQ%@?=`Kn_2Z9Un9T1LlLx z31}SyJeKSID9(QCQe!6px^)z}1A+L^?uXD25K9_G`9b%kE$Ph-?LsApxlejAllANE zN=QMt^`PX8j;%x7da(x5gq{eb1cc#vG^DA)q-MwsXn5x5(X6Z=8=xfGjuedfzMNl>HI(8 zX*D}jaCUsBrf5wkuEVp?rQ!bo4qteN<76np*nR0g!o4?1@D`6?h$V@qm%GXS6@Nyw zi%QePFsiF#=f`@`HyPzy01C!cTWu|kl{I2(e+y|-KtZ&R1K3w9tavL*o!w!HV|;e5 z_f45k${k6?U~BRSWiFdWJJhMQsh1_)k14$Hg|(&XTiskq3=Vma0C8Oog`(*8+RQ)M z%<@JCB$4~md_#W~_L^66?o-Aoz8jS^=mT!aKDD!`r3U(n5R#syUx^y+x?V%4JGfZJ z;)B0ED_7yqf%HETXy;hIMrAC@ZNu#Y2Zkhb(y?`23d2y;X1}|a&7J<}&j40xnRJVJ z?R5LuEn>OInIe+_{VB&5l{HCe=5$XFDXk9Qz|zNOu4_?2xM}wHatH}I1p(ulo5X%2 zi7qB)b;oMq?X}o6Z6sSn-dO%4o=>?o%*(3HtKIC4*`gWU=xZk>IeWVqIC3v|?`-Ef zqwi?GP%;l%)`L-*9K|{)ix?iq+}1yZVkrP(tQA+MYQKMbX?6aEceVw77BTmvu87(( zvBOcfE3J#qG-!`H&GwZT!Y9lHEP>FOO0NF^E9H(c^JLa{kq(6vjdLnn*e(c&ADO+s z!mGos>KC`qai>@f*Yl_^RMT8d6x$zRP{BpB1s*j zbB9-EQI`u`hqB&;x><}0<)Cw+fLl4Q4ATXh(YF5r9Cl;_DL`-Mne zI~?|*soUw-QMy?y)66#I&T8h57N;Go_g9zE+S;<6w(&ks*XvlC#7ioLd09kEaz{~$ zr(>_#CGbSIn&biZA0!1GrM-+O!w7%_f!`E;ws`ICXSvkkTZCLjGtPZ+SaWs`OERvhcNB3! zYO5e~%kjdGt#RHW)p0Cq1i3}y713Nra$q;tS87YfNzYS(>0W<(A(XYt?NvPmOyr)Y zMF{J5Y1>QZrhkg3Tf+$ocV@9IZiT#ii#Fr@sqJ&-CgS|o6KTfG_2|hbba&b=vZ;k; z&2@0y2}b2?SB+WUG#3Ld)!gX%p&)K(jKU%wRejfxHZYPZn}`sy)VkJ6=!8}Pj-5fjp1@17HafMzf z%N{UyeQHHhyJ+cBM*^M|yVFf2sE8z&1S+pi^(D21)$8v?%JmO6z{j z4V}LnV05hc)~HSNN1fhjZEYUs;9{w1-c+|>d)AMNH5Qgujy>2XwR3j264}YSy;5Ar z(lK^D1!s!cH*Ur|R$i&%6y;-H>m& zxpK<#6WX?P-wtb6XeA2Bo~E_@IigPtf#rwg1F03xPIl77&Q^9>oV~uA zacF^MedeILu!eO%FEzP->Y)6;jby8aeXQMUCns{CuC+M5TT1f5+Lgs$poZgXEqb=C z62^p%b6#WOFrwpf^)=B(S9+P&f>F7W((K`CKRN#C?@@#5)TJ5DSDNWoxxm=(J^ug^ z-j~i{$)+T1UjwaAEwq6_+t!BCc3?;5l6P+Al^K}x%|wVf3oet2vWy3i3^9Tc*juUVv6|ZE8~TB-OI_2;=dp_lcWK56-64oene9)ENfc zuI|-WR=8h70pmSIMhN@0YGiJ4RLJLw(I;z=(3o!*sfoJYI2b5L88yJ+du)R$u* z1aFtPrDoXG>{D(|M|#=OkO#x^D#9k_|(24Yss&t7&g@ zbv(P9(z*Gah1uQDJ?p5^Nil8gXq4=eTa^@DxR&8<3fuguI|}6{1m&A{{Qh;`MzF&Z zto_GI#PzDuM3AQOE`6%G zM423IpOA2B#BGiOr)htd_l6sCQ##VZPabG+J!Kso(&n&>zMLk$`H8M$# zyK`2W5-%$bG18^RMq7haVs$4B%qq}e{{S#%^yaCxWndeQY07eGS#eFy4FFDa+K>W1 z^&+=@)DyVy)LaQw!KV@d7^qdwaZ)ME^0e<}1Gpywp=_S3h4rbj2_b2$a+urRo74!g zlf!hUt2ZRBeW|WLyG~VXd(eY%*dzFOH1#HsXB_mVu_L7qO+l8Uanx0~*c=mCsNs04 zvA8(JQom6>%Zhy)tvyI1-k?*S1xyG71Cvzl1a6r*E6qab^ZQlY9COy9Wyt!}q`E4=9r^*+KbY+JFr@b|xo9;m(6Zg2PlEvAV9+j+P40E^es2(EyI*LtQi8CRT zh2POvtuGETy$x8JAe@e!#X*g{h2YdZ!uKO|7{yke4CId0p@75qO)^9nAgbW?sc%u3 zaz(S=l}^F!S7wC|-P{FKWHFpQX44rm9x^Iz`M~w6DJ~=(g-)k0%{8^c-HXw<0}I}l z0-#Ai#ulaD&04S;1e5X(p0tGED!Vu>{{l>>P63(|?cNmj|s4lGM}az%X3k@##yFIP|2-_gwo@;1T^Py#Q`9 zb3r4f?r6c!prajgNp3cS7#ZE4Y5?3b+|xlI^UXUXbKlaP#30B|y_#GSySf?}j+?0I zz--aiKu8!Lyc&=&JZfLCQ3yI%p=QOz^e`6k6Z`3FNgIImc=U>AS5QVCI*YY8)Cc0KjaDG7kr(E;-NXLXZvJgOa}~ zrI9g)?M=xCpURw19MJ9w1~&|fOkiNp7=xaofFb4~o zFQ_dA05SHZBj&;6QVfy9aY#Dw+|cb{wxCW<(ZHqXGf9k{-koWAq?kPgRa4ikCJ#Q8 zbATxU$6oZ+m;gLbLm!y7D8@QavAnJne9V7qpbfvCJ;*49tT zsZDP^w3}y%kowf$O$O6iG7ve*qdztWT5}8^RrRK+1Nd@%X{UV&6-mxLD9J7NX>s3m zH$3E1S_Z?E0Vh3axg;EM+J)G>dU@F4nn_XOYsnOYKe@3t6tNUuq!9tUaytM!w9M-x zSI-h|c_i(Ua%-M1t2(0;(>|>GFthNm)FhomtrE?t)Bbs3`_JxzIXgj}0TL!noiR=LpFSn7KIM0_Cis}_j* z2CCMV8(20u`qj?_U&n1Ek$lC^1M#Q$!o|Gtbc)P#miktZN+{)=8~sE0edsxQgO<1X0HB0EpwUuD@538-x<0vo0~3 zXb>S*;~golp-h3Ga^-yul%%aBjqM*@ z-a@ndrn-o(Rza2MMR2#;1lm%^b#E#^nseoj*sWbRQJxe;mAaA1{#D0PDXW`bon0MB zkd7#6h{vT=OOWZ2$)ZUPFnBf3ZEPi`jJG79^yyW}&pql8#NZB;=?UsO(zc@_l29J2 zODHEavj#lXW)#}$JB*Rbo+*X!FnOe6M@og8oK>p}am^z19qKl1qt=4EiS`tXpkp;k z%W+(diEc$i*)=}KZk;F*XQI(`1$JEX-lJ%V88v-v@z;S%Q7mACi!CpstFQ}N-j9?mgz>l7};)Y?+(-rbh z%hRE%)d-L%+*owU44KN-hMxmm$^x%?#PfIYyQOq` zEUOtqyC$YrXl}^sA%QHd!%E69GgvyuiY?GGBV^+hrGFInv4uuu3^7(GbJE9EYh?;qVUTcs)iIc0GD+5xchJTWZR&H{wB<6rDvq97dw`#N-l5elWWK%f zAXazJYS`256GgQ1Ze4ui&N!%7I@?f%x|yCL3lu?mU>w(u>(eZ^q$%lL$BcYW8#_l6 zWr#ciIIlIDLo1mHk90C|Aov8wu_(&%z>MA1p;YQ$}T32&`F`P5vU)m|_NEUn(H zYPBb3T?`&TM*vowML5T$VZ$j``KwmeP+xIwJt}3`rMQ=)jMF1+@a=9Yd$Obtn>)LD zRXDR5E4T5Y%Ec#grPN_g164h^=C0hFy;f1aO{alcMpi`IQL(#6OfFpGcUoE0hop@+ zzTTOpn@Z&BXzB0=kYRbP=;QeeXt_P=u9pc!$zGl7YfQ1YzrIMI+GKNpI%n!@E8Ul} z)Z(ubZSfuRT@IMyI02}sy+%6Txa#5xl-e{>HhO+5Z5AFgw>&6_uXmQfcai zk`_6`R5?h~A9=kh*3!+mHy)KzL|yqUwEETBPm>?=;33JW(40aoV24w(8Md!mt9_9>9=A;jg zlr9PHOvoQ8;EuE@?b?_VsQw+^HPui<*`juk&fM|>VLgWh>3vg^$`pY6>F_A zmmfFqp4651B#l_N9V$juago69QR5GT(DP1L>aEg~V9L@(gMrOanKtINWEdGdp4Cc7 z%kp|sU{F(p6!kge^r6tENa@&97EPbwS?E>AN{Nhx>si+k5IO5wdCxTrslVw%*lOk@ zE+3wiDzV?~Q^^i|><|nqGqj znmDBF^hGoa!KCF+J88rd)2${m!%&`<7@6XMjA6OWE-}R(rjuG+1i&9JYC(g>*2M(j zbL&b0Tz3>|#DL^{%F1y~W1JJz((#@;8aic72?Nkf@k5S+j=WKg$LUJi=mF9F#Ww&x z;ndQo$?jYcF=|~?3?$Yf940WU)^gR{8G1U6d zNyZ0i2PTc!1PV*I2thbLly&Fyr3Hx|rjvocKX_BM_6xA%k9siM^W0J>zzt7tljhyl zm73IJag(_4O&JH}+d%+-6&#M8>C0gPp5Bz)6Zg8BQPk3?B>Ph7aKAyh>^o9`0sGC9 zKp-JK={e!4?g9aTXaEnXrvZrh??^G6p43=jz&IRd)`ll=0)`>@?LjAiI#G3DJBxxT znI!$zr?4y1kd{4orR0GzS0sfi*1ZG5It9F7T)L|<=ub-X;h!*k)#+snN6#K?O7V7y^gUNZHgqtW?x+wPAe<>LQ81}&4E}(qepD8(QC}- zbqg6Z>w=wBnxw}EA$YFV>e4-4(6YDhM@r+aA(Gl(Df;HRp)O@}%&P|(SdRmo^4D;XHBWF4m`y>IwyR!uJ8`HzKiFYRhmT6SOm1cvHPhc~Uu5vewrBaa;Dy(3$QUg+Bds0Wrg?rX^7BsSsvJl4Z_it+7)AHoG%mqH~AyQ94L zEv=0s#z#+;{{VMz3J*=huST7NoWJv?(+cou|2Kje9)5P}ouc%)~b944hHWFLQLyt1D7VcZk0L7vr*;^^*XBa2xTV6IxDfJm8 zytrkIawF{3h*9+o2+4E)i>D|0zb}l{J85$#-44<0?v1;)jO%ja@7!D;lpn2IjV_JR zH=2ZZlPrHUKn;uZ_55j;lEZtV;VoXq!3WA>`C3eSRCaKew_mbYEH;3A*Ag5^#+B~J zC$55duJA~bY*YLw2T!eYI=TJc(9FP|1#L{P8@}!%JnubCV`@V<3cb%Y)fdlA#q<<( znqj5g$1RiE+)C+hoU$hckEazCnU)Piiz{_WALWe6{3F(=>345!d>^>ZH;yw_C6y%9 ziJIZWEORc-zd>BC$sH{_m9L?S-%us4n(jo&X%9lg_WD+R-}0xeXkW>1<|^A; zv?=@>`k!-I*HKBh3y02n0a><^(5Pz4(j3IWR|*ePS{f`%EbAG3D|O&jeZc}eD&cxn z-5J7852ZwiW&T=J89y-!Lo)5z)Lwu(e|FZX+Kn#-EerQYMY;0n!#c?iNg9G*>STKS?t-!T;} zt68x=SeLDB+7t@gvsN4z>(Eli=DOsqPS(s9Ca{uMx@RQqdyz+h9^ZO8npGGa&_aq! zK_{UMfMTggxT}%?dQ=`(PFkyUGMgu@FvXLe)p3zY+exr=6fHFoS76B_y*wZTJ9AU4 zUbHXY+9>9};cW;!ob%G0BK#`hjDebOlpB-Ql6s9TH7gjm3^#8|VT&obm#0d<L!%qXUoMhXCP%Ns}^I=TGA=KL{8I?Fgd3J6mBh_YOF^97Vk+jsthah zO`$htNiEjIEH>5u00-X7cdthaH_6BIu3qkP$%U;?1k7!<=-K;_KUz|apv2wT?_NSC z09C-LMZ{wW6>>eQ)upW0umKENIL&jmk1X2d+zz-f$%@HEsHP}MNwjnfOUJ^f$F+0X zgi=2vc5_>+A#=1pnJy!UF}HsdLoU zk%N}Rr^>I?>NPD_OYpU!3AL^mbvP$A<(lt}Z?y>u#U>E`b%UvDR~ntcmf}pF!!F{1s&;M zK@X7#ek*p$;onc&>D1P4!cXB>>?37~*ng|6WoB8Is43o9u5(o5J3wR9^a8G5NZXy4 zpyH`Sgr9!3q%}mfsWSD;brojaxyWusRF@$)9<=Lnx%Z-0+-q}HpMTBXs{+DJt`7dW5D zTAOwj?^2bQ*{*c}_p(SKX3UN;y1JOI^t)MF4JUfEpL$I2N2PJr@b7S2?wag0*dc}_ z9#WP)2(9B*+B95}<*_EUs(G4pcAL0S&2rvL54!t@t!(QN^YX7f>j)PC2A&Ss#L#s_5>Gg=WQAS9c$Mg*|pdDw|nz_i;=XauRnUo_MPgEQIBqs-%wN zC(Ue*l`iO3B>NoT;Ii@BrjFMmEix`UXPT$x$UrR3liq+x`udttZ9A~k)Kg~|ecin&5r%R)ihg>L-kS3e#FGaF zu~rrL9ow=xRYCxK?ae$e1JjyX^c{=q>rQYS4{EI$Bb_R)=KC~$hvdgh}Cny>)JE1IO$v<-TaTbAm0J*w)C38KtO=Ai!g9BBci>(yB(opy(=fIbM1mwW4IVVsyZ#Fv#6e22elQsZ^4gG`xU` z&~@)oFyxxJ!APpIARQ`N>LM^h4XxIg!_%b<3Yr6EjVuXRt1|PEReYcyC#`8nnH*JF zkQdwBR5Y$Tl@yTY(v%O~(8+>n6|wTrS4)w|o5vMSYjMMO6{HBL;P zdKBmG(1maqDUI00G&VS9$ftb0KRRvzNg>(YP*0Gyvn7?X_jp!DaVp?*)DxnI_k>;eE!S_ax(-KfAFIvQ(DMj7nA zX^JooKN@oY3GL}dJBlpta1}@++K^`(MGP`H>qba9J$umXAW?zxb*7NS<*C^uosHJh+5J~OL00WFtunoZ+ z4z#~9!nbNn5OQ|Xl15K@cIq`@SmUL1nl7SDUQ0D|MB^UyHN4FQz+=-rjb}LXD;m+8 zg!DTZv-g{o^sG%u&hM9}rEIL9X|zUF=M~RtmocF#&x2e}F6XGKCa&3UK-7#EJ0xt! z+*ZE1qb2lTYPMFu8LkF9!m|%6ZsKuTvupR_)Y~KNPKO7Y^l;c(wLTNi#Z`sx)S)w_ zv$%h}ILBInu9b%iny$|jZdkJxZb>8>f=x$ZC42E+s=?ESwIq4Yw5076UU?;x3N|YH z)Dk>!NtckeKfBViroEP43vpFiM$cMO#Np{HLN{QeHtyMW>i5i(D(;|kt9E`TytPf6 z*_N=*O*sJ%#}(ybCaOyII$JSVdp3Lp=qt>;rz^W@$E|4SS7y^t1UFtOsdOev z==ARqOKGSO_l<~9?$5ZWd_OX3i8@?LpV^6#8Xowpo2#EP0lVfS4xVX1D`!i?m>h!ngsW{tgja3O8 zlTlqkmJR9FtByGv$Q6X{n@eMNPUxo%^ z3nGkGX*TpOD6RdPCXaJ*p474FQba>5{GznjZCnN2QQeaq04s88+!eJqQgK=d0dF&C zers~iP7(mk&2tGUPMvG5(55m(nCG5rj;d>8MOIB(=9D^oNq{B3+87Xe8~ZUHW68 zsag8eAQR7O(KH}pe(JV3s#6oNsBUW0FMZWYOwRsVE*hG8i>Xz}Bq`&bYkx!1r<&kN z61XD`#U`7h6Cin)E7P8}=sIPx+FFEHS))UmGA0L zdgQb#z?XL~JK{;1osX_+M!9)nD9g4rA3K5Cxf{JiKBm!W?8e?MJl@3Ba{HGvr)b_i zPfa?MD47p~T;{9dTX-_2T$t&UrN zHJN$iRf!5fjNbLlHI$(YtgJCqrV2lcinSPuQ)P?)01)2ZxyxZsYQ>R>JDIZ8EQNFO zbgJ$vrCDrYDRsEkW^QS?%^4tLy*OZCo|S6GP22+a^r>S|S9@{Vjh)9%)a6E=To1ZB z)VI_`U<{TWs?1{ph0R8GnKt@*RF>!cAtM{GPdTZ2ps}JxBL{CaW(H{>^80tDybKrb zWD2>kTWQ;ysr>5~c3L_6;6vlqqKN?M+Ln1k&cyW{DoBv94bWE5R!K2E%JUtd=9z5e zB;&nFdyv>WaqUq-joB4aO3eb?*NkpV?WiRse(Ps7Vi*0v9@S59IsX1@G?G?DGI+x@ zc&f7}2X|Vz5F~rlS0e)(dee)rJ&55AxP9DXtxlw-L0s)R&wW(sfn!=IVdxnwv9+hVDVo)nK2ensSyAC;~m9+({ELpkU5OmFTx_*4ImfKvt zh((Y&T$<`_M(`Nax2??{#(uB}e4a&PNrpL9#w%-ARvexy1>J*`+QZ(uqVz{IT8uI} z9B%7VLhAi$u1@~|o1mqP?URm`ce4d;nR$Y^A(w&DsY@ESD!BEligEzmNi<{bj`ZxB z12>XM{HP_eDoGRP0eTq}YO)iZy-iA_cccRY@S`q{%p9%gsBmv1_Q?+M{L80PRYSGmo1zxxpvai#@``8v`7xWL1S^AH#!9 z0Y}}X#~IsFkPM!XpA1&5}d)*Ya4d9cCVvK{9#VZq>nlXw__tY*Xe8IGJ zpz-)qi3g69n8yaH+7qyL$y!AvfyEg7$4XofGW~l}O6*~~A2(`mIrlxO$}z)tq|Sc| zc0d3e{qB7!Ff*Qq(v*RX!>FOKMtx`ygbdQK%Hwq+@+ci~OLj3w&7Ab4R?h>Vppp;0 zE=V-qf*XQ~luqM)UYn za$Py$g%{UB+qh#NDeFqA3SjX{&x4J%8h|oSCWUK)90LK5;iGW}Bc(SBigs1V8*nJ< z0g^HW3J6@DD9-9`06g>}o8?zzLm{X1b|hYR_9)5b8x}T#|Uic`e?dHzm%7;Uc5_476$p>!&lW}p%^sOU_lou+{ zjzrzq@bFu1Nx#&U#aK8qK?o%#e`3 zT20w}^rmMtqBcDR4U~}YFq25mUX7URNWzVK2mm6CvEr9$;*10QRICh6pTkN=9CxOZ zMsrPDs1DhI^HG(?3eySA6lgK*!2Q+0re{59qZD0$QBMfX(P`oWd8Kp&AQMkTInLbG zk0^EQI@5qt_c+BDNEW7~EgRVFUAf01vi68>Lk<8uRjW+k)NX{ylk3u#HGxH)J-hkV zXv46nwE6CQ{{SJTWP$qPq0>xjYyRL|c}VJe@l={gWI~&E#y>Moh1bjqi;g*`7iV@i9SEmD{$}RJPAa@`v5#)<7pJ{l zj0cdS{{VZvSxDoI9Ijf4rzdo62)>`;YoC-oQ@}BiE zOg9w3g^xX|Q?`Q|2Hq)ggUvajINmA24;iYm+yXEO;c9hU@wSjhp1f46^6^UA+*c4N zQ_o6CTx0Ij+nTQ{@q^ZyTHS@nCu|JW3x_?b%*iStwJeh~rxb~A&gQE^)2Rl+-8xcA!ZEYGKH_vl zD!ppFaZhtD0_1k9Nmx4AW=zf%7bi8<=sp@(#Pfbs-4{U-pE6~~eru>(h^?dBxk8G@ zbsoqaj9a8wbr6fR0ot@0?`j2BUzgIcF78B^zawC0tz1i(h*j!y$*HqzVRI#-Ju|~A zq~7>`R=Z!Ef*c(5{431-M7B^}8(lUZBGMfH0Kku}dX|%Ordjw|m^5nTPdVqMc>e&3 zBr7VIol3|uzPPTHtWGFO)mvtE$VlBMHA-99pnM|n+L+Nw_%h3k)oBtK@&je6R8i9A zHsbb4{!~`1yNG2UGct;`HP*z*+E2ArlKG_I?X4pheGKI#(5;3%y6`*HEEIgwjH%>4r{J!VlyCG>MfsS0RI38 zu5(R{Z`{3WWt^zoy$=|yp60y=Ua*}BZi28S4d!w8YiP)xSqJY`3y7GXnX)|vbklkq z(ps}IlmbUq^rm1hEZC`Jjkn~c7NaUpO48cgNSYQr1JXJF%=Yd3IO zlcC<9D{?#3%K7KDR^9u*m)5Lq2rxUru8#@90lzO$(*X2xSa+ zHC{;p`FaY)hC&e4*rvFeyPgMt+eMX86A0!H5k}CVeF`nkD$q@UauUb}M*&cpOZsgNlGyF7-koc*iY>ZUB z#AizuPu;49`BH-|PdQ~@V5YUV_aC*`0yC#=u2cERvPfiUW6@kYq znpPObIi$%0nm82I!~`DP(r&=R^FjG}6yQl1>zW`^nt3~qN_WsTVcQ)j;B=)N{Kk+FD9~vNM|x-+Q?dp!)P$)#H6#JNpaX7A z82&BXp46p*=(L1q7^BbzD=pl7IDsP(53bB)y2<${hqY4iZVUz?~j0kh_6G7D|$ z1qA1>yl^n6>udM+5-sXlp?W05&ViHFm zttc4eQ+&l7GphY+Cc0G^Rn9%?;R#9EAZ;af$+Ac%Zxq&%RXJ=`e>Q1>2)li%qa0_= zmyz1KY2c?PX6#3`k3#XgiAGtneFZ?*GoQN`8P8g%_b`vS5>yR(NGsC1l?**4@4K@% zIlYU{%t$gyz~}I&ns}r6PTY?8>shaI*~aF_)}v=H$=#ZnV=2K}nh$3u@iO$c?CXV9 zA4;tE4E*kF)BtnVpMVA$xoTr-&r6n}6d`seIciUsoNuQ92O^E?c;Fve<#LquY^}Bv z1asDa0Qt9bL&^^Wr7*BPIH+w7%y|Q@?r99XUTIXoULD2ge(v?4G?A?*1VxH$YXJIYl zZMU|S+;%~l=xzK7tVwU@-85E^9<3{Z`c?byh_4#GwufPFVQ#|%2sdNvT%G2%sb8@3 z?&fei7vj5AF!a^i=3{Ov%-p)uJUye^6_WSumw)uke4@EIq*){+C=1vMNf?v!R5i<5 ztYrPz*%00K98Uw9ZfM0jZD8BA#58eERVR^3sh&?1^vM1kXNsGGR~d}|01IZC22FL^ zFM=<1G#4}cksM%mHK(cgGSbQd*ufq5R63Epja4Z%dmJi3mE3Tu3&3Y zNc*)1o=Eogr*>xI)3GVQ8-lkq-Nf*{Y4F5f1h)sE^sA9a5}r9CrLvS;=u${nla=Qj zRMFc@AywJ)de!~${oS}Gwe-jWko$NZv^HxREvvl>F=!J(2ihcV4{C)ikiPasuCr1( z)4uBgT-pK#2RW;Xy1A@j6bre2@8wdcCDSyW!j26}22VY!NX0E!mDsv2ocDKonR1!PuS~GCD1nOL3eM5AgtWAcnR&%+32-)! zg1owuyLL3TgygF9=~d-$#~rC8kagXR)pmdOt1FEzta^~7)NFIjFu$!v(t%5@${&$N zNgk%73<=FVw%$cjyAv6=9cTkRdeXCZq$j2+2wlI!PgUb5wMJV8nq}vXl*R;aBD@pK7$25=i*qbgENM zsl&Df6rJ^36YkrFM>mKL$ zT1q}x-*@jHuwQl@d-go{eO>1%6IHGbndq*F{4B4J0-K)jEGc*?LT18bywsp4_L~_= zrL=}QYuRRtOrtxxX3lVHW@Z?bb-<^$b&>Q7F8ySVtvEL)(};1E?ZoPCiJRwYPmH_p z&)2MW&rCx*e*R>GG05S27NhsupCzBHz)wI_H%$cPrM_>k{La{viju@wa5P;>|BJCz z5@F3_ha8u+wS*pDuNDG+-j3r2t%vBQRZf9P8zc+b2)-K3GwwP)Q*20+s-8kR}=jVF;Y4;`K?-3C}*eD#zJum{lf6MpC*83 z>@X$YcfE^l@K|>iX6s(CgMjN?a^?FNfmC-TCo>`Vj(NW-*5W15kV&0i9G`;ueBW2V zcYXMV`@;(Ih1K2@8q|hO;b@-?%u) z=!ApJg-m^&Dv!&^?*7_r7HJ~U&Y{B+Pxwwas9_iPY*Z{W#NjFn=b0CduQk6%$H~AH zw!ZcNe>XH?U|Q9`0$LEJF}2)qk{VN%;ai=b8ihTKD!K=JtdnTSKW^z zVZCiyUg8qoUEFQuU)IK7S=YXgI3Qzu^Ajl8p|dfGbxUOV{A(gUk(`u0>uz1N-0&~?nd!?z0^LRr?)op5A2(L$4272uIBx45s6IcMDqrY+$QLor$u9ffct$z_`sPO%xTI}< zoY=_dB)&9YkL{ZmFiHQ0lILq9kmP2)~q{l?i$*8oYBU|lxs z=m6l8lj%BQeXEW&Wl%yd48F9{U8m}O;L!<5t$HG%7IfPg15D5O(7xh|y{A-nU*2Ce z%31>f@3=^E5upruNc!kUcIkY9Rs@ZyD+TpxW*wGQY%a)@eo4IXluKa){Z;@VXXyx1 znj&P)NDzMCdENRMPCKLVEbwx!Kcm`p0J69GvYix;*|jyT9;0mjs{4-2({(n%^}z zvYyZkycJ}PtR3ToCXOmeq`=kxiFnJTf8oj6!D#N<=IWQ?9SOf5Cl8i$gQ?l@s+M(O zjvuQLyVjv{L|FuI(&Ik=GZFhs_Wj#hv}NH9s-BvXL@mTXA5i|co+$Ij#Y#L&a8zjB zIQPKQ?!_$E7sp19d_ovm$q2PWM`!XPY2W$S)v-gv^qFg*6Y`Cijmuz;u%!^oB~6=)J5T2 z-u_^TE2^IYLBZefPq3i#frcH07%uw_VX9KhNWQ)X$J2$gbuiigMl1qRVh%LL5??*i zqM=RSDDJHlV)ky;~x@uzlqRZ@}~KHf`5vutE$4>kqsK!It zPxP@-b`=pDcNUoU@Ar;pq)jPvG*dA48bgzZefNS=QRmyFGIGhgEAh z&w6ZYruU(Cqw1crx=)^l#&!?J@T%7DXS0*gIQjXfp88{u$vkW~TlC}aPo>OCH%KRU z_Q;#Mcejr3Ft8kfjv+vR;;9Df@nDUjb5nb2_Vmfmh7a+MM1VlYT!Xs(RpZO@{(9BF zD_P4rson3zTUVAC&1U5ypWZJhz7Co5 zyN1V#OmUojC~1>I2kp65rx^zR6G)EdZf=6bU!)g#_ac6Jr&vk_ELi#KZ5QgK?9{b; z?r$B%UftUtG7B@3m4GpS5wp5%Y)ML;kuyPY}tg4wvRRMDFsy$ZK`qhf&``#94 zlt`#%XlQ`qVNbPBzWH|ZtKX(k3TD^`FaTF^8)27~R^%PZ5UhN*-Dn7>xbSRQxzrv$ zNilD4qa_=L{mnJD=#eY`VWZGHb75;bG+B9oYlzI8e+9`f)%coo!kDwR;NY*hd41Eg zpFMH`ejR>iRk|RId=0s}RJYv(iw8V;B4_`;eYv-pkl4iX&vAbW1&IdCQJv`qu*Q0v zPTgk}d{zAZ$wuwn<^k}(eWih9{%hU}v8el}(T08}Z|}kg*&rj3Z0lWj(@l4lqF=x0 z!B5N=ZPDT>Q)IE^D(}))8~SyE;K3@J!z|VRUs$N(p6YRS=7;U5fKY&|yezF)2BiHWg z9xhvMZ@%5IRsx(%V^|-%t}RIf+0h-^S&Q5`9=?h30{?%wT|7n4Mg3ICDK54j zX4l=R&lAbSuo^7YYUOwRa5YyvXESzrNMkRg$H6}P(4rluG_uZg&q@03t~U3G{>!Q2 z{{RI}cp2sxhY!zIik_0tj9}zY&UGMtBV;f2Nw$>U)on6M{R()Etp00p>ve6~cEbt@ zoPI-}-L|-EhYpu3q=MFCn8cqLbzM8rc5d1E4T$vCiuU)sb@F!-MkDjVYBgBnOA$$A zh*J1nk2SrX#&w;@hOq+7pDI@+M9Y?=}gqw>bLFe`Ql*f4(I&k!eX z$vWnx*1CGpbm}IUa`@FIkb$J%u_P~4aQxO0A*wKvZ6PC~`uE6Lea}SG_~k;(wrs=) z-MfAtMf3b+&S9q%2YP0d4R@N9ugyT%-cyV=zr*k8uI2^In}8}u0fOM%Qc7tL7Di3J zwS;{vFwL-|WlK~Omup+&A7WGFaWxAbHt=^2()w^BE8*Iq5WTTLdOHrKQn6qQn}Ya|+Q zLOjC6wl^~nmm?W4*82RL7q(29Ki;WhEyHHTAy(55OYI9*JF4_XCOY?T(BbeGAlTV5 zi3mvs)IE#h205{t?@y=qnd1>GUDqu*JfssS?G%h3;u(=hiC|$_EnRT7C!G#7XObB! zr^fqbU#0*{y~3omT)#ri-8X8%NcR^uh6*oi1#8n9g6$AKwn8nJUety6cl5xG-!pv8k zN-N=PH#+3eR5Yk|vmSZfurCg*H z5Q_-pGM~El-EXWzNU8r2bTsk3Xvyj(oB6Y4>p%^Peih=X0j^i|b&>5&Wa1w8``i-R zW5cctXG?EUgClZfH?1utZ$@vb1^^=aY2h5WN2KU;vrW2k;tt_8eKTmp6OmI5P%;b> zizD(arz8DySHs7;iqI0dOE3uH=E%6-pcuoKhiDA`locKrI5fI-&FUT)J2pfB_)9}U z-Yl|3lmImm29QVuX`EqtKXkR8TB%C&kwG0Uuc9Prh)@{MiI6R6onAu_$Etfyn~EIA z4bd8F(w{`H*s>0@1B(?0Uu?%yXGGot9a>`nuO34CDtd2|A?`+RmjdgNeV?}_4I2}c z#!gI-Icx9Dl{of``RD33j!&m7avVb9$19`o68r|?pfBZpOCC}Ik-dBhHWI1lQ7qho z=i`-;oHB85wQ9B@ zKD}R8tk+&5c<3ML@4~8v?ossf=%fD8V~d?M+(KSKya#v}4sM+i4AK}N+9;(?c~*^p zQd(u;Un7j@NFJt0nHscuoSqwP1rw5#kxb8A*;}HltK~FP%pfUyPetC0LbCnFhU_=$ zrBvp%b90z~)YZ`G*aJD}9T)5Dj9)(XTN9Pje-`)c3jJ_V@ApOPt!)0dW$?1Y3s%p= z-T+v#jB(j%ENlg`QyyPu&)BtUWO^-^0qUQ;xaUT`sEB?|KSJHr=q9CPQ^)wnF_Oc2 zebvf)HpPQ+po#!2wFPQ1JT=lGBae=eQnmBEQH zFSv3W`q4PAYI~4;^Vlc!S$0tp;e}-08fY7?&}XXJHpt76$LJF17Fv`$Ertu&cFYrx zB(;+ca(%NKE=Ps!M(IwriyU4~>;YF+sTyT!>CauNQT95FoAROxv^ylZb|NaQ!UC-{ zU;4v-qEAmz6-0#pU0dx~1}B>--t&`Aba(h8VBc5zM~;k!e!H78Ex+)yqseuUvsK;q z3#VV|yMhUqlAtZe-wpZyi{uhXP|eBJ8xk5n(+-*5cEVGak{7%i$v@?wab# zOFBkuWPX~>dly9xxHI;^{k9ljD7ry`pC~T?ig&Yr;b;{{o!DHEXSKWTX9pZMYZR{K zVcThOBXH^V=*9h{(~NwHUO*E=Of@264?QVudc1_9d{%yd65YfRm8)3hz;BSN{R1-A zQFGaU)J$2{FFVa401K3MX!UvEcUG>T-nsS+5tg&#l|0vL*aNqFlFC>~8Kpzh8TIx$ zHQ^qXd!T_Qp%ydkzbcIAH3m@h`s>>{Elwsuz2RHNIqLq`IQw#FNbZn|H-jrFr$UH6 z>wrI$l3KxUKkq@Q5a}+UDOyU@=Gw z*Y@M_f7TP$RB6QuRZq7YsyFPicy%T>;yWb7H-2f}e+QZhlUKIEzUFyt+4krndn)p( zzH;RVmLa+Hxl^*-_pp^A#ERV;Lqt9P#kQjn-8=4Xvr<#5Y%8A2{N%|7uqLc|Fdb@M zn7i1pQ~FabC`Tdfd8>7^heg<$T+*A6J%d-VZU9(8=kZ38-M7P{5U=lEv4`eHzs{)0J{O zW-3|H%-ZvBCQNg$hwLPN3VaXYgynsHfwXsv$@tow@su8VhQxf1mbUhotxEe-$N>)A zbBqsD)7JL=^{M7FK4Y>}nQVKR#4rIB~EXvW*hs8>F-7_dCyG$^Hrj19ZFr|yB^O<1#Y{OuO zl>-AT`|T(RR)~Ketw!d`Hi1T_y$N~lgAmS;cwy+$3p6>|$Q=_RPE z71&x8U5jjF*eGewqGxfQwtxak@U%zCKZa_c-#w?HBu8g8VPbrZjF^1p50pBXK`dlB|iA*yOktv5!_ z$hfmNA60lBV-w(*_V#lqQ$D+2NO_1I>TRp646q_tjOpC5qm9C{V7~=O_uJ-&nAx;<|ZspO=PPspIU6E-=eEL=+fw9T$y^M#M2LE8yNTB zepNUCl(OJ4Rk+eUo>TOoz zX;+1|PG)y#(Y2=QdtO40O7CJl5~=fKTMiw|36~5xv=(~%<{;q|lJICAWtYQo5Wtl# z_^zHc%IKbg$6V5GW1y%5(}#} zh}y4plhled(TDV=XvDax!Qg2{93iIMFV2mSp>@6#{Ifjn5~C7B#;j|xoh~;I*DD## z(*8`Fud4~0*UJTOm&SFbWXJpufUA5<#p+LHR{02c(~?M2x}Q}V1P+XFX&+HK)?EQ` za7H4(;^(QJZ-%1DrE_(E$B{HkQNVH({_!p5kH9mD6xF^ngRlL%&Im(Bl8WKBom{R* z@RrPf3(W6{FQrGO7E8G(2*{f3vI#RgaG+fU#K-bs+*+|5M{4%Dsa1w?5O~k=&}fqS zzMdZJk+9plmgx}7lm7uc5n|e61oUpmsb1h?11Wu#Hhb*yEWuSU#5%)ZRIj-LXVc)~ zC*7{lOaZ8dlAsiXRP)X&=m~ zMa(o%1KY9M_AUJMNqG;_>o9`B|M2&}MMhmri2>XLh`QChx#^9rwDM^+j=#ye#-&IS zcdNc^#{m@xv~1F{n$mg4#1q-o8`5KLbyWP=BX&~Krg%)~ z7bIqpCs=`LbNwpsKIrs5zm-sFT)!gU3cB#1oDCu1%Osa>;{1>4nXvN_e{S1{9sEuG zZLr~?HgVSsoC@HI3BhAT&ZeyGG-hh7V+&X%EG|kDQQ*omkU4CubM0l#rNQtS6qy^# z8nHQV-x335xeVgW@w+afrHSdtGXxsuu{V6^a+K&A-xlopPk2tfSfnHmw*a zGC$>K*ekee71S7jPa;TC{LK{o`w96nFo||JY1YYR^ht_8V83J|&|)p(&|sX5J`PqJknK;)=c^j z8b*B*#sm)qHf>7UM4~b%Bq?qA5S zsz=5Gl*gJq48xIGkJB>=lX(!|)p+ml_fvsJ4MK;vc!skbug7npOS5MeLg*|dkv_A_ zUIO-2qVMe!hh1&F%lGxuJofaG5~@AY)kl{K2d0jyBD7_=xjQJEV1gYg@|>*{7N$=; z3`-Ymdmnvz2P{bq6cbt_JcWd~Lg%f?La^@{AYqHcBI5udFPCfFQPS)JD@lN+DpFD1vBDCE6~D2~1hf&W9j@0<;Y_ZN|Ks_9 z4Fv_c7&qC=m%%OmPX6%e#NE`ElB&A3zVuMN1<>G?zn73Kl^OqRm=_;L zjKnSLaonsG+^Wc(yku-zMaV4L!cz{q5?-lqUCz46|TuY2};VPC45R&9c4s)y?t-?D#m; zfJ#@xnf}I~hA%kO#7>=@tg`#)w?|@Te+{CRXNV2ILGP@?>)uqqIek_7Q~jn7p^l%B z*}*E>>pV$*l4y+Zg)yL~qY(~QSSc*3?$CC&LVo8q{qN@$tO*IbWspe@cS8PHEmDru ztS9A*yhcjucae&K;+e^{XxO`nveh6HNpfQ$pmTrxqU7VYSL{|UCNCO3S(J&eX?%m1 z_mk|}XU7iGe=6?c+CErpJa|P^|Cuv9v|({2t%UVx?PvW8_krZHV99>zUN1PZR=c|} z121MzE)|iXVny>IoZQzYe(+;bO|Vs*&7K>F)tb#mYnITlo7%q}3X0!Fn&N&f=qI=r zKuW}l$I0e{(W6dyw}{pAI>>mW1Ci~z;lX>?f+@C*FS2vB?j038cF+c9Tg}Ib$6(#C z4Eb_81Am+0>8`r)mNY8AIVyIgn}!@c!Z(OBc&j+DU2p8|xcAQn$?o{}xHb8REisT> zbZC zq}~Ud+qZOZ5o6nL31#wmH>2UEkUU?%A?>gveL@~*DX)oyt(@IpKP}fxrcKKSJ@cMr zcc&CTS7}uNdGYDZUg&dwxD{hoAl%Nwq3G*H>CcAANCNh`mXOCgwXydbFbi5N+4xSr zM>O%Gu4=c%#gsP#84RVIA-u;0PhGFY#o+U!dM1ARjR|qxN@!a%yu{#%wybuiQT1UP z_l=quM0bY9x=thF`L6XC@p4_k@Era{-Jbr1{EqhhK8&=nS2(}@UVSF z{|v0D*)bi<%RzJ%f(UP6CfX^Ou#PRITLhoh|vO*abKLlJO3kNpHNq>sk11pER`& z%P}cwec8rFJFgIeFh&P`iavV#G_By*?0L%sY%?uIfA_*7X~w8T2`Di<$I7CLJ2)UA z#4(`C8Bt)Npv_+d`mZ}8GfdeEzhB}ynec-@sv z@C)f+YCjOvA#T8IjSC~Xr*x-@9SpbVx3I#<^LA=I6?ik*!y}@ESu98|D#Z*y7By?m zT1n;-@fRxf_$ttwaNZ5B*$Jk1ve`0|#tM^`9%KlQab$#Op6K$IZz>V+K($heJdSk6 z<$uvsNBStb5AmE+AI&^$+`fd&z;*=2Myl$e6@6wQhPHWx zV5FrHgi#Fm2R41h%^vfE$plgU;O_=jS4zm(h(a>)G5@5G4Zft& zw||0zA54jTO-%kl81vZ{2hK1Fp1kH_viSuKXZ>q~$5V_+lYvQ-0z;AN*bUo@r+DZxsp4Y=RVVvTin=4g{XR?YrF?&^Qga&M4m#EDQYSvUja zuk-i0T zWG4(s%22pL4QDv>R%Y*cQK~;3MyUS}a9Jlk?w00%xNOM|sF7H#wQ;AS!4)M0s2Mf} zRt=6AnHe3}Q2XCX)#{H;NY#o9{Me|#c(08l5!!LUpdp>P*-=~Z=#6~QN)nO;uph-f zJm&F4(03nlQWNSRJR&{T>3#UIRlcIy3`WnQocRLX``spG(>>pJF1Eou1nj#y7f~yd zBg1^vXe#Gv%O1rYcH(`I%IPG=07w8I}YVyFgwd#YXoA!+o8ilh_Y#C{yqQY?RRTDp)1O^rthtMuMC@LoqPw>8X6&r z-?6LC5T0D}_sxWG?qC;cc22=PC(4$g;M79KSLsMMl-WXDn;_1QHTDXd z?c!;HExrpm_)0u61DV!PbRR%JYWw-pHt%H5QwO&;!A}U2r^slG!2F>D=i5C^Zj057 z^B}a+4ay2(5+7MNOH!WqnpnCM5ky)V%Gq9|Msc7Ko1+OjR3^%3r_Ith-ADwAxlGD4 z^9Mi7&7DUnb{!h_wji&c1u3&p3L#js2M!JTUL5P*ugw_0y6$Wz zseU-57ky0#<&7)j$hvX=LGE7`f<$ND)G=K0UKwryc}3V7j=`DO(O1bNT#&0H2Yh!! zn7&FN&8QnkoXvAOigD2$5z>|;XzM`kkJGV3U93Q3*4M*J=W+SK?rEQQ@pw&6yvrIM zZj%CWEPa8ouM!tiGCc94Yy`$k+Pjr@Jg2~TBL(PT+7HzOAX5s#<@?%>ex|FzFu{Zj z0%tCJ?_#B~UFXUsX1Cpw{rSjbpS9jvto6I`sKu%TzQwEoYd`-yd@qIQkw=LJTtfeE z`T3lW&lnBC0U`Q70E687?9yu2{{h^c?m6xQZ0z25X^+c`wb%^|x`?QvLarV$nHe@d zR|5lo(!siW0P{SEH8gpm29T~ zh8|kTf*NDJYdGmh4mv%wVUsuUur1VTS-Ygd(6FQ4Z2tM$^e2po7u3foVkp=|1@kc! zHBjJ;FJo^c9GDES$qB~GKO?i?ny$}}UE$WjU)Sk=%AGE-X~35>XpTd8Pm2TBDk7G^@x#RSby30>oLf4{J)@8Y}_g0O)WAtzsXwX8_`We z5W_~|86ncnQEs?wr&PP{$m^y#trvmeymd3zEHnX8cM37hm=w81d3KVPOfzUYFndF^ zGxFvQ-m*^j@{cd3*TiL( z47Zj{G*o+h2!2qSWsOOcKXrZAV|^=e!$wt7c_!3d0kF@ zW$8iRcsFbKw0ET0I~;T^-dIISka27Bj6u>ANqArucS@%zcF{Um;nC9Ieps)Vo_?T@ zVXnxz^dc9 zU}OTEG`PlIVH71sa^|QN2Ktz9kY4ofr&G%Hh;~?@vu6tN~S{oAWQ%K0HNHElb+F*>4gmFdVMA=C)&_zdy8h zQN)>@#_BB}TZtTmYg#a=F#tEi%Rb~uZi|b|2t>_l3Z4CcrhG#gvGZ-zZo?U+)NF$L zr(`)^uC^gco^cHgo|=da4zcwo5o_G@uk8BA8Diq90SGZ@)*N1u>vEt;_=rQko!*Q} z@sufEpAuTz4Th%myvrO$fg?v08>Ghwo5@_(&tRSY34$|r8UK6A%I+_n=|01`ji5?# z@%kV{#>tO^(dc!@^7WI%N7wh6I#vTz=xN5!%Of+{r1uXq0f?|{4qW|$yyfh}jdnL|-1km3#s2OQ*E_r9{SRRM zbp+!%7A||>^D_39&?$BM=x%FVl(WgF+`w5|ePP%#)U)E}xuU@6KsGnq@vrn=)ZAWb z4c4);$+yJURQ}8h|7MqiTHjn^oPaRc3^J@vrKP; z$`%sCr1Z3Dugth9rZ+^`%p#7W;8wVe?SSqFAr{Rl&U8>Krmc54IkM<{jCQWNU~8^eoF-8yL&tkP)$g;=VnA%Su9x|&Q2!l=_-XE zuDs)C6f($jPswFfbfIHmQCvr0$z~njRMMt*k(UC_P5A&^i2N3_D7Zx~+p-DsC}F)! z7<1rD3E}8cdVN`i$`cAglq<7;^w6k=xA^2?PI%bE&ut?hLe>oMy9@cd2IM`%nSet} zcYv1Egt<3=?Z<{^o@LL1cMk;9<=sr*C=#GMdrp^%wYvv$s@@UqGbkbc4!PG#MgPs0 zo;J?W(lhsK-c#BWU2{dRF_ZL%n8DY6{^*LTk@+XX(X#shS3lgXV)H&)%+Vr^n87W? zA;P^kK=Hdz*gGcv5Ss+6Abt(N=U_Tjy~kI2$e4Te{!#HJOp!F zr;8H)ZUE}1x(8Q#1$*Ag=8=-YLg5~O*a-)xa3wzfBjOWZ{Ex%jN%;ml>qT!N7MoQ^ z`JZoiM{N#GjaGAZe{(D*Yz_O&UNvNi&GL3yd{1d?r?q_^%jrM8-}43&Mk;ZLn3}L+ z?ZmfH`)V*eOUVf1JHz)Tjn}DG5{vdYS&D4v@pB2$+2bg*Tf3R+=Q#}U&r*jxa8>H!uuKz-hCVLc3MAv^zV=rWX#|jgydNEP4M}RMT7{GwT^X)y zl9WT&Bd?KTuV79@gNJ78_FtwW2y5zNZLX3GG8T%QWjU38fYT<)MxoFZQl+=~2?lVH zfGe-$*}(vCaU&ZjMOAQHm!NFMUvw1i9)Uxcw=fW-C_9&yvo7)_=MPGV^lAhv5ItB0 zq=??g>+{Ti4}SzK8j|XWkIRZ;(GtydzMyZ(5_?sxrEL_&1v`GJ9Zu68_OLNEA_)Le#7KCrrFIGc-Ly*9@}A~2 zS6gvg#wxot57PS-A5Awp+NiZ|u-=#X_St}sFJVgEQ;b&v zxloj=IAa8>HGdYhqxWBdg>Ee%#}k3%Q2 zhwlGbh3Tyh&g?nLs>a6zD>pGB_9lgrz1meN5_su#6J8VvkcD{2d2Y_%(zQ@a5cRyNH;7( z9lfPw37P}Cb^E;W7e}u020hhVw;xdym`_+rIgksWhCJmV7LQ@FEa-@02pQt5@QwAK zayA?cRbL48{M{vq;hH>;IKUTNr3C7WzDel<;6Vd_ki^V!5(1xstBcKdEQdlhn4V0|`$0tt zl&&JBl5dJ3jCMQ-JE}Sld>y#JzpB%1yInN)L2YV`3G+H&c`SnxO6nBX9<#Fzw< zcDxrS3V_1O;xIJ#VCwdaDvwE4YVeq?0=0`r>iMK^+y73&)zk!~xyl0Tx*HScWpYm3 zvXi;rnc=%gJ>PANFsl0+m)XwL{BbFTj-%@Bi)Mu?$;N!oH;_6n-2NLy-CptHArEtM2C%#GG_;VwuaX4E4hA-EQ_7yd>|I??^YZsA= zi3|pahW1Tu>q(#0d+ZpTIe(byrp}+qNZwW2{F{JSnwjPhUt09ScHVt*Qyw~eC(}dE zMcM@s~XWQ(5!&L+_srM;8QP~wugGODAXG2KYb zxjv7k^8fThkps7Rz+08Gt@wavX^BbC)Kt%?nE}Jm*!ZBr-Jpd7@wVCBC8PVgNeQbE z70HigKVZBoO4&E5Lv{Tujy7E9LDFm@IBOUd8>jGU%Gyh zkl*iM=9BsOth_A5W<@VIHsTtyRjonJ+TAGs>qVdbYcN#ytD&Pd!V$XXihkhvZsqG3 zY;Sib<$J9CDvupVvFZ0HJ}GQ%1F!hi35iuYuB8jywFbcqt&?R_S)XNFe6#cwG~CW5 zou7;{pg`C8u1+7B=s21^Hv9SyH@}c2e}K$4IZ3tW-6zXA%)Jit-_so zl2Elr%{EIIo${UxNgHP;(rRLgLgk!f-y!BwaFkuvqYZmx56V(LZO4R3ao&W1n4cW8 zLzz0B^r%~Ell(C?FVxKEnaAXo6+c^BCV7&E)vX>jtuQW>8vLz<_LDMUP$1qPNRnFt zGd!-eR~ooOH>Pprw;5?Fs-a1k70vKM^#Gy|Zr>7FK@ZbhIWR016tDmb6Bf9|mun!h z9!Zud%fDDjO&qe3aK(|h9~&GDpUdIOATzgI4%oQMv@`=`pKE1RW{*wL28P?n(*%u& z3~%JCMkNbX9@?}-1TIgRAxockHF=y?ttX}Uc2jLc!g?u*?mWc~9WFk6>$T$x`piky zESfQbbKP#gf1yzI$sIJMpg;fcD0=GC0;b%JtAr0Erf-&}O+>TUBfQY3WTrZuS|{nz z?xpGT9BApAx>w60V`hi4?d;v88`91)z=6>XWFePDGNAb7>j2UzRd6 z_G7w57g5)-gW#DD$b{7z%?0`HTP5R2ILRECgEsv!r{V|Z14p_X>nsgo0&ZgVmU6)6 zS}iT2QzuM&B}|jOzPSJz!o~$NTrXNk<&BiKZsy25tG{iTSnKYrdr?rVS3yZ2z&t~ zN~}IwB3ELb*bF~{)=6$zl}F7h^nO@4+-QR6XrDa^wFSfFf3ikvAxT195w*01!6Sae zZ7QHj26)a^T+uJ#=9#Vi*NMA}%~pGv>K5wQF-o-22|rG658J2C_+u?>PV{f>vtr8Q zT&GJ4)pAI?oN)nO&XA+SGJ@pLlGpV@*Wp^OhTi^LSIZZ}!DC3r&jGpxG9>>fouB5t zL#HKtx6x1#{dJXJ#BXdXsFF9wILwTAq0xS%=!T#k>wu|KLIEjv~V|2{9x z>kavSjkNziP9KN?6M?cokw*V8N3TK8;mz%K&1D81)R0cclAxceF{xz+!SSZd=L!TW z6;W;8lnT<4l7++K!(W(*8^W%i*)cH@3>z2reb&&z^vvjIZQ0k-{3&}+Yt4*&Po;2< zFu6>2Hw^#(Yq)EuG`?Q(QH?<0qm{0mkTHjd>7(N3Q$EbK`)1_r&jB-#n1z@=>X{4| z#YW2viv@k(?2z?AfD2wv z!>YIb&=gQnbX!|q?eX(Vjt$)QwPbkg8V1~%CcK6X#y`w+M|s}()O# z>D@qOl3r-_KI?W(OR1Cf;{Vwg8!IKkuK`ZV zV!b~S*L8JWKSpzzaRc|3C-Bni$E^f<@MHFFjj<8C*J#a=^-V(SZuw>(rQPl?o4aKB zqScRuVYsPk=iIZtnPKXWjV#!m`$c0HR&qFmAmwQ7VzOi)35OJO?bg0_$$@@@0g_MH+Ub6o-Bz$RNsK%_ zw59xZ8wHk0^SG&`B&s9oid9BXszq5DZw&yQlS(q5^JPuxt7D9)=-P3cbD_kS%74e5 zNJd~l50C3>*){TmeI}7>IRcR`azCR6NRpPqkNXbNnKpw4t9K(^^!s^6clyN|o!lNX z=C8*&FfWO)`5AtIEj_0%F^{<^6HKQ~J`Y8IKw`t)8Jnq|KY7dv748Ii|d9xE0n-cL#{p z12Gj_#~LI#%Cl5QQ8o@vBn8K}Xey<#W5Oov@Nq`JcL##fg27_BUeaA=2+K^dSWA?t zCPIKOIyTbzhbV})-p4GWi#1pv%lH$If`h%kqKct{6f&KAmR_@*`$}#HDFtGYrCXNW z=gu6;e(fN;pxZ{D``mXnVYAf_mA;2MtPlTOVSvx2>c#UVJO8^uBDo3!KyCVb%_}bv zR8DXGw%b2tg5HZh939#XnGI$|uRd2ZZbfoq`f;gB{Bm1<;i!;~Gctqf@r8 zfT9celZNIsp9J12-0BTi#6KHGr6~qi#|%<>Q#JeSA-nY~I+a(q5u7(^8_6-OUzca! z&TL$xw_^^_O{2TdMqpTA$v4jYA-QOC?)qvu_fkZ#4kxrbGVnpW-TB=pI)XY8*flMyK)T(?R*J+evhp#KH!fDX}#sQCQsGzy_jG*B<7@}5l0 zfC7S%E#{JdKAg<+9k(OW4q9yUr<#VH&hNk9%kE*Di_CW``|PhMr>#;!Al>a|F-##E z(>O)GN({cGGHc`6p&1Bd z_GPokGRr^>9}BuIz=9~@OjpPSIzTj!u5IN?SBYmjVzP`!2<&n$B zMx?S{ns}uXEs=dWWs5WKmyOBd0{@VVQt&bJ>8lrQ;S+>8YccZ3`u$fRUmAV1sdI(^ z%Lv>Tnz`iyn}iaoD<}S|%o1)Ra;-jWyKFO^B+sD(8cc#R;j+(k&S$XVV_j*IbC$zL zQraPA2(8cOo+We6tPP=5a4=T7uD z>>SZ6?V}7#w6A$qI}q+X!%B4`LrPhvYtRZvOq@>+N$wv-w5W_vhE?t+DfolFd7Niz6G#uk6M~lRBa##ZvsK2k3?E%FmT@+= z2?bJ{#4JuRQKg6xjDumUuT5i*BiL(-MxB^<@Rzpbk-A6x4-*+xVYZfIWd-An`- z4!@bSZkAwhPeEe9D@I%MlFE0I7yn1mdH=KFzFj=TrnD8cM@tc^_6TCuh!MnWs9H5* z)Tot~8bzBDyNF$aAVw>;evG2pA|h0++I!Wg>iRx;{(=0ESMFT*eVudOhc~{uB{EC2 zYr5y%onhhlQOAxJY}Ch2S>Wy+FY-muld&T{$>Rk<**=vx_hZdRjc(t$5>|^jT1S$9 zIp*yk?Z=9BhK$9-QMmTb+|_liam>Wz%1GaqEW{?75lPx(9?3+U%eiz{cm*tk%+}Bk z%acW>>QwXtSw*9!6(aOg_V0N5H!BU%0Yp~n*47&4YwGyM_*$7sitX8to`&@Z5*fNN zh#;|N+la5tK(5)s8_Qo)7F3*-Uc?6FvT0tLkD*2z?2@Oor0(_9Rp!&t(SXVQ87s=i ztE#W(4CJVj6u8{SlB$++K^Qa1d#eHs+(u^6Kg(Q9Cf0nI+0QP?`Fg|K!1jQOVIR`D zKUQ@WKwo>LxzQkR@PPEW&D#b$Ky)nN94`o!IhzHKXvfIZHHo80{vv7oxgehnS4Lfl zCkuosb)ksL**V2dl9i2W$dQdkR7D^!7A!2bZOyLKO>*Gh_O zAI1C(I-MjlkBH{$-0#+$0>5^J*8YppqK4k#jFCR!buO^T{~(I=wTP?kaeZ}TV4^EV zrYO;m|DULt)xD2Mlv%Zg{b@DRY*Ba(FH2a*TZHkj_C8@p0BYX+9{^3Q36817w8M1* za3rB352A`xN4N_P-LY*C%Igk#YxyEu^(fSS63U5Yi9)gU50f|Yw({;f! zSS2oc{7~$D!q&PHAgg<&1jRr+VT5(3`afCZO}QSaRuvl5nOu7O_S2dpG!51V;j z7NWNjCkg2q4f5F>za_(U^vUP=aH>a!-bSV|n&K%6-pG^DI5c=Gp+q;x;fNPBIj?c( zn{{|eOujzwC%-SfTuwdfz|mtsIIHEe2ocxR3clm9!}S=1K2+e-9k8>6!kf9^|MqLt(;T=bBc* zRIV<4$c+R(u|e6Z?>VU|3J@q7A)3L3v==&_NBGE}mH{CjXrJV=jDAe<;ywvxygfNl zxV~@yhHRl1(V;(5#&N7^>!c`X!Vp<~x=q1LoU_j;ae)?1KFv)RDd>2@{`%D+KRiwp z(dhx><9ZLVeqn7|nh~Q{vbe9ucD()zpaYgHY|+qMX}8T=(E>)=S>JN6by06K_=xw2 z{Z6FX_5!Qj2iZURJRF_3rm&|;rKa~712mx0bT4D3s+LN8dor>(08#icWU435U&wkf zi6KQ8#S~l7V>$+mD~{P=6)H;JMa+wqJPq%M{L66_G(h4;I_+m{jt!zAFHA>m`g_hMx%#%CbxLnjt@5C|uiJvR`@g#!CKq_cDX#7FOkAwnGW*hZ z+IH$7TLSH0_bkhBYC7tMn)^^l2Mu8vf;XCi4(L;uQ>Q~6(Yy>3#T)xQbWtLtW}%;Y zDa5dgZ<1&Gj@LtvFMUh8HmN^Sg>1L_Rv}^;SUE?G-o?Dn2PVfZ=6Y!Tm;JyDnR&C^ zYvd#&8uZnLZqVjcs3_)XVF#^HN_r+80l}`0`rHFU{f*sez0;rDJ!G;EBufotJoAR; z?fgF-{1YhgaQZuo;wsgOMG86yI2gd^#D>wIya9hv`zOo&nAh}JE96#%;GGu-{J?nA z>di44CFo_it2BU9*6yrXTnQa{hPOYwm^d`Yo~qWo>Q`sRShMb$a%!Gd=;q#TWuLdm zT@9D@5h6*8#j51@4cqL(x|sSEx6o`3T5x6y#FCE`UggAa>XMV)nom%SpW+BqnRb~& zQ$*TN%Wp5u#I2{E&=MVChiA#bR#bkpNd$4k?ly6jsB6mS1pgGYLHW?wx~ZEWS&v6g?hr$h?#jAJv> z@AA*bM%Zf)lss?6e7`$~K$*?Tea(xmxuzc|Q2T5ZGs31bHLh}A1k>vLMYYZff;6Dh zaSkR%8q&j`C+ukc!uBuCwMUy8b+p~IOF;4`g(CZzdFkI%CF!&EvP%wuPAMJL{9BQB z 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

H@NXkT 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%0D3Tg)m&o|>6*AX_B5?#EGVojJwD_6C}G**IIx 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

SYS(GoFhW)sQ06We#~0hEN355@N4i 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 uml*F!z&I43pointer = $head->bandjoin($components)->pointer; + $joined = $head->bandjoin($components); + $this->pointer = $joined->pointer; } /** diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 3f39d70..11cd3b9 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -92,7 +92,11 @@ public function setMatch($name, $match_image, $value) { } else if ($gtype == Init::gtypes("VipsArrayImage") && is_array($value)) { - array_map(fn($x) => $match_image->imageize($x), $value); + $new_value = []; + foreach ($value as $x) { + $new_value[] = $match_image->imageize($x); + } + $value = $new_value; } } From be90a10245667b686dac2ca8dd8cad35a497cd5a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 17 Feb 2022 12:30:07 +0000 Subject: [PATCH 38/58] all tests pass --- src/GObject.php | 8 ++++++++ src/GValue.php | 16 ++++++++-------- src/Image.php | 6 ++++++ tests/ShortcutTest.php | 7 +++++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/GObject.php b/src/GObject.php index e3ae97c..f8c2ba0 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -75,6 +75,14 @@ function __construct($pointer) } function __destruct() { + $this->unref(); + } + + function ref() { + Init::ffi()->g_object_ref($this->pointer); + } + + function unref() { Init::ffi()->g_object_unref($this->pointer); } diff --git a/src/GValue.php b/src/GValue.php index 3d4297c..80b8de1 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -158,9 +158,9 @@ function set($value) { $array = Init::ffi()-> vips_value_get_array_image($this->pointer, NULL); for ($i = 0; $i < $n; $i++) { - $pointer = $value[$i]->pointer; - $array[$i] = $pointer; - Init::ffi()->g_object_ref($pointer); + $image = $value[$i]; + $array[$i] = $image->pointer; + $image->ref(); } break; @@ -243,9 +243,9 @@ function get() { case Init::gtypes("VipsImage"): $pointer = Init::ffi()->g_value_get_object($this->pointer); - // get_object does not increment the ref count - Init::ffi()->g_object_ref($pointer); $result = new Image($pointer); + // get_object does not increment the ref count + $result->ref(); break; case Init::gtypes("VipsArrayInt"): @@ -274,9 +274,9 @@ function get() { vips_value_get_array_image($this->pointer, $p_len); $result = []; for ($i = 0; $i < $p_len[0]; $i++) { - $image_pointer = $pointer[$i]; - Init::ffi()->g_object_ref($image_pointer); - $result[] = new Image($image_pointer); + $image = new Image($pointer[$i]); + $image->ref(); + $result[] = $image; } break; diff --git a/src/Image.php b/src/Image.php index 2fc697b..7e57b53 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1525,6 +1525,12 @@ public function offsetSet($offset, $value): void $head = array_shift($components); $joined = $head->bandjoin($components); + + /* Overwrite our pointer with the pointer from the new, joined object. + * We have to adjust the refs, yuk! + */ + $joined->ref(); + $this->unref(); $this->pointer = $joined->pointer; } diff --git a/tests/ShortcutTest.php b/tests/ShortcutTest.php index da251a2..3bbf2fe 100644 --- a/tests/ShortcutTest.php +++ b/tests/ShortcutTest.php @@ -207,6 +207,13 @@ public function testOffsetSet() // replace band with image $test = $image->copy(); $test[1] = $base; + + $avg = $test->avg(); + + exit; + $this->assertEquals($avg, 2.666); + + $this->assertEquals($test->bands, 3); $this->assertEquals($test[0]->avg(), 2); $this->assertEquals($test[1]->avg(), 2); From 401c80ea42f0168ca7431eeac7ffbc97ef8d612d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 17 Feb 2022 12:54:49 +0000 Subject: [PATCH 39/58] fix phpcs warnings --- examples/vips-ffi.php | 905 ----------------------------------- examples/watermark-image.php | 9 +- src/GObject.php | 16 +- src/GValue.php | 400 ++++++++-------- src/Image.php | 61 ++- src/Init.php | 50 +- src/Interpolate.php | 7 +- src/Introspect.php | 15 +- src/VipsObject.php | 43 +- src/VipsOperation.php | 53 +- 10 files changed, 330 insertions(+), 1229 deletions(-) delete mode 100755 examples/vips-ffi.php diff --git a/examples/vips-ffi.php b/examples/vips-ffi.php deleted file mode 100755 index d305a59..0000000 --- a/examples/vips-ffi.php +++ /dev/null @@ -1,905 +0,0 @@ -#!/usr/bin/env php -vips_error_buffer()"); -} - -$result = $base_ffi->vips_init($argv[0]); -if ($result != 0) { - error(); -} -trace("vips_init: $result"); - -# get the library version number, then we can build the API -$library_major = $base_ffi->vips_version(0); -$library_minor = $base_ffi->vips_version(1); -$library_micro = $base_ffi->vips_version(2); -trace("found libvips version: $library_major.$library_minor.$library_micro"); - -function at_least($need_major, $need_minor) -{ - global $library_major, $library_minor; - - return $need_major < $library_major || - ($need_major == $library_major && $need_minor <= $library_minor); -} - -if (!at_least(8, 7)) { - trace("your libvips is too old -- 8.7 or later required"); - exit(1); -} - -if (PHP_INT_SIZE != 8) { - # we could maybe fix this if it's important ... it's mostly necessary since - # GType is the size of a pointer, and there's no easy way to discover if php - # is running on a 32 or 64-bit systems (as far as I can see) - trace("your php only supports 32-bit ints -- 64 bit ints required"); - exit(1); -} - -// bind the libvips API to the library binary - -# largely copied from pyvips -$header = <<"); - exit(1); -} -$filename = $argv[1]; - -trace("attempting to open: $filename"); - -$loader = $ffi->vips_foreign_find_load($filename); -trace("selected loader: $loader"); - -$operation = $ffi->vips_operation_new($loader); -if (FFI::isNull($operation)) { - error(); -} - -// now introspect $operation and show all the args it wants ... about the next -// 250 lines of code - -$vipsObject = $ffi->type("VipsObject*"); -$gObject = $ffi->type("GObject*"); -$description = $ffi->vips_object_get_description( - FFI::cast($vipsObject, $operation)); -trace("description: $description"); - -$operationFlags = [ - "NONE" => 0, - "SEQUENTIAL" => 1, - "NOCACHE" => 4, - "DEPRECATED" => 8 -]; -$flags = $ffi->vips_operation_get_flags($operation); -trace("flags: $flags"); -foreach ($operationFlags as $name => $flag) { - if ($flags & $flag) { - trace(" $name"); - } -} - -$argumentFlags = [ - "REQUIRED" => 1, - "CONSTRUCT" => 2, - "SET_ONCE" => 4, - "SET_ALWAYS" => 8, - "INPUT" => 16, - "OUTPUT" => 32, - "DEPRECATED" => 64, - "MODIFY" => 128 -]; -$p_names = $ffi->new("char**[1]"); -$p_flags = $ffi->new("int*[1]"); -$p_n_args = $ffi->new("int[1]"); -$result = $ffi->vips_object_get_args( - FFI::cast($vipsObject, $operation), - $p_names, - $p_flags, - $p_n_args -); -if ($result != 0) { - error(); -} -$p_names = $p_names[0]; -$p_flags = $p_flags[0]; -$n_args = $p_n_args[0]; - -trace("n_args: $n_args"); - -# make a hash from arg name to flags -$arguments = []; -for ($i = 0; $i < $n_args; $i++) { - if (($p_flags[$i] & $argumentFlags["CONSTRUCT"]) != 0) { - # libvips uses '-' to separate parts of arg names, but we - # need '_' for php - $name = FFI::string($p_names[$i]); - $name = str_replace("-", "_", $name); - $arguments[$name] = $p_flags[$i]; - } -} - -// get the pspec for a property from a VipsObject -// NULL for no such name -function get_pspec($object, $name) { - global $ffi; - global $vipsObject; - - $pspec = $ffi->new("GParamSpec*[1]"); - $argument_class = $ffi->new("VipsArgumentClass*[1]"); - $argument_instance = $ffi->new("VipsArgumentInstance*[1]"); - $result = $ffi->vips_object_get_argument( - FFI::cast($vipsObject, $object), - $name, - $pspec, - $argument_class, - $argument_instance - ); - - if ($result != 0) { - return FFI::NULL; - } - else { - return $pspec[0]; - } -} - -// get the type of a property from a VipsObject -// 0 if no such property -function get_typeof($object, $name) { - global $base_ffi; - - $pspec = get_pspec($object, $name); - if (FFI::isNULL($pspec)) { - # need to clear any error, this is horrible - $base_ffi->vips_error_clear(); - return 0; - } - else { - return $pspec->value_type; - } -} - -function get_blurb($object, $name) { - global $ffi; - - $pspec = get_pspec($object, $name); - return $ffi->g_param_spec_get_blurb($pspec); -} - -# make a hash from arg name to detailed arg info -$details = []; -foreach ($arguments as $name => $flags) { - $details[$name] = [ - "name" => $name, - "flags" => $flags, - "blurb" => get_blurb($operation, $name), - "type" => get_typeof($operation, $name) - ]; -} - -# split args into categories -$required_input = []; -$optional_input = []; -$required_output = []; -$optional_output = []; - -foreach ($details as $name => $detail) { - $flags = $detail["flags"]; - $blurb = $detail["blurb"]; - $type = $detail["type"]; - $typeName = $ffi->g_type_name($type); - - if (($flags & $argumentFlags["INPUT"]) && - ($flags & $argumentFlags["REQUIRED"]) && - !($flags & $argumentFlags["DEPRECATED"])) { - $required_input[] = $name; - - # required inputs which we MODIFY are also required outputs - if ($flags & $argumentFlags["MODIFY"]) { - $required_output[] = $name; - } - } - - if (($flags & $argumentFlags["OUTPUT"]) && - ($flags & $argumentFlags["REQUIRED"]) && - !($flags & $argumentFlags["DEPRECATED"])) { - $required_output[] = $name; - } - - # we let deprecated optional args through, but warn about them - # if they get used, see below - if (($flags & $argumentFlags["INPUT"]) && - !($flags & $argumentFlags["REQUIRED"])) { - $optional_input[] = $name; - } - - if (($flags & $argumentFlags["OUTPUT"]) && - !($flags & $argumentFlags["REQUIRED"])) { - $optional_output[] = $name; - } -} - -# find the first required input image arg, if any ... that will be self -$imageType = $ffi->g_type_from_name("VipsImage"); -$member_x = null; -foreach ($required_input as $name) { - $type = $details[$name]["type"]; - if ($type == $imageType) { - $member_x = $name; - break; - } -} - -# method args are required args, but without the image they are a -# method on -$method_args = $required_input; -if ($member_x != null) { - $index = array_search($member_x, $method_args); - array_splice($method_args, $index); -} - -# print! -foreach ($details as $name => $detail) { - $flags = $detail["flags"]; - $blurb = $detail["blurb"]; - $type = $detail["type"]; - $typeName = $ffi->g_type_name($type); - - trace(" $name:"); - - trace(" flags: $flags"); - foreach ($argumentFlags as $name => $flag) { - if ($flags & $flag) { - trace(" $name"); - } - } - - trace(" blurb: $blurb"); - trace(" type: $typeName"); -} - -$info = implode(", ", $required_input); -trace("required input: $info"); -$info = implode(", ", $required_output); -trace("required output: $info"); -$info = implode(", ", $optional_input); -trace("optional input: $info"); -$info = implode(", ", $optional_output); -trace("optional output: $info"); -trace("member_x: $member_x"); -$info = implode(", ", $method_args); -trace("method args: $info"); - -// look these up in advance -$gtypes = [ - "gboolean" => $ffi->g_type_from_name("gboolean"), - "gchararray" => $ffi->g_type_from_name("gchararray"), - "VipsRefString" => $ffi->g_type_from_name("VipsRefString"), - "GObject" => $ffi->g_type_from_name("GObject"), -]; - -// a tiny class to wrap GValue ... we need to be able to trigger g_value_unset -// when we are done with one of these, so we need to make a class - -class GValue -{ - private FFI\CData $struct; - public FFI\CData $pointer; - - function __construct() { - global $ffi; - - # allocate a gvalue on the heap, and make it persistent between requests - $this->struct = $ffi->new("GValue", true, true); - $this->pointer = FFI::addr($this->struct); - - # GValue needs to be inited to all zero - FFI::memset($this->pointer, 0, FFI::sizeof($this->struct)); - } - - function __destruct() { - global $ffi; - - $ffi->g_value_unset($this->pointer); - } - - function set_type(int $gtype) { - global $ffi; - - $ffi->g_value_init($this->pointer, $gtype); - } - - function get_type(): int { - return $this->pointer->g_type; - } - - function set($value) { - global $ffi, $gtypes; - - $gtype = $this->get_type(); - - switch ($gtype) { - case $gtypes["gboolean"]: - $ffi->g_value_set_boolean($this->pointer, $value); - break; - - case $gtypes["gchararray"]: - $ffi->g_value_set_string($this->pointer, $value); - break; - - case $gtypes["VipsRefString"]: - $ffi->vips_value_set_ref_string($this->pointer, $value); - break; - - default: - $fundamental = $ffi->g_type_fundamental($gtype); - switch ($fundamental) { - case $gtypes["GObject"]: - break; - - default: - trace("GValue::set(): gtype $gtype not implemented"); - exit(1); - } - } - } - - function get() { - global $ffi, $gtypes; - - $gtype = $this->get_type(); - $result = null; - - switch ($gtype) { - case $gtypes["gboolean"]: - $result = $ffi->g_value_get_boolean($this->pointer); - break; - - case $gtypes["gchararray"]: - $ffi->g_value_get_string($this->pointer); - break; - - case $gtypes["VipsRefString"]: - $psize = $ffi->new("size_t*"); - $result = $ffi->vips_value_get_ref_string($this->pointer, $psize); - # $psize[0] will be the string length, but assume it's null terminated - break; - - default: - $fundamental = $ffi->g_type_fundamental($gtype); - switch ($fundamental) { - case $gtypes["GObject"]: - # we need a class wrapping gobject before we can impement this - trace("in get() get object"); - break; - - default: - trace("GValue::get(): gtype $gtype not implemented"); - exit(1); - } - } - - return $result; - } - -} - -function gobject_set($object, $name, $value) { - global $ffi; - global $gObject; - - $gtype = get_typeof($object, $name); - - $gvalue = new GValue(); - $gvalue->set_type($gtype); - $gvalue->set($value); - - $gobject = FFI::cast($gObject, $object); - $ffi->g_object_set_property($gobject, $name, $gvalue->pointer); -} - -function gobject_get($object, $name) { - global $ffi; - global $gObject; - - $gtype = get_typeof($object, $name); - - $gvalue = new GValue(); - $gvalue->set_type($gtype); - - $gobject = FFI::cast($gObject, $object); - $ffi->g_object_get_property($gobject, $name, $gvalue->pointer); - - return $gvalue->get(); -} - -// now use the info from introspection to set some parameters on $operation - -trace("setting arguments ..."); -gobject_set($operation, "filename", $filename); - -// build the operation - -trace("building ..."); -$new_operation = $ffi->vips_cache_operation_build($operation); -if (FFI::isNull($new_operation)) { - $ffi->vips_object_unref_outputs($operation); - error(); -} -$operation = $new_operation; - -# need to attach input refs to output - -// fetch required output args - -$image = gobject_get($operation, "out"); -trace("result: " . print_r($image, true)); - -trace("shutting down ..."); -$base_ffi->vips_shutdown(); diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 91abdef..9e5a9f6 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -6,7 +6,7 @@ #Vips\Config::setLogger(new Vips\DebugLogger()); -if(count($argv) != 4) { +if (count($argv) != 4) { echo("usage: ./watermark.php input-image output-image watermark-image\n"); exit(1); } @@ -17,8 +17,8 @@ // we'll read the watermark image many times, so we need random access for this $watermark = Vips\Image::newFromFile($argv[3]); -// the watermark image needs to have an alpha channel -if(!$watermark->hasAlpha() || $watermark->bands != 4) { +// the watermark image needs to have an alpha channel +if (!$watermark->hasAlpha() || $watermark->bands != 4) { echo("watermark image is not RGBA\n"); exit(1); } @@ -29,7 +29,8 @@ // repeat the watermark to the size of the image $watermark = $watermark->replicate( 1 + $image->width / $watermark->width, - 1 + $image->height / $watermark->height); + 1 + $image->height / $watermark->height +); $watermark = $watermark->crop(0, 0, $image->width, $image->height); // composite the watermark over the main image diff --git a/src/GObject.php b/src/GObject.php index f8c2ba0..f7c8790 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -48,7 +48,7 @@ * @license https://opensource.org/licenses/MIT MIT * @link https://github.com/libvips/php-vips */ -abstract class GObject +abstract class GObject { /** * A pointer to the underlying GObject. @@ -64,30 +64,32 @@ abstract class GObject * Don't call this yourself, users should stick to (for example) * Image::newFromFile(). * - * @param FFI\CData $pointer The underlying pointer that this + * @param FFI\CData $pointer The underlying pointer that this * object should wrap. * * @internal */ - function __construct($pointer) + public function __construct($pointer) { $this->pointer = \FFI::cast(Init::ctypes("GObject"), $pointer); } - function __destruct() { + public function __destruct() + { $this->unref(); } - function ref() { + public function ref() + { Init::ffi()->g_object_ref($this->pointer); } - function unref() { + public function unref() + { Init::ffi()->g_object_unref($this->pointer); } // TODO signal marshalling to go in - } /* diff --git a/src/GValue.php b/src/GValue.php index 80b8de1..a6f8af3 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -43,7 +43,8 @@ class GValue private \FFI\CData $struct; public \FFI\CData $pointer; - function __construct() { + public function __construct() + { # allocate a gvalue on the heap, and make it persistent between requests $this->struct = Init::ffi()->new("GValue", true, true); $this->pointer = \FFI::addr($this->struct); @@ -54,22 +55,23 @@ function __construct() { /* Turn a string into an enum value, if possible */ - static function toEnum($gtype, $value) { + public static function toEnum($gtype, $value) + { if (is_string($value)) { $enum_value = Init::ffi()-> vips_enum_from_nick("php-vips", $gtype, $value); if ($enum_value < 0) { Init::error(); } - } - else { + } else { $enum_value = $value; } return $enum_value; } - static function fromEnum($gtype, $value) { + public static function fromEnum($gtype, $value) + { $result = Init::ffi()->vips_enum_nick($gtype, $value); if ($result === null) { Init::error("value not in enum"); @@ -78,234 +80,246 @@ static function fromEnum($gtype, $value) { return $result; } - function __destruct() { + public function __destruct() + { Init::ffi()->g_value_unset($this->pointer); } - function setType(int $gtype) { + public function setType(int $gtype) + { Init::ffi()->g_value_init($this->pointer, $gtype); } - function getType(): int { + public function getType(): int + { return $this->pointer->g_type; } - function set($value) { + public function set($value) + { $gtype = $this->getType(); switch ($gtype) { - case Init::gtypes("gboolean"): - Init::ffi()->g_value_set_boolean($this->pointer, $value); - break; - - case Init::gtypes("gint"): - Init::ffi()->g_value_set_int($this->pointer, $value); - break; + case Init::gtypes("gboolean"): + Init::ffi()->g_value_set_boolean($this->pointer, $value); + break; - case Init::gtypes("gint64"): - Init::ffi()->g_value_set_int64($this->pointer, $value); - break; + case Init::gtypes("gint"): + Init::ffi()->g_value_set_int($this->pointer, $value); + break; - case Init::gtypes("guint64"): - Init::ffi()->g_value_set_uint64($this->pointer, $value); - break; + case Init::gtypes("gint64"): + Init::ffi()->g_value_set_int64($this->pointer, $value); + break; - case Init::gtypes("gdouble"): - Init::ffi()->g_value_set_double($this->pointer, $value); - break; + case Init::gtypes("guint64"): + Init::ffi()->g_value_set_uint64($this->pointer, $value); + break; - case Init::gtypes("gchararray"): - Init::ffi()->g_value_set_string($this->pointer, $value); - break; + case Init::gtypes("gdouble"): + Init::ffi()->g_value_set_double($this->pointer, $value); + break; - case Init::gtypes("VipsRefString"): - Init::ffi()->vips_value_set_ref_string($this->pointer, $value); - break; + case Init::gtypes("gchararray"): + Init::ffi()->g_value_set_string($this->pointer, $value); + break; - case Init::gtypes("VipsArrayInt"): - if (!is_array($value)) { - $value = [$value]; - } - $n = count($value); - $ctype = \FFI::arrayType(\FFI::type("int"), [$n]); - $array = \FFI::new($ctype); - for ($i = 0; $i < $n; $i++) { - $array[$i] = $value[$i]; - } - Init::ffi()->vips_value_set_array_int($this->pointer, $array, $n); - break; + case Init::gtypes("VipsRefString"): + Init::ffi()->vips_value_set_ref_string($this->pointer, $value); + break; - case Init::gtypes("VipsArrayDouble"): - if (!is_array($value)) { - $value = [$value]; - } - $n = count($value); - $ctype = \FFI::arrayType(\FFI::type("double"), [$n]); - $array = \FFI::new($ctype); - for ($i = 0; $i < $n; $i++) { - $array[$i] = $value[$i]; - } - Init::ffi()-> - vips_value_set_array_double($this->pointer, $array, $n); - break; + case Init::gtypes("VipsArrayInt"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + $ctype = \FFI::arrayType(\FFI::type("int"), [$n]); + $array = \FFI::new($ctype); + for ($i = 0; $i < $n; $i++) { + $array[$i] = $value[$i]; + } + Init::ffi()-> + vips_value_set_array_int($this->pointer, $array, $n); + break; - case Init::gtypes("VipsArrayImage"): - if (!is_array($value)) { - $value = [$value]; - } - $n = count($value); - Init::ffi()->vips_value_set_array_image($this->pointer, $n); - $array = Init::ffi()-> - vips_value_get_array_image($this->pointer, NULL); - for ($i = 0; $i < $n; $i++) { - $image = $value[$i]; - $array[$i] = $image->pointer; - $image->ref(); - } - break; - - case Init::gtypes("VipsBlob"): - # we need to set the blob to a copy of the data that vips_lib - # can own and free - $n = strlen($value); - $ctype = \FFI::arrayType(\FFI::type("char"), [$n]); - $memory = \FFI::new($ctype, false, true); - for ($i = 0; $i < $n; $i++) { - $memory[$i] = $value[$i]; - } - Init::ffi()-> - vips_value_set_blob_free($this->pointer, $memory, $n); - break; - - default: - $fundamental = Init::ffi()->g_type_fundamental($gtype); - switch ($fundamental) { - case Init::gtypes("GObject"): + case Init::gtypes("VipsArrayDouble"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + $ctype = \FFI::arrayType(\FFI::type("double"), [$n]); + $array = \FFI::new($ctype); + for ($i = 0; $i < $n; $i++) { + $array[$i] = $value[$i]; + } Init::ffi()-> - g_value_set_object($this->pointer, $value->pointer); + vips_value_set_array_double($this->pointer, $array, $n); break; - case Init::gtypes("GEnum"): - Init::ffi()->g_value_set_enum($this->pointer, - self::toEnum($gtype, $value)); + case Init::gtypes("VipsArrayImage"): + if (!is_array($value)) { + $value = [$value]; + } + $n = count($value); + Init::ffi()->vips_value_set_array_image($this->pointer, $n); + $array = Init::ffi()-> + vips_value_get_array_image($this->pointer, null); + for ($i = 0; $i < $n; $i++) { + $image = $value[$i]; + $array[$i] = $image->pointer; + $image->ref(); + } break; - case Init::gtypes("GFlags"): - /* Just set as int. - */ - Init::ffi()->g_value_set_flags($this->pointer, $value); + case Init::gtypes("VipsBlob"): + # we need to set the blob to a copy of the data that vips_lib + # can own and free + $n = strlen($value); + $ctype = \FFI::arrayType(\FFI::type("char"), [$n]); + $memory = \FFI::new($ctype, false, true); + for ($i = 0; $i < $n; $i++) { + $memory[$i] = $value[$i]; + } + Init::ffi()-> + vips_value_set_blob_free($this->pointer, $memory, $n); break; default: - $typeName = Init::ffi()->g_type_name($gtype); - throw new \BadMethodCallException("gtype $gtype not implemented"); - break; - } + $fundamental = Init::ffi()->g_type_fundamental($gtype); + switch ($fundamental) { + case Init::gtypes("GObject"): + Init::ffi()-> + g_value_set_object($this->pointer, $value->pointer); + break; + + case Init::gtypes("GEnum"): + Init::ffi()->g_value_set_enum( + $this->pointer, + self::toEnum($gtype, $value) + ); + break; + + case Init::gtypes("GFlags"): + /* Just set as int. + */ + Init::ffi()->g_value_set_flags($this->pointer, $value); + break; + + default: + $typeName = Init::ffi()->g_type_name($gtype); + throw new \BadMethodCallException( + "gtype $typeName ($gtype) not implemented" + ); + break; + } } } - function get() { + public function get() + { $gtype = $this->getType(); $result = null; switch ($gtype) { - case Init::gtypes("gboolean"): - $result = Init::ffi()->g_value_get_boolean($this->pointer); - break; - - case Init::gtypes("gint"): - $result = Init::ffi()->g_value_get_int($this->pointer); - break; - - case Init::gtypes("gint64"): - $result = Init::ffi()->g_value_get_int64($this->pointer); - break; - - case Init::gtypes("guint64"): - $result = Init::ffi()->g_value_get_uint64($this->pointer); - break; - - case Init::gtypes("gdouble"): - $result = Init::ffi()->g_value_get_double($this->pointer); - break; - - case Init::gtypes("gchararray"): - $result = Init::ffi()->g_value_get_string($this->pointer); - break; - - case Init::gtypes("VipsRefString"): - $p_size = Init::ffi()->new("size_t[1]"); - $result = Init::ffi()-> - vips_value_get_ref_string($this->pointer, $p_size); - # $p_size[0] will be the string length, but assume it's null - # terminated - break; - - case Init::gtypes("VipsImage"): - $pointer = Init::ffi()->g_value_get_object($this->pointer); - $result = new Image($pointer); - // get_object does not increment the ref count - $result->ref(); - break; - - case Init::gtypes("VipsArrayInt"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> - vips_value_get_array_int($this->pointer, $p_len); - $result = []; - for ($i = 0; $i < $p_len[0]; $i++) { - $result[] = $pointer[$i]; - } - break; - - case Init::gtypes("VipsArrayDouble"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> - vips_value_get_array_double($this->pointer, $p_len); - $result = []; - for ($i = 0; $i < $p_len[0]; $i++) { - $result[] = $pointer[$i]; - } - break; - - case Init::gtypes("VipsArrayImage"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> - vips_value_get_array_image($this->pointer, $p_len); - $result = []; - for ($i = 0; $i < $p_len[0]; $i++) { - $image = new Image($pointer[$i]); - $image->ref(); - $result[] = $image; - } - break; - - case Init::gtypes("VipsBlob"): - $p_len = Init::ffi()->new("size_t[1]"); - $pointer = Init::ffi()-> - vips_value_get_blob($this->pointer, $p_len); - $result = \FFI::string($pointer, $p_len[0]); - break; - - default: - $fundamental = Init::ffi()->g_type_fundamental($gtype); - switch ($fundamental) { - case Init::gtypes("GEnum"): - $result = Init::ffi()->g_value_get_enum($this->pointer); - $result = self::fromEnum($gtype, $result); + case Init::gtypes("gboolean"): + $result = Init::ffi()->g_value_get_boolean($this->pointer); break; - case Init::gtypes("GFlags"): - /* Just get as int. - */ - $result = Init::ffi()->g_value_get_flags($this->pointer); + case Init::gtypes("gint"): + $result = Init::ffi()->g_value_get_int($this->pointer); break; - default: - $typeName = Init::ffi()->g_type_name($gtype); - throw new \BadMethodCallException("$typeName not implemented"); + case Init::gtypes("gint64"): + $result = Init::ffi()->g_value_get_int64($this->pointer); break; - } + + case Init::gtypes("guint64"): + $result = Init::ffi()->g_value_get_uint64($this->pointer); + break; + + case Init::gtypes("gdouble"): + $result = Init::ffi()->g_value_get_double($this->pointer); + break; + + case Init::gtypes("gchararray"): + $result = Init::ffi()->g_value_get_string($this->pointer); + break; + + case Init::gtypes("VipsRefString"): + $p_size = Init::ffi()->new("size_t[1]"); + $result = Init::ffi()-> + vips_value_get_ref_string($this->pointer, $p_size); + # $p_size[0] will be the string length, but assume it's null + # terminated + break; + + case Init::gtypes("VipsImage"): + $pointer = Init::ffi()->g_value_get_object($this->pointer); + $result = new Image($pointer); + // get_object does not increment the ref count + $result->ref(); + break; + + case Init::gtypes("VipsArrayInt"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_int($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $result[] = $pointer[$i]; + } + break; + + case Init::gtypes("VipsArrayDouble"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_double($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $result[] = $pointer[$i]; + } + break; + + case Init::gtypes("VipsArrayImage"): + $p_len = Init::ffi()->new("int[1]"); + $pointer = Init::ffi()-> + vips_value_get_array_image($this->pointer, $p_len); + $result = []; + for ($i = 0; $i < $p_len[0]; $i++) { + $image = new Image($pointer[$i]); + $image->ref(); + $result[] = $image; + } + break; + + case Init::gtypes("VipsBlob"): + $p_len = Init::ffi()->new("size_t[1]"); + $pointer = Init::ffi()-> + vips_value_get_blob($this->pointer, $p_len); + $result = \FFI::string($pointer, $p_len[0]); + break; + + default: + $fundamental = Init::ffi()->g_type_fundamental($gtype); + switch ($fundamental) { + case Init::gtypes("GEnum"): + $result = Init::ffi()->g_value_get_enum($this->pointer); + $result = self::fromEnum($gtype, $result); + break; + + case Init::gtypes("GFlags"): + /* Just get as int. + */ + $result = Init::ffi()->g_value_get_flags($this->pointer); + break; + + default: + $typeName = Init::ffi()->g_type_name($gtype); + throw new \BadMethodCallException( + "gtype $typeName ($gtype) not implemented" + ); + break; + } } return $result; diff --git a/src/Image.php b/src/Image.php index 7e57b53..876d074 100644 --- a/src/Image.php +++ b/src/Image.php @@ -581,7 +581,7 @@ class Image extends ImageAutodoc implements \ArrayAccess * * @internal */ - public \FFI\CData $pointer; + public \FFI\CData $pointer; /** * Wrap an Image around an underlying CData pointer. @@ -683,13 +683,11 @@ public function imageize($value): Image { if ($value instanceof Image) { return $value; - } - else if (self::is2D($value)) { + } elseif (self::is2D($value)) { return self::newFromArray($value); - } - else { + } else { return $this->newFromImage($value); - } + } } /** @@ -793,8 +791,8 @@ public static function newFromFile( 'arguments' => [$name, $options] ]); - $filename = Init::filename_get_filename($name); - $string_options = Init::filename_get_options($name); + $filename = Init::filenameGetFilename($name); + $string_options = Init::filenameGetOptions($name); $loader = Init::ffi()->vips_foreign_find_load($filename); if ($loader == "") { @@ -890,8 +888,8 @@ public static function newFromArray( $n = $width * $height; $ctype = \FFI::arrayType(\FFI::type("double"), [$n]); $a = \FFI::new($ctype, true, true); - for($y = 0; $y < $height; $y++) { - for($x = 0; $x < $width; $x++) { + for ($y = 0; $y < $height; $y++) { + for ($x = 0; $x < $width; $x++) { $a[$x + $y * $width] = $array[$y][$x]; } } @@ -937,11 +935,11 @@ public static function newFromMemory( ]); $pointer = Init::ffi()->vips_image_new_from_memory( - $data, - strlen($data), - $width, - $height, - $bands, + $data, + strlen($data), + $width, + $height, + $bands, $format ); if ($pointer == null) { @@ -1028,8 +1026,8 @@ public function writeToFile(string $name, array $options = []): void 'options' => $options ]); - $filename = Init::filename_get_filename($name); - $string_options = Init::filename_get_options($name); + $filename = Init::filenameGetFilename($name); + $string_options = Init::filenameGetOptions($name); $saver = Init::ffi()->vips_foreign_find_save($filename); if ($saver == "") { @@ -1069,8 +1067,8 @@ public function writeToBuffer(string $suffix, array $options = []): string 'arguments' => [$suffix, $options] ]); - $filename = Init::filename_get_filename($suffix); - $string_options = Init::filename_get_options($suffix); + $filename = Init::filenameGetFilename($suffix); + $string_options = Init::filenameGetOptions($suffix); $saver = Init::ffi()->vips_foreign_find_save_buffer($filename); if ($saver == "") { @@ -1113,7 +1111,7 @@ public function writeToMemory(): string Init::error(); } - $result = \FFI::string($pointer, $p_size[0]); + $result = \FFI::string($pointer, $p_size[0]); Utils::debugLog('writeToMemory', ['result' => $result]); @@ -1307,24 +1305,18 @@ public function set(string $name, $value): void if (is_array($value)) { if (is_int($value[0])) { $gtype = Init::gtypes("VipsArrayInt"); - } - else if (is_float($value[0])) { + } elseif (is_float($value[0])) { $gtype = Init::gtypes("VipsArrayDouble"); - } - else { + } else { $gtype = Init::gtypes("VipsArrayImage"); } - } - else if (is_int($value)) { + } elseif (is_int($value)) { $gtype = Init::gtypes("gint"); - } - else if (is_float($value)) { + } elseif (is_float($value)) { $gtype = Init::gtypes("gdouble"); - } - else if (is_string($value)) { + } elseif (is_string($value)) { $gtype = Init::gtypes("VipsRefString"); - } - else { + } else { $gtype = Init::gtypes("VipsImage"); } } @@ -1463,7 +1455,7 @@ public function offsetExists($offset): bool */ public function offsetGet($offset): ?Image { - return $this->offsetExists($offset) ? + return $this->offsetExists($offset) ? $this->extract_band($offset) : null; } @@ -1994,7 +1986,8 @@ public function composite($other, $mode, array $options = []): Image $mode = array_map( // Use BlendMode::OVER if a non-existent value is given. fn($x) => self::$blendModeToInt[$x] ?? BlendMode::OVER, - $mode); + $mode + ); return VipsOperation::call( 'composite', diff --git a/src/Init.php b/src/Init.php index 8053488..eb81ec1 100644 --- a/src/Init.php +++ b/src/Init.php @@ -79,8 +79,8 @@ public static function getInit() static $instance; if (!$instance) { - $instance = new Init(); - $instance->init(); + $instance = new Init(); + $instance->init(); } return $instance; @@ -121,7 +121,7 @@ public static function error(string $message = "") throw $exception; } - public static function filename_get_filename($name) + public static function filenameGetFilename($name) { $pointer = Init::ffi()->vips_filename_get_filename($name); $filename = \FFI::string($pointer); @@ -130,7 +130,7 @@ public static function filename_get_filename($name) return $filename; } - public static function filename_get_options($name) + public static function filenameGetOptions($name) { $pointer = Init::ffi()->vips_filename_get_options($name); $options = \FFI::string($pointer); @@ -145,8 +145,8 @@ public function __construct() public function atLeast($need_major, $need_minor) { - return $need_major < $this->library_major || - ($need_major == $this->library_major && + return $need_major < $this->library_major || + ($need_major == $this->library_major && $need_minor <= $this->library_minor); } @@ -154,25 +154,24 @@ private function init() { $library_name = "libvips"; - switch(PHP_OS_FAMILY) { - case "Windows": - $library_ext = ".dll"; - break; + switch (PHP_OS_FAMILY) { + case "Windows": + $library_ext = ".dll"; + break; - case "OSX": - $library_ext = ".dylib"; - break; + case "OSX": + $library_ext = ".dylib"; + break; - default; - $library_ext = ".so"; - break; + default: + $library_ext = ".so"; + break; } $vipshome = getenv("VIPSHOME"); if ($vipshome) { $library_location = $vipshome . "/lib/"; - } - else { + } else { # rely on ffi's search $library_location = ""; } @@ -180,7 +179,7 @@ private function init() $library = "$library_location$library_name$library_ext"; Utils::debugLog("init", ["libray" => $library]); - // TODO put a try/catch around this and generate a helpful message + // TODO put a try/catch around this and generate a helpful message // since this is likely to be the main failure point $ffi = \FFI::cdef(<<ffi = \FFI::cdef($header, $library); + $this->ffi = \FFI::cdef($header, $library); // look these up in advance $this->ctypes = [ @@ -666,7 +665,7 @@ private function init() "VipsBandFormat" => $this->ffi->g_type_from_name("VipsBandFormat"), "VipsBlendMode" => $this->ffi->g_type_from_name("VipsBlendMode"), "VipsArrayInt" => $this->ffi->g_type_from_name("VipsArrayInt"), - "VipsArrayDouble" => + "VipsArrayDouble" => $this->ffi->g_type_from_name("VipsArrayDouble"), "VipsArrayImage" => $this->ffi->g_type_from_name("VipsArrayImage"), "VipsBlob" => $this->ffi->g_type_from_name("VipsBlob"), @@ -678,4 +677,3 @@ private function init() Utils::debugLog("init", ["done"]); } } - diff --git a/src/Interpolate.php b/src/Interpolate.php index 72fefa2..703f3d3 100644 --- a/src/Interpolate.php +++ b/src/Interpolate.php @@ -39,8 +39,8 @@ namespace Jcupitt\Vips; /** - * This class holds a pointer to a VipsInterpolate (the libvips - * base class for interpolators) and manages argument introspection and + * This class holds a pointer to a VipsInterpolate (the libvips + * base class for interpolators) and manages argument introspection and * operation call. * * @category Images @@ -60,7 +60,7 @@ class Interpolate extends VipsObject */ public \FFI\CData $pointer; - function __construct($pointer) + public function __construct($pointer) { $this->pointer = Init::ffi()-> cast(Init::ctypes("VipsInterpolate"), $pointer); @@ -96,7 +96,6 @@ public static function newFromName($name) return new Interpolate($pointer); } - } /* diff --git a/src/Introspect.php b/src/Introspect.php index 679965f..ee48caf 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -80,7 +80,7 @@ class Introspect public array $required_output; public array $optional_output; - /** + /** * The name of the arg this operation uses as "this". */ public string $member_this; @@ -90,7 +90,7 @@ class Introspect */ public array $method_args; - function __construct($name) + public function __construct($name) { $this->name = $name; @@ -104,8 +104,8 @@ function __construct($name) $p_n_args = Init::ffi()->new("int[1]"); $result = Init::ffi()->vips_object_get_args( \FFI::cast(Init::ctypes("VipsObject"), $operation->pointer), - $p_names, - $p_flags, + $p_names, + $p_flags, $p_n_args ); if ($result != 0) { @@ -166,14 +166,14 @@ function __construct($name) !($flags & ArgumentFlags::DEPRECATED)) { $this->required_output[] = $name; } - + # we let deprecated optional args through, but warn about them # if they get used, see below if (($flags & ArgumentFlags::INPUT) && !($flags & ArgumentFlags::REQUIRED)) { $this->optional_input[] = $name; } - + if (($flags & ArgumentFlags::OUTPUT) && !($flags & ArgumentFlags::REQUIRED)) { $this->optional_output[] = $name; @@ -201,7 +201,8 @@ function __construct($name) Utils::debugLog($name, ['introspect' => strval($this)]); } - public function __toString() { + public function __toString() + { $result = ""; $result .= "$this->name:\n"; diff --git a/src/VipsObject.php b/src/VipsObject.php index f4ee011..6d8196e 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -39,7 +39,7 @@ namespace Jcupitt\Vips; /** - * This class holds a pointer to a VipsObject (the libvips base class) and + * This class holds a pointer to a VipsObject (the libvips base class) and * manages properties. * * @category Images @@ -66,7 +66,7 @@ abstract class VipsObject extends GObject */ private \FFI\CData $gObject; - function __construct($pointer) + public function __construct($pointer) { $this->pointer = Init::ffi()-> cast(Init::ctypes("VipsObject"), $pointer); @@ -77,63 +77,68 @@ function __construct($pointer) } // print a table of all active vipsobjects ... handy for debugging - static function printAll() { + public static function printAll() + { Init::ffi()->vips_object_print_all(); } - function getDescription() { + public function getDescription() + { return Init::ffi()->vips_object_get_description($this->pointer); } - // get the pspec for a property + // get the pspec for a property // NULL for no such name // very slow! avoid if possible // FIXME add a cache for this thing - function getPspec(string $name) { + public function getPspec(string $name) + { $pspec = Init::ffi()->new("GParamSpec*[1]"); $argument_class = Init::ffi()->new("VipsArgumentClass*[1]"); $argument_instance = Init::ffi()->new("VipsArgumentInstance*[1]"); $result = Init::ffi()->vips_object_get_argument( $this->pointer, $name, - $pspec, + $pspec, $argument_class, $argument_instance ); if ($result != 0) { return null; - } - else { + } else { return $pspec[0]; } } // get the type of a property from a VipsObject // 0 if no such property - function getType(string $name) { + public function getType(string $name) + { $pspec = $this->getPspec($name); if (\FFI::isNull($pspec)) { # need to clear any error, this is horrible Init::ffi()->vips_error_clear(); return 0; - } - else { + } else { return $pspec->value_type; } } - function getBlurb(string $name): string { + public function getBlurb(string $name): string + { $pspec = $this->getPspec($name); return Init::ffi()->g_param_spec_get_blurb($pspec); } - function getArgumentDescription(string $name): string { + public function getArgumentDescription(string $name): string + { $pspec = $this->getPspec($name); return Init::ffi()->g_param_spec_get_description($pspec); } - function get(string $name) { + public function get(string $name) + { $gvalue = new GValue(); $gvalue->setType($this->getType($name)); @@ -146,7 +151,8 @@ function get(string $name) { return $value; } - function set(string $name, $value) { + public function set(string $name, $value) + { Utils::debugLog("set", [$name => $value]); $gvalue = new GValue(); @@ -157,14 +163,15 @@ function set(string $name, $value) { g_object_set_property($this->gObject, $name, $gvalue->pointer); } - function setString(string $string_options) { + public function setString(string $string_options) + { $result = Init::ffi()-> vips_object_set_from_string($this->pointer, $string_options); return $result == 0; } - function unrefOutputs() + public function unrefOutputs() { Init::ffi()->vips_object_unref_outputs($this->pointer); } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 11cd3b9..d29b06b 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -39,7 +39,7 @@ namespace Jcupitt\Vips; /** - * This class holds a pointer to a VipsOperation (the libvips operation base + * This class holds a pointer to a VipsOperation (the libvips operation base * class) and manages argument introspection and operation call. * * @category Images @@ -64,7 +64,7 @@ class VipsOperation extends VipsObject */ public Introspect $introspect; - function __construct($pointer) + public function __construct($pointer) { $this->pointer = Init::ffi()-> cast(Init::ctypes("VipsOperation"), $pointer); @@ -82,15 +82,15 @@ public static function newFromName($name) return new VipsOperation($pointer); } - public function setMatch($name, $match_image, $value) { + public function setMatch($name, $match_image, $value) + { $flags = $this->introspect->arguments[$name]["flags"]; $gtype = $this->introspect->arguments[$name]["type"]; if ($match_image != null) { if ($gtype == Init::gtypes("VipsImage")) { $value = $match_image->imageize($value); - } - else if ($gtype == Init::gtypes("VipsArrayImage") && + } elseif ($gtype == Init::gtypes("VipsArrayImage") && is_array($value)) { $new_value = []; foreach ($value as $x) { @@ -110,7 +110,8 @@ public function setMatch($name, $match_image, $value) { parent::set($name, $value); } - private static function introspect($name): Introspect { + private static function introspect($name): Introspect + { static $cache = []; if (!array_key_exists($name, $cache)) { @@ -120,7 +121,8 @@ private static function introspect($name): Introspect { return $cache[$name]; } - private static function findInside($predicate, $x) { + private static function findInside($predicate, $x) + { if ($predicate($x)) { return $x; } @@ -249,7 +251,7 @@ private static function errorIsArray($result): void * * @return mixed The result(s) of the operation. */ - static function callBase( + public static function callBase( string $operation_name, ?Image $instance, array $arguments @@ -268,18 +270,17 @@ static function callBase( */ if ($instance != null) { $match_image = $instance; - } - else { + } else { $match_image = self::findInside( - fn($x) => $x instanceof Image, + fn($x) => $x instanceof Image, $arguments ); } /* Because of the way php callStatic works, we can sometimes be given - * an instance even when no instance was given. + * an instance even when no instance was given. * - * We must loop over the required args and set them from the supplied + * We must loop over the required args and set them from the supplied * args, using instance if required, and only check the nargs after * this pass. */ @@ -295,12 +296,10 @@ static function callBase( } $operation->setMatch($name, $match_image, $instance); $used_instance = true; - } - else if ($n_used < $n_supplied) { + } elseif ($n_used < $n_supplied) { $operation->setMatch($name, $match_image, $arguments[$n_used]); $n_used += 1; - } - else { + } else { $operation->unrefOutputs(); Init::error("$n_required arguments required, " . "but $n_supplied supplied"); @@ -365,7 +364,7 @@ static function callBase( } } - /* Free any outputs we've not used. + /* Free any outputs we've not used. */ $operation->unrefOutputs(); @@ -398,20 +397,12 @@ public static function call( array $arguments, array $options = [] ) { - /* - echo "call: $name \n"; - echo "instance = \n"; - var_dump($instance); - echo "arguments = \n"; - var_dump($arguments); - echo "options = \n"; - var_dump($options); - */ - - return self::callBase($name, $instance, - array_merge($arguments, [$options])); + return self::callBase( + $name, + $instance, + array_merge($arguments, [$options]) + ); } - } /* From 686921687ae5db666ff298d5608df1862378c0ea Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 17 Feb 2022 13:31:49 +0000 Subject: [PATCH 40/58] start soak testing watermark-image.php fails on 1087 iterations, looks like we're missing a ref somewhere --- examples/watermark-image.php | 46 ++++++++++++++++++++---------------- src/Init.php | 16 +++++++++++++ 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 9e5a9f6..46c166e 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -11,29 +11,35 @@ exit(1); } -// we can stream the main image -$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); +for ($i = 0; $i < 10000; $i++) { + echo "loop $i ...\n"; -// we'll read the watermark image many times, so we need random access for this -$watermark = Vips\Image::newFromFile($argv[3]); + // we can stream the main image + $image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); -// the watermark image needs to have an alpha channel -if (!$watermark->hasAlpha() || $watermark->bands != 4) { - echo("watermark image is not RGBA\n"); - exit(1); -} + // we'll read the watermark image many times, so we need random access for this + $watermark = Vips\Image::newFromFile($argv[3]); + + // the watermark image needs to have an alpha channel + if (!$watermark->hasAlpha() || $watermark->bands != 4) { + echo("watermark image is not RGBA\n"); + exit(1); + } -// make the watermark semi-transparent -$watermark = $watermark->multiply([1, 1, 1, 0.3])->cast("uchar"); + // make the watermark semi-transparent + $watermark = $watermark->multiply([1, 1, 1, 0.3])->cast("uchar"); -// repeat the watermark to the size of the image -$watermark = $watermark->replicate( - 1 + $image->width / $watermark->width, - 1 + $image->height / $watermark->height -); -$watermark = $watermark->crop(0, 0, $image->width, $image->height); + // repeat the watermark to the size of the image + $watermark = $watermark->replicate( + 1 + $image->width / $watermark->width, + 1 + $image->height / $watermark->height + ); + $watermark = $watermark->crop(0, 0, $image->width, $image->height); -// composite the watermark over the main image -$image = $image->composite2($watermark, 'over'); + // composite the watermark over the main image + $image = $image->composite2($watermark, 'over'); + + $image->writeToFile($argv[2]); +} -$image->writeToFile($argv[2]); +Vips\Init::shutDown(); diff --git a/src/Init.php b/src/Init.php index eb81ec1..f057d8e 100644 --- a/src/Init.php +++ b/src/Init.php @@ -121,6 +121,20 @@ public static function error(string $message = "") throw $exception; } + /** + * Shut down libvips. Call this just before process exit. + * + * @throws Exception + * + * @return void + * + * @internal + */ + public static function shutDown() + { + Init::ffi()->vips_shutdown(); + } + public static function filenameGetFilename($name) { $pointer = Init::ffi()->vips_filename_get_filename($name); @@ -674,6 +688,8 @@ private function init() "VipsImage" => $this->ffi->g_type_from_name("VipsImage"), ]; + $this->ffi->vips_leak_set(true); + Utils::debugLog("init", ["done"]); } } From 7073b6e1849e5db7f09443eb6b2f063ab6d3f5d1 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 28 Feb 2022 15:53:35 +0000 Subject: [PATCH 41/58] fix a segv filenameGetFilename() could crash under load, mysteriously remove the free() for now --- src/Config.php | 18 +++++++++++++----- src/Init.php | 16 ++++++++++++++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Config.php b/src/Config.php index b546870..ad77fb9 100644 --- a/src/Config.php +++ b/src/Config.php @@ -96,7 +96,7 @@ public static function getLogger(): ?LoggerInterface */ public static function cacheSetMax(int $value): void { - vips_cache_set_max($value); + Init::ffi()->vips_cache_set_max($value); } /** @@ -110,7 +110,7 @@ public static function cacheSetMax(int $value): void */ public static function cacheSetMaxMem(int $value): void { - vips_cache_set_max_mem($value); + Init::ffi()->vips_cache_set_max_mem($value); } /** @@ -123,7 +123,7 @@ public static function cacheSetMaxMem(int $value): void */ public static function cacheSetMaxFiles(int $value): void { - vips_cache_set_max_files($value); + Init::ffi()->vips_cache_set_max_files($value); } /** @@ -137,7 +137,7 @@ public static function cacheSetMaxFiles(int $value): void */ public static function concurrencySet(int $value): void { - vips_concurrency_set($value); + Init::ffi()->vips_concurrency_set($value); } /** @@ -148,7 +148,15 @@ public static function concurrencySet(int $value): void */ public static function version(): string { - return vips_version(); + return Init::ffi()->vips_version(); + } + + /** + * Handy for debugging. + */ + public static function printAll() + { + Init::ffi()->vips_object_print_all(); } } diff --git a/src/Init.php b/src/Init.php index f057d8e..86e7089 100644 --- a/src/Init.php +++ b/src/Init.php @@ -139,7 +139,10 @@ public static function filenameGetFilename($name) { $pointer = Init::ffi()->vips_filename_get_filename($name); $filename = \FFI::string($pointer); - \FFI::free($pointer); + + // You'[d think we should free this pointer, but php starts failing + // under load if you do :( + // \FFI::free($pointer); return $filename; } @@ -148,7 +151,10 @@ public static function filenameGetOptions($name) { $pointer = Init::ffi()->vips_filename_get_options($name); $options = \FFI::string($pointer); - \FFI::free($pointer); + + // You'[d think we should free this pointer, but php starts failing + // under load if you do :( + // \FFI::free($pointer); return $options; } @@ -571,6 +577,12 @@ private function init() size_t vips_cache_get_max_mem(); int vips_cache_get_max_files(); +size_t vips_tracked_get_mem_highwater(); +size_t vips_tracked_get_mem(); +int vips_tracked_get_allocs(); +int vips_tracked_get_files(); +void vips_object_print_all(); + char** vips_image_get_fields (VipsImage* image); int vips_image_hasalpha (VipsImage* image); From 692dbc502cdbe107f7e17a2e0dcc757332275cec Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 28 Feb 2022 18:49:10 +0000 Subject: [PATCH 42/58] revise string handling it's finally becoming clearer how php-ffi handles ownership --- README.md | 23 +++++++++++++++++++++++ src/GValue.php | 9 ++++++--- src/Init.php | 11 +++-------- src/Utils.php | 2 +- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5ce98ce..fb16243 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,29 @@ image. When the pipe is connected to a destination, the whole pipeline executes at once and in parallel, streaming the image from source to destination in a set of small fragments. +## TODO + +- Needs a refs system for newFromMemory etc. + +- More robust startup, and a better error message for lib not found or FFI + disabled. + +- Move some stuff from Init to Config or Utils. + +- Read and check the whole diff. + +- Rewrite the enum generator in php. + +- Check docs. + +### After merge + +- Add source/target API + +- Add progress callbacks etc. + +- Add mutable. + ### Install You need to [install the libvips diff --git a/src/GValue.php b/src/GValue.php index a6f8af3..663f5f5 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -242,15 +242,17 @@ public function get() break; case Init::gtypes("gchararray"): - $result = Init::ffi()->g_value_get_string($this->pointer); + $c_string = Init::ffi()->g_value_get_string($this->pointer); + $result = \FFI::string($c_string); break; case Init::gtypes("VipsRefString"): $p_size = Init::ffi()->new("size_t[1]"); - $result = Init::ffi()-> + $c_string = Init::ffi()-> vips_value_get_ref_string($this->pointer, $p_size); # $p_size[0] will be the string length, but assume it's null # terminated + $result = \FFI::string($c_string); break; case Init::gtypes("VipsImage"): @@ -310,7 +312,8 @@ public function get() case Init::gtypes("GFlags"): /* Just get as int. */ - $result = Init::ffi()->g_value_get_flags($this->pointer); + $result = Init::ffi()-> + g_value_get_flags($this->pointer); break; default: diff --git a/src/Init.php b/src/Init.php index 86e7089..bdff764 100644 --- a/src/Init.php +++ b/src/Init.php @@ -139,10 +139,7 @@ public static function filenameGetFilename($name) { $pointer = Init::ffi()->vips_filename_get_filename($name); $filename = \FFI::string($pointer); - - // You'[d think we should free this pointer, but php starts failing - // under load if you do :( - // \FFI::free($pointer); + Init::ffi()->g_free($pointer); return $filename; } @@ -151,14 +148,12 @@ public static function filenameGetOptions($name) { $pointer = Init::ffi()->vips_filename_get_options($name); $options = \FFI::string($pointer); - - // You'[d think we should free this pointer, but php starts failing - // under load if you do :( - // \FFI::free($pointer); + Init::ffi()->g_free($pointer); return $options; } + public function __construct() { } diff --git a/src/Utils.php b/src/Utils.php index 2f4fe53..fc3b87b 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -92,7 +92,7 @@ public static function errorLog(string $message, \Exception $exception): void */ public static function typeFromName(string $name): int { - return vips_type_from_name($name); + return Init::ffi()->g_type_from_name($name); } } From 05327a93adca0450f39c297135eb643fb96ccd89 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 03:23:51 +0000 Subject: [PATCH 43/58] revise startup --- README.md | 7 +++---- src/Init.php | 16 +++++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fb16243..0a8af50 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,15 @@ destination in a set of small fragments. - Needs a refs system for newFromMemory etc. -- More robust startup, and a better error message for lib not found or FFI - disabled. - - Move some stuff from Init to Config or Utils. + Put the whole of init inside config? + - Read and check the whole diff. - Rewrite the enum generator in php. -- Check docs. +- Revise docs. ### After merge diff --git a/src/Init.php b/src/Init.php index bdff764..866ac69 100644 --- a/src/Init.php +++ b/src/Init.php @@ -194,17 +194,19 @@ private function init() $library = "$library_location$library_name$library_ext"; Utils::debugLog("init", ["libray" => $library]); - // TODO put a try/catch around this and generate a helpful message - // since this is likely to be the main failure point + /* FIXME ... maybe display a helpful message on failure? This will + * probably be the main point of failure. + */ $ffi = \FFI::cdef(<<vips_init(""); if ($result != 0) { - throw new Vips\Exception("libvips error: $ffi->vips_error_buffer()"); + $msg = $ffi->vips_error_buffer(); + throw new Vips\Exception("libvips error: $msg"); } Utils::debugLog("init", ["vips_init" => $result]); From 8537cba94fd43c2c4deb6a281a4fbf9f6f5cd949 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 03:47:37 +0000 Subject: [PATCH 44/58] more init into config --- README.md | 4 +- src/Config.php | 657 ++++++++++++++++++++++++++++++++++++++- src/GObject.php | 6 +- src/GValue.php | 149 ++++----- src/Image.php | 172 +++++++---- src/Init.php | 704 ------------------------------------------ src/Interpolate.php | 8 +- src/Introspect.php | 18 +- src/Utils.php | 2 +- src/VipsObject.php | 34 +- src/VipsOperation.php | 28 +- 11 files changed, 893 insertions(+), 889 deletions(-) delete mode 100644 src/Init.php diff --git a/README.md b/README.md index 0a8af50..6d34058 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ destination in a set of small fragments. - Needs a refs system for newFromMemory etc. -- Move some stuff from Init to Config or Utils. +- nicknameToCanonical needs redoing for FFI - Put the whole of init inside config? +- blendModeToInt needs redoing for FFI - Read and check the whole diff. diff --git a/src/Config.php b/src/Config.php index ad77fb9..2441d38 100644 --- a/src/Config.php +++ b/src/Config.php @@ -60,6 +60,31 @@ class Config */ private static $logger; + /** + * The FFI handle we use for the libvips binary. + * + * @internal + */ + private static \FFI $ffi; + private static $ffi_inited = false; + + /** + * The library version number we detect. + * + * @internal + */ + private static int $library_major; + private static int $library_minor; + private static int $library_micro; + + /** + * Look up these once. + * + * @internal + */ + private static array $ctypes; + private static array $gtypes; + /** * Sets a logger. This can be handy for debugging. For example: * @@ -96,7 +121,7 @@ public static function getLogger(): ?LoggerInterface */ public static function cacheSetMax(int $value): void { - Init::ffi()->vips_cache_set_max($value); + Config::ffi()->vips_cache_set_max($value); } /** @@ -110,7 +135,7 @@ public static function cacheSetMax(int $value): void */ public static function cacheSetMaxMem(int $value): void { - Init::ffi()->vips_cache_set_max_mem($value); + Config::ffi()->vips_cache_set_max_mem($value); } /** @@ -123,7 +148,7 @@ public static function cacheSetMaxMem(int $value): void */ public static function cacheSetMaxFiles(int $value): void { - Init::ffi()->vips_cache_set_max_files($value); + Config::ffi()->vips_cache_set_max_files($value); } /** @@ -137,7 +162,7 @@ public static function cacheSetMaxFiles(int $value): void */ public static function concurrencySet(int $value): void { - Init::ffi()->vips_concurrency_set($value); + Config::ffi()->vips_concurrency_set($value); } /** @@ -148,7 +173,7 @@ public static function concurrencySet(int $value): void */ public static function version(): string { - return Init::ffi()->vips_version(); + return Config::ffi()->vips_version(); } /** @@ -156,7 +181,627 @@ public static function version(): string */ public static function printAll() { - Init::ffi()->vips_object_print_all(); + Config::ffi()->vips_object_print_all(); + } + + public static function ffi() + { + if (!self::$ffi_inited) { + self::init(); + self::$ffi_inited = true; + } + + return self::$ffi; + } + + public static function ctypes(string $name) + { + Config::ffi(); + + return self::$ctypes[$name]; + } + + public static function gtypes(string $name) + { + Config::ffi(); + + return self::$gtypes[$name]; + } + + /** + * Throw a vips error as an exception. + * + * @throws Exception + * + * @return void + * + * @internal + */ + public static function error(string $message = "") + { + if ($message == "") { + $message = Config::ffi()->vips_error_buffer(); + Config::ffi()->vips_error_clear(); + } + $exception = new Exception($message); + Utils::errorLog($message, $exception); + throw $exception; + } + + /** + * Shut down libvips. Call this just before process exit. + * + * @throws Exception + * + * @return void + * + * @internal + */ + public static function shutDown() + { + Config::ffi()->vips_shutdown(); + } + + public static function filenameGetFilename($name) + { + $pointer = Config::ffi()->vips_filename_get_filename($name); + $filename = \FFI::string($pointer); + Config::ffi()->g_free($pointer); + + return $filename; + } + + public static function filenameGetOptions($name) + { + $pointer = Config::ffi()->vips_filename_get_options($name); + $options = \FFI::string($pointer); + Config::ffi()->g_free($pointer); + + return $options; + } + + public static function atLeast($need_major, $need_minor) + { + return $need_major < self::$library_major || + ($need_major == self::$library_major && + $need_minor <= self::$library_minor); + } + + private static function init() + { + $library_name = "libvips"; + + switch (PHP_OS_FAMILY) { + case "Windows": + $library_ext = ".dll"; + break; + + case "OSX": + $library_ext = ".dylib"; + break; + + default: + $library_ext = ".so"; + break; + } + + $vipshome = getenv("VIPSHOME"); + if ($vipshome) { + $library_location = $vipshome . "/lib/"; + } else { + # rely on ffi's search + $library_location = ""; + } + + $library = "$library_location$library_name$library_ext"; + Utils::debugLog("init", ["libray" => $library]); + + /* FIXME ... maybe display a helpful message on failure? This will + * probably be the main point of failure. + */ + $ffi = \FFI::cdef(<<vips_init(""); + if ($result != 0) { + $msg = $ffi->vips_error_buffer(); + throw new Vips\Exception("libvips error: $msg"); + } + Utils::debugLog("init", ["vips_init" => $result]); + + # get the library version number, then we can build the API + self::$library_major = $ffi->vips_version(0); + self::$library_minor = $ffi->vips_version(1); + self::$library_micro = $ffi->vips_version(2); + Utils::debugLog("init", [ + "libvips version" => [ + self::$library_major, + self::$library_minor, + self::$library_micro + ] + ]); + + if (!self::atLeast(8, 7)) { + throw new Vips\Exception("your libvips is too old -- " . + "8.7 or later required"); + } + + if (PHP_INT_SIZE != 8) { + # we could maybe fix this if it's important ... it's mostly + # necessary since GType is the size of a pointer, and there's no + # easy way to discover if php is running on a 32 or 64-bit + # systems (as far as I can see) + throw new Vips\Exception("your php only supports 32-bit ints -- " . + "64 bit ints required"); + } + + # the whole libvips API, mostly adapted from pyvips + $header = << self::$ffi->type("GObject*"), + "VipsObject" => self::$ffi->type("VipsObject*"), + "VipsOperation" => self::$ffi->type("VipsOperation*"), + "VipsImage" => self::$ffi->type("VipsImage*"), + "VipsInterpolate" => self::$ffi->type("VipsInterpolate*"), + ]; + + self::$gtypes = [ + "gboolean" => self::$ffi->g_type_from_name("gboolean"), + "gint" => self::$ffi->g_type_from_name("gint"), + "gint64" => self::$ffi->g_type_from_name("gint64"), + "guint64" => self::$ffi->g_type_from_name("guint64"), + "gdouble" => self::$ffi->g_type_from_name("gdouble"), + "gchararray" => self::$ffi->g_type_from_name("gchararray"), + "VipsRefString" => self::$ffi->g_type_from_name("VipsRefString"), + + "GEnum" => self::$ffi->g_type_from_name("GEnum"), + "GFlags" => self::$ffi->g_type_from_name("GFlags"), + "VipsBandFormat" => self::$ffi->g_type_from_name("VipsBandFormat"), + "VipsBlendMode" => self::$ffi->g_type_from_name("VipsBlendMode"), + "VipsArrayInt" => self::$ffi->g_type_from_name("VipsArrayInt"), + "VipsArrayDouble" => + self::$ffi->g_type_from_name("VipsArrayDouble"), + "VipsArrayImage" => self::$ffi->g_type_from_name("VipsArrayImage"), + "VipsBlob" => self::$ffi->g_type_from_name("VipsBlob"), + + "GObject" => self::$ffi->g_type_from_name("GObject"), + "VipsImage" => self::$ffi->g_type_from_name("VipsImage"), + ]; + + self::$ffi->vips_leak_set(true); + + Utils::debugLog("init", ["done"]); } } diff --git a/src/GObject.php b/src/GObject.php index f7c8790..ca5e4cb 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -71,7 +71,7 @@ abstract class GObject */ public function __construct($pointer) { - $this->pointer = \FFI::cast(Init::ctypes("GObject"), $pointer); + $this->pointer = \FFI::cast(Config::ctypes("GObject"), $pointer); } public function __destruct() @@ -81,12 +81,12 @@ public function __destruct() public function ref() { - Init::ffi()->g_object_ref($this->pointer); + Config::ffi()->g_object_ref($this->pointer); } public function unref() { - Init::ffi()->g_object_unref($this->pointer); + Config::ffi()->g_object_unref($this->pointer); } // TODO signal marshalling to go in diff --git a/src/GValue.php b/src/GValue.php index 663f5f5..a4b9d10 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -46,7 +46,7 @@ class GValue public function __construct() { # allocate a gvalue on the heap, and make it persistent between requests - $this->struct = Init::ffi()->new("GValue", true, true); + $this->struct = Config::ffi()->new("GValue", true, true); $this->pointer = \FFI::addr($this->struct); # GValue needs to be inited to all zero @@ -58,10 +58,10 @@ public function __construct() public static function toEnum($gtype, $value) { if (is_string($value)) { - $enum_value = Init::ffi()-> + $enum_value = Config::ffi()-> vips_enum_from_nick("php-vips", $gtype, $value); if ($enum_value < 0) { - Init::error(); + Config::error(); } } else { $enum_value = $value; @@ -72,9 +72,9 @@ public static function toEnum($gtype, $value) public static function fromEnum($gtype, $value) { - $result = Init::ffi()->vips_enum_nick($gtype, $value); + $result = Config::ffi()->vips_enum_nick($gtype, $value); if ($result === null) { - Init::error("value not in enum"); + Config::error("value not in enum"); } return $result; @@ -82,12 +82,12 @@ public static function fromEnum($gtype, $value) public function __destruct() { - Init::ffi()->g_value_unset($this->pointer); + Config::ffi()->g_value_unset($this->pointer); } public function setType(int $gtype) { - Init::ffi()->g_value_init($this->pointer, $gtype); + Config::ffi()->g_value_init($this->pointer, $gtype); } public function getType(): int @@ -100,35 +100,36 @@ public function set($value) $gtype = $this->getType(); switch ($gtype) { - case Init::gtypes("gboolean"): - Init::ffi()->g_value_set_boolean($this->pointer, $value); + case Config::gtypes("gboolean"): + Config::ffi()->g_value_set_boolean($this->pointer, $value); break; - case Init::gtypes("gint"): - Init::ffi()->g_value_set_int($this->pointer, $value); + case Config::gtypes("gint"): + Config::ffi()->g_value_set_int($this->pointer, $value); break; - case Init::gtypes("gint64"): - Init::ffi()->g_value_set_int64($this->pointer, $value); + case Config::gtypes("gint64"): + Config::ffi()->g_value_set_int64($this->pointer, $value); break; - case Init::gtypes("guint64"): - Init::ffi()->g_value_set_uint64($this->pointer, $value); + case Config::gtypes("guint64"): + Config::ffi()->g_value_set_uint64($this->pointer, $value); break; - case Init::gtypes("gdouble"): - Init::ffi()->g_value_set_double($this->pointer, $value); + case Config::gtypes("gdouble"): + Config::ffi()->g_value_set_double($this->pointer, $value); break; - case Init::gtypes("gchararray"): - Init::ffi()->g_value_set_string($this->pointer, $value); + case Config::gtypes("gchararray"): + Config::ffi()->g_value_set_string($this->pointer, $value); break; - case Init::gtypes("VipsRefString"): - Init::ffi()->vips_value_set_ref_string($this->pointer, $value); + case Config::gtypes("VipsRefString"): + Config::ffi()-> + vips_value_set_ref_string($this->pointer, $value); break; - case Init::gtypes("VipsArrayInt"): + case Config::gtypes("VipsArrayInt"): if (!is_array($value)) { $value = [$value]; } @@ -138,11 +139,11 @@ public function set($value) for ($i = 0; $i < $n; $i++) { $array[$i] = $value[$i]; } - Init::ffi()-> + Config::ffi()-> vips_value_set_array_int($this->pointer, $array, $n); break; - case Init::gtypes("VipsArrayDouble"): + case Config::gtypes("VipsArrayDouble"): if (!is_array($value)) { $value = [$value]; } @@ -152,17 +153,17 @@ public function set($value) for ($i = 0; $i < $n; $i++) { $array[$i] = $value[$i]; } - Init::ffi()-> + Config::ffi()-> vips_value_set_array_double($this->pointer, $array, $n); break; - case Init::gtypes("VipsArrayImage"): + case Config::gtypes("VipsArrayImage"): if (!is_array($value)) { $value = [$value]; } $n = count($value); - Init::ffi()->vips_value_set_array_image($this->pointer, $n); - $array = Init::ffi()-> + Config::ffi()->vips_value_set_array_image($this->pointer, $n); + $array = Config::ffi()-> vips_value_get_array_image($this->pointer, null); for ($i = 0; $i < $n; $i++) { $image = $value[$i]; @@ -171,7 +172,7 @@ public function set($value) } break; - case Init::gtypes("VipsBlob"): + case Config::gtypes("VipsBlob"): # we need to set the blob to a copy of the data that vips_lib # can own and free $n = strlen($value); @@ -180,33 +181,34 @@ public function set($value) for ($i = 0; $i < $n; $i++) { $memory[$i] = $value[$i]; } - Init::ffi()-> + Config::ffi()-> vips_value_set_blob_free($this->pointer, $memory, $n); break; default: - $fundamental = Init::ffi()->g_type_fundamental($gtype); + $fundamental = Config::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case Init::gtypes("GObject"): - Init::ffi()-> + case Config::gtypes("GObject"): + Config::ffi()-> g_value_set_object($this->pointer, $value->pointer); break; - case Init::gtypes("GEnum"): - Init::ffi()->g_value_set_enum( + case Config::gtypes("GEnum"): + Config::ffi()->g_value_set_enum( $this->pointer, self::toEnum($gtype, $value) ); break; - case Init::gtypes("GFlags"): + case Config::gtypes("GFlags"): /* Just set as int. */ - Init::ffi()->g_value_set_flags($this->pointer, $value); + Config::ffi()-> + g_value_set_flags($this->pointer, $value); break; default: - $typeName = Init::ffi()->g_type_name($gtype); + $typeName = Config::ffi()->g_type_name($gtype); throw new \BadMethodCallException( "gtype $typeName ($gtype) not implemented" ); @@ -221,50 +223,50 @@ public function get() $result = null; switch ($gtype) { - case Init::gtypes("gboolean"): - $result = Init::ffi()->g_value_get_boolean($this->pointer); + case Config::gtypes("gboolean"): + $result = Config::ffi()->g_value_get_boolean($this->pointer); break; - case Init::gtypes("gint"): - $result = Init::ffi()->g_value_get_int($this->pointer); + case Config::gtypes("gint"): + $result = Config::ffi()->g_value_get_int($this->pointer); break; - case Init::gtypes("gint64"): - $result = Init::ffi()->g_value_get_int64($this->pointer); + case Config::gtypes("gint64"): + $result = Config::ffi()->g_value_get_int64($this->pointer); break; - case Init::gtypes("guint64"): - $result = Init::ffi()->g_value_get_uint64($this->pointer); + case Config::gtypes("guint64"): + $result = Config::ffi()->g_value_get_uint64($this->pointer); break; - case Init::gtypes("gdouble"): - $result = Init::ffi()->g_value_get_double($this->pointer); + case Config::gtypes("gdouble"): + $result = Config::ffi()->g_value_get_double($this->pointer); break; - case Init::gtypes("gchararray"): - $c_string = Init::ffi()->g_value_get_string($this->pointer); + case Config::gtypes("gchararray"): + $c_string = Config::ffi()->g_value_get_string($this->pointer); $result = \FFI::string($c_string); break; - case Init::gtypes("VipsRefString"): - $p_size = Init::ffi()->new("size_t[1]"); - $c_string = Init::ffi()-> + case Config::gtypes("VipsRefString"): + $p_size = Config::ffi()->new("size_t[1]"); + $c_string = Config::ffi()-> vips_value_get_ref_string($this->pointer, $p_size); # $p_size[0] will be the string length, but assume it's null # terminated $result = \FFI::string($c_string); break; - case Init::gtypes("VipsImage"): - $pointer = Init::ffi()->g_value_get_object($this->pointer); + case Config::gtypes("VipsImage"): + $pointer = Config::ffi()->g_value_get_object($this->pointer); $result = new Image($pointer); // get_object does not increment the ref count $result->ref(); break; - case Init::gtypes("VipsArrayInt"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> + case Config::gtypes("VipsArrayInt"): + $p_len = Config::ffi()->new("int[1]"); + $pointer = Config::ffi()-> vips_value_get_array_int($this->pointer, $p_len); $result = []; for ($i = 0; $i < $p_len[0]; $i++) { @@ -272,9 +274,9 @@ public function get() } break; - case Init::gtypes("VipsArrayDouble"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> + case Config::gtypes("VipsArrayDouble"): + $p_len = Config::ffi()->new("int[1]"); + $pointer = Config::ffi()-> vips_value_get_array_double($this->pointer, $p_len); $result = []; for ($i = 0; $i < $p_len[0]; $i++) { @@ -282,9 +284,9 @@ public function get() } break; - case Init::gtypes("VipsArrayImage"): - $p_len = Init::ffi()->new("int[1]"); - $pointer = Init::ffi()-> + case Config::gtypes("VipsArrayImage"): + $p_len = Config::ffi()->new("int[1]"); + $pointer = Config::ffi()-> vips_value_get_array_image($this->pointer, $p_len); $result = []; for ($i = 0; $i < $p_len[0]; $i++) { @@ -294,30 +296,31 @@ public function get() } break; - case Init::gtypes("VipsBlob"): - $p_len = Init::ffi()->new("size_t[1]"); - $pointer = Init::ffi()-> + case Config::gtypes("VipsBlob"): + $p_len = Config::ffi()->new("size_t[1]"); + $pointer = Config::ffi()-> vips_value_get_blob($this->pointer, $p_len); $result = \FFI::string($pointer, $p_len[0]); break; default: - $fundamental = Init::ffi()->g_type_fundamental($gtype); + $fundamental = Config::ffi()->g_type_fundamental($gtype); switch ($fundamental) { - case Init::gtypes("GEnum"): - $result = Init::ffi()->g_value_get_enum($this->pointer); + case Config::gtypes("GEnum"): + $result = Config::ffi()-> + g_value_get_enum($this->pointer); $result = self::fromEnum($gtype, $result); break; - case Init::gtypes("GFlags"): + case Config::gtypes("GFlags"): /* Just get as int. */ - $result = Init::ffi()-> + $result = Config::ffi()-> g_value_get_flags($this->pointer); break; default: - $typeName = Init::ffi()->g_type_name($gtype); + $typeName = Config::ffi()->g_type_name($gtype); throw new \BadMethodCallException( "gtype $typeName ($gtype) not implemented" ); diff --git a/src/Image.php b/src/Image.php index 876d074..ddc1678 100644 --- a/src/Image.php +++ b/src/Image.php @@ -540,7 +540,7 @@ class Image extends ImageAutodoc implements \ArrayAccess /** * Combine takes an array of blend modes, passed to libvips as an array of - * int. Because libvips does now know they should be enums, we have to do + * int. Because libvips does not know they should be enums, we have to do * the string->int conversion ourselves. We ought to introspect to find the * mapping, but until we have the machinery for that, we just hardwire the * mapping here. @@ -593,7 +593,8 @@ class Image extends ImageAutodoc implements \ArrayAccess */ public function __construct($pointer) { - $this->pointer = Init::ffi()->cast(Init::ctypes("VipsImage"), $pointer); + $this->pointer = Config::ffi()-> + cast(Config::ctypes("VipsImage"), $pointer); parent::__construct($pointer); } @@ -768,7 +769,12 @@ private function callEnum( if (self::isImageish($other)) { return VipsOperation::call($base, $this, [$other, $op], $options); } else { - return VipsOperation::call($base . '_const', $this, [$op, $other], $options); + return VipsOperation::call( + $base . '_const', + $this, + [$op, $other], + $options + ); } } @@ -791,12 +797,12 @@ public static function newFromFile( 'arguments' => [$name, $options] ]); - $filename = Init::filenameGetFilename($name); - $string_options = Init::filenameGetOptions($name); + $filename = Config::filenameGetFilename($name); + $string_options = Config::filenameGetOptions($name); - $loader = Init::ffi()->vips_foreign_find_load($filename); + $loader = Config::ffi()->vips_foreign_find_load($filename); if ($loader == "") { - Init::error(); + Config::error(); } if (strlen($string_options) != 0) { @@ -834,10 +840,10 @@ public static function newFromBuffer( 'arguments' => [$buffer, $string_options, $options] ]); - $loader = Init::ffi()-> + $loader = Config::ffi()-> vips_foreign_find_load_buffer($buffer, strlen($buffer)); if ($loader == null) { - Init::error(); + Config::error(); } if (strlen($string_options) != 0) { @@ -894,15 +900,15 @@ public static function newFromArray( } } - $pointer = Init::ffi()-> + $pointer = Config::ffi()-> vips_image_new_matrix_from_array($width, $height, $a, $n); if ($pointer == null) { - Init::error(); + Config::error(); } $result = new Image($pointer); - $result->setType(Init::gtypes("gdouble"), 'scale', $scale); - $result->setType(Init::gtypes("gdouble"), 'offset', $offset); + $result->setType(Config::gtypes("gdouble"), 'scale', $scale); + $result->setType(Config::gtypes("gdouble"), 'offset', $offset); Utils::debugLog('newFromArray', ['result' => $result]); @@ -934,7 +940,7 @@ public static function newFromMemory( 'arguments' => [$data, $width, $height, $bands, $format] ]); - $pointer = Init::ffi()->vips_image_new_from_memory( + $pointer = Config::ffi()->vips_image_new_from_memory( $data, strlen($data), $width, @@ -943,7 +949,7 @@ public static function newFromMemory( $format ); if ($pointer == null) { - Init::error(); + Config::error(); } $result = new Image($pointer); @@ -1026,12 +1032,12 @@ public function writeToFile(string $name, array $options = []): void 'options' => $options ]); - $filename = Init::filenameGetFilename($name); - $string_options = Init::filenameGetOptions($name); + $filename = Config::filenameGetFilename($name); + $string_options = Config::filenameGetOptions($name); - $saver = Init::ffi()->vips_foreign_find_save($filename); + $saver = Config::ffi()->vips_foreign_find_save($filename); if ($saver == "") { - Init::error(); + Config::error(); } if (strlen($string_options) != 0) { @@ -1045,7 +1051,7 @@ public function writeToFile(string $name, array $options = []): void Utils::debugLog('writeToFile', ['result' => $result]); if ($result === -1) { - Init::error(); + Config::error(); } } @@ -1067,12 +1073,12 @@ public function writeToBuffer(string $suffix, array $options = []): string 'arguments' => [$suffix, $options] ]); - $filename = Init::filenameGetFilename($suffix); - $string_options = Init::filenameGetOptions($suffix); + $filename = Config::filenameGetFilename($suffix); + $string_options = Config::filenameGetOptions($suffix); - $saver = Init::ffi()->vips_foreign_find_save_buffer($filename); + $saver = Config::ffi()->vips_foreign_find_save_buffer($filename); if ($saver == "") { - Init::error(); + Config::error(); } if (strlen($string_options) != 0) { @@ -1105,10 +1111,10 @@ public function writeToMemory(): string $ctype = \FFI::arrayType(\FFI::type("size_t"), [1]); $p_size = \FFI::new($ctype); - $pointer = Init::ffi()-> + $pointer = Config::ffi()-> vips_image_write_to_memory($this->pointer, $p_size); if ($pointer == null) { - Init::error(); + Config::error(); } $result = \FFI::string($pointer, $p_size[0]); @@ -1148,9 +1154,9 @@ public function writeToArray(): array 'arguments' => [] ]); - $result = Init::ffi()->vips_image_write_to_array($this->pointer); + $result = Config::ffi()->vips_image_write_to_array($this->pointer); if ($result === -1) { - Init::error(); + Config::error(); } Utils::debugLog('writeToArray', ['result' => $result]); @@ -1179,9 +1185,9 @@ public function copyMemory(): Image 'arguments' => [] ]); - $pointer = Init::ffi()->vips_image_copy_memory($this->pointer); + $pointer = Config::ffi()->vips_image_copy_memory($this->pointer); if ($pointer == null) { - Init::error(); + Config::error(); } $result = new Image($pointer); @@ -1247,9 +1253,9 @@ public function __isset(string $name): bool public function get(string $name) { $gvalue = new GValue(); - if (Init::ffi()-> + if (Config::ffi()-> vips_image_get($this->pointer, $name, $gvalue->pointer) != 0) { - Init::error(); + Config::error(); } return $gvalue->get(); @@ -1266,7 +1272,7 @@ public function get(string $name) */ public function getType(string $name): int { - return Init::ffi()->vips_image_get_typeof($this->pointer, $name); + return Config::ffi()->vips_image_get_typeof($this->pointer, $name); } /** @@ -1304,27 +1310,27 @@ public function set(string $name, $value): void if ($gtype == 0) { if (is_array($value)) { if (is_int($value[0])) { - $gtype = Init::gtypes("VipsArrayInt"); + $gtype = Config::gtypes("VipsArrayInt"); } elseif (is_float($value[0])) { - $gtype = Init::gtypes("VipsArrayDouble"); + $gtype = Config::gtypes("VipsArrayDouble"); } else { - $gtype = Init::gtypes("VipsArrayImage"); + $gtype = Config::gtypes("VipsArrayImage"); } } elseif (is_int($value)) { - $gtype = Init::gtypes("gint"); + $gtype = Config::gtypes("gint"); } elseif (is_float($value)) { - $gtype = Init::gtypes("gdouble"); + $gtype = Config::gtypes("gdouble"); } elseif (is_string($value)) { - $gtype = Init::gtypes("VipsRefString"); + $gtype = Config::gtypes("VipsRefString"); } else { - $gtype = Init::gtypes("VipsImage"); + $gtype = Config::gtypes("VipsImage"); } } $gvalue->setType($gtype); $gvalue->set($value); - Init::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); + Config::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); } /** @@ -1349,7 +1355,7 @@ public function setType($type, string $name, $value): void $gvalue = new GValue(); $gvalue->setType($type); $gvalue->set($value); - Init::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); + Config::ffi()->vips_image_set($this->pointer, $name, $gvalue->pointer); } /** @@ -1363,8 +1369,8 @@ public function setType($type, string $name, $value): void */ public function remove(string $name): void { - if (!Init::ffi()->vips_image_remove($this->pointer, $name)) { - Init::error(); + if (!Config::ffi()->vips_image_remove($this->pointer, $name)) { + Config::error(); } } @@ -1662,7 +1668,12 @@ public function remainder($other, array $options = []): Image if (self::isImageish($other)) { return VipsOperation::call('remainder', $this, [$other], $options); } else { - return VipsOperation::call('remainder_const', $this, [$other], $options); + return VipsOperation::call( + 'remainder_const', + $this, + [$other], + $options + ); } } @@ -1723,7 +1734,12 @@ public function lshift($other, array $options = []): Image */ public function rshift($other, array $options = []): Image { - return self::callEnum($other, 'boolean', OperationBoolean::RSHIFT, $options); + return self::callEnum( + $other, + 'boolean', + OperationBoolean::RSHIFT, + $options + ); } /** @@ -1771,7 +1787,12 @@ public function orimage($other, array $options = []): Image */ public function eorimage($other, array $options = []): Image { - return self::callEnum($other, 'boolean', OperationBoolean::EOR, $options); + return self::callEnum( + $other, + 'boolean', + OperationBoolean::EOR, + $options + ); } /** @@ -1786,7 +1807,12 @@ public function eorimage($other, array $options = []): Image */ public function more($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::MORE, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::MORE, + $options + ); } /** @@ -1801,7 +1827,12 @@ public function more($other, array $options = []): Image */ public function moreEq($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::MOREEQ, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::MOREEQ, + $options + ); } /** @@ -1816,7 +1847,12 @@ public function moreEq($other, array $options = []): Image */ public function less($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::LESS, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::LESS, + $options + ); } /** @@ -1831,7 +1867,12 @@ public function less($other, array $options = []): Image */ public function lessEq($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::LESSEQ, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::LESSEQ, + $options + ); } /** @@ -1846,7 +1887,12 @@ public function lessEq($other, array $options = []): Image */ public function equal($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::EQUAL, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::EQUAL, + $options + ); } /** @@ -1861,7 +1907,12 @@ public function equal($other, array $options = []): Image */ public function notEq($other, array $options = []): Image { - return self::callEnum($other, 'relational', OperationRelational::NOTEQ, $options); + return self::callEnum( + $other, + 'relational', + OperationRelational::NOTEQ, + $options + ); } /** @@ -1897,7 +1948,12 @@ public function bandjoin($other, array $options = []): Image /* We can't use self::bandjoin(), that would just recurse. */ if ($is_const) { - return VipsOperation::call('bandjoin_const', $this, [$other], $options); + return VipsOperation::call( + 'bandjoin_const', + $this, + [$other], + $options + ); } else { return VipsOperation::call( 'bandjoin', @@ -2049,7 +2105,6 @@ public function ifthenelse($then, $else, array $options = []): Image * match each other first, and only if they are both constants do we * match to $this. */ - $match_image = null; foreach ([$then, $else, $this] as $item) { if ($item instanceof Image) { @@ -2066,7 +2121,12 @@ public function ifthenelse($then, $else, array $options = []): Image $else = $match_image->imageize($else); } - return VipsOperation::call('ifthenelse', $this, [$then, $else], $options); + return VipsOperation::call( + 'ifthenelse', + $this, + [$then, $else], + $options + ); } /** diff --git a/src/Init.php b/src/Init.php deleted file mode 100644 index 866ac69..0000000 --- a/src/Init.php +++ /dev/null @@ -1,704 +0,0 @@ - - * @copyright 2016 John Cupitt - * @license https://opensource.org/licenses/MIT MIT - * @link https://github.com/libvips/php-vips - */ - -namespace Jcupitt\Vips; - -/** - * This singleton class manages the connection to the libvips binary. - * - * @category Images - * @package Jcupitt\Vips - * @author John Cupitt - * @copyright 2016 John Cupitt - * @license https://opensource.org/licenses/MIT MIT - * @link https://github.com/jcupitt/php-vips - */ -class Init -{ - /** - * The FFI handle we use for the libvips binary. - * - * @internal - */ - private \FFI $ffi; - - /** - * The library version number we detect. - * - * @internal - */ - private int $library_major; - private int $library_minor; - private int $library_micro; - - /** - * Look up these once. - * - * @internal - */ - private array $ctypes; - private array $gtypes; - - public static function getInit() - { - static $instance; - - if (!$instance) { - $instance = new Init(); - $instance->init(); - } - - return $instance; - } - - public static function ffi() - { - return self::getInit()->ffi; - } - - public static function ctypes(string $name) - { - return self::getInit()->ctypes[$name]; - } - - public static function gtypes(string $name) - { - return self::getInit()->gtypes[$name]; - } - - /** - * Throw a vips error as an exception. - * - * @throws Exception - * - * @return void - * - * @internal - */ - public static function error(string $message = "") - { - if ($message == "") { - $message = Init::ffi()->vips_error_buffer(); - Init::ffi()->vips_error_clear(); - } - $exception = new Exception($message); - Utils::errorLog($message, $exception); - throw $exception; - } - - /** - * Shut down libvips. Call this just before process exit. - * - * @throws Exception - * - * @return void - * - * @internal - */ - public static function shutDown() - { - Init::ffi()->vips_shutdown(); - } - - public static function filenameGetFilename($name) - { - $pointer = Init::ffi()->vips_filename_get_filename($name); - $filename = \FFI::string($pointer); - Init::ffi()->g_free($pointer); - - return $filename; - } - - public static function filenameGetOptions($name) - { - $pointer = Init::ffi()->vips_filename_get_options($name); - $options = \FFI::string($pointer); - Init::ffi()->g_free($pointer); - - return $options; - } - - - public function __construct() - { - } - - public function atLeast($need_major, $need_minor) - { - return $need_major < $this->library_major || - ($need_major == $this->library_major && - $need_minor <= $this->library_minor); - } - - private function init() - { - $library_name = "libvips"; - - switch (PHP_OS_FAMILY) { - case "Windows": - $library_ext = ".dll"; - break; - - case "OSX": - $library_ext = ".dylib"; - break; - - default: - $library_ext = ".so"; - break; - } - - $vipshome = getenv("VIPSHOME"); - if ($vipshome) { - $library_location = $vipshome . "/lib/"; - } else { - # rely on ffi's search - $library_location = ""; - } - - $library = "$library_location$library_name$library_ext"; - Utils::debugLog("init", ["libray" => $library]); - - /* FIXME ... maybe display a helpful message on failure? This will - * probably be the main point of failure. - */ - $ffi = \FFI::cdef(<<vips_init(""); - if ($result != 0) { - $msg = $ffi->vips_error_buffer(); - throw new Vips\Exception("libvips error: $msg"); - } - Utils::debugLog("init", ["vips_init" => $result]); - - # get the library version number, then we can build the API - $this->library_major = $ffi->vips_version(0); - $this->library_minor = $ffi->vips_version(1); - $this->library_micro = $ffi->vips_version(2); - Utils::debugLog("init", [ - "libvips version" => [ - $this->library_major, - $this->library_minor, - $this->library_micro - ] - ]); - - if (!$this->atLeast(8, 7)) { - throw new Vips\Exception("your libvips is too old -- " . - "8.7 or later required"); - } - - if (PHP_INT_SIZE != 8) { - # we could maybe fix this if it's important ... it's mostly - # necessary since GType is the size of a pointer, and there's no - # easy way to discover if php is running on a 32 or 64-bit - # systems (as far as I can see) - throw new Vips\Exception("your php only supports 32-bit ints -- " . - "64 bit ints required"); - } - - # the whole libvips API, mostly adapted from pyvips - $header = <<atLeast(8, 8)) { - $header = $header . <<atLeast(8, 8)) { - $header = $header . <<ffi = \FFI::cdef($header, $library); - - // look these up in advance - $this->ctypes = [ - "GObject" => $this->ffi->type("GObject*"), - "VipsObject" => $this->ffi->type("VipsObject*"), - "VipsOperation" => $this->ffi->type("VipsOperation*"), - "VipsImage" => $this->ffi->type("VipsImage*"), - "VipsInterpolate" => $this->ffi->type("VipsInterpolate*"), - ]; - - $this->gtypes = [ - "gboolean" => $this->ffi->g_type_from_name("gboolean"), - "gint" => $this->ffi->g_type_from_name("gint"), - "gint64" => $this->ffi->g_type_from_name("gint64"), - "guint64" => $this->ffi->g_type_from_name("guint64"), - "gdouble" => $this->ffi->g_type_from_name("gdouble"), - "gchararray" => $this->ffi->g_type_from_name("gchararray"), - "VipsRefString" => $this->ffi->g_type_from_name("VipsRefString"), - - "GEnum" => $this->ffi->g_type_from_name("GEnum"), - "GFlags" => $this->ffi->g_type_from_name("GFlags"), - "VipsBandFormat" => $this->ffi->g_type_from_name("VipsBandFormat"), - "VipsBlendMode" => $this->ffi->g_type_from_name("VipsBlendMode"), - "VipsArrayInt" => $this->ffi->g_type_from_name("VipsArrayInt"), - "VipsArrayDouble" => - $this->ffi->g_type_from_name("VipsArrayDouble"), - "VipsArrayImage" => $this->ffi->g_type_from_name("VipsArrayImage"), - "VipsBlob" => $this->ffi->g_type_from_name("VipsBlob"), - - "GObject" => $this->ffi->g_type_from_name("GObject"), - "VipsImage" => $this->ffi->g_type_from_name("VipsImage"), - ]; - - $this->ffi->vips_leak_set(true); - - Utils::debugLog("init", ["done"]); - } -} diff --git a/src/Interpolate.php b/src/Interpolate.php index 703f3d3..6f594ea 100644 --- a/src/Interpolate.php +++ b/src/Interpolate.php @@ -62,8 +62,8 @@ class Interpolate extends VipsObject public function __construct($pointer) { - $this->pointer = Init::ffi()-> - cast(Init::ctypes("VipsInterpolate"), $pointer); + $this->pointer = Config::ffi()-> + cast(Config::ctypes("VipsInterpolate"), $pointer); parent::__construct($pointer); } @@ -89,9 +89,9 @@ public static function newFromName($name) 'arguments' => [$name] ]); - $pointer = Init::ffi()->vips_interpolate_new($name); + $pointer = Config::ffi()->vips_interpolate_new($name); if ($pointer == null) { - Init::error(); + Config::error(); } return new Interpolate($pointer); diff --git a/src/Introspect.php b/src/Introspect.php index ee48caf..b4aca43 100644 --- a/src/Introspect.php +++ b/src/Introspect.php @@ -97,13 +97,13 @@ public function __construct($name) $operation = VipsOperation::newFromName($name); $this->description = $operation->getDescription(); - $flags = Init::ffi()->vips_operation_get_flags($operation->pointer); + $flags = Config::ffi()->vips_operation_get_flags($operation->pointer); - $p_names = Init::ffi()->new("char**[1]"); - $p_flags = Init::ffi()->new("int*[1]"); - $p_n_args = Init::ffi()->new("int[1]"); - $result = Init::ffi()->vips_object_get_args( - \FFI::cast(Init::ctypes("VipsObject"), $operation->pointer), + $p_names = Config::ffi()->new("char**[1]"); + $p_flags = Config::ffi()->new("int*[1]"); + $p_n_args = Config::ffi()->new("int[1]"); + $result = Config::ffi()->vips_object_get_args( + \FFI::cast(Config::ctypes("VipsObject"), $operation->pointer), $p_names, $p_flags, $p_n_args @@ -148,7 +148,7 @@ public function __construct($name) $flags = $details["flags"]; $blurb = $details["blurb"]; $type = $details["type"]; - $typeName = Init::ffi()->g_type_name($type); + $typeName = Config::ffi()->g_type_name($type); if (($flags & ArgumentFlags::INPUT) && ($flags & ArgumentFlags::REQUIRED) && @@ -184,7 +184,7 @@ public function __construct($name) $this->member_this = ""; foreach ($this->required_input as $name) { $type = $this->arguments[$name]["type"]; - if ($type == Init::gtypes("VipsImage")) { + if ($type == Config::gtypes("VipsImage")) { $this->member_this = $name; break; } @@ -211,7 +211,7 @@ public function __toString() $flags = $details["flags"]; $blurb = $details["blurb"]; $type = $details["type"]; - $typeName = Init::ffi()->g_type_name($type); + $typeName = Config::ffi()->g_type_name($type); $result .= " $name:\n"; diff --git a/src/Utils.php b/src/Utils.php index fc3b87b..41c9602 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -92,7 +92,7 @@ public static function errorLog(string $message, \Exception $exception): void */ public static function typeFromName(string $name): int { - return Init::ffi()->g_type_from_name($name); + return Config::ffi()->g_type_from_name($name); } } diff --git a/src/VipsObject.php b/src/VipsObject.php index 6d8196e..2a027cf 100644 --- a/src/VipsObject.php +++ b/src/VipsObject.php @@ -68,10 +68,10 @@ abstract class VipsObject extends GObject public function __construct($pointer) { - $this->pointer = Init::ffi()-> - cast(Init::ctypes("VipsObject"), $pointer); - $this->gObject = Init::ffi()-> - cast(Init::ctypes("GObject"), $pointer); + $this->pointer = Config::ffi()-> + cast(Config::ctypes("VipsObject"), $pointer); + $this->gObject = Config::ffi()-> + cast(Config::ctypes("GObject"), $pointer); parent::__construct($pointer); } @@ -79,12 +79,12 @@ public function __construct($pointer) // print a table of all active vipsobjects ... handy for debugging public static function printAll() { - Init::ffi()->vips_object_print_all(); + Config::ffi()->vips_object_print_all(); } public function getDescription() { - return Init::ffi()->vips_object_get_description($this->pointer); + return Config::ffi()->vips_object_get_description($this->pointer); } // get the pspec for a property @@ -93,10 +93,10 @@ public function getDescription() // FIXME add a cache for this thing public function getPspec(string $name) { - $pspec = Init::ffi()->new("GParamSpec*[1]"); - $argument_class = Init::ffi()->new("VipsArgumentClass*[1]"); - $argument_instance = Init::ffi()->new("VipsArgumentInstance*[1]"); - $result = Init::ffi()->vips_object_get_argument( + $pspec = Config::ffi()->new("GParamSpec*[1]"); + $argument_class = Config::ffi()->new("VipsArgumentClass*[1]"); + $argument_instance = Config::ffi()->new("VipsArgumentInstance*[1]"); + $result = Config::ffi()->vips_object_get_argument( $this->pointer, $name, $pspec, @@ -118,7 +118,7 @@ public function getType(string $name) $pspec = $this->getPspec($name); if (\FFI::isNull($pspec)) { # need to clear any error, this is horrible - Init::ffi()->vips_error_clear(); + Config::ffi()->vips_error_clear(); return 0; } else { return $pspec->value_type; @@ -128,13 +128,13 @@ public function getType(string $name) public function getBlurb(string $name): string { $pspec = $this->getPspec($name); - return Init::ffi()->g_param_spec_get_blurb($pspec); + return Config::ffi()->g_param_spec_get_blurb($pspec); } public function getArgumentDescription(string $name): string { $pspec = $this->getPspec($name); - return Init::ffi()->g_param_spec_get_description($pspec); + return Config::ffi()->g_param_spec_get_description($pspec); } public function get(string $name) @@ -142,7 +142,7 @@ public function get(string $name) $gvalue = new GValue(); $gvalue->setType($this->getType($name)); - Init::ffi()-> + Config::ffi()-> g_object_get_property($this->gObject, $name, $gvalue->pointer); $value = $gvalue->get(); @@ -159,13 +159,13 @@ public function set(string $name, $value) $gvalue->setType($this->getType($name)); $gvalue->set($value); - Init::ffi()-> + Config::ffi()-> g_object_set_property($this->gObject, $name, $gvalue->pointer); } public function setString(string $string_options) { - $result = Init::ffi()-> + $result = Config::ffi()-> vips_object_set_from_string($this->pointer, $string_options); return $result == 0; @@ -173,7 +173,7 @@ public function setString(string $string_options) public function unrefOutputs() { - Init::ffi()->vips_object_unref_outputs($this->pointer); + Config::ffi()->vips_object_unref_outputs($this->pointer); } } diff --git a/src/VipsOperation.php b/src/VipsOperation.php index d29b06b..348bfba 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -66,17 +66,17 @@ class VipsOperation extends VipsObject public function __construct($pointer) { - $this->pointer = Init::ffi()-> - cast(Init::ctypes("VipsOperation"), $pointer); + $this->pointer = Config::ffi()-> + cast(Config::ctypes("VipsOperation"), $pointer); parent::__construct($pointer); } public static function newFromName($name) { - $pointer = Init::ffi()->vips_operation_new($name); + $pointer = Config::ffi()->vips_operation_new($name); if ($pointer == null) { - Init::error(); + Config::error(); } return new VipsOperation($pointer); @@ -88,9 +88,9 @@ public function setMatch($name, $match_image, $value) $gtype = $this->introspect->arguments[$name]["type"]; if ($match_image != null) { - if ($gtype == Init::gtypes("VipsImage")) { + if ($gtype == Config::gtypes("VipsImage")) { $value = $match_image->imageize($value); - } elseif ($gtype == Init::gtypes("VipsArrayImage") && + } elseif ($gtype == Config::gtypes("VipsArrayImage") && is_array($value)) { $new_value = []; foreach ($value as $x) { @@ -173,7 +173,7 @@ private static function unwrap(array $result): array private static function isImagePointer($value): bool { return $value instanceof \FFI\CData && - \FFI::typeof($value) == Init::ctypes("VipsImage"); + \FFI::typeof($value) == Config::ctypes("VipsImage"); } /** @@ -229,7 +229,7 @@ private static function wrapResult($result) private static function errorIsArray($result): void { if (!is_array($result)) { - Init::error(); + Config::error(); } } @@ -292,7 +292,7 @@ public static function callBase( if ($name == $operation->introspect->member_this) { if (!$instance) { $operation->unrefOutputs(); - Init::error("instance argument not supplied"); + Config::error("instance argument not supplied"); } $operation->setMatch($name, $match_image, $instance); $used_instance = true; @@ -301,7 +301,7 @@ public static function callBase( $n_used += 1; } else { $operation->unrefOutputs(); - Init::error("$n_required arguments required, " . + Config::error("$n_required arguments required, " . "but $n_supplied supplied"); } } @@ -316,7 +316,7 @@ public static function callBase( if ($n_supplied != $n_used) { $operation->unrefOutputs(); - Init::error("$n_required arguments required, " . + Config::error("$n_required arguments required, " . "but $n_supplied supplied"); } @@ -326,7 +326,7 @@ public static function callBase( if (!in_array($name, $operation->introspect->optional_input) && !in_array($name, $operation->introspect->optional_output)) { $operation->unrefOutputs(); - Init::error("optional argument '$name' does not exist"); + Config::error("optional argument '$name' does not exist"); } $operation->setMatch($name, $match_image, $value); @@ -335,11 +335,11 @@ public static function callBase( /* Build the operation */ Utils::debugLog("callBase", ["building ..."]); - $pointer = Init::ffi()-> + $pointer = Config::ffi()-> vips_cache_operation_build($operation->pointer); if ($pointer == null) { $operation->unrefOutputs(); - Init::error(); + Config::error(); } $operation = new VipsOperation($pointer); $operation->introspect = self::introspect($operation_name); From 44ad854c1c41dcdb322e64d4e5d551e738728274 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 11:43:11 +0000 Subject: [PATCH 45/58] start fixing up tests again --- src/Config.php | 8 ++- src/Image.php | 154 ++++++++++------------------------------- src/Utils.php | 2 +- tests/ShortcutTest.php | 7 +- 4 files changed, 45 insertions(+), 126 deletions(-) diff --git a/src/Config.php b/src/Config.php index 2441d38..0b324b5 100644 --- a/src/Config.php +++ b/src/Config.php @@ -173,7 +173,11 @@ public static function concurrencySet(int $value): void */ public static function version(): string { - return Config::ffi()->vips_version(); + Config::ffi(); + + return self::$library_major . "." . + self::$library_minor . ".". + self::$library_micro; } /** @@ -666,6 +670,8 @@ private static function init() int vips_operation_get_flags (VipsOperation* operation); +void vips_concurrency_set( int concurrency ); + void vips_cache_set_max (int max); void vips_cache_set_max_mem (size_t max_mem); void vips_cache_set_max_files (int max_files); diff --git a/src/Image.php b/src/Image.php index ddc1678..56ea1fc 100644 --- a/src/Image.php +++ b/src/Image.php @@ -499,82 +499,6 @@ */ class Image extends ImageAutodoc implements \ArrayAccess { - /** - * Map load nicknames to canonical names. Regenerate this table with - * something like: - * - * $ vips -l foreign | grep -i load | awk '{ print $2, $1; }' - * - * Plus a bit of editing. - * - * @internal - */ - private static $nicknameToCanonical = [ - 'csvload' => 'VipsForeignLoadCsv', - 'matrixload' => 'VipsForeignLoadMatrix', - 'rawload' => 'VipsForeignLoadRaw', - 'vipsload' => 'VipsForeignLoadVips', - 'analyzeload' => 'VipsForeignLoadAnalyze', - 'ppmload' => 'VipsForeignLoadPpm', - 'radload' => 'VipsForeignLoadRad', - 'pdfload' => 'VipsForeignLoadPdfFile', - 'pdfload_buffer' => 'VipsForeignLoadPdfBuffer', - 'svgload' => 'VipsForeignLoadSvgFile', - 'svgload_buffer' => 'VipsForeignLoadSvgBuffer', - 'gifload' => 'VipsForeignLoadGifFile', - 'gifload_buffer' => 'VipsForeignLoadGifBuffer', - 'pngload' => 'VipsForeignLoadPng', - 'pngload_buffer' => 'VipsForeignLoadPngBuffer', - 'matload' => 'VipsForeignLoadMat', - 'jpegload' => 'VipsForeignLoadJpegFile', - 'jpegload_buffer' => 'VipsForeignLoadJpegBuffer', - 'webpload' => 'VipsForeignLoadWebpFile', - 'webpload_buffer' => 'VipsForeignLoadWebpBuffer', - 'tiffload' => 'VipsForeignLoadTiffFile', - 'tiffload_buffer' => 'VipsForeignLoadTiffBuffer', - 'magickload' => 'VipsForeignLoadMagickFile', - 'magickload_buffer' => 'VipsForeignLoadMagickBuffer', - 'fitsload' => 'VipsForeignLoadFits', - 'openexrload' => 'VipsForeignLoadOpenexr' - ]; - - /** - * Combine takes an array of blend modes, passed to libvips as an array of - * int. Because libvips does not know they should be enums, we have to do - * the string->int conversion ourselves. We ought to introspect to find the - * mapping, but until we have the machinery for that, we just hardwire the - * mapping here. - * - * @internal - */ - private static $blendModeToInt = [ - BlendMode::CLEAR => 0, - BlendMode::SOURCE => 1, - BlendMode::OVER => 2, - BlendMode::IN => 3, - BlendMode::OUT => 4, - BlendMode::ATOP => 5, - BlendMode::DEST => 6, - BlendMode::DEST_OVER => 7, - BlendMode::DEST_IN => 8, - BlendMode::DEST_OUT => 9, - BlendMode::DEST_ATOP => 10, - BlendMode::XOR1 => 11, - BlendMode::ADD => 12, - BlendMode::SATURATE => 13, - BlendMode::MULTIPLY => 14, - BlendMode::SCREEN => 15, - BlendMode::OVERLAY => 16, - BlendMode::DARKEN => 17, - BlendMode::LIGHTEN => 18, - BlendMode::COLOUR_DODGE => 19, - BlendMode::COLOUR_BURN => 20, - BlendMode::HARD_LIGHT => 21, - BlendMode::SOFT_LIGHT => 22, - BlendMode::DIFFERENCE => 23, - BlendMode::EXCLUSION => 24 - ]; - /** * A pointer to the underlying VipsImage. This is the same as the * GObject, just cast to VipsImage to help FFI. @@ -770,9 +694,9 @@ private function callEnum( return VipsOperation::call($base, $this, [$other, $op], $options); } else { return VipsOperation::call( - $base . '_const', - $this, - [$op, $other], + $base . '_const', + $this, + [$op, $other], $options ); } @@ -1669,9 +1593,9 @@ public function remainder($other, array $options = []): Image return VipsOperation::call('remainder', $this, [$other], $options); } else { return VipsOperation::call( - 'remainder_const', - $this, - [$other], + 'remainder_const', + $this, + [$other], $options ); } @@ -1735,9 +1659,9 @@ public function lshift($other, array $options = []): Image public function rshift($other, array $options = []): Image { return self::callEnum( - $other, - 'boolean', - OperationBoolean::RSHIFT, + $other, + 'boolean', + OperationBoolean::RSHIFT, $options ); } @@ -1788,9 +1712,9 @@ public function orimage($other, array $options = []): Image public function eorimage($other, array $options = []): Image { return self::callEnum( - $other, - 'boolean', - OperationBoolean::EOR, + $other, + 'boolean', + OperationBoolean::EOR, $options ); } @@ -1808,9 +1732,9 @@ public function eorimage($other, array $options = []): Image public function more($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::MORE, + $other, + 'relational', + OperationRelational::MORE, $options ); } @@ -1828,9 +1752,9 @@ public function more($other, array $options = []): Image public function moreEq($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::MOREEQ, + $other, + 'relational', + OperationRelational::MOREEQ, $options ); } @@ -1848,9 +1772,9 @@ public function moreEq($other, array $options = []): Image public function less($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::LESS, + $other, + 'relational', + OperationRelational::LESS, $options ); } @@ -1868,9 +1792,9 @@ public function less($other, array $options = []): Image public function lessEq($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::LESSEQ, + $other, + 'relational', + OperationRelational::LESSEQ, $options ); } @@ -1888,9 +1812,9 @@ public function lessEq($other, array $options = []): Image public function equal($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::EQUAL, + $other, + 'relational', + OperationRelational::EQUAL, $options ); } @@ -1908,9 +1832,9 @@ public function equal($other, array $options = []): Image public function notEq($other, array $options = []): Image { return self::callEnum( - $other, - 'relational', - OperationRelational::NOTEQ, + $other, + 'relational', + OperationRelational::NOTEQ, $options ); } @@ -1949,9 +1873,9 @@ public function bandjoin($other, array $options = []): Image */ if ($is_const) { return VipsOperation::call( - 'bandjoin_const', - $this, - [$other], + 'bandjoin_const', + $this, + [$other], $options ); } else { @@ -2039,12 +1963,6 @@ public function composite($other, $mode, array $options = []): Image $mode = [$mode]; } - $mode = array_map( - // Use BlendMode::OVER if a non-existent value is given. - fn($x) => self::$blendModeToInt[$x] ?? BlendMode::OVER, - $mode - ); - return VipsOperation::call( 'composite', null, @@ -2122,9 +2040,9 @@ public function ifthenelse($then, $else, array $options = []): Image } return VipsOperation::call( - 'ifthenelse', - $this, - [$then, $else], + 'ifthenelse', + $this, + [$then, $else], $options ); } diff --git a/src/Utils.php b/src/Utils.php index 41c9602..d5ee068 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -92,7 +92,7 @@ public static function errorLog(string $message, \Exception $exception): void */ public static function typeFromName(string $name): int { - return Config::ffi()->g_type_from_name($name); + return Config::ffi()->g_type_from_name($name); } } diff --git a/tests/ShortcutTest.php b/tests/ShortcutTest.php index 3bbf2fe..a4cc80c 100644 --- a/tests/ShortcutTest.php +++ b/tests/ShortcutTest.php @@ -207,13 +207,8 @@ public function testOffsetSet() // replace band with image $test = $image->copy(); $test[1] = $base; - $avg = $test->avg(); - - exit; - $this->assertEquals($avg, 2.666); - - + $this->assertTrue(abs($avg - 2.666) < 0.001); $this->assertEquals($test->bands, 3); $this->assertEquals($test[0]->avg(), 2); $this->assertEquals($test[1]->avg(), 2); From 9c0bcce5e1b21dc7177028940951d68ed927b283 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 12:48:57 +0000 Subject: [PATCH 46/58] all tests pass cleanly --- README.md | 4 +--- src/Config.php | 13 +++++++++++-- src/GValue.php | 8 ++++---- src/Image.php | 14 +++++++++++++- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6d34058..98a254b 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,7 @@ destination in a set of small fragments. - Needs a refs system for newFromMemory etc. -- nicknameToCanonical needs redoing for FFI - -- blendModeToInt needs redoing for FFI +- Support preloading, see https://www.php.net/manual/en/class.ffi.php - Read and check the whole diff. diff --git a/src/Config.php b/src/Config.php index 0b324b5..9836606 100644 --- a/src/Config.php +++ b/src/Config.php @@ -175,8 +175,8 @@ public static function version(): string { Config::ffi(); - return self::$library_major . "." . - self::$library_minor . ".". + return self::$library_major . "." . + self::$library_minor . ".". self::$library_micro; } @@ -773,6 +773,15 @@ private static function init() Utils::debugLog("init", ["binding ..."]); self::$ffi = \FFI::cdef($header, $library); + # force the creation of some types we need + self::$ffi->vips_blend_mode_get_type(); + self::$ffi->vips_interpretation_get_type(); + self::$ffi->vips_operation_flags_get_type(); + self::$ffi->vips_band_format_get_type(); + self::$ffi->vips_token_get_type(); + self::$ffi->vips_saveable_get_type(); + self::$ffi->vips_image_type_get_type(); + // look these up in advance self::$ctypes = [ "GObject" => self::$ffi->type("GObject*"), diff --git a/src/GValue.php b/src/GValue.php index a4b9d10..c0ce60d 100644 --- a/src/GValue.php +++ b/src/GValue.php @@ -61,6 +61,8 @@ public static function toEnum($gtype, $value) $enum_value = Config::ffi()-> vips_enum_from_nick("php-vips", $gtype, $value); if ($enum_value < 0) { + echo "gtype = " . $gtype . "\n"; + echo "value = " . $value . "\n"; Config::error(); } } else { @@ -244,17 +246,15 @@ public function get() break; case Config::gtypes("gchararray"): - $c_string = Config::ffi()->g_value_get_string($this->pointer); - $result = \FFI::string($c_string); + $result = Config::ffi()->g_value_get_string($this->pointer); break; case Config::gtypes("VipsRefString"): $p_size = Config::ffi()->new("size_t[1]"); - $c_string = Config::ffi()-> + $result = Config::ffi()-> vips_value_get_ref_string($this->pointer, $p_size); # $p_size[0] will be the string length, but assume it's null # terminated - $result = \FFI::string($c_string); break; case Config::gtypes("VipsImage"): diff --git a/src/Image.php b/src/Image.php index 56ea1fc..3292880 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1488,9 +1488,14 @@ public function offsetUnset($offset): void $head = array_shift($components); if (empty($components)) { + $head->ref(); + $this->unref(); $this->pointer = $head->pointer; } else { - $this->pointer = $head->bandjoin($components)->pointer; + $new_image = $head->bandjoin($components); + $new_image->ref(); + $this->unref(); + $this->pointer = $new_image->pointer; } } } @@ -1959,10 +1964,17 @@ public function composite($other, $mode, array $options = []): Image } else { $other = (array) $other; } + if (!is_array($mode)) { $mode = [$mode]; } + # composite takes an arrayint, but it's really an array of blend modes + # gvalue doesn't know this, so we must do name -> enum value mapping + $mode = array_map(function ($x) { + return GValue::toEnum(Config::gtypes("VipsBlendMode"), $x); + }, $mode); + return VipsOperation::call( 'composite', null, From 01e4e9fe479b26bcb8367398f422ff3ed39a6633 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 16:03:44 +0000 Subject: [PATCH 47/58] use new_from_memory_copy for now --- README.md | 14 ++++++-------- src/Config.php | 2 ++ src/Image.php | 10 +++++++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 98a254b..22fe864 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build Status](https://travis-ci.org/libvips/php-vips.svg?branch=master)](https://travis-ci.org/libvips/php-vips) `php-vips` is a binding for [libvips](https://github.com/libvips/libvips) for -PHP 7.4 and later. +PHP 7.4 and later, and libvips 8.7 and later. libvips is fast and needs little memory. The [`vips-php-bench`](https://github.com/jcupitt/php-vips-bench) repository @@ -19,18 +19,16 @@ destination in a set of small fragments. ## TODO -- Needs a refs system for newFromMemory etc. - -- Support preloading, see https://www.php.net/manual/en/class.ffi.php - - Read and check the whole diff. -- Rewrite the enum generator in php. - -- Revise docs. +- Review docs. ### After merge +- Support preloading, see https://www.php.net/manual/en/class.ffi.php + +- Rewrite the enum generator in php. + - Add source/target API - Add progress callbacks etc. diff --git a/src/Config.php b/src/Config.php index 9836606..8c1bafa 100644 --- a/src/Config.php +++ b/src/Config.php @@ -614,6 +614,8 @@ private static function init() const double* array, int size); VipsImage* vips_image_new_from_memory (const void* data, size_t size, int width, int height, int bands, int format); +VipsImage* vips_image_new_from_memory_copy (const void *data, size_t size, + int width, int height, int bands, int format); VipsImage* vips_image_copy_memory (VipsImage* image); diff --git a/src/Image.php b/src/Image.php index 3292880..544115f 100644 --- a/src/Image.php +++ b/src/Image.php @@ -842,7 +842,7 @@ public static function newFromArray( /** * Wraps an Image around an area of memory containing a C-style array. * - * @param string $data C-style array. + * @param mixed $data C-style array. * @param int $width Image width in pixels. * @param int $height Image height in pixels. * @param int $bands Number of bands. @@ -853,7 +853,7 @@ public static function newFromArray( * @return Image A new Image. */ public static function newFromMemory( - string $data, + mixed $data, int $width, int $height, int $bands, @@ -864,7 +864,11 @@ public static function newFromMemory( 'arguments' => [$data, $width, $height, $bands, $format] ]); - $pointer = Config::ffi()->vips_image_new_from_memory( + /* Take a copy of the memory area to avoid lifetime issues. + * + * TODO add a references system instead, see pyvips. + */ + $pointer = Config::ffi()->vips_image_new_from_memory_copy( $data, strlen($data), $width, From 249d7fa9e652c424d00325953a74984a3088ac07 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 16:11:52 +0000 Subject: [PATCH 48/58] revise docs --- README.md | 50 ++++++++++++++------------------------------------ composer.json | 2 +- src/Image.php | 31 ++++--------------------------- 3 files changed, 19 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 22fe864..592ef6b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![Build Status](https://travis-ci.org/libvips/php-vips.svg?branch=master)](https://travis-ci.org/libvips/php-vips) -`php-vips` is a binding for [libvips](https://github.com/libvips/libvips) for -PHP 7.4 and later, and libvips 8.7 and later. +`php-vips` is a binding for [libvips](https://github.com/libvips/libvips) 8.7 +and later for PHP 7.4 and later. libvips is fast and needs little memory. The [`vips-php-bench`](https://github.com/jcupitt/php-vips-bench) repository @@ -17,24 +17,6 @@ image. When the pipe is connected to a destination, the whole pipeline executes at once and in parallel, streaming the image from source to destination in a set of small fragments. -## TODO - -- Read and check the whole diff. - -- Review docs. - -### After merge - -- Support preloading, see https://www.php.net/manual/en/class.ffi.php - -- Rewrite the enum generator in php. - -- Add source/target API - -- Add progress callbacks etc. - -- Add mutable. - ### Install You need to [install the libvips @@ -54,22 +36,6 @@ brew install vips Then add vips to your `composer.json`: -``` -{ - "repositories": [ - { - "type": "path", - "url": "/your/local/path/to/php-vips" - } - ], - "require": { - "jcupitt/vips": "*" - } -} -``` - -Once this is finished, switch to: - ``` "require": { "jcupitt/vips" : "2.0.0" @@ -166,6 +132,18 @@ introduction: https://libvips.github.io/libvips/API/current +### TODO after merge + +- Support preloading, see https://www.php.net/manual/en/class.ffi.php + +- Rewrite the enum and doc generator in php. + +- Add source/target API + +- Add progress callbacks etc. + +- Add mutable. + ### Test and install ``` diff --git a/composer.json b/composer.json index 3d5aa7f..faa5a71 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "scripts": { diff --git a/src/Image.php b/src/Image.php index 544115f..f57c5e8 100644 --- a/src/Image.php +++ b/src/Image.php @@ -42,11 +42,8 @@ * This class represents a Vips image object. * * This module provides a binding for the [vips image processing - * library](https://jcupitt.github.io/libvips/). - * - * It needs libvips 8.0 or later to be installed, and it needs the binary - * [`vips` extension](https://github.com/jcupitt/php-vips-ext) to be added to - * your PHP. + * library](https://libvips.org) version 8.7 and later, and required PHP 7.4 + * and later. * * # Example * @@ -213,26 +210,6 @@ * Use `$image->get('ipct-data')` for property names which are not valid under * PHP syntax. * - * # How it works - * - * The binary - * [`vips` extension](https://github.com/jcupitt/php-vips-ext) adds a few extra - * functions to PHP to let you call anything in the libvips library. The API - * it provides is simple, but horrible. - * - * This module is pure PHP and builds on the binary extension to provide a - * convenient interface for programmers. It uses the PHP magic methods - * `__call()`, `__callStatic()`, `__get()` and `__set()` to make vips operators - * appear as methods on the `Image` class, and vips properties as PHP - * properties. - * - * The API you end up with is a object-oriented version of the [VIPS C - * API](https://jcupitt.github.io/libvips/API/current). - * Full documentation - * on the operations and what they do is there, you can use it directly. This - * document explains the extra features of the PHP API and lists the available - * operations very briefly. - * * # Automatic wrapping * * This binding has a `__call()` method and uses @@ -249,8 +226,8 @@ * produces several results. * * For example, `Image::min`, the vips operation that searches an image for - * the minimum value, has a large number of optional arguments. You can use it to - * find the minimum value like this: + * the minimum value, has a large number of optional arguments. You can use it + * to find the minimum value like this: * * ```php * $min_value = $image->min(); From ed25bc9ae2aec9412da61db09f1eb4884645ce0d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Mar 2022 16:20:02 +0000 Subject: [PATCH 49/58] final checks --- CHANGELOG.md | 17 +++++++++++-- examples/composer.json | 9 +------ examples/watermark-image.php | 46 ++++++++++++++++-------------------- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef05be..f41a017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,22 @@ All notable changes to `:vips` will be documented in this file. ## 2.0.0 - 2022-1-20 Rewritten to use PHP FFI to call into the libvips library rather than a binary -extension. +extension. This means php-vips now requires php 7.4 or later. -No API Changes. +### Added +- `Interpolate` class + +### Deprecated +- Nothing + +### Fixed +- Nothing + +### Remove +- Nothing + +### Security +- Nothing ### 1.0.9 - 2021-11-20 diff --git a/examples/composer.json b/examples/composer.json index 40d7c46..2de9b0e 100644 --- a/examples/composer.json +++ b/examples/composer.json @@ -1,12 +1,5 @@ { - "minimum-stability": "dev", - "repositories": [ - { - "type": "path", - "url": "/home/john/GIT/php-vips" - } - ], "require": { - "jcupitt/vips": "*" + "jcupitt/vips": "2.0.0" } } diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 46c166e..f581c05 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -4,42 +4,38 @@ require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; -#Vips\Config::setLogger(new Vips\DebugLogger()); +# Vips\Config::setLogger(new Vips\DebugLogger()); if (count($argv) != 4) { echo("usage: ./watermark.php input-image output-image watermark-image\n"); exit(1); } -for ($i = 0; $i < 10000; $i++) { - echo "loop $i ...\n"; +// we can stream the main image +$image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); - // we can stream the main image - $image = Vips\Image::newFromFile($argv[1], ['access' => 'sequential']); +// we'll read the watermark image many times, so we need random access for this +$watermark = Vips\Image::newFromFile($argv[3]); - // we'll read the watermark image many times, so we need random access for this - $watermark = Vips\Image::newFromFile($argv[3]); - - // the watermark image needs to have an alpha channel - if (!$watermark->hasAlpha() || $watermark->bands != 4) { - echo("watermark image is not RGBA\n"); - exit(1); - } +// the watermark image needs to have an alpha channel +if (!$watermark->hasAlpha() || $watermark->bands != 4) { + echo("watermark image is not RGBA\n"); + exit(1); +} - // make the watermark semi-transparent - $watermark = $watermark->multiply([1, 1, 1, 0.3])->cast("uchar"); +// make the watermark semi-transparent +$watermark = $watermark->multiply([1, 1, 1, 0.3])->cast("uchar"); - // repeat the watermark to the size of the image - $watermark = $watermark->replicate( - 1 + $image->width / $watermark->width, - 1 + $image->height / $watermark->height - ); - $watermark = $watermark->crop(0, 0, $image->width, $image->height); +// repeat the watermark to the size of the image +$watermark = $watermark->replicate( + 1 + $image->width / $watermark->width, + 1 + $image->height / $watermark->height +); +$watermark = $watermark->crop(0, 0, $image->width, $image->height); - // composite the watermark over the main image - $image = $image->composite2($watermark, 'over'); +// composite the watermark over the main image +$image = $image->composite2($watermark, 'over'); - $image->writeToFile($argv[2]); -} +$image->writeToFile($argv[2]); Vips\Init::shutDown(); From 998ca6de2a567c95e9314ffe3d9a77b22ce4c53a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 6 Mar 2022 16:26:42 +0000 Subject: [PATCH 50/58] add findLoad and findLoadBuffer thanks chregu ! --- examples/watermark-image.php | 4 +-- src/Config.php | 2 -- src/Image.php | 54 +++++++++++++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index f581c05..c132070 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -36,6 +36,4 @@ // composite the watermark over the main image $image = $image->composite2($watermark, 'over'); -$image->writeToFile($argv[2]); - -Vips\Init::shutDown(); +Vips\Config::shutDown(); diff --git a/src/Config.php b/src/Config.php index 8c1bafa..24f3d14 100644 --- a/src/Config.php +++ b/src/Config.php @@ -816,8 +816,6 @@ private static function init() "VipsImage" => self::$ffi->g_type_from_name("VipsImage"), ]; - self::$ffi->vips_leak_set(true); - Utils::debugLog("init", ["done"]); } } diff --git a/src/Image.php b/src/Image.php index f57c5e8..ffc717c 100644 --- a/src/Image.php +++ b/src/Image.php @@ -679,6 +679,29 @@ private function callEnum( } } + /** + * Find the name of the load operation vips will use to load a file, for + * example "VipsForeignLoadJpegFile". You can use this to work out what + * options to pass to newFromFile(). + * + * @param string $filename The file to test. + * + * @return string|null The name of the load operation, or null. + */ + public static function findLoad(string $filename): ?string + { + Utils::debugLog('findLoad', [ + 'instance' => null, + 'arguments' => [$filename] + ]); + + $result = Config::ffi()->vips_foreign_find_load($filename); + + Utils::debugLog('findLoad', ['result' => [$result]]); + + return $result; + } + /** * Create a new Image from a file on disc. * @@ -701,8 +724,8 @@ public static function newFromFile( $filename = Config::filenameGetFilename($name); $string_options = Config::filenameGetOptions($name); - $loader = Config::ffi()->vips_foreign_find_load($filename); - if ($loader == "") { + $loader = self::findLoad($filename); + if ($loader == null) { Config::error(); } @@ -719,6 +742,30 @@ public static function newFromFile( return $result; } + /** + * Find the name of the load operation vips will use to load a buffer, for + * example 'VipsForeignLoadJpegBuffer'. You can use this to work out what + * options to pass to newFromBuffer(). + * + * @param string $buffer The formatted image to test. + * + * @return string|null The name of the load operation, or null. + */ + public static function findLoadBuffer(string $buffer): ?string + { + Utils::debugLog('findLoadBuffer', [ + 'instance' => null, + 'arguments' => [$buffer] + ]); + + $result = Config::ffi()-> + vips_foreign_find_load_buffer($buffer, strlen($buffer)); + + Utils::debugLog('findLoadBuffer', ['result' => [$result]]); + + return $result; + } + /** * Create a new Image from a compressed image held as a string. * @@ -741,8 +788,7 @@ public static function newFromBuffer( 'arguments' => [$buffer, $string_options, $options] ]); - $loader = Config::ffi()-> - vips_foreign_find_load_buffer($buffer, strlen($buffer)); + $loader = self::findLoadBuffer($buffer); if ($loader == null) { Config::error(); } From 156a772383909f302e8da6d16234db668a9a6e8c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 15:17:24 +0000 Subject: [PATCH 51/58] add writeToArray() thanks chregu --- examples/watermark-image.php | 5 +++++ src/Config.php | 22 ++++++++++++++++++++++ src/Image.php | 30 ++++++++++++++++++++++++++---- tests/WriteTest.php | 12 ++++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index c132070..3b580d6 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -36,4 +36,9 @@ // composite the watermark over the main image $image = $image->composite2($watermark, 'over'); +$image->writeToFile($argv[2]); + +$image = null; +$watermark = null; + Vips\Config::shutDown(); diff --git a/src/Config.php b/src/Config.php index 24f3d14..21e27a3 100644 --- a/src/Config.php +++ b/src/Config.php @@ -84,6 +84,7 @@ class Config */ private static array $ctypes; private static array $gtypes; + private static array $ftypes; /** * Sets a logger. This can be handy for debugging. For example: @@ -212,6 +213,13 @@ public static function gtypes(string $name) return self::$gtypes[$name]; } + public static function ftypes(string $name) + { + Config::ffi(); + + return self::$ftypes[$name]; + } + /** * Throw a vips error as an exception. * @@ -816,6 +824,20 @@ private static function init() "VipsImage" => self::$ffi->g_type_from_name("VipsImage"), ]; + // map vips format names to c type names + self::$ftypes = [ + "char" => "char", + "uchar" => "unsigned char", + "short" => "short", + "ushort" => "unsigned short", + "int" => "int", + "uint" => "unsigned int", + "float" => "float", + "double" => "double", + "complex" => "float", + "dpcomplex" => "double", + ]; + Utils::debugLog("init", ["done"]); } } diff --git a/src/Image.php b/src/Image.php index ffc717c..562e4f8 100644 --- a/src/Image.php +++ b/src/Image.php @@ -42,7 +42,7 @@ * This class represents a Vips image object. * * This module provides a binding for the [vips image processing - * library](https://libvips.org) version 8.7 and later, and required PHP 7.4 + * library](https://libvips.org) version 8.7 and later, and required PHP 7.4 * and later. * * # Example @@ -226,7 +226,7 @@ * produces several results. * * For example, `Image::min`, the vips operation that searches an image for - * the minimum value, has a large number of optional arguments. You can use it + * the minimum value, has a large number of optional arguments. You can use it * to find the minimum value like this: * * ```php @@ -1068,8 +1068,11 @@ public function writeToMemory(): string Config::error(); } + // string() takes a copy $result = \FFI::string($pointer, $p_size[0]); + Config::ffi()->g_free($pointer); + Utils::debugLog('writeToMemory', ['result' => $result]); return $result; @@ -1105,11 +1108,30 @@ public function writeToArray(): array 'arguments' => [] ]); - $result = Config::ffi()->vips_image_write_to_array($this->pointer); - if ($result === -1) { + $ctype = \FFI::arrayType(\FFI::type("size_t"), [1]); + $p_size = \FFI::new($ctype); + + $pointer = Config::ffi()-> + vips_image_write_to_memory($this->pointer, $p_size); + if ($pointer == null) { Config::error(); } + // wrap pointer up as a C array of the right type + $n = $this->width * $this->height * $this->bands; + $type_name = Config::ftypes($this->format); + $ctype = \FFI::arrayType(\FFI::type($type_name), [$n]); + $array = \FFI::cast($ctype, $pointer); + + // copy to PHP memory as a flat array + $result = []; + for ($i = 0; $i < $n; $i++) { + $result[] = $array[$i]; + } + + // the vips result is not PHP memory, so we must free it + Config::ffi()->g_free($pointer); + Utils::debugLog('writeToArray', ['result' => $result]); return $result; diff --git a/tests/WriteTest.php b/tests/WriteTest.php index cc27b81..de2169d 100644 --- a/tests/WriteTest.php +++ b/tests/WriteTest.php @@ -68,6 +68,18 @@ public function testVipsWriteToMemory() $this->assertEquals($binaryStr, $memStr); } + + public function testVipsWriteToArray() + { + $filename = __DIR__ . '/images/img_0076.jpg'; + $image = Vips\Image::newFromFile($filename, ['shrink' => 8]); + $array = $image->crop(0, 0, 2, 2)->writeToArray(); + + $this->assertEquals( + $array, + [34, 39, 35, 44, 49, 45, 67, 52, 49, 120, 105, 102] + ); + } } /* From ff75115c2087b33e7485725164c4063ba1b285c9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 15:21:26 +0000 Subject: [PATCH 52/58] Update src/Config.php Co-authored-by: Kleis Auke Wolthuizen --- src/Config.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Config.php b/src/Config.php index 21e27a3..77b238f 100644 --- a/src/Config.php +++ b/src/Config.php @@ -382,9 +382,6 @@ private static function init() void vips_leak_set (int leak); -char* vips_path_filename7 (const char* path); -char* vips_path_mode7 (const char* path); - GType vips_type_find (const char* basename, const char* nickname); const char* vips_nickname_find (GType type); From 2b0cfc83c7bcee119c9833794563b25316495bc3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 15:22:26 +0000 Subject: [PATCH 53/58] incorporate review comments --- composer.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index faa5a71..2c61251 100644 --- a/composer.json +++ b/composer.json @@ -18,13 +18,14 @@ ], "require": { "php": ">=7.4", + "ext-ffi": "*", "psr/log": "^1.1.3|^2.0|^3.0" }, "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpdocumentor/phpdocumentor": "3.0.0", - "phpunit/phpunit": "^9.3", - "squizlabs/php_codesniffer": "^3.5" + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpdocumentor/shim": "^3.3", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.6" }, "autoload": { "psr-4": { From 47d9fbb52ee23f3943e1fe9a9063cba1456a729b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 15:34:35 +0000 Subject: [PATCH 54/58] fix testVipsWriteToBuffer with options thabnks kleis --- src/Image.php | 2 +- tests/WriteTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Image.php b/src/Image.php index 562e4f8..6c98716 100644 --- a/src/Image.php +++ b/src/Image.php @@ -1038,7 +1038,7 @@ public function writeToBuffer(string $suffix, array $options = []): string ], $options); } - $result = VipsOperation::call($saver, $this, $options); + $result = VipsOperation::call($saver, $this, [], $options); Utils::debugLog('writeToBuffer', ['result' => $result]); diff --git a/tests/WriteTest.php b/tests/WriteTest.php index de2169d..ed592f7 100644 --- a/tests/WriteTest.php +++ b/tests/WriteTest.php @@ -52,7 +52,7 @@ public function testVipsWriteToBuffer() $filename = __DIR__ . '/images/img_0076.jpg'; $image = Vips\Image::newFromFile($filename, ['shrink' => 8]); - $buffer1 = $image->writeToBuffer('.jpg'); + $buffer1 = $image->writeToBuffer('.jpg', ['Q' => 75]); $output_filename = $this->tmp('.jpg'); $image->writeToFile($output_filename); $buffer2 = file_get_contents($output_filename); From 387f4c18e0ea80bc1e5fd3c7ad80499a8a8e119f Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 18:42:41 +0000 Subject: [PATCH 55/58] try to improve shared library finding --- src/Config.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/Config.php b/src/Config.php index 77b238f..5553f2f 100644 --- a/src/Config.php +++ b/src/Config.php @@ -285,7 +285,8 @@ private static function init() switch (PHP_OS_FAMILY) { case "Windows": - $library_ext = ".dll"; + // win needs the ABI number before the .dll + $library_ext = "42.dll"; break; case "OSX": @@ -293,19 +294,14 @@ private static function init() break; default: - $library_ext = ".so"; + // many *nix distributions only add the "libvips.so" symlink + // if the dev package is installed + $library_ext = ".so.42"; break; } - $vipshome = getenv("VIPSHOME"); - if ($vipshome) { - $library_location = $vipshome . "/lib/"; - } else { - # rely on ffi's search - $library_location = ""; - } + $library = "$library_name$library_ext"; - $library = "$library_location$library_name$library_ext"; Utils::debugLog("init", ["libray" => $library]); /* FIXME ... maybe display a helpful message on failure? This will From 009411db96c2ffbeb3c0f1a084c1441f6c46409d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 18:49:44 +0000 Subject: [PATCH 56/58] make debugLog less chatty --- examples/watermark-image.php | 2 +- src/Image.php | 85 ------------------------------------ src/Interpolate.php | 4 -- src/VipsOperation.php | 2 - 4 files changed, 1 insertion(+), 92 deletions(-) diff --git a/examples/watermark-image.php b/examples/watermark-image.php index 3b580d6..195343f 100755 --- a/examples/watermark-image.php +++ b/examples/watermark-image.php @@ -4,7 +4,7 @@ require __DIR__ . '/vendor/autoload.php'; use Jcupitt\Vips; -# Vips\Config::setLogger(new Vips\DebugLogger()); +Vips\Config::setLogger(new Vips\DebugLogger()); if (count($argv) != 4) { echo("usage: ./watermark.php input-image output-image watermark-image\n"); diff --git a/src/Image.php b/src/Image.php index 6c98716..c6de83a 100644 --- a/src/Image.php +++ b/src/Image.php @@ -690,15 +690,8 @@ private function callEnum( */ public static function findLoad(string $filename): ?string { - Utils::debugLog('findLoad', [ - 'instance' => null, - 'arguments' => [$filename] - ]); - $result = Config::ffi()->vips_foreign_find_load($filename); - Utils::debugLog('findLoad', ['result' => [$result]]); - return $result; } @@ -716,11 +709,6 @@ public static function newFromFile( string $name, array $options = [] ): Image { - Utils::debugLog('newFromFile', [ - 'instance' => null, - 'arguments' => [$name, $options] - ]); - $filename = Config::filenameGetFilename($name); $string_options = Config::filenameGetOptions($name); @@ -737,8 +725,6 @@ public static function newFromFile( $result = VipsOperation::call($loader, null, [$filename], $options); - Utils::debugLog('newFromFile', ['result' => $result]); - return $result; } @@ -753,16 +739,9 @@ public static function newFromFile( */ public static function findLoadBuffer(string $buffer): ?string { - Utils::debugLog('findLoadBuffer', [ - 'instance' => null, - 'arguments' => [$buffer] - ]); - $result = Config::ffi()-> vips_foreign_find_load_buffer($buffer, strlen($buffer)); - Utils::debugLog('findLoadBuffer', ['result' => [$result]]); - return $result; } @@ -783,11 +762,6 @@ public static function newFromBuffer( string $string_options = '', array $options = [] ): Image { - Utils::debugLog('newFromBuffer', [ - 'instance' => null, - 'arguments' => [$buffer, $string_options, $options] - ]); - $loader = self::findLoadBuffer($buffer); if ($loader == null) { Config::error(); @@ -801,8 +775,6 @@ public static function newFromBuffer( $result = VipsOperation::call($loader, null, [$buffer], $options); - Utils::debugLog('newFromBuffer', ['result' => $result]); - return $result; } @@ -826,11 +798,6 @@ public static function newFromArray( float $scale = 1.0, float $offset = 0.0 ): Image { - Utils::debugLog('newFromArray', [ - 'instance' => null, - 'arguments' => [$array, $scale, $offset] - ]); - if (!self::is2D($array)) { $array = [$array]; } @@ -857,8 +824,6 @@ public static function newFromArray( $result->setType(Config::gtypes("gdouble"), 'scale', $scale); $result->setType(Config::gtypes("gdouble"), 'offset', $offset); - Utils::debugLog('newFromArray', ['result' => $result]); - return $result; } @@ -882,11 +847,6 @@ public static function newFromMemory( int $bands, string $format ): Image { - Utils::debugLog('newFromMemory', [ - 'instance' => null, - 'arguments' => [$data, $width, $height, $bands, $format] - ]); - /* Take a copy of the memory area to avoid lifetime issues. * * TODO add a references system instead, see pyvips. @@ -905,8 +865,6 @@ public static function newFromMemory( $result = new Image($pointer); - Utils::debugLog('newFromMemory', ['result' => $result]); - return $result; } @@ -938,11 +896,6 @@ public static function newInterpolator(string $name) */ public function newFromImage($value): Image { - Utils::debugLog('newFromImage', [ - 'instance' => $this, - 'arguments' => [$value] - ]); - $pixel = static::black(1, 1)->add($value)->cast($this->format); $image = $pixel->embed( 0, @@ -959,8 +912,6 @@ public function newFromImage($value): Image 'yoffset' => $this->yoffset ]); - Utils::debugLog('newFromImage', ['result' => $image]); - return $image; } @@ -977,12 +928,6 @@ public function newFromImage($value): Image */ public function writeToFile(string $name, array $options = []): void { - Utils::debugLog('writeToFile', [ - 'instance' => $this, - 'name' => $name, - 'options' => $options - ]); - $filename = Config::filenameGetFilename($name); $string_options = Config::filenameGetOptions($name); @@ -999,8 +944,6 @@ public function writeToFile(string $name, array $options = []): void $result = VipsOperation::call($saver, $this, [$filename], $options); - Utils::debugLog('writeToFile', ['result' => $result]); - if ($result === -1) { Config::error(); } @@ -1019,11 +962,6 @@ public function writeToFile(string $name, array $options = []): void */ public function writeToBuffer(string $suffix, array $options = []): string { - Utils::debugLog('writeToBuffer', [ - 'instance' => $this, - 'arguments' => [$suffix, $options] - ]); - $filename = Config::filenameGetFilename($suffix); $string_options = Config::filenameGetOptions($suffix); @@ -1040,8 +978,6 @@ public function writeToBuffer(string $suffix, array $options = []): string $result = VipsOperation::call($saver, $this, [], $options); - Utils::debugLog('writeToBuffer', ['result' => $result]); - return $result; } @@ -1054,11 +990,6 @@ public function writeToBuffer(string $suffix, array $options = []): string */ public function writeToMemory(): string { - Utils::debugLog('writeToMemory', [ - 'instance' => $this, - 'arguments' => [] - ]); - $ctype = \FFI::arrayType(\FFI::type("size_t"), [1]); $p_size = \FFI::new($ctype); @@ -1073,8 +1004,6 @@ public function writeToMemory(): string Config::ffi()->g_free($pointer); - Utils::debugLog('writeToMemory', ['result' => $result]); - return $result; } @@ -1103,11 +1032,6 @@ public function writeToMemory(): string */ public function writeToArray(): array { - Utils::debugLog('writeToArray', [ - 'instance' => $this, - 'arguments' => [] - ]); - $ctype = \FFI::arrayType(\FFI::type("size_t"), [1]); $p_size = \FFI::new($ctype); @@ -1132,8 +1056,6 @@ public function writeToArray(): array // the vips result is not PHP memory, so we must free it Config::ffi()->g_free($pointer); - Utils::debugLog('writeToArray', ['result' => $result]); - return $result; } @@ -1153,19 +1075,12 @@ public function writeToArray(): array */ public function copyMemory(): Image { - Utils::debugLog('copyMemory', [ - 'instance' => $this, - 'arguments' => [] - ]); - $pointer = Config::ffi()->vips_image_copy_memory($this->pointer); if ($pointer == null) { Config::error(); } $result = new Image($pointer); - Utils::debugLog('copyMemory', ['result' => $result]); - return $result; } diff --git a/src/Interpolate.php b/src/Interpolate.php index 6f594ea..c70b327 100644 --- a/src/Interpolate.php +++ b/src/Interpolate.php @@ -85,10 +85,6 @@ public function __construct($pointer) */ public static function newFromName($name) { - Utils::debugLog('newFromName', [ - 'arguments' => [$name] - ]); - $pointer = Config::ffi()->vips_interpolate_new($name); if ($pointer == null) { Config::error(); diff --git a/src/VipsOperation.php b/src/VipsOperation.php index 348bfba..606792d 100644 --- a/src/VipsOperation.php +++ b/src/VipsOperation.php @@ -334,7 +334,6 @@ public static function callBase( /* Build the operation */ - Utils::debugLog("callBase", ["building ..."]); $pointer = Config::ffi()-> vips_cache_operation_build($operation->pointer); if ($pointer == null) { @@ -356,7 +355,6 @@ public static function callBase( /* Any optional output args. */ - Utils::debugLog("callBase", ["fetching result ..."]); $option_keys = array_keys($options); foreach ($operation->introspect->optional_output as $name) { if (in_array($name, $option_keys)) { From 8b30c9ffe30046eff5abd024c578eb52fd8f1b0b Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 7 Mar 2022 19:33:40 +0000 Subject: [PATCH 57/58] revise library name generation again --- src/Config.php | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/Config.php b/src/Config.php index 5553f2f..ed720df 100644 --- a/src/Config.php +++ b/src/Config.php @@ -279,28 +279,24 @@ public static function atLeast($need_major, $need_minor) $need_minor <= self::$library_minor); } - private static function init() + private static function libraryName($name, $abi) { - $library_name = "libvips"; - switch (PHP_OS_FAMILY) { case "Windows": - // win needs the ABI number before the .dll - $library_ext = "42.dll"; - break; + return "$name-$abi.dll"; case "OSX": - $library_ext = ".dylib"; - break; + return "$name.$abi.dylib"; default: - // many *nix distributions only add the "libvips.so" symlink - // if the dev package is installed - $library_ext = ".so.42"; - break; + // most *nix + return "$name.so.$abi"; } + } - $library = "$library_name$library_ext"; + private static function init() + { + $library = self::libraryName("libvips", 42); Utils::debugLog("init", ["libray" => $library]); From c202836de529e7ca2cd23e04b628022196ddc063 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 9 Mar 2022 17:29:41 +0000 Subject: [PATCH 58/58] add __clone() fixes a crash, phew --- src/GObject.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/GObject.php b/src/GObject.php index ca5e4cb..74c35ef 100644 --- a/src/GObject.php +++ b/src/GObject.php @@ -79,6 +79,11 @@ public function __destruct() $this->unref(); } + public function __clone() + { + $this->ref(); + } + public function ref() { Config::ffi()->g_object_ref($this->pointer);