| 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 } |