📄 hplx_hor_analysis_by_convolution.c
字号:
taps = self->branch_taps[b];
/* LANL Even Length Begin */
/* Apply offsets corrected for all cases */
sp = in_buf + offset;
for (n=(width+1-offset)>>1; n > 0; n--, sp+=2, dp++)
{
for (sum=0.0F, k=-neg; k <= pos; k++)
sum += sp[k] * taps[k];
*dp = sum;
}
/* LANL Even Length End */
}
/**** Start Point Symmetric SSWT ****/
/* Data rearrangement is required for even length input data */
if ((base->usePsExtension) && ((width % 2) == 0))
{
float* low = branch_bufs[0];
float* high = branch_bufs[1];
assert(width >= 4);
high[width / 2 - 1] = (low[width / 2 - 1] - 0.75F * in_buf[width - 1]
- 0.25F * low[width / 2 - 2]);
low[width / 2 - 1] = in_buf[width - 1];
}
/**** End Point Symmetric SSWT ****/
/* LANL Even Length Begin */
/* Apply (L,L) -> (L',H') postprocessing at right end of output when
required */
if (self->even_taps) {
if (width%2 && first_sample_odd) /* Odd length, odd offset case */
analysis_end_filter(&branch_bufs[0][(width-1)/2-1],
&branch_bufs[0][(width-1)/2-1],
&branch_bufs[1][(width-1)/2]);
if (!(width%2) && !first_sample_odd) /* Even length, even offset case */
analysis_end_filter(&branch_bufs[0][width/2-1],
&branch_bufs[0][width/2-1],
&branch_bufs[1][width/2-1]);
}
/* LANL Even Length End */
}
/* ========================================================================= */
/* ------------------ Implementation of Interface Functions ---------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(hplx_analysis_stage_ref base, forward_info_ref info,
canvas_dims_ptr dims, canvas_dims_ptr frame_dims)
{
hplx_hor_analysis_by_convolution_ref self =
(hplx_hor_analysis_by_convolution_ref) base;
frame_info frame;
int kernel_type;
int b;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
int xnum, num_levels, factor, hor_offset, hor_subsampling;
info->get_fixed_tile_info(info, base->component_idx,
0, &xnum, NULL, NULL,
&hor_subsampling, NULL,
&hor_offset, NULL, &num_levels, NULL,NULL);
factor = 1 << (num_levels - base->component_idx);
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if (base->sso_ext)
local_error("SSO-DWT style extensions are implemented only in lifting; "
"you have opted for a convolution-style implementation!");
kernel_type =
info->get_kernel_type(info,base->direction,INFO__ANALYSIS,
base->component_idx,base->level_idx,
self->branch_neg_supports,
self->branch_pos_supports,
self->branch_neg_supports+1,
self->branch_pos_supports+1);
assert(kernel_type == INFO__CONVOLUTION);
info->get_convolution_taps(info,base->direction,base->component_idx,
base->level_idx,self->branch_taps,
self->branch_taps+1);
self->even_taps =
((self->branch_neg_supports[0]+self->branch_pos_supports[0]) & 1);
for (self->extend=0, b=0; b < base->horiz_limit; b++)
{
if (self->branch_neg_supports[b] > self->extend)
self->extend = self->branch_neg_supports[b];
if (self->branch_pos_supports[b] > self->extend)
self->extend = self->branch_pos_supports[b];
check_kernel_symmetry(self->branch_neg_supports[b],
self->branch_pos_supports[b],
self->branch_taps[b],
self->even_taps,b);
}
info->get_level_info(info,base->component_idx,base->level_idx,
NULL,NULL,&frame,NULL);
if (frame.hor_ssodwt)
local_error("Single sample overlap mode cannot be used with convolution "
"implementations of the Wavelet transform.");
self->tile_width = dims->cols;
self->first_idx = dims->left_col;
self->in_buf = (float *)
local_malloc(XFORM_HBUF_KEY,
sizeof(float)*(self->tile_width+2*self->extend));
self->in_buf += self->extend;
for (b=0; b < base->horiz_limit; b++)
{
canvas_dims branch_dims, branch_frame_dims;
int left, right;
branch_dims = *dims;
if (base->horiz_limit > 1) {
left = branch_dims.left_col;
right = left + branch_dims.cols - 1;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
if(base->otlpf_convention) {
int twidth;
twidth=right-left+1;
twidth=(twidth+1-b)>>1;
left = info->next_otlpf_sub_band(b, left, factor, xnum, hor_offset, hor_subsampling);
right = left + twidth - 1;
}
else {
left = (left+1-b)>>1;
right = (right-b)>>1;
}
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
branch_dims.left_col = left;
branch_dims.cols = right+1-left;
}
branch_frame_dims = *frame_dims;
if (base->horiz_limit > 1) {
branch_frame_dims.cols >>= 1;
branch_frame_dims.left_col = (branch_frame_dims.left_col+1-b)>>1;
}
/* LANL Even Length Begin */
/* Modified offset computations in the convolution can overrun
the previous buffer size by one sample. There may be a more
elegant solution to this problem, but this one appears to
be adequate. */
self->branch_bufs[b] = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*(branch_dims.cols+1));
/* LANL Even Length End */
base->branches[b]->initialize(base->branches[b],info,
&branch_dims,&branch_frame_dims);
}
}
/*****************************************************************************/
/* __push_line_fixed */
/*****************************************************************************/
static void
__push_line_fixed(hplx_analysis_stage_ref base, ifc_int *line_buf,
int width)
{
hplx_hor_analysis_by_convolution_ref self =
(hplx_hor_analysis_by_convolution_ref) base;
float *dp;
int n, b, first_sample_odd, band_width;
assert(base->use_floats); /* In the future, we might like to implement
fixed-point convolution. */
assert(width == self->tile_width);
if (width == 0)
return;
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if(!base->otlpf_convention)
first_sample_odd = self->first_idx & 1;
else
first_sample_odd =0;
/** always treat it as if it were even. **/
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
first_sample_odd = self->first_idx & 1;
if (base->horiz_limit == 2) {
for (dp=self->in_buf, n=width; n > 0; n--)
*(dp++) = (float)(*(line_buf++));
perform_1d_analysis(self,self->in_buf,self->branch_bufs,
width,first_sample_odd);
/* Push the results out to next stage. */
for (b=0; b < base->horiz_limit; b++)
{
band_width = (width + 1 - (b ^ first_sample_odd)) >> 1;
base->branches[b]->push_line_float(base->branches[b],
self->branch_bufs[b],band_width);
}
}
else {
for (dp = self->branch_bufs[0], n=width; n > 0; n--)
*(dp++) = (float) *(line_buf++);
band_width = width;
base->branches[0]->push_line_float(base->branches[0],
self->branch_bufs[0], band_width);
}
}
/*****************************************************************************/
/* __push_line_float */
/*****************************************************************************/
static void
__push_line_float(hplx_analysis_stage_ref base, float *line_buf,
int width)
{
hplx_hor_analysis_by_convolution_ref self =
(hplx_hor_analysis_by_convolution_ref) base;
float *dp;
int n, b, band_width, first_sample_odd;
assert(base->use_floats); /* In the future, we might like to implement
fixed-point convolution. */
assert(width == self->tile_width);
if (width == 0)
return;
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if(!base->otlpf_convention)
first_sample_odd = self->first_idx & 1;
else
first_sample_odd =0;
/** always treat it as if it were even. **/
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if (base->horiz_limit == 2) {
for (dp=self->in_buf, n=width; n > 0; n--)
*(dp++) = *(line_buf++);
perform_1d_analysis(self,self->in_buf,self->branch_bufs,
width,first_sample_odd);
/* Push the results out to next stage. */
for (b=0; b < base->horiz_limit; b++)
{
band_width = (width + 1 - (b ^ first_sample_odd)) >> 1;
base->branches[b]->push_line_float(base->branches[b],
self->branch_bufs[b],band_width);
}
}
else {
for (dp = self->branch_bufs[0], n=width; n > 0; n--)
*(dp++) = *(line_buf++);
band_width = width;
base->branches[0]->push_line_float(base->branches[0],
self->branch_bufs[0], band_width);
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(hplx_analysis_stage_ref base)
{
hplx_hor_analysis_by_convolution_ref self =
(hplx_hor_analysis_by_convolution_ref) base;
int b;
if (self->in_buf != NULL)
local_free(self->in_buf - self->extend);
for (b=0; b < base->horiz_limit; b++)
{
if (self->branch_bufs[b] != NULL)
local_free(self->branch_bufs[b]);
base->branches[b]->terminate(base->branches[b]);
}
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_hor_analysis_by_convolution */
/*****************************************************************************/
hplx_analysis_stage_ref
create_hplx_hor_analysis_by_convolution(void)
{
hplx_hor_analysis_by_convolution_ref result;
result = (hplx_hor_analysis_by_convolution_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_hor_analysis_by_convolution_obj));
result->base.initialize = __initialize;
result->base.push_line_fixed = __push_line_fixed;
result->base.push_line_float = __push_line_float;
result->base.terminate = __terminate;
return((hplx_analysis_stage_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -