📄 std_forward_info.c
字号:
exp_val--;
}
assert((mant_val >= 0) && (mant_val < (1<<STEP_MANTISSA_BITS)));
*exponent = exp_val;
*mantissa = mant_val;
}
/*****************************************************************************/
/* STATIC val_to_ieee32 */
/*****************************************************************************/
static void
val_to_ieee32(double step, std_uint *ieee)
/* Computes ieee 32-bit format for the value step. */
{
int exp_val, mant_val;
*ieee = 0;
if (step < 0){
*ieee = (1<<31);
step *= -1;
}
if (step == 0.0F){
return;
}
exp_val = 127;
while (step >= 2.0F)
{
step *= 0.5F;
exp_val++;
}
while (step < 1.0F && exp_val>1)
{
step *= 2.0F;
exp_val--;
}
if (step >= 1.0)
step = step-1.0;
else
exp_val--;
mant_val = (int) floor((step)*((double)(1<<23)) + 0.5);
if (mant_val == (1<<23))
{
mant_val = 0;
exp_val++;
}
assert((mant_val >= 0) && (mant_val < (1<<23)));
if (exp_val>255) exp_val = 255;
*ieee += (exp_val<<23);
*ieee += mant_val;
}
/*****************************************************************************/
/* STATIC ieee32_to_val */
/*****************************************************************************/
static double
ieee32_to_val(std_uint ieee)
/* Generates float from a ieee 32-bit format. */
{
int exp_val, mant_val, sign;
double step;
if (ieee==0) return (0.0F);
if (ieee==(1<<31)) return (-0.0F);
sign = ieee & (1<<31);
exp_val = (ieee>>23) & 255;
mant_val = ieee & ((1<<23)-1);
if (exp_val>0) mant_val += (1<<23);
else exp_val++;
step = (double)mant_val/(1<<23);
exp_val -= 127;
if (exp_val<0) step /= (1<<(-exp_val));
else step *= (1<<exp_val);
if(sign) step *= -1;
return step;
}
/* Begin David T Cvis mod */
/*****************************************************************************/
/* STATIC compute_band_nominal_ranges */
/*****************************************************************************/
static void
compute_band_nominal_ranges(std_component_info_ptr comp_info)
/* Fills in the `nominal_range' fields for each subband in the component. */
{
float image_range;
int n, b;
std_level_info_ptr lev;
std_band_info_ptr band;
image_range = (float)(1<<(comp_info->bitdepth+comp_info->sample_upshift));
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
if (!band->valid_band)
continue;
band->nominal_range = image_range * band->nominal_gain;
}
}
}
/* End David T Cvis mod */
/*****************************************************************************/
/* STATIC set_step_sizes_and_weights */
/*****************************************************************************/
/* Begin David T Cvis mod (nominal range already computed and recorded) */
static void
set_step_sizes_and_weights(std_component_info_ptr comp_info, float base_step)
/* This function fills in each subband's `rel_step_exponent',
`rel_step_mantissa' and `step_wmse' fields, based upon the `l2_norm'
value and the supplied arguments. The `base_step' value is used
only for non-reversible decompositions. */
{
int n, b, level_depth;
std_level_info_ptr lev;
std_band_info_ptr band;
int mantissa, exponent, base_mantissa, base_exponent;
step_to_exponent_mantissa(base_step,&base_exponent,&base_mantissa);
for (level_depth=0, n=comp_info->num_levels; n >= 0; n--, level_depth++)
{
lev = comp_info->levels + n;
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
if (!band->valid_band)
continue;
if (comp_info->reversible == INFO__IRREVERSIBLE)
{
float rel_step;
if (comp_info->implicit_quantization)
{
mantissa = base_mantissa;
/* SAIC General Decomp Begin mods */
exponent = base_exponent + level_depth +
(band->vert_hp_descent+band->horiz_hp_descent)/2;
if ((band->vert_hp_descent+band->horiz_hp_descent) % 2) {
/* Account for half-integer number of levels (i.e.,
horizontal and vertical subsampling factors that do not
match) */
if (mantissa >= 849) {
exponent++;
mantissa = (int) (((1 << 11) + mantissa) * 0.070106781F -
(1 << 11));
}
else {
mantissa = (int) (((1 << 11) + mantissa) * 1.414213562 -
(1 << 11));
}
}
/* SAIC General Decomp End mods */
}
else
{
rel_step = base_step / band->l2_norm;
step_to_exponent_mantissa(rel_step,&exponent,&mantissa);
}
band->rel_step_exponent = exponent;
band->rel_step_mantissa = mantissa;
rel_step = exponent_mantissa_to_step(exponent,mantissa);
rel_step *= band->l2_norm;
band->step_wmse = rel_step*rel_step;
}
else
{ /* Reversible decomposition. */
float val;
band->rel_step_mantissa = 0;
band->rel_step_exponent = 0;
val = band->nominal_range;
while (val < 1.0F)
{
val *= 2.0F;
band->rel_step_exponent--;
}
while (val > 1.1F) /* epsilon is 0.1 here */
{
val *= 0.5F;
band->rel_step_exponent++;
}
val = band->l2_norm * band->nominal_gain / band->nominal_range;
band->step_wmse = val*val;
}
/* SAIC/Fuji LRA begin */
/* Initialize visual weights */
band->csf_weight = 1.0F;
/* SAIC/Fuji LRA begin */
}
}
}
/* End David T Cvis mod (nominal range already computed and recorded) */
/*****************************************************************************/
/* STATIC is_blank_line */
/*****************************************************************************/
static int
is_blank_line(char *line)
{
while ((*line == ' ') || (*line == '\t') || (*line == '\n') ||
(*line == '\r'))
line++;
return((*line == '\0') || (*line == '#'));
}
/*****************************************************************************/
/* STATIC apply_step_quotient */
/*****************************************************************************/
static void
apply_step_quotient(std_band_info_ptr band, float factor)
{
float old_step, new_step;
int exponent, mantissa;
if (factor < 0.0F)
local_error("Illegal quantization step quotient value, %f, parsed "
"from `-Fsteps' file! Quotients must be "
"non-negative!",factor);
if (factor == 0.0F) { /* Suggestion by Margaret Lepley */
band->quant_to_zero = 1;
band->rel_step_exponent = 31;
band->rel_step_mantissa = 0;
band->step_wmse = 0;
return;
}
exponent = band->rel_step_exponent;
mantissa = band->rel_step_mantissa;
old_step = exponent_mantissa_to_step(exponent,mantissa);
new_step = old_step / factor;
step_to_exponent_mantissa(new_step,&exponent,&mantissa);
band->rel_step_exponent = exponent;
band->rel_step_mantissa = mantissa;
new_step = exponent_mantissa_to_step(exponent,mantissa);
factor = new_step / old_step;
band->step_wmse *= factor*factor;
}
/* SAIC/Fuji LRA begin */
/*****************************************************************************/
/* compute_energy_weights */
/*****************************************************************************/
/*
* Here we steal the l2_norm of the (reconstruction basis vectors for
* each subband) from std_forward_info. We square these quantities to
* get the energy weights and write them to the quantizer object.
*
* In the future we may simply copy the code from the std_forward_info
* object initialize function which computes these energy weights.
* See the mask dequantizer for how to do this.
*/
static void
compute_energy_weights(std_forward_info_ref info, lra_stats_ref lra_stats,
int comp_idx, int level_idx, int band_idx)
{
std_component_info_ptr info_comp; /* Convenience pointer */
std_level_info_ptr info_lev; /* Convenience pointer */
std_band_info_ptr info_band; /* Convenience pointer */
lra_component_info_ptr lra_comp; /* Convenience pointer */
lra_level_info_ptr lra_lev; /* Convenience pointer */
lra_band_info_ptr lra_band; /* Convenience pointer */
/* We put some simple assertions here to verify that at least
* all the dimensions are the same between the standard forward
* info object and this quantization object.
*/
if (lra_stats->components != NULL) {
assert( info->num_components == lra_stats->num_components );
info_comp = info->default_components + comp_idx;
lra_comp = lra_stats->components + comp_idx;
assert(info_comp->num_levels == lra_comp->num_levels);
info_lev = info_comp->levels + level_idx;
lra_lev = lra_comp->levels + level_idx;
assert(info_lev->min_band == lra_lev->min_band);
assert(info_lev->max_band == lra_lev->max_band);
info_band = info_lev->bands + band_idx;
lra_band = lra_lev->bands + band_idx;
/* Copy from info_info to the lra_stats object */
lra_band->energy_weight = info_band->l2_norm * info_band->l2_norm;
/* Apply square
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -