works!
just needs some tests could be faster too
This commit is contained in:
parent
9179156132
commit
d03416d386
@ -31,6 +31,7 @@
|
||||
- add Mitchell kernel
|
||||
- pyramid builders have a choice of 2x2 shrinkers [harukizaemon]
|
||||
- add `palette` option to pngsave [felixbuenemann]
|
||||
- add basic nifti load/save support
|
||||
|
||||
12/3/18 started 8.6.4
|
||||
- better fitting of fonts with overhanging edges [Adrià]
|
||||
|
@ -103,6 +103,43 @@ vips_foreign_load_nifti_dispose( GObject *gobject )
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_nifti_is_a( const char *filename )
|
||||
{
|
||||
char *hfile;
|
||||
znzFile fp;
|
||||
nifti_1_header nhdr;
|
||||
|
||||
/* Unfortunately is_nifti_file() is very slow and produces lots of
|
||||
* output. We have to make our own.
|
||||
*/
|
||||
|
||||
if( !(hfile = nifti_findhdrname( filename )) )
|
||||
return( 0 );
|
||||
|
||||
fp = znzopen( hfile, "rb", nifti_is_gzfile( hfile ));
|
||||
if( znz_isnull( fp ) ) {
|
||||
free( hfile );
|
||||
return( 0 );
|
||||
}
|
||||
free( hfile );
|
||||
|
||||
(void) znzread( &nhdr, 1, sizeof( nhdr ), fp );
|
||||
|
||||
znzclose( fp );
|
||||
|
||||
/* Test for sanity both ways around. There's a thing to test for byte
|
||||
* order in niftilib, but it's static :(
|
||||
*/
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
swap_nifti_header( &nhdr, FALSE );
|
||||
if( nifti_hdr_looks_good( &nhdr ) )
|
||||
return( 1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Map DT_* datatype values to VipsBandFormat.
|
||||
*/
|
||||
typedef struct _VipsForeignDT2Vips {
|
||||
@ -360,7 +397,7 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
nim->ndim );
|
||||
return( 0 );
|
||||
}
|
||||
for( i = 1; i < 8; i++ ) {
|
||||
for( i = 1; i < 8 && i < nim->ndim + 1; i++ ) {
|
||||
if( nim->dim[i] <= 0 ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "invalid dimension" ) );
|
||||
@ -368,7 +405,7 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
}
|
||||
|
||||
/* If we have several images in a dimension, the spacing must
|
||||
* be non-zero, or we'll get a /0 error in resolution
|
||||
* be non-zero or we'll get a /0 error in resolution
|
||||
* calculation.
|
||||
*/
|
||||
if( nim->dim[i] > 1 &&
|
||||
@ -385,7 +422,7 @@ vips_foreign_load_nifti_set_header( VipsForeignLoadNifti *nifti,
|
||||
bands = 1;
|
||||
width = (guint) nim->nx;
|
||||
height = (guint) nim->ny;
|
||||
for( i = 3; i < 8; i++ )
|
||||
for( i = 3; i < 8 && i < nim->ndim + 1; i++ )
|
||||
if( !g_uint_checked_mul( &height, height, nim->dim[i] ) ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "dimension overflow" ) );
|
||||
@ -568,7 +605,7 @@ vips_foreign_load_nifti_class_init( VipsForeignLoadNiftiClass *class )
|
||||
|
||||
foreign_class->suffs = vips__nifti_suffs;
|
||||
|
||||
load_class->is_a = is_nifti_file;
|
||||
load_class->is_a = vips_foreign_load_nifti_is_a;
|
||||
load_class->header = vips_foreign_load_nifti_header;
|
||||
load_class->load = vips_foreign_load_nifti_load;
|
||||
|
||||
|
@ -86,7 +86,73 @@ static int
|
||||
vips_foreign_save_nifti_header_vips( VipsForeignSaveNifti *nifti,
|
||||
VipsImage *image )
|
||||
{
|
||||
g_assert( FALSE );
|
||||
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( nifti );
|
||||
|
||||
int dims[8];
|
||||
int datatype;
|
||||
int i;
|
||||
|
||||
/* Most nifti images have this defaulted as 1.
|
||||
*/
|
||||
for( i = 0; i < VIPS_NUMBER( dims ); i++ )
|
||||
dims[i] = 1;
|
||||
|
||||
dims[0] = 2;
|
||||
dims[1] = image->Xsize;
|
||||
dims[2] = image->Ysize;
|
||||
|
||||
if( vips_image_get_typeof( image, VIPS_META_PAGE_HEIGHT ) ) {
|
||||
int page_height;
|
||||
|
||||
if( vips_image_get_int( image,
|
||||
VIPS_META_PAGE_HEIGHT, &page_height ) )
|
||||
return( -1 );
|
||||
|
||||
if( image->Ysize % page_height == 0 ) {
|
||||
dims[0] = 3;
|
||||
dims[2] = page_height;
|
||||
dims[3] = image->Ysize / page_height;
|
||||
}
|
||||
}
|
||||
|
||||
datatype = vips__foreign_nifti_BandFmt2datatype( image->BandFmt );
|
||||
if( datatype == -1 ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "unsupported libvips image type" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( image->Bands > 1 ) {
|
||||
if( image->BandFmt != VIPS_FORMAT_UCHAR ) {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "8-bit colour images only" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( image->Bands == 3 )
|
||||
datatype = DT_RGB;
|
||||
else if( image->Bands == 4 )
|
||||
datatype = DT_RGBA32;
|
||||
else {
|
||||
vips_error( class->nickname,
|
||||
"%s", _( "3 or 4 band colour images only" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( !(nifti->nim = nifti_make_new_nim( dims, datatype, FALSE )) )
|
||||
return( -1 );
|
||||
|
||||
nifti->nim->dx = 1.0 / image->Xres;
|
||||
nifti->nim->dy = 1.0 / image->Yres;
|
||||
nifti->nim->dz = 1.0 / image->Yres;
|
||||
nifti->nim->xyz_units = NIFTI_UNITS_MM;
|
||||
|
||||
vips_snprintf( nifti->nim->descrip, sizeof( nifti->nim->descrip ),
|
||||
"libvips-%s", VIPS_VERSION );
|
||||
|
||||
/* All other fields can stay at their default value.
|
||||
*/
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -183,6 +249,11 @@ vips_foreign_save_nifti_header_nifti( VipsForeignSaveNifti *nifti,
|
||||
guint height;
|
||||
int i;
|
||||
|
||||
/* Most nifti images have this defaulted as 1.
|
||||
*/
|
||||
for( i = 0; i < VIPS_NUMBER( dims ); i++ )
|
||||
dims[i] = 1;
|
||||
|
||||
info.image = image;
|
||||
info.dims = dims;
|
||||
info.n = 0;
|
||||
@ -190,8 +261,22 @@ vips_foreign_save_nifti_header_nifti( VipsForeignSaveNifti *nifti,
|
||||
vips_foreign_save_nifti_set_dims, &info, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
/* FIXME what about page-height? should check that too.
|
||||
/* page-height overrides ny if it makes sense. This might not be
|
||||
* correct :(
|
||||
*/
|
||||
if( vips_image_get_typeof( image, VIPS_META_PAGE_HEIGHT ) ) {
|
||||
int page_height;
|
||||
|
||||
if( vips_image_get_int( image,
|
||||
VIPS_META_PAGE_HEIGHT, &page_height ) )
|
||||
return( -1 );
|
||||
|
||||
if( image->Ysize % page_height == 0 ) {
|
||||
dims[0] = 3;
|
||||
dims[2] = page_height;
|
||||
dims[3] = image->Ysize / page_height;
|
||||
}
|
||||
}
|
||||
|
||||
height = 1;
|
||||
for( i = 2; i < VIPS_NUMBER( dims ) && i < dims[0] + 1; i++ )
|
||||
|
Loading…
Reference in New Issue
Block a user