Mercurial > hg > smallbox
comparison util/Rice Wavelet Toolbox/mirdwt.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: mirdwt.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 | |
21 #include <math.h> | |
22 /*#include <malloc.h>*/ | |
23 #include <stdio.h> | |
24 #include "mex.h" | |
25 #include "matrix.h" | |
26 #if !defined(_WIN32) && !defined(_WIN64) | |
27 #include <inttypes.h> | |
28 #endif | |
29 #define max(A,B) (A > B ? A : B) | |
30 #define min(A,B) (A < B ? A : B) | |
31 #define even(x) ((x & 1) ? 0 : 1) | |
32 #define isint(x) ((x - floor(x)) > 0.0 ? 0 : 1) | |
33 | |
34 | |
35 void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]) | |
36 | |
37 { | |
38 double *x, *h, *yl, *yh, *Lf, *Lr; | |
39 intptr_t m, n, mh, nh, h_col, h_row, lh, L, i, po2, j; | |
40 double mtest, ntest; | |
41 | |
42 /* check for correct # of input variables */ | |
43 if (nrhs>4){ | |
44 mexErrMsgTxt("There are at most 4 input parameters allowed!"); | |
45 return; | |
46 } | |
47 if (nrhs<3){ | |
48 mexErrMsgTxt("There are at least 3 input parameters required!"); | |
49 return; | |
50 } | |
51 yl = mxGetPr(prhs[0]); | |
52 n = mxGetN(prhs[0]); | |
53 m = mxGetM(prhs[0]); | |
54 yh = mxGetPr(prhs[1]); | |
55 nh = mxGetN(prhs[1]); | |
56 mh = mxGetM(prhs[1]); | |
57 h = mxGetPr(prhs[2]); | |
58 h_col = mxGetN(prhs[2]); | |
59 h_row = mxGetM(prhs[2]); | |
60 if (h_col>h_row) | |
61 lh = h_col; | |
62 else | |
63 lh = h_row; | |
64 if (nrhs == 4){ | |
65 L = (intptr_t) *mxGetPr(prhs[3]); | |
66 if (L < 0) | |
67 mexErrMsgTxt("The number of levels, L, must be a non-negative integer"); | |
68 } | |
69 else /* Estimate L */ { | |
70 i=n;j=0; | |
71 while (even(i)){ | |
72 i=(i>>1); | |
73 j++; | |
74 } | |
75 L=m;i=0; | |
76 while (even(L)){ | |
77 L=(L>>1); | |
78 i++; | |
79 } | |
80 if(min(m,n) == 1) | |
81 L = max(i,j); | |
82 else | |
83 L = min(i,j); | |
84 if (L==0){ | |
85 mexErrMsgTxt("Maximum number of levels is zero; no decomposition can be performed!"); | |
86 return; | |
87 } | |
88 } | |
89 /* check for consistency of rows and columns of yl, yh */ | |
90 if (min(m,n) > 1){ | |
91 if((m != mh) | (3*n*L != nh)){ | |
92 mexErrMsgTxt("Dimensions of first two input matrices not consistent!"); | |
93 return; | |
94 } | |
95 } | |
96 else{ | |
97 if((m != mh) | (n*L != nh)){ | |
98 mexErrMsgTxt("Dimensions of first two input vectors not consistent!");{ | |
99 return; | |
100 } | |
101 } | |
102 } | |
103 /* Check the ROW dimension of input */ | |
104 if(m > 1){ | |
105 mtest = (double) m/pow(2.0, (double) L); | |
106 if (!isint(mtest)) | |
107 mexErrMsgTxt("The matrix row dimension must be of size m*2^(L)"); | |
108 } | |
109 /* Check the COLUMN dimension of input */ | |
110 if(n > 1){ | |
111 ntest = (double) n/pow(2.0, (double) L); | |
112 if (!isint(ntest)) | |
113 mexErrMsgTxt("The matrix column dimension must be of size n*2^(L)"); | |
114 } | |
115 plhs[0] = mxCreateDoubleMatrix(m,n,mxREAL); | |
116 x = mxGetPr(plhs[0]); | |
117 plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL); | |
118 Lr = mxGetPr(plhs[1]); | |
119 *Lr = L; | |
120 MIRDWT(x, m, n, h, lh, L, yl, yh); | |
121 } | |
122 #define mat(a, i, j) (*(a + (m*(j)+i))) /* macro for matrix indices */ | |
123 | |
124 #ifdef __STDC__ | |
125 MIRDWT(double *x, intptr_t m, intptr_t n, double *h, intptr_t lh, intptr_t L, | |
126 double *yl, double *yh) | |
127 #else | |
128 MIRDWT(x, m, n, h, lh, L, yl, yh) | |
129 double *x, *h, *yl, *yh; | |
130 intptr_t m, n, lh, L; | |
131 #endif | |
132 { | |
133 double *g0, *g1, *ydummyll, *ydummylh, *ydummyhl; | |
134 double *ydummyhh, *xdummyl , *xdummyh, *xh; | |
135 intptr_t i, j; | |
136 intptr_t actual_L, actual_m, actual_n, c_o_a, ir, n_c, n_cb, n_c_o, lhm1; | |
137 intptr_t ic, n_r, n_rb, n_r_o, c_o_a_p2n, sample_f; | |
138 xh = (double *)(intptr_t)mxCalloc(m*n,sizeof(double)); | |
139 xdummyl = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); | |
140 xdummyh = (double *)(intptr_t)mxCalloc(max(m,n),sizeof(double)); | |
141 ydummyll = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); | |
142 ydummylh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); | |
143 ydummyhl = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); | |
144 ydummyhh = (double *)(intptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double)); | |
145 g0 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); | |
146 g1 = (double *)(intptr_t)mxCalloc(lh,sizeof(double)); | |
147 | |
148 if (n==1){ | |
149 n = m; | |
150 m = 1; | |
151 } | |
152 /* analysis lowpass and highpass */ | |
153 for (i=0; i<lh; i++){ | |
154 g0[i] = h[i]/2; | |
155 g1[i] = h[lh-i-1]/2; | |
156 } | |
157 for (i=1; i<=lh; i+=2) | |
158 g1[i] = -g1[i]; | |
159 | |
160 lhm1 = lh - 1; | |
161 /* 2^L */ | |
162 sample_f = 1; | |
163 for (i=1; i<L; i++) | |
164 sample_f = sample_f*2; | |
165 actual_m = m/sample_f; | |
166 actual_n = n/sample_f; | |
167 /* restore yl in x */ | |
168 for (i=0;i<m*n;i++) | |
169 x[i] = yl[i]; | |
170 | |
171 /* main loop */ | |
172 for (actual_L=L; actual_L >= 1; actual_L--){ | |
173 /* actual (level dependent) column offset */ | |
174 if (m==1) | |
175 c_o_a = n*(actual_L-1); | |
176 else | |
177 c_o_a = 3*n*(actual_L-1); | |
178 c_o_a_p2n = c_o_a + 2*n; | |
179 | |
180 /* go by columns in case of a 2D signal*/ | |
181 if (m>1){ | |
182 n_rb = m/actual_m; /* # of row blocks per column */ | |
183 for (ic=0; ic<n; ic++){ /* loop over column */ | |
184 for (n_r=0; n_r<n_rb; n_r++){ /* loop within one column */ | |
185 /* store in dummy variables */ | |
186 ir = -sample_f + n_r; | |
187 for (i=0; i<actual_m; i++){ | |
188 ir = ir + sample_f; | |
189 ydummyll[i+lhm1] = mat(x, ir, ic); | |
190 ydummylh[i+lhm1] = mat(yh, ir, c_o_a+ic); | |
191 ydummyhl[i+lhm1] = mat(yh, ir,c_o_a+n+ic); | |
192 ydummyhh[i+lhm1] = mat(yh, ir, c_o_a_p2n+ic); | |
193 } | |
194 /* perform filtering and adding: first LL/LH, then HL/HH */ | |
195 bpconv(xdummyl, actual_m, g0, g1, lh, ydummyll, ydummylh); | |
196 bpconv(xdummyh, actual_m, g0, g1, lh, ydummyhl, ydummyhh); | |
197 /* store dummy variables in matrices */ | |
198 ir = -sample_f + n_r; | |
199 for (i=0; i<actual_m; i++){ | |
200 ir = ir + sample_f; | |
201 mat(x, ir, ic) = xdummyl[i]; | |
202 mat(xh, ir, ic) = xdummyh[i]; | |
203 } | |
204 } | |
205 } | |
206 } | |
207 | |
208 /* go by rows */ | |
209 n_cb = n/actual_n; /* # of column blocks per row */ | |
210 for (ir=0; ir<m; ir++){ /* loop over rows */ | |
211 for (n_c=0; n_c<n_cb; n_c++){ /* loop within one row */ | |
212 /* store in dummy variable */ | |
213 ic = -sample_f + n_c; | |
214 for (i=0; i<actual_n; i++){ | |
215 ic = ic + sample_f; | |
216 ydummyll[i+lhm1] = mat(x, ir, ic); | |
217 if (m>1) | |
218 ydummyhh[i+lhm1] = mat(xh, ir, ic); | |
219 else | |
220 ydummyhh[i+lhm1] = mat(yh, ir, c_o_a+ic); | |
221 } | |
222 /* perform filtering lowpass/highpass */ | |
223 bpconv(xdummyl, actual_n, g0, g1, lh, ydummyll, ydummyhh); | |
224 /* restore dummy variables in matrices */ | |
225 ic = -sample_f + n_c; | |
226 for (i=0; i<actual_n; i++){ | |
227 ic = ic + sample_f; | |
228 mat(x, ir, ic) = xdummyl[i]; | |
229 } | |
230 } | |
231 } | |
232 sample_f = sample_f/2; | |
233 actual_m = actual_m*2; | |
234 actual_n = actual_n*2; | |
235 } | |
236 } | |
237 | |
238 #ifdef __STDC__ | |
239 bpconv(double *x_out, intptr_t lx, double *g0, double *g1, intptr_t lh, | |
240 double *x_inl, double *x_inh) | |
241 #else | |
242 bpconv(x_out, lx, g0, g1, lh, x_inl, x_inh) | |
243 double *x_inl, *x_inh, *g0, *g1, *x_out; | |
244 intptr_t lx, lh; | |
245 #endif | |
246 { | |
247 intptr_t i, j; | |
248 double x0; | |
249 | |
250 for (i=lh-2; i > -1; i--){ | |
251 x_inl[i] = x_inl[lx+i]; | |
252 x_inh[i] = x_inh[lx+i]; | |
253 } | |
254 for (i=0; i<lx; i++){ | |
255 x0 = 0; | |
256 for (j=0; j<lh; j++) | |
257 x0 = x0 + x_inl[j+i]*g0[lh-1-j] + | |
258 x_inh[j+i]*g1[lh-1-j]; | |
259 x_out[i] = x0; | |
260 } | |
261 } |