support old header names

vips_image_get_int() and friends let you use the old header names eg.
"Xsize"
This commit is contained in:
John Cupitt 2011-03-23 14:44:20 +00:00
parent 1135e553f3
commit 0b9189b2ef
3 changed files with 125 additions and 79 deletions

View File

@ -41,6 +41,7 @@
- better png read for 1-bit and palette images - better png read for 1-bit and palette images
- fits write - fits write
- better fits metadata support - better fits metadata support
- renamed all header fields, old names still supported, hopefully
30/11/10 started 7.24.0 30/11/10 started 7.24.0
- bump for new stable - bump for new stable

8
TODO
View File

@ -1,11 +1,3 @@
- header should display new names for fields
add "header -f Xsize" etc. as a special case in header.c
or perhaps in vips_image_get()?
- vips_attach_save() in image.c has problems if save fails ... there's no way - vips_attach_save() in image.c has problems if save fails ... there's no way
for the result of the "written" callback to propogate the error for the result of the "written" callback to propogate the error

View File

@ -98,27 +98,47 @@ typedef struct _HeaderField {
/* Built in fields and struct offsets. /* Built in fields and struct offsets.
*/ */
static HeaderField int_field[] = { static HeaderField int_field[] = {
{ "width", G_STRUCT_OFFSET( IMAGE, Xsize ) }, { "width", G_STRUCT_OFFSET( VipsImage, Xsize ) },
{ "height", G_STRUCT_OFFSET( IMAGE, Ysize ) }, { "height", G_STRUCT_OFFSET( VipsImage, Ysize ) },
{ "bands", G_STRUCT_OFFSET( IMAGE, Bands ) }, { "bands", G_STRUCT_OFFSET( VipsImage, Bands ) },
{ "format", G_STRUCT_OFFSET( IMAGE, BandFmt ) }, { "format", G_STRUCT_OFFSET( VipsImage, BandFmt ) },
{ "coding", G_STRUCT_OFFSET( IMAGE, Coding ) }, { "coding", G_STRUCT_OFFSET( VipsImage, Coding ) },
{ "interpretation", G_STRUCT_OFFSET( IMAGE, Type ) }, { "interpretation", G_STRUCT_OFFSET( VipsImage, Type ) },
{ "xoffset", G_STRUCT_OFFSET( IMAGE, Xoffset ) }, { "xoffset", G_STRUCT_OFFSET( VipsImage, Xoffset ) },
{ "yoffset", G_STRUCT_OFFSET( IMAGE, Yoffset ) } { "yoffset", G_STRUCT_OFFSET( VipsImage, Yoffset ) }
}; };
/* These are actually floats :-( how annoying. We report them as doubles for /* These are actually floats :-( how annoying. We report them as doubles for
* consistency with the im_meta_*() functions. * consistency with the im_meta_*() functions.
*/ */
static HeaderField double_field[] = { static HeaderField double_field[] = {
{ "xres", G_STRUCT_OFFSET( IMAGE, Xres ) }, { "xres", G_STRUCT_OFFSET( VipsImage, Xres ) },
{ "yres", G_STRUCT_OFFSET( IMAGE, Yres ) } { "yres", G_STRUCT_OFFSET( VipsImage, Yres ) }
}; };
static HeaderField string_field[] = { static HeaderField string_field[] = {
{ "filename", G_STRUCT_OFFSET( IMAGE, filename ) } { "filename", G_STRUCT_OFFSET( VipsImage, filename ) }
};
/* Old names we keep around for back-compat. We never loop over these with
* map, but we do check them when we look up fields by name.
*/
static HeaderField old_int_field[] = {
{ "Xsize", G_STRUCT_OFFSET( VipsImage, Xsize ) },
{ "Ysize", G_STRUCT_OFFSET( VipsImage, Ysize ) },
{ "Bands", G_STRUCT_OFFSET( VipsImage, Bands ) },
{ "Bbits", G_STRUCT_OFFSET( VipsImage, Bbits ) },
{ "BandFmt", G_STRUCT_OFFSET( VipsImage, BandFmt ) },
{ "Coding", G_STRUCT_OFFSET( VipsImage, Coding ) },
{ "Type", G_STRUCT_OFFSET( VipsImage, Type ) },
{ "Xoffset", G_STRUCT_OFFSET( VipsImage, Xoffset ) },
{ "Yoffset", G_STRUCT_OFFSET( VipsImage, Yoffset ) }
};
static HeaderField old_double_field[] = {
{ "Xres", G_STRUCT_OFFSET( VipsImage, Xres ) },
{ "Yres", G_STRUCT_OFFSET( VipsImage, Yres ) }
}; };
/* This is used by (eg.) IM_IMAGE_SIZEOF_ELEMENT() to calculate object /* This is used by (eg.) IM_IMAGE_SIZEOF_ELEMENT() to calculate object
@ -285,7 +305,7 @@ vips_image_init_fields( VipsImage *image,
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.
*/ */
int int
vips_image_copy_fields_array( IMAGE *out, IMAGE *in[] ) vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] )
{ {
int i; int i;
int ni; int ni;
@ -344,15 +364,15 @@ vips_image_copy_fields_array( IMAGE *out, IMAGE *in[] )
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.
*/ */
int int
vips_image_copy_fieldsv( IMAGE *out, IMAGE *in1, ... ) vips_image_copy_fieldsv( VipsImage *out, VipsImage *in1, ... )
{ {
va_list ap; va_list ap;
int i; int i;
IMAGE *in[MAX_IMAGES]; VipsImage *in[MAX_IMAGES];
in[0] = in1; in[0] = in1;
va_start( ap, in1 ); va_start( ap, in1 );
for( i = 1; i < MAX_IMAGES && (in[i] = va_arg( ap, IMAGE * )); i++ ) for( i = 1; i < MAX_IMAGES && (in[i] = va_arg( ap, VipsImage * )); i++ )
; ;
va_end( ap ); va_end( ap );
if( i == MAX_IMAGES ) { if( i == MAX_IMAGES ) {
@ -377,14 +397,14 @@ vips_image_copy_fieldsv( IMAGE *out, IMAGE *in1, ... )
* Returns: 0 on success, -1 on error. * Returns: 0 on success, -1 on error.
*/ */
int int
vips_image_copy_fields( IMAGE *out, IMAGE *in ) vips_image_copy_fields( VipsImage *out, VipsImage *in )
{ {
return( vips_image_copy_fieldsv( out, in, NULL ) ); return( vips_image_copy_fieldsv( out, in, NULL ) );
} }
/** /**
* vips_image_get_int: * vips_image_get_int:
* @im: image to get the header field from * @image: image to get the header field from
* @field: field name * @field: field name
* @out: return field value * @out: return field value
* *
@ -404,22 +424,27 @@ vips_image_get_int( VipsImage *image, const char *field, int *out )
if( strcmp( field, int_field[i].field ) == 0 ) { if( strcmp( field, int_field[i].field ) == 0 ) {
*out = G_STRUCT_MEMBER( int, image, *out = G_STRUCT_MEMBER( int, image,
int_field[i].offset ); int_field[i].offset );
break; return( 0 );
}
for( i = 0; i < VIPS_NUMBER( old_int_field ); i++ )
if( strcmp( field, old_int_field[i].field ) == 0 ) {
*out = G_STRUCT_MEMBER( int, image,
old_int_field[i].offset );
return( 0 );
} }
if( i == VIPS_NUMBER( int_field ) && if( !im_meta_get_int( image, field, out ) )
im_meta_get_int( image, field, out ) ) { return( 0 );
vips_error( "im_header_int",
_( "no such int field \"%s\"" ), field );
return( -1 );
}
return( 0 ); vips_error( "im_header_int",
_( "no such int field \"%s\"" ), field );
return( -1 );
} }
/** /**
* vips_image_get_double: * vips_image_get_double:
* @im: image to get the header field from * @image: image to get the header field from
* @field: field name * @field: field name
* @out: return field value * @out: return field value
* *
@ -432,30 +457,35 @@ vips_image_get_int( VipsImage *image, const char *field, int *out )
* Returns: 0 on success, -1 otherwise. * Returns: 0 on success, -1 otherwise.
*/ */
int int
vips_image_get_double( IMAGE *im, const char *field, double *out ) vips_image_get_double( VipsImage *image, const char *field, double *out )
{ {
int i; int i;
for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) for( i = 0; i < VIPS_NUMBER( double_field ); i++ )
if( strcmp( field, double_field[i].field ) == 0 ) { if( strcmp( field, double_field[i].field ) == 0 ) {
*out = G_STRUCT_MEMBER( float, im, *out = G_STRUCT_MEMBER( float, image,
double_field[i].offset ); double_field[i].offset );
break; return( 0 );
}
for( i = 0; i < VIPS_NUMBER( old_double_field ); i++ )
if( strcmp( field, old_double_field[i].field ) == 0 ) {
*out = G_STRUCT_MEMBER( float, image,
old_double_field[i].offset );
return( 0 );
} }
if( i == VIPS_NUMBER( double_field ) && if( !im_meta_get_double( image, field, out ) )
im_meta_get_double( im, field, out ) ) { return( 0 );
vips_error( "im_header_double",
_( "no such double field \"%s\"" ), field );
return( -1 );
}
return( 0 ); vips_error( "im_header_double",
_( "no such double field \"%s\"" ), field );
return( -1 );
} }
/** /**
* vips_image_get_string: * vips_image_get_string:
* @im: image to get the header field from * @image: image to get the header field from
* @field: field name * @field: field name
* @out: return field value * @out: return field value
* *
@ -469,30 +499,29 @@ vips_image_get_double( IMAGE *im, const char *field, double *out )
* Returns: 0 on success, -1 otherwise. * Returns: 0 on success, -1 otherwise.
*/ */
int int
vips_image_get_string( IMAGE *im, const char *field, char **out ) vips_image_get_string( VipsImage *image, const char *field, char **out )
{ {
int i; int i;
for( i = 0; i < VIPS_NUMBER( string_field ); i++ ) for( i = 0; i < VIPS_NUMBER( string_field ); i++ )
if( strcmp( field, string_field[i].field ) == 0 ) { if( strcmp( field, string_field[i].field ) == 0 ) {
*out = G_STRUCT_MEMBER( char *, im, *out = G_STRUCT_MEMBER( char *, image,
string_field[i].offset ); string_field[i].offset );
break; return( 0 );
} }
if( i == VIPS_NUMBER( string_field ) && if( !im_meta_get_string( image, field, out ) )
im_meta_get_string( im, field, out ) ) { return( 0 );
vips_error( "im_header_string",
_( "no such string field \"%s\"" ), field );
return( -1 );
}
return( 0 ); vips_error( "im_header_string",
_( "no such string field \"%s\"" ), field );
return( -1 );
} }
/** /**
* vips_image_get_as_string: * vips_image_get_as_string:
* @im: image to get the header field from * @image: image to get the header field from
* @field: field name * @field: field name
* @out: return field value as string * @out: return field value as string
* *
@ -505,12 +534,12 @@ vips_image_get_string( IMAGE *im, const char *field, char **out )
* Returns: 0 on success, -1 otherwise. * Returns: 0 on success, -1 otherwise.
*/ */
int int
vips_image_get_as_string( IMAGE *im, const char *field, char **out ) vips_image_get_as_string( VipsImage *image, const char *field, char **out )
{ {
GValue value = { 0 }; GValue value = { 0 };
GType type; GType type;
if( vips_image_get( im, field, &value ) ) if( vips_image_get( image, field, &value ) )
return( -1 ); return( -1 );
/* Display the save form, if there is one. This way we display /* Display the save form, if there is one. This way we display
@ -536,7 +565,7 @@ vips_image_get_as_string( IMAGE *im, const char *field, char **out )
/** /**
* vips_image_get_typeof: * vips_image_get_typeof:
* @im: image to test * @image: image to test
* @field: the name to search for * @field: the name to search for
* *
* Read the GType for a header field. Returns zero if there is no * Read the GType for a header field. Returns zero if there is no
@ -548,7 +577,7 @@ vips_image_get_as_string( IMAGE *im, const char *field, char **out )
* field of that name. * field of that name.
*/ */
GType GType
vips_image_get_typeof( IMAGE *im, const char *field ) vips_image_get_typeof( VipsImage *image, const char *field )
{ {
int i; int i;
GType type; GType type;
@ -556,13 +585,19 @@ vips_image_get_typeof( IMAGE *im, const char *field )
for( i = 0; i < VIPS_NUMBER( int_field ); i++ ) for( i = 0; i < VIPS_NUMBER( int_field ); i++ )
if( strcmp( field, int_field[i].field ) == 0 ) if( strcmp( field, int_field[i].field ) == 0 )
return( G_TYPE_INT ); return( G_TYPE_INT );
for( i = 0; i < VIPS_NUMBER( old_int_field ); i++ )
if( strcmp( field, old_int_field[i].field ) == 0 )
return( G_TYPE_INT );
for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) for( i = 0; i < VIPS_NUMBER( double_field ); i++ )
if( strcmp( field, double_field[i].field ) == 0 ) if( strcmp( field, double_field[i].field ) == 0 )
return( G_TYPE_DOUBLE ); return( G_TYPE_DOUBLE );
for( i = 0; i < VIPS_NUMBER( old_double_field ); i++ )
if( strcmp( field, old_double_field[i].field ) == 0 )
return( G_TYPE_DOUBLE );
for( i = 0; i < VIPS_NUMBER( string_field ); i++ ) for( i = 0; i < VIPS_NUMBER( string_field ); i++ )
if( strcmp( field, string_field[i].field ) == 0 ) if( strcmp( field, string_field[i].field ) == 0 )
return( G_TYPE_STRING ); return( G_TYPE_STRING );
if( (type = im_meta_get_typeof( im, field )) ) if( (type = im_meta_get_typeof( image, field )) )
return( type ); return( type );
return( 0 ); return( 0 );
@ -574,7 +609,7 @@ vips_image_get_typeof( IMAGE *im, const char *field )
/** /**
* vips_image_get: * vips_image_get:
* @im: image to get the field from from * @image: image to get the field from from
* @field: the name to give the metadata * @field: the name to give the metadata
* @value_copy: the GValue is copied into this * @value_copy: the GValue is copied into this
* *
@ -593,7 +628,7 @@ vips_image_get_typeof( IMAGE *im, const char *field )
* GValue value = { 0 }; * GValue value = { 0 };
* double d; * double d;
* *
* if( vips_image_get( im, field, &value ) ) * if( vips_image_get( image, field, &value ) )
* return( -1 ); * return( -1 );
* *
* if( G_VALUE_TYPE( &value ) != G_TYPE_DOUBLE ) { * if( G_VALUE_TYPE( &value ) != G_TYPE_DOUBLE ) {
@ -616,7 +651,7 @@ vips_image_get_typeof( IMAGE *im, const char *field )
* Returns: 0 on success, -1 otherwise. * Returns: 0 on success, -1 otherwise.
*/ */
int int
vips_image_get( IMAGE *im, const char *field, GValue *value_copy ) vips_image_get( VipsImage *image, const char *field, GValue *value_copy )
{ {
int i; int i;
@ -624,30 +659,48 @@ vips_image_get( IMAGE *im, const char *field, GValue *value_copy )
if( strcmp( field, int_field[i].field ) == 0 ) { if( strcmp( field, int_field[i].field ) == 0 ) {
g_value_init( value_copy, G_TYPE_INT ); g_value_init( value_copy, G_TYPE_INT );
g_value_set_int( value_copy, g_value_set_int( value_copy,
G_STRUCT_MEMBER( int, im, G_STRUCT_MEMBER( int, image,
int_field[i].offset ) ); int_field[i].offset ) );
return( 0 ); return( 0 );
} }
for( i = 0; i < VIPS_NUMBER( old_int_field ); i++ )
if( strcmp( field, old_int_field[i].field ) == 0 ) {
g_value_init( value_copy, G_TYPE_INT );
g_value_set_int( value_copy,
G_STRUCT_MEMBER( int, image,
old_int_field[i].offset ) );
return( 0 );
}
for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) for( i = 0; i < VIPS_NUMBER( double_field ); i++ )
if( strcmp( field, double_field[i].field ) == 0 ) { if( strcmp( field, double_field[i].field ) == 0 ) {
g_value_init( value_copy, G_TYPE_DOUBLE ); g_value_init( value_copy, G_TYPE_DOUBLE );
g_value_set_double( value_copy, g_value_set_double( value_copy,
G_STRUCT_MEMBER( float, im, G_STRUCT_MEMBER( float, image,
double_field[i].offset ) ); double_field[i].offset ) );
return( 0 ); return( 0 );
} }
for( i = 0; i < VIPS_NUMBER( old_double_field ); i++ )
if( strcmp( field, old_double_field[i].field ) == 0 ) {
g_value_init( value_copy, G_TYPE_DOUBLE );
g_value_set_double( value_copy,
G_STRUCT_MEMBER( float, image,
old_double_field[i].offset ) );
return( 0 );
}
for( i = 0; i < VIPS_NUMBER( string_field ); i++ ) for( i = 0; i < VIPS_NUMBER( string_field ); i++ )
if( strcmp( field, string_field[i].field ) == 0 ) { if( strcmp( field, string_field[i].field ) == 0 ) {
g_value_init( value_copy, G_TYPE_STRING ); g_value_init( value_copy, G_TYPE_STRING );
g_value_set_static_string( value_copy, g_value_set_static_string( value_copy,
G_STRUCT_MEMBER( char *, im, G_STRUCT_MEMBER( char *, image,
string_field[i].offset ) ); string_field[i].offset ) );
return( 0 ); return( 0 );
} }
if( !im_meta_get( im, field, value_copy ) ) if( !im_meta_get( image, field, value_copy ) )
return( 0 ); return( 0 );
return( -1 ); return( -1 );
@ -661,7 +714,7 @@ vips_image_map_fn( Meta *meta, VipsImageMapFn fn, void *a )
/** /**
* vips_image_map: * vips_image_map:
* @im: image to map over * @image: image to map over
* @fn: function to call for each header field * @fn: function to call for each header field
* @a: user data for function * @a: user data for function
* *
@ -676,15 +729,15 @@ vips_image_map_fn( Meta *meta, VipsImageMapFn fn, void *a )
* Returns: %NULL on success, the failing pointer otherwise. * Returns: %NULL on success, the failing pointer otherwise.
*/ */
void * void *
vips_image_map( IMAGE *im, VipsImageMapFn fn, void *a ) vips_image_map( VipsImage *image, VipsImageMapFn fn, void *a )
{ {
int i; int i;
GValue value = { 0 }; GValue value = { 0 };
void *result; void *result;
for( i = 0; i < VIPS_NUMBER( int_field ); i++ ) { for( i = 0; i < VIPS_NUMBER( int_field ); i++ ) {
vips_image_get( im, int_field[i].field, &value ); vips_image_get( image, int_field[i].field, &value );
result = fn( im, int_field[i].field, &value, a ); result = fn( image, int_field[i].field, &value, a );
g_value_unset( &value ); g_value_unset( &value );
if( result ) if( result )
@ -692,8 +745,8 @@ vips_image_map( IMAGE *im, VipsImageMapFn fn, void *a )
} }
for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) { for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) {
vips_image_get( im, double_field[i].field, &value ); vips_image_get( image, double_field[i].field, &value );
result = fn( im, double_field[i].field, &value, a ); result = fn( image, double_field[i].field, &value, a );
g_value_unset( &value ); g_value_unset( &value );
if( result ) if( result )
@ -701,16 +754,16 @@ vips_image_map( IMAGE *im, VipsImageMapFn fn, void *a )
} }
for( i = 0; i < VIPS_NUMBER( string_field ); i++ ) { for( i = 0; i < VIPS_NUMBER( string_field ); i++ ) {
vips_image_get( im, string_field[i].field, &value ); vips_image_get( image, string_field[i].field, &value );
result = fn( im, string_field[i].field, &value, a ); result = fn( image, string_field[i].field, &value, a );
g_value_unset( &value ); g_value_unset( &value );
if( result ) if( result )
return( result ); return( result );
} }
if( im->Meta_traverse && if( image->Meta_traverse &&
(result = im_slist_map2( im->Meta_traverse, (result = im_slist_map2( image->Meta_traverse,
(VSListMap2Fn) vips_image_map_fn, fn, a )) ) (VSListMap2Fn) vips_image_map_fn, fn, a )) )
return( result ); return( result );
@ -730,7 +783,7 @@ vips_image_map( IMAGE *im, VipsImageMapFn fn, void *a )
* For example: * For example:
* *
* |[ * |[
* vips_image_history_printf( im, "vips im_invert %s %s", * vips_image_history_printf( image, "vips im_invert %s %s",
* in->filename, out->filename ); * in->filename, out->filename );
* ]| * ]|
* *