store all string metadata as refstr

various things break if you attach a G_TYPE_STRING as metadata, so make
sure it's always VIPS_TYPE_REF_STRING

also, type convert on read
This commit is contained in:
John Cupitt 2015-07-16 14:46:20 +01:00
parent 69fc2c1b7c
commit 180e5efe6f
2 changed files with 18 additions and 2 deletions
libvips/iofuncs

@ -20,6 +20,8 @@
* 22/3/11 * 22/3/11
* - rename fields for vips8 * - rename fields for vips8
* - move to vips_ prefix * - move to vips_ prefix
* 16/7/15
* - auto wrap GString as RefString
*/ */
/* /*
@ -284,8 +286,21 @@ meta_new( VipsImage *image, const char *field, GValue *value )
memset( &meta->value, 0, sizeof( GValue ) ); memset( &meta->value, 0, sizeof( GValue ) );
meta->field = g_strdup( field ); meta->field = g_strdup( field );
g_value_init( &meta->value, G_VALUE_TYPE( value ) ); /* Special case: we don't want to have G_STRING on meta. They will be
g_value_copy( value, &meta->value ); * copied down pipelines, plus some of our API (like
* vips_image_get_string()) assumes that the GValue is a refstring and
* that read-only pointers can be handed out.
*
* Turn G_TYPE_STRING into VIPS_TYPE_REF_STRING.
*/
if( G_VALUE_TYPE( value ) == G_TYPE_STRING )
g_value_init( &meta->value, VIPS_TYPE_REF_STRING );
else
g_value_init( &meta->value, G_VALUE_TYPE( value ) );
/* We don't do any conversions that can fail.
*/
(void) g_value_transform( value, &meta->value );
image->meta_traverse = g_slist_append( image->meta_traverse, meta ); image->meta_traverse = g_slist_append( image->meta_traverse, meta );
g_hash_table_replace( image->meta, meta->field, meta ); g_hash_table_replace( image->meta, meta->field, meta );

@ -1339,6 +1339,7 @@ vips_value_set_ref_string( GValue *value, const char *str )
VipsRefString *ref_str; VipsRefString *ref_str;
g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING ); g_assert( G_VALUE_TYPE( value ) == VIPS_TYPE_REF_STRING );
ref_str = vips_ref_string_new( str ); ref_str = vips_ref_string_new( str );
g_value_set_boxed( value, ref_str ); g_value_set_boxed( value, ref_str );
vips_area_unref( VIPS_AREA( ref_str ) ); vips_area_unref( VIPS_AREA( ref_str ) );