1 #include "mrilib.h"
2
3 /*-------------------------------------------------------------------------*/
4 /*! Composite a collection of MRI_rgb/MRI_rgba/MRI_byte images.
5 The first image is on top, etc. For MRI_rgb/MRI_byte images,
6 the default opacity is alpha in 0..1. Black (0,0,0) pixels on input
7 are not overlaid (unless AFNI_OVERLAY_ZERO is YES).
8 The output image is MRI_rgb; it is composited against a black backdrop.
9 ---------------------------------------------------------------------------*/
10
mri_rgba_composite_array(MRI_IMARR * imar,float alpha)11 MRI_IMAGE * mri_rgba_composite_array( MRI_IMARR *imar, float alpha )
12 {
13 register int npix,ii,jj , nn,nim ;
14 MRI_IMAGE *outim , *inim ;
15 rgbyte *outar ;
16 float *usop ;
17 int reject_zero = !AFNI_yesenv("AFNI_OVERLAY_ZERO") ;
18
19 ENTRY("mri_rgba_composite") ;
20
21 if( imar == NULL || IMARR_COUNT(imar) == 0 ) RETURN(NULL) ;
22
23 if( alpha <= 0.0 || alpha > 1.0 ) alpha = 1.0 ; /* default default */
24
25 nim = IMARR_COUNT(imar) ;
26 outim = mri_new_conforming( IMARR_SUBIM(imar,0) , MRI_rgb ) ;
27 outar = (rgbyte *) MRI_RGB_PTR(outim) ; /* is all zero */
28 npix = outim->nvox ;
29
30 usop = (float *) malloc(sizeof(float)*npix) ; /* used up opacity */
31 for( ii=0 ; ii < npix ; ii++ ) usop[ii] = 0.0 ;
32
33 #undef MAX_OPACITY
34 #define MAX_OPACITY 0.95
35
36 for( nn=0 ; nn < nim ; nn++ ){
37 inim = IMARR_SUBIM(imar,nn) ;
38 if( inim->nvox < npix ) continue ; /* bad */
39
40 switch( inim->kind ){
41 default: break ; /* bad */
42
43 case MRI_byte:{
44 byte *inar = (byte *) MRI_BYTE_PTR(inim) , val ;
45 register float opa ;
46 for( ii=0 ; ii < npix ; ii++ ){
47 if( reject_zero && inar[ii]==0 ) continue ;
48 if( usop[ii] < MAX_OPACITY ){
49
50 opa = alpha * (1.0-usop[ii]) ; usop[ii] += opa ;
51 val = (byte)( opa * inar[ii] ) ;
52
53 outar[ii].r += val ;
54 outar[ii].g += val ;
55 outar[ii].b += val ;
56 }
57 }
58 }
59
60 case MRI_rgb:{
61 rgbyte *inar = (rgbyte *) MRI_RGB_PTR(inim) ;
62 register float opa ;
63 for( ii=0 ; ii < npix ; ii++ ){
64 if( reject_zero && inar[ii].r==0
65 && inar[ii].g==0 && inar[ii].b==0 ) continue ;
66 if( usop[ii] < MAX_OPACITY ){
67
68 opa = alpha * (1.0-usop[ii]) ; usop[ii] += opa ;
69
70 outar[ii].r += (byte)( opa * inar[ii].r ) ;
71 outar[ii].g += (byte)( opa * inar[ii].g ) ;
72 outar[ii].b += (byte)( opa * inar[ii].b ) ;
73 }
74 }
75 }
76 break ;
77
78 case MRI_rgba:{
79 rgba *inar = (rgba *) MRI_RGBA_PTR(inim) ;
80 register float opa ;
81 for( ii=0 ; ii < npix ; ii++ ){
82 if( reject_zero && inar[ii].r==0
83 && inar[ii].g==0 && inar[ii].b==0 ) continue ;
84 if( usop[ii] < MAX_OPACITY ){
85
86 opa = 0.00392156*inar[ii].a * (1.0-usop[ii]) ; usop[ii] += opa ;
87
88 outar[ii].r += (byte)( opa * inar[ii].r ) ;
89 outar[ii].g += (byte)( opa * inar[ii].g ) ;
90 outar[ii].b += (byte)( opa * inar[ii].b ) ;
91 }
92 }
93 }
94 break ;
95 }
96 }
97
98 free(usop) ; RETURN(outim) ;
99 }
100
101 /*--------------------------------------------------------------------------*/
102 #include <stdarg.h>
103 /*--------------------------------------------------------------------------*/
104
mri_rgba_composite_VA(float alpha,...)105 MRI_IMAGE * mri_rgba_composite_VA( float alpha, ... )
106 {
107 MRI_IMARR *imar=NULL ;
108 MRI_IMAGE *im ;
109 va_list vararg_ptr ;
110
111 va_start( vararg_ptr , alpha ) ;
112
113 while(1){
114 im = va_arg( vararg_ptr , MRI_IMAGE * ) ;
115 if( im == NULL ) break ;
116 if( imar == NULL ) INIT_IMARR(imar) ;
117 ADDTO_IMARR(imar,im) ;
118 }
119
120 va_end( vararg_ptr ) ;
121
122 if( imar == NULL ) return NULL ;
123 im = mri_rgba_composite_array( imar , alpha ) ;
124
125 FREE_IMARR(imar) ; return im ;
126 }
127
128 /*--------------------------------------------------------------------------*/
129
mri_rgba_composite_two(float alpha,MRI_IMAGE * i1,MRI_IMAGE * i2)130 MRI_IMAGE * mri_rgba_composite_two( float alpha, MRI_IMAGE *i1, MRI_IMAGE *i2 )
131 {
132 MRI_IMARR *imar ; MRI_IMAGE *im ;
133 INIT_IMARR(imar) ;
134 ADDTO_IMARR(imar,i1) ; ADDTO_IMARR(imar,i2) ;
135 im = mri_rgba_composite_array( imar , alpha ) ;
136 FREE_IMARR(imar) ; return im ;
137 }
138