📄 ebcot_decoder.c
字号:
extra_lsbs = band->extra_lsbs;
roi_boost_delta = 0;
if (band->roi != NULL)
{
int min_boost;
if (master->roi_mask == NULL)
master->roi_mask = (std_byte **)
local_malloc(EBCOT_MEM_KEY,sizeof(std_byte *)*master->max_height);
roi_boost_delta =
band->roi->check_roi(band->roi,band->component_idx,band->level_idx,
band->band_idx,info->rows,info->cols,
info->top_row,info->left_col,
&min_boost,master->roi_mask);
/* We can completely ignore `min_boost', since this was taken care
of implicitly at the encoder by adjusting distortion estimates. */
assert((roi_boost_delta >= 0) &&
(roi_boost_delta <= band->max_roi_boost));
extra_lsbs -= roi_boost_delta;
}
/* SAIC TCQ begin mods */ /* Force signalling for inverse TCQ when all
indices get decoded to zero. See the note under
decoder__pull_line__func in ifc.h for details */
if (info->total_bytes == 0)
{
if (info->insignificant_msbs == 0) {
int ii;
for (ii=0; ii< master->sample_row_gap*info->rows; ii++) {
sample_buffer[ii] = 1 << (band->extra_lsbs - 1);
/* Do not use variable extra_lsbs in above line since that
variable is modified during ROI processing */
}
}
else {
memset(sample_buffer,0,
sizeof(ifc_int)*(size_t)(master->sample_row_gap*info->rows));
}
return;
}
/* SAIC TCQ end mods */
assert(info->num_passes > 0);
/* See if code word byte order needs to be reversed. */
msb_first = 1; *((std_byte *)(&msb_first)) = 0;
if (!msb_first)
{ /* Least significant byte appears first in each code word. Need to
reverse this to account for the fact that word buffers were read
from the bit-stream as byte buffers. */
int heap_remnant;
std_int word, *wp;
heap = info->first_unit;
wp = heap->words;
heap_remnant = DST_HEAP_WORDS;
for (n=(info->total_bytes+3)>>2; n > 0; n--)
{
word = *wp;
word = ((word >> 24) & 0x000000FF) | ((word >> 8) & 0x0000FF00) |
((word << 8) & 0x00FF0000) | ((word << 24) & 0xFF000000);
*(wp++) = word;
if ((--heap_remnant) == 0)
{ heap_remnant = DST_HEAP_WORDS; heap=heap->next; wp=heap->words; }
}
}
/* Start of timed section. */
if (self->cpu_time >= 0)
{ cpu_time = clock(); cpu_iterations = EBCOT_CPU_ITERATIONS; }
else
cpu_iterations = 1;
do {
success = decode_block_once(master,band,info,extra_lsbs);
if (!success)
{ /* The `info->num_passes' value should now identify the number of
passes decoded up to but not including the point at which the
error occurred. Further adjust the value of `info->num_passes'
according to our error tolerance and decode again. */
int verified_bits;
assert(master->min_erkeep_bits > 0);
verified_bits = 0;
for (n=info->num_passes-1; n >= 0; n--)
{
verified_bits += master->incremental_er_bits[n];
if (verified_bits >= master->min_erkeep_bits)
break;
}
info->num_passes = n+1;
success = decode_block_once(master,band,info,extra_lsbs);
assert(success);
}
cpu_iterations--;
} while (cpu_iterations > 0);
if (self->cpu_time >= 0)
self->cpu_time += (std_int)(clock()-cpu_time);
/* End of timed section. */
/* Copy the interleaved sample buffer into the non-interleaved
`sample_buffer' array. */
deinterleave_sample_buffer(master,sample_buffer);
/* Make any necessary adjustments to compensate for ROI activities at
the encoder. */
if (roi_boost_delta)
{
if (band->roi_implicit)
{
assert(master->roi_mask[0] == NULL);
undo_roi_boost_using_implicit_mask(sample_buffer,info->rows,
info->cols,
master->sample_row_gap,
roi_boost_delta);
}
else
{
assert(master->roi_mask[0] != NULL);
undo_roi_boost_using_mask(sample_buffer,info->rows,info->cols,
master->sample_row_gap,roi_boost_delta,
master->roi_mask);
}
}
/* SAIC TCQ begin */ /* Force signalling for non-fully-decoded
inverse TCQ See the note under
decoder__pull_line__func in ifc.h for details. */
if ((info->num_passes == info->max_passes) ||
((info->passes[info->max_passes-1].layer_bytes == 0) &&
(info->num_passes == (info->max_passes - 1)))) {
int ii;
for (ii=0; ii<master->sample_row_gap*info->rows; ii++) {
sample_buffer[ii] |= 1 << (band->extra_lsbs - 1);
}
}
/* SAIC TCQ end */
/* Release storage used for block code-stream. */
while ((heap = info->first_unit) != NULL)
{
info->first_unit = heap->next;
self->code_heap_mgr->return_unit(self->code_heap_mgr,heap);
}
}
/* ========================================================================= */
/* -------------------- Configuration Management Functions ----------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC set_code_block_dims */
/*****************************************************************************/
static void
set_code_block_dims(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
int tnum = comp_info->tnum;
int instance = comp_info->component_idx;
int xcb, ycb;
xcb = 2 + (int)
stream->get_marker_val(stream,tnum,MARKER_COC_XCB,instance,0);
ycb = 2 + (int)
stream->get_marker_val(stream,tnum,MARKER_COC_YCB,instance,0);
comp_info->master.max_height = (1<<ycb);
comp_info->master.max_width = (1<<xcb);
}
/*****************************************************************************/
/* STATIC set_precinct_partition_dims */
/*****************************************************************************/
static void
set_precinct_partition_dims(stream_in_ref stream,
ebcot_component_info_ptr comp_info)
{
int tnum = comp_info->tnum;
int instance = comp_info->component_idx;
ebcot_level_info_ptr lev;
int x_specs, y_specs, n;
x_specs = stream->size_marker_elt(stream,tnum,MARKER_COC_PPX,instance);
y_specs = stream->size_marker_elt(stream,tnum,MARKER_COC_PPY,instance);
assert(x_specs == y_specs);
if (x_specs == 0)
{ /* Partition dimensions default to 2^15. */
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
lev->ppx = lev->ppy = 15;
}
}
else
{
assert(x_specs == (comp_info->num_levels+1));
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
lev->ppx = (int)
stream->get_marker_val(stream,tnum,MARKER_COC_PPX,instance,n);
lev->ppy = (int)
stream->get_marker_val(stream,tnum,MARKER_COC_PPY,instance,n);
}
}
}
/*****************************************************************************/
/* STATIC set_respect_frames */
/*****************************************************************************/
static void
set_respect_frames(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
int tnum = comp_info->tnum;
int instance = comp_info->component_idx;
if (stream->size_marker_elt(stream,tnum,MARKER_COC_CCB,instance))
comp_info->respect_frames = (int)
stream->get_marker_val(stream,tnum,MARKER_COC_CCB,instance,0);
}
/*****************************************************************************/
/* STATIC set_mode_flags */
/*****************************************************************************/
static void
set_mode_flags(stream_in_ref stream, ebcot_component_info_ptr comp_info)
{
int tnum = comp_info->tnum;
int instance = comp_info->component_idx;
std_byte mode_byte;
mode_byte = (std_byte)
stream->get_marker_val(stream,tnum,MARKER_COC_MOD,instance,0);
comp_info->master.causal =
(mode_byte & MODE_FLAG_CAUSAL)?1:0;
comp_info->master.reset =
(mode_byte & MODE_FLAG_RESET)?1:0;
comp_info->master.terminate_each_pass =
(mode_byte & MODE_FLAG_TERMINATE)?1:0;
comp_info->master.lazy =
(mode_byte & MODE_FLAG_LAZY)?1:0;
comp_info->master.error_resilient_termination =
(mode_byte & MODE_FLAG_ERTERM)?1:0;
comp_info->master.segmark =
(mode_byte & MODE_FLAG_SEGMARK)?1:0;
}
/*****************************************************************************/
/* STATIC set_num_layers */
/*****************************************************************************/
static void
set_num_layers(stream_in_ref stream, ebcot_tile_ptr tile)
{
int tnum = tile->tnum;
tile->num_layers = (int)
stream->get_marker_val(stream,tnum,MARKER_COD_LAYERS,0,0);
assert(tile->num_layers > 0);
}
/* ========================================================================= */
/* ---------------------- Structure Management Functions ------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC construct_layer_progression */
/*****************************************************************************/
static int
construct_layer_progression(ebcot_tile_ptr tile,
ebcot_sequence_ptr seq,
int min_level, int min_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;
int new_packets;
int layer, n, c, p;
new_packets = 0;
for (layer=0; layer < max_layers; layer++)
for (n=min_level; n < max_levels; n++)
for (c=min_component; c < max_components; c++)
{
comp_info = tile->components + c;
if (n > comp_info->num_levels)
continue;
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
if (precinct->sequenced_layers > layer)
continue;
assert(precinct->sequenced_layers == layer);
precinct->sequenced_layers++;
seq->layer_idx = layer;
seq->precinct = precinct;
new_packets++;
seq++;
}
}
return(new_packets);
}
/*****************************************************************************/
/* STATIC construct_resolution_layer_progression */
/*****************************************************************************/
static int
construct_resolution_layer_progression(ebcot_tile_ptr tile,
ebcot_sequence_ptr seq,
int min_level, int min_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;
int new_packets;
int layer, n, c, p;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -