From 48763493e5e8a27432a5e3a7ac7e846995ff917a Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 1 Dec 2011 14:52:49 +0000 Subject: [PATCH] get byteswap working again --- TODO | 14 ------ libvips/iofuncs/header.c | 4 ++ libvips/iofuncs/image.c | 16 +++--- libvips/iofuncs/vips.c | 106 +++++++++++++++------------------------ tools/header.c | 4 +- 5 files changed, 53 insertions(+), 91 deletions(-) diff --git a/TODO b/TODO index 11020eba..f1d517d1 100644 --- a/TODO +++ b/TODO @@ -1,19 +1,5 @@ -- try - - edvips -n big x.v - header x.v - vips_image_build: byteswapping vips read - vips warning: VipsImage: unable to read data for "x.v", file has been - truncated - sanity failure: VipsImage (0x1764170) bad enum - - - - - test vips_foreign_load_vips_get_flags(), sense inverted? - we have various printf()s left in the byteswap codepath - test load/save jpeg buffer leaktest diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 57465121..082dcb7d 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -538,6 +538,10 @@ vips_image_copy_fields_array( VipsImage *out, VipsImage *in[] ) g_assert( in[0] ); + /* Copy magic too, handy for knowing the original image's byte order. + */ + out->magic = in[0]->magic; + out->Xsize = in[0]->Xsize; out->Ysize = in[0]->Ysize; out->Bands = in[0]->Bands; diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 3595a0d2..064e0cb2 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -405,12 +405,11 @@ vips_image_sanity( VipsObject *object, VipsBuf *buf ) if( !image->filename ) vips_buf_appends( buf, "NULL filename\n" ); - /* All -1 means im has been inited but never used. + /* All 0 means im has been inited but never used. */ - if( image->Xsize != -1 || - image->Ysize != -1 || - image->Bands != -1 || - image->BandFmt != -1 ) { + if( image->Xsize != 0 || + image->Ysize != 0 || + image->Bands != 0 ) { if( image->Xsize <= 0 || image->Ysize <= 0 || image->Bands <= 0 ) @@ -602,9 +601,6 @@ vips_image_build( VipsObject *object ) VipsImage *t; VipsImage *t2; - printf( "vips_image_build: " - "byteswapping vips read\n" ); - /* Open the image in t, then byteswap to this * image. */ @@ -1597,8 +1593,8 @@ int vips_image_write( VipsImage *image, VipsImage *out ) { if( vips_image_pio_input( image ) || - vips_image_pio_output( out ) ) - if( vips_image_copy_fields( out, image ) ) + vips_image_pio_output( out ) || + vips_image_copy_fields( out, image ) ) return( -1 ); vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, image, NULL ); diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index a566e94e..6c676021 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -170,54 +170,34 @@ image_pixel_length( VipsImage *image ) return( psize + image->sizeof_header ); } -/* Read short/int/float LSB and MSB first. +/* Copy 2 and 4 bytes, swapping to and from native. */ void -vips__read_4byte( int msb_first, unsigned char *to, unsigned char **from ) +vips__copy_4byte( int msb_first, unsigned char *to, unsigned char *from ) { - unsigned char *p = *from; - int out; + guint32 out; if( msb_first ) - out = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; + out = from[0] << 24 | from[1] << 16 | from[2] << 8 | from[3]; else - out = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0]; + out = from[3] << 24 | from[2] << 16 | from[1] << 8 | from[0]; - *from += 4; *((guint32 *) to) = out; } void -vips__read_2byte( int msb_first, unsigned char *to, unsigned char **from ) +vips__copy_2byte( int msb_first, unsigned char *to, unsigned char *from ) { - int out; - unsigned char *p = *from; + guint16 out; if( msb_first ) - out = p[0] << 8 | p[1]; + out = from[0] << 8 | from[1]; else - out = p[1] << 8 | p[0]; + out = from[1] << 8 | from[0]; - *from += 2; *((guint16 *) to) = out; } -/* We always write in native byte order. - */ -void -vips__write_4byte( unsigned char **to, unsigned char *from ) -{ - *((guint32 *) *to) = *((guint32 *) from); - *to += 4; -} - -void -vips__write_2byte( unsigned char **to, unsigned char *from ) -{ - *((guint16 *) *to) = *((guint16 *) from); - *to += 2; -} - guint32 vips__file_magic( const char *filename ) { @@ -235,39 +215,25 @@ vips__file_magic( const char *filename ) */ typedef struct _FieldIO { glong offset; - void (*read)( int msb_first, unsigned char *to, unsigned char **from ); - void (*write)( unsigned char **to, unsigned char *from ); + int size; + void (*copy)( int msb_first, unsigned char *to, unsigned char *from ); } FieldIO; static FieldIO fields[] = { - { G_STRUCT_OFFSET( VipsImage, Xsize ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Ysize ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Bands ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Bbits ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, BandFmt ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Coding ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Type ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Xres ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Yres ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Length ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Compression ), - vips__read_2byte, vips__write_2byte }, - { G_STRUCT_OFFSET( VipsImage, Level ), - vips__read_2byte, vips__write_2byte }, - { G_STRUCT_OFFSET( VipsImage, Xoffset ), - vips__read_4byte, vips__write_4byte }, - { G_STRUCT_OFFSET( VipsImage, Yoffset ), - vips__read_4byte, vips__write_4byte } + { G_STRUCT_OFFSET( VipsImage, Xsize ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Ysize ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Bands ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Bbits ), 4, vips__copy_4byte }, + { 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, Length ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Compression ), 2, vips__copy_2byte }, + { G_STRUCT_OFFSET( VipsImage, Level ), 2, vips__copy_2byte }, + { G_STRUCT_OFFSET( VipsImage, Xoffset ), 4, vips__copy_4byte }, + { G_STRUCT_OFFSET( VipsImage, Yoffset ), 4, vips__copy_4byte } }; int @@ -276,19 +242,23 @@ vips__read_header_bytes( VipsImage *im, unsigned char *from ) int msb_first; int i; - vips__read_4byte( 1, (unsigned char *) &im->magic, &from ); + vips__copy_4byte( 1, (unsigned char *) &im->magic, from ); + from += 4; if( im->magic != VIPS_MAGIC_INTEL && im->magic != VIPS_MAGIC_SPARC ) { vips_error( "VipsImage", _( "\"%s\" is not a VIPS image" ), im->filename ); return( -1 ); } + msb_first = im->magic == VIPS_MAGIC_SPARC; - for( i = 0; i < VIPS_NUMBER( fields ); i++ ) - fields[i].read( msb_first, + for( i = 0; i < VIPS_NUMBER( fields ); i++ ) { + fields[i].copy( msb_first, &G_STRUCT_MEMBER( unsigned char, im, fields[i].offset ), - &from ); + from ); + from += fields[i].size; + } /* Set this ourselves ... bbits is deprecated in the file format. */ @@ -300,6 +270,7 @@ vips__read_header_bytes( VipsImage *im, unsigned char *from ) int vips__write_header_bytes( VipsImage *im, unsigned char *to ) { + int msb_first; int i; unsigned char *q; @@ -311,10 +282,15 @@ vips__write_header_bytes( VipsImage *im, unsigned char *to ) to[3] = im->magic; q = to + 4; - for( i = 0; i < VIPS_NUMBER( fields ); i++ ) - fields[i].write( &q, + msb_first = im->magic == VIPS_MAGIC_SPARC; + + for( i = 0; i < VIPS_NUMBER( fields ); i++ ) { + fields[i].copy( msb_first, + q, &G_STRUCT_MEMBER( unsigned char, im, fields[i].offset ) ); + q += fields[i].size; + } /* Pad spares with zeros. */ diff --git a/tools/header.c b/tools/header.c index 1b374a52..c8ddee08 100644 --- a/tools/header.c +++ b/tools/header.c @@ -160,9 +160,9 @@ print_header( IMAGE *im, gboolean many ) vips_image_get_interpretation( im ) ) ); if( im->magic == VIPS_MAGIC_SPARC ) - printf( ", SPARC" ); + printf( ", sparc" ); else if( im->magic == VIPS_MAGIC_INTEL ) - printf( ", INTEL" ); + printf( ", intel" ); printf( "\n" );