📄 std_reverse_info.c
字号:
}
}
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; /* TJF: =0 to avoid warnings */
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 copy_taps */
/*****************************************************************************/
static void
copy_taps(std_tap_info_ptr src, std_tap_info_ptr dest)
{
int support, t;
support = src->neg_support + src->pos_support + 1;
*dest = *src;
if (src->taps != NULL)
{
dest->taps = (float *)
local_malloc(INFO_MEM_KEY,sizeof(float)*support);
for (t=0; t < support; t++)
dest->taps[t] = src->taps[t];
}
if (src->int_taps != NULL)
{
dest->int_taps = (int *)
local_malloc(INFO_MEM_KEY,sizeof(int)*support);
for (t=0; t < support; t++)
dest->int_taps[t] = src->int_taps[t];
}
}
/*****************************************************************************/
/* STATIC copy_kernel */
/*****************************************************************************/
static void
copy_kernel(std_kernel_info_ptr src, std_kernel_info_ptr dest)
{
std_lifting_info_ptr src_lift, dest_lift;
int num_steps, n;
dest->kernel_type = src->kernel_type;
src_lift = &(src->lifting);
dest_lift = &(dest->lifting);
num_steps = src_lift->num_steps;
dest_lift->num_steps = num_steps;
dest_lift->steps = (std_tap_info_ptr)
local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
for (n=0; n < num_steps; n++)
copy_taps(src_lift->steps+n,dest_lift->steps+n);
dest_lift->lp_scale = src_lift->lp_scale;
dest_lift->hp_scale = src_lift->hp_scale;
for (n=0; n < 2; n++)
{
copy_taps(src->low+n,dest->low+n);
copy_taps(src->high+n,dest->high+n);
}
}
/*****************************************************************************/
/* STATIC exponent_mantissa_to_step */
/*****************************************************************************/
static float
exponent_mantissa_to_step(int exponent, int mantissa)
/* Computes a relative or absolute step size as 2{-E} * (1+2^{-Mbits)*M),
where E is the `exponent' value, M is the `mantissa' value and
Mbits is the STEP_MANTISSA_BITS constant. */
{
float step;
assert((mantissa >= 0) && (mantissa < (1<<STEP_MANTISSA_BITS)));
step = 1.0F + ((float) mantissa) / ((float)(1<<STEP_MANTISSA_BITS));
while (exponent > 0)
{
step *= 0.5F;
exponent--;
}
while (exponent < 0)
{
step *= 2.0F;
exponent++;
}
return(step);
}
/*****************************************************************************/
/* 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;
}
/*****************************************************************************/
/* STATIC retrieve_size_info_from_stream */
/*****************************************************************************/
static void
retrieve_size_info_from_stream(stream_in_ref stream,
canvas_dims_ptr grid_dims,
canvas_dims_ptr tile_dims,
int num_components,
std_component_info_ptr components)
/* Retrieves canvas and image component dimensions and precision information
from the SIZ marker. */
{
int n;
grid_dims->left_col =
stream->get_marker_val(stream,-1,MARKER_SIZ_XO,0,0);
grid_dims->top_row =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -