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 
9 /*** 7D SAFE ***/
10 
mri_to_short(double scl,MRI_IMAGE * oldim)11 MRI_IMAGE *mri_to_short( double scl , MRI_IMAGE *oldim )
12 {
13    MRI_IMAGE *newim ;
14    register int ii , npix ;
15    register double scale , val ;
16    register short *sar ;
17 
18 ENTRY("mri_to_short") ;
19 
20    if( oldim == NULL ) RETURN( NULL );  /* 09 Feb 1999 */
21 
22    newim = mri_new_conforming( oldim , MRI_short ) ;
23    sar   = MRI_SHORT_PTR(newim) ;
24    npix  = oldim->nvox ;
25 
26    if( scl == 0.0 ){
27       switch( oldim->kind ){
28          case MRI_int:
29          case MRI_float:
30          case MRI_double:
31          case MRI_complex:
32             scale = mri_maxabs( oldim ) ;
33             if( scale != 0.0 ) scale = 10000.0 / scale ;
34 #ifdef MRI_DEBUG
35    fprintf( stderr , "mri_to_short: scale factor = %e\n" , scale ) ;
36 #endif
37          break ;
38 
39          default:
40             scale = 1.0 ;
41          break ;
42       }
43    } else {
44       scale = scl ;
45    }
46 
47    switch( oldim->kind ){
48 
49       case MRI_rgb:{
50          byte *rgb = MRI_RGB_PTR(oldim) ;
51          float rfac=0.299*scale , gfac=0.587*scale , bfac=0.114*scale ;
52 
53          for( ii=0 ; ii < npix ; ii++ )
54             sar[ii] = (short)(  rfac * rgb[3*ii]
55                               + gfac * rgb[3*ii+1]
56                               + bfac * rgb[3*ii+2] ) ;
57       }
58       break ;
59 
60       case MRI_byte:{
61          byte *qar = MRI_BYTE_PTR(oldim) ;
62          if( scale != 1.0 )
63             for( ii=0 ; ii < npix ; ii++ ){
64                val = scale * qar[ii] ;
65                sar[ii] = SHORTIZE(val) ;
66             }
67          else
68             for( ii=0 ; ii < npix ; ii++ )
69                sar[ii] = (short) qar[ii] ;
70          break ;
71       }
72 
73       case MRI_short:{
74          short *qar = MRI_SHORT_PTR(oldim) ;
75          if( scale != 1.0 )
76             for( ii=0 ; ii < npix ; ii++ ){
77                val = scale * qar[ii] ;
78                sar[ii] = SHORTIZE(val) ;
79             }
80          else
81             (void) memcpy( sar , qar , sizeof(short)*npix ) ;
82          break ;
83       }
84 
85       case MRI_int:{
86          int *qar = MRI_INT_PTR(oldim) ;
87          if( scale != 1.0 )
88             for( ii=0 ; ii < npix ; ii++ ){
89                val = scale * qar[ii] ;
90                sar[ii] = SHORTIZE(val) ;
91             }
92          else
93             for( ii=0 ; ii < npix ; ii++ )
94                sar[ii] = SHORTIZE(qar[ii]) ;
95          break ;
96       }
97 
98       case MRI_float:{
99          float *qar = MRI_FLOAT_PTR(oldim) ;
100          if( scale != 1.0 )
101             for( ii=0 ; ii < npix ; ii++ ){
102                val = scale * qar[ii] ;
103                sar[ii] = SHORTIZE(val) ;
104             }
105          else
106             for( ii=0 ; ii < npix ; ii++ )
107                sar[ii] = SHORTIZE(qar[ii]) ;
108          break ;
109       }
110 
111       case MRI_double:{
112          double *qar = MRI_DOUBLE_PTR(oldim) ;
113          for( ii=0 ; ii < npix ; ii++ )
114             sar[ii] = scale * qar[ii] ;
115          break ;
116       }
117 
118       case MRI_complex:{
119         complex *qar = MRI_COMPLEX_PTR(oldim) ;
120         for( ii=0 ; ii < npix ; ii++ )
121            sar[ii] = scale * CABS(qar[ii]) ;
122         break ;
123      }
124 
125       default:
126          fprintf( stderr , "mri_to_short:  unrecognized image kind\n" ) ;
127          MRI_FATAL_ERROR ;
128    }
129 
130    MRI_COPY_AUX(newim,oldim) ;
131    RETURN( newim );
132 }
133 
134 /*========================================================================*/
135 
mri_to_short_scl(double scl,double lev,MRI_IMAGE * oldim)136 MRI_IMAGE *mri_to_short_scl( double scl , double lev , MRI_IMAGE *oldim )
137 {
138    MRI_IMAGE * im ;
139    im =  mri_to_short_sclip( scl , lev , 0,0 , oldim ) ;
140    return im ;
141 }
142 
143 
144 /* scale, lev->0, and clip */
145 
mri_to_short_sclip(double scl,double lev,int bot,int top,MRI_IMAGE * oldim)146 MRI_IMAGE *mri_to_short_sclip( double scl , double lev ,
147                                int bot , int top , MRI_IMAGE *oldim )
148 {
149    MRI_IMAGE *newim ;
150    register int ii , npix ;
151    double   imin,imax ;
152    register double dscale , dbbot ;
153    register float  scale  , flbot , val ;
154    register short * ar ;
155 
156 ENTRY("mri_to_short_sclip") ;
157 
158    if( oldim == NULL ) RETURN( NULL );  /* 09 Feb 1999 */
159 
160    newim = mri_new_conforming( oldim , MRI_short ) ;
161    npix  = oldim->nvox ;
162 
163    if( scl == 0 ){  /* compute scaling to make [min..max] -> [0..lev] */
164 
165       imin = (oldim->kind==MRI_complex || oldim->kind==MRI_rgb) ? (0) : mri_min(oldim) ;
166       imax = mri_max( oldim ) ;
167       imax = (imax <= imin) ? imin+1 : imax ;
168 
169       scale = dscale = (lev+0.99) / (imax-imin)  ;
170       flbot = dbbot  = imin ;
171 
172    } else {          /* user controlled scaling, with lev -> 0 */
173       scale = dscale = scl ;
174       flbot = dbbot  = lev ;
175    }
176 
177    ar = mri_data_pointer( newim ) ;  /* fast access to data */
178 
179    switch( oldim->kind ){
180 
181       case MRI_rgb:{
182          register byte * rgb = mri_data_pointer(oldim) ;
183          float rfac=0.299*scale , gfac=0.587*scale , bfac=0.114*scale ;
184          for( ii=0 ; ii < npix ; ii++ )
185             ar[ii] = (short) (  rfac * rgb[3*ii]
186                               + gfac * rgb[3*ii+1]
187                               + bfac * rgb[3*ii+2] ) ;
188       }
189       break ;
190 
191       case MRI_byte:{
192          register byte * oar = mri_data_pointer(oldim) ;
193          for( ii=0 ; ii < npix ; ii++ ){
194             val = scale * (oar[ii]-flbot) ;
195             ar[ii] = BYTEIZE(val) ;
196          }
197          break ;
198       }
199 
200       case MRI_short:{
201          register short * oar = mri_data_pointer(oldim) ;
202          for( ii=0 ; ii < npix ; ii++ ){
203             val = scale * (oar[ii]-flbot) ;
204             ar[ii] = SHORTIZE(val) ;
205          }
206          break ;
207       }
208 
209       case MRI_int:{
210          register int * oar = mri_data_pointer(oldim) ;
211          for( ii=0 ; ii < npix ; ii++ )
212             ar[ii] = scale * (oar[ii]-flbot) ;
213          break ;
214       }
215 
216       case MRI_float:{
217          register float * oar = mri_data_pointer(oldim) ;
218          for( ii=0 ; ii < npix ; ii++ )
219             ar[ii] = scale * (oar[ii]-flbot) ;
220          break ;
221       }
222 
223       case MRI_double:{
224          register double * oar = mri_data_pointer(oldim) ;
225          for( ii=0 ; ii < npix ; ii++ )
226             ar[ii] = dscale * (oar[ii]-dbbot) ;
227          break ;
228       }
229 
230       case MRI_complex:{
231          register complex * oar = mri_data_pointer(oldim) ;
232          for( ii=0 ; ii < npix ; ii++ )
233             ar[ii] = scale * CABS(oar[ii]) ;
234          break ;
235       }
236 
237       default:
238          fprintf( stderr , "mri_to_short_scl:  unrecognized image kind\n" ) ;
239          MRI_FATAL_ERROR ;
240    }
241 
242    /* clip, if desired */
243 
244    if( bot < top ){
245       register short bb = bot , tt = top ;
246       for( ii=0 ; ii < npix ; ii++ ){
247              if( ar[ii] < bb ) ar[ii] = bb ;
248        else if( ar[ii] > tt ) ar[ii] = tt ;
249       }
250    }
251 
252    MRI_COPY_AUX(newim,oldim) ;
253    RETURN( newim );
254 }
255