new-style vips load/save works

This commit is contained in:
John Cupitt 2011-11-26 12:41:54 +00:00
parent 43587801f7
commit 8ee5f36d4b
6 changed files with 65 additions and 75 deletions

9
TODO
View File

@ -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
savers need it too ... image->output_to_arg()
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()
make compat wrappers for old im_jpeg2vips() and im_vips2jpeg() make compat wrappers for old im_jpeg2vips() and im_vips2jpeg()

View File

@ -414,7 +414,7 @@ vips_file_load_start_cb( VipsImage *out, void *a, void *dummy )
*/ */
if( load->disc && if( load->disc &&
disc_threshold && disc_threshold &&
(load->flags & VIPS_FORMAT_PARTIAL) && (load->flags & VIPS_FILE_PARTIAL) &&
image_size > disc_threshold ) image_size > disc_threshold )
if( !(load->real = vips_image_new_disc_temp( "%s.v" )) ) if( !(load->real = vips_image_new_disc_temp( "%s.v" )) )
return( NULL ); return( NULL );

View File

@ -42,6 +42,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <vips/vips.h> #include <vips/vips.h>
#include <vips/internal.h>
typedef VipsFileLoad VipsFileLoadVips; typedef VipsFileLoad VipsFileLoadVips;
typedef VipsFileLoadClass VipsFileLoadVipsClass; typedef VipsFileLoadClass VipsFileLoadVipsClass;
@ -58,41 +59,25 @@ vips_file_load_vips_build( VipsObject *object )
return( 0 ); return( 0 );
} }
static int static gboolean
vips_file_load_vips_is_a( const char *filename ) vips_file_load_vips_is_a( const char *filename )
{ {
unsigned char buf[4]; return( vips__file_magic( filename ) );
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 );
} }
static int static int
vips_file_load_vips_get_flags( VipsFileLoad *load ) vips_file_load_vips_get_flags( VipsFileLoad *load )
{ {
VipsFile *file = VIPS_FILE( load ); VipsFile *file = VIPS_FILE( load );
unsigned char buf[4];
load->flags = VIPS_FILE_PARTIAL; load->flags = VIPS_FILE_PARTIAL;
if( vips__get_bytes( file->filename, buf, 4 ) && if( vips__file_magic( file->filename ) == VIPS_MAGIC_INTEL ) {
buf[0] == 0x08 && printf( "vips_file_load_vips_get_flags: "
buf[1] == 0xf2 && "%s is intel, setting bigendian\n",
buf[2] == 0xa6 && file->filename );
buf[3] == 0xb6 ) load->flags |= VIPS_FILE_BIGENDIAN;
load->flags |= VIPS_FORMAT_BIGENDIAN; }
return( 0 ); return( 0 );
} }

View File

@ -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__read_2byte( int msb_first, unsigned char *to, unsigned char **from );
void vips__write_4byte( 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 ); void vips__write_2byte( unsigned char **to, unsigned char *from );
guint32 vips__file_magic( const char *filename );
int vips__has_extension_block( VipsImage *im ); int vips__has_extension_block( VipsImage *im );
void *vips__read_extension_block( VipsImage *im, int *size ); void *vips__read_extension_block( VipsImage *im, int *size );
int vips__write_extension_block( VipsImage *im, void *buf, int size ); int vips__write_extension_block( VipsImage *im, void *buf, int size );

View File

@ -464,36 +464,26 @@ vips_image_rewind( VipsObject *object )
*/ */
/* If we write to (eg.) TIFF, actually do the write /* If we write to (eg.) TIFF, actually do the write
* to a "p" and on "written" do im_vips2tiff() or whatever. Track save * to a "p" and on "written" do im_vips2tiff() or whatever.
* parameters here.
*/ */
typedef struct {
const char *file_op; /* Save function */
char *filename; /* Save args */
} SaveBlock;
/* From "written" callback: invoke a delayed save. /* From "written" callback: invoke a delayed save.
*/ */
static void 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; *result = -1;
g_free( sb->filename ); g_free( filename );
g_free( sb );
} }
static void 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_signal_connect( image, "written",
G_CALLBACK( vips_image_save_cb ), sb ); G_CALLBACK( vips_image_save_cb ),
g_strdup( filename ) );
} }
/* Progress feedback. /* Progress feedback.
@ -576,7 +566,7 @@ vips_image_build( VipsObject *object )
const char *filename = image->filename; const char *filename = image->filename;
const char *mode = image->mode; const char *mode = image->mode;
const char *file_op; guint32 magic;
size_t sizeof_image; size_t sizeof_image;
VIPS_DEBUG_MSG( "vips_image_build: %p\n", image ); VIPS_DEBUG_MSG( "vips_image_build: %p\n", image );
@ -587,37 +577,39 @@ vips_image_build( VipsObject *object )
/* Parse the mode string. /* Parse the mode string.
*/ */
switch( mode[0] ) { switch( mode[0] ) {
case 'r': case 'v':
if( !(file_op = vips_file_find_load( filename )) ) native:
if( vips_image_open_input( image ) )
return( -1 ); 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. /* We may need to byteswap.
*/ */
VipsImage *t; guint32 us = vips_amiMSBfirst() ?
VipsFormatFlags flags; VIPS_MAGIC_INTEL : VIPS_MAGIC_SPARC;
if( vips_call( file_op, filename, &t, if( magic == us )
"flags", &flags,
NULL ) )
return( -1 );
if( (flags & VIPS_FORMAT_BIGENDIAN) ==
vips_amiMSBfirst() ) {
/* Native byte order .. open directly into /* Native byte order .. open directly into
* this image. * this image.
*/ */
g_object_unref( t ); goto native;
if( vips_image_open_input( image ) )
return( -1 );
if( mode[1] == 'w' )
image->dtype = VIPS_IMAGE_MMAPINRW;
}
else { else {
VipsImage *t;
VipsImage *t2; 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, if( vips_copy( t, &t2,
"swap", TRUE, "swap", TRUE,
NULL ) ) { NULL ) ) {
@ -626,8 +618,6 @@ vips_image_build( VipsObject *object )
} }
g_object_unref( t ); g_object_unref( t );
/* Byteswap t and copy into this image.
*/
image->dtype = VIPS_IMAGE_PARTIAL; image->dtype = VIPS_IMAGE_PARTIAL;
if( vips_image_write( t2, image ) ) { if( vips_image_write( t2, image ) ) {
g_object_unref( t2 ); g_object_unref( t2 );
@ -639,8 +629,10 @@ vips_image_build( VipsObject *object )
else { else {
VipsImage *t; VipsImage *t;
if( vips_call( file_op, filename, &t, NULL ) ) if( vips_file_read( filename, &t, NULL ) )
return( -1 ); return( -1 );
image->dtype = VIPS_IMAGE_PARTIAL;
if( vips_image_write( t, image ) ) { if( vips_image_write( t, image ) ) {
g_object_unref( t ); g_object_unref( t );
return( -1 ); return( -1 );
@ -651,15 +643,19 @@ vips_image_build( VipsObject *object )
break; break;
case 'w': case 'w':
{
const char *file_op;
if( !(file_op = vips_file_find_save( filename )) ) if( !(file_op = vips_file_find_save( filename )) )
return( -1 ); return( -1 );
if( strcmp( file_op, "vipssave" ) == 0 ) if( strcmp( file_op, "VipsFileSaveVips" ) == 0 )
image->dtype = VIPS_IMAGE_OPENOUT; image->dtype = VIPS_IMAGE_OPENOUT;
else { else {
image->dtype = VIPS_IMAGE_PARTIAL; image->dtype = VIPS_IMAGE_PARTIAL;
vips_attach_save( image, file_op, filename ); vips_attach_save( image, filename );
} }
}
break; break;
case 't': case 't':

View File

@ -218,6 +218,19 @@ vips__write_2byte( unsigned char **to, unsigned char *from )
*to += 2; *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. /* offset, read, write functions.
*/ */
typedef struct _FieldIO { typedef struct _FieldIO {