diff --git a/ChangeLog b/ChangeLog index 7595660a..f0052df3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ - oop, histnorm was broken by the new vipsstats - never use IM ping to get a header, fixes BMP load - set @filename for non-vips formats in vips7 compat layer +- make Xres/Yres double 20/8/11 started 7.27.0 - version bump for new dev cycle diff --git a/TODO b/TODO index 366e729d..a9ac086e 100644 --- a/TODO +++ b/TODO @@ -1,24 +1,9 @@ blocking bugs ============= -- im_copy_set is broken? - - $ vips im_copy_set babe.jpg x.v 22 2.83 2.83 100 100 - $ header -a x.v - x.v: 1024x768 uchar, 3 bands, srgb VipsImage (0x14e8000) - interpretation: 22 - srgb - xoffset: 0 - yoffset: 0 - xres: 0.000000 - yres: 0.000000 - - xres/yres need to become double (they are float atm) - - the compat stuff and the wrappers in header.c need revising - - - turning on all debug in object.c causes huge mem use? + seems to be when making a string for a set of flags? - none! diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index d937b9ed..7570ef70 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -227,7 +227,7 @@ static const char *vips_copy_names[] = { "xres", "yres", "xoffset", - "xoffset", + "yoffset", "bands", "format", "coding", diff --git a/libvips/include/vips/header.h b/libvips/include/vips/header.h index 82f50e58..dcee0143 100644 --- a/libvips/include/vips/header.h +++ b/libvips/include/vips/header.h @@ -105,7 +105,7 @@ void vips_image_init_fields( VipsImage *image, int xsize, int ysize, int bands, VipsBandFormat format, VipsCoding coding, VipsInterpretation interpretation, - float xres, float yres ); + double xres, double yres ); int vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] ); int vips_image_copy_fieldsv( VipsImage *out, VipsImage *in1, ... ) diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 601bb22e..3e9ea0c0 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -263,8 +263,8 @@ typedef struct _VipsImage { VipsBandFormat BandFmt; /* pixel format */ VipsCoding Coding; /* pixel coding */ VipsInterpretation Type;/* pixel interpretation */ - float Xres; /* horizontal pixels per millimetre */ - float Yres; /* vertical pixels per millimetre */ + double Xres; /* horizontal pixels per millimetre */ + double Yres; /* vertical pixels per millimetre */ int Xoffset; /* image origin hint */ int Yoffset; /* image origin hint */ @@ -294,6 +294,13 @@ typedef struct _VipsImage { * VipsImage. */ + /* During vips image read and write we need temporary float-sized + * fields in the struct for staging xres/yres. Don't use these any + * other time. + */ + float Xres_float; + float Yres_float; + char *mode; /* mode string passed to _new() */ VipsImageType dtype; /* descriptor type */ int fd; /* file descriptor */ diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index cd8aee27..219bc9bb 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -153,9 +153,6 @@ static HeaderField int_field[] = { { "yoffset", G_STRUCT_OFFSET( VipsImage, Yoffset ) } }; -/* These are actually floats :-( how annoying. We report them as doubles for - * consistency with the vips_image_*() functions. - */ static HeaderField double_field[] = { { "xres", G_STRUCT_OFFSET( VipsImage, Xres ) }, { "yres", G_STRUCT_OFFSET( VipsImage, Yres ) } @@ -456,7 +453,7 @@ vips_image_init_fields( VipsImage *image, int xsize, int ysize, int bands, VipsBandFormat format, VipsCoding coding, VipsInterpretation interpretation, - float xres, float yres ) + double xres, double yres ) { g_object_set( image, "width", xsize, @@ -554,8 +551,8 @@ vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] ) out->Coding = in[0]->Coding; out->Xres = in[0]->Xres; out->Yres = in[0]->Yres; - out->Xoffset = 0; - out->Yoffset = 0; + out->Xoffset = in[0]->Xoffset; + out->Yoffset = in[0]->Yoffset; /* Count number of images. */ @@ -750,7 +747,7 @@ vips_image_get( VipsImage *image, const char *field, GValue *value_copy ) if( strcmp( field, double_field[i].field ) == 0 ) { g_value_init( value_copy, G_TYPE_DOUBLE ); g_value_set_double( value_copy, - G_STRUCT_MEMBER( float, image, + G_STRUCT_MEMBER( double, image, double_field[i].offset ) ); return( 0 ); } @@ -759,7 +756,7 @@ vips_image_get( VipsImage *image, const char *field, GValue *value_copy ) 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, + G_STRUCT_MEMBER( double, image, old_double_field[i].offset ) ); return( 0 ); } @@ -1135,13 +1132,13 @@ vips_image_get_double( VipsImage *image, const char *field, double *out ) for( i = 0; i < VIPS_NUMBER( double_field ); i++ ) if( strcmp( field, double_field[i].field ) == 0 ) { - *out = G_STRUCT_MEMBER( float, image, + *out = G_STRUCT_MEMBER( double, image, double_field[i].offset ); 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, + *out = G_STRUCT_MEMBER( double, image, old_double_field[i].offset ); return( 0 ); } diff --git a/libvips/iofuncs/object.c b/libvips/iofuncs/object.c index e4faeb48..d529b94a 100644 --- a/libvips/iofuncs/object.c +++ b/libvips/iofuncs/object.c @@ -925,6 +925,7 @@ vips_object_set_property( GObject *gobject, vips_object_print_name( object ); printf( ".%s = %s\n", g_param_spec_get_name( pspec ), str_value ); g_free( str_value ); + } #endif /*DEBUG*/ @@ -1372,7 +1373,8 @@ vips_object_class_install_argument( VipsObjectClass *object_class, VipsArgumentClass *argument_class = g_new( VipsArgumentClass, 1 ); #ifdef DEBUG - printf( "vips_object_class_install_argument: %s\n", + printf( "vips_object_class_install_argument: %s %s\n", + g_type_name( G_TYPE_FROM_CLASS( object_class ) ), g_param_spec_get_name( pspec ) ); #endif /*DEBUG*/ diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index cee70b8a..8c65478b 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -255,8 +255,8 @@ static FieldIO fields[] = { { G_STRUCT_OFFSET( VipsImage, BandFmt ), 4, vips__copy_4byte }, { G_STRUCT_OFFSET( VipsImage, Coding ), 4, vips__copy_4byte }, { G_STRUCT_OFFSET( VipsImage, Type ), 4, vips__copy_4byte }, - { G_STRUCT_OFFSET( VipsImage, Xres ), 4, vips__copy_4byte }, - { G_STRUCT_OFFSET( VipsImage, Yres ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Xres_float ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Yres_float ), 4, vips__copy_4byte }, { G_STRUCT_OFFSET( VipsImage, Length ), 4, vips__copy_4byte }, { G_STRUCT_OFFSET( VipsImage, Compression ), 2, vips__copy_2byte }, { G_STRUCT_OFFSET( VipsImage, Level ), 2, vips__copy_2byte }, @@ -304,6 +304,12 @@ vips__read_header_bytes( VipsImage *im, unsigned char *from ) */ im->Bbits = vips_format_sizeof( im->BandFmt ) << 3; + /* We read xres/yres as floats to a staging area, then copy to double + * in the main fields. + */ + im->Xres = im->Xres_float; + im->Yres = im->Yres_float; + return( 0 ); } @@ -318,6 +324,12 @@ vips__write_header_bytes( VipsImage *im, unsigned char *to ) int i; unsigned char *q; + /* We set xres/yres as floats in a staging area, then copy those + * smaller values to the file. + */ + im->Xres_float = im->Xres; + im->Yres_float = im->Yres; + /* Always write the magic number MSB first. */ vips__copy_4byte( !vips_amiMSBfirst(),