home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
APR94_1.ZIP
/
WAVE3.ASC
< prev
Wrap
Text File
|
1994-02-27
|
11KB
|
226 lines
_The Wavelet Packet Transform_
by Mac A. Cody
Listing One
/* CONVOLVE.C */
/* Copyright (C) 1993 Mac A. Cody - All rights reserved */
#include "convolve.h"
/* DualConvDec2 - Convolution of data array with decomposition filters
followed by decimation by two.
Input(s): REAL_TYPE *src - Pointer to source data sample array.
REAL_TYPE *htilda - Pointer to lowpass filter array.
REAL_TYPE *gtilda - Pointer to highpass filter array.
short srclen - length of source data array.
short filtlen - length of filter arrays.
Output(s): REAL_TYPE *adst - Pointer to approximation data sample array.
REAL_TYPE *ddst - Pointer to detail data sample array.
*/
void DualConvDec2(REAL_TYPE *src, REAL_TYPE *adst, REAL_TYPE *ddst,
REAL_TYPE *htilda, REAL_TYPE *gtilda, short srclen, short filtlen)
{
short i, j, brklen, endlen;
REAL_TYPE adot_p, ddot_p;
REAL_TYPE *head_src, *lp_fltr, *hp_fltr;
brklen = 1; /* initial break in dot product is after first element */
/* perform truncated dot products until filter no longer hangs off end of
array; decimation by two handled by two-element shift; break count
increases by two on every iteration */
for(j = 0; j < filtlen; j += 2, brklen += 2)
{
head_src = src + j; /* point to appropriate initial element at head */
lp_fltr = htilda; /* set up pointer to lowpass filter */
hp_fltr = gtilda; /* set up pointer to highpass filter */
adot_p = *head_src * *lp_fltr++; /* initial lowpass product of head */
ddot_p = *head_src-- * *hp_fltr++; /* initial highpass product of head */
for(i = 1; i < brklen; i++) /* perform remaining products of head */
{
adot_p += *head_src * *lp_fltr++;
ddot_p += *head_src-- * *hp_fltr++;
}
*adst++ = adot_p; /* save the completed lowpass dot product */
*ddst++ = ddot_p; /* save the completed highpass dot product */
}
endlen = srclen + filtlen - 2; /* find total length of array */
/* perform convolution to the physical end of the array
with a simple dot product loop */
for(; j <= endlen; j += 2)
{
head_src = src + j; /* point to appropriate initial element at head */
lp_fltr = htilda; /* set up pointer to lowpass filter */
hp_fltr = gtilda; /* set up pointer to highpass filter */
adot_p = *head_src * *lp_fltr++; /* initial lowpass product */
ddot_p = *head_src-- * *hp_fltr++; /* initial highpass product */
for(i = 1; i < filtlen; i++) /* perform remaining products */
{
adot_p += *head_src * *lp_fltr++;
ddot_p += *head_src-- * *hp_fltr++;
}
*adst++ = adot_p; /* save the completed lowpass dot product */
*ddst++ = ddot_p; /* save the completed highpass dot product */
}
/* perform convolution off the physical end of the array
with a partial dot product loop, like at the beginning */
for(brklen = filtlen - 2, j = 2; brklen > 0; brklen -= 2, j += 2)
{
head_src = src + endlen; /* point to last element in array */
lp_fltr = htilda + j; /* set up pointer to lowpass filter offset */
hp_fltr = gtilda + j; /* set up pointer to highpass filter offset*/
adot_p = *head_src * *lp_fltr++; /* initial lowpass product */
ddot_p = *head_src-- * *hp_fltr++; /* initial highpass product */
for(i = 1; i < brklen; i++) /* perform remaining products */
{
adot_p += *head_src * *lp_fltr++;
ddot_p += *head_src-- * *hp_fltr++;
}
*adst++ = adot_p; /* save the completed lowpass dot product */
*ddst++ = ddot_p; /* save the completed highpass dot product */
}
} /* End of DualConvDec2 */
/* DualConvInt2Sum - Convolution of data array with reconstruction
filters with interpolation by two and sum together.
Input(s): REAL_TYPE *asrc - Pointer to approximation data sample array.
REAL_TYPE *dsrc - Pointer to detail data sample array.
REAL_TYPE *h - Pointer to lowpass filter array.
REAL_TYPE *g - Pointer to highpass filter array.
short srclen - length of source data array.
short filtlen - length of filter arrays.
Output(s): REAL_TYPE *dst - Pointer to output data sample array.
*/
void DualConvInt2Sum(REAL_TYPE *asrc, REAL_TYPE *dsrc, REAL_TYPE *dst,
REAL_TYPE *h, REAL_TYPE *g, short srclen, short filtlen)
{
short i, j, endlen;
REAL_TYPE dot_pe, dot_po;
REAL_TYPE *head_asrc, *head_dsrc, *lp_fltr, *hp_fltr;
endlen = srclen + filtlen - 2; /* find total length of array */
filtlen /= 2; /* adjust filter length value for interpolation */
j = filtlen - 1; /* start with filter 'covering' end of array */
head_asrc = asrc + j; /* point to initial element at head */
head_dsrc = dsrc + j; /* point to initial element at head */
lp_fltr = h + 1; /* set up pointer to lowpass filter */
hp_fltr = g + 1; /* set up pointer to highpass filter */
/* initial lowpass and highpass odd product */
dot_po = *head_asrc-- * *lp_fltr + *head_dsrc-- * *hp_fltr;
lp_fltr += 2; hp_fltr += 2; /* skip over even filter elements */
for(i = 1; i < filtlen; i += 2) /* perform remaining products */
{
dot_po += *head_asrc-- * *lp_fltr + *head_dsrc-- * *hp_fltr;
lp_fltr += 2; hp_fltr += 2; /* skip over even filter elements */
}
/* save the completed lowpass and highpass odd dot product */
*dst++ = dot_po;
/* perform initial convolution with a simple dot product loop */
for(j++; j <= endlen; j++)
{
head_asrc = asrc + j; /* point to appropriate initial element at head */
head_dsrc = dsrc + j; /* point to appropriate initial element at head */
lp_fltr = h; /* set up pointer to lowpass filter */
hp_fltr = g; /* set up pointer to highpass filter */
/* initial lowpass and highpass even product */
dot_pe = *head_asrc * *lp_fltr++ + *head_dsrc * *hp_fltr++;
/* initial lowpass and highpass odd product */
dot_po = *head_asrc-- * *lp_fltr++ + *head_dsrc-- * *hp_fltr++;
for(i = 1; i < filtlen; i++) /* perform remaining products */
{
dot_pe += *head_asrc * *lp_fltr++ + *head_dsrc * *hp_fltr++;
dot_po += *head_asrc-- * *lp_fltr++ + *head_dsrc-- * *hp_fltr++;
}
/* save the completed lowpass and highpass even dot product */
*dst++ = dot_pe;
/* save the completed lowpass and highpass odd dot product */
*dst++ = dot_po;
}
} /* End of DualConvInt2Sum */
Listing Two
/* AWPT.C */
/* Copyright (C) 1993 Mac A. Cody - All rights reserved */
#include "wp_types.h"
#include "awpt.h"
#include "convolve.h"
/* AWPT - Aperiodic Wavelet Packet Transform: Data is assumed to be
non-periodic, so convolutions do not wrap around arrays.
Convolution data past end of data is generated and retained
to allow perfect reconstruction of original input.
Input(s): REAL_TYPE *indata - Pointer to input data sample array.
REAL_TYPE *htilda - Pointer to lowpass filter array.
REAL_TYPE *gtilda - Pointer to highpass filter array.
short filtlen - Length of filter arrays.
Output(s): WPTstruct *out - Pointer to transform data structure.
Note: Structure pointed to by 'out' contains:
out->levels - Number of levels in transform (short).
out->length - Length of input data sample array (short).
out->data - Pointer to pointer of arrays of data (REAL_TYPE ***).
*/
void AWPT(REAL_TYPE *indata, WPTstruct *out,
REAL_TYPE *htilda, REAL_TYPE *gtilda, short filtlen)
{
short i, j, nodes, datalen;
REAL_TYPE *src;
levels = out->levels;
datalen = out->length; /* start with length of input array */
/* loop for all levels, halving the data length on each lower level */
for (i = 0, nodes = 2; i < levels; i++, nodes <<= 1)
{
for(j = 0; j < nodes; j += 2)
{
if(out->data[i][j] == 0) continue;
if(i == 0) /* ... source for highest level is input data */
src = indata;
else /* ... source is corresponding node of higher level */
src = out->data[i-1][j >> 1];
DualConvDec2(src, out->data[i][j], out->data[i][j+1],
htilda, gtilda, datalen, filtlen);
}
datalen /= 2; /* input length for next level is half this level */
}
} /* End of AWPT */
/* IAWPT - Inverse Aperiodic Wavelet Packet Transform: Data is assumed to be
non-periodic, so convolutions do not wrap arround arrays.
Convolution data past end of data is used to generate perfect
reconstruction of original input.
Input(s): WPTstruct *in - Pointer to transform data structure.
REAL_TYPE *htilda - Pointer to lowpass filter array.
REAL_TYPE *gtilda - Pointer to highpass filter array.
short filtlen - Length of filter arrays.
Note: Structure pointed to by 'in' contains:
in->levels - Number of levels in transform (short).
in->length - Length of output data sample array (short).
in->data - Pointer to pointer of arrays of data (REAL_TYPE ***).
Output(s): REAL_TYPE *indata - Pointer to input data sample array.
*/
void IAWPT(WPTstuct *in, REAL_TYPE *outdata,
REAL_TYPE *htilda, REAL_TYPE *gtilda, short filtlen)
{
short i, j, levels, nodes, datalen;
REAL_TYPE *dst;
levels = in->levels;
/* start with length of lowest level input array */
datalen = in->length >> levels;
/* loop for all levels, doubling the data length on each higher level;
destination of all but the highest branch of the reconstruction
is the next higher node */
for (i = levels - 1, nodes = 1 << levels; i >= 0; i--, nodes >>= 1)
{
for(j = 0; j < nodes; j += 2)
{
if(out->data[i][j] == 0) continue;
if(i == 0) /* ... destination for highest level is input data */
dst = outdata;
else /* ... destination is corresponding node of higher level */
dst = in->data[i - 1][j >> 1];
DualConvInt2Sum(in->data[i][j], in->data[i][j+1], dst,
htilda, gtilda, datalen, filtlen);
}
datalen *= 2; /* input length for next level is half this level */
}
}/* End of IAWPT */