/* convert by hand, since no scaling will be done * (byte seems inappropriate and float does not need it) */ int write_result(param_t * params, THD_3dim_dataset * oset, int argc, char * argv[]) { short * sptr; int nvox = DSET_NVOX(oset), ind; ENTRY("write_results"); EDIT_dset_items(oset, ADN_prefix, params->prefix, ADN_none); if( params->verb ) INFO_message("writing result %s...\n", DSET_PREFIX(oset)); switch( params->datum ) { default: ERROR_exit("invalid datum for result: %d", params->datum); case MRI_short: break; /* nothing to do */ case MRI_float: { float * data = (float *)malloc(nvox*sizeof(float)); sptr = DBLK_ARRAY(oset->dblk, 0); if( ! data ) ERROR_exit("failed to alloc %d output floats\n", nvox); for( ind = 0; ind < nvox; ind++ ) data[ind] = (float)sptr[ind]; EDIT_substitute_brick(oset, 0, params->datum, data); } break; case MRI_byte: { byte * data = (byte *)malloc(nvox*sizeof(byte)); int errs = 0; sptr = DBLK_ARRAY(oset->dblk, 0); if( ! data ) ERROR_exit("failed to alloc %d output bytes\n", nvox); for( ind = 0; ind < nvox; ind++ ) { if( sptr[ind] > 255 ) { /* watch for overflow */ data[ind] = (byte)255; errs++; } else data[ind] = (byte)sptr[ind]; } EDIT_substitute_brick(oset, 0, params->datum, data); if(errs) WARNING_message("convert to byte: %d truncated voxels",errs); } break; } tross_Make_History( "3dmask_tool", argc, argv, oset ); DSET_write(oset); WROTE_DSET(oset); RETURN(0); }
/* * A hole is defined as a connected set of zero voxels that does * not reach an edge. * * The core functionality was added to libmri.a in THD_mask_fill_holes. */ int fill_holes(THD_3dim_dataset * dset, int verb) { short * sptr; /* to for filling holes */ byte * bmask; /* computed result */ int nfilled; int nx, ny, nz, nvox, index, fill=0; ENTRY("fill_holes"); bmask = THD_makemask(dset, 0, 1, 0); /* copy input as byte mask */ nx = DSET_NX(dset); ny = DSET_NY(dset); nz = DSET_NZ(dset); nvox = DSET_NVOX(dset); /* created filled mask */ nfilled = THD_mask_fill_holes(nx,ny,nz, bmask, verb); if( nfilled < 0 ) { ERROR_message("failed to fill holes"); RETURN(1); } /* apply to short volume */ sptr = DBLK_ARRAY(dset->dblk, 0); for( index = 0; index < nvox; index++ ) if( !sptr[index] && bmask[index] ) { fill++; sptr[index] = 1; } if(verb>2) INFO_message("final check: fill=%d, nfilled=%d", fill, nfilled); RETURN(0); }
double ENTROPY_datablock( THD_datablock *blk ) { int iv ; double sum ; ENTRY("ENTROPY_datablock") ; ENTROPY_setup() ; for( iv=0 ; iv < blk->nvals ; iv++ ) ENTROPY_accumulate( DBLK_BRICK_BYTES(blk,iv) , DBLK_ARRAY(blk,iv) ) ; sum = ENTROPY_compute() ; ENTROPY_setdown() ; RETURN(sum) ; }
/* * check count against limit * - clear small values * - if not count, set large values to 1 */ int limit_to_frac(THD_3dim_dataset * cset, int limit, int count, int verb) { short * dptr; int index, nsub, nsuper; ENTRY("limit_to_frac"); if( ! ISVALID_3DIM_DATASET(cset) ) { ERROR_message("invalid count dataset"); RETURN(1); } else if( DSET_BRICK_TYPE(cset, 0) != MRI_short ) { ERROR_message("count dataset not of type short"); RETURN(1); } if(verb > 1) INFO_message("limiting to %d (count = %d)\n",limit,count); /* note how many voxels are affected, just for kicks */ dptr = DBLK_ARRAY(cset->dblk, 0); nsub = nsuper = 0; for(index = 0; index < DSET_NVOX(cset); index++, dptr++) { if( ! *dptr ) continue; /* 0, so skip */ else if( *dptr < limit ) { /* small, so clear */ *dptr = 0; nsub++; } else { /* big enough */ if ( ! count ) *dptr = 1; nsuper++; } } /* entertain the user */ if( verb ) INFO_message("voxel limits: %d clipped, %d survived, %d were zero\n", nsub, nsuper, DSET_NVOX(cset)-nsub-nsuper); RETURN(0); }
/* * create empty count dataset * for each input dataset and each sub-volume * for each voxel, if set: increment * close datasets as they are processed */ int count_masks(THD_3dim_dataset * dsets[], int ndsets, int verb, /* inputs */ THD_3dim_dataset ** cset, int * nvol) /* outputs */ { THD_3dim_dataset * dset; short * counts = NULL; /* will become data for returned cset */ byte * bptr; /* always points to mask volumes */ int nxyz, iset, ivol, ixyz; ENTRY("count_masks"); if( !dsets || !cset || !nvol ) ERROR_exit("NULL inputs to count_masks"); if( ndsets <= 0 ) { ERROR_message("count_masks: no input datasets"); RETURN(1); } *nvol = 0; nxyz = DSET_NVOX(dsets[0]); /* allocate memory for the counts */ counts = (short *)calloc(nxyz, sizeof(short)); if( !counts ) ERROR_exit("failed to malloc %d shorts", nxyz); /* for each volume of each dataset, count set voxels */ for( iset=0; iset < ndsets; iset++ ) { dset = dsets[iset]; *nvol += DSET_NVALS(dset); /* accumulate num volumes */ /* for each volume in this dataset, count set voxels */ for( ivol=0; ivol < DSET_NVALS(dset); ivol++ ) { if( DSET_BRICK_TYPE(dset, ivol) != MRI_byte ) ERROR_exit("in count_masks with non-byte data (set %d, vol %d)", iset, ivol); bptr = DBLK_ARRAY(dset->dblk, ivol); for( ixyz = 0; ixyz < nxyz; ixyz++ ) if( bptr[ixyz] ) counts[ixyz]++; } if( iset > 0 ) DSET_delete(dset); /* close the first one at end */ } /* dataset */ if( verb > 1 ) { int maxval; for( maxval=counts[0], ixyz=1; ixyz < nxyz; ixyz++ ) if( counts[ixyz] > maxval ) maxval = counts[ixyz]; INFO_message("counted %d mask volumes in %d datasets (%d voxels)\n", *nvol, ndsets, nxyz); INFO_message(" (maximum overlap = %d)\n", maxval); } if( *nvol >= (1<<15) ) WARNING_message("too many volumes to count as shorts: %d", *nvol); /* create output dataset */ *cset = EDIT_empty_copy(dsets[0]); EDIT_dset_items(*cset, ADN_nvals, 1, ADN_ntt, 0, ADN_none); EDIT_substitute_brick(*cset, 0, MRI_short, counts); DSET_delete(dsets[0]); /* now finished with first dataset */ RETURN(0); }
/* * 1. zeropad (if needed for dilations) * 2. make byte copy of dataset (if not already) * 3. dilate (using binary mask) * 4. if not converting, modify original data * 5. undo any zeropad * 6. return new dataset (might be same as old) * * dilations are passed as a list of +/- integers (- means erode) * * convert: flag specifying whether dset should be converted to MRI_byte * * note: the dilations list should not be long (does more than 2 even * make any sense?), but here they will be treated generically * - foreach dilation: dilate or erode, as specified by sign */ THD_3dim_dataset * apply_dilations(THD_3dim_dataset * dset, int_list * D, int convert, int verb) { THD_3dim_dataset * dnew = NULL; byte * bdata = NULL; int index, ivol, id, dsize, datum, pad; int nx, ny, nz, nvox; ENTRY("apply_dilations"); if( !dset || !D ) ERROR_exit("missing inputs to apply_dilations"); /* note and apply any needed zeropadding */ pad = needed_padding(D); if(verb > 3 && pad) INFO_message("padding by %d (for dilations)", pad); if( pad ) dnew = THD_zeropad(dset, pad, pad, pad, pad, pad, pad, "pad", 0); else dnew = dset; /* note geometry */ nx = DSET_NX(dnew); ny = DSET_NY(dnew); nz = DSET_NZ(dnew); nvox = nx*ny*nz; /* now apply the actual dilations */ if(verb>1) INFO_message("applying dilation list to dataset"); for( ivol=0; ivol < DSET_NVALS(dnew); ivol++ ) { datum = DSET_BRICK_TYPE(dnew, ivol); /* if non-byte data (short/float), make byte mask of volume */ if( datum == MRI_byte ) bdata = DBLK_ARRAY(dnew->dblk, ivol); else if ( datum == MRI_float || datum == MRI_short ) bdata = THD_makemask(dnew, ivol, 1, 0); else { ERROR_message("invalid datum for result: %d", datum); RETURN(NULL); } if( !bdata ) { ERROR_message("failed to make as mask"); RETURN(NULL); } for( index=0; index < D->num; index++ ) { dsize = D->list[index]; if(verb>2) INFO_message("... dilating vol %d by %d\n", ivol, dsize); if( dsize > 0 ) { for( id=0; id < dsize; id++ ) THD_mask_dilate(nx, ny, nz, bdata, 1); } else if( dsize < 0 ) { for( id=0; id > dsize; id-- ) THD_mask_erode_sym(nx, ny, nz, bdata, 1); } } /* if we are converting, just replace the old data */ if( convert && (datum == MRI_short || datum == MRI_float) ) { if( verb > 2 ) INFO_message("applying byte result from dilate"); EDIT_substitute_brick(dnew, ivol, MRI_byte, bdata); /* explicit set needed on an Fedora 8 system? 5 Jun 2012 */ DSET_BRICK_TYPE(dnew, ivol) = MRI_byte; continue; /* so nothing more to do */ } /* if short or float data, apply mask changes to data */ if( datum == MRI_short ) { short * dptr = DBLK_ARRAY(dnew->dblk, ivol); int nfill=0; if( verb > 2 ) INFO_message("applying dilate result to short data"); for( index = 0; index < nvox; index++ ) if( ! dptr[index] && bdata[index] ){ dptr[index] = 1; nfill++; } if( verb > 1 ) INFO_message("AD: filled %d voxels", nfill); free(bdata); } else if( datum == MRI_float ) { float * dptr = DBLK_ARRAY(dnew->dblk, ivol); if( verb > 2 ) INFO_message("applying dilate result to float data"); for( index = 0; index < nvox; index++ ) if( ! dptr[index] && bdata[index] ) dptr[index] = 1.0; free(bdata); } } /* undo any zeropadding (delete original and temporary datasets) */ if( pad ) { DSET_delete(dset); dset = THD_zeropad(dnew, -pad, -pad, -pad, -pad, -pad, -pad, "pad", 0); DSET_delete(dnew); dnew = dset; } RETURN(dnew); }
Boolean THD_write_datablock( THD_datablock *blk , Boolean write_brick ) { THD_diskptr *dkptr ; Boolean good ; int id , nx , ny , nz , nv , nxy , nxyz , ibr ; int atrank[ATRSIZE_DATASET_RANK] , atdims[ATRSIZE_DATASET_DIMENSIONS] ; MRI_IMAGE *im ; int save_order ; int64_t nb , idone ; int do_mripurge ; /*-- sanity checks --*/ if( ! ISVALID_DATABLOCK(blk) ) return False ; if( DBLK_IS_MASTERED(blk) ) return False ; /* 11 Jan 1999 */ if( DBLK_IS_MINC(blk) ) WRITE_ERR("MINC with bad name extension?") ; /* 29 Oct 2001 */ if( DBLK_IS_ANALYZE(blk) ) WRITE_ERR("ANALYZE but bad name extension?") ; /* 27 Aug 2002 */ if( DBLK_IS_NIFTI(blk) ) WRITE_ERR("NIFTI but bad name extension?") ; /* 28 Aug 2003 */ dkptr = blk->diskptr ; if( ! ISVALID_DISKPTR(dkptr) ) WRITE_ERR("illegal file type") ; if( strlen(dkptr->directory_name) == 0 || strlen(dkptr->header_name) == 0 || strlen(dkptr->filecode) == 0 ) WRITE_ERR("illegal file names stored in dataset") ; if( dkptr->rank != 3 ) WRITE_ERR("cannot write non-3D datablock") ; /*-- create directory if necessary --*/ if( ! THD_is_directory(dkptr->directory_name) ){ id = mkdir( dkptr->directory_name , THD_MKDIR_MODE ) ; if( id != 0 ){ fprintf(stderr, "\n" "*** cannot mkdir new directory: %s\n" " - Do you have permission to write to this disk?\n" " - Is the disk full?\n" , dkptr->directory_name) ; return False ; } } /* 25 April 1998: deal with byte order issues */ if( native_order < 0 ){ /* initialization */ native_order = mri_short_order() ; if( output_order < 0 ) THD_enviro_write_order() ; } if( dkptr->byte_order <= 0 ) dkptr->byte_order = native_order ; save_order = (output_order > 0) ? output_order : dkptr->byte_order ; #if 0 fprintf(stderr,"THD_write_datablock: save_order=%d dkptr->byte_order=%d\n", save_order, dkptr->byte_order ) ; #endif if( save_order != LSB_FIRST && save_order != MSB_FIRST ) save_order = native_order ; if( save_order == LSB_FIRST ) THD_set_string_atr( blk , ATRNAME_BYTEORDER , LSB_FIRST_STRING ) ; else if( save_order == MSB_FIRST ) THD_set_string_atr( blk , ATRNAME_BYTEORDER , MSB_FIRST_STRING ) ; /*-- actually write attributes to disk --*/ good = THD_write_atr( blk ) ; if( good == False ) WRITE_ERR( "failure to write attributes - is disk full? do you have write permission?"); /*-- if not writing data, can exit --*/ if( write_brick == False || blk->brick == NULL || dkptr->storage_mode == STORAGE_UNDEFINED ) return True ; if( dkptr->storage_mode == STORAGE_BY_VOLUMES ){ /* 20 Jun 2002 */ fprintf(stderr,"** Writing dataset by VOLUMES not yet supported.\n") ; return False ; } /*-- check each brick for existence: if none exist, cannot write, but is OK if some but not all exist, cannot write, and is an error --*/ id = THD_count_potential_databricks( blk ) ; if( id <= 0 ) return True ; if( id < blk->nvals ){ ERROR_message("Write dataset error: only %d out of %d bricks in memory", id,blk->nvals) ; return False ; } if( blk->malloc_type == DATABLOCK_MEM_UNDEFINED ) WRITE_ERR("undefined data exists in memory") ; /*-- 13 Mar 2006: check for free disk space --*/ { int mm = THD_freemegabytes( dkptr->header_name ) ; int rr = blk->total_bytes / (1024l * 1024l) ; if( mm >= 0 && mm <= rr ) WARNING_message("Disk space: writing file %s (%d MB)," " but only %d free MB on disk" , dkptr->brick_name , rr , mm ) ; } /*-- write data out in whatever format is ordered --*/ nx = dkptr->dimsizes[0] ; ny = dkptr->dimsizes[1] ; nxy = nx * ny ; nz = dkptr->dimsizes[2] ; nxyz = nxy * nz ; nv = dkptr->nvals ; nb = blk->total_bytes ; switch( dkptr->storage_mode ){ default: WRITE_ERR("illegal storage_mode!") ; break ; case STORAGE_BY_BRICK:{ FILE *far ; Boolean purge_when_done = False , ok ; int force_gzip=0 , csave=COMPRESS_NONE ; /** if we have a mmap-ed file, copy into RAM (ugh) **/ if( blk->malloc_type == DATABLOCK_MEM_MMAP ){ char *bnew , *bold ; int offset ; bnew = (char *) malloc( (size_t)nb ) ; /* work space */ bold = DBLK_ARRAY(blk,0) ; /* start of mapped file */ if( bnew == NULL ) WRITE_ERR("cannot rewrite due to malloc failure - is memory exhausted?") ; memcpy( bnew , bold , (size_t)nb ) ; /* make a copy, */ munmap( (void *) bold , (size_t)nb ) ; /* then unmap file */ /* fix sub-brick pointers */ offset = 0 ; for( ibr=0 ; ibr < nv ; ibr++ ){ mri_fix_data_pointer( (void *)(bnew+offset) , DBLK_BRICK(blk,ibr) ) ; offset += DBLK_BRICK_BYTES(blk,ibr) ; DBLK_BRICK(blk,ibr)->fondisk = 0 ; /* 31 Jan 2007 */ } purge_when_done = True ; } /** fall thru to here if have a malloc-ed dataset **/ if( save_order != native_order ) purge_when_done = True ; /** delete old file, if any **/ COMPRESS_unlink( dkptr->brick_name ) ; /* Feb 1998 */ /** create new file **/ id = strlen(dkptr->directory_name) ; ok = ( dkptr->directory_name[id-1] == '/' ) ; if( ok ) sprintf( dkptr->brick_name , "%s%s.%s", dkptr->directory_name , dkptr->filecode , DATASET_BRICK_SUFFIX ); else sprintf( dkptr->brick_name , "%s/%s.%s", dkptr->directory_name , dkptr->filecode , DATASET_BRICK_SUFFIX ); /** COMPRESS for output added Feb 1998 */ if( compress_mode == COMPRESS_NOFILE ) THD_enviro_write_compression() ; #ifdef COMPRESS_GZIP /*-- 02 Mar 2001: check if we will force gzip --*/ if( compress_mode == COMPRESS_NONE && AFNI_yesenv("AFNI_AUTOGZIP") ){ double entrop = ENTROPY_datablock(blk) ; force_gzip = (entrop < 2.7) ; #if 0 fprintf(stderr,"Entropy=%g ==> forcing write gzip on %s\n",entrop,dkptr->brick_name) ; #endif } else { force_gzip = 0 ; } if( force_gzip ){ csave = compress_mode ; compress_mode = COMPRESS_GZIP ; } #endif far = COMPRESS_fopen_write( dkptr->brick_name , compress_mode ) ; if( far == NULL ){ if( compress_mode != COMPRESS_NONE ){ compress_mode = COMPRESS_NONE ; force_gzip = 0 ; far = COMPRESS_fopen_write( dkptr->brick_name , compress_mode ) ; } } if( far == NULL ) WRITE_ERR("cannot open output brick file - do you have write permission?") ; /** write each brick out in a separate operation **/ idone = 0 ; for( ibr=0 ; ibr < nv ; ibr++ ){ do_mripurge = MRI_IS_PURGED( DBLK_BRICK(blk,ibr) ) ; if( do_mripurge ) mri_unpurge( DBLK_BRICK(blk,ibr) ) ; if( save_order != native_order ){ /* 25 April 1998 */ switch( DBLK_BRICK_TYPE(blk,ibr) ){ default: break ; case MRI_short: mri_swap2( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ; break ; case MRI_complex: /* 23 Nov 1999 */ mri_swap4( 2*DBLK_BRICK_NVOX(blk,ibr), DBLK_ARRAY(blk,ibr)) ; break ; case MRI_float: /* 23 Nov 1999 */ case MRI_int: mri_swap4( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ; break ; } } idone += fwrite( DBLK_ARRAY(blk,ibr), 1, DBLK_BRICK_BYTES(blk,ibr), far ); if( do_mripurge ){ /* 31 Jan 2007 */ if( !purge_when_done ) mri_purge( DBLK_BRICK(blk,ibr) ) ; else mri_clear( DBLK_BRICK(blk,ibr) ) ; } } /* end of loop over sub-bricks */ COMPRESS_fclose(far) ; if( purge_when_done ){ if( blk->malloc_type == DATABLOCK_MEM_MMAP ){ free( DBLK_ARRAY(blk,0) ) ; for( ibr=0 ; ibr < nv ; ibr++ ) mri_clear_data_pointer( DBLK_BRICK(blk,ibr) ) ; } else { THD_purge_datablock( blk , DATABLOCK_MEM_MALLOC ) ; } } if( compress_mode >= 0 || save_order != native_order ){ blk->malloc_type = DATABLOCK_MEM_MALLOC ; } DBLK_mmapfix(blk) ; /* 28 Mar 2005 */ if( force_gzip ) compress_mode = csave ; /* 02 Mar 2001 */ if( idone != blk->total_bytes ) WRITE_ERR("Write error in brick file: Is disk full, or write_protected?") ; dkptr->byte_order = save_order ; /* 23 Nov 1999 */ return True ; } break ; } /* end of switch over data storage mode */ return False ; /* should NEVER be reached */ }
void THD_load_nifti( THD_datablock *dblk ) { THD_diskptr *dkptr ; int nx,ny,nz,nxy,nxyz,nxyzv , nerr=0,ibr,nv, nslice ; int datum, need_copy=0 ; int scale_data=0 ; void *ptr ; nifti_image *nim ; nifti_brick_list NBL ; /* holds the data read from disk */ ENTRY("THD_load_nifti") ; /*-- open and read input [these errors should never occur] --*/ if( !ISVALID_DATABLOCK(dblk) || dblk->diskptr->storage_mode != STORAGE_BY_NIFTI || dblk->brick == NULL ) EXRETURN ; dkptr = dblk->diskptr ; /* purge any existing bricks [10 Mar 2014] */ STATUS("purging existing data bricks (if any)") ; THD_purge_datablock(dblk,DATABLOCK_MEM_ANY) ; STATUS("calling nifti_image_read_bricks") ; NBL.nbricks = 0 ; if( ! DBLK_IS_MASTERED(dblk) ) /* allow mastering 14 Apr 2006 [rickr] */ nim = nifti_image_read_bricks( dkptr->brick_name, 0,NULL , &NBL ) ; else { /* n2 10 Jul, 2015 [rickr] */ /* convert master_ival to an array of int64_t */ int64_t * i64_vals = copy_ints_as_i64(dblk->master_ival, dblk->nvals); nim = nifti_image_read_bricks( dkptr->brick_name, dblk->nvals, i64_vals, &NBL ) ; } if( nim == NULL || NBL.nbricks <= 0 ) EXRETURN ; datum = DBLK_BRICK_TYPE(dblk,0) ; /* destination data type */ /*-- determine if we need to copy the data from the bricks as loaded above because of a type conversion --*/ switch( nim->datatype ){ case DT_INT16: case DT_UINT8: need_copy = (datum == MRI_float) ; break ; case DT_FLOAT32: case DT_COMPLEX64: case DT_RGB24: need_copy = 0 ; break ; case DT_INT8: /* these are the cases where AFNI can't */ case DT_UINT16: /* directly handle the NIFTI datatype, */ case DT_INT32: /* so we'll convert them to floats. */ case DT_UINT32: case DT_FLOAT64: need_copy = 1 ; break ; #if 0 case DT_COMPLEX128: need_copy = 1 ; break ; #endif } /*-- various dimensions --*/ nx = dkptr->dimsizes[0] ; ny = dkptr->dimsizes[1] ; nxy = nx * ny ; nz = dkptr->dimsizes[2] ; nxyz = nxy * nz ; nv = dkptr->nvals ; if( nv > NBL.nbricks ) nv = NBL.nbricks ; nxyzv = nxyz * nv ; nslice = nz*nv ; dblk->malloc_type = DATABLOCK_MEM_MALLOC ; /*------ don't need to copy data ==> just copy pointers from NBL ------*/ if( !need_copy ){ STATUS("copying brick pointers directly") ; for( ibr=0 ; ibr < nv ; ibr++ ){ mri_fix_data_pointer( NBL.bricks[ibr] ,DBLK_BRICK(dblk,ibr) ) ; NBL.bricks[ibr] = NULL ; /* so it won't be deleted later */ if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_float ){ STATUS("doing floatscan") ; nerr += thd_floatscan( DBLK_BRICK_NVOX(dblk,ibr) , DBLK_ARRAY(dblk,ibr) ) ; } else if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_complex ){ STATUS("doing complexscan") ; nerr += thd_complexscan( DBLK_BRICK_NVOX(dblk,ibr) , DBLK_ARRAY(dblk,ibr) ) ; } } if( nerr > 0 ) WARNING_message("file %s: corrected %d float errors\n", dkptr->brick_name , nerr ) ; } else { /*---------- need to copy data ==> do some more work -----------*/ register int ii ; void *nbuf ; STATUS("converting input bricks to floats") ; for( ibr=0 ; ibr < nv ; ibr++ ){ if( DBLK_ARRAY(dblk,ibr) == NULL ){ /* make space */ ptr = AFMALL(void, DBLK_BRICK_BYTES(dblk,ibr) ) ; /* for this */ if( ptr == NULL ) ERROR_message("malloc fails for NIfTI sub-brick #%d",ibr) ; mri_fix_data_pointer( ptr , DBLK_BRICK(dblk,ibr) ) ; /* sub-brick! */ } ptr = DBLK_ARRAY(dblk,ibr) ; if( ptr == NULL ) break ; /* bad news!! */ nbuf = NBL.bricks[ibr] ; /* data as read from NIfTI file */ /* macro to convert data from type "ityp" in nbuf to float in dataset */ #undef CPF #define CPF(ityp) do{ ityp *sar = (ityp *)nbuf ; float *far = (float *)ptr ; \ for( ii=0 ; ii < nxyz ; ii++ ) far[ii] = (float)sar[ii]; \ } while(0) /* load from nbuf into brick array (will be float or complex) */ STATUS(" converting sub-brick") ; switch( nim->datatype ){ case DT_UINT8: CPF(unsigned char) ; break ; case DT_INT8: CPF(signed char) ; break ; case DT_INT16: CPF(signed short) ; break ; case DT_UINT16: CPF(unsigned short) ; break ; case DT_INT32: CPF(signed int) ; break ; case DT_UINT32: CPF(unsigned int) ; break ; case DT_FLOAT64: /* added floatscan 2 Dec, 2014 [rickr] */ { CPF(double) ; thd_floatscan(nxyz, (float *)ptr) ; break ; } #if 0 case DT_COMPLEX128: break ; #endif } STATUS(" free-ing NIfTI volume") ; free(NBL.bricks[ibr]) ; NBL.bricks[ibr] = NULL ; } }