hplx_hor_synthesis_by_lifting.c
来自「JPEG2000实现的源码」· C语言 代码 · 共 929 行 · 第 1/3 页
C
929 行
/* ========================================================================= */
/* ------------------ 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_hor_synthesis_by_lifting_ref self =
(hplx_hor_synthesis_by_lifting_ref) base;
frame_info frame;
int b, n;
/* Begin by determining the Wavelet kernels and derivative properties. */
self->kernel_type =
info->get_kernel_type(info,base->direction,INFO__SYNTHESIS,
base->component_idx,base->level_idx,NULL,NULL,
NULL,NULL);
if (self->kernel_type == INFO__INT_LIFTING)
{
self->num_steps =
info->get_int_steps(info,base->direction,base->component_idx,
base->level_idx,self->neg_supports,
self->pos_supports,self->int_taps,
self->int_downshifts);
}
else if (self->kernel_type == INFO__FLOAT_LIFTING)
{
self->num_steps =
info->get_float_steps(info,base->direction,base->component_idx,
base->level_idx,self->neg_supports,
self->pos_supports,self->float_taps,
self->branch_scale,self->branch_scale+1);
for (b=0; b < base->horiz_limit; b++)
self->branch_scale[b] = 1.0F / self->branch_scale[b];
}
else
assert(0);
for (n=0; n < self->num_steps; n++)
{
if (self->neg_supports[n] > self->neg_extend)
self->neg_extend = self->neg_supports[n];
if (self->pos_supports[n] > self->pos_extend)
self->pos_extend = self->pos_supports[n];
}
if (self->kernel_type == INFO__FLOAT_LIFTING)
{ /* Compute DC gains associated with the output of each update lifting
step, i.e. the 1'st, 3'rd, ... lifting steps. */
float current_gain, source_gain, step_gain;
int k;
for (n=0; n < self->num_steps; n++)
{
current_gain = (n>=2)?(self->step_dc_gains[n-2]):1.0F;
source_gain = (n>=1)?(self->step_dc_gains[n-1]):1.0F;
step_gain = 0.0F;
for (k=-self->neg_supports[n]; k <= self->pos_supports[n]; k++)
step_gain += (self->float_taps[n])[k];
self->step_dc_gains[n] = current_gain + step_gain*source_gain;
}
for (current_gain=1.0F, n=1; n < self->num_steps; n+=2)
{ /* This step ensures that the update lifting steps identify
the incremental DC gain relative to the output of the previous
update step, rather than the absolute DC gain at the end of
each step. */
step_gain = self->step_dc_gains[n] / current_gain;
current_gain = self->step_dc_gains[n];
self->step_dc_gains[n] = step_gain;
}
}
/* Now determine tile and frame dimensions and attributes. */
self->tile_width = dims->cols;
self->first_idx = dims->left_col;
info->get_level_info(info,base->component_idx,base->level_idx,
NULL,NULL,&frame,NULL);
if (frame.hor_ssodwt)
{ /* Set up frame dimensions. */
self->frame_cols = frame_dims->cols;
self->frame_ref = frame_dims->left_col;
self->first_frame_cols = self->frame_cols -
((self->first_idx - self->frame_ref) & (self->frame_cols - 1));
if (self->first_frame_cols >= self->tile_width)
{
self->first_frame_cols = self->tile_width;
self->num_frames = 1;
}
else
self->num_frames = 2 +
(self->tile_width - self->first_frame_cols - 1) / self->frame_cols;
}
else
{ /* No frames, set frame dimensions to refer to the entire tile. */
self->num_frames = 1;
self->frame_cols = self->first_frame_cols = self->tile_width;
self->frame_ref = self->first_idx;
}
/* Finally, perform branch-specific initialization. */
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;
left = (left+1-b)>>1;
right = (right-b)>>1;
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;
}
if (self->kernel_type == INFO__INT_LIFTING)
{
self->branch_buf_int[b] = (ifc_int *)
local_malloc(XFORM_HBUF_KEY,sizeof(ifc_int)*
(branch_dims.cols+self->neg_extend+self->pos_extend+1));
self->branch_buf_int[b] += self->neg_extend;
}
else if (self->kernel_type == INFO__FLOAT_LIFTING)
{
self->branch_buf_float[b] = (float *)
local_malloc(XFORM_HBUF_KEY,sizeof(float)*
(branch_dims.cols+self->neg_extend+self->pos_extend+1));
self->branch_buf_float[b] += self->neg_extend;
}
else
assert(0);
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_lifting_ref self =
(hplx_hor_synthesis_by_lifting_ref) base;
int n, b, first_sample_odd;
assert(base->use_floats);
assert(width == self->tile_width);
if (width == 0)
return;
assert(self->kernel_type == INFO__FLOAT_LIFTING);
first_sample_odd = self->first_idx & 1;
if (base->horiz_limit > 1) {
for (b=0; b < base->horiz_limit; b++)
{ /* Retrieve even and odd bands */
base->branches[b]->pull_line_float(base->branches[b],
self->branch_buf_float[b],
(width+1-(b^first_sample_odd))>>1);
}
undo_1d_float_lifting(self);
for (b=0; b < base->horiz_limit; b++)
{ /* Interleave even and odd sub-sequences. */
float *sp, *dp;
for (dp=line_buf+b, sp=self->branch_buf_float[b^first_sample_odd],
n=(width+1-b)>>1; n > 0; n--, dp+=2, sp++)
*dp = *sp;
}
}
else {
base->branches[0]->pull_line_float(base->branches[0], line_buf, width);
}
}
/*****************************************************************************/
/* __pull_line_fixed */
/*****************************************************************************/
static void
__pull_line_fixed(hplx_synthesis_stage_ref base, ifc_int *line_buf,
int width)
{
hplx_hor_synthesis_by_lifting_ref self =
(hplx_hor_synthesis_by_lifting_ref) base;
int n, b, first_sample_odd;
assert(width == self->tile_width);
if (width == 0)
return;
first_sample_odd = self->first_idx & 1;
if (self->kernel_type == INFO__FLOAT_LIFTING)
{
assert(base->use_floats);
if (base->horiz_limit > 1) {
for (b=0; b < base->horiz_limit; b++)
{ /* Retrieve even and odd bands */
base->branches[b]->pull_line_float(base->branches[b],
self->branch_buf_float[b],
(width+1-(b^first_sample_odd))>>1);
}
undo_1d_float_lifting(self);
for (b=0; b < base->horiz_limit; b++)
{ /* Convert and interleave even and odd sub-sequences. */
ifc_int *dp;
float *sp, val;
for (dp=line_buf+b, sp=self->branch_buf_float[b^first_sample_odd],
n=(width+1-b)>>1; n > 0; n--, dp+=2, sp++)
{
val = *sp;
*dp = (ifc_int)((val<0.0F)?(val-0.5F):(val+0.5F));
}
}
}
else {
ifc_int *dp;
float *sp, *tmp_buf;
tmp_buf = (float *) local_malloc(XFORM_MEM_KEY, width*sizeof(float));
base->branches[0]->pull_line_float(base->branches[0], tmp_buf, width);
for (dp=line_buf, sp=tmp_buf, n=width; n > 0; n--)
*(dp++) = (ifc_int) *(sp++);
}
}
else if (self->kernel_type == INFO__INT_LIFTING)
{
assert(!base->use_floats);
if (base->horiz_limit > 1) {
for (b=0; b < base->horiz_limit; b++)
{ /* Retrieve even and odd bands */
base->branches[b]->pull_line_fixed(base->branches[b],
self->branch_buf_int[b],
(width+1-(b^first_sample_odd))>>1);
}
undo_1d_int_lifting(self);
for (b=0; b < base->horiz_limit; b++)
{ /* Interleave even and odd sub-sequences. */
ifc_int *sp, *dp;
for (dp=line_buf+b, sp=self->branch_buf_int[b^first_sample_odd],
n=(width+1-b)>>1; n > 0; n--, dp+=2, sp++)
*dp = *sp;
}
}
else {
base->branches[0]->pull_line_fixed(base->branches[0], line_buf, width);
}
}
else
assert(0);
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(hplx_synthesis_stage_ref base)
{
hplx_hor_synthesis_by_lifting_ref self =
(hplx_hor_synthesis_by_lifting_ref) base;
int b;
for (b=0; b < base->horiz_limit; b++)
{
if (self->branch_buf_float[b] != NULL)
local_free(self->branch_buf_float[b]-self->neg_extend);
if (self->branch_buf_int[b] != NULL)
local_free(self->branch_buf_int[b]-self->neg_extend);
base->branches[b]->terminate(base->branches[b]);
if (self->frame_work_buf_float[b] != NULL)
local_free(self->frame_work_buf_float[b]-self->neg_extend);
if (self->frame_work_buf_int[b] != NULL)
local_free(self->frame_work_buf_int[b]-self->neg_extend);
}
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_hplx_hor_synthesis_by_lifting */
/*****************************************************************************/
hplx_synthesis_stage_ref
create_hplx_hor_synthesis_by_lifting(void)
{
hplx_hor_synthesis_by_lifting_ref result;
result = (hplx_hor_synthesis_by_lifting_ref)
local_malloc(XFORM_MEM_KEY,sizeof(hplx_hor_synthesis_by_lifting_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 + =
减小字号Ctrl + -
显示快捷键?