📄 hplx_hor_analysis_by_lifting.c
字号:
pos_support-=src_offset;
neg_support+=src_offset;
taps += src_offset;
left_ext = (src_on_left_boundary)?0:1;
right_ext = (src_on_right_boundary)?0:1;
}
/* Perform extensions, alternating between left and right extension
until we are done. */
sp = src; dp = sp + src_cols - 1;
pos_support += dst_cols - src_cols;
for (n=p=1; (n <= neg_support) || (p <= pos_support); )
{
int did_something;
did_something = 0;
if (n <= neg_support)
{ /* Still need extension on the left. */
if (left_ext)
{ /* Half-point extension. */
if (n <= (src_cols+p-1))
{ sp[-n] = sp[n-1]*left_ext; n++; did_something = 1; }
}
else
{ /* Whole-point extension */
if (n < (src_cols+p-1))
{ sp[-n] = sp[n]; n++; did_something = 1; }
}
}
if (p <= pos_support)
{ /* Still need extension on the right. */
if (right_ext)
{ /* Half-point extension. */
if (p <= (src_cols+n-1))
{ dp[p] = dp[-p+1]*right_ext; p++; did_something = 1; }
}
else
{ /* Whole-point extension. */
if (p < (src_cols+n-1))
{ dp[p] = dp[-p]; p++; did_something = 1; }
}
}
assert(did_something);
}
pos_support -= dst_cols - src_cols;
/* Apply lifting step. Note that `taps' points to "centre" of support. */
offset = (1<<downshift) >> 1;
if (skip_first)
{ dst_cols--; dst++; src++; }
if (skip_last)
{ dst_cols--; }
for (; dst_cols > 0; dst_cols--, src++, dst++)
{
for (sum=0, n=-neg_support; n <= pos_support; n++)
sum += src[n] * taps[n];
*dst += (ifc_int)((sum+offset) >> downshift);
}
}
/*****************************************************************************/
/* STATIC perform_1d_float_lifting */
/*****************************************************************************/
static void
perform_1d_float_lifting(hplx_hor_analysis_by_lifting_ref self)
/* Performs the sequence of floating point lifting steps on the
two branch buffers in the `self->branch_buf_float' array. Also takes
care of frames where necessary. */
{
float *src_bufs[2], *work_bufs[2], *sp, *dp, scale;
int b, n, remaining_cols, frame_cols, first_col_idx;
int frame_idx;
/* Set up the `src_bufs' and `work_bufs' arrays first. */
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
src_bufs[b] = work_bufs[b] = self->branch_buf_float[b];
if (self->num_frames > 1)
{
if (self->frame_work_buf_float[b] == NULL)
{
self->frame_work_buf_float[b] = (float *)
local_malloc(XFORM_HBUF_KEY,
sizeof(float)*((self->frame_cols>>1)+
self->neg_extend+self->pos_extend + 2));
self->frame_work_buf_float[b] += self->neg_extend;
}
work_bufs[b] = self->frame_work_buf_float[b];
}
}
/* Now for the main processing loop. */
frame_cols = self->first_frame_cols;
remaining_cols = self->tile_width;
assert(remaining_cols > 0);
first_col_idx = self->first_idx;
for (frame_idx=0; frame_idx < self->num_frames; frame_idx++)
{
int special_first, special_last, ovlp_left, ovlp_right;
int left_boundary_odd, right_boundary_odd;
int subseq_cols[2]; /* even and odd sub-sequence lengths. */
left_boundary_odd = first_col_idx & 1;
right_boundary_odd = (first_col_idx+frame_cols-1) & 1;
subseq_cols[0] = (frame_cols+1-left_boundary_odd) >> 1;
subseq_cols[1] = (frame_cols+left_boundary_odd) >> 1;
special_first = special_last = ovlp_left = ovlp_right = 0;
if (frame_idx > 0)
{ /* Internal left boundary. */
special_first = 1;
if (left_boundary_odd)
{ ovlp_left = 1; subseq_cols[0]++; left_boundary_odd = 0; }
}
else if (self->base.sso_ext && !left_boundary_odd)
special_first = 1; /* Use SSO-DWT style extension. */
if (frame_idx < (self->num_frames-1))
{ /* Internal right boundary. */
special_last = 1;
if (right_boundary_odd)
{ ovlp_right = 1; subseq_cols[0]++; right_boundary_odd = 0; }
}
else if (self->base.sso_ext && !right_boundary_odd)
special_last = 1; /* Use SSO-DWT style extension. */
if (self->num_frames > 1)
{ /* Transfer input to `work_bufs', including overlap samples */
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
for (sp=src_bufs[b]-(ovlp_left&(1-b)), dp=work_bufs[b],
n=subseq_cols[b]; n > 0; n--)
*(dp++) = *(sp++);
}
}
if ((subseq_cols[0]+subseq_cols[1]) > 1)
{ /* If there is only 1 sample in the frame, we have nothing to do. */
for (n=0; n < self->num_steps; n++)
{
int src_seq, dst_seq;
int src_offset; /* First src index - first dst index */
src_seq = n & 1; dst_seq = (n+1) & 1;
src_offset = (src_seq&1)?(-left_boundary_odd):left_boundary_odd;
apply_float_step(n,self->neg_supports[n],self->pos_supports[n],
self->float_taps[n],
work_bufs[src_seq],work_bufs[dst_seq],
subseq_cols[src_seq],subseq_cols[dst_seq],
src_offset,left_boundary_odd^dst_seq,
right_boundary_odd^dst_seq,
special_first&src_seq,special_last&src_seq,
self->step_dc_gains[n]);
}
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
scale = self->branch_scale[b];
for (sp=work_bufs[b], n=subseq_cols[b]; n > 0; n--)
*(sp++) *= scale;
}
}
if (self->num_frames > 1)
{ /* Transfer output from `work_bufs', excluding overlap samples */
subseq_cols[0] -= ovlp_left+ovlp_right;
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
for (dp=src_bufs[b], sp=work_bufs[b]+(ovlp_left&(1-b)),
n=subseq_cols[b]; n > 0; n--)
*(dp++) = *(sp++);
src_bufs[b] += subseq_cols[b];
}
}
first_col_idx += frame_cols;
remaining_cols -= frame_cols;
frame_cols = self->frame_cols;
if (frame_cols > remaining_cols)
frame_cols = remaining_cols;
}
}
/*****************************************************************************/
/* STATIC perform_1d_int_lifting */
/*****************************************************************************/
static void
perform_1d_int_lifting(hplx_hor_analysis_by_lifting_ref self)
/* Performs the sequence of integer lifting steps on the
two branch buffers in the `self->branch_buf_int' array. Also takes
care of frames where necessary. */
{
ifc_int *src_bufs[2], *work_bufs[2], *sp, *dp;
int b, n, remaining_cols, frame_cols, first_col_idx;
int frame_idx;
/* Set up the `src_bufs' and `work_bufs' arrays first. */
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
src_bufs[b] = work_bufs[b] = self->branch_buf_int[b];
if (self->num_frames > 1)
{
if (self->frame_work_buf_int[b] == NULL)
{
self->frame_work_buf_int[b] = (ifc_int *)
local_malloc(XFORM_HBUF_KEY,
sizeof(ifc_int)*((self->frame_cols>>1)+
self->neg_extend+self->pos_extend + 2));
self->frame_work_buf_int[b] += self->neg_extend;
}
work_bufs[b] = self->frame_work_buf_int[b];
}
}
/* Now for the main processing loop. */
frame_cols = self->first_frame_cols;
remaining_cols = self->tile_width;
assert(remaining_cols > 0);
first_col_idx = self->first_idx;
for (frame_idx=0; frame_idx < self->num_frames; frame_idx++)
{
int special_first, special_last, ovlp_left, ovlp_right;
int left_boundary_odd, right_boundary_odd;
int subseq_cols[2]; /* even and odd sub-sequence lengths. */
left_boundary_odd = first_col_idx & 1;
right_boundary_odd = (first_col_idx+frame_cols-1) & 1;
subseq_cols[0] = (frame_cols+1-left_boundary_odd) >> 1;
subseq_cols[1] = (frame_cols+left_boundary_odd) >> 1;
special_first = special_last = ovlp_left = ovlp_right = 0;
if (frame_idx > 0)
{ /* Internal left boundary. */
special_first = 1;
if (left_boundary_odd)
{ ovlp_left = 1; subseq_cols[0]++; left_boundary_odd = 0; }
}
else if (self->base.sso_ext && !left_boundary_odd)
special_first = 1; /* Use SSO-DWT style extension. */
if (frame_idx < (self->num_frames-1))
{ /* Internal right boundary. */
special_last = 1;
if (right_boundary_odd)
{ ovlp_right = 1; subseq_cols[0]++; right_boundary_odd = 0; }
}
else if (self->base.sso_ext && !right_boundary_odd)
special_last = 1; /* Use SSO-DWT style extension. */
if (self->num_frames > 1)
{ /* Transfer input to `work_bufs', including overlap samples */
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
for (sp=src_bufs[b]-(ovlp_left&(1-b)), dp=work_bufs[b],
n=subseq_cols[b]; n > 0; n--)
*(dp++) = *(sp++);
}
}
if ((subseq_cols[0]+subseq_cols[1]) > 1)
{ /* If there is only 1 sample in the frame, we have nothing to do. */
for (n=0; n < self->num_steps; n++)
{
int src_seq, dst_seq;
int src_offset; /* First src index - first dst index */
src_seq = n & 1; dst_seq = (n+1) & 1;
src_offset = (src_seq&1)?(-left_boundary_odd):left_boundary_odd;
apply_int_step(n,self->neg_supports[n],self->pos_supports[n],
self->int_taps[n],self->int_downshifts[n],
work_bufs[src_seq],work_bufs[dst_seq],
subseq_cols[src_seq],subseq_cols[dst_seq],
src_offset,left_boundary_odd^dst_seq,
right_boundary_odd^dst_seq,
special_first&src_seq,special_last&src_seq);
}
}
/* Fix for single sample discrepancy between VM8.5 and FDIS */
else if ((frame_cols == 1) && (left_boundary_odd))
{
for (sp=work_bufs[1], n=subseq_cols[1]; n > 0; n--)
*(sp++) <<= 1;
}
if (self->num_frames > 1)
{ /* Transfer output from `work_bufs', excluding overlap samples */
subseq_cols[0] -= ovlp_left+ovlp_right;
for (b=0; b < ((hplx_analysis_stage_ref) self)->horiz_limit; b++)
{
for (dp=src_bufs[b], sp=work_bufs[b]+(ovlp_left&(1-b)),
n=subseq_cols[b]; n > 0; n--)
*(dp++) = *(sp++);
src_bufs[b] += subseq_cols[b];
}
}
first_col_idx += frame_cols;
remaining_cols -= frame_cols;
frame_cols = self->frame_cols;
if (frame_cols > remaining_cols)
frame_cols = remaining_cols;
}
}
/* ========================================================================= */
/* ------------------ Implementation of Interface Functions ---------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -