📄 std_forward_info.c
字号:
/*****************************************************************************/
/* STATIC initialize_tiles */
/*****************************************************************************/
static void
initialize_tiles(std_forward_info_ref self)
/* Sets the coordinates for each tile in the newly created array of tiles
referenced from `self' and initializes the `components' field for each
tile to point to the `default_components' array in the `self' object,
corresponding to the default coding parameters. */
{
canvas_dims_ptr tile_ref, grid_ref;
std_tile_info_ptr info;
int tiles_wide, tiles_high, left, top, next_left, next_top, r, c, idx;
tile_ref = &(self->tile_dims);
grid_ref = &(self->grid_dims);
tiles_wide = self->tiles_wide;
tiles_high = self->tiles_high;
assert((tiles_wide > 0) && (tiles_high > 0));
for (idx=0, top=tile_ref->top_row,r=0; r < tiles_high; r++, top=next_top)
{
next_top = top + tile_ref->rows;
if (top < grid_ref->top_row)
top = grid_ref->top_row;
if (next_top > (grid_ref->top_row+grid_ref->rows))
next_top = grid_ref->top_row + grid_ref->rows;
for (left=tile_ref->left_col,c=0;c<tiles_wide;c++,left=next_left,idx++)
{
next_left = left + tile_ref->cols;
if (left < grid_ref->left_col)
left = grid_ref->left_col;
if (next_left > (grid_ref->left_col+grid_ref->cols))
next_left = grid_ref->left_col + grid_ref->cols;
info = self->tiles + idx;
info->idx = idx;
info->x_idx = c;
info->y_idx = r;
info->components = self->default_components;
info->dims.left_col = left;
info->dims.top_row = top;
info->dims.cols = next_left - left;
info->dims.rows = next_top - top;
}
}
}
/*****************************************************************************/
/* STATIC set_frame_parameters */
/*****************************************************************************/
static void
set_frame_parameters(std_component_info_ptr comp_info,
int height, int width, int vert_sso, int hor_sso)
/* This function sets the fields of the top-level `frame' structure in
`comp_info' (not the frame structures in derivative `std_level_info'
structures) and also the two flags `using_frames_vertically' and
`using_frames_horizontally' based upon the four arguments whose
interpretation may be judged by reading the usage statement for the
`-Fframes' argument. */
{
frame_info_ptr frame;
int rdx;
frame = &(comp_info->frame);
if (height == 0)
{
comp_info->using_frames_vertically = 0;
frame->row_rdx = 28; /* Some ridiculously large value not
likely to cause numeric overflow. */
frame->vert_ssodwt = 0;
}
else
{
comp_info->using_frames_vertically = 1;
for (rdx=0; (1<<rdx) < height; rdx++);
if (height != (1<<rdx))
local_error("The `-Fframes' argument requires nominal frame "
"dimensions which are exact powers of 2!");
frame->row_rdx = rdx;
frame->vert_ssodwt = vert_sso;
}
if (width == 0)
{
comp_info->using_frames_horizontally = 0;
frame->col_rdx = 28; /* Some ridiculously large value not
likely to cause numeric overflow. */
frame->hor_ssodwt = 0;
}
else
{
comp_info->using_frames_horizontally = 1;
for (rdx=0; (1<<rdx) < width; rdx++);
if (width != (1<<rdx))
local_error("The `-Fframes' argument requires nominal frame "
"dimensions which are exact powers of 2!");
frame->col_rdx = rdx;
frame->hor_ssodwt = hor_sso;
}
frame->dims.rows = 1 << frame->row_rdx;
frame->dims.cols = 1 << frame->col_rdx;
frame->dims.left_col = 0;
frame->dims.top_row = 0;
}
/*****************************************************************************/
/* STATIC is_legal_decomposition_spec */
/*****************************************************************************/
static int
is_legal_decomposition_spec(char *spec)
{
if (strcmp(spec,"mallat") == 0)
return(1);
if (strcmp(spec,"spacl") == 0)
return(1);
if (strcmp(spec,"packet") == 0)
return(1);
if (*spec == '\0')
return(0);
for (; *spec != '\0'; spec++)
if ((*spec < '1') || (*spec > '3')) /* 3 -> '3' correction by
Christophe Parisot */
return(0);
return(1);
}
/*****************************************************************************/
/* STATIC set_decomp_sequence */
/*****************************************************************************/
static void
set_decomp_sequence(std_component_info_ptr comp_info, char *string)
{
int n;
char *cp;
if (strcmp(string,"mallat") == 0)
string = "1";
else if (strcmp(string,"spacl") == 0)
string = "21";
else if (strcmp(string,"packet") == 0)
string = "321";
if (strlen(string) > 16)
local_error("No support for decomposition structure strings with "
"more that 16 characters! Offending string is \"%s\"!",
string);
for (cp=string, n=0; *cp != '\0'; n++, cp++)
{
comp_info->decomp_sequence[n] = (*cp) - '0';
if ((comp_info->decomp_sequence[n] < 1) ||
(comp_info->decomp_sequence[n] > 3))
local_error("Illegal decomposition structure string! Offending "
"string is \"%s\"!",string);
}
assert(n > 0);
while ((n > 1) &&
(comp_info->decomp_sequence[n-1] == comp_info->decomp_sequence[n-2]))
n--;
comp_info->decomp_sequence[n] = 0;
}
/* SAIC General Decomp. Begin */
/*****************************************************************************/
/* STATIC set_general_decomp_sequence */
/*****************************************************************************/
static void
set_general_decomp_sequence(std_component_info_ptr comp_info, char *string)
{
int n;
int decomp_length;
decomp_length = strlen(string);
comp_info->general_decomp_sequence = (int *)
local_malloc(INFO_MEM_KEY, (decomp_length + 1) * sizeof(int));
for (n=0; n<decomp_length; n++)
comp_info->general_decomp_sequence[n] = string[n] - '0';
comp_info->general_decomp_sequence[n] = -1;
}
/*****************************************************************************/
/* STATIC decode_general_decomp_sequence */
/*****************************************************************************/
static int
decode_general_decomp_sequence(std_level_info_ptr lev, int level_idx,
int all_hp_descent, int vert_hp_descent,
int horiz_hp_descent, int root_band_idx,
int *decomp_sequence, int *decomp_sequence_pos,
int vert_limit, int hor_limit,
int *vert_hp_descent_chg,
int *horiz_hp_descent_chg, int chg_pos)
/* This function provides for much more general wavelet decompositions. It
does so by allowing the band->hp_descent value to differ from the
lev->max_hp_descent value for the parent level of band. The input
`decomp_sequence_pos' specifies how to split a level with a series of
integers from 0 to 3. Value 0 indicates that the current subband should
not be decomposed further. Value 1 indicates that the current subband
should be split both horizontally and vertically. Value 2 indicates that
the current subband should be split in just the horizontal direction.
Value 3 indicates that the current subband should be split in just the
vertical direction. The input `decomp_sequence_pos' string provides
information for at least the current level. Information in this string
after that required for the current level specifies spliting information
for remaining levels. This function returns the character position to the
string for the next level. If the character at that position is NULL, the
previous character position passed to this routine will be used for
remaining levels. Note that this function assumes that the LL_BAND
resulting from the first horizontal and vertical splits of a level are
ignored unless that subband is the only subband for level 0. */
{
std_band_info_ptr band;
int vert_idx, hor_idx, band_idx;
int first_decomp_sequence_pos;
int orient;
int retval = 0;
int decomp_sequence_length = 0;
int current_opcode;
int n;
assert(chg_pos < 4);
while (decomp_sequence[decomp_sequence_length] != -1)
decomp_sequence_length++;
if ((vert_limit < 0) && (hor_limit < 0)) {
first_decomp_sequence_pos = *decomp_sequence_pos;
if (level_idx == 0) {
if (lev->bands != NULL) {
band = lev->bands;
band->vert_hp_descent = 0;
band->horiz_hp_descent = 0;
band->valid_band = 1;
for (n=0; n<4; n++) {
band->vert_hp_descent_chg[n] = 1;
band->horiz_hp_descent_chg[n] = 1;
}
}
return(0);
}
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)++;
switch(current_opcode) {
case 0:
local_error("Decomposition string for `-Fgen_decomp' is either too "
"short or too long since a character `0' has been detected "
"at the base of a resolution level!\n");
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],
root_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);
lev->bands[0].vert_hp_descent_chg[0] = 1;
lev->bands[0].horiz_hp_descent_chg[0] = 1;
lev->decomp_sequence = (int *)
local_malloc(INFO_MEM_KEY,
(*decomp_sequence_pos - first_decomp_sequence_pos + 1) * sizeof(int));
for (n=first_decomp_sequence_pos; n<*decomp_sequence_pos; n++) {
lev->decomp_sequence[n-first_decomp_sequence_pos] = decomp_sequence[n];
}
lev->decomp_sequence[n-first_decomp_sequence_pos] = -1;
if (*decomp_sequence_pos == decomp_sequence_length)
retval = 1;
return(retval);
}
for (vert_idx=0; vert_idx < vert_limit; vert_idx++) {
for (hor_idx=0; hor_idx < hor_limit; hor_idx++) {
if ((vert_idx == 0) && (hor_idx == 0))
if ((level_idx != 0) && (all_hp_descent <= 1))
continue;
else
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 << ((lev->max_hp_descent - all_hp_descent) +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -