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