📄 hplx_hor_synthesis_by_convolution.c
字号:
{
hplx_hor_synthesis_by_convolution_ref self =
(hplx_hor_synthesis_by_convolution_ref) base;
frame_info frame;
int branch_neg_supports[2], branch_pos_supports[2];
float *branch_taps[2];
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__SYNTHESIS,
base->component_idx,base->level_idx,
branch_neg_supports,branch_pos_supports,
branch_neg_supports+1,branch_pos_supports+1);
assert(kernel_type == INFO__CONVOLUTION);
info->get_convolution_taps(info,base->direction,base->component_idx,
base->level_idx,branch_taps,branch_taps+1);
self->even_taps = ((branch_neg_supports[0]+branch_pos_supports[0]) & 1);
self->extend = 0;
for (b=0; b < base->horiz_limit; b++)
{
create_polyphase_kernel(self->branch_to_even+b,b,0,
branch_neg_supports[b],branch_pos_supports[b],
branch_taps[b]);
create_polyphase_kernel(self->branch_to_odd+b,b,1,
branch_neg_supports[b],branch_pos_supports[b],
branch_taps[b]);
if (self->branch_to_even[b].neg_support > self->extend)
self->extend = self->branch_to_even[b].neg_support;
if (self->branch_to_even[b].pos_support > self->extend)
self->extend = self->branch_to_even[b].pos_support;
if (self->branch_to_odd[b].neg_support > self->extend)
self->extend = self->branch_to_odd[b].neg_support;
if (self->branch_to_odd[b].pos_support > self->extend)
self->extend = self->branch_to_odd[b].pos_support;
}
self->extend++; /* High-pass subbands from odd length rows might have to
be extended 1 more sample on the right than one might
expect from the above calculations. This is because
the centre sample for the second branch to even kernel
lies 1 sample beyond the end of the high-pass subband.
It never hurts to extend too far. */
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;
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;
}
self->branch_bufs[b] = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*
(branch_dims.cols+2*self->extend+2));
/* Need the added 2 elements here because the symmetric extension
implementation for even length filters may run over by 2. */
self->branch_bufs[b] += self->extend;
base->branches[b]->initialize(base->branches[b],info,
&branch_dims,&branch_frame_dims);
}
}
/*****************************************************************************/
/* __pull_line_float */
/*****************************************************************************/
static void
__pull_line_float(hplx_synthesis_stage_ref base, float *line_buf,
int width)
{
hplx_hor_synthesis_by_convolution_ref self =
(hplx_hor_synthesis_by_convolution_ref) base;
int b, band_width, first_sample_odd;
/* LANL Even Length Begin */
/* Ensure that line_buf isn't a null pointer */
assert(line_buf);
/* LANL Even Length End */
assert(base->use_floats);
assert(width == self->tile_width);
if (width == 0)
return;
/* OTLPF_CONVENTION begin; 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 (width == 1)
{ /* The generic implementation can only be guaranteed to work properly
for signals of length 2 or more. */
base->branches[first_sample_odd]->pull_line_float(
base->branches[first_sample_odd],line_buf,1);
return;
}
/* First, recover the subband samples from which to synthesize. */
if (base->horiz_limit == 2) {
for (b=0; b < base->horiz_limit; b++)
{
band_width = (width + 1 - (b ^ first_sample_odd)) >> 1;
base->branches[b]->pull_line_float(base->branches[b],
self->branch_bufs[b],band_width);
}
/* Now perform the 1-D synthesis operation. */
perform_1d_synthesis(self,line_buf,self->branch_bufs,width,first_sample_odd);
}
else {
float *sp, *dp;
int n;
band_width = width;
base->branches[0]->pull_line_float(base->branches[0],
self->branch_bufs[0],band_width);
for (dp=line_buf, sp=self->branch_bufs[0], n=width; n > 0; n--)
*(dp++) = *(sp++);
}
}
/*****************************************************************************/
/* __pull_line_fixed */
/*****************************************************************************/
static void
__pull_line_fixed(hplx_synthesis_stage_ref base, ifc_int *line_buf,
int width)
{
hplx_hor_synthesis_by_convolution_ref self =
(hplx_hor_synthesis_by_convolution_ref) base;
float *conv_buf, *sp, val;
int n;
assert(base->use_floats); /* In the future, we might like to support fixed-
point implementation of the convolution. */
if (width == 0)
return;
if ((conv_buf = self->conversion_buf) == NULL)
conv_buf = self->conversion_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->tile_width);
__pull_line_float(base,conv_buf,width);
for (sp=conv_buf, n=width; n > 0; n--)
{
val = *(sp++);
*(line_buf++) = (ifc_int)((val<0.0F)?(val-0.5F):(val+0.5F));
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(hplx_synthesis_stage_ref base)
{
hplx_hor_synthesis_by_convolution_ref self =
(hplx_hor_synthesis_by_convolution_ref) base;
int b;
for (b=0; b < base->horiz_limit; b++)
{
if (self->branch_to_even[b].taps != NULL)
local_free(self->branch_to_even[b].taps -
self->branch_to_even[b].neg_support);
if (self->branch_to_odd[b].taps != NULL)
local_free(self->branch_to_odd[b].taps -
self->branch_to_odd[b].neg_support);
if (self->branch_bufs[b] != NULL)
local_free(self->branch_bufs[b]-self->extend);
}
if (self->conversion_buf != NULL)
local_free(self->conversion_buf);
for (b=0; b < base->horiz_limit; b++)
base->branches[b]->terminate(base->branches[b]);
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_hor_synthesis_by_convolution */
/*****************************************************************************/
hplx_synthesis_stage_ref
create_hplx_hor_synthesis_by_convolution(void)
{
hplx_hor_synthesis_by_convolution_ref result;
result = (hplx_hor_synthesis_by_convolution_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_hor_synthesis_by_convolution_obj));
result->base.initialize = __initialize;
result->base.pull_line_fixed = __pull_line_fixed;
result->base.pull_line_float = __pull_line_float;
result->base.terminate = __terminate;
return((hplx_synthesis_stage_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -