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