diff --git a/ChangeLog b/ChangeLog index e30eddfe..76df4922 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,7 @@ - set MAP_NOCACHE on OS X, otherwise performance dives off a cliff with files larger than memory - removed man pages, we are all gtk-doc now +- added VIPS_FORMAT_BIGENDIAN format flag 30/11/10 started 7.24.0 - bump for new stable diff --git a/libvips/format/format.c b/libvips/format/format.c index bf401c7d..22b5da6a 100644 --- a/libvips/format/format.c +++ b/libvips/format/format.c @@ -68,11 +68,16 @@ * VipsFormatFlags: * @VIPS_FORMAT_NONE: no flags set * @VIPS_FORMAT_PARTIAL: the image may be read lazilly + * @VIPS_FORMAT_BIGENDIAN: image pixels are most-significant byte first * * Some hints about the image loader. * * @VIPS_FORMAT_PARTIAL means that the image can be read directly from the * file without needing to be unpacked to a temporary image first. + * + * @VIPS_FORMAT_BIGENDIAN means that image pixels are most-significant byte + * first. Depending on the native byte order of the host machine, you may + * need to swap bytes. See im_copy_swap(). */ /** @@ -339,6 +344,27 @@ vips_format_get_flags( VipsFormatClass *format, const char *filename ) static const char *vips_suffs[] = { ".v", NULL }; +int +im_isvips( const char *filename ) +{ + unsigned char buf[4]; + + if( im__get_bytes( filename, buf, 4 ) ) { + if( buf[0] == 0x08 && buf[1] == 0xf2 && + buf[2] == 0xa6 && buf[3] == 0xb6 ) + /* SPARC-order VIPS image. + */ + return( 1 ); + else if( buf[3] == 0x08 && buf[2] == 0xf2 && + buf[1] == 0xa6 && buf[0] == 0xb6 ) + /* INTEL-order VIPS image. + */ + return( 1 ); + } + + return( 0 ); +} + static int file2vips( const char *filename, IMAGE *out ) { @@ -366,7 +392,19 @@ vips2file( IMAGE *im, const char *filename ) static VipsFormatFlags vips_flags( const char *filename ) { - return( VIPS_FORMAT_PARTIAL ); + VipsFormatFlags flags; + unsigned char buf[4]; + + flags = VIPS_FORMAT_PARTIAL; + + if( im__get_bytes( filename, buf, 4 ) && + buf[0] == 0x08 && + buf[1] == 0xf2 && + buf[2] == 0xa6 && + buf[3] == 0xb6 ) + flags |= VIPS_FORMAT_BIGENDIAN; + + return( flags ); } /* Vips format adds no new members. diff --git a/libvips/include/vips/format.h b/libvips/include/vips/format.h index 57bc7cad..4405c6a7 100644 --- a/libvips/include/vips/format.h +++ b/libvips/include/vips/format.h @@ -54,7 +54,8 @@ extern "C" { */ typedef enum { VIPS_FORMAT_NONE = 0, /* No flags set */ - VIPS_FORMAT_PARTIAL = 1 /* Lazy read OK (eg. tiled tiff) */ + VIPS_FORMAT_PARTIAL = 1, /* Lazy read OK (eg. tiled tiff) */ + VIPS_FORMAT_BIGENDIAN = 2 /* Most-significant byte first */ } VipsFormatFlags; /* Don't instantiate these things, just use the class stuff. diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 220984a2..d4433c92 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -382,7 +382,7 @@ vips_image_finalize( GObject *gobject ) if( image->dtype == VIPS_IMAGE_OPENOUT ) (void) im__writehist( image ); if( close( image->fd ) == -1 ) - im_error( "vips_image_finalize", + im_error( "VipsImage", _( "unable to close fd for %s" ), image->filename ); image->fd = -1; @@ -818,6 +818,21 @@ vips_image_build( VipsObject *object ) return( -1 ); if( vips_format_is_vips( format ) ) { + /* We may need to byteswap. + */ + VipsFormatFlags flags = + vips_format_get_flags( format, + image->filename ); + gboolean bigendian = flags & VIPS_FORMAT_BIGENDIAN; + gboolean swap = bigendian != im_amiMSBfirst(); + + if( swap ) { + VipsImage *real; + + if( !(real = im_open_local( image, "p" ); + image->dtype = VIPS_IMAGE_PARTIAL; + + if( vips_open_input( image ) ) return( -1 ); @@ -835,59 +850,48 @@ vips_image_build( VipsObject *object ) im_amiMSBfirst() && vips_format_sizeof( image->BandFmt ) != 1 ) { - im_error( "vips_image_build", - _( "open for read-" + im_error( "VipsImage", "%s", + _( "open read-" "write for native format " "images only" ) ); return( -1 ); } - image->dtype = VIPS_IMAGE_TYPE_OPENIN; + image->dtype = VIPS_IMAGE_OPENINRW; } } else { - if( vips_open_lazy( image, - format, filename, mode[1] == 'd' ) ) + if( vips_open_lazy( image, format, + image->filename, image->mode[1] == 'd' ) ) return( -1 ); } break; case 'w': - if( (format = vips_format_for_name( filename )) ) { - if( vips_format_is_vips( format ) ) { - if( vips_open_output( image ) ) - return( -1 ); - } - else { - image->dtype = VIPS_IMAGE_TYPE_PARTIAL; - vips_attach_save( image, - format->save, filename ); - } - } - else { - char suffix[FILENAME_MAX]; - - im_filename_suffix( filename, suffix ); - im_error( "vips_image_build", - _( "unsupported filetype \"%s\"" ), - suffix ); - + if( !(format = vips_format_for_name( image->filename )) ) return( -1 ); + + if( vips_format_is_vips( format ) ) + image->dtype = VIPS_IMAGE_OPENOUT; + else { + image->dtype = VIPS_IMAGE_PARTIAL; + vips_attach_save( image, + format->save, image->filename ); } break; case 't': - image->dtype = VIPS_IMAGE_TYPE_SETBUF; + image->dtype = VIPS_IMAGE_SETBUF; image->dhint = VIPS_DEMAND_ANY; break; case 'p': - image->dtype = VIPS_IMAGE_TYPE_PARTIAL; + image->dtype = VIPS_IMAGE_PARTIAL; break; default: - im_error( "vips_image_build", _( "bad mode \"%s\"" ), mode ); + im_error( "VipsImage", _( "bad mode \"%s\"" ), mode ); return( -1 ); } diff --git a/libvips/iofuncs/util.c b/libvips/iofuncs/util.c index 5ebb6281..aff424f3 100644 --- a/libvips/iofuncs/util.c +++ b/libvips/iofuncs/util.c @@ -1498,27 +1498,6 @@ im_ispoweroftwo( int p ) return( 0 ); } -int -im_isvips( const char *filename ) -{ - unsigned char buf[4]; - - if( im__get_bytes( filename, buf, 4 ) ) { - if( buf[0] == 0x08 && buf[1] == 0xf2 && - buf[2] == 0xa6 && buf[3] == 0xb6 ) - /* SPARC-order VIPS image. - */ - return( 1 ); - else if( buf[3] == 0x08 && buf[2] == 0xf2 && - buf[1] == 0xa6 && buf[0] == 0xb6 ) - /* INTEL-order VIPS image. - */ - return( 1 ); - } - - return( 0 ); -} - /* Test this processor for endianness. True for SPARC order. */ int diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 6e4e9430..93a09b6d 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -1031,16 +1031,3 @@ im_open_vips( const char *filename ) return( im ); } - -IMAGE * -im_openout( const char *filename ) -{ - IMAGE *image; - - if( !(image = im_init( filename )) ) - return( NULL ); - image->dtype = IM_OPENOUT; - - return( image ); -} -