ivan@78
|
1 /*
|
ivan@78
|
2 File Name: MIDWT.c
|
ivan@78
|
3 Last Modification Date: 06/14/95 13:01:15
|
ivan@78
|
4 Current Version: MIDWT.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 Fix minor bug to allow maximum number of levels
|
ivan@78
|
50
|
ivan@78
|
51 decription of the matlab call:
|
ivan@78
|
52 %y = midwt(x,h,L);
|
ivan@78
|
53 %
|
ivan@78
|
54 % function computes the inverse discrete wavelet transform y for a 1D or 2D
|
ivan@78
|
55 % input signal x.
|
ivan@78
|
56 %
|
ivan@78
|
57 % Input:
|
ivan@78
|
58 % x : finite length 1D or 2D input signal (implicitely periodized)
|
ivan@78
|
59 % h : scaling filter
|
ivan@78
|
60 % L : number of levels. in case of a 1D signal length(x) must be
|
ivan@78
|
61 % divisible by 2^L; in case of a 2D signal the row and the
|
ivan@78
|
62 % column dimension must be divisible by 2^L.
|
ivan@78
|
63 %
|
ivan@78
|
64 % see also: mdwt, mrdwt, mirdwt
|
ivan@78
|
65
|
ivan@78
|
66 */
|
ivan@78
|
67
|
ivan@78
|
68 #include <math.h>
|
ivan@78
|
69 #include <stdio.h>
|
ivan@78
|
70 #include <inttypes.h>
|
ivan@78
|
71
|
ivan@78
|
72 #define max(A,B) (A > B ? A : B)
|
ivan@78
|
73 #define mat(a, i, j) (*(a + (m*(j)+i))) /* macro for matrix indices */
|
ivan@78
|
74
|
ivan@78
|
75
|
ivan@78
|
76 #ifdef __STDC__
|
ivan@78
|
77 MIDWT(double *x, uintptr_t m, uintptr_t n, double *h, uintptr_t lh, uintptr_t L, double *y)
|
ivan@78
|
78 #else
|
ivan@78
|
79 MIDWT(x, m, n, h, lh, L, y)
|
ivan@78
|
80 double *x, *h, *y;
|
ivan@78
|
81 uintptr_t m, n, lh, L;
|
ivan@78
|
82 #endif
|
ivan@78
|
83 {
|
ivan@78
|
84 double *g0, *g1, *ydummyl, *ydummyh, *xdummy;
|
ivan@78
|
85 uintptr_t i, j;
|
ivan@78
|
86 uintptr_t actual_L, actual_m, actual_n, r_o_a, c_o_a, ir, ic, lhm1, lhhm1, sample_f;
|
ivan@78
|
87 xdummy = (double *)(uintptr_t)mxCalloc(max(m,n),sizeof(double));
|
ivan@78
|
88 ydummyl = (double *)(uintptr_t)mxCalloc(max(m,n)+lh/2-1,sizeof(double));
|
ivan@78
|
89 ydummyh = (double *)(uintptr_t)mxCalloc(max(m,n)+lh/2-1,sizeof(double));
|
ivan@78
|
90 g0 = (double *)(uintptr_t)mxCalloc(lh,sizeof(double));
|
ivan@78
|
91 g1 = (double *)(uintptr_t)mxCalloc(lh,sizeof(double));
|
ivan@78
|
92
|
ivan@78
|
93 if (n==1){
|
ivan@78
|
94 n = m;
|
ivan@78
|
95 m = 1;
|
ivan@78
|
96 }
|
ivan@78
|
97 /* synthesis lowpass and highpass */
|
ivan@78
|
98 for (i=0; i<lh; i++){
|
ivan@78
|
99 g0[i] = h[i];
|
ivan@78
|
100 g1[i] = h[lh-i-1];
|
ivan@78
|
101 }
|
ivan@78
|
102 for (i=1; i<=lh; i+=2)
|
ivan@78
|
103 g1[i] = -g1[i];
|
ivan@78
|
104
|
ivan@78
|
105 lhm1 = lh - 1;
|
ivan@78
|
106 lhhm1 = lh/2 - 1;
|
ivan@78
|
107 /* 2^L */
|
ivan@78
|
108 sample_f = 1;
|
ivan@78
|
109 for (i=1; i<L; i++)
|
ivan@78
|
110 sample_f = sample_f*2;
|
ivan@78
|
111
|
ivan@78
|
112 if (m>1)
|
ivan@78
|
113 actual_m = m/sample_f;
|
ivan@78
|
114 else
|
ivan@78
|
115 actual_m = 1;
|
ivan@78
|
116 actual_n = n/sample_f;
|
ivan@78
|
117
|
ivan@78
|
118 for (i=0; i<(m*n); i++)
|
ivan@78
|
119 x[i] = y[i];
|
ivan@78
|
120
|
ivan@78
|
121 /* main loop */
|
ivan@78
|
122 for (actual_L=L; actual_L >= 1; actual_L--){
|
ivan@78
|
123 r_o_a = actual_m/2;
|
ivan@78
|
124 c_o_a = actual_n/2;
|
ivan@78
|
125
|
ivan@78
|
126 /* go by columns in case of a 2D signal*/
|
ivan@78
|
127 if (m>1){
|
ivan@78
|
128 for (ic=0; ic<actual_n; ic++){ /* loop over column */
|
ivan@78
|
129 /* store in dummy variables */
|
ivan@78
|
130 ir = r_o_a;
|
ivan@78
|
131 for (i=0; i<r_o_a; i++){
|
ivan@78
|
132 ydummyl[i+lhhm1] = mat(x, i, ic);
|
ivan@78
|
133 ydummyh[i+lhhm1] = mat(x, ir++, ic);
|
ivan@78
|
134 }
|
ivan@78
|
135 /* perform filtering lowpass and highpass*/
|
ivan@78
|
136 bpsconv(xdummy, r_o_a, g0, g1, lhm1, lhhm1, ydummyl, ydummyh);
|
ivan@78
|
137 /* restore dummy variables in matrix */
|
ivan@78
|
138 for (i=0; i<actual_m; i++)
|
ivan@78
|
139 mat(x, i, ic) = xdummy[i];
|
ivan@78
|
140 }
|
ivan@78
|
141 }
|
ivan@78
|
142 /* go by rows */
|
ivan@78
|
143 for (ir=0; ir<actual_m; ir++){ /* loop over rows */
|
ivan@78
|
144 /* store in dummy variable */
|
ivan@78
|
145 ic = c_o_a;
|
ivan@78
|
146 for (i=0; i<c_o_a; i++){
|
ivan@78
|
147 ydummyl[i+lhhm1] = mat(x, ir, i);
|
ivan@78
|
148 ydummyh[i+lhhm1] = mat(x, ir, ic++);
|
ivan@78
|
149 }
|
ivan@78
|
150 /* perform filtering lowpass and highpass*/
|
ivan@78
|
151 bpsconv(xdummy, c_o_a, g0, g1, lhm1, lhhm1, ydummyl, ydummyh);
|
ivan@78
|
152 /* restore dummy variables in matrices */
|
ivan@78
|
153 for (i=0; i<actual_n; i++)
|
ivan@78
|
154 mat(x, ir, i) = xdummy[i];
|
ivan@78
|
155 }
|
ivan@78
|
156 if (m==1)
|
ivan@78
|
157 actual_m = 1;
|
ivan@78
|
158 else
|
ivan@78
|
159 actual_m = actual_m*2;
|
ivan@78
|
160 actual_n = actual_n*2;
|
ivan@78
|
161 }
|
ivan@78
|
162 }
|
ivan@78
|
163
|
ivan@78
|
164 #ifdef __STDC__
|
ivan@78
|
165 bpsconv(double *x_out, uintptr_t lx, double *g0, double *g1, uintptr_t lhm1,
|
ivan@78
|
166 uintptr_t lhhm1, double *x_inl, double *x_inh)
|
ivan@78
|
167 #else
|
ivan@78
|
168 bpsconv(x_out, lx, g0, g1, lhm1, lhhm1, x_inl, x_inh)
|
ivan@78
|
169 double *x_inl, *x_inh, *g0, *g1, *x_out;
|
ivan@78
|
170 uintptr_t lx, lhm1, lhhm1;
|
ivan@78
|
171 #endif
|
ivan@78
|
172 {
|
ivan@78
|
173 uintptr_t i, j, ind, tj;
|
ivan@78
|
174 double x0, x1;
|
ivan@78
|
175
|
ivan@78
|
176 for (i=lhhm1-1; i > -1; i--){
|
ivan@78
|
177 x_inl[i] = x_inl[lx+i];
|
ivan@78
|
178 x_inh[i] = x_inh[lx+i];
|
ivan@78
|
179 }
|
ivan@78
|
180 ind = 0;
|
ivan@78
|
181 for (i=0; i<(lx); i++){
|
ivan@78
|
182 x0 = 0;
|
ivan@78
|
183 x1 = 0;
|
ivan@78
|
184 tj = -2;
|
ivan@78
|
185 for (j=0; j<=lhhm1; j++){
|
ivan@78
|
186 tj+=2;
|
ivan@78
|
187 x0 = x0 + x_inl[i+j]*g0[lhm1-1-tj] + x_inh[i+j]*g1[lhm1-1-tj] ;
|
ivan@78
|
188 x1 = x1 + x_inl[i+j]*g0[lhm1-tj] + x_inh[i+j]*g1[lhm1-tj] ;
|
ivan@78
|
189 }
|
ivan@78
|
190 x_out[ind++] = x0;
|
ivan@78
|
191 x_out[ind++] = x1;
|
ivan@78
|
192 }
|
ivan@78
|
193 }
|