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 [some of it] ***/
10 
mri_to_rgb(MRI_IMAGE * oldim)11 MRI_IMAGE *mri_to_rgb( MRI_IMAGE *oldim )  /* 11 Feb 1999 */
12 {
13    MRI_IMAGE *newim ;
14    register int ii , npix ;
15    register byte * rgb ;
16 
17 ENTRY("mri_to_rgb") ;
18 
19    if( oldim == NULL ) RETURN( NULL );
20 
21    newim = mri_new_conforming( oldim , MRI_rgb ) ; rgb = MRI_RGB_PTR(newim) ;
22    npix  = oldim->nvox ;
23 
24    switch( oldim->kind ){
25 
26       case MRI_byte:{ byte *qar = MRI_BYTE_PTR(oldim) ;
27         for( ii=0 ; ii < npix ; ii++ )
28           rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ;
29       } break ;
30 
31       case MRI_float:{ float *qar = MRI_FLOAT_PTR(oldim) ;
32         for( ii=0 ; ii < npix ; ii++ )
33           rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ;
34       } break ;
35 
36       case MRI_short:{ short *qar = MRI_SHORT_PTR(oldim) ;
37         for( ii=0 ; ii < npix ; ii++ )
38           rgb[3*ii] = rgb[3*ii+1] = rgb[3*ii+2] = qar[ii] ;
39       } break ;
40 
41       case MRI_rgb:
42         memcpy( rgb , MRI_RGB_PTR(oldim) , 3*npix ) ;
43       break ;
44 
45       case MRI_rgba:{ rgba *qar = MRI_RGBA_PTR(oldim) ;
46         float aa ;
47         for( ii=0 ; ii < npix ; ii++ ){ /* scale by A [13 Feb 2020] */
48           aa = qar[ii].a / 255.0f ;     /* instead of just dropping A */
49           if( aa > 0.99f ){
50             rgb[3*ii]   = qar[ii].r ;
51             rgb[3*ii+1] = qar[ii].g ;
52             rgb[3*ii+2] = qar[ii].b ;
53           } else {
54             rgb[3*ii]   = (byte)(aa*qar[ii].r+0.4f) ;
55             rgb[3*ii+1] = (byte)(aa*qar[ii].g+0.4f) ;
56             rgb[3*ii+2] = (byte)(aa*qar[ii].b+0.4f) ;
57           }
58         }
59       } break ;
60 
61       default:
62         ERROR_message("mri_to_rgb: unrecognized image conversion %d",oldim->kind) ;
63         mri_free(newim) ; RETURN(NULL);
64    }
65 
66    MRI_COPY_AUX(newim,oldim) ;
67    RETURN( newim );
68 }
69 
70 /*---------------------------------------------------------------------------
71    Inputs must be in same formats (# voxels and kinds)!
72 -----------------------------------------------------------------------------*/
73 
mri_3to_rgb(MRI_IMAGE * rim,MRI_IMAGE * gim,MRI_IMAGE * bim)74 MRI_IMAGE * mri_3to_rgb( MRI_IMAGE *rim , MRI_IMAGE *gim , MRI_IMAGE *bim )
75 {
76    MRI_IMAGE *newim ;
77    register int ii , npix ;
78    register byte * rgb ;
79 
80 ENTRY("mri_3to_rgb") ;
81 
82    if( rim == NULL || bim == NULL || gim == NULL ) RETURN( NULL );
83 
84    newim = mri_new_conforming( rim , MRI_rgb ) ; rgb = MRI_BYTE_PTR(newim) ;
85    npix  = rim->nvox ;
86 
87    switch( rim->kind ){
88 
89       case MRI_byte:{
90         byte *rr=MRI_BYTE_PTR(rim), *gg=MRI_BYTE_PTR(gim), *bb=MRI_BYTE_PTR(bim) ;
91         for( ii=0 ; ii < npix ; ii++ ){
92           rgb[3*ii  ] = rr[ii] ;
93           rgb[3*ii+1] = gg[ii] ;
94           rgb[3*ii+2] = bb[ii] ;
95         }
96       }
97       break ;
98 
99       case MRI_float:{
100         float *rr=MRI_FLOAT_PTR(rim), *gg=MRI_FLOAT_PTR(gim), *bb=MRI_FLOAT_PTR(bim) ;
101         for( ii=0 ; ii < npix ; ii++ ){
102           rgb[3*ii  ] = rr[ii] ;
103           rgb[3*ii+1] = gg[ii] ;
104           rgb[3*ii+2] = bb[ii] ;
105         }
106       }
107       break ;
108 
109       default:
110         ERROR_message("mri_3to_rgb: unrecognized image conversion %d",rim->kind) ;
111         mri_free(newim) ; RETURN(NULL) ;
112    }
113 
114    MRI_COPY_AUX(newim,rim) ;
115    RETURN( newim );
116 }
117 
118 /*-------------------------------------------------------------------------------*/
119 
mri_rgb_to_3float(MRI_IMAGE * oldim)120 MRI_IMARR * mri_rgb_to_3float( MRI_IMAGE *oldim )
121 {
122    MRI_IMARR *imar ;
123    MRI_IMAGE *rim , *gim , *bim ;
124    float     *rr  , *gg  , *bb  ;
125    byte      *rgb ;
126    int ii , npix ;
127 
128 ENTRY("mri_rgb_to_3float") ;
129 
130    if( oldim == NULL || oldim->kind != MRI_rgb ) RETURN( NULL );
131 
132    rim = mri_new_conforming( oldim , MRI_float ) ; rr = MRI_FLOAT_PTR(rim) ;
133    gim = mri_new_conforming( oldim , MRI_float ) ; gg = MRI_FLOAT_PTR(gim) ;
134    bim = mri_new_conforming( oldim , MRI_float ) ; bb = MRI_FLOAT_PTR(bim) ;
135                                                    rgb= MRI_BYTE_PTR(oldim);
136    npix = oldim->nvox ;
137 
138    for( ii=0 ; ii < npix ; ii++ ){
139      rr[ii] = (float)rgb[3*ii  ] ;
140      gg[ii] = (float)rgb[3*ii+1] ;
141      bb[ii] = (float)rgb[3*ii+2] ;
142    }
143 
144    INIT_IMARR(imar) ;
145    ADDTO_IMARR(imar,rim) ; ADDTO_IMARR(imar,gim) ; ADDTO_IMARR(imar,bim) ;
146 
147    RETURN( imar );
148 }
149 
150 /*-------------------------------------------------------------------------------*/
151 
mri_rgb_to_3byte(MRI_IMAGE * oldim)152 MRI_IMARR * mri_rgb_to_3byte( MRI_IMAGE *oldim )  /* 15 Apr 1999 */
153 {
154    MRI_IMARR *imar ;
155    MRI_IMAGE *rim , *gim , *bim ;
156    byte      *rr  , *gg  , *bb  , *rgb ;
157    int ii , npix ;
158 
159 ENTRY("mri_rgb_to_3byte") ;
160    if( oldim == NULL || oldim->kind != MRI_rgb ) RETURN( NULL );
161 
162    rim = mri_new_conforming( oldim , MRI_byte ) ; rr = MRI_BYTE_PTR(rim) ;
163    gim = mri_new_conforming( oldim , MRI_byte ) ; gg = MRI_BYTE_PTR(gim) ;
164    bim = mri_new_conforming( oldim , MRI_byte ) ; bb = MRI_BYTE_PTR(bim) ;
165                                                   rgb= MRI_BYTE_PTR(oldim);
166    npix = oldim->nvox ;
167 
168    for( ii=0 ; ii < npix ; ii++ ){
169      rr[ii] = rgb[3*ii  ] ;
170      gg[ii] = rgb[3*ii+1] ;
171      bb[ii] = rgb[3*ii+2] ;
172    }
173 
174    INIT_IMARR(imar) ;
175    ADDTO_IMARR(imar,rim) ; ADDTO_IMARR(imar,gim) ; ADDTO_IMARR(imar,bim) ;
176 
177    RETURN( imar );
178 }
179 
180 /*-----------------------------------------------------------------------------*/
181 
mri_sharpen_rgb(float phi,MRI_IMAGE * im)182 MRI_IMAGE * mri_sharpen_rgb( float phi , MRI_IMAGE *im )
183 {
184    MRI_IMAGE *flim , *shim , *newim ;
185    byte  *iar , *nar ;
186    float *sar , *far ;
187    int ii , nvox , rr,gg,bb ;
188    float fac ;
189 
190 ENTRY("mri_sharpen_rgb") ;
191 
192    if( im == NULL ) RETURN( NULL );
193 
194    if( im->kind != MRI_rgb ) RETURN( mri_sharpen(phi,0,im) );
195 
196    flim  = mri_to_float( im ) ;                  /* intensity of input */
197    shim  = mri_sharpen( phi , 0 , flim ) ;       /* sharpen intensity */
198    newim = mri_new_conforming( im , MRI_rgb ) ;  /* will be output    */
199 
200    nar = MRI_BYTE_PTR(newim) ; iar = MRI_BYTE_PTR(im) ;
201    far = MRI_FLOAT_PTR(flim) ; sar = MRI_FLOAT_PTR(shim) ;
202 
203    nvox = newim->nvox ;
204    for( ii=0 ; ii < nvox ; ii++ ){
205      if( far[ii] <= 0.0 || sar[ii] <= 0.0 ){
206        nar[3*ii] = nar[3*ii+1] = nar[3*ii+2] = 0 ;
207      } else {
208        fac = sar[ii] / far[ii] ; /* will be positive */
209        rr  = fac * iar[3*ii]   ;
210        gg  = fac * iar[3*ii+1] ;
211        bb  = fac * iar[3*ii+2] ;
212        nar[3*ii  ] = (rr > 255) ? 255 : rr ;
213        nar[3*ii+1] = (gg > 255) ? 255 : gg ;
214        nar[3*ii+2] = (bb > 255) ? 255 : bb ;
215      }
216    }
217 
218    mri_free(flim) ; mri_free(shim) ;
219    MRI_COPY_AUX(newim,im) ;
220    RETURN( newim );
221 }
222 
223 /*-----------------------------------------------------------------------------*/
224 
225 static float mfac = 0.4f ;
226 
mri_flatten_rgb(MRI_IMAGE * im)227 MRI_IMAGE * mri_flatten_rgb( MRI_IMAGE *im )
228 {
229    MRI_IMAGE *flim , *shim , *newim ;
230    byte  *iar , *nar ;
231    float *sar , *far ;
232    int ii , nvox , rr,gg,bb ;
233    float fac , ifac,ffac ;
234 
235 ENTRY("mri_flatten_rgb") ;
236 
237    if( im == NULL ) RETURN( NULL );
238 
239    if( im->kind != MRI_rgb ) RETURN( mri_flatten(im) );
240 
241    flim  = mri_to_float( im ) ;                  /* intensity of input */
242    shim  = mri_flatten( flim ) ;                 /* flatten intensity  */
243    newim = mri_new_conforming( im , MRI_rgb ) ;  /* will be output     */
244 
245    nar = MRI_BYTE_PTR(newim) ; iar = MRI_BYTE_PTR(im) ;
246    far = MRI_FLOAT_PTR(flim) ; sar = MRI_FLOAT_PTR(shim) ;
247    nvox = newim->nvox ;
248 
249    ifac = mfac ;
250    ffac = (1.0f-ifac) ;
251 
252    for( ii=0 ; ii < nvox ; ii++ ){
253      if( far[ii] < 0.0f || sar[ii] < 0.0f ){
254        nar[3*ii] = nar[3*ii+1] = nar[3*ii+2] = 0 ;
255      } else {
256        fac = ffac*(255.9f*sar[ii]/far[ii])+ifac ; /* will be positive */
257        rr  = fac * iar[3*ii]   ;
258        gg  = fac * iar[3*ii+1] ;
259        bb  = fac * iar[3*ii+2] ;
260        nar[3*ii  ] = (rr > 255) ? 255 : rr ;
261        nar[3*ii+1] = (gg > 255) ? 255 : gg ;
262        nar[3*ii+2] = (bb > 255) ? 255 : bb ;
263      }
264    }
265 
266    mri_free(flim) ; mri_free(shim) ;
267    MRI_COPY_AUX(newim,im) ;
268    RETURN( newim );
269 }
270 
271 /*-----------------------------------------------------------------------------*/
272 
mri_invert_inplace(MRI_IMAGE * im)273 void mri_invert_inplace( MRI_IMAGE *im )
274 {
275    register byte *bar ;
276    register int ii , nbar ;
277 
278 ENTRY("mri_invert_inplace") ;
279 
280    if( im == NULL ) EXRETURN ;
281    switch( im->kind ){
282      default: EXRETURN ;
283      case MRI_byte:  nbar =   im->nvox ; bar = MRI_BYTE_PTR(im) ; break ;
284      case MRI_rgb:   nbar = 3*im->nvox ; bar = MRI_RGB_PTR(im)  ; break ;
285    }
286    for( ii=0 ; ii < nbar ; ii++ ) bar[ii] = 255 - bar[ii] ;
287    EXRETURN ;
288 }
289 
290 /*-----------------------------------------------------------------------------*/
291 
292 /*** Am not sure if this works properly! ***/
293 
mri_gamma_rgb_inplace(float gam,MRI_IMAGE * im)294 void mri_gamma_rgb_inplace( float gam , MRI_IMAGE *im )  /* 15 Jan 2007 */
295 {
296    MRI_IMAGE *flim ; byte *iar ; float *far ;
297    int ii , nvox , rr,gg,bb ; float fac , val , gg1 ;
298 
299 ENTRY("mri_gamma_rgb_inplace") ;
300 
301    if( im == NULL || im->kind != MRI_rgb || gam <= 0.0f ) EXRETURN ;
302 
303    flim = mri_to_float( im ) ; /* intensity of input */
304    iar = MRI_BYTE_PTR(im) ; far = MRI_FLOAT_PTR(flim) ;
305    fac = mri_max(flim) ;
306    if( fac <= 0.0f ){ mri_free(flim); EXRETURN; } else fac = 1.0f/fac ;
307 
308    nvox = im->nvox ; gg1 = gam-1.0f ;
309    for( ii=0 ; ii < nvox ; ii++ ){
310      if( far[ii] <= 0.0f ){
311        iar[3*ii] = iar[3*ii+1] = iar[3*ii+2] = 0 ;
312      } else {
313        val = powf( far[ii]*fac , gg1 ) ;
314        rr  = rint(val * iar[3*ii  ]) ;
315        gg  = rint(val * iar[3*ii+1]) ;
316        bb  = rint(val * iar[3*ii+2]) ;
317        iar[3*ii  ] = (rr > 255) ? 255 : rr ;
318        iar[3*ii+1] = (gg > 255) ? 255 : gg ;
319        iar[3*ii+2] = (bb > 255) ? 255 : bb ;
320      }
321    }
322 
323    mri_free(flim) ; EXRETURN ;
324 }
325 
326 /*-----------------------------------------------------------------------------*/
327 
mri_make_rainbow(int nx,int ny,int ncol,rgbyte * col)328 MRI_IMAGE * mri_make_rainbow( int nx , int ny , int ncol , rgbyte *col )
329 {
330    MRI_IMAGE *bim ; byte *bar ; int ii,jj , pp ; float qq,rr ;
331 
332    if( ncol < 2 || col == NULL ) return NULL ;
333    if( nx < 1      ) nx = 8 ;
334    if( ny < 2*ncol ) ny = 2*ncol ;
335 
336    bim = mri_new(nx,ny,MRI_rgb) ; bar = MRI_RGB_PTR(bim) ;
337 
338    for( jj=0 ; jj < ny ; jj++ ){
339      qq = jj*(ncol-1.001f)/(ny-1.0f) ; pp = (int)qq ;
340      qq = qq-pp ; rr = 1.0f-qq ;
341      for( ii=0 ; ii < nx ; ii++ ){
342        bar[3*(ii+jj*nx)+0] = (byte)( rr*col[pp].r + qq*col[pp+1].r ) ;
343        bar[3*(ii+jj*nx)+1] = (byte)( rr*col[pp].g + qq*col[pp+1].g ) ;
344        bar[3*(ii+jj*nx)+2] = (byte)( rr*col[pp].b + qq*col[pp+1].b ) ;
345      }
346    }
347    return bim ;
348 }
349