ivan@78
|
1 /*
|
ivan@78
|
2 File Name: MRDWT.c
|
ivan@78
|
3 Last Modification Date: 09/21/95 15:42:59
|
ivan@78
|
4 Current Version: MRDWT.c 2.4
|
ivan@78
|
5 File Creation Date: Wed Oct 12 08:44:43 1994
|
ivan@78
|
6 Author: Markus Lang <lang@jazz.rice.edu>
|
ivan@78
|
7
|
ivan@78
|
8 Copyright (c) 2000 RICE UNIVERSITY. All rights reserved.
|
ivan@78
|
9 Created by Markus Lang, Department of ECE, Rice University.
|
ivan@78
|
10
|
ivan@78
|
11 This software is distributed and licensed to you on a non-exclusive
|
ivan@78
|
12 basis, free-of-charge. Redistribution and use in source and binary forms,
|
ivan@78
|
13 with or without modification, are permitted provided that the following
|
ivan@78
|
14 conditions are met:
|
ivan@78
|
15
|
ivan@78
|
16 1. Redistribution of source code must retain the above copyright notice,
|
ivan@78
|
17 this list of conditions and the following disclaimer.
|
ivan@78
|
18 2. Redistribution in binary form must reproduce the above copyright notice,
|
ivan@78
|
19 this list of conditions and the following disclaimer in the
|
ivan@78
|
20 documentation and/or other materials provided with the distribution.
|
ivan@78
|
21 3. All advertising materials mentioning features or use of this software
|
ivan@78
|
22 must display the following acknowledgment: This product includes
|
ivan@78
|
23 software developed by Rice University, Houston, Texas and its contributors.
|
ivan@78
|
24 4. Neither the name of the University nor the names of its contributors
|
ivan@78
|
25 may be used to endorse or promote products derived from this software
|
ivan@78
|
26 without specific prior written permission.
|
ivan@78
|
27
|
ivan@78
|
28 THIS SOFTWARE IS PROVIDED BY WILLIAM MARSH RICE UNIVERSITY, HOUSTON, TEXAS,
|
ivan@78
|
29 AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
ivan@78
|
30 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
ivan@78
|
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RICE UNIVERSITY
|
ivan@78
|
32 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
ivan@78
|
33 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
ivan@78
|
34 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
ivan@78
|
35 OR BUSINESS INTERRUPTIONS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
ivan@78
|
36 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
ivan@78
|
37 OTHERWISE), PRODUCT LIABILITY, OR OTHERWISE ARISING IN ANY WAY OUT OF THE
|
ivan@78
|
38 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ivan@78
|
39
|
ivan@78
|
40 For information on commercial licenses, contact Rice University's Office of
|
ivan@78
|
41 Technology Transfer at techtran@rice.edu or (713) 348-6173
|
ivan@78
|
42
|
ivan@78
|
43 Change History: Fixed the code such that 1D vectors passed to it can be in
|
ivan@78
|
44 either passed as a row or column vector. Also took care of
|
ivan@78
|
45 the code such that it will compile with both under standard
|
ivan@78
|
46 C compilers as well as for ANSI C compilers
|
ivan@78
|
47 Jan Erik Odegard <odegard@ece.rice.edu> Wed Jun 14 1995
|
ivan@78
|
48
|
ivan@78
|
49 MATLAB description:
|
ivan@78
|
50 %[yl,yh] = mrdwt(x,h,L);
|
ivan@78
|
51 %
|
ivan@78
|
52 % function computes the redundant discrete wavelet transform y for a 1D or
|
ivan@78
|
53 % 2D input signal . redundant means here that the subsampling after each
|
ivan@78
|
54 % stage is omitted. yl contains the lowpass and yl the highpass
|
ivan@78
|
55 % components. In case of a 2D signal the ordering in yh is [lh hl hh lh hl
|
ivan@78
|
56 % ... ] (first letter refers to row, second to column filtering).
|
ivan@78
|
57 %
|
ivan@78
|
58 % Input:
|
ivan@78
|
59 % x : finite length 1D or 2D signal (implicitely periodized)
|
ivan@78
|
60 % h : scaling filter
|
ivan@78
|
61 % L : number of levels. in case of a 1D signal length(x) must be
|
ivan@78
|
62 % divisible by 2^L; in case of a 2D signal the row and the
|
ivan@78
|
63 % column dimension must be divisible by 2^L.
|
ivan@78
|
64 %
|
ivan@78
|
65 % Output:
|
ivan@78
|
66 % yl : lowpass component
|
ivan@78
|
67 % yh : highpass components
|
ivan@78
|
68 %
|
ivan@78
|
69 % see also: mdwt, midwt, mirdwt
|
ivan@78
|
70
|
ivan@78
|
71
|
ivan@78
|
72 */
|
ivan@78
|
73
|
ivan@78
|
74 #include <math.h>
|
ivan@78
|
75 #include <stdio.h>
|
ivan@78
|
76 #include <inttypes.h>
|
ivan@78
|
77
|
ivan@78
|
78 /*#define mat(a, i, j) (a[m*(j)+i]) */
|
ivan@78
|
79 #define max(a, b) ((a) > (b) ? (a) : (b))
|
ivan@78
|
80 #define mat(a, i, j) (*(a + (m*(j)+i)))
|
ivan@78
|
81
|
ivan@78
|
82
|
ivan@78
|
83 #ifdef __STDC__
|
ivan@78
|
84 MRDWT(double *x, uintptr_t m, uintptr_t n, double *h, uintptr_t lh, uintptr_t L,
|
ivan@78
|
85 double *yl, double *yh)
|
ivan@78
|
86 #else
|
ivan@78
|
87 MRDWT(x, m, n, h, lh, L, yl, yh)
|
ivan@78
|
88 double *x, *h, *yl, *yh;
|
ivan@78
|
89 uintptr_t m, n, lh, L;
|
ivan@78
|
90 #endif
|
ivan@78
|
91 {
|
ivan@78
|
92 double *tmp;
|
ivan@78
|
93 double *h0, *h1, *ydummyll, *ydummylh, *ydummyhl;
|
ivan@78
|
94 double *ydummyhh, *xdummyl , *xdummyh;
|
ivan@78
|
95 long i, j;
|
ivan@78
|
96 uintptr_t actual_L, actual_m, actual_n, c_o_a, ir, n_c, n_cb, n_c_o;
|
ivan@78
|
97 uintptr_t ic, n_r, n_rb, n_r_o, c_o_a_p2n, sample_f;
|
ivan@78
|
98 xdummyl = (double *)(uintptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
|
ivan@78
|
99 xdummyh = (double *)(uintptr_t)mxCalloc(max(m,n)+lh-1,sizeof(double));
|
ivan@78
|
100 ydummyll = (double *)(uintptr_t)mxCalloc(max(m,n),sizeof(double));
|
ivan@78
|
101 ydummylh = (double *)(uintptr_t)mxCalloc(max(m,n),sizeof(double));
|
ivan@78
|
102 ydummyhl = (double *)(uintptr_t)mxCalloc(max(m,n),sizeof(double));
|
ivan@78
|
103 ydummyhh = (double *)(uintptr_t)mxCalloc(max(m,n),sizeof(double));
|
ivan@78
|
104 h0 = (double *)(uintptr_t)mxCalloc(lh,sizeof(double));
|
ivan@78
|
105 h1 = (double *)(uintptr_t)mxCalloc(lh,sizeof(double));
|
ivan@78
|
106
|
ivan@78
|
107 if (n==1){
|
ivan@78
|
108 n = m;
|
ivan@78
|
109 m = 1;
|
ivan@78
|
110 }
|
ivan@78
|
111 /* analysis lowpass and highpass */
|
ivan@78
|
112 for (i=0; i<lh; i++){
|
ivan@78
|
113 h0[i] = h[lh-i-1];
|
ivan@78
|
114 h1[i] =h[i];
|
ivan@78
|
115 }
|
ivan@78
|
116 for (i=0; i<lh; i+=2)
|
ivan@78
|
117 h1[i] = -h1[i];
|
ivan@78
|
118
|
ivan@78
|
119 actual_m = 2*m;
|
ivan@78
|
120 actual_n = 2*n;
|
ivan@78
|
121 for (i=0; i<m*n; i++)
|
ivan@78
|
122 yl[i] = x[i];
|
ivan@78
|
123
|
ivan@78
|
124 /* main loop */
|
ivan@78
|
125 sample_f = 1;
|
ivan@78
|
126 for (actual_L=1; actual_L <= L; actual_L++){
|
ivan@78
|
127 actual_m = actual_m/2;
|
ivan@78
|
128 actual_n = actual_n/2;
|
ivan@78
|
129 /* actual (level dependent) column offset */
|
ivan@78
|
130 if (m==1)
|
ivan@78
|
131 c_o_a = n*(actual_L-1);
|
ivan@78
|
132 else
|
ivan@78
|
133 c_o_a = 3*n*(actual_L-1);
|
ivan@78
|
134 c_o_a_p2n = c_o_a + 2*n;
|
ivan@78
|
135
|
ivan@78
|
136 /* go by rows */
|
ivan@78
|
137 n_cb = n/actual_n; /* # of column blocks per row */
|
ivan@78
|
138 for (ir=0; ir<m; ir++){ /* loop over rows */
|
ivan@78
|
139 for (n_c=0; n_c<n_cb; n_c++){ /* loop within one row */
|
ivan@78
|
140 /* store in dummy variable */
|
ivan@78
|
141 ic = -sample_f + n_c;
|
ivan@78
|
142 for (i=0; i<actual_n; i++){
|
ivan@78
|
143 ic = ic + sample_f;
|
ivan@78
|
144 xdummyl[i] = mat(yl, ir, ic);
|
ivan@78
|
145 }
|
ivan@78
|
146 /* perform filtering lowpass/highpass */
|
ivan@78
|
147 fpconv(xdummyl, actual_n, h0, h1, lh, ydummyll, ydummyhh);
|
ivan@78
|
148 /* restore dummy variables in matrices */
|
ivan@78
|
149 ic = -sample_f + n_c;
|
ivan@78
|
150 for (i=0; i<actual_n; i++){
|
ivan@78
|
151 ic = ic + sample_f;
|
ivan@78
|
152 mat(yl, ir, ic) = ydummyll[i];
|
ivan@78
|
153 mat(yh, ir, c_o_a+ic) = ydummyhh[i];
|
ivan@78
|
154 }
|
ivan@78
|
155 }
|
ivan@78
|
156 }
|
ivan@78
|
157
|
ivan@78
|
158 /* go by columns in case of a 2D signal*/
|
ivan@78
|
159 if (m>1){
|
ivan@78
|
160 n_rb = m/actual_m; /* # of row blocks per column */
|
ivan@78
|
161 for (ic=0; ic<n; ic++){ /* loop over column */
|
ivan@78
|
162 for (n_r=0; n_r<n_rb; n_r++){ /* loop within one column */
|
ivan@78
|
163 /* store in dummy variables */
|
ivan@78
|
164 ir = -sample_f + n_r;
|
ivan@78
|
165 for (i=0; i<actual_m; i++){
|
ivan@78
|
166 ir = ir + sample_f;
|
ivan@78
|
167 xdummyl[i] = mat(yl, ir, ic);
|
ivan@78
|
168 xdummyh[i] = mat(yh, ir,c_o_a+ic);
|
ivan@78
|
169 }
|
ivan@78
|
170 /* perform filtering: first LL/LH, then HL/HH */
|
ivan@78
|
171 fpconv(xdummyl, actual_m, h0, h1, lh, ydummyll, ydummylh);
|
ivan@78
|
172 fpconv(xdummyh, actual_m, h0, h1, lh, ydummyhl, ydummyhh);
|
ivan@78
|
173 /* restore dummy variables in matrices */
|
ivan@78
|
174 ir = -sample_f + n_r;
|
ivan@78
|
175 for (i=0; i<actual_m; i++){
|
ivan@78
|
176 ir = ir + sample_f;
|
ivan@78
|
177 mat(yl, ir, ic) = ydummyll[i];
|
ivan@78
|
178 mat(yh, ir, c_o_a+ic) = ydummylh[i];
|
ivan@78
|
179 mat(yh, ir,c_o_a+n+ic) = ydummyhl[i];
|
ivan@78
|
180 mat(yh, ir, c_o_a_p2n+ic) = ydummyhh[i];
|
ivan@78
|
181 }
|
ivan@78
|
182 }
|
ivan@78
|
183 }
|
ivan@78
|
184 }
|
ivan@78
|
185 sample_f = sample_f*2;
|
ivan@78
|
186 }
|
ivan@78
|
187 }
|
ivan@78
|
188
|
ivan@78
|
189 #ifdef __STDC__
|
ivan@78
|
190 fpconv(double *x_in, uintptr_t lx, double *h0, double *h1, uintptr_t lh,
|
ivan@78
|
191 double *x_outl, double *x_outh)
|
ivan@78
|
192 #else
|
ivan@78
|
193 fpconv(x_in, lx, h0, h1, lh, x_outl, x_outh)
|
ivan@78
|
194 double *x_in, *h0, *h1, *x_outl, *x_outh;
|
ivan@78
|
195 uintptr_t lx, lh;
|
ivan@78
|
196 #endif
|
ivan@78
|
197 {
|
ivan@78
|
198 uintptr_t i, j;
|
ivan@78
|
199 double x0, x1;
|
ivan@78
|
200
|
ivan@78
|
201 for (i=lx; i < lx+lh-1; i++)
|
ivan@78
|
202 x_in[i] = x_in[i-lx];
|
ivan@78
|
203 for (i=0; i<lx; i++){
|
ivan@78
|
204 x0 = 0;
|
ivan@78
|
205 x1 = 0;
|
ivan@78
|
206 for (j=0; j<lh; j++){
|
ivan@78
|
207 x0 = x0 + x_in[j+i]*h0[lh-1-j];
|
ivan@78
|
208 x1 = x1 + x_in[j+i]*h1[lh-1-j];
|
ivan@78
|
209 }
|
ivan@78
|
210 x_outl[i] = x0;
|
ivan@78
|
211 x_outh[i] = x1;
|
ivan@78
|
212 }
|
ivan@78
|
213 }
|