📄 hplx_vert_synthesis_by_convolution.c
字号:
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
for (dp=line_buf, n=self->cols; n > 0; n--)
*(dp++) = 0.0F; /* We will be accumulating the impact of the two subbands
into this buffer. */
for (b=0; b < base->vert_limit; b++, kernel++)
{ /* Walk through the two subbands which contribute to the output. */
window = self->branch_windows + b;
neg = kernel->neg_support;
pos = kernel->pos_support;
support = neg + pos + 1;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
if(!base->otlpf_convention) {
/* LANL Even Length Begin */
/* Correct row index computation for even length filters */
if (self->even_taps) {
min_row_idx = ((self->next_row_idx-self->first_row_idx)>>1) - neg;
min_row_idx -= (1-b)>>1;
}
else {
min_row_idx = (self->next_row_idx>>1) - neg;
min_row_idx -= (self->first_row_idx+1-b)>>1;
}
/* LANL Even Length End */
}
else min_row_idx = ((self->next_row_idx-self->first_row_idx)>>1) - neg;
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
sign_flips[b] = NULL;
if (self->even_taps && b)
sign_flips[b] = self->sign_flips_buffer;
/* LANL Even Length Begin */
/* Modify effective filter alignment to give desired filter centres */
if ((oddevencase || evenevencase) && (self->next_row_idx%2))
min_row_idx++;
if (window->top_extension_special)
window->rows++;
/* LANL Even Length End */
while ((source[b] =
hplx_rolling_buffer__get_rows(window,min_row_idx,
support,sign_flips[b],b,0,
base->usePsExtension,
self->ps_low_buf)) == NULL)
{ /* Need to advance the moving window. */
dp = hplx_rolling_buffer__advance(window);
/* LANL Even Length Begin */
if (b && window->lookahead_final_seen &&
(self->next_high_lookahead < self->high_lookahead_rows)) {
/* Need to take the next highpass row from the lookahead buffer */
for (k = 0; k < window->cols; k++)
dp[k] = window->ps_buf[1][self->next_high_lookahead][k];
self->next_high_lookahead++;
} else
if (!b && self->extra_right_low_ready) {
/* Need to take the final lowpass row from self->ps_low_buf */
self->extra_right_low_ready = 0;
for (k = 0; k < window->cols; k++)
dp[k] = self->ps_low_buf[k];
} else
/* LANL Even Length End */
base->branches[b]->pull_line_float(base->branches[b],dp,
self->cols);
}
/* LANL Even Length Begin */
if ((evenevencase || oddoddcase) &&
(window->next_row_idx == window->rows)) {
/* One of the windows has reached the last incoming row
in the odd/odd or even/even case */
int delta = evenevencase?1:0;
if (b && !window->lookahead_final_seen) {
/* We have reached the final highpass row for the first time */
window->lookahead_final_seen = 1;
/* Store final highpass row for later use and return it to its
"original" (prior to analysis postprocessing) state */
for (k = 0; k < window->cols; k++) {
self->ps_high_buf[k] = dp[k];
dp[k] = 0.0;
}
window->rows--;
window->next_row_idx--;
}
if (!b && !window->lookahead_final_seen) {
/* We have reached the final lowpass row for the first time */
hplx_rolling_buffer_ptr hwindow;
hwindow = self->branch_windows + 1;
window->lookahead_final_seen = 1;
if (hwindow->lookahead_final_seen) {
/* We have already seen the final highpass row. Undo
(L,L) -> (L',H') postprocessing at bottom end of tile,
taking the final highpass row from self->ps_high_buf */
synthesis_end_filter(dp, self->ps_high_buf,
dp, self->ps_low_buf, self->cols);
self->extra_right_low_ready = 1;
window->rows++;
} else {
/* We need to read the remaining highpass rows into
a lookahead buffer */
for (n=0; n <hwindow->rows-hwindow->next_row_idx+delta; n++) {
base->branches[1]->pull_line_float(base->branches[1],
hwindow->ps_buf[1][n],
self->cols);
}
self->next_high_lookahead = 0;
self->high_lookahead_rows = n;
hwindow->lookahead_final_seen = 1;
/* Undo (L,L) -> (L',H') postprocessing at bottom end of tile,
taking the final highpass row from the end of the lookahead
buffer */
synthesis_end_filter(dp, hwindow->ps_buf[1][n-1],
dp, self->ps_low_buf, self->cols);
self->extra_right_low_ready = 1;
window->rows++;
hwindow->rows--;
/* The symmetric extensions need to be recomputed when
the window simultaneously contains rows past the top
boundary of the tile and the row resulting from
undoing the (L,L) -> (L',H') postprocessing */
while ((source[b] =
hplx_rolling_buffer__get_rows(window,min_row_idx,
support,sign_flips[b],b,0,
base->usePsExtension,
self->ps_low_buf)) == NULL)
{
dp = hplx_rolling_buffer__advance(window);
self->extra_right_low_ready = 0;
for (k = 0; k < window->cols; k++)
dp[k] = self->ps_low_buf[k];
}
}
}
}
/* Apply filter alignment correction for odd asymmetric extensions
at the top of the tile */
if (window->top_extension_special)
window->rows--;
/* LANL Even Length End */
}
kernel -= 2;
/*
* Perform the required data rearrangement for every column, only when doing
* the row.
*/
if (base->usePsExtension)
{
int reorderLow, reorderHigh;
reorderLow = -1;
reorderHigh = -1;
/* Remember the second to last row as soon as it appears */
if (2 * window->rows ==
(self->next_row_idx-self->first_row_idx) + 3 +
2*kernel[0].pos_support)
{
int row = kernel[0].neg_support + kernel[0].pos_support;
for (n=0; n<self->cols; n++)
self->ps_prev_buf[n] = source[0][row][n];
}
/* When the last low row first appears, reorder */
if (2 * window->rows ==
(self->next_row_idx-self->first_row_idx) + 1 +
2*kernel[0].pos_support)
{
int lastHigh = kernel[1].neg_support + kernel[1].pos_support;
reorderLow = kernel[0].neg_support + kernel[0].pos_support;
for (n=0; n<self->cols; n++)
{
self->ps_low_buf[n] = source[0][reorderLow][n];
source[0][reorderLow][n] = (source[1][lastHigh][n]
+ 0.75F * source[0][reorderLow][n]
+ 0.25F * self->ps_prev_buf[n]);
}
}
/* When the last high row first appears, reorder */
if (2 * window->rows ==
(self->next_row_idx-self->first_row_idx) + 1 +
2*kernel[1].pos_support)
{
reorderHigh = kernel[1].neg_support + kernel[1].pos_support;
for (n=0; n<self->cols; n++)
{
self->ps_high_buf[n] = source[1][reorderHigh][n];
source[1][reorderHigh][n] = 0;
}
}
}
/*
* Split this operation into two passes, so that point symmetric extension
* related data rearrangement can occur.
*/
for (b=0; b < base->vert_limit; b++, kernel++)
{
neg = kernel->neg_support;
pos = kernel->pos_support;
support = neg + pos + 1;
taps = kernel->taps - neg;
if (sign_flips[b] != NULL)
{
for (n=0; n < support; n++)
self->taps_copy[n] = (sign_flips[b][n])?(-taps[n]):(taps[n]);
taps = self->taps_copy;
}
for (dp=line_buf, n=0; n < self->cols; n++)
{
for (sum=0.0F, k=0; k < support; k++)
sum += taps[k] * source[b][k][n];
*(dp++) += sum;
}
}
}
/* ========================================================================= */
/* ------------------ Implementation of Interface Functions ---------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(hplx_synthesis_stage_ref base, reverse_info_ref info,
canvas_dims_ptr dims, canvas_dims_ptr frame_dims)
{
hplx_vert_synthesis_by_convolution_ref self =
(hplx_vert_synthesis_by_convolution_ref) base;
frame_info frame;
hplx_rolling_buffer_ptr window;
int branch_neg_supports[2], branch_pos_supports[2];
float *branch_taps[2];
int kernel_type;
int b, n, bb, neg, pos;
int first_row_odd;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
int ynum, num_levels, factor, vert_offset, vert_subsampling;
info->get_fixed_tile_info(info, base->component_idx,
0, NULL, &ynum, NULL,
NULL, &vert_subsampling,
NULL, &vert_offset, &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);
for (b=0; b < base->vert_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]);
window = self->branch_windows + b;
neg = self->branch_to_even[b].neg_support;
if (self->branch_to_odd[b].neg_support > neg)
neg = self->branch_to_odd[b].neg_support;
pos = self->branch_to_even[b].pos_support;
if (self->branch_to_odd[b].pos_support > pos)
pos = self->branch_to_odd[b].pos_support;
window->cols = dims->cols;
window->window_rows = neg+pos+1;
window->buffer = (float **)
local_malloc(XFORM_VBUF_KEY,sizeof(float *)*window->window_rows);
for (n=0; n < window->window_rows; n++)
window->buffer[n] = (float *)
local_malloc(XFORM_VBUF_KEY,sizeof(float)*window->cols);
window->receiving_buf = (float **)
local_malloc(XFORM_VBUF_KEY,sizeof(float *)*window->window_rows);
if (base->usePsExtension)
for (bb=0; bb < base->vert_limit; bb++)
{
int y;
window->ps_buf[bb] = (float **)
local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
for (y = 0; y < window->window_rows; y++)
window->ps_buf[bb][y] = (float *)
local_malloc(XFORM_MEM_KEY,sizeof(float)*window->cols);
}
}
if (self->even_taps)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -