From 69fc2c1b7c11782b6e091d660aa523df0174a3a3 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 16 Jul 2015 11:14:33 +0100 Subject: [PATCH] getting closer ... fix RefString handling, add a test case --- TODO | 15 ++++++++++++++ libvips/include/vips/type.h | 1 + libvips/iofuncs/header.c | 10 ++++++--- libvips/iofuncs/type.c | 41 ++++++++++++++++++++++++++----------- python/Vips.py | 1 + 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/TODO b/TODO index 89d2af7f..62f44a0d 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,18 @@ +- try: + +>>> from gi.repository import Vips +>>> x = Vips.Image.new_from_file("images/IMG_4618.jpg") +>>> x.get_value("exif-ifd0-Orientation") +'1 (Top-left, Short, 1 components, 2 bytes)' +>>> x.set_value("exif-ifd0-Orientation", "2") +>>> x.write_to_file("x.jpg") + + Orientation comes out as zero in vipsheader -a x.jpg + + add a test-case for changing exif from py + + + - colour needs to split _build() into preprocess / process / postprocess phases diff --git a/libvips/include/vips/type.h b/libvips/include/vips/type.h index 16e0e4d4..e43bdbfa 100644 --- a/libvips/include/vips/type.h +++ b/libvips/include/vips/type.h @@ -140,6 +140,7 @@ typedef struct _VipsRefString { VipsArea area; } VipsRefString; +VipsRefString *vips_ref_string_new( const char *str ); const char *vips_ref_string_get( VipsRefString *refstr, size_t *length ); GType vips_ref_string_get_type( void ); diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 89ac0b45..436151ff 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -1106,18 +1106,22 @@ static int meta_get_value( const VipsImage *image, const char *field, GType type, GValue *value_copy ) { - if( vips_image_get( image, field, value_copy ) ) + GValue value = { 0 }; + + if( vips_image_get( image, field, &value ) ) return( -1 ); - if( G_VALUE_TYPE( value_copy ) != type ) { + g_value_init( value_copy, type ); + if( !g_value_transform( &value, value_copy ) ) { vips_error( "VipsImage", _( "field \"%s\" is of type %s, not %s" ), field, g_type_name( G_VALUE_TYPE( value_copy ) ), g_type_name( type ) ); - g_value_unset( value_copy ); + g_value_unset( &value ); return( -1 ); } + g_value_unset( &value ); return( 0 ); } diff --git a/libvips/iofuncs/type.c b/libvips/iofuncs/type.c index 0296c4a4..c40797c5 100644 --- a/libvips/iofuncs/type.c +++ b/libvips/iofuncs/type.c @@ -502,6 +502,31 @@ transform_save_string_ref_string( const GValue *src_value, GValue *dest_value ) vips_value_get_save_string( src_value ) ); } +/** + * vips_ref_string_new: + * @str: (transfer none): string to store + * + * Create a new refstring. These are reference-counted immutable strings, used + * to store string data in vips image metadata. + * + * See also: vips_area_unref(). + * + * Returns: (transfer full): the new #VipsRefString. + */ +VipsRefString * +vips_ref_string_new( const char *str ) +{ + VipsArea *area; + + area = vips_area_new( (VipsCallbackFn) g_free, g_strdup( str ) ); + + /* Handy place to cache this. + */ + area->length = strlen( str ); + + return( (VipsRefString *) area ); +} + /** * vips_ref_string_get: * @refstr: the #VipsRefString to fetch from @@ -1311,20 +1336,12 @@ vips_value_get_ref_string( const GValue *value, size_t *length ) void vips_value_set_ref_string( GValue *value, const char *str ) { - VipsArea *area; - char *str_copy; + VipsRefString *ref_str; g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING ); - - str_copy = g_strdup( str ); - area = vips_area_new( (VipsCallbackFn) vips_free, str_copy ); - - /* Handy place to cache this. - */ - area->length = strlen( str ); - - g_value_set_boxed( value, area ); - vips_area_unref( area ); + ref_str = vips_ref_string_new( str ); + g_value_set_boxed( value, ref_str ); + vips_area_unref( VIPS_AREA( ref_str ) ); } /** diff --git a/python/Vips.py b/python/Vips.py index bbce5550..fb9d78ef 100644 --- a/python/Vips.py +++ b/python/Vips.py @@ -55,6 +55,7 @@ vips_type_array_image = GObject.GType.from_name("VipsArrayImage") vips_type_blob = GObject.GType.from_name("VipsBlob") vips_type_image = GObject.GType.from_name("VipsImage") vips_type_operation = GObject.GType.from_name("VipsOperation") +vips_type_ref_string = GObject.GType.from_name("VipsRefString") def is_2D(value): if not isinstance(value, list):