|
// Onur G. Guleryuz 1995, 1996, 1997,<br />// University of Illinois at Urbana-Champaign,<br />// Princeton University,<br />// Polytechnic University.<br /><br />#include "wav_basic.h"<br />#include "wav_filters_extern.h"<br />#include "alloc.h"<br />#include "wav_gen.h"<br /><br />// Macro that sets filter parameters.<br />// Called via choose_filter().<br />#define set_filter_param(fname) \<br />{ \<br /> MFLP= fname ## _FLP; \<br /> MFHP= fname ## _FHP; \<br /> MILP= fname ## _ILP; \<br /> MIHP= fname ## _IHP; \<br /> \<br /> /* Filter size. */ \<br /> Nflp= fname ## _Nflp; \<br /> Nfhp= fname ## _Nfhp; \<br /> Nilp= fname ## _Nilp; \<br /> Nihp= fname ## _Nihp; \<br /> \<br /> /* Filter symmetry */ \<br /> PS= fname ## _PS; \<br /> \<br /> /* Filter starting points. */ \<br /> begflp=mfl= fname ## _begflp; \<br /> begfhp=mfh= fname ## _begfhp; \<br /> begilp=mil= fname ## _begilp; \<br /> begihp=mih= fname ## _begihp; \<br />}<br /><br />// Set wavelet filter parameters depending on name<br />// and tap. See wav_filters.h and wav_filters_extern.h <br />// This routine must be called before doing any transforms<br />// to select which wavelet bank to use.<br />void choose_filter(char name,int tap)<br /><br />{<br /> switch (name) {<br /> case 'A':<br /> switch (tap) {<br /> default:<br /> set_filter_param(Antonini);<br /> }<br /> break;<br /><br /> case 'H':<br /> switch (tap) {<br /> default:<br /> set_filter_param(Haar);<br /> }<br /> break;<br /><br /> case 'N':<br /> switch (tap) {<br /> case -1:<br /> set_filter_param(Nick_flip);<br /> break;<br /><br /> default:<br /> set_filter_param(Nick);<br /> }<br /> break;<br /><br /> default:<br /> switch (tap) {<br /> case 9:<br /> set_filter_param(D79);<br /> break;<br /><br /> default:<br /> set_filter_param(D8);<br /> }<br /> }<br />}<br /><br />// 2D "in place" wavelet transform. Input data is in<br />// float **image and output is returned inside image.<br />//<br />// levs>=1 is the number of wavelet levels.<br />//<br />// Ni and Nj are the dimensions of the image.<br />// Ni and Nj should be divisible by 2^levs.<br />//<br />// shift_arr_row and shift_arr_col (each of dimension levs)<br />// contain the amount of shift (0 or 1)<br />// that should be applied to filters in each level for transforms over rows and columns.<br />// The use of shift_arr_row and shift_arr_col is mainly intended for <br />// overcomplete filtering/transforms.<br />//<br />// forw != 0 for a forward transform (inverse is calculated otherwise).<br />//<br />// float *lp of dimension Nl contains the low pass wavelet filter.<br />// float *hp of dimension Nh contains the high pass wavelet filter.<br />//<br />void wav2d_inpl(float **image,int Ni,int Nj,int levs,float *lp,int Nl,<br /> float *hp,int Nh,char forw,int *shift_arr_row,int *shift_arr_col)<br /><br />{<br /> int i,dimi,dimj;<br /><br /> dimi=(forw)?NiNi>>(levs-1));<br /> dimj=(forw)?NjNj>>(levs-1));<br /><br /> for(i=0;i<levs;i++) {<br /><br /> if(forw) {<br /><br /> // Do the rows.<br /><br /> // Adjust filter parameters for overcomplete filtering.<br /> begflp=mfl+shift_arr_row; <br /> begfhp=mfh-shift_arr_row;<br /><br /> filt_n_dec_all_rows(image,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Now the columns.<br /><br /> begflp=mfl+shift_arr_col; <br /> begfhp=mfh-shift_arr_col;<br /><br /> filt_n_dec_all_cols(image,dimi,dimj,lp,Nl,hp,Nh);<br /> }<br /> else {<br /><br /> // Rows.<br /> begilp=mil+shift_arr_row[levs-1-i];<br /> begihp=mih-shift_arr_row[levs-1-i];<br /><br /> ups_n_filt_all_rows(image,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_row);<br /><br /> // Columns.<br /> begilp=mil+shift_arr_col[levs-1-i];<br /> begihp=mih-shift_arr_col[levs-1-i];<br /><br /> ups_n_filt_all_cols(image,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_col);<br /> }<br /><br /> dimi=(forw)?(dimi>>1)dimi<<1);<br /> dimj=(forw)?(dimj>>1)dimj<<1);<br /> }<br />}<br /><br /><br /><br />// 2-D "in place" wavelet packet transform.<br />// See wav2d_inpl() for an explanation of parameters.<br />//<br />// This routine will grow a full packet tree for levels upto LL_ONLY_AFTER_LEV <br />// and just a wavelet tree afterward, i.e., if levs>LL_ONLY_AFTER_LEV<br />// we grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br />// LL_ONLY_AFTER_LEV is set in wav_gen.h Just set it to some large number<br />// if you want packets all the way.<br />// <br />// Ni and Nj should be divisible by 2^levs.<br />// shift_arr_row and shift_arr_col contain the amount of shift (0 or 1)<br />// that should be applied to filters in each level.<br />// This is mainly intended for overcomplete filtering.<br />// See wav2d_inpl() comments.<br />//<br />void wavpack2d_inpl(float **image,int Ni,int Nj,int levs,float *lp,int Nl,<br /> float *hp,int Nh,char forw,int *shift_arr_row,int *shift_arr_col)<br /><br />{<br /> int i,k,l,dimi,dimj;<br /> int p,q,rcnt,ccnt;<br /> float **buffer;<br /><br /> buffer=allocate_2d_float(Ni,Nj,0);<br /><br /> dimi=(forw)?NiNi>>(levs-1));<br /> dimj=(forw)?Nj:(Nj>>(levs-1));<br /><br /> for(i=0;i<levs;i++) {<br /><br /> // Number of row bands.<br /> rcnt=Ni/dimi;<br /><br /> // Number of column bands.<br /> ccnt=Nj/dimj;<br /><br /> if(forw&&(i>=LL_ONLY_AFTER_LEV)) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /> else if((!forw)&&(levs-1-i>=LL_ONLY_AFTER_LEV)) {<br /> // Inverse wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /><br /> // Do the next level of the wavelet tree over all of<br /> // the bands we are supposed to grow on.<br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=image[p*dimi+k][q*dimj+l];<br /><br /> if(forw) {<br /><br /> // Do the rows.<br /><br /> // Adjust filter parameters for overcomplete filtering.<br /> begflp=mfl+shift_arr_row; <br /> begfhp=mfh-shift_arr_row;<br /><br /> filt_n_dec_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Now the columns.<br /> begflp=mfl+shift_arr_col; <br /> begfhp=mfh-shift_arr_col;<br /><br /> filt_n_dec_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /> }<br /> else {<br /><br /> // Rows.<br /> begilp=mil+shift_arr_row[levs-1-i];<br /> begihp=mih-shift_arr_row[levs-1-i];<br /><br /> ups_n_filt_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_row);<br /><br /> // Columns.<br /> begilp=mil+shift_arr_col[levs-1-i];<br /> begihp=mih-shift_arr_col[levs-1-i];<br /><br /> ups_n_filt_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-i,shift_arr_col);<br /> }<br /><br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> image[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /><br /> dimi=(forw)?(dimi>>1):(dimi<<1);<br /> dimj=(forw)?(dimj>>1):(dimj<<1);<br /> }<br /><br /> free_2d_float(buffer,Ni);<br />}<br /><br />// Forward complex wavelet transform using Kingsbury's paper.<br />// Please check with Nick Kingsbury's paper to confirm that<br />// I am doing things correctly here.<br />//<br />// Input is in float **im, and the results are returned in 4<br />// **float's, trf[0],...,trf[3].<br />//<br />// Ni, Nj multiples of 2^levs.<br />// levs>=1.<br />// See wav2d_inpl() for an explanation of parameters.<br />//<br />void complex_wav_forw(float **im,float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // First level, fully overcomplete resulting 4x redundancy.<br /> // Results are in trf.<br /> for(i=0;i<4;i++) {<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> trf[k][l]=im[k][l];<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Transform.<br /> wav2d_inpl(trf,Ni,Nj,1,lp,Nl,hp,Nh,1,shift_arr_r,shift_arr_c);<br /> }<br /><br /> // Now grow complex wavelets over the LL band<br /> // using Kingsbury's orthogonal bank.<br /> if(levs>1) {<br /><br /> for(i=0;i<4;i++) {<br /><br /> dimi=Ni/2;<br /> dimj=Nj/2;<br /> for(j=1;j<levs;j++) {<br /> <br /> if(i/2==0) {<br /> // Regular orth. bank.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped orth. bank (see Kingsbury).<br /> // Flipped is same as inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over rows.<br /> filt_n_dec_all_rows(trf,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> if(i%2==0) {<br /> // Regular.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over columns.<br /> filt_n_dec_all_cols(trf,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> dimi>>=1;<br /> dimj>>=1;<br /> <br /> }<br /> }<br /> }<br /><br /> // Generate the complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // After this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=trf[0][k][l]+trf[3][k][l];<br /> trf[3][k][l]=trf[0][k][l]-trf[3][k][l];<br /> trf[0][k][l]=tmp;<br /><br /> tmp=trf[1][k][l]+trf[2][k][l];<br /> // It is possible that the below is 2 - 1.<br /> trf[2][k][l]=trf[1][k][l]-trf[2][k][l];<br /> trf[1][k][l]=tmp;<br /> }<br />}<br /><br />// Inverse complex wavelet transform.<br />// trf is modified in intermediate computations.<br />// Ni, Nj multiples of 2^levs<br />// levs>=1.<br />//<br />// See complex_wav_forw() comments.<br />//<br />float **complex_wav_inv(float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /> float **im;<br /><br /><br /> // Clean the filter shift arrays.<br /> for(i=0;i<1<<levs;i++)<br /> shift_arr_r=shift_arr_c=0;<br /><br /> // Get back the intermediate wavelet coefficients from the<br /> // complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // Prior to this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=(trf[0][k][l]+trf[3][k][l])/2;<br /> trf[3][k][l]=(trf[0][k][l]-trf[3][k][l])/2;<br /> trf[0][k][l]=tmp;<br /><br /> tmp=(trf[1][k][l]+trf[2][k][l])/2;<br /> trf[2][k][l]=(trf[1][k][l]-trf[2][k][l])/2;<br /> trf[1][k][l]=tmp;<br /> }<br /><br /> if(levs>1) {<br /><br /> for(i=0;i<4;i++) {<br /> <br /> dimi=Ni>>(levs-1);<br /> dimj=Nj>>(levs-1);<br /> <br /> <br /> for(j=1;j<levs;j++) {<br /> <br /> if(i/2==0) {<br /> // Regular inverse, it just happens that orth. inverses are flipped.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over rows.<br /> ups_n_filt_all_rows(trf,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_r);<br /> <br /> <br /> if(i%2==0) {<br /> // Regular inverse.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over columns.<br /> ups_n_filt_all_cols(trf,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_c);<br /> <br /> dimi<<=1;<br /> dimj<<=1;<br /> }<br /> }<br /> }<br /><br /> // Initialize final result with zeros.<br /> im=allocate_2d_float(Ni,Nj,1);<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Now the first level.<br /> for(i=0;i<4;i++) {<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Inverse transform.<br /> wav2d_inpl(trf,Ni,Nj,1,lp,Nl,hp,Nh,0,shift_arr_r,shift_arr_c);<br /><br /> // Accumulate the results of 4x redundancy.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]+=trf[k][l];<br /><br /> }<br /><br /> // Normalize results by 4 to account for 4x redundancy accumulation.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]/=4;<br /><br /> return(im);<br />}<br /><br /><br />// Forward complex wavelet packet transform.<br />// Ni, Nj multiples of 2^levs.<br />// levs>=1.<br />//<br />// See complex_wav_forw() comments.<br />// See wavpack2d_inpl() comments for LL_ONLY_AFTER_LEV.<br />//<br />// Not fully tested. Please check with literature.<br />//<br />void complex_wav_pack_forw(float **im,float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp,**buffer;<br /> int p,q,rcnt,ccnt;<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // First level, fully overcomplete resulting 4x redundancy.<br /> // Results are in trf.<br /> for(i=0;i<4;i++) {<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> trf[k][l]=im[k][l];<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Transform.<br /> wav2d_inpl(trf,Ni,Nj,1,lp,Nl,hp,Nh,1,shift_arr_r,shift_arr_c);<br /> }<br /><br /> // Now grow using Kingsbury's orthogonal bank.<br /> if(levs>1) {<br /><br /> buffer=allocate_2d_float(Ni/2,Nj/2,0);<br /><br /> for(i=0;i<4;i++) {<br /><br /> dimi=Ni/2;<br /> dimj=Nj/2;<br /> for(j=1;j<levs;j++) {<br /><br /> // Number of row/column bands.<br /> rcnt=Ni/dimi;<br /> ccnt=Nj/dimj;<br /><br /> if(j>=LL_ONLY_AFTER_LEV) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /> <br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> // Copy data to buffer.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=trf[p*dimi+k][q*dimj+l];<br /> <br /> if(i/2==0) {<br /> // Regular orth. bank.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped orth. bank (see Kingsbury).<br /> // Flipped is same as inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over rows.<br /> filt_n_dec_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /> <br /> if(i%2==0) {<br /> // Regular.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MFLP;Nl=Nflp; <br /> hp=MFHP;Nh=Nfhp;<br /><br /> // Transform over columns.<br /> filt_n_dec_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh);<br /><br /> // Copy results to trf.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> trf[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /> <br /> dimi>>=1;<br /> dimj>>=1;<br /> <br /> }<br /> }<br /> free_2d_float(buffer,Ni/2);<br /> }<br /><br /> // Generate the complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // After this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=trf[0][k][l]+trf[3][k][l];<br /> trf[3][k][l]=trf[0][k][l]-trf[3][k][l];<br /> trf[0][k][l]=tmp;<br /><br /> tmp=trf[1][k][l]+trf[2][k][l];<br /> trf[2][k][l]=trf[1][k][l]-trf[2][k][l];<br /> trf[1][k][l]=tmp;<br /> }<br />}<br /><br />// Inverse complex wavelet packet transform.<br />// trf is modified in intermediate computations.<br />// Ni, Nj multiples of 2^levs<br />// levs>=1.<br />//<br />// See complex_wav_pack_forw() comments.<br />//<br />float **complex_wav_pack_inv(float ***trf,int Ni,int Nj,int levs)<br /><br />{<br /> int i,j,k,l;<br /> int Nl,Nh,dimi,dimj,hdimi,hdimj;<br /> float *lp,*hp;<br /> int shift_arr_r[MAX_ARR_SIZE],shift_arr_c[MAX_ARR_SIZE];<br /> float tmp;<br /> float **im,**buffer;<br /> int p,q,rcnt,ccnt;<br /><br /><br /> // Clean the filter shift arrays.<br /> for(i=0;i<1<<levs;i++)<br /> shift_arr_r=shift_arr_c=0;<br /><br /> // Get back the intermediate wavelet coefficients from the<br /> // complex wavelet coefficients.<br /> hdimi=Ni/(1<<levs);<br /> hdimj=Nj/(1<<levs);<br /><br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++) {<br /><br /> // Prior to this computation the complex wavelet coefficients<br /> // are given by trf[0]+jtrf[2] and trf[3]+jtrf[1];<br /> tmp=(trf[0][k][l]+trf[3][k][l])/2;<br /> trf[3][k][l]=(trf[0][k][l]-trf[3][k][l])/2;<br /> trf[0][k][l]=tmp;<br /><br /> tmp=(trf[1][k][l]+trf[2][k][l])/2;<br /> trf[2][k][l]=(trf[1][k][l]-trf[2][k][l])/2;<br /> trf[1][k][l]=tmp;<br /> }<br /><br /> if(levs>1) {<br /><br /> buffer=allocate_2d_float(Ni/2,Nj/2,0);<br /> for(i=0;i<4;i++) {<br /> <br /> dimi=Ni>>(levs-1);<br /> dimj=Nj>>(levs-1);<br /> <br /> <br /> for(j=1;j<levs;j++) {<br /> <br /> // Number of row/column bands.<br /> rcnt=Ni/dimi;<br /> ccnt=Nj/dimj;<br /><br /> if(j>=LL_ONLY_AFTER_LEV) {<br /> // Grow wavelets only over LL band after LL_ONLY_AFTER_LEV.<br /> rcnt=ccnt=1;<br /> }<br /><br /> for(p=0;p<rcnt;p++)<br /> for(q=0;q<ccnt;q++) {<br /><br /> // Copy data to buffer.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> buffer[k][l]=trf[p*dimi+k][q*dimj+l];<br /><br /> if(i/2==0) {<br /> // Regular inverse, it just happens that orth. inverses are flipped.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over rows.<br /> ups_n_filt_all_rows(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_r);<br /> <br /> <br /> if(i%2==0) {<br /> // Regular inverse.<br /> choose_filter('N',0);<br /> }<br /> else {<br /> // Flipped inverse.<br /> choose_filter('N',-1);<br /> }<br /> <br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Inverse transform over columns.<br /> ups_n_filt_all_cols(buffer,dimi,dimj,lp,Nl,hp,Nh,levs-1-j,shift_arr_c);<br /><br /> // Copy results to trf.<br /> for(k=0;k<dimi;k++)<br /> for(l=0;l<dimj;l++)<br /> trf[p*dimi+k][q*dimj+l]=buffer[k][l];<br /> }<br /> <br /> dimi<<=1;<br /> dimj<<=1;<br /> }<br /> }<br /><br /> free_2d_float(buffer,Ni/2);<br /> }<br /><br /> // Initialize final result with zeros.<br /> im=allocate_2d_float(Ni,Nj,1);<br /><br /> // Choose Antonini.<br /> choose_filter('A',0);<br /><br /> lp=MILP;Nl=Nilp; <br /> hp=MIHP;Nh=Nihp;<br /><br /> // Now the first level.<br /> for(i=0;i<4;i++) {<br /><br /> // Set shifts as specified by Kingsbury's paper.<br /> if(i/2==0)<br /> shift_arr_r[0]=1;<br /> else<br /> shift_arr_r[0]=0;<br /><br /> if(i%2==0)<br /> shift_arr_c[0]=1;<br /> else<br /> shift_arr_c[0]=0;<br /><br /> // Inverse transform.<br /> wav2d_inpl(trf,Ni,Nj,1,lp,Nl,hp,Nh,0,shift_arr_r,shift_arr_c);<br /><br /> // Accumulate the results of 4x redundancy.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]+=trf[k][l];<br /><br /> }<br /><br /> // Normalize results by 4 to account for 4x redundancy accumulation.<br /> for(k=0;k<Ni;k++)<br /> for(l=0;l<Nj;l++)<br /> im[k][l]/=4;<br /><br /> return(im);<br />} |
|