From fe815ff587cab3eac32ae81cbf865ea8261816a9 Mon Sep 17 00:00:00 2001 From: Kyle Schwarz Date: Sat, 1 Aug 2020 21:58:14 -0400 Subject: [PATCH] Add C++ bindings for new_from_memory_steal() new_from_memory_steal() will create a new image with the input buffer and will "move" the data into the image. The buffer is then managed by the image, and will be freed when it goes out of scope. --- cplusplus/include/vips/VImage8.h | 17 +++++++++++++++ libvips/include/vips/image.h | 2 ++ libvips/iofuncs/image.c | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/cplusplus/include/vips/VImage8.h b/cplusplus/include/vips/VImage8.h index 99b61a3b..b2f29c28 100644 --- a/cplusplus/include/vips/VImage8.h +++ b/cplusplus/include/vips/VImage8.h @@ -550,6 +550,23 @@ public: return( new_from_image( to_vectorv( 1, pixel ) ) ); } + static VImage + new_from_memory_steal( void *data, size_t size, + int width, int height, int bands, VipsBandFormat format ) + { + VipsImage *image; + + if( !(image = vips_image_new_from_memory( data, size, + width, height, bands, format )) ) + throw( VError() ); + + if( g_signal_connect( image, "postclose", + G_CALLBACK(vips_image_free_buffer), data) < 0 ) + throw( VError() ); + + return( VImage( image ) ); + } + VImage copy_memory() const { diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 01b59968..e766b3fd 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -522,6 +522,8 @@ int vips_reorder_prepare_many( VipsImage *image, struct _VipsRegion **regions, VipsRect *r ); void vips_reorder_margin_hint( VipsImage *image, int margin ); +void vips_image_free_buffer( VipsImage* image, void* buffer ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 2516351d..f115905c 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -3872,6 +3872,43 @@ vips_band_format_iscomplex( VipsBandFormat format ) } } +/** + * vips_image_free_buffer: + * @image: the image that contains the buffer + * @buffer: the orignal buffer that was stolen + * + * Free the externally allocated buffer found in the input image. This function + * is intened to be used with g_signal_connect, so it can free an externally + * allocated buffer. + */ +void +vips_image_free_buffer( VipsImage* image, void* buffer ) +{ + switch( vips_image_get_format( image ) ) { + case VIPS_FORMAT_UCHAR: + free( (unsigned char*)buffer ); break; + case VIPS_FORMAT_CHAR: + free( (char*)buffer ); break; + case VIPS_FORMAT_USHORT: + free( (unsigned short*)buffer ); break; + case VIPS_FORMAT_SHORT: + free( (short*)buffer ); break; + case VIPS_FORMAT_UINT: + free( (unsigned int*)buffer ); break; + case VIPS_FORMAT_INT: + free( (int*)buffer ); break; + case VIPS_FORMAT_FLOAT: + case VIPS_FORMAT_COMPLEX: + free( (float*)buffer ); break; + case VIPS_FORMAT_DOUBLE: + case VIPS_FORMAT_DPCOMPLEX: + free( (double*)buffer ); break; + + default: + g_assert_not_reached(); + } +} + /* Handy for debugging: view an image in nip2. */ int