comparison 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
comparison
equal deleted inserted replaced
76:d052ec5b742f 78:f69ae88b8be5
1 /*
2 File Name: mrdwt.c
3 Last Modification Date: %G% %U%
4 Current Version: %M% %I%
5 File Creation Date: Wed Oct 12 08:44:43 1994
6 Author: Markus Lang <lang@jazz.rice.edu>
7
8 Copyright: All software, documentation, and related files in this distribution
9 are Copyright (c) 1994 Rice University
10
11 Permission is granted for use and non-profit distribution providing that this
12 notice be clearly maintained. The right to distribute any portion for profit
13 or as part of any commercial product is specifically reserved for the author.
14
15 Change History: Fixed code such that the result has the same dimension as the
16 input for 1D problems. Also, added some standard error checking.
17 Jan Erik Odegard <odegard@ece.rice.edu> Wed Jun 14 1995
18 */
19
20 #include <math.h>
21 /*#include <malloc.h>*/
22 #include <stdio.h>
23 #include "mex.h"
24 #include "matrix.h"
25 #if !defined(_WIN32) && !defined(_WIN64)
26 #include <inttypes.h>
27 #endif
28 #define max(A,B) (A > B ? A : B)
29 #define min(A,B) (A < B ? A : B)
30 #define even(x) ((x & 1) ? 0 : 1)
31 #define isint(x) ((x - floor(x)) > 0.0 ? 0 : 1)
32
33
34 void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
35
36 {
37 double *x, *h, *yl, *yh, *Lf, *Lr;
38 intptr_t m, n, h_col, h_row, lh, L, i, po2, j;
39 double mtest, ntest;
40
41 /* check for correct # of input variables */
42 if (nrhs>3){
43 mexErrMsgTxt("There are at most 3 input parameters allowed!");
44 return;
45 }
46 if (nrhs<2){
47 mexErrMsgTxt("There are at least 2 input parameters required!");
48 return;
49 }
50 x = mxGetPr(prhs[0]);
51 n = mxGetN(prhs[0]);
52 m = mxGetM(prhs[0]);
53 h = mxGetPr(prhs[1]);
54 h_col = mxGetN(prhs[1]);
55 h_row = mxGetM(prhs[1]);
56 if (h_col>h_row)
57 lh = h_col;
58 else
59 lh = h_row;
60 if (nrhs == 3){
61 L = (intptr_t) *mxGetPr(prhs[2]);
62 if (L < 0)
63 mexErrMsgTxt("The number of levels, L, must be a non-negative integer");
64 }
65 else /* Estimate L */ {
66 i=n;j=0;
67 while (even(i)){
68 i=(i>>1);
69 j++;
70 }
71 L=m;i=0;
72 while (even(L)){
73 L=(L>>1);
74 i++;
75 }
76 if(min(m,n) == 1)
77 L = max(i,j);
78 else
79 L = min(i,j);
80 if (L==0){
81 mexErrMsgTxt("Maximum number of levels is zero; no decomposition can be performed!");
82 return;
83 }
84 }
85 /* Check the ROW dimension of input */
86 if(m > 1){
87 mtest = (double) m/pow(2.0, (double) L);
88 if (!isint(mtest))
89 mexErrMsgTxt("The matrix row dimension must be of size m*2^(L)");
90 }
91 /* Check the COLUMN dimension of input */
92 if(n > 1){
93 ntest = (double) n/pow(2.0, (double) L);
94 if (!isint(ntest))
95 mexErrMsgTxt("The matrix column dimension must be of size n*2^(L)");
96 }
97 plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL);
98 yl = mxGetPr(plhs[0]);
99 if (min(m,n) == 1)
100 plhs[1] = mxCreateDoubleMatrix(m,L*n,mxREAL);
101 else
102 plhs[1] = mxCreateDoubleMatrix(m,3*L*n,mxREAL);
103 yh = mxGetPr(plhs[1]);
104 plhs[2] = mxCreateDoubleMatrix(1,1,mxREAL);
105 Lr = mxGetPr(plhs[2]);
106 *Lr = L;
107 MRDWT(x, m, n, h, lh, L, yl, yh);
108 }
109 #define mat(a, i, j) (*(a + (m*(j)+i)))
110
111
112 #ifdef __STDC__
113 MRDWT(double *x, intptr_t m, intptr_t n, double *h, intptr_t lh, intptr_t L,
114 double *yl, double *yh)
115 #else
116 MRDWT(x, m, n, h, lh, L, yl, yh)
117 double *x, *h, *yl, *yh;
118 intptr_t m, n, lh, L;
119 #endif
120 {
121 double *tmp;
122 double *h0, *h1, *ydummyll, *ydummylh, *ydummyhl;
123 double *ydummyhh, *xdummyl , *xdummyh;
124 long i, j;
125 intptr_t actual_L, actual_m, actual_n, c_o_a, ir, n_c, n_cb, n_c_o;
126 intptr_t ic, n_r, n_rb, n_r_o, c_o_a_p2n, sample_f;
127 xdummyl = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
128 xdummyh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
129 ydummyll = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
130 ydummylh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
131 ydummyhl = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
132 ydummyhh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double));
133 h0 = (double *)(intptr_t)mxCalloc(lh,sizeof(double));
134 h1 = (double *)(intptr_t)mxCalloc(lh,sizeof(double));
135
136 if (n==1){
137 n = m;
138 m = 1;
139 }
140 /* analysis lowpass and highpass */
141 for (i=0; i<lh; i++){
142 h0[i] = h[lh-i-1];
143 h1[i] =h[i];
144 }
145 for (i=0; i<lh; i+=2)
146 h1[i] = -h1[i];
147
148 actual_m = 2*m;
149 actual_n = 2*n;
150 for (i=0; i<m*n; i++)
151 yl[i] = x[i];
152
153 /* main loop */
154 sample_f = 1;
155 for (actual_L=1; actual_L <= L; actual_L++){
156 actual_m = actual_m/2;
157 actual_n = actual_n/2;
158 /* actual (level dependent) column offset */
159 if (m==1)
160 c_o_a = n*(actual_L-1);
161 else
162 c_o_a = 3*n*(actual_L-1);
163 c_o_a_p2n = c_o_a + 2*n;
164
165 /* go by rows */
166 n_cb = n/actual_n; /* # of column blocks per row */
167 for (ir=0; ir<m; ir++){ /* loop over rows */
168 for (n_c=0; n_c<n_cb; n_c++){ /* loop within one row */
169 /* store in dummy variable */
170 ic = -sample_f + n_c;
171 for (i=0; i<actual_n; i++){
172 ic = ic + sample_f;
173 xdummyl[i] = mat(yl, ir, ic);
174 }
175 /* perform filtering lowpass/highpass */
176 fpconv(xdummyl, actual_n, h0, h1, lh, ydummyll, ydummyhh);
177 /* restore dummy variables in matrices */
178 ic = -sample_f + n_c;
179 for (i=0; i<actual_n; i++){
180 ic = ic + sample_f;
181 mat(yl, ir, ic) = ydummyll[i];
182 mat(yh, ir, c_o_a+ic) = ydummyhh[i];
183 }
184 }
185 }
186
187 /* go by columns in case of a 2D signal*/
188 if (m>1){
189 n_rb = m/actual_m; /* # of row blocks per column */
190 for (ic=0; ic<n; ic++){ /* loop over column */
191 for (n_r=0; n_r<n_rb; n_r++){ /* loop within one column */
192 /* store in dummy variables */
193 ir = -sample_f + n_r;
194 for (i=0; i<actual_m; i++){
195 ir = ir + sample_f;
196 xdummyl[i] = mat(yl, ir, ic);
197 xdummyh[i] = mat(yh, ir,c_o_a+ic);
198 }
199 /* perform filtering: first LL/LH, then HL/HH */
200 fpconv(xdummyl, actual_m, h0, h1, lh, ydummyll, ydummylh);
201 fpconv(xdummyh, actual_m, h0, h1, lh, ydummyhl, ydummyhh);
202 /* restore dummy variables in matrices */
203 ir = -sample_f + n_r;
204 for (i=0; i<actual_m; i++){
205 ir = ir + sample_f;
206 mat(yl, ir, ic) = ydummyll[i];
207 mat(yh, ir, c_o_a+ic) = ydummylh[i];
208 mat(yh, ir,c_o_a+n+ic) = ydummyhl[i];
209 mat(yh, ir, c_o_a_p2n+ic) = ydummyhh[i];
210 }
211 }
212 }
213 }
214 sample_f = sample_f*2;
215 }
216 }
217
218 #ifdef __STDC__
219 fpconv(double *x_in, intptr_t lx, double *h0, double *h1, intptr_t lh,
220 double *x_outl, double *x_outh)
221 #else
222 fpconv(x_in, lx, h0, h1, lh, x_outl, x_outh)
223 double *x_in, *h0, *h1, *x_outl, *x_outh;
224 intptr_t lx, lh;
225 #endif
226 {
227 intptr_t i, j;
228 double x0, x1;
229
230 for (i=lx; i < lx+lh-1; i++)
231 x_in[i] = x_in[i-lx];
232 for (i=0; i<lx; i++){
233 x0 = 0;
234 x1 = 0;
235 for (j=0; j<lh; j++){
236 x0 = x0 + x_in[j+i]*h0[lh-1-j];
237 x1 = x1 + x_in[j+i]*h1[lh-1-j];
238 }
239 x_outl[i] = x0;
240 x_outh[i] = x1;
241 }
242 }