From 8ee5f36d4b3a4d70710fa8fe6f85a19b7dea9cb5 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sat, 26 Nov 2011 12:41:54 +0000 Subject: [PATCH] new-style vips load/save works --- TODO | 9 +--- libvips/file/file.c | 2 +- libvips/file/vipsload.c | 33 ++++--------- libvips/include/vips/internal.h | 1 + libvips/iofuncs/image.c | 82 ++++++++++++++++----------------- libvips/iofuncs/vips.c | 13 ++++++ 6 files changed, 65 insertions(+), 75 deletions(-) diff --git a/TODO b/TODO index 067e0950..9a56a6f6 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,6 @@ -- we have to open the image to see flags argh +- CLI stuff image->new_from_string() needs to use new system too, check this - - - CLI stuff image->new_from_string() needs to use new system too, chcek this - - savers need it too ... delayed save system and also - image->output_to_arg() + savers need it too ... image->output_to_arg() make compat wrappers for old im_jpeg2vips() and im_vips2jpeg() diff --git a/libvips/file/file.c b/libvips/file/file.c index 5f8c2e81..905f2ac1 100644 --- a/libvips/file/file.c +++ b/libvips/file/file.c @@ -414,7 +414,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy ) */ if( load->disc && disc_threshold && - (load->flags & VIPS_FORMAT_PARTIAL) && + (load->flags & VIPS_FILE_PARTIAL) && image_size > disc_threshold ) if( !(load->real = vips_image_new_disc_temp( "%s.v" )) ) return( NULL ); diff --git a/libvips/file/vipsload.c b/libvips/file/vipsload.c index 0fb909ae..298a9094 100644 --- a/libvips/file/vipsload.c +++ b/libvips/file/vipsload.c @@ -42,6 +42,7 @@ #include #include +#include typedef VipsFileLoad VipsFileLoadVips; typedef VipsFileLoadClass VipsFileLoadVipsClass; @@ -58,41 +59,25 @@ vips_file_load_vips_build( VipsObject *object ) return( 0 ); } -static int +static gboolean vips_file_load_vips_is_a( const char *filename ) { - unsigned char buf[4]; - - if( vips__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 ); + return( vips__file_magic( filename ) ); } static int vips_file_load_vips_get_flags( VipsFileLoad *load ) { VipsFile *file = VIPS_FILE( load ); - unsigned char buf[4]; load->flags = VIPS_FILE_PARTIAL; - if( vips__get_bytes( file->filename, buf, 4 ) && - buf[0] == 0x08 && - buf[1] == 0xf2 && - buf[2] == 0xa6 && - buf[3] == 0xb6 ) - load->flags |= VIPS_FORMAT_BIGENDIAN; + if( vips__file_magic( file->filename ) == VIPS_MAGIC_INTEL ) { + printf( "vips_file_load_vips_get_flags: " + "%s is intel, setting bigendian\n", + file->filename ); + load->flags |= VIPS_FILE_BIGENDIAN; + } return( 0 ); } diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 7cc16db7..b69a4505 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -107,6 +107,7 @@ void vips__read_4byte( int msb_first, unsigned char *to, unsigned char **from ); void vips__read_2byte( int msb_first, unsigned char *to, unsigned char **from ); void vips__write_4byte( unsigned char **to, unsigned char *from ); void vips__write_2byte( unsigned char **to, unsigned char *from ); +guint32 vips__file_magic( const char *filename ); int vips__has_extension_block( VipsImage *im ); void *vips__read_extension_block( VipsImage *im, int *size ); int vips__write_extension_block( VipsImage *im, void *buf, int size ); diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 0e30f36d..6ac98cc1 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -464,36 +464,26 @@ vips_image_rewind( VipsObject *object ) */ /* If we write to (eg.) TIFF, actually do the write - * to a "p" and on "written" do im_vips2tiff() or whatever. Track save - * parameters here. + * to a "p" and on "written" do im_vips2tiff() or whatever. */ -typedef struct { - const char *file_op; /* Save function */ - char *filename; /* Save args */ -} SaveBlock; /* From "written" callback: invoke a delayed save. */ static void -vips_image_save_cb( VipsImage *image, int *result, SaveBlock *sb ) +vips_image_save_cb( VipsImage *image, int *result, char *filename ) { - if( vips_call( sb->file_op, image, sb->filename, NULL ) ) + if( vips_file_write( image, filename, NULL ) ) *result = -1; - g_free( sb->filename ); - g_free( sb ); + g_free( filename ); } static void -vips_attach_save( VipsImage *image, const char *file_op, const char *filename ) +vips_attach_save( VipsImage *image, const char *filename ) { - SaveBlock *sb; - - sb = g_new( SaveBlock, 1 ); - sb->file_op = file_op; - sb->filename = g_strdup( filename ); g_signal_connect( image, "written", - G_CALLBACK( vips_image_save_cb ), sb ); + G_CALLBACK( vips_image_save_cb ), + g_strdup( filename ) ); } /* Progress feedback. @@ -576,7 +566,7 @@ vips_image_build( VipsObject *object ) const char *filename = image->filename; const char *mode = image->mode; - const char *file_op; + guint32 magic; size_t sizeof_image; VIPS_DEBUG_MSG( "vips_image_build: %p\n", image ); @@ -587,37 +577,39 @@ vips_image_build( VipsObject *object ) /* Parse the mode string. */ switch( mode[0] ) { - case 'r': - if( !(file_op = vips_file_find_load( filename )) ) + case 'v': + native: + if( vips_image_open_input( image ) ) return( -1 ); - if( strcmp( file_op, "vipsload" ) == 0 ) { + if( mode[1] == 'w' ) + image->dtype = VIPS_IMAGE_MMAPINRW; + + break; + + case 'r': + if( (magic = vips__file_magic( filename )) ) { /* We may need to byteswap. */ - VipsImage *t; - VipsFormatFlags flags; + guint32 us = vips_amiMSBfirst() ? + VIPS_MAGIC_INTEL : VIPS_MAGIC_SPARC; - if( vips_call( file_op, filename, &t, - "flags", &flags, - NULL ) ) - return( -1 ); - - if( (flags & VIPS_FORMAT_BIGENDIAN) == - vips_amiMSBfirst() ) { + if( magic == us ) /* Native byte order .. open directly into * this image. */ - g_object_unref( t ); - - if( vips_image_open_input( image ) ) - return( -1 ); - - if( mode[1] == 'w' ) - image->dtype = VIPS_IMAGE_MMAPINRW; - } + goto native; else { + VipsImage *t; VipsImage *t2; + /* Open the image in t, then byteswap to this + * image. + */ + if( !(t = vips_image_new_mode( filename, + "v" )) ) + return( -1 ); + if( vips_copy( t, &t2, "swap", TRUE, NULL ) ) { @@ -626,8 +618,6 @@ vips_image_build( VipsObject *object ) } g_object_unref( t ); - /* Byteswap t and copy into this image. - */ image->dtype = VIPS_IMAGE_PARTIAL; if( vips_image_write( t2, image ) ) { g_object_unref( t2 ); @@ -639,8 +629,10 @@ vips_image_build( VipsObject *object ) else { VipsImage *t; - if( vips_call( file_op, filename, &t, NULL ) ) + if( vips_file_read( filename, &t, NULL ) ) return( -1 ); + + image->dtype = VIPS_IMAGE_PARTIAL; if( vips_image_write( t, image ) ) { g_object_unref( t ); return( -1 ); @@ -651,15 +643,19 @@ vips_image_build( VipsObject *object ) break; case 'w': +{ + const char *file_op; + if( !(file_op = vips_file_find_save( filename )) ) return( -1 ); - if( strcmp( file_op, "vipssave" ) == 0 ) + if( strcmp( file_op, "VipsFileSaveVips" ) == 0 ) image->dtype = VIPS_IMAGE_OPENOUT; else { image->dtype = VIPS_IMAGE_PARTIAL; - vips_attach_save( image, file_op, filename ); + vips_attach_save( image, filename ); } +} break; case 't': diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 1603ccc4..a86df9af 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -218,6 +218,19 @@ vips__write_2byte( unsigned char **to, unsigned char *from ) *to += 2; } +guint32 +vips__file_magic( const char *filename ) +{ + guint32 magic; + + if( vips__get_bytes( filename, (unsigned char *) &magic, 4 ) && + (magic == VIPS_MAGIC_INTEL || + magic == VIPS_MAGIC_SPARC ) ) + return( magic ); + + return( 0 ); +} + /* offset, read, write functions. */ typedef struct _FieldIO {