📄 std_forward_info.c
字号:
(lev->max_hp_descent - all_hp_descent)));
if (all_hp_descent < lev->max_hp_descent) {
if ((*decomp_sequence_pos + 1) > decomp_sequence_length)
local_error("Decomposition string for `-Fgen_decomp' "
"is too short. Check string to avoid errors!");
current_opcode = decomp_sequence[*decomp_sequence_pos];
(*decomp_sequence_pos)++;
}
else {
current_opcode = 0;
}
switch(current_opcode) {
case 0:
if (lev->bands != NULL) {
band = lev->bands + band_idx;
band->vert_hp_descent = vert_hp_descent;
band->horiz_hp_descent = horiz_hp_descent;
band->valid_band = 1;
for (n=0; n<chg_pos; n++) {
band->vert_hp_descent_chg[n]=vert_hp_descent_chg[n];
band->horiz_hp_descent_chg[n]=horiz_hp_descent_chg[n];
}
for (; n<4; n++) {
band->vert_hp_descent_chg[n] = 2;
band->horiz_hp_descent_chg[n] = 2;
}
}
break;
case 1:
vert_hp_descent_chg[chg_pos] = 1;
horiz_hp_descent_chg[chg_pos] = 1;
break;
case 2:
vert_hp_descent_chg[chg_pos] = 0;
horiz_hp_descent_chg[chg_pos] = 1;
break;
case 3:
vert_hp_descent_chg[chg_pos] = 1;
horiz_hp_descent_chg[chg_pos] = 0;
break;
}
if (current_opcode > 0)
decode_general_decomp_sequence(lev,level_idx,
all_hp_descent+1,
vert_hp_descent+vert_hp_descent_chg[chg_pos],
horiz_hp_descent+horiz_hp_descent_chg[chg_pos],
band_idx,decomp_sequence,decomp_sequence_pos,
1+vert_hp_descent_chg[chg_pos],
1+horiz_hp_descent_chg[chg_pos],
vert_hp_descent_chg,horiz_hp_descent_chg,chg_pos+1);
}
}
return(retval);
}
/* SAIC General Decomp. End */
/* SAIC General Decomp. Begin mods */
/*****************************************************************************/
/* STATIC build_level_structure */
/*****************************************************************************/
static void
build_level_structure(std_component_info_ptr comp_info, int use_convolution)
/* On entry, all fields of the `comp_info' structure have been completed,
except the `levels' array which has yet to be allocated. This function
allocates this array and fills out all the fields which can be completed
based upon available information. The remaining fields will be completed
to reflect quantization levels and specific Wavelet transform kernels
after this function has completed. The `use_convolution' flag is used
to determine whether non-reversible kernels should have type
INFO__FLOAT_LIFTING or INFO__CONVOLUTION. */
{
int num_levels,is_reversible,frame_width_rdx,frame_height_rdx,n,*decomp;
std_level_info_ptr lev;
int *general_decomp;
int decomp_pos = 0, prev_decomp_pos = 0;
int valid_gen_decomp_sequence = 0;
int prev_max_hp_descent = -1;
int b;
num_levels = comp_info->num_levels;
is_reversible = (comp_info->reversible == INFO__REVERSIBLE);
comp_info->levels = (std_level_info_ptr)
local_malloc(INFO_MEM_KEY,sizeof(std_level_info)*(num_levels+1));
decomp = comp_info->decomp_sequence;
frame_width_rdx = comp_info->frame.col_rdx;
frame_height_rdx = comp_info->frame.row_rdx;
general_decomp = comp_info->general_decomp_sequence;
for(n=num_levels;n>=0;n--,frame_width_rdx--,frame_height_rdx--)
{
lev = comp_info->levels + n;
if (n == 0)
lev->max_hp_descent = 0;
else
{
lev->max_hp_descent = *decomp;
assert((lev->max_hp_descent >= 1) && (lev->max_hp_descent <= 3));
if (decomp[1] != '\0')
decomp++;
}
if ((frame_width_rdx < lev->max_hp_descent) ||
(frame_height_rdx < lev->max_hp_descent))
local_error("Frame dimensions are too small for the number "
"of resolution levels in some image component. Each "
"frame must have at least one sample in each resolution "
"level!");
lev->frame.col_rdx = frame_width_rdx;
lev->frame.row_rdx = frame_height_rdx;
lev->frame.dims.cols = 1<<frame_width_rdx;
lev->frame.dims.rows = 1<<frame_height_rdx;
lev->frame.hor_ssodwt = (n <= comp_info->frame.hor_ssodwt);
lev->frame.vert_ssodwt = (n <= comp_info->frame.vert_ssodwt);
lev->frame.dims.left_col = comp_info->frame.dims.left_col;
lev->frame.dims.top_row = comp_info->frame.dims.top_row;
if (is_reversible)
lev->hor_kernel.kernel_type =
lev->vert_kernel.kernel_type = INFO__INT_LIFTING;
else if (use_convolution)
lev->hor_kernel.kernel_type =
lev->vert_kernel.kernel_type = INFO__CONVOLUTION;
else
lev->hor_kernel.kernel_type =
lev->vert_kernel.kernel_type = INFO__FLOAT_LIFTING;
if (n == 0)
lev->min_band = lev->max_band = LL_BAND;
else
{
lev->min_band = 1 << (lev->max_hp_descent+lev->max_hp_descent-2);
lev->max_band = (1<<(lev->max_hp_descent+lev->max_hp_descent))-1;
}
lev->bands = (std_band_info_ptr)
local_malloc(INFO_MEM_KEY,sizeof(std_band_info)*(lev->max_band+1));
if (general_decomp != NULL) {
int vert_hp_descent_chg[4];
int horiz_hp_descent_chg[4];
int i;
for (i=0; i<4; i++) {
vert_hp_descent_chg[i] = 2;
horiz_hp_descent_chg[i] = 2;
}
if (general_decomp[decomp_pos] == -1) {
if ((prev_max_hp_descent >= 0) && (lev->max_hp_descent > 0) &&
(prev_max_hp_descent != lev->max_hp_descent))
local_error("Decomposition string for `-Fgen_decomp' is "
"too short and cannot be used for levels with "
"different `-Fdecomp' parameters!");
decomp_pos = prev_decomp_pos;
}
prev_decomp_pos = decomp_pos;
valid_gen_decomp_sequence +=
decode_general_decomp_sequence(lev, n, 0, 0, 0, 0,
general_decomp, &decomp_pos, -1, -1,
vert_hp_descent_chg, horiz_hp_descent_chg, 0);
prev_max_hp_descent = lev->max_hp_descent;
}
else {
std_band_info_ptr band;
int i;
lev->bands[0].vert_hp_descent_chg[0] = 1;
lev->bands[0].horiz_hp_descent_chg[0] = 1;
for (b=lev->min_band; b<=lev->max_band; b++) {
band = lev->bands + b;
band->vert_hp_descent = lev->max_hp_descent;
band->horiz_hp_descent = lev->max_hp_descent;
band->valid_band = 1;
for (i=0; i<4; i++) {
band->vert_hp_descent_chg[i] = 1;
band->horiz_hp_descent_chg[i] = 1;
}
}
}
}
if ((general_decomp != NULL) && (valid_gen_decomp_sequence == 0))
local_error("Decomposition string for `-Fgen_decomp' is too long. "
"Check string to avoid errors!");
}
/* SAIC General Decomp. End mods */
/*****************************************************************************/
/* STATIC destroy_taps */
/*****************************************************************************/
static void
destroy_taps(std_tap_info_ptr taps)
{
if (taps->taps != NULL)
local_free(taps->taps);
if (taps->int_taps != NULL)
local_free(taps->int_taps);
}
/*****************************************************************************/
/* STATIC destroy_lifting */
/*****************************************************************************/
static void
destroy_lifting(std_lifting_info_ptr lifting)
{
int n;
if (lifting->steps != NULL)
{
for (n=0; n < lifting->num_steps; n++)
destroy_taps(lifting->steps + n);
local_free(lifting->steps);
}
}
/*****************************************************************************/
/* STATIC destroy_kernel */
/*****************************************************************************/
static void
destroy_kernel(std_kernel_info_ptr kernel)
{
int i;
destroy_lifting(&(kernel->lifting));
for (i=0; i < 2; i++)
{
destroy_taps(kernel->low+i);
destroy_taps(kernel->high+i);
}
}
/*****************************************************************************/
/* STATIC install_level_kernels */
/*****************************************************************************/
static void
install_level_kernels(std_level_info_ptr lev, char *id, char *kernels_dir)
{
char *hor, *vert, *dp;
int hor_len, vert_len;
if (id == NULL)
id = (lev->hor_kernel.kernel_type==INFO__INT_LIFTING)?"W5X3":"W9X7";
hor = id;
vert = strchr(id,',');
if (vert == NULL)
{
vert = id;
hor_len = vert_len = strlen(id);
}
else
{
hor_len = vert-hor;
vert++;
vert_len = strlen(vert);
}
lev->hor_identifier = dp = (char *)
local_malloc(INFO_MEM_KEY,hor_len+1);
while (hor_len--)
*(dp++) = *(hor++);
*dp = '\0';
lev->vert_identifier = dp = (char *)
local_malloc(INFO_MEM_KEY,vert_len+1);
while (vert_len--)
*(dp++) = *(vert++);
*dp = '\0';
/* Now we are ready to load the kernel specification. */
lev->hor_kernel_user_defined =
std_load_kernel(lev->hor_identifier,kernels_dir,&(lev->hor_kernel));
lev->vert_kernel_user_defined =
std_load_kernel(lev->vert_identifier,kernels_dir,&(lev->vert_kernel));
}
/*****************************************************************************/
/* STATIC install_component_kernels */
/*****************************************************************************/
static void
install_component_kernels(std_component_info_ptr comp_info,
char *kernel_ids[], int num_ids,
char *kernels_dir)
{
int n;
char *id;
id = NULL;
for (n=comp_info->num_levels; n > 0; n--, kernel_ids++, num_ids--)
{
if (num_ids > 0)
id = *kernel_ids;
install_level_kernels(comp_info->levels+n,id,kernels_dir);
}
}
/*****************************************************************************/
/* STATIC convolve_waveforms */
/*****************************************************************************/
static void
convolve_waveforms(std_tap_info_ptr synth, std_tap_info_ptr in,
std_tap_info_ptr out, int interp_factor)
/* This function is key to the determination of synthesis waveforms and their
L2-norms. Essentially, the function takes the synthesis waveform provided
via the `synth' argument, interpolates by `interp_factor', inserting
`interp_factor'-1 zeros between the entries, and convolves with the
filter represented by `in', writing the result into `out'. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -