Mercurial > hg > smallbox
diff util/Rice Wavelet Toolbox/mrdwt.c @ 78:f69ae88b8be5
added Rice Wavelet Toolbox with my modification, so it can be compiled on newer systems.
author | Ivan Damnjanovic lnx <ivan.damnjanovic@eecs.qmul.ac.uk> |
---|---|
date | Fri, 25 Mar 2011 15:27:33 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/Rice Wavelet Toolbox/mrdwt.c Fri Mar 25 15:27:33 2011 +0000 @@ -0,0 +1,242 @@ +/* +File Name: mrdwt.c +Last Modification Date: %G% %U% +Current Version: %M% %I% +File Creation Date: Wed Oct 12 08:44:43 1994 +Author: Markus Lang <lang@jazz.rice.edu> + +Copyright: All software, documentation, and related files in this distribution + are Copyright (c) 1994 Rice University + +Permission is granted for use and non-profit distribution providing that this +notice be clearly maintained. The right to distribute any portion for profit +or as part of any commercial product is specifically reserved for the author. + +Change History: Fixed code such that the result has the same dimension as the + input for 1D problems. Also, added some standard error checking. + Jan Erik Odegard <odegard@ece.rice.edu> Wed Jun 14 1995 +*/ + +#include <math.h> +/*#include <malloc.h>*/ +#include <stdio.h> +#include "mex.h" +#include "matrix.h" +#if !defined(_WIN32) && !defined(_WIN64) +#include <inttypes.h> +#endif +#define max(A,B) (A > B ? A : B) +#define min(A,B) (A < B ? A : B) +#define even(x) ((x & 1) ? 0 : 1) +#define isint(x) ((x - floor(x)) > 0.0 ? 0 : 1) + + +void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) + +{ + double *x, *h, *yl, *yh, *Lf, *Lr; + intptr_t m, n, h_col, h_row, lh, L, i, po2, j; + double mtest, ntest; + + /* check for correct # of input variables */ + if (nrhs>3){ + mexErrMsgTxt("There are at most 3 input parameters allowed!"); + return; + } + if (nrhs<2){ + mexErrMsgTxt("There are at least 2 input parameters required!"); + return; + } + x = mxGetPr(prhs[0]); + n = mxGetN(prhs[0]); + m = mxGetM(prhs[0]); + h = mxGetPr(prhs[1]); + h_col = mxGetN(prhs[1]); + h_row = mxGetM(prhs[1]); + if (h_col>h_row) + lh = h_col; + else + lh = h_row; + if (nrhs == 3){ + L = (intptr_t) *mxGetPr(prhs[2]); + if (L < 0) + mexErrMsgTxt("The number of levels, L, must be a non-negative integer"); + } + else /* Estimate L */ { + i=n;j=0; + while (even(i)){ + i=(i>>1); + j++; + } + L=m;i=0; + while (even(L)){ + L=(L>>1); + i++; + } + if(min(m,n) == 1) + L = max(i,j); + else + L = min(i,j); + if (L==0){ + mexErrMsgTxt("Maximum number of levels is zero; no decomposition can be performed!"); + return; + } + } + /* Check the ROW dimension of input */ + if(m > 1){ + mtest = (double) m/pow(2.0, (double) L); + if (!isint(mtest)) + mexErrMsgTxt("The matrix row dimension must be of size m*2^(L)"); + } + /* Check the COLUMN dimension of input */ + if(n > 1){ + ntest = (double) n/pow(2.0, (double) L); + if (!isint(ntest)) + mexErrMsgTxt("The matrix column dimension must be of size n*2^(L)"); + } + plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL); + yl = mxGetPr(plhs[0]); + if (min(m,n) == 1) + plhs[1] = mxCreateDoubleMatrix(m,L*n,mxREAL); + else + plhs[1] = mxCreateDoubleMatrix(m,3*L*n,mxREAL); + yh = mxGetPr(plhs[1]); + plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL); + Lr = mxGetPr(plhs[2]); + *Lr = L; + MRDWT(x, m, n, h, lh, L, yl, yh); +} +#define mat(a, i, j) (*(a + (m*(j)+i))) + + +#ifdef __STDC__ +MRDWT(double *x, intptr_t m, intptr_t n, double *h, intptr_t lh, intptr_t L, + double *yl, double *yh) +#else +MRDWT(x, m, n, h, lh, L, yl, yh) +double *x, *h, *yl, *yh; +intptr_t m, n, lh, L; +#endif +{ + double *tmp; + double *h0, *h1, *ydummyll, *ydummylh, *ydummyhl; + double *ydummyhh, *xdummyl , *xdummyh; + long i, j; + intptr_t actual_L, actual_m, actual_n, c_o_a, ir, n_c, n_cb, n_c_o; + intptr_t ic, n_r, n_rb, n_r_o, c_o_a_p2n, sample_f; + xdummyl = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); + xdummyh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); + ydummyll = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); + ydummylh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); + ydummyhl = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); + ydummyhh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); + h0 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); + h1 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); + + if (n==1){ + n = m; + m = 1; + } + /* analysis lowpass and highpass */ + for (i=0; i<lh; i++){ + h0[i] = h[lh-i-1]; + h1[i] =h[i]; + } + for (i=0; i<lh; i+=2) + h1[i] = -h1[i]; + + actual_m = 2*m; + actual_n = 2*n; + for (i=0; i<m*n; i++) + yl[i] = x[i]; + + /* main loop */ + sample_f = 1; + for (actual_L=1; actual_L <= L; actual_L++){ + actual_m = actual_m/2; + actual_n = actual_n/2; + /* actual (level dependent) column offset */ + if (m==1) + c_o_a = n*(actual_L-1); + else + c_o_a = 3*n*(actual_L-1); + c_o_a_p2n = c_o_a + 2*n; + + /* go by rows */ + n_cb = n/actual_n; /* # of column blocks per row */ + for (ir=0; ir<m; ir++){ /* loop over rows */ + for (n_c=0; n_c<n_cb; n_c++){ /* loop within one row */ + /* store in dummy variable */ + ic = -sample_f + n_c; + for (i=0; i<actual_n; i++){ + ic = ic + sample_f; + xdummyl[i] = mat(yl, ir, ic); + } + /* perform filtering lowpass/highpass */ + fpconv(xdummyl, actual_n, h0, h1, lh, ydummyll, ydummyhh); + /* restore dummy variables in matrices */ + ic = -sample_f + n_c; + for (i=0; i<actual_n; i++){ + ic = ic + sample_f; + mat(yl, ir, ic) = ydummyll[i]; + mat(yh, ir, c_o_a+ic) = ydummyhh[i]; + } + } + } + + /* go by columns in case of a 2D signal*/ + if (m>1){ + n_rb = m/actual_m; /* # of row blocks per column */ + for (ic=0; ic<n; ic++){ /* loop over column */ + for (n_r=0; n_r<n_rb; n_r++){ /* loop within one column */ + /* store in dummy variables */ + ir = -sample_f + n_r; + for (i=0; i<actual_m; i++){ + ir = ir + sample_f; + xdummyl[i] = mat(yl, ir, ic); + xdummyh[i] = mat(yh, ir,c_o_a+ic); + } + /* perform filtering: first LL/LH, then HL/HH */ + fpconv(xdummyl, actual_m, h0, h1, lh, ydummyll, ydummylh); + fpconv(xdummyh, actual_m, h0, h1, lh, ydummyhl, ydummyhh); + /* restore dummy variables in matrices */ + ir = -sample_f + n_r; + for (i=0; i<actual_m; i++){ + ir = ir + sample_f; + mat(yl, ir, ic) = ydummyll[i]; + mat(yh, ir, c_o_a+ic) = ydummylh[i]; + mat(yh, ir,c_o_a+n+ic) = ydummyhl[i]; + mat(yh, ir, c_o_a_p2n+ic) = ydummyhh[i]; + } + } + } + } + sample_f = sample_f*2; + } +} + +#ifdef __STDC__ +fpconv(double *x_in, intptr_t lx, double *h0, double *h1, intptr_t lh, + double *x_outl, double *x_outh) +#else +fpconv(x_in, lx, h0, h1, lh, x_outl, x_outh) +double *x_in, *h0, *h1, *x_outl, *x_outh; +intptr_t lx, lh; +#endif +{ + intptr_t i, j; + double x0, x1; + + for (i=lx; i < lx+lh-1; i++) + x_in[i] = x_in[i-lx]; + for (i=0; i<lx; i++){ + x0 = 0; + x1 = 0; + for (j=0; j<lh; j++){ + x0 = x0 + x_in[j+i]*h0[lh-1-j]; + x1 = x1 + x_in[j+i]*h1[lh-1-j]; + } + x_outl[i] = x0; + x_outh[i] = x1; + } +}