📄 hplx_info.c
字号:
complete_1d_filter_bank(lev->vert_low,lev->vert_high,
lev->vert_low+1,lev->vert_high+1);
for (n=1; n < levels; n++)
for (i=0; i < 2; i++)
{ /* Copy filter information into the other levels. */
copy_tap_info(lev[n-1].hor_low+i,lev[n].hor_low+i);
copy_tap_info(lev[n-1].hor_high+i,lev[n].hor_high+i);
copy_tap_info(lev[n-1].vert_low+i,lev[n].vert_low+i);
copy_tap_info(lev[n-1].vert_high+i,lev[n].vert_high+i);
}
/* Now fill out the quantization and range information for each band. */
conv_h1.neg_support = conv_h1.pos_support = 0;
conv_h1.taps = (float *)
local_malloc(sizeof(float));
conv_h1.taps[0] = 1.0F;
conv_h2.neg_support = conv_h2.pos_support = 0;
conv_h2.taps = (float *)
local_malloc(sizeof(float));
conv_h2.taps[0] = 1.0F;
conv_v1.neg_support = conv_v1.pos_support = 0;
conv_v1.taps = (float *)
local_malloc(sizeof(float));
conv_v1.taps[0] = 1.0F;
conv_v2.neg_support = conv_v2.pos_support = 0;
conv_v2.taps = (float *)
local_malloc(sizeof(float));
conv_v2.taps[0] = 1.0F;
lev = comp_info->levels + levels - 1; /* Highest resolution level. */
ideal_norm = 1.0F;
for (n=levels-1; n >= 0; n--, lev--)
{
vert_high_norm =
convolve_and_get_norm(lev->vert_high+1,&conv_v1,&conv_v2,
1<<(levels-1-n));
vert_low_norm = save_vert_low_norm =
convolve_and_get_norm(lev->vert_low+1,&conv_v1,&conv_v2,
1<<(levels-1-n));
tmp_taps = conv_v1; conv_v1 = conv_v2; conv_v2 = tmp_taps;
hor_high_norm =
convolve_and_get_norm(lev->hor_high+1,&conv_h1,&conv_h2,
1<<(levels-1-n));
hor_low_norm = save_hor_low_norm =
convolve_and_get_norm(lev->hor_low+1,&conv_h1,&conv_h2,
1<<(levels-1-n));
tmp_taps = conv_h1; conv_h1 = conv_h2; conv_h2 = tmp_taps;
ideal_norm *= 2.0F;
lev->bands[LL_BAND].step_size =
base_step / (hor_low_norm*vert_low_norm);
lev->bands[HL_BAND].step_size =
base_step / (hor_high_norm*vert_low_norm);
lev->bands[LH_BAND].step_size =
base_step / (hor_low_norm*vert_high_norm);
lev->bands[HH_BAND].step_size =
base_step / (hor_high_norm*vert_high_norm);
for (i=0; i < 4; i++)
{
lev->bands[i].step_wmse = mse;
if (comp_info->ideal_quant)
{
factor = (base_step / ideal_norm) / lev->bands[i].step_size;
lev->bands[i].step_size *= factor;
lev->bands[i].step_wmse *= factor * factor;
}
lev->bands[i].nearest_exponent =
get_nearest_exponent(lev->bands[i].step_size);
if (comp_info->radix_quant)
{
if (lev->bands[i].nearest_exponent >= 0)
factor = (float)(1<<lev->bands[i].nearest_exponent);
else
factor = 1.0F/(float)(1<<-lev->bands[i].nearest_exponent);
factor = factor / lev->bands[i].step_size;
lev->bands[i].step_size *= factor;
lev->bands[i].step_wmse *= factor * factor;
}
lev->bands[i].extra_lsbs =
get_extra_lsbs(lev->bands[i].step_size,nom_range);
while (lev->bands[i].extra_lsbs < min_extra_lsbs)
{
lev->bands[i].extra_lsbs++;
lev->bands[i].step_size *= 2.0F;
lev->bands[i].nearest_exponent++;
lev->bands[i].step_wmse *= 4.0F;
}
}
}
local_free(conv_h1.taps);
local_free(conv_h2.taps);
local_free(conv_v1.taps);
local_free(conv_v2.taps);
comp_info->id_copy = (char *)
local_malloc(strlen(id)+1);
strcpy(comp_info->id_copy,id);
}
/* Finally, let's parse the command line arguments. */
for (; argc > 2; argc--, argv++)
if (strcmp(*argv,"-Fweights") == 0)
{
int min_comp, max_comp, success, min_band, max_band;
float weight;
double wt;
char *ch;
*(argv++) = ""; argc--;
ch = strchr(*argv,'-');
if (ch == NULL)
{
success = sscanf(*argv,"%d",&min_comp);
max_comp = min_comp;
}
else
{
*ch = '\0';
success =
sscanf(*argv,"%d",&min_comp) && sscanf(ch+1,"%d",&max_comp);
*ch = '-';
}
if ((!success) || (min_comp > max_comp) ||
(min_comp < 1) || (max_comp > components))
{
fprintf(stderr,"Invalid component range specifier found with\n"
" the \"-Fweights\" argument!\n");
exit(-1);
}
min_comp--;
max_comp--;
*(argv++) = ""; argc--;
weight = 1.0F;
for (n=0; n < levels; n++)
{
lev = self->components[min_comp].levels+n;
min_band = lev->min_band;
max_band = lev->max_band;
for (i=min_band; i <= max_band; i++)
{
if (argc > 0)
{
if (sscanf(*argv,"%lf",&wt))
{ weight = (float) wt; *(argv++) = ""; argc--; }
else
argc = 0;
}
for (comp=min_comp; comp <= max_comp; comp++)
{
lev = self->components[comp].levels+n;
lev->bands[i].step_wmse *= weight;
}
}
}
while (argc > 0)
{ /* Flush any extra parameters. */
if (sscanf(*argv,"%lf",&wt))
{ *(argv++) = ""; argc--; }
else
argc = 0;
}
}
}
/*****************************************************************************/
/* STATIC __print_usage */
/*****************************************************************************/
static void
__print_usage(filter_info_ref base, FILE *dest)
{
fprintf(dest,">> HP Filter Info Object arguments:\n"
" -Fweights <c>|(<c1>-<c2>) <w1> <w2> ... (default: no weighting)\n"
" -- Specifies visual weighting factors to be applied to the\n"
" MSE contribution of each subband in one or more components.\n"
" A single component index <c>, or a set of component indices,\n"
" <c1>-<c2>, may be specified where c runs from 1 through to\n"
" the number of components (usually colour components).\n"
" Separate weights are supplied for every subband, starting\n"
" from the LL band and working through each resolution level in\n"
" the order HL, (horizontally high-pass), LH then HH.\n"
" It is legal to supply too many factors or too few factors;\n"
" if too few are supplied, the last specified factor will be\n"
" applied to all remaining subbands in the relevant components.\n"
" The argument may be used multiple times to specify different\n"
" sets of weights for different components or sets of\n"
" components. The argument will usually only affect the\n"
" behaviour of the compression algorithm, not decompression.\n");
}
/*****************************************************************************/
/* STATIC __get_taps */
/*****************************************************************************/
static float *
__get_taps(filter_info_ref base, int flags, int component_idx,
int level_idx, int *neg_support, int *pos_support, char **id)
{
my_filter_info_ref self = (my_filter_info_ref) base;
component_info_ptr comp_info;
level_info_ptr lev;
tap_info_ptr taps;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(level_idx < comp_info->num_levels));
lev = comp_info->levels + level_idx;
if (flags & FILTER__HIGH)
taps = (flags & FILTER__VERT)?(lev->vert_high):(lev->hor_high);
else
taps = (flags & FILTER__VERT)?(lev->vert_low):(lev->hor_low);
if (flags & FILTER__SYNTH)
taps++;
*neg_support = taps->neg_support;
*pos_support = taps->pos_support;
if (id != NULL)
*id = comp_info->id_copy;
return(taps->taps);
}
/*****************************************************************************/
/* STATIC __get_quant_info */
/*****************************************************************************/
static void
__get_quant_info(filter_info_ref base, int component_idx, int level_idx,
int band_idx, float *step_size, int *nearest_exponent,
float *step_wmse, int *extra_lsbs)
{
my_filter_info_ref self = (my_filter_info_ref) base;
component_info_ptr comp_info;
level_info_ptr lev;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(level_idx <= comp_info->num_levels));
lev = comp_info->levels + level_idx;
assert((band_idx >= lev->min_band) && (band_idx <= lev->max_band));
if (step_size != NULL)
*step_size = lev->bands[band_idx].step_size;
if (nearest_exponent != NULL)
*nearest_exponent = lev->bands[band_idx].nearest_exponent;
if (step_wmse != NULL)
*step_wmse = lev->bands[band_idx].step_wmse;
if (extra_lsbs != NULL)
*extra_lsbs = lev->bands[band_idx].extra_lsbs;
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(filter_info_ref base)
{
my_filter_info_ref self = (my_filter_info_ref) base;
component_info_ptr comp_info;
level_info_ptr lev;
int i, n, comp;
if (self->components == NULL)
return;
for (comp=0; comp < self->num_components; comp++)
{
comp_info = self->components + comp;
for (lev=comp_info->levels, n=0; n < comp_info->num_levels; n++, lev++)
for (i=0; i < 2; i++)
{
local_free(lev->hor_low[i].taps);
local_free(lev->hor_high[i].taps);
local_free(lev->vert_low[i].taps);
local_free(lev->vert_high[i].taps);
}
local_free(comp_info->levels);
if (comp_info->id_copy != NULL)
local_free(comp_info->id_copy);
}
local_free(self->components);
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_filter_info */
/*****************************************************************************/
filter_info_ref
create_filter_info(void)
{
my_filter_info_ref result;
result = (my_filter_info_ref)
local_malloc(sizeof(my_filter_info_obj));
memset(result,0,sizeof(my_filter_info_obj));
result->base.initialize = __initialize;
result->base.print_usage = __print_usage;
result->base.get_taps = __get_taps;
result->base.get_quant_info = __get_quant_info;
result->base.terminate = __terminate;
return((filter_info_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -