From 4793c69bba72211157b5e330f504963345123dc1 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 2 Sep 2014 21:59:11 +0100 Subject: [PATCH] turn VipsBlob into a proper type with a .get() method we call call from Python --- TODO | 13 +----- libvips/foreign/foreign.c | 32 +++++++-------- libvips/foreign/jpegsave.c | 8 ++-- libvips/foreign/pngsave.c | 10 ++--- libvips/foreign/webpsave.c | 8 ++-- libvips/include/vips/type.h | 9 ++++- libvips/iofuncs/image.c | 8 ++-- libvips/iofuncs/type.c | 80 +++++++++++++++++++++++-------------- 8 files changed, 90 insertions(+), 78 deletions(-) diff --git a/TODO b/TODO index a9d66098..d8f7a038 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,7 @@ - python: - - try6 produces a VipsBlob object ... need to turn this into a Python - buffer, or whatever they are called now - - memoryview, but that's py3 only, stick with buffer - - swig/vipsCC/VImage.i has code: - - $result = PyBuffer_FromMemory ($1.data, $1.size); - - how can we do this from VipsBlob? - - + - turns blobs into strings on return with .get() - add more constructors diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index 3e4f3a22..7f9fb065 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1755,18 +1755,18 @@ int vips_tiffload_buffer( void *buf, size_t len, VipsImage **out, ... ) { va_list ap; - VipsArea *area; + VipsBlob *blob; int result; /* We don't take a copy of the data or free it. */ - area = vips_area_new_blob( NULL, buf, len ); + blob = vips_blob_new( NULL, buf, len ); va_start( ap, out ); - result = vips_call_split( "tiffload_buffer", ap, area, out ); + result = vips_call_split( "tiffload_buffer", ap, blob, out ); va_end( ap ); - vips_area_unref( area ); + vips_area_unref( VIPS_AREA( blob ) ); return( result ); } @@ -1955,18 +1955,18 @@ int vips_jpegload_buffer( void *buf, size_t len, VipsImage **out, ... ) { va_list ap; - VipsArea *area; + VipsBlob *blob; int result; /* We don't take a copy of the data or free it. */ - area = vips_area_new_blob( NULL, buf, len ); + blob = vips_blob_new( NULL, buf, len ); va_start( ap, out ); - result = vips_call_split( "jpegload_buffer", ap, area, out ); + result = vips_call_split( "jpegload_buffer", ap, blob, out ); va_end( ap ); - vips_area_unref( area ); + vips_area_unref( VIPS_AREA( blob ) ); return( result ); } @@ -2168,18 +2168,18 @@ int vips_webpload_buffer( void *buf, size_t len, VipsImage **out, ... ) { va_list ap; - VipsArea *area; + VipsBlob *blob; int result; /* We don't take a copy of the data or free it. */ - area = vips_area_new_blob( NULL, buf, len ); + blob = vips_blob_new( NULL, buf, len ); va_start( ap, out ); - result = vips_call_split( "webpload_buffer", ap, area, out ); + result = vips_call_split( "webpload_buffer", ap, blob, out ); va_end( ap ); - vips_area_unref( area ); + vips_area_unref( VIPS_AREA( blob ) ); return( result ); } @@ -2472,18 +2472,18 @@ int vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... ) { va_list ap; - VipsArea *area; + VipsBlob *blob; int result; /* We don't take a copy of the data or free it. */ - area = vips_area_new_blob( NULL, buf, len ); + blob = vips_blob_new( NULL, buf, len ); va_start( ap, out ); - result = vips_call_split( "pngload_buffer", ap, area, out ); + result = vips_call_split( "pngload_buffer", ap, blob, out ); va_end( ap ); - vips_area_unref( area ); + vips_area_unref( VIPS_AREA( blob ) ); return( result ); } diff --git a/libvips/foreign/jpegsave.c b/libvips/foreign/jpegsave.c index 5c54e537..30c32caf 100644 --- a/libvips/foreign/jpegsave.c +++ b/libvips/foreign/jpegsave.c @@ -251,7 +251,7 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object ) void *obuf; size_t olen; - VipsArea *area; + VipsBlob *blob; if( VIPS_OBJECT_CLASS( vips_foreign_save_jpeg_buffer_parent_class )-> build( object ) ) @@ -262,9 +262,9 @@ vips_foreign_save_jpeg_buffer_build( VipsObject *object ) jpeg->interlace, save->strip, jpeg->no_subsample ) ) return( -1 ); - area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen ); - g_object_set( file, "buffer", area, NULL ); - vips_area_unref( area ); + blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen ); + g_object_set( file, "buffer", blob, NULL ); + vips_area_unref( VIPS_AREA( blob ) ); return( 0 ); } diff --git a/libvips/foreign/pngsave.c b/libvips/foreign/pngsave.c index 50465ac8..e3b78048 100644 --- a/libvips/foreign/pngsave.c +++ b/libvips/foreign/pngsave.c @@ -197,7 +197,7 @@ vips_foreign_save_png_buffer_build( VipsObject *object ) void *obuf; size_t olen; - VipsArea *area; + VipsBlob *blob; if( VIPS_OBJECT_CLASS( vips_foreign_save_png_buffer_parent_class )-> build( object ) ) @@ -207,11 +207,9 @@ vips_foreign_save_png_buffer_build( VipsObject *object ) png->compression, png->interlace ) ) return( -1 ); - area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen ); - - g_object_set( object, "buffer", area, NULL ); - - vips_area_unref( area ); + blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen ); + g_object_set( object, "buffer", blob, NULL ); + vips_area_unref( VIPS_AREA( blob ) ); return( 0 ); } diff --git a/libvips/foreign/webpsave.c b/libvips/foreign/webpsave.c index d1342ba7..b61a3f74 100644 --- a/libvips/foreign/webpsave.c +++ b/libvips/foreign/webpsave.c @@ -198,7 +198,7 @@ vips_foreign_save_webp_buffer_build( VipsObject *object ) void *obuf; size_t olen; - VipsArea *area; + VipsBlob *blob; if( VIPS_OBJECT_CLASS( vips_foreign_save_webp_buffer_parent_class )-> build( object ) ) @@ -208,9 +208,9 @@ vips_foreign_save_webp_buffer_build( VipsObject *object ) webp->Q, webp->lossless ) ) return( -1 ); - area = vips_area_new_blob( (VipsCallbackFn) vips_free, obuf, olen ); - g_object_set( file, "buffer", area, NULL ); - vips_area_unref( area ); + blob = vips_blob_new( (VipsCallbackFn) vips_free, obuf, olen ); + g_object_set( file, "buffer", blob, NULL ); + vips_area_unref( VIPS_AREA( blob ) ); return( 0 ); } diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index c9115f45..d8c0e2c8 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -92,8 +92,6 @@ VipsArea *vips_area_copy( VipsArea *area ); void vips_area_unref( VipsArea *area ); VipsArea *vips_area_new( VipsCallbackFn free_fn, void *data ); -VipsArea *vips_area_new_blob( VipsCallbackFn free_fn, - void *data, size_t length ); VipsArea *vips_area_new_array( GType type, size_t sizeof_type, int n ); VipsArea *vips_area_new_array_object( int n ); void *vips_area_get_data( VipsArea *area, @@ -145,6 +143,13 @@ GType vips_ref_string_get_type( void ); * The %GType for a #VipsBlob. */ #define VIPS_TYPE_BLOB (vips_blob_get_type()) + +typedef struct _VipsBlob { + VipsArea area; +} VipsBlob; + +VipsBlob *vips_blob_new( VipsCallbackFn free_fn, void *data, size_t size ); +void *vips_blob_get( VipsBlob *blob, size_t *size ); GType vips_blob_get_type( void ); /** diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index b8b5f586..6179dbab 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -2020,7 +2020,7 @@ vips_image_new_from_buffer( void *buf, size_t len, const char *option_string, ... ) { const char *operation_name; - VipsArea *area; + VipsBlob *blob; va_list ap; int result; VipsImage *out; @@ -2032,14 +2032,14 @@ vips_image_new_from_buffer( void *buf, size_t len, /* We don't take a copy of the data or free it. */ - area = vips_area_new_blob( NULL, buf, len ); + blob = vips_blob_new( NULL, buf, len ); va_start( ap, option_string ); result = vips_call_split_option_string( operation_name, - option_string, ap, area, &out ); + option_string, ap, blob, &out ); va_end( ap ); - vips_area_unref( area ); + vips_area_unref( VIPS_AREA( blob ) ); if( result ) return( NULL ); diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index c797d701..e083b2bc 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -274,32 +274,6 @@ vips__type_leak( void ) } } -/** - * vips_area_new_blob: - * @free_fn: (scope async): @data will be freed with this function - * @data: data will be freed with this function - * @length: number of bytes in @data - * - * Like vips_area_new(), but track a length as well. - * - * An area of mem with a free func and a length (some sort of binary object, - * like an ICC profile). - * - * See also: vips_area_unref(). - * - * Returns: (transfer full): the new #VipsArea. - */ -VipsArea * -vips_area_new_blob( VipsCallbackFn free_fn, void *data, size_t length ) -{ - VipsArea *area; - - area = vips_area_new( free_fn, data ); - area->length = length; - - return( area ); -} - /** * vips_area_new_array: * @type: %GType of elements to store @@ -537,6 +511,52 @@ vips_ref_string_get_type( void ) return( type ); } +/** + * vips_blob_new: + * @free_fn: (scope async): (allow-none): @data will be freed with this function + * @data: (array length=size) (element-type guint8) (transfer full): data to store + * @size: number of bytes in @data + * + * Like vips_area_new(), but track a length as well. The returned #VipsBlob + * takes ownership of @data and will free it with @free_fn. Pass NULL for + * @free_fn to not transfer ownership. + * + * An area of mem with a free func and a length (some sort of binary object, + * like an ICC profile). + * + * See also: vips_area_unref(). + * + * Returns: (transfer full): the new #VipsBlob. + */ +VipsBlob * +vips_blob_new( VipsCallbackFn free_fn, void *data, size_t size ) +{ + VipsArea *area; + + area = vips_area_new( free_fn, data ); + area->length = size; + + return( (VipsBlob *) area ); +} + +/** + * vips_blob_get: + * @blob: #VipsBlob to fetch from + * @size: return number of bytes of data + * + * Get the data from a #VipsBlob. + * + * See also: vips_blob_new(). + * + * Returns: (array length=size) (element-type guint8) (transfer none): the data + */ +void * +vips_blob_get( VipsBlob *blob, size_t *size ) +{ + return( vips_area_get_data( VIPS_AREA( blob ), + size, NULL, NULL, NULL ) ); +} + /* Transform a blob to a G_TYPE_STRING. */ static void @@ -1196,13 +1216,13 @@ void vips_value_set_blob( GValue *value, VipsCallbackFn free_fn, void *data, size_t length ) { - VipsArea *area; + VipsBlob *blob; g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_BLOB ); - area = vips_area_new_blob( free_fn, data, length ); - g_value_set_boxed( value, area ); - vips_area_unref( area ); + blob = vips_blob_new( free_fn, data, length ); + g_value_set_boxed( value, blob ); + vips_area_unref( VIPS_AREA( blob ) ); } /**