📄 ebcot_decoder.c
字号:
static int
construct_component_position_progression(ebcot_tile_ptr tile,
ebcot_sequence_ptr seq,
int first_level,
int first_component,
int max_layers, int max_levels,
int max_components)
{
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_precinct_info_ptr precinct;
canvas_dims dims;
int new_packets;
int n, c, p;
int x_inc, y_inc, inc, x0, x1, y0, y1, x, y;
/* Reset `next_precinct_idx' fields. */
for (c=first_component; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=first_level; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels +n;
lev->next_precinct_idx = 0;
}
}
new_packets = 0;
for (c=first_component; c < max_components; c++)
{
comp_info = tile->components + c;
/* Determine spatial progression parameters. */
x_inc = y_inc = 0;
for (n=first_level; n < max_levels; n++)
{
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
if (lev->ppx >= 0)
{
/* SAIC General Decomp. Begin mods */
int xfact = 0;
int l;
for (l=comp_info->num_levels; l>n; l--) {
switch(comp_info->levels[l].decomp_sequence[0]) {
case 1:
xfact++;
break;
case 2:
xfact++;
break;
case 3:
break;
}
}
inc = comp_info->hor_subsampling;
inc <<= lev->ppx + xfact;
/* SAIC General Decomp. End mods */
if ((x_inc == 0) || (inc < x_inc))
x_inc = inc;
}
if (lev->ppy >= 0)
{
/* SAIC General Decomp. Begin mods */
int yfact = 0;
int l;
for (l=comp_info->num_levels; l>n; l--) {
switch(comp_info->levels[l].decomp_sequence[0]) {
case 1:
yfact++;
break;
case 2:
break;
case 3:
yfact++;
break;
}
}
inc = comp_info->vert_subsampling;
inc <<= lev->ppy + yfact;
/* SAIC General Decomp. End mods */
if ((y_inc == 0) || (inc < y_inc))
y_inc = inc;
}
}
dims = tile->reference_dims;
if (tile->overlapped)
local_error("Spatially oriented packet progressions not defined "
"for overlapping tiles!");
if (x_inc == 0)
{ /* Only one precinct horizontally. */
x0 = 0; x1 = x_inc = 1;
}
else
{
x0 = dims.left_col; x1 = x0 + dims.cols;
x0 &= ~(x_inc-1); /* Start on integer multiple of x_inc. */
}
if (y_inc == 0)
{ /* Only one precinct vertically. */
y0 = 0; y1 = y_inc = 1;
}
else
{
y0 = dims.top_row; y1 = y0 + dims.rows;
y0 &= ~(y_inc-1); /* Start on integer multiple of y_inc. */
}
/* Now walk through the component's progression. */
for (y=y0; y < y1; y += y_inc)
for (x=x0; x < x1; x += x_inc)
for (n=first_level; n < max_levels; n++)
{
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
p = lev->next_precinct_idx;
precinct = lev->precincts + p;
if ((p < lev->total_precincts) &&
((y==y0) || (y==precinct->yref)) &&
((x==x0) || (x==precinct->xref)))
{
lev->next_precinct_idx++;
while (precinct->sequenced_layers < max_layers)
{
seq->layer_idx = precinct->sequenced_layers;
seq->precinct = precinct;
new_packets++;
seq++;
precinct->sequenced_layers++;
}
}
}
}
return(new_packets);
}
/* Begin DST POC mod */
/*****************************************************************************/
/* STATIC apply_progression_sequence_spec */
/*****************************************************************************/
static void
apply_progression_sequence_spec(ebcot_tile_ptr tile,
int first_level, int first_component,
int max_levels, int max_components,
int max_layers, int progression)
/* Returns the number of new packets sequenced by the progression
spec supplied here. */
{
ebcot_sequence_ptr seq;
int num_packets;
if (max_layers > tile->num_layers)
max_layers = tile->num_layers;
if (max_levels > (tile->max_levels+1))
max_levels = tile->max_levels+1;
if (max_components > tile->num_components)
max_components = tile->num_components;
seq = tile->packet_sequence + tile->sequenced_packets;
switch (progression) {
case LAYER_PROGRESSIVE:
num_packets =
construct_layer_progression(tile,seq,first_level,first_component,
max_layers,max_levels,max_components);
break;
case RESOLUTION_LAYER_PROGRESSIVE:
num_packets =
construct_resolution_layer_progression(tile,seq,first_level,
first_component,max_layers,
max_levels,max_components);
break;
case RESOLUTION_POSITION_PROGRESSIVE:
num_packets =
construct_resolution_position_progression(tile,seq,first_level,
first_component,max_layers,
max_levels,max_components);
break;
case POSITION_COMPONENT_PROGRESSIVE:
num_packets =
construct_position_component_progression(tile,seq,first_level,
first_component,max_layers,
max_levels,max_components);
break;
case COMPONENT_POSITION_PROGRESSIVE:
num_packets =
construct_component_position_progression(tile,seq,first_level,
first_component,max_layers,
max_levels,max_components);
break;
default: assert(0);
}
tile->sequenced_packets += num_packets;
assert(tile->sequenced_packets <= tile->total_packets);
}
/*****************************************************************************/
/* STATIC initialize_progression_sequence */
/*****************************************************************************/
static void
initialize_progression_sequence(stream_in_ref stream, ebcot_tile_ptr tile)
{
int tnum = tile->tnum;
int first_level, first_component;
int max_layers, max_levels, max_components;
int progression;
int num_poc_specs, n;
/* Set up storage. */
tile->packet_sequence = (ebcot_sequence_ptr)
local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_sequence)*tile->total_packets);
/* Get default sequencing parameters based on relevant COD marker. */
first_level = first_component = 0;
max_layers = tile->num_layers;
max_components = tile->num_components;
max_levels = tile->max_levels+1;
progression = (int)
stream->get_marker_val(stream,tnum,MARKER_COD_PROG,0,0);
/* Process all available sequencing information. */
num_poc_specs = stream->size_marker_elt(stream,tnum,MARKER_POC_CHANGES,0);
assert(!(num_poc_specs % 6));
num_poc_specs /= 6;
n = 0;
do {
if (num_poc_specs > 0)
{ /* Change the sequencing parameters. */
first_level = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+0);
first_component = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+1);
max_layers = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+2);
max_levels = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+3);
max_components = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+4);
progression = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,0,6*n+5);
n++;
}
apply_progression_sequence_spec(tile,first_level,first_component,
max_levels,max_components,max_layers,
progression);
num_poc_specs--;
} while (num_poc_specs > 0);
}
/*****************************************************************************/
/* STATIC augment_packet_sequencing_info */
/*****************************************************************************/
static void
augment_packet_sequencing_info(ebcot_tile_ptr tile,
stream_in_ref stream)
/* This function is called from within `retrieve_next_packet' when there
is insufficient sequencing information available to identify the
coordinates of the packet retrieved for the current tile. The
sequencing information must lie in a new POC marker which should have
appeared in a tile-part header of the tile. The function invokes the
`stream_in__pop_tile_part_poc' function to get the next available POC
marker and incorporate its sequencing information. */
{
int tnum = tile->tnum;
int first_level, first_component;
int max_layers, max_levels, max_components;
int progression;
int num_poc_specs, n;
/* Process next available sequencing identifier. */
tile->current_poc_instance++;
num_poc_specs = stream->size_marker_elt(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance);
if (num_poc_specs == 0)
local_error("Insufficient tile-part specific POC markers supplied to "
"sequence all packets for the tile!");
assert(!(num_poc_specs % 6));
num_poc_specs /= 6;
for (n=0; n < num_poc_specs; n++)
{
first_level = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+0);
first_component = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+1);
max_layers = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+2);
max_levels = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+3);
max_components = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+4);
progression = (int)
stream->get_marker_val(stream,tnum,MARKER_POC_CHANGES,
tile->current_poc_instance,6*n+5);
apply_progression_sequence_spec(tile,first_level,first_component,
max_levels,max_components,max_layers,
progression);
}
}
/* End DST POC mod */
/*****************************************************************************/
/* STATIC build_partitions */
/*****************************************************************************/
static int
build_partitions(ebcot_component_info_ptr comp_info)
/* This function constructs the code-block partition and the precinct
partition for all resolution levels and subbands in the tile-component
referenced by `comp_info'. The function returns the total number
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -