📄 hplx_vert_analysis_by_convolution.c
字号:
/* Remember the second to last low row */
if ((self->branch_next_row_idx[0] == window->rows / 2 - 2) &&
(!continued[0]))
{
for (n=0; n<self->cols; n++)
self->ps_buf[n] = self->out_buf[0][n];
}
/* Rearrange the last low and high rows */
else if ((self->branch_next_row_idx[0] == window->rows / 2 - 1) &&
(!continued[0]) && (!continued[1]))
{
for (n=0; n<self->cols; n++)
{
self->out_buf[1][n] = (self->out_buf[0][n] - 0.75F * bottom[n]
- 0.25F * self->ps_buf[n]);
self->out_buf[0][n] = bottom[n];
}
}
}
/* End PSE Stuff */
/*
* Split this operation into two passes, so that point symmetric extension
* related data rearrangement can occur.
*/
for (b=0; b < base->vert_limit; b++)
{
if (continued[b])
continue;
/* LANL Even Length Begin */
if ((oddoddcase || evenevencase) && !b &&
(self->branch_next_row_idx[0] == self->branch_rows[0]-1)) {
/* Postprocessing is required and the last or 2nd last lowpass row
has just been generated */
if (self->second_last_low_seen) {
/* The 2nd last lowpass row has been stored. Apply the
postprocessor and decrement the lowpass subband size
and next index to the correct final values */
analysis_end_filter(self->ps_buf, self->out_buf[0],
self->out_buf[0], self->ps_buf,
self->cols);
self->final_high_ready = 1;
self->branch_rows[b]--;
self->branch_next_row_idx[b]--;
} else {
/* Store the 2nd last lowpass row and increment lowpass subband
size and index of next row to be generated so that the last
lowpass row will be generated on the next pass */
for (n=0; n<self->cols; n++)
self->ps_buf[n] = self->out_buf[0][n];
self->second_last_low_seen = 1;
self->branch_rows[b]++;
self->branch_next_row_idx[b]++;
continue;
}
}
/* LANL Even Length End */
/* LANL Even Length Begin */
if ((oddoddcase || evenevencase) && b &&
self->branch_next_row_idx[1] == self->branch_rows[1]-1) {
/* Postprocessing is necessary and the last highpass row is required
next. Ensure that this row has been constructed by the postprocessor,
output the row, and increment the relevant row index to indicate
that the final highpass row has been dealt with */
assert(self->final_high_ready);
base->branches[1]->push_line_float(base->branches[1],
self->ps_buf,self->cols);
self->branch_next_row_idx[1]++;
continue;
}
/* LANL Even Length End */
base->branches[b]->push_line_float(base->branches[b],
self->out_buf[b],self->cols);
self->branch_next_row_idx[b]++;
}
} while (!done);
}
/* ========================================================================= */
/* ------------------ 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_vert_analysis_by_convolution_ref self =
(hplx_vert_analysis_by_convolution_ref) base;
frame_info frame;
hplx_rolling_buffer_ptr window;
int kernel_type, neg, pos;
int b, n;
/* 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 */
/* LANL Even Length Begin */
/* Flags required for postprocessing for even length filters */
self->second_last_low_seen = 0;
self->final_high_ready = 0;
/* LANL Even Length End */
if (base->sso_ext)
local_error("SSO-DWT style extensions are implemented only in lifting; "
"you have opted for a convolution-style implementation!");
window = &(self->window);
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 (neg=pos=0, b=0; b < base->vert_limit; b++)
{
if (self->branch_neg_supports[b] > neg)
neg = self->branch_neg_supports[b];
if (self->branch_pos_supports[b] > pos)
pos = 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);
}
window->cols = dims->cols;
window->rows = dims->rows;
window->window_rows = neg+pos+1;
window->buffer = (float **)
local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
for (n=0; n < window->window_rows; n++)
{
assert(window->buffer[n] == NULL);
window->buffer[n] = (float *)
local_malloc(XFORM_VBUF_KEY,sizeof(float)*window->cols);
}
window->receiving_buf = (float **)
local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
if (base->usePsExtension)
for (b=0; b < base->vert_limit; b++)
if (window->ps_buf[b] == NULL)
{
int y;
window->ps_buf[b] = (float **)
local_malloc(XFORM_MEM_KEY,sizeof(float *)*window->window_rows);
for (y = 0; y < window->window_rows; y++)
window->ps_buf[b][y] = (float *)
local_malloc(XFORM_MEM_KEY,sizeof(float)*window->cols);
}
window->bottom_extension_odd = window->top_extension_odd = !self->even_taps;
window->bottom_extension_special = 0;
info->get_level_info(info,base->component_idx,base->level_idx,
NULL,NULL,&frame,NULL);
if (frame.vert_ssodwt)
local_error("Single sample overlap mode cannot be used with convolution "
"implementations of the Wavelet transform.");
self->cols = dims->cols;
self->first_row_idx = dims->top_row;
self->out_buf[0] = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
self->out_buf[1] = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
self->ps_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
for (b=0; b < base->vert_limit; b++)
{
canvas_dims branch_dims, branch_frame_dims;
int top, bottom;
branch_dims = *dims;
if (base->vert_limit > 1) {
top = branch_dims.top_row;
bottom = top + branch_dims.rows - 1;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
if(base->otlpf_convention) {
int twidth;
twidth=bottom-top+1;
twidth=(twidth+1-b)>>1;
top=info->next_otlpf_sub_band(b, top, factor, ynum, vert_offset, vert_subsampling);
bottom=top+twidth-1;
}
else {
top = (top+1-b)>>1;
bottom = (bottom-b)>>1;
}
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
branch_dims.top_row = top;
branch_dims.rows = bottom+1-top;
}
branch_frame_dims = *frame_dims;
if (base->vert_limit > 1) {
branch_frame_dims.rows >>= 1;
branch_frame_dims.top_row = (branch_frame_dims.top_row+1-b)>>1;
}
self->branch_rows[b] = branch_dims.rows;
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_vert_analysis_by_convolution_ref self =
(hplx_vert_analysis_by_convolution_ref) base;
float *dp;
int n;
assert(base->use_floats); /* In the future, we might like to implement
convolution in fixed-point also. */
assert(width == self->cols);
if (width == 0)
return;
if (base->vert_limit == 2) {
dp = hplx_rolling_buffer__advance(&(self->window));
for (n=width; n > 0; n--)
*(dp++) = (float)(*(line_buf++));
complete_push_line(base);
}
else {
for (dp = self->out_buf[0], n=width; n > 0; n--)
*(dp++) = (float) *(line_buf++);
base->branches[0]->push_line_float(base->branches[0], self->out_buf[0],self->cols);
self->branch_next_row_idx[0]++;
}
}
/*****************************************************************************/
/* __push_line_float */
/*****************************************************************************/
static void
__push_line_float(hplx_analysis_stage_ref base, float *line_buf,
int width)
{
hplx_vert_analysis_by_convolution_ref self =
(hplx_vert_analysis_by_convolution_ref) base;
float *dp;
int n;
assert(base->use_floats);
assert(width == self->cols);
if (width == 0)
return;
if (base->vert_limit == 2) {
dp = hplx_rolling_buffer__advance(&(self->window));
for (n=width; n > 0; n--)
*(dp++) = *(line_buf++);
complete_push_line(base);
}
else {
for (dp = self->out_buf[0], n=width; n > 0; n--)
*(dp++) = *(line_buf++);
base->branches[0]->push_line_float(base->branches[0], self->out_buf[0],self->cols);
self->branch_next_row_idx[0]++;
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(hplx_analysis_stage_ref base)
{
hplx_vert_analysis_by_convolution_ref self =
(hplx_vert_analysis_by_convolution_ref) base;
int b, n;
if (self->window.buffer != NULL)
{
for (n=0; n < self->window.window_rows; n++)
if (self->window.buffer[n] != NULL)
local_free(self->window.buffer[n]);
local_free(self->window.buffer);
}
if (self->window.receiving_buf != NULL)
local_free(self->window.receiving_buf);
if (base->usePsExtension)
for (b=0; b < base->vert_limit; b++)
{
for (n = 0; n < self->window.window_rows; n++)
local_free(self->window.ps_buf[b][n]);
local_free(self->window.ps_buf[b]);
}
if (self->out_buf[0] != NULL)
local_free(self->out_buf[0]);
if (self->out_buf[1] != NULL)
local_free(self->out_buf[1]);
if (self->ps_buf != NULL)
local_free(self->ps_buf);
for (b=0; b < base->vert_limit; b++)
base->branches[b]->terminate(base->branches[b]);
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_vert_analysis_by_convolution */
/*****************************************************************************/
hplx_analysis_stage_ref
create_hplx_vert_analysis_by_convolution(void)
{
hplx_vert_analysis_by_convolution_ref result;
result = (hplx_vert_analysis_by_convolution_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_vert_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 + -