diff --git a/src/FFI.php b/src/FFI.php index f259f7b..ff7d689 100644 --- a/src/FFI.php +++ b/src/FFI.php @@ -539,6 +539,8 @@ private static function init(): void typedef void (*FreeFn)(void* a); void vips_value_set_blob (GValue* value, FreeFn free_fn, void* data, size_t length); +void* vips_blob_copy (const void *data, size_t length); +void vips_area_unref (void *area); const char* vips_value_get_ref_string (const GValue* value, size_t* length); @@ -760,8 +762,7 @@ private static function init(): void VipsSource* vips_source_new_from_descriptor (int descriptor); VipsSource* vips_source_new_from_file (const char* filename); -VipsSource* vips_source_new_from_memory (const void* data, - size_t size); +VipsSource* vips_source_new_from_blob (void* blob); typedef struct _VipsSourceCustom { VipsSource parent_object; diff --git a/src/Source.php b/src/Source.php index 9a028a7..5afdbb0 100644 --- a/src/Source.php +++ b/src/Source.php @@ -64,17 +64,19 @@ public static function newFromFile(string $filename): self */ public static function newFromMemory(string $data): self { - # we need to set the memory to a copy of the data that vips_lib - # can own and free - $n = strlen($data); - $memory = FFI::vips()->new("char[$n]", false, true); - \FFI::memcpy($memory, $data, $n); - $pointer = FFI::vips()->vips_source_new_from_memory($memory, $n); + $blob = FFI::vips()->vips_blob_copy($data, strlen($data)); + if ($blob === null) { + throw new Exception("can't create source from memory"); + } + $pointer = FFI::vips()->vips_source_new_from_blob($blob); if ($pointer === null) { + FFI::vips()->vips_area_unref($blob); throw new Exception("can't create source from memory"); } - return new self($pointer); + $source = new self($pointer); + FFI::vips()->vips_area_unref($blob); + return $source; } }