more getting ready for niftisave
This commit is contained in:
parent
d186ac69d6
commit
7496381fc9
@ -103,7 +103,14 @@ vips_foreign_load_nifti_dispose( GObject *gobject )
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
VipsForeignDT2Vips vips_foreign_DT2Vips[] = {
|
||||
/* Map DT_* datatype values to VipsBandFormat.
|
||||
*/
|
||||
typedef struct _VipsForeignDT2Vips {
|
||||
int datatype;
|
||||
VipsBandFormat fmt;
|
||||
} VipsForeignDT2Vips ;
|
||||
|
||||
static VipsForeignDT2Vips vips_foreign_nifti_DT2Vips[] = {
|
||||
{ DT_UINT8, VIPS_FORMAT_UCHAR },
|
||||
{ DT_INT8, VIPS_FORMAT_CHAR },
|
||||
{ DT_UINT16, VIPS_FORMAT_USHORT },
|
||||
@ -118,17 +125,39 @@ VipsForeignDT2Vips vips_foreign_DT2Vips[] = {
|
||||
{ DT_RGBA32, VIPS_FORMAT_UCHAR }
|
||||
};
|
||||
|
||||
/* Slow and horrid version if there's no recent glib.
|
||||
*/
|
||||
#ifndef HAVE_CHECKED_MUL
|
||||
#define g_uint_checked_mul( dest, a, b ) ( \
|
||||
((guint64) a * b) > UINT_MAX ? \
|
||||
(*dest = UINT_MAX, FALSE) : \
|
||||
(*dest = a * b, TRUE) \
|
||||
)
|
||||
#endif /*HAVE_CHECKED_MUL*/
|
||||
VipsBandFormat
|
||||
vips__foreign_nifti_datatype2BandFmt( int datatype )
|
||||
{
|
||||
int i;
|
||||
|
||||
VipsForeignNiftiFields vips_foreign_nifti_fields[] = {
|
||||
for( i = 0; i < VIPS_NUMBER( vips_foreign_nifti_DT2Vips ); i++ )
|
||||
if( vips_foreign_nifti_DT2Vips[i].datatype == datatype )
|
||||
return( vips_foreign_nifti_DT2Vips[i].fmt );
|
||||
|
||||
return( VIPS_FORMAT_NOTSET );
|
||||
}
|
||||
|
||||
int
|
||||
vips__foreign_nifti_BandFmt2datatype( VipsBandFormat fmt )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < VIPS_NUMBER( vips_foreign_nifti_DT2Vips ); i++ )
|
||||
if( vips_foreign_nifti_DT2Vips[i].fmt == fmt )
|
||||
return( vips_foreign_nifti_DT2Vips[i].datatype );
|
||||
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* All the header fields we attach as metadata.
|
||||
*/
|
||||
typedef struct _VipsForeignNiftiFields {
|
||||
char *name;
|
||||
GType type;
|
||||
glong offset;
|
||||
} VipsForeignNiftiFields;
|
||||
|
||||
static VipsForeignNiftiFields vips_foreign_nifti_fields[] = {
|
||||
/* The first 8 must be the dims[] fields, see
|
||||
* vips_foreign_save_nifti_make_nim().
|
||||
*/
|
||||
@ -251,8 +280,29 @@ VipsForeignNiftiFields vips_foreign_nifti_fields[] = {
|
||||
G_STRUCT_OFFSET( nifti_image, intent_p3 ) },
|
||||
};
|
||||
|
||||
void *
|
||||
vips__foreign_nifti_map( VipsNiftiMapFn fn, void *a, void *b )
|
||||
{
|
||||
int i;
|
||||
void *result;
|
||||
|
||||
for( i = 0; i < VIPS_NUMBER( vips_foreign_nifti_fields ); i++ ) {
|
||||
GValue value = { 0 };
|
||||
|
||||
g_value_init( &value, vips_foreign_nifti_fields[i].type );
|
||||
result = fn( vips_foreign_nifti_fields[i].name, &value,
|
||||
vips_foreign_nifti_fields[i].offset, a, b );
|
||||
g_value_unset( &value );
|
||||
|
||||
if( result )
|
||||
return( result );
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* How I wish glib had something like this :( Just implement the ones we need
|
||||
* for Field above.
|
||||
* for vips_foreign_nifti_fields above.
|
||||
*/
|
||||
static void
|
||||
vips_gvalue_read( GValue *value, void *p )
|
||||
@ -272,6 +322,32 @@ vips_gvalue_read( GValue *value, void *p )
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
vips_foreign_load_nifti_set( const char *name, GValue *value, glong offset,
|
||||
void *a, void *b )
|
||||
{
|
||||
nifti_image *nim = (nifti_image *) a;
|
||||
VipsImage *out = VIPS_IMAGE( b );
|
||||
|
||||
char vips_name[256];
|
||||
|
||||
vips_gvalue_read( value, (gpointer) nim + offset );
|
||||
vips_snprintf( vips_name, 256, "nifti-%s", name );
|
||||
vips_image_set( out, vips_name, value );
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Slow and horrid version if there's no recent glib.
|
||||
*/
|
||||
#ifndef HAVE_CHECKED_MUL
|
||||
#define g_uint_checked_mul( dest, a, b ) ( \
|
||||
((guint64) a * b) > UINT_MAX ? \
|
||||
(*dest = UINT_MAX, FALSE) : \
|
||||
(*dest = a * b, TRUE) \
|
||||
)
|
||||
#endif /*HAVE_CHECKED_MUL*/
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
nifti_image *nim, VipsImage *out )
|
||||
@ -330,15 +406,7 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Decode voxel format.
|
||||
*/
|
||||
fmt = VIPS_FORMAT_UCHAR;
|
||||
for( i = 0; i < VIPS_NUMBER( vips_DT2Vips ); i++ )
|
||||
if( nim->datatype == vips_DT2Vips[i].datatype ) {
|
||||
fmt = vips_DT2Vips[i].fmt;
|
||||
break;
|
||||
}
|
||||
if( i == VIPS_NUMBER( vips_DT2Vips ) ) {
|
||||
if( !(fmt = vips__foreign_nifti_BandFmt2datatype( nim->datatype )) ) {
|
||||
vips_error( class->nickname,
|
||||
_( "datatype %d not supported" ), nim->datatype );
|
||||
return( -1 );
|
||||
@ -389,17 +457,9 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
VIPS_INTERPRETATION_B_W : VIPS_INTERPRETATION_sRGB,
|
||||
xres, yres );
|
||||
|
||||
for( i = 0; i < VIPS_NUMBER( vips_foreign_nifti_fields ); i++ ) {
|
||||
GValue value = { 0 };
|
||||
|
||||
g_value_init( &value, vips_foreign_nifti_fields[i].type );
|
||||
vips_gvalue_read( &value,
|
||||
(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 );
|
||||
}
|
||||
/* Set some vips metadata for every nifti header field.
|
||||
*/
|
||||
vips__foreign_nifti_map( vips_foreign_load_nifti_set, nim, out );
|
||||
|
||||
/* One byte longer than the spec to leave space for any extra
|
||||
* '\0' termination.
|
||||
|
@ -78,8 +78,19 @@ vips_foreign_save_nifti_dispose( GObject *gobject )
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
/* Make ->nim from the vips header fields.
|
||||
*/
|
||||
static int
|
||||
vips_foreign_save_nifti_make_nim( VipsForeignSaveNifti *nifti,
|
||||
vips_foreign_save_nifti_header_vips( VipsForeignSaveNifti *nifti,
|
||||
VipsImage *image )
|
||||
{
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Make ->nim from the nifti- fields.
|
||||
*/
|
||||
static int
|
||||
vips_foreign_save_nifti_header_nifti( VipsForeignSaveNifti *nifti,
|
||||
VipsImage *image )
|
||||
{
|
||||
int dims[8];
|
||||
@ -135,17 +146,24 @@ vips_foreign_save_nifti_build( VipsObject *object )
|
||||
VipsImage **t = (VipsImage **)
|
||||
vips_object_local_array( VIPS_OBJECT( nifti ), 2 );
|
||||
|
||||
struct nifti_1_header nhdr;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_save_nifti_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_foreign_save_nifti_make_header( nifti, save->ready, &nhdr ) )
|
||||
return( -1 );
|
||||
|
||||
if( !(nifti->nim = nifti_convert_nhdr2nim( nhdr, nifti->filename )) )
|
||||
return( -1 );
|
||||
/* This could be an image (indirectly) from niftiload, or something
|
||||
* like OME_TIFF, which does not have all the "nifti-ndim" fields.
|
||||
*
|
||||
* If it doesn't look like a nifti, try to make a nifti header from
|
||||
* what we have.
|
||||
*/
|
||||
if( vips_image_get_typeof( save->ready, "nifti-ndim" ) ) {
|
||||
if( vips_foreign_save_nifti_header_nifti( nifti, save->ready ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( vips_foreign_save_nifti_header_vips( nifti, save->ready ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* set ext, plus other stuff
|
||||
*/
|
||||
|
@ -256,24 +256,12 @@ 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
|
||||
VipsBandFormat vips__foreign_nifti_datatype2BandFmt( int datatype );
|
||||
int vips__foreign_nifti_BandFmt2datatype( VipsBandFormat fmt );
|
||||
|
||||
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[];
|
||||
typedef void *(*VipsNiftiMapFn)( const char *name, GValue *value, glong offset,
|
||||
void *a, void *b );
|
||||
void *vips__foreign_nifti_map( VipsNiftiMapFn fn, void *a, void *b );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user