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.
This commit is contained in:
Kyle Schwarz 2020-08-01 21:58:14 -04:00
parent ba45c87b50
commit fe815ff587
3 changed files with 56 additions and 0 deletions

View File

@ -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
{

View File

@ -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*/

View File

@ -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