1 #include "mrilib.h"
2
3 /*----------------------------------------------------------------------------*/
4 static int use_padval = 0 ;
5 static int typ_padval = -1 ;
6 static char padval[32] ;
7
EDIT_set_padval(int ftype,char * pval)8 void EDIT_set_padval( int ftype , char *pval )
9 {
10 int dsiz = mri_datum_size(ftype) ;
11 if( pval == NULL || dsiz == 0 ){ use_padval = 0; typ_padval = -1; return; }
12 memcpy( padval , pval , dsiz ) ;
13 use_padval = 1 ; typ_padval = ftype ;
14 return ;
15 }
16
17 /*----------------------------------------------------------------------------*/
18 /***** pad a volume by adding/subtracting planes of zeros:
19 nxbot = # to add on -x side (can be negative, to remove planes)
20 nxtop = # to add on +x side, etc.
21 If all n?bot,n?top values are zero, just returns a copy
22 of the input. If too much is cut off, or something else
23 bad happens, returns NULL.
24
25 Adapted from thd_zeropad.c -- 02 Feb 2001 -- RWCox
26 Modified to allow uneven padding -- 09 Feb 2001 -- RWCox *****/
27
EDIT_volpad(int nxbot,int nxtop,int nybot,int nytop,int nzbot,int nztop,int nx,int ny,int nz,int ftype,void * fim)28 void * EDIT_volpad( int nxbot , int nxtop ,
29 int nybot , int nytop ,
30 int nzbot , int nztop ,
31 int nx, int ny, int nz, int ftype, void *fim )
32 {
33 int nxold,nyold,nzold , nxnew,nynew,nznew , nxyold,nxynew ;
34 int ii,jj,kk , iv , iibot,iitop , jjbot,jjtop , kkbot,kktop ;
35 void *vnew ;
36
37 ENTRY("EDIT_volpad") ;
38
39 /*- check for user stupidity -*/
40
41 if( nx <= 0 || ny <= 0 || nz <= 0 || fim == NULL ) RETURN(NULL) ;
42
43 /*- special case: just copy input -*/
44
45 if( nxbot == 0 && nybot == 0 && nzbot == 0 &&
46 nxtop == 0 && nytop == 0 && nztop == 0 ){
47
48 vnew = malloc( mri_datum_size(ftype) * nx*ny*nz ) ;
49 memcpy( vnew , fim , mri_datum_size(ftype) * nx*ny*nz ) ;
50 RETURN(vnew) ;
51 }
52
53 nxold = nx ; nxnew = nxold + nxbot + nxtop ; /* dimensions */
54 nyold = ny ; nynew = nyold + nybot + nytop ;
55 nzold = nz ; nznew = nzold + nzbot + nztop ;
56
57 nxyold = nxold * nyold ; /* for computing 3D subscripts */
58 nxynew = nxnew * nynew ;
59
60 iibot = MAX(0,-nxbot) ; iitop = MIN(nxold,nxold+nxtop) ; /* range of data */
61 jjbot = MAX(0,-nybot) ; jjtop = MIN(nyold,nyold+nytop) ; /* in old dataset */
62 kkbot = MAX(0,-nzbot) ; kktop = MIN(nzold,nzold+nztop) ; /* to copy to new */
63
64 if( nxnew < 2 || iibot >= iitop || /* check for reasonable sizes */
65 nynew < 2 || jjbot >= jjtop || /* and ranges of dataset */
66 nznew < 2 || kkbot >= kktop ){
67
68 ERROR_message("EDIT_volpad: can't cut volume down to nothing!") ;
69 RETURN(NULL) ;
70 }
71
72 vnew = calloc( nxnew*nynew*nznew , mri_datum_size(ftype) ) ; /* new brick */
73 if( vnew == NULL ){
74 ERROR_message("EDIT_volpad: Can't malloc space for new array") ;
75 RETURN(NULL) ;
76 }
77
78 /* non-zero pad value was set? copy it over all the data [22 Sep 2020] */
79
80 if( use_padval && typ_padval == ftype ){
81 int dsiz = mri_datum_size(ftype) , nvox = nxnew*nynew*nznew ;
82 char *cnew = (char *)vnew ;
83 if( dsiz == 1 ){
84 memset( cnew , nvox , padval[0] ) ;
85 } else {
86 for( ii=0 ; ii < nvox ; ii++ )
87 memcpy( cnew + ii*dsiz , padval , dsiz ) ;
88 }
89 }
90
91 /* macros for computing 1D subscripts from 3D indices */
92
93 #undef SNEW /* in case was defined in some stupid .h file */
94 #undef SOLD
95 #define SNEW(i,j,k) ((i+nxbot)+(j+nybot)*nxnew+(k+nzbot)*nxynew)
96 #define SOLD(i,j,k) (i+j*nxold+k*nxyold)
97
98 switch( ftype ){ /* copy rows of old into new */
99
100 default:
101 ERROR_message("EDIT_volpad: unknown input datum=%d",ftype) ;
102 free(vnew) ;
103 RETURN(NULL) ;
104
105 case MRI_byte:{
106 byte *bnew = (byte *) vnew, *bold = (byte *) fim ;
107 for( kk=kkbot ; kk < kktop ; kk++ )
108 for( jj=jjbot ; jj < jjtop ; jj++ )
109 for( ii=iibot ; ii < iitop ; ii++ )
110 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
111 }
112 break ;
113
114 case MRI_rgb:{
115 byte *bnew = (byte *) vnew, *bold = (byte *) fim ;
116 for( kk=kkbot ; kk < kktop ; kk++ )
117 for( jj=jjbot ; jj < jjtop ; jj++ )
118 for( ii=iibot ; ii < iitop ; ii++ ){
119 bnew[3*SNEW(ii,jj,kk) ] = bold[3*SOLD(ii,jj,kk) ] ;
120 bnew[3*SNEW(ii,jj,kk)+1] = bold[3*SOLD(ii,jj,kk)+1] ;
121 bnew[3*SNEW(ii,jj,kk)+2] = bold[3*SOLD(ii,jj,kk)+2] ;
122 }
123 }
124 break ;
125
126 case MRI_short:{
127 short *bnew = (short *) vnew, *bold = (short *) fim ;
128 for( kk=kkbot ; kk < kktop ; kk++ )
129 for( jj=jjbot ; jj < jjtop ; jj++ )
130 for( ii=iibot ; ii < iitop ; ii++ )
131 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
132 }
133 break ;
134
135 case MRI_int:{
136 int *bnew = (int *) vnew, *bold = (int *) fim ;
137 for( kk=kkbot ; kk < kktop ; kk++ )
138 for( jj=jjbot ; jj < jjtop ; jj++ )
139 for( ii=iibot ; ii < iitop ; ii++ )
140 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
141 }
142 break ;
143
144 case MRI_float:{
145 float *bnew = (float *) vnew, *bold = (float *) fim ;
146 for( kk=kkbot ; kk < kktop ; kk++ )
147 for( jj=jjbot ; jj < jjtop ; jj++ )
148 for( ii=iibot ; ii < iitop ; ii++ )
149 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
150 }
151 break ;
152
153 case MRI_double:{
154 double *bnew = (double *) vnew, *bold = (double *) fim ;
155 for( kk=kkbot ; kk < kktop ; kk++ )
156 for( jj=jjbot ; jj < jjtop ; jj++ )
157 for( ii=iibot ; ii < iitop ; ii++ )
158 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
159 }
160 break ;
161
162 case MRI_complex:{
163 complex *bnew = (complex *) vnew, *bold = (complex *) fim ;
164 for( kk=kkbot ; kk < kktop ; kk++ )
165 for( jj=jjbot ; jj < jjtop ; jj++ )
166 for( ii=iibot ; ii < iitop ; ii++ )
167 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
168 }
169 break ;
170
171 } /* end of switch on datum type */
172
173 RETURN(vnew) ;
174 }
175
176 /*------------------------------------------------------------------
177 14 Feb 2001: do the above to an image struct, just for fun
178 --------------------------------------------------------------------*/
179
mri_zeropad_3D(int nxbot,int nxtop,int nybot,int nytop,int nzbot,int nztop,MRI_IMAGE * im)180 MRI_IMAGE * mri_zeropad_3D( int nxbot , int nxtop ,
181 int nybot , int nytop ,
182 int nzbot , int nztop , MRI_IMAGE *im )
183 {
184 MRI_IMAGE *jm ;
185 void *var ;
186
187 ENTRY("mri_zeropad_3D") ;
188
189 if( im == NULL ) RETURN(NULL) ; /* bad */
190
191 if( !MRI_IS_3D(im) ){
192 jm = mri_zeropad_2D( nxbot,nxtop , nybot,nytop , im ) ;
193 RETURN(jm) ;
194 }
195
196 /* do the padding work */
197
198 var = EDIT_volpad( nxbot,nxtop,nybot,nytop,nzbot,nztop ,
199 im->nx , im->ny , im->nz ,
200 im->kind , mri_data_pointer(im) ) ;
201
202 if( var == NULL ) RETURN(NULL) ; /* bad */
203
204 /* put padded data into new image */
205
206 jm = mri_new_vol_empty( im->nx + nxbot + nxtop ,
207 im->ny + nybot + nytop ,
208 im->nz + nzbot + nztop , im->kind ) ;
209 MRI_COPY_AUX(jm,im) ;
210 mri_fix_data_pointer( var , jm ) ;
211 RETURN( jm );
212 }
213