📄 ebcot_receive_bits.c
字号:
bit-stream might as well have terminated at the beginning of the
layer.
`layer_idx' identifies the layer within the bit-stream which is
being retrieved here. The first layer should always have a `layer_idx'
value of 0, which causes appropriate initialization steps to be applied.
Thereafter, the indices must be strictly increasing. The `layer_idx'
value is used with each band's inclusion tag tree in an interesting
and elegant manner to implement an efficient coding of the point at
which information from any given block is first included in the
bit-stream.
The `tags' argument supplies a `tag_buffer' object whose
`tag_buffer__pull_bit' and `tag_buffer__pull_bits' functions should
be used to recover tag bits associated with the layer. */
{
int b, m, k, tag_val, new_passes, something_new;
band_info_ptr band;
block_info_ptr block;
int actual_bytes;
tag_buffer__reset(tags);
if (layer_idx == 0)
{ /* Initialize various quantities. */
level->bitstream_layers = 0;
for (b=level->min_band; b <= level->max_band; b++)
{
band = level->bands + b;
band->byte_count_bits = 3; /* Minimum number of bits for
signalling byte counts. */
tag_tree__reset(band->inclusion_tree);
tag_tree__reset(band->insignificant_msbs_tree);
for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
{
block->num_passes = 0;
block->total_bytes = 0;
block->new_passes = 0;
block->insignificant_msbs = 0;
}
}
}
tag_buffer__pull_bit(tags,tag_val);
if (!tag_val)
return(1);
for (b=level->min_band; b <= level->max_band; b++)
{
band = level->bands + b;
something_new = 0;
for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
{
/* Recover inclusion information. */
if (block->num_passes == 0)
{ /* Not previously included. */
tag_val =
tag_tree__decode(band->inclusion_tree+m,layer_idx+1,tags);
}
else
{ /* Block has already been included in a previous layer. */
tag_buffer__pull_bit(tags,tag_val);
}
if (!tag_val)
continue;
/* Recover `insignificant_msbs' information, if necessary. */
if (block->num_passes == 0)
{
k = 1;
while (!tag_tree__decode(band->insignificant_msbs_tree+m,k,tags))
k++;
block->insignificant_msbs = k-1;
}
/* Now recover information about the number of new passes. */
if (block->num_passes == 0)
new_passes = block->insignificant_msbs * PASSES_PER_BITPLANE + 1;
else
new_passes = 1;
tag_buffer__pull_bit(tags,tag_val);
if (tag_val)
{
new_passes++;
tag_buffer__pull_bit(tags,tag_val);
if (tag_val)
{
new_passes++;
tag_val = tag_buffer__pull_bits(tags,2);
new_passes += tag_val;
if (tag_val == 3)
{
tag_val = tag_buffer__pull_bits(tags,5);
new_passes += tag_val;
if (tag_val == 31)
{
tag_val = tag_buffer__pull_bits(tags,7);
new_passes += tag_val;
}
}
}
}
assert((block->num_passes+new_passes) <= block->max_passes);
block->new_passes = new_passes;
something_new = 1;
}
if (something_new)
{
int num_bits;
/* Recover the number of bits which will be used to signal the
number of new bytes for each included block. */
num_bits = band->byte_count_bits;
do {
tag_buffer__pull_bit(tags,tag_val);
num_bits++;
} while (tag_val);
num_bits--;
band->byte_count_bits = num_bits;
assert(num_bits <= 16);
/* Recover the number of new bytes for each included block. */
for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
if ((new_passes=block->new_passes) > 0)
{
k = new_passes;
if (block->num_passes == 0)
k -= block->insignificant_msbs * PASSES_PER_BITPLANE;
for (num_bits=band->byte_count_bits; k > 1; k=(k+1)>>1)
num_bits++;
tag_val = tag_buffer__pull_bits(tags,num_bits);
k = block->num_passes;
block->passes[k].num_bytes = (std_ushort) tag_val;
block->passes[k].layer_idx = (std_ushort) layer_idx;
for (new_passes--, k++; new_passes > 0; new_passes--, k++)
{
block->passes[k].num_bytes = 0;
block->passes[k].layer_idx = (std_ushort) layer_idx;
}
}
}
}
assert(level->bitstream_layers == layer_idx);
level->layer_tag_bytes[layer_idx] = tags->retrieved_bytes;
level->bitstream_layers = layer_idx + 1;
/* Now go ahead and recover the code bytes themselves. */
actual_bytes = tags->retrieved_bytes;
for (b=level->min_band; b <= level->max_band; b++)
{
band = level->bands + b;
for (block=band->blocks, m=0; m < band->band_blocks; m++, block++)
if ((new_passes = block->new_passes) > 0)
{
std_byte *wp;
heap_unit_ptr unit;
int num_bytes, remaining_bytes;
unit = block->first_unit;
if (unit == NULL)
{ remaining_bytes = 0; wp = NULL; }
else
{ remaining_bytes = HEAP_BYTES; wp = (std_byte *)(unit->words); }
num_bytes = block->total_bytes; /* Must skip over these. */
while (num_bytes > 0)
{
if (num_bytes > remaining_bytes)
{
unit = unit->next;
num_bytes -= remaining_bytes;
remaining_bytes = HEAP_BYTES;
wp = (std_byte *)(unit->words);
}
else
{
wp += num_bytes;
remaining_bytes -= num_bytes;
num_bytes = 0;
}
}
tag_val = block->passes[block->num_passes].num_bytes;
num_bytes = tag_val; /* Must read these in. */
while (num_bytes > 0)
{
if (remaining_bytes == 0)
{ /* Allocate new unit. */
if (unit == NULL)
block->first_unit = unit = code_mgr->get_unit(code_mgr);
else
unit = unit->next = code_mgr->get_unit(code_mgr);
unit->next = NULL;
remaining_bytes = HEAP_BYTES;
wp = (std_byte *)(unit->words);
}
if (num_bytes > remaining_bytes)
{
if (input->pull_bytes(input,wp,remaining_bytes) <
remaining_bytes)
return(actual_bytes); /* End of bit-stream. */
num_bytes -= remaining_bytes;
remaining_bytes = 0;
wp = NULL;
}
else
{
if (input->pull_bytes(input,wp,num_bytes) < num_bytes)
return(actual_bytes); /* End of bit-stream. */
wp += num_bytes;
remaining_bytes -= num_bytes;
num_bytes = 0;
}
}
block->total_bytes += tag_val;
block->num_passes += new_passes;
block->new_passes = 0;
actual_bytes += tag_val;
}
}
return(actual_bytes);
}
/*****************************************************************************/
/* STATIC parse_out_level */
/*****************************************************************************/
static int
parse_out_level(level_info_ptr level, the_decoder_ref self)
/* The purpose of this function is to simulate complete removal of the
indicated resolution level from the bit-stream and to report the number
of bytes which are saved in this way. A resolution level might need
to be removed from the bit-stream either because it belongs to an
image component which is not required or because it contains subbands
whose frequencies exceed the desired reconstruction resolution. In
the former case, all subbands are completely removed from the level.
If the level contains the DC subband and belongs to an included
image component, however, then only the three AC subbands are removed. */
{
int stripped_bytes;
int remove_dc, k, b, m;
band_info_ptr band;
block_info_ptr block;
heap_unit_ptr tmp;
remove_dc = (level->component_idx >= self->max_components);
stripped_bytes = 0;
if ((level->min_band > 0) || remove_dc)
{ /* Can remove all tag bytes for the level. */
for (k=0; k < level->bitstream_layers; k++)
stripped_bytes += level->layer_tag_bytes[k];
level->bitstream_layers = 0;
}
for (b=level->min_band; b <= level->max_band; b++)
{
if ((b==0) && !remove_dc)
continue;
band = level->bands + b;
for (block=band->blocks, m=band->band_blocks; m > 0; m--, block++)
{
stripped_bytes += block->total_bytes;
block->total_bytes = 0;
block->num_passes = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -