From d186ac69d6ed4b85555f52745c568be5f1dec7bd Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 10 Jul 2018 17:16:49 +0100 Subject: [PATCH] a more more work on niftisave --- .gitignore | 1 + libvips/foreign/niftiload.c | 31 ++++++++----------------- libvips/foreign/niftisave.c | 46 ++++++++++++++++++++++++++++++++++--- libvips/foreign/pforeign.h | 19 +++++++++++++++ 4 files changed, 73 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index c91c0ee7..d7989938 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.pytest_cache compile a.out *.log diff --git a/libvips/foreign/niftiload.c b/libvips/foreign/niftiload.c index 6523f7d1..e622fab3 100644 --- a/libvips/foreign/niftiload.c +++ b/libvips/foreign/niftiload.c @@ -103,14 +103,7 @@ vips_foreign_load_nifti_dispose( GObject *gobject ) dispose( gobject ); } -/* Map DT_* datatype values to VipsBandFormat. - */ -typedef struct _DT2Vips { - int datatype; - VipsBandFormat fmt; -} DT2Vips; - -static DT2Vips vips_DT2Vips[] = { +VipsForeignDT2Vips vips_foreign_DT2Vips[] = { { DT_UINT8, VIPS_FORMAT_UCHAR }, { DT_INT8, VIPS_FORMAT_CHAR }, { DT_UINT16, VIPS_FORMAT_USHORT }, @@ -135,15 +128,10 @@ static DT2Vips vips_DT2Vips[] = { ) #endif /*HAVE_CHECKED_MUL*/ -/* All the header fields we attach as metadata. - */ -typedef struct _Field { - char *name; - GType type; - glong offset; -} Field; - -static Field other_fields[] = { +VipsForeignNiftiFields vips_foreign_nifti_fields[] = { + /* The first 8 must be the dims[] fields, see + * vips_foreign_save_nifti_make_nim(). + */ { "ndim", G_TYPE_INT, G_STRUCT_OFFSET( nifti_image, ndim ) }, { "nx", G_TYPE_INT, G_STRUCT_OFFSET( nifti_image, nx ) }, { "ny", G_TYPE_INT, G_STRUCT_OFFSET( nifti_image, ny ) }, @@ -401,13 +389,14 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti, VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB, xres, yres ); - for( i = 0; i < VIPS_NUMBER( other_fields ); i++ ) { + for( i = 0; i < VIPS_NUMBER( vips_foreign_nifti_fields ); i++ ) { GValue value = { 0 }; - g_value_init( &value, other_fields[i].type ); + g_value_init( &value, vips_foreign_nifti_fields[i].type ); vips_gvalue_read( &value, - (gpointer) nim + other_fields[i].offset ); - vips_snprintf( txt, 256, "nifti-%s", other_fields[i].name ); + (gpointer) nim + vips_foreign_nifti_fields[i].offset ); + vips_snprintf( txt, 256, "nifti-%s", + vips_foreign_nifti_fields[i].name ); vips_image_set( out, txt, &value ); g_value_unset( &value ); } diff --git a/libvips/foreign/niftisave.c b/libvips/foreign/niftisave.c index f40f5b85..80c51fa2 100644 --- a/libvips/foreign/niftisave.c +++ b/libvips/foreign/niftisave.c @@ -79,10 +79,50 @@ vips_foreign_save_nifti_dispose( GObject *gobject ) } static int -vips_foreign_save_nifti_make_header( VipsForeignSaveNifti *nifti, - struct nifti_1_header *nhdr ) +vips_foreign_save_nifti_make_nim( VipsForeignSaveNifti *nifti, + VipsImage *image ) { + int dims[8]; + int datatype; + int height; + int i; + /* The first 8 members of vips_foreign_nifti_fields[] are the dims + * fields. + */ + for( i = 0; i < VIPS_NUMBER( dims ); i++ ) { + static char name[256]; + + vips_snprintf( name, 256, "nifti-%s", + vips_foreign_nifti_fields[i].name ); + if( vips_image_get_int( image, name, &dims[i] ) ) + return( -1 ); + } + + height = 1; + for( i = 2; i < VIPS_NUMBER( dims ) && i < dims[0]; i++ ) + height *= dims[i]; + if( images->Xsize != dims[1] || + images->Ysize != height ) { + vips_error( class->nickname, + "%s", _( "bad image dimensions" ) ); + return( -1 ); + } + + datatype = -1; + for( i = 0; i < vips_foreign_DT2Vips; i++ ) + if( vips_foreign_DT2Vips[i].format == image.format ) { + datatype = vips_foreign_DT2Vips[i].datatype; + break; + } + if( datatype == -1 ) { + vips_error( class->nickname, + "%s", _( "unsupported libvips image type" ) ); + return( -1 ); + } + + if( !(nnifti->nim = nifti_make_new_nim( dims, datatype, FALSE )) ) + return( -1 ); return( 0 ); } @@ -101,7 +141,7 @@ vips_foreign_save_nifti_build( VipsObject *object ) build( object ) ) return( -1 ); - if( vips_foreign_save_nifti_make_header( nifti, &nhdr ) ) + if( vips_foreign_save_nifti_make_header( nifti, save->ready, &nhdr ) ) return( -1 ); if( !(nifti->nim = nifti_convert_nhdr2nim( nhdr, nifti->filename )) ) diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index c18c634e..7179c501 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -256,6 +256,25 @@ int vips__quantise_image( VipsImage *in, VipsImage **index_out, VipsImage **palette_out, int colours, int Q, double dither ); +/* Map DT_* datatype values to VipsBandFormat. + */ +typedef struct _VipsForeignDT2Vips { + int datatype; + VipsBandFormat fmt; +} VipsForeignDT2Vips + +extern VipsForeignDT2Vips vips_foreign_DT2Vips[]; + +/* All the header fields we attach as metadata. + */ +typedef struct _VipsForeignNiftiFields { + char *name; + GType type; + glong offset; +} VipsForeignNiftiFields; + +VipsForeignNiftiFields vips_foreign_nifti_fields[]; + #ifdef __cplusplus } #endif /*__cplusplus*/