📄 hplx_vert_synthesis_by_convolution.c
字号:
/* LANL Even Length Begin */
/* Recompute neg and pos so that the sign flips and taps
copy buffers are allocated large enough for all
extensions of the lowpass or highpass subbands */
neg = self->branch_to_even[0].neg_support;
if (self->branch_to_odd[0].neg_support > neg)
neg = self->branch_to_odd[0].neg_support;
if (self->branch_to_even[1].neg_support > neg)
neg = self->branch_to_even[1].neg_support;
if (self->branch_to_odd[1].neg_support > neg)
neg = self->branch_to_odd[1].neg_support;
pos = self->branch_to_even[0].pos_support;
if (self->branch_to_odd[0].pos_support > pos)
pos = self->branch_to_odd[0].pos_support;
if (self->branch_to_even[1].pos_support > pos)
pos = self->branch_to_even[1].pos_support;
if (self->branch_to_odd[1].pos_support > pos)
pos = self->branch_to_odd[1].pos_support;
/* LANL Even Length End */
self->sign_flips_buffer = (int *)
local_malloc(XFORM_VBUF_KEY,sizeof(int)*(neg+pos+1));
self->taps_copy = (float *)
local_malloc(XFORM_VBUF_KEY,sizeof(float)*(neg+pos+1));
}
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->ps_prev_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
self->ps_low_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
self->ps_high_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
self->next_row_idx = self->first_row_idx;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
if(!base->otlpf_convention)
first_row_odd = self->first_row_idx & 1;
else
first_row_odd =0;
/** always treat it as if it were even. **/
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
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;
}
base->branches[b]->initialize(base->branches[b],info,
&branch_dims,&branch_frame_dims);
/* Initialize rolling buffer. */
window = self->branch_windows + b;
window->min_row_idx = window->next_row_idx = 0;
window->have_zero_row = 0;
window->rows = branch_dims.rows;
/* Set the extension policy for the rolling buffer. */
window->bottom_extension_special = 0;
if (self->even_taps)
{
/* LANL Even Length Begin */
/* Disable odd indexing even filter error message in modified code */
/* LANL Even Length End */
window->top_extension_odd = 0;
/* Both bands have even symmetry at top. */
window->bottom_extension_odd = (dims->rows & 1);
/* LANL Even Length Begin */
/* Set up modified subband extension policies based
on modifications to filter centres */
if (!(dims->top_row%2)) {
window->top_extension_odd = 1;
window->top_extension_special = b;
/* Window modifications required for odd asymmetric extensions
at the top of the tile */
if (window->top_extension_special) {
float* zp;
/* Insert fake initial row of zeroes */
window->rows++;
zp = hplx_rolling_buffer__advance(window);
window->rows--;
for (n=window->cols; n > 0; n--)
*(zp++) = 0.0F;
}
if (dims->rows%2)
window->bottom_extension_odd = 0;
else {
window->bottom_extension_odd = 1;
window->bottom_extension_special = b;
}
}
if (b && !((dims->rows%2) ^ (dims->top_row%2))) {
/* Construct a lookahead buffer for use in undoing
(L,L) -> (L',H') postprocessing at bottom end of tile */
/* Should really work out correct minimum size of the
lookahead buffer. This choice is adequate though */
int buf_size = self->branch_windows[0].window_rows +
self->branch_windows[1].window_rows;
window->ps_buf[1] = (float **)
local_malloc(XFORM_MEM_KEY,sizeof(float *)*buf_size);
for (n = 0; n < buf_size; n++)
window->ps_buf[1][n] = (float *)
local_malloc(XFORM_MEM_KEY,sizeof(float)*window->cols);
}
/* LANL Even Length End */
/* LANL Even Length Begin */
/* Flags for lookahead/preprocessing */
self->extra_right_low_ready = 0;
self->next_high_lookahead = 0;
self->high_lookahead_rows = 0;
window->lookahead_final_seen = 0;
/* LANL Even Length End */
if (window->bottom_extension_odd)
window->bottom_extension_special = b;
/* For even-length signals, both bands have even symmetry at
the bottom. For odd-length signals, both bands have odd
symmetry, but the high-pass band's symmetry is about the
first missing high-pass row, which must be set to zero
by the extension. We refer to this as special symmetry. */
}
else
{
if (self->base.usePsExtension && first_row_odd)
local_error("Cannot start image, tile or frame with an odd "
"indexed sample when using the PSE! Use regular "
"symmetric extension!");
window->top_extension_odd = 1 - (b^first_row_odd);
window->bottom_extension_odd = (dims->rows + (b^first_row_odd)) & 1;
}
}
}
/*****************************************************************************/
/* __pull_line_float */
/*****************************************************************************/
static void
__pull_line_float(hplx_synthesis_stage_ref base, float *line_buf,
int width)
{
hplx_vert_synthesis_by_convolution_ref self =
(hplx_vert_synthesis_by_convolution_ref) base;
assert(width == self->cols);
if (width == 0)
return;
if (base->vert_limit > 1) {
complete_pull_line(base,line_buf);
}
else {
base->branches[0]->pull_line_float(base->branches[0],line_buf,
self->cols);
}
self->next_row_idx++;
}
/*****************************************************************************/
/* __pull_line_fixed */
/*****************************************************************************/
static void
__pull_line_fixed(hplx_synthesis_stage_ref base, ifc_int *line_buf,
int width)
{
hplx_vert_synthesis_by_convolution_ref self =
(hplx_vert_synthesis_by_convolution_ref) base;
float *conv_buf, *sp, val;
int n;
assert(base->use_floats);
if (width == 0)
return;
conv_buf = self->conversion_buf;
if (conv_buf == NULL)
self->conversion_buf = conv_buf = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*self->cols);
__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_vert_synthesis_by_convolution_ref self =
(hplx_vert_synthesis_by_convolution_ref) base;
hplx_rolling_buffer_ptr window=NULL; /* TJF: =NULL to avoid warnings */
int b, n;
for (b=0; b < base->vert_limit; b++)
{
window = self->branch_windows + b;
if (window->buffer != NULL)
{
for (n=0; n < window->window_rows; n++)
if (window->buffer[n] != NULL)
local_free(window->buffer[n]);
local_free(window->buffer);
}
if (window->receiving_buf != NULL)
local_free(window->receiving_buf);
if (base->usePsExtension)
{
for (n = 0; n < window->window_rows; n++)
{
local_free(window->ps_buf[0][n]);
local_free(window->ps_buf[1][n]);
}
local_free(window->ps_buf[0]);
local_free(window->ps_buf[1]);
}
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);
}
/* LANL Even Length Begin */
if (self->even_taps) {
/* Clean up lookahead buffer when necessary */
int num_rows = self->branch_windows[0].rows+
self->branch_windows[1].rows;
int buf_size = self->branch_windows[0].window_rows +
self->branch_windows[1].window_rows;
if (!((num_rows%2) ^ (self->first_row_idx%2))) {
for (n = 0; n < buf_size; n++)
local_free(window->ps_buf[1][n]);
local_free(window->ps_buf[1]);
}
}
/* LANL Even Length End */
if (self->ps_prev_buf != NULL)
local_free(self->ps_prev_buf);
if (self->ps_low_buf != NULL)
local_free(self->ps_low_buf);
if (self->ps_high_buf != NULL)
local_free(self->ps_high_buf);
if (self->conversion_buf != NULL)
local_free(self->conversion_buf);
if (self->sign_flips_buffer != NULL)
local_free(self->sign_flips_buffer);
if (self->taps_copy != NULL)
local_free(self->taps_copy);
for (b=0; b < base->vert_limit; b++)
base->branches[b]->terminate(base->branches[b]);
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_vert_synthesis_by_convolution */
/*****************************************************************************/
hplx_synthesis_stage_ref
create_hplx_vert_synthesis_by_convolution(void)
{
hplx_vert_synthesis_by_convolution_ref result;
result = (hplx_vert_synthesis_by_convolution_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_vert_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 + -