1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #include "mrilib.h"
8 #include <math.h>
9 #include <stdlib.h>
10 
11 #if 1
12 #  ifdef isfinite
13 #    define IS_GOOD_FLOAT(x) isfinite(x) /* 28 Aug 2003: use C99 macro if exists */
14 #  else
15 #    define IS_GOOD_FLOAT(x) finite(x)
16 #    define isfinite finite
17 #  endif
18 #else
19 #    define IS_GOOD_FLOAT(x) finite(x)
20 #endif
21 
22 #if 0
23 # define IS_GOOD_FLOAT(x) isnan(x)  /* obsolete */
24 #endif
25 
26 /*---------------------------------------------------------------------
27    Scan an array of floats for illegal values, replacing them with 0.
28    Return the number of illegal values found.
29 -----------------------------------------------------------------------*/
30 
thd_floatscan(size_t nbuf,float * fbuf)31 size_t thd_floatscan( size_t nbuf , float *fbuf )
32 {
33    size_t ii , nerr ;
34 
35    if( nbuf <= 0 || fbuf == NULL ) return 0 ;
36 
37    for( nerr=ii=0 ; ii < nbuf ; ii++ )
38      if( !IS_GOOD_FLOAT(fbuf[ii]) ){ fbuf[ii] = 0.0f ; nerr++ ; }
39 
40    return nerr ;
41 }
42 
43 /*--------------------------------------------------------------------*/
44 
45 #if 0
46 typedef struct complex { float r , i ; } complex ;  /* cf. mrilib.h */
47 #endif
48 
thd_complexscan(size_t nbuf,complex * cbuf)49 size_t thd_complexscan( size_t nbuf , complex *cbuf )
50 {
51    size_t ii , nerr ;
52 
53    if( nbuf <= 0 || cbuf == NULL ) return 0 ;
54 
55    for( nerr=ii=0 ; ii < nbuf ; ii++ ){
56      if( !IS_GOOD_FLOAT(cbuf[ii].r) ){ cbuf[ii].r = 0.0f ; nerr++ ; }
57      if( !IS_GOOD_FLOAT(cbuf[ii].i) ){ cbuf[ii].i = 0.0f ; nerr++ ; }
58    }
59 
60    return nerr ;
61 }
62 
63 /*--------------------------------------------------------------------*/
64 /* Functions below added 22 Feb 2007 -- RWCox */
65 
mri_floatscan(MRI_IMAGE * im)66 size_t mri_floatscan( MRI_IMAGE *im )
67 {
68    if( im == NULL ) return 0 ;
69    switch( im->kind ){
70      default: break ;
71      case MRI_float:
72        return thd_floatscan  ( im->nvox , MRI_FLOAT_PTR(im)   ) ;
73      case MRI_complex:
74        return thd_complexscan( im->nvox , MRI_COMPLEX_PTR(im) ) ;
75    }
76    return 0 ;
77 }
78 
79 /*--------------------------------------------------------------------*/
80 
imarr_floatscan(MRI_IMARR * imar)81 size_t imarr_floatscan( MRI_IMARR *imar )
82 {
83    size_t ii , nn ;
84    if( imar == NULL ) return 0 ;
85    for( nn=ii=0 ; ii < IMARR_COUNT(imar) ; ii++ ){
86      nn += mri_floatscan( IMARR_SUBIM(imar,ii) ) ;
87    }
88    return nn ;
89 }
90 
91 /*--------------------------------------------------------------------*/
92 
dblk_floatscan(THD_datablock * dblk)93 size_t dblk_floatscan( THD_datablock *dblk )
94 {
95    size_t nn ;
96    if( !ISVALID_DATABLOCK(dblk) ) return 0 ;
97    nn = imarr_floatscan( dblk->brick ) ;
98    return nn ;
99 }
100 
101 /*--------------------------------------------------------------------*/
102 
dset_floatscan(THD_3dim_dataset * dset)103 size_t dset_floatscan( THD_3dim_dataset *dset )
104 {
105    size_t nn ;
106    if( !ISVALID_DSET(dset) ) return 0 ;
107    nn = dblk_floatscan( dset->dblk ) ;
108    return nn ;
109 }
110