📄 ebcot_receive_bits.c
字号:
while ((tmp=block->first_unit) != NULL)
{
block->first_unit = tmp->next;
self->code_heap_mgr->return_unit(self->code_heap_mgr,tmp);
}
}
}
return(stripped_bytes);
}
/*****************************************************************************/
/* STATIC parse_bitstream_layer */
/*****************************************************************************/
static int
parse_bitstream_layer(level_info_ptr level, int layer_idx,
the_decoder_ref self)
/* This function parses the information recovered from the bit-stream to
satisfy the constraint imposed by the `self->max_levels' bound. It
should be invoked on each layer in turn, starting from the bitstream
layer with the highest index; within each layer, it should be applied to
each resolution level in turn, starting from the highest resolution level.
At each resolution, it should be applied to each image component (usually
colour components), starting from the component with the highest index.
The function returns -1 if the constraint is already satisfied;
otherwise, it returns the non-negative number of bytes which were parsed
out, including all tag bytes which are now redundant. The function always
removes whole code blocks at a time, until enough bytes have been saved
or the entire layer has been removed. If the whole layer is removed, the
tag bytes for the level are also removed. */
{
int stripped_bytes, min_stripped_bytes, num_bytes, b, m, k;
band_info_ptr band;
block_info_ptr block;
heap_unit_ptr prev, scan;
stripped_bytes = 0;
min_stripped_bytes = self->actual_bytes - self->max_bytes;
if (min_stripped_bytes <= 0)
return(-1); /* Constraint satisfied. */
if (layer_idx >= level->bitstream_layers)
return(0); /* Bit-stream was probably truncated. */
m = 1; /* Avoid compiler warnings. */
for (b=level->max_band; b >= level->min_band; b--)
{
band = level->bands + b;
for (m=band->band_blocks, block=band->blocks+m-1;
(m > 0) && (stripped_bytes < min_stripped_bytes);
m--, block--)
if (((k=block->num_passes) > 0) &&
(block->passes[k-1].layer_idx >= layer_idx))
{
do {
k--;
assert(layer_idx == block->passes[k].layer_idx);
} while ((num_bytes=block->passes[k].num_bytes) == 0);
block->num_passes = k;
block->total_bytes -= num_bytes;
assert(block->total_bytes >= 0);
stripped_bytes += num_bytes;
for (prev=NULL, scan=block->first_unit,
num_bytes=block->total_bytes; num_bytes > 0;
prev=scan, scan=scan->next)
num_bytes -= HEAP_BYTES;
if (prev == NULL)
block->first_unit = NULL;
else
prev->next = NULL;
while ((prev=scan) != NULL)
{
scan=prev->next;
self->code_heap_mgr->return_unit(self->code_heap_mgr,prev);
}
}
for (; m > 0; m--, block--)
if (block->total_bytes > 0)
break;
}
if (m == 0)
{ /* Entire layer stripped out. */
num_bytes = level->layer_tag_bytes[layer_idx];
level->bitstream_layers = layer_idx;
stripped_bytes += num_bytes;
if (self->profile & PROFILE__RESOLUTION_PROGRESSIVE)
{ /* Can't just discard arbitrary layers from a particular resolution
level, since the decoder would have no way of knowing they were
discarded and would not correctly interpret lower layers of
higher frequency subbands. Generally need to mark the layer as
empty by setting the first bit of a single-byte tag to 0. */
if (level->level_idx < (self->max_levels-1))
{ /* Can't just drop the layer altogether without corrupting
the interpretation of layers which might not be dropped in
higher resolution levels of the parsed bit-stream. */
stripped_bytes -= 1; /* Allow a single byte to mark the layer
as empty (first bit equals 0). */
if (level->level_idx == 0)
{ /* Get all the single byte markers back again, because the
total number of bit-stream layers identified in the
header of the parsed bit-stream can be decremented. */
stripped_bytes += self->max_levels-1;
}
}
}
}
return(stripped_bytes);
}
/* ========================================================================= */
/* ---------------------------- Start and Finish --------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC start_bitstream_recovery */
/*****************************************************************************/
static void
start_bitstream_recovery(the_decoder_ref self)
{
level_info_ptr lev;
band_info_ptr band;
int comp_idx, n, b;
for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
for (lev=self->components[comp_idx].levels,
n=0; n <= self->num_levels; n++, lev++)
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
band->inclusion_tree =
create_tag_tree(band->blocks_high,band->blocks_wide);
band->insignificant_msbs_tree =
create_tag_tree(band->blocks_high,band->blocks_wide);
}
}
/*****************************************************************************/
/* STATIC finish_bitstream_recovery */
/*****************************************************************************/
static void
finish_bitstream_recovery(the_decoder_ref self)
{
level_info_ptr lev;
band_info_ptr band;
int comp_idx, n, b;
for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
for (lev=self->components[comp_idx].levels,
n=0; n <= self->num_levels; n++, lev++)
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
local_free(band->inclusion_tree);
local_free(band->insignificant_msbs_tree);
}
}
/* ========================================================================= */
/* ---------------------------- External Functions ------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* EXTERN ebcot_load_bit_stream */
/*****************************************************************************/
void
ebcot_load_bit_stream(the_decoder_ref self)
{
tag_buffer_ptr tags;
jmp_buf except;
int comp_idx, n, layer;
level_info_ptr lev;
codeword_heap_ref code_mgr;
bitstream_source_ref input;
self->actual_bytes = 0;
start_bitstream_recovery(self);
if (setjmp(except) == 0)
{
input = self->input;
code_mgr = self->code_heap_mgr;
tags = create_tag_buffer(input,&except);
if (self->profile & PROFILE__RESOLUTION_PROGRESSIVE)
{
for (n=0; n <= self->num_levels; n++)
for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
{
lev = self->components[comp_idx].levels + n;
if (lev->min_band <= lev->max_band)
for (layer=0; layer < self->bitstream_layers; layer++)
self->actual_bytes +=
recover_bitstream_layer(lev,layer,tags,input,code_mgr);
}
}
else
{ /* SNR, rather than Resolution order. */
for (layer=0; layer < self->bitstream_layers; layer++)
for (n=0; n <= self->num_levels; n++)
for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
{
lev = self->components[comp_idx].levels + n;
if (lev->min_band <= lev->max_band)
self->actual_bytes +=
recover_bitstream_layer(lev,layer,tags,input,code_mgr);
}
}
}
tag_buffer__destroy(tags);
finish_bitstream_recovery(self);
}
/*****************************************************************************/
/* EXTERN ebcot_parse_bit_stream */
/*****************************************************************************/
void
ebcot_parse_bit_stream(the_decoder_ref self)
{
int comp_idx, n, layer, stripped_bytes;
level_info_ptr lev;
/* First, strip out all redundant components and resolution levels. */
for (comp_idx=self->max_components;
comp_idx < self->num_components; comp_idx++)
for (n=0; n <= self->num_levels; n++)
{
lev = self->components[comp_idx].levels + n;
if (lev->min_band <= lev->max_band)
self->actual_bytes -= parse_out_level(lev,self);
}
for (n=self->max_levels; n < self->num_levels; n++)
for (comp_idx=0; comp_idx < self->num_components; comp_idx++)
{
lev = self->components[comp_idx].levels + n;
if (lev->min_band <= lev->max_band)
self->actual_bytes -= parse_out_level(lev,self);
}
/* Now parse out layers and/or blocks until the rate target is achieved. */
for (layer=self->bitstream_layers-1; layer >= 0; layer--)
{
for (n=self->num_levels; n >= 0; n--)
for (comp_idx=self->max_components-1; comp_idx >= 0; comp_idx--)
{
lev = self->components[comp_idx].levels + n;
if (lev->min_band <= lev->max_band)
{
if ((stripped_bytes =
parse_bitstream_layer(lev,layer,self)) < 0)
return;
else
self->actual_bytes -= stripped_bytes;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -