📄 hplx_analysis.c
字号:
orient = LL_BAND;
else if ((vert_idx == 0) && (hor_idx == 1))
orient = HL_BAND;
else if ((vert_idx == 1) && (hor_idx == 0))
orient = LH_BAND;
else
orient = HH_BAND;
band_idx = root_band_idx + orient *
(1 << 2*(remaining_hp_descent - 1));
info->get_band_info(info,component_idx,num_levels,band_idx,
NULL,NULL,&vert_hp_descent,&horiz_hp_descent,NULL,NULL,NULL);
if (band_idx == 0)
{ /* Must be the LL band for the level. Propagate split into
next level. */
assert(first_split_in_level);
stage->branches[hor_idx] =
create_decomposition_tree(num_levels-1,component_idx,info,
quantizer,use_floats,0,0,
usePsExtension,sso_ext,
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
otlpf_convention,
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
/* SAIC/Sharp/Fuji Xmask begin */
encoder, alpha, beta,
minlevel, win_width, bits_retained,
respect_block_boundaries,
/* SAIC/Sharp/Fuji Xmask end */
0, 0, 0, 0,
new_decomp_sequence,
&new_decomp_sequence_pos,
first_max_horiz_hp_descent,
first_max_vert_hp_descent);
}
else if ((remaining_hp_descent > 1) &&
((remaining_max_vert_hp_descent >
(first_max_vert_hp_descent - vert_hp_descent + 1)) ||
((remaining_max_horiz_hp_descent >
(first_max_horiz_hp_descent - horiz_hp_descent + 1)))))
{ /* Band needs to be further decomposed within current level. */
int new_vert_limit=2, new_horiz_limit=2;
int new_remaining_max_vert_hp_descent = remaining_max_vert_hp_descent-1;
int new_remaining_max_horiz_hp_descent = remaining_max_horiz_hp_descent-1;
current_opcode = decomp_sequence[*decomp_sequence_pos];
(*decomp_sequence_pos)++;
assert(current_opcode > 0);
switch (current_opcode) {
case 1:
new_vert_limit = 2;
new_horiz_limit = 2;
new_remaining_max_vert_hp_descent = remaining_max_vert_hp_descent-1;
new_remaining_max_horiz_hp_descent = remaining_max_horiz_hp_descent-1;
break;
case 2:
new_vert_limit = 1;
new_horiz_limit = 2;
new_remaining_max_vert_hp_descent = remaining_max_vert_hp_descent;
new_remaining_max_horiz_hp_descent = remaining_max_horiz_hp_descent-1;
break;
case 3:
new_vert_limit = 2;
new_remaining_max_vert_hp_descent = remaining_max_vert_hp_descent-1;
new_remaining_max_horiz_hp_descent = remaining_max_horiz_hp_descent;
new_horiz_limit = 1;
break;
}
stage->branches[hor_idx] =
create_decomposition_tree(num_levels,component_idx,info,
quantizer,use_floats,
remaining_hp_descent-1,band_idx,
usePsExtension,sso_ext,
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
otlpf_convention,
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
/* SAIC/Sharp/Fuji Xmask begin */
encoder, alpha, beta,
minlevel, win_width, bits_retained,
respect_block_boundaries,
/* SAIC/Sharp/Fuji Xmask end */
new_vert_limit, new_horiz_limit,
new_remaining_max_vert_hp_descent,
new_remaining_max_horiz_hp_descent,
decomp_sequence,
decomp_sequence_pos,
first_max_horiz_hp_descent,
first_max_vert_hp_descent);
}
else
{ /* Band is finished. */
hplx_analysis_stage_ref leaf;
if (remaining_hp_descent > 1) {
current_opcode = decomp_sequence[*decomp_sequence_pos];
assert(current_opcode == 0);
(*decomp_sequence_pos)++;
}
leaf = create_hplx_analysis_leaf();
leaf->sso_ext = sso_ext;
leaf->use_floats = use_floats;
leaf->component_idx = component_idx;
leaf->level_idx = num_levels;
leaf->direction = 0;
leaf->quant = quantizer;
leaf->usePsExtension = usePsExtension;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
result->otlpf_convention = otlpf_convention;
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
/* SAIC/Fuji LRA begin */
if (info->set_stats != NULL)
leaf->get_lra_stats = 1;
/* SAIC/Fuji LRA end */
/* SAIC/Sharp/Fuji Xmask begin */
leaf->encoder = encoder;
leaf->alpha = alpha;
leaf->beta = beta;
leaf->minlevel = minlevel;
leaf->win_width = win_width;
leaf->bits_retained = bits_retained;
leaf->respect_block_boundaries = respect_block_boundaries;
leaf->info = info;
/* SAIC/Sharp/Fuji Xmask end */
leaf->band_idx = band_idx;
leaf->branches[0] = leaf->branches[1];
stage->branches[hor_idx] = leaf;
}
}
}
return(result);
}
/* SAIC General Decomp. End mods */
/* SAIC/Sharp/Fuji Xmask begin */
/*****************************************************************************/
/* STATIC apply_visual_mask_float */
/*****************************************************************************/
static void
apply_visual_mask_float(hplx_analysis_stage_ref base, float *line_buf,
int width)
/* This function applies an extended visual mask to floating point data. */
{
forward_info_ref info = base->info;
encoder_ref encoder = base->encoder;
float **prev_rows = base->prev_rows;
float alpha = base->alpha;
float beta = base->beta;
float norm;
float scale;
float step_size;
float *sp;
float *buf_pt0, *buf_pt1,wt;
float *lut_alpha = base->lut_alpha;
float *lut_beta_alpha = base->lut_beta_alpha;
int level_idx = base->level_idx;
int band_idx = base->band_idx;
int minlevel = base->minlevel;
int component_idx = base->component_idx;
int block_height;
int block_width;
int respect_block_boundaries = base->respect_block_boundaries;
int bits_lost = IMPLEMENTATION_PRECISION - base->bits_retained;
/* "bits_lost" least significant bits will be discarded, 22 is good
for 0.5bpp and alpha=0.7, 23 is good for alpha=0.8 at 0.5bpp */
int lower_ht_limit, lower_wd_limit, upper_wd_limit;
int win_width = base->win_width;
int M=(win_width*2+1+1)*win_width; /* causal neighborhood size */
int upshift;
int tmp;
ifc_int val;
int extra_lsbs;
int sample_upshift;
long one_upshifted;
long tmp_mod;
int i, j, k;
encoder->get_block_ht_wd(encoder,component_idx, level_idx, band_idx,
&block_height,&block_width);
info->get_quant_info(info, component_idx, level_idx, band_idx,
&step_size, NULL, NULL, &extra_lsbs, NULL, NULL);
if (!respect_block_boundaries) {
block_height = -1;
block_width = width;
}
if (extra_lsbs >= 0)
scale = ((float)(1<<extra_lsbs)) / step_size;
else
scale = 1.0F / (step_size * ((float)(1<<-extra_lsbs)));
info->get_var_tile_info(info,component_idx,NULL,NULL,NULL,&sample_upshift,NULL);
upshift = sample_upshift;
one_upshifted = (1<< upshift);
if (prev_rows == NULL) {
prev_rows = base->prev_rows = (float **) local_malloc(XFORM_HBUF_KEY,
(2*win_width+1)*sizeof(float *));
for (i=0; i<2*win_width+1; i++) {
prev_rows[i] = (float *) local_malloc(XFORM_HBUF_KEY,
(width + 2*win_width)*sizeof(float));
memset(prev_rows[i], 0, (width + 2*win_width)*sizeof(float));
}
}
if (lut_alpha == NULL) {
lut_alpha = base->lut_alpha =
(float *) local_malloc(XFORM_HBUF_KEY, 1025*sizeof(float));
lut_beta_alpha = base->lut_beta_alpha =
(float *) local_malloc(XFORM_HBUF_KEY, 1025*sizeof(float));
for (i=0; i<1025; i++) {
lut_alpha[i] = (float) pow(i, alpha);
lut_beta_alpha[i] = (float) pow(i, beta/alpha);
}
}
/**extended nonlinearity: c'=c^alpha/(1+(\sum c_i^beta)/M/norm);**/
norm = (float)
pow(0.25*((double)MAX_IFC_INT)/(1<< upshift)*0.0001,beta);
buf_pt0=&(prev_rows[win_width][win_width]);
lower_ht_limit = MAX(-win_width, base->lowest_ht_limit);
for (sp=line_buf, i=0; i<width; i++, sp++) {
if (level_idx >= minlevel) {
wt = 0.0;
if (beta != 0.0) {
lower_wd_limit = MAX(-win_width, (i/block_width)*block_width - i);
upper_wd_limit = MIN(win_width, ((i/block_width) + 1)*block_width - i);
for (j=lower_ht_limit; j<0; j++) {
for (k=lower_wd_limit; k<=upper_wd_limit; k++) {
wt+=prev_rows[win_width+j][i+k+win_width];
}
}
for (j=lower_wd_limit; j<0; j++) {
wt+=prev_rows[win_width][i+j+win_width];
}
wt/=M;
wt/=norm;
}
wt+=1;
/* better to do power function of "un-shifted" value, to keep quantization precision
(i.e., scale) invariant to alpha */
tmp = (int) fabs(*sp)/one_upshifted;
tmp_mod=((ifc_int) fabs(*sp)) % one_upshifted;
if (tmp>1023)
{
local_printf(0, 80, "tmp greater than 1023, tmp= %d \n", tmp);
tmp=1023;
}
val=(ifc_int) ((lut_alpha[tmp] + tmp_mod*(lut_alpha[tmp+1] -
lut_alpha[tmp])/one_upshifted)*one_upshifted/wt);
val=(*sp>=0)?val:-val;
*sp = (float) val;
if (beta != 0.0) {
val=(ifc_int) (val*scale); /* nonlinear mapping first, then quantization */
/* use quantized val to calculate masking weight */
tmp=abs(val)>>bits_lost; /*discard least signif. bits */
tmp=tmp<<bits_lost;
/*implement *buf_pt0=pow(tmp*wt/scale/(1<< upshift), beta/alpha);*/
tmp = (int) (tmp*wt/scale / one_upshifted);
tmp_mod = ((int) (tmp*wt/scale)) % one_upshifted;
if (tmp>1023)
{
local_printf(0, 80, "tmp greater than 1023 =%d \n", tmp);
tmp=1023;
}
*buf_pt0=lut_beta_alpha[tmp] + tmp_mod*(lut_beta_alpha[tmp+1] - lut_beta_alpha[tmp])/one_upshifted;
buf_pt0++;
}
}
}
if ((abs(base->lowest_ht_limit)+1) == block_height)
base->lowest_ht_limit = 0;
else
base->lowest_ht_limit--;
for (i=0; i<win_width; i++) {
buf_pt0 = &prev_rows[i][win_width];
buf_pt1 = &prev_rows[i+1][win_width];
for (j=0; j<width; j++) *buf_pt0++ = *buf_pt1++;
}
}
/*****************************************************************************/
/* STATIC destroy_Xmask_prev_rows */
/*****************************************************************************/
static void
destroy_Xmask_prev_rows(hplx_analysis_stage_ref base)
{
if ((base->branches[0] == NULL) && (base->branches[1] == NULL))
{
int i;
if (base->prev_rows != NULL) {
for (i=0; i<2*base->win_width+1; i++) {
if (base->prev_rows[i] != NULL) local_free(base->prev_rows[i]);
}
local_free(base->prev_rows);
local_free(base->lut_alpha);
local_free(base->lut_beta_alpha);
base->prev_rows = NULL;
}
}
else
{
destroy_Xmask_prev_rows(base->branches[0]);
destroy_Xmask_prev_rows(base->branches[1]);
}
}
/* SAIC/Sharp/Fuji Xmask end */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -