diff --git a/cplusplus/VImage.cpp b/cplusplus/VImage.cpp index d459adc9..5a08d80f 100644 --- a/cplusplus/VImage.cpp +++ b/cplusplus/VImage.cpp @@ -714,17 +714,38 @@ VImage::write_to_buffer( const char *suffix, void **buf, size_t *size, const char *operation_name; VipsBlob *blob; + /* Save with the new target API if we can. Fall back to the older + * mechanism in case the saver we need has not been converted yet. + * + * We need to hide any errors from this first phase. + */ vips__filename_split8( suffix, filename, option_string ); - if( !(operation_name = vips_foreign_find_save_buffer( filename )) ) { + + vips_error_freeze(); + operation_name = vips_foreign_find_save_target( filename ); + vips_error_thaw(); + + if( operation_name ) { + VTarget target = VTarget::new_to_memory(); + + call_option_string( operation_name, option_string, + (options ? options : VImage::option())-> + set( "in", *this )-> + set( "target", target ) ); + + g_object_get( target.get_target(), "blob", &blob, NULL ); + } + else if( (operation_name = vips_foreign_find_save_buffer( filename )) ) { + call_option_string( operation_name, option_string, + (options ? options : VImage::option())-> + set( "in", *this )-> + set( "buffer", &blob ) ); + } + else { delete options; throw VError(); } - call_option_string( operation_name, option_string, - (options ? options : VImage::option())-> - set( "in", *this )-> - set( "buffer", &blob ) ); - if( blob ) { if( buf ) { *buf = VIPS_AREA( blob )->data; diff --git a/cplusplus/examples/test.cpp b/cplusplus/examples/test.cpp index 764485b8..87128848 100644 --- a/cplusplus/examples/test.cpp +++ b/cplusplus/examples/test.cpp @@ -9,7 +9,7 @@ * * run with: * - * ./a.out ~/pics/k2.jpg ~/pics/shark.jpg --vips-leak + * VIPS_LEAK=1 ./a.out ~/pics/k2.jpg ~/pics/shark.jpg * valgrind --leak-check=yes ./a.out ~/pics/k2.jpg ~/pics/shark.jpg * rm x.tif * @@ -295,6 +295,31 @@ main( int argc, char **argv ) g_free( buf ); } +{ + // write to a formatted AVIF memory buffer + printf( "testing formatted AVIF memory write ...\n" ); + + if( vips_type_find("VipsOperation", "avifsave_target") != 0 ) { + size_t size; + void *buf; + + // speed-up test by setting @effort to 0 + left.write_to_buffer( ".avif", &buf, &size, + VImage::option()->set( "effort", 0 ) ); + printf( "written to memory %p in AVIF format, %zu bytes\n", buf, size ); + + // load from the formatted memory area + VImage im = VImage::new_from_buffer( buf, size, "" ); + printf( "loaded from memory, %d x %d pixel %s image\n", + im.width(), im.height(), im.get_string("heif-compression") ); + + g_free( buf ); + } + else { + printf( "skipped, not compiled against libheif\n" ); + } +} + { // write to a vanilla memory buffer printf( "testing memory array write ...\n" ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 6f93cb8d..330ccc5a 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -2678,7 +2678,7 @@ vips_image_write_to_file( VipsImage *image, const char *name, ... ) int result; /* Save with the new target API if we can. Fall back to the older - * mechanism in case the loader we need has not been converted yet. + * mechanism in case the saver we need has not been converted yet. * * We need to hide any errors from this first phase. */