📄 vminterface.c
字号:
/*****************************************************************************/
/* Author: Brendt Wohlberg (Los Alamos National Laboratory). */
/* Copyright 2001 University of California. */
/*****************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "VMInterface.h"
#include "Lifting.h"
/* Not very elegant, but simple - more easily removed later than
adding parameters to the function interfaces */
int OverrideExtensionPolicy = 0;
StdExtension EvenUpdateExtension = NullStdExt;
StdExtension OddUpdateExtension = NullStdExt;
/* Compute values for Filt_Cat (WS or HS) and non_sym (the number of
non-symmetric steps in an HS filter bank. The value of rev should
be 1 if the filter bank is reversible, and 0 if it is not. */
static void compute_filt_cat(std_lifting_info_ptr stdliftptr, int rev,
int* Filt_Cat);
/* Return 1 if step s in filter bank pointed to by stdliftptr has all
zero taps, otherwise return 0. The value of rev should be 1 if the
filter bank is reversible, and 0 if it is not. */
static int null_step(std_lifting_info_ptr stdliftptr, int s, int rev);
/* Determine the symmetry of step s in filter bank pointed to by
stdliftptr. The value of rev should be 1 if the filter bank is
reversible, and 0 if it is not. Returns -1 for anti-symmetry,
0 for no symmetry, and 1 for symmetry. */
static int symmetry_step(std_lifting_info_ptr stdliftptr, int s, int rev);
/* Determine the symmetry of an array of float values */
static int symmetry_step_float(float* alpha, int Ns);
/* Determine the symmetry of an array of int values */
static int symmetry_step_int(int* alpha, int Ns);
void fltbankirr_init_from_std_lifting_info(FltBankIrr* fltbankirr,
std_lifting_info_ptr stdliftptr) {
int Filt_Cat, N_LS, m0;
int *L = 0, *off = 0;
float **alpha = 0, K;
int s,n;
N_LS = stdliftptr->num_steps;
compute_filt_cat(stdliftptr, 0, &Filt_Cat);
L = malloc(sizeof(int)*N_LS);
off = malloc(sizeof(int)*N_LS);
alpha = malloc(sizeof(float*)*N_LS);
assert(L && off && alpha);
m0 = 1;
K = 1.0/stdliftptr->lp_scale;
for (s = 0; s < N_LS; s++) {
L[s] = 1 + stdliftptr->steps[s].neg_support +
stdliftptr->steps[s].pos_support;
off[s] = -stdliftptr->steps[s].pos_support;
alpha[s] = malloc(sizeof(float)*L[s]);
assert(alpha[s]);
for (n = 0; n < L[s]; n++)
alpha[s][n] = stdliftptr->steps[s].taps[L[s]-n-1];
}
fltbankirr_initialise(fltbankirr, Filt_Cat, N_LS, m0, L, off,
(const float **)alpha, K);
for (s = 0; s < N_LS; s++)
free(alpha[s]);
free(alpha);
free(off);
free(L);
}
void fltbankrev_init_from_std_lifting_info(FltBankRev* fltbankrev,
std_lifting_info_ptr stdliftptr) {
int Filt_Cat, N_LS, m0;
int *L = 0, *off = 0;
int **alpha = 0, *beta = 0, *epsilon = 0;
int s, n;
N_LS = stdliftptr->num_steps;
compute_filt_cat(stdliftptr, 1, &Filt_Cat);
L = malloc(sizeof(int)*N_LS);
off = malloc(sizeof(int)*N_LS);
epsilon = malloc(sizeof(int)*N_LS);
beta = malloc(sizeof(int)*N_LS);
alpha = malloc(sizeof(int*)*N_LS);
assert(alpha);
m0 = 1;
for (s = 0; s < N_LS; s++) {
L[s] = 1 + stdliftptr->steps[s].neg_support +
stdliftptr->steps[s].pos_support;
off[s] = -stdliftptr->steps[s].pos_support;
alpha[s] = malloc(sizeof(int)*L[s]);
assert(alpha[s]);
for (n = 0; n < L[s]; n++)
alpha[s][n] = stdliftptr->steps[s].int_taps[L[s]-n-1];
epsilon[s] = stdliftptr->steps[s].int_rdx;
beta[s] = epsilon[s]/2;
}
fltbankrev_initialise(fltbankrev, Filt_Cat, N_LS, m0, L, off,
(const int **)alpha, beta, epsilon);
for (s = 0; s < N_LS; s++)
free(alpha[s]);
free(alpha);
free(beta);
free(epsilon);
free(off);
free(L);
}
void compute_filt_cat(std_lifting_info_ptr stdliftptr, int rev,
int* Filt_Cat) {
int s;
/* Start by assuming WSS filter bank */
*Filt_Cat = 1;
for (s = 0; s < stdliftptr->num_steps; s++)
if (symmetry_step(stdliftptr, s, rev) != 1 &&
!null_step(stdliftptr, s, rev))
*Filt_Cat = 0;
/* If Filt_Cat is still 1, all steps are symmetric and it is WSS,
otherwise check for HSS (other alternative ignored for now). */
if (*Filt_Cat != 1) {
s = 0;
while (s < stdliftptr->num_steps &&
symmetry_step(stdliftptr, s, rev) == 0)
s++;
*Filt_Cat = 2;
}
}
int null_step(std_lifting_info_ptr stdliftptr, int s, int rev) {
int k, Ns;
Ns = 1 + stdliftptr->steps[s].neg_support +
stdliftptr->steps[s].pos_support;
for (k = 0; k < Ns; k++) {
if (rev) {
if (stdliftptr->steps[s].int_taps[k] != 0)
return 0;
} else {
if (fabs(stdliftptr->steps[s].taps[k]) > 0.0)
return 0;
}
}
return 1;
}
int symmetry_step(std_lifting_info_ptr stdliftptr, int s, int rev) {
int Ns = 1 + stdliftptr->steps[s].neg_support +
stdliftptr->steps[s].pos_support;
if (rev) {
return symmetry_step_int(stdliftptr->steps[s].int_taps, Ns);
} else {
return symmetry_step_float(stdliftptr->steps[s].taps, Ns);
}
}
int symmetry_step_float(float* alpha, int Ns) {
const float epsilon = 1e-6;
int k;
int sym;
sym = (fabs(alpha[0]-alpha[Ns-1])<epsilon)?1:
((fabs(alpha[0]+alpha[Ns-1])<epsilon)?-1:0);
if (sym == 0 || Ns == 1)
return 0;
if (sym == -1) {
for (k = 1; k < Ns/2; k++)
if (fabs(alpha[k]+alpha[Ns-1-k])>epsilon)
return 0;
} else {
for (k = 1; k < Ns/2; k++)
if (fabs(alpha[k]-alpha[Ns-1-k])>epsilon)
return 0;
}
return sym;
}
int symmetry_step_int(int* alpha, int Ns) {
int k;
int sym;
sym = (alpha[0] == alpha[Ns-1])?1:((alpha[0] == -alpha[Ns-1])?-1:0);
if (sym == 0 || Ns == 1)
return 0;
if (sym == -1) {
for (k = 1; k < Ns/2; k++)
if (alpha[k] != -alpha[Ns-1-k])
return 0;
} else {
for (k = 1; k < Ns/2; k++)
if (alpha[k] != alpha[Ns-1-k])
return 0;
}
return sym;
}
void OneD_SD_I(const FltBankIrr* fltbankirr, const float* X,
int i0, int i1, float* Y) {
int ok;
ok = lift_fwd_irr(fltbankirr, X, i0, i1-i0, Y);
assert(ok);
}
void OneD_SR_I(const FltBankIrr* fltbankirr,
const float* Y, int i0, int i1, float* X) {
int ok;
ok = lift_inv_irr(fltbankirr, Y, i0, i1-i0, X);
assert(ok);
}
void OneD_SD_R(const FltBankRev* fltbankrev, const int* X,
int i0, int i1, int* Y) {
int ok;
ok = lift_fwd_rev(fltbankrev, X, i0, i1-i0, Y);
assert(ok);
}
void OneD_SR_R(const FltBankRev* fltbankrev,
const int* Y, int i0, int i1, int* X) {
int ok;
ok = lift_inv_rev(fltbankrev, Y, i0, i1-i0, X);
assert(ok);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -