00001 #include "mrilib.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 THD_3dim_dataset * THD_zeropad( THD_3dim_dataset * inset ,
00019 int add_I , int add_S , int add_A ,
00020 int add_P , int add_L , int add_R ,
00021 char * prefix , int flag )
00022 {
00023 THD_3dim_dataset *outset ;
00024 int nxold,nyold,nzold , nxnew,nynew,nznew , nxyold,nxynew ,
00025 nxbot=0,nxtop=0 , nybot=0,nytop=0 , nzbot=0,nztop=0 ;
00026 int ii,jj,kk , iv , iibot,iitop , jjbot,jjtop , kkbot,kktop ;
00027
00028 int empty_flag = (flag & ZPAD_EMPTY) ;
00029 int purge_flag = (flag & ZPAD_PURGE) ;
00030 int mm_flag = (flag & ZPAD_MM ) ;
00031
00032 THD_ivec3 iv_nxyz ;
00033 THD_fvec3 fv_xyzorg ;
00034
00035 MRI_IMAGE * oldim ;
00036 void * vnew ;
00037
00038 ENTRY("THD_zeropad") ;
00039
00040
00041
00042 if( !ISVALID_DSET(inset) ) RETURN( NULL ) ;
00043
00044 if( add_I==0 && add_S==0 && add_P==0 &&
00045 add_A==0 && add_L==0 && add_R==0 ){
00046
00047 fprintf(stderr,"++ THD_zeropad: all pad values are zero!\n") ;
00048
00049 outset = EDIT_full_copy( inset , prefix ) ;
00050 RETURN( outset );
00051 }
00052
00053 if( !THD_filename_ok(prefix) ) prefix = "zeropad" ;
00054
00055
00056
00057 nxold = DSET_NX(inset) ;
00058 nyold = DSET_NY(inset) ;
00059 nzold = DSET_NZ(inset) ;
00060
00061
00062
00063
00064 switch( inset->daxes->xxorient ){
00065 default:
00066 fprintf(stderr,"*** THD_zeropad: Unknown orientation codes!\n") ;
00067 RETURN( NULL );
00068
00069 case ORI_R2L_TYPE: nxtop = add_L ; nxbot = add_R ; break ;
00070 case ORI_L2R_TYPE: nxtop = add_R ; nxbot = add_L ; break ;
00071 case ORI_P2A_TYPE: nxtop = add_A ; nxbot = add_P ; break ;
00072 case ORI_A2P_TYPE: nxtop = add_P ; nxbot = add_A ; break ;
00073 case ORI_I2S_TYPE: nxtop = add_S ; nxbot = add_I ; break ;
00074 case ORI_S2I_TYPE: nxtop = add_I ; nxbot = add_S ; break ;
00075 }
00076
00077 switch( inset->daxes->yyorient ){
00078 default:
00079 fprintf(stderr,"*** THD_zeropad: Unknown orientation codes!\n") ;
00080 RETURN( NULL );
00081
00082 case ORI_R2L_TYPE: nytop = add_L ; nybot = add_R ; break ;
00083 case ORI_L2R_TYPE: nytop = add_R ; nybot = add_L ; break ;
00084 case ORI_P2A_TYPE: nytop = add_A ; nybot = add_P ; break ;
00085 case ORI_A2P_TYPE: nytop = add_P ; nybot = add_A ; break ;
00086 case ORI_I2S_TYPE: nytop = add_S ; nybot = add_I ; break ;
00087 case ORI_S2I_TYPE: nytop = add_I ; nybot = add_S ; break ;
00088 }
00089
00090 switch( inset->daxes->zzorient ){
00091 default:
00092 fprintf(stderr,"*** THD_zeropad: Unknown orientation codes!\n") ;
00093 RETURN( NULL );
00094
00095 case ORI_R2L_TYPE: nztop = add_L ; nzbot = add_R ; break ;
00096 case ORI_L2R_TYPE: nztop = add_R ; nzbot = add_L ; break ;
00097 case ORI_P2A_TYPE: nztop = add_A ; nzbot = add_P ; break ;
00098 case ORI_A2P_TYPE: nztop = add_P ; nzbot = add_A ; break ;
00099 case ORI_I2S_TYPE: nztop = add_S ; nzbot = add_I ; break ;
00100 case ORI_S2I_TYPE: nztop = add_I ; nzbot = add_S ; break ;
00101 }
00102
00103
00104
00105 #undef RMM
00106 #define RMM(n,d) \
00107 do{ if( (n) > 0 ) (n) = (int)( (n)/fabs(d) + 0.999 ) ; \
00108 else if( (n) < 0 ) (n) = (int)( (n)/fabs(d) - 0.999 ) ; } while(0) ;
00109
00110 if( mm_flag ){
00111 RMM(nxtop,inset->daxes->xxdel) ; RMM(nxbot,inset->daxes->xxdel) ;
00112 RMM(nytop,inset->daxes->yydel) ; RMM(nybot,inset->daxes->yydel) ;
00113 RMM(nztop,inset->daxes->zzdel) ; RMM(nzbot,inset->daxes->zzdel) ;
00114 }
00115
00116 nxnew = nxold + nxbot + nxtop ;
00117 nynew = nyold + nybot + nytop ;
00118 nznew = nzold + nzbot + nztop ;
00119
00120 nxyold = nxold * nyold ;
00121 nxynew = nxnew * nynew ;
00122
00123 iibot = MAX(0,-nxbot) ; iitop = MIN(nxold,nxold+nxtop) ;
00124 jjbot = MAX(0,-nybot) ; jjtop = MIN(nyold,nyold+nytop) ;
00125 kkbot = MAX(0,-nzbot) ; kktop = MIN(nzold,nzold+nztop) ;
00126
00127 if( nxnew < 1 || iibot > iitop ||
00128 nynew < 1 || jjbot > jjtop ||
00129 nznew < 1 || kkbot > kktop ){
00130
00131 fprintf(stderr,"*** THD_zeropad: Can't cut dataset down too much!\n") ;
00132 RETURN( NULL );
00133 }
00134
00135 #if 0
00136 if( nxnew < 2 || iibot >= iitop ||
00137 nynew < 2 || jjbot >= jjtop ||
00138 nznew < 2 || kkbot >= kktop ){
00139
00140 fprintf(stderr,"*** WARNING - THD_zeropad: dataset cut down to %dx%dx%d\n",
00141 nxnew,nynew,nznew) ;
00142 }
00143 #endif
00144
00145
00146
00147 outset = EDIT_empty_copy( inset ) ;
00148
00149 LOAD_IVEC3( iv_nxyz , nxnew,nynew,nznew ) ;
00150
00151 LOAD_FVEC3( fv_xyzorg, inset->daxes->xxorg - nxbot * inset->daxes->xxdel,
00152 inset->daxes->yyorg - nybot * inset->daxes->yydel,
00153 inset->daxes->zzorg - nzbot * inset->daxes->zzdel );
00154
00155 STATUS("setting new dimensions") ;
00156
00157 EDIT_dset_items( outset ,
00158 ADN_prefix , prefix ,
00159 ADN_nxyz , iv_nxyz ,
00160 ADN_xyzorg , fv_xyzorg ,
00161 ADN_none ) ;
00162
00163
00164
00165 EDIT_ZERO_ANATOMY_PARENT_ID( outset ) ;
00166 outset->anat_parent_name[0] = '\0' ;
00167
00168 #if 0
00169
00170
00171 if( (nzbot!=0 || nztop!=0) && outset->taxis != NULL && outset->taxis->nsl > 0 ){
00172 EDIT_dset_items( outset , ADN_nsl , 0 , ADN_none ) ;
00173 fprintf(stderr,
00174 "*** THD_zeropad: warning - slice-dependent time shifts have been removed!\n") ;
00175 }
00176 #else
00177
00178
00179
00180 if( (nzbot!=0 || nztop!=0) && outset->taxis != NULL && outset->taxis->nsl > 0 ){
00181 int old_nsl , new_nsl , ii, nkeep,kbot,ibot ;
00182 float old_zorg_sl , *old_toff_sl , new_zorg_sl , *new_toff_sl ;
00183
00184
00185
00186 old_nsl = outset->taxis->nsl ;
00187 old_zorg_sl = outset->taxis->zorg_sl ;
00188 old_toff_sl = (float *) malloc(sizeof(float)*old_nsl) ;
00189 memcpy( old_toff_sl , outset->taxis->toff_sl , sizeof(float)*old_nsl ) ;
00190
00191
00192
00193 new_nsl = nznew ;
00194 new_zorg_sl = outset->daxes->zzorg ;
00195 new_toff_sl = (float *) malloc(sizeof(float)*new_nsl) ;
00196 for( ii=0 ; ii < new_nsl ; ii++ ) new_toff_sl[ii] = 0.0 ;
00197
00198 nkeep = old_nsl ;
00199 if( nzbot < 0 ) nkeep += nzbot ;
00200 if( nztop < 0 ) nkeep += nztop ;
00201
00202 if( nzbot < 0 ){
00203 kbot = -nzbot ;
00204 ibot = 0 ;
00205 } else {
00206 kbot = 0 ;
00207 ibot = nzbot ;
00208 }
00209
00210 memcpy( new_toff_sl+ibot , old_toff_sl+kbot , sizeof(float)*nkeep ) ;
00211
00212
00213
00214 STATUS("setting new time-offsets") ;
00215
00216 EDIT_dset_items( outset ,
00217 ADN_nsl , new_nsl ,
00218 ADN_toff_sl , new_toff_sl ,
00219 ADN_zorg_sl , new_zorg_sl ,
00220 ADN_none ) ;
00221
00222 free(new_toff_sl) ; free(old_toff_sl) ;
00223 }
00224 #endif
00225
00226 if( empty_flag ) RETURN(outset) ;
00227
00228
00229
00230 STATUS("reading dataset in") ;
00231
00232 DSET_load(inset) ;
00233 if( !DSET_LOADED(inset) ){
00234 fprintf(stderr,"*** THD_zeropad: Can't load input dataset BRIK!\n");
00235 DSET_delete(outset) ;
00236 RETURN( NULL );
00237 }
00238
00239 STATUS("padding") ;
00240
00241 for( iv=0 ; iv < DSET_NVALS(inset) ; iv++ ){
00242
00243
00244
00245 oldim = DSET_BRICK(inset,iv) ;
00246
00247 vnew = (void*)calloc( nxnew*nynew*nznew ,
00248 oldim->pixel_size ) ;
00249 if( vnew == NULL ){
00250 fprintf(stderr,
00251 "*** THD_zeropad: Can't malloc space for new sub-brick %d\n",
00252 iv) ;
00253 DSET_delete(outset) ; RETURN( NULL );
00254 }
00255
00256
00257
00258 #undef SNEW
00259 #undef SOLD
00260 #define SNEW(i,j,k) ((i+nxbot)+(j+nybot)*nxnew+(k+nzbot)*nxynew)
00261 #define SOLD(i,j,k) (i+j*nxold+k*nxyold)
00262
00263 switch( oldim->kind ){
00264
00265 case MRI_byte:{
00266 byte * bnew = (byte *) vnew, * bold = mri_data_pointer(oldim) ;
00267 for( kk=kkbot ; kk < kktop ; kk++ )
00268 for( jj=jjbot ; jj < jjtop ; jj++ )
00269 for( ii=iibot ; ii < iitop ; ii++ )
00270 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00271 }
00272 break ;
00273
00274 case MRI_short:{
00275 short * bnew = (short *) vnew, * bold = mri_data_pointer(oldim) ;
00276 for( kk=kkbot ; kk < kktop ; kk++ )
00277 for( jj=jjbot ; jj < jjtop ; jj++ )
00278 for( ii=iibot ; ii < iitop ; ii++ )
00279 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00280 }
00281 break ;
00282
00283 case MRI_float:{
00284 float * bnew = (float *) vnew, * bold = mri_data_pointer(oldim) ;
00285 for( kk=kkbot ; kk < kktop ; kk++ )
00286 for( jj=jjbot ; jj < jjtop ; jj++ )
00287 for( ii=iibot ; ii < iitop ; ii++ )
00288 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00289 }
00290 break ;
00291
00292 case MRI_complex:{
00293 complex * bnew = (complex *) vnew, * bold = mri_data_pointer(oldim) ;
00294 for( kk=kkbot ; kk < kktop ; kk++ )
00295 for( jj=jjbot ; jj < jjtop ; jj++ )
00296 for( ii=iibot ; ii < iitop ; ii++ )
00297 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00298 }
00299 break ;
00300
00301 case MRI_int:{
00302 int * bnew = (int *) vnew, * bold = mri_data_pointer(oldim) ;
00303 for( kk=kkbot ; kk < kktop ; kk++ )
00304 for( jj=jjbot ; jj < jjtop ; jj++ )
00305 for( ii=iibot ; ii < iitop ; ii++ )
00306 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00307 }
00308 break ;
00309
00310 case MRI_rgb:{
00311 rgbyte * bnew = (rgbyte *) vnew, * bold = mri_data_pointer(oldim) ;
00312 for( kk=kkbot ; kk < kktop ; kk++ )
00313 for( jj=jjbot ; jj < jjtop ; jj++ )
00314 for( ii=iibot ; ii < iitop ; ii++ )
00315 bnew[SNEW(ii,jj,kk)] = bold[SOLD(ii,jj,kk)] ;
00316 }
00317 break ;
00318
00319 }
00320
00321 if( purge_flag) DSET_unload_one(inset,iv) ;
00322
00323 EDIT_substitute_brick( outset , iv , oldim->kind , vnew ) ;
00324
00325 }
00326
00327 #if 0
00328 if( purge_flag ) DSET_unload(inset) ;
00329 #endif
00330
00331 RETURN( outset );
00332 }