📄 ebcot_receive_bits.c
字号:
}
passes[pass_idx].terminated = 0;
if (terminate_each_pass ||
((full_effort_msbs <= 0) &&
((n==0) || (n==(PASSES_PER_BITPLANE-1)))))
passes[pass_idx].terminated = 1;
}
}
/*****************************************************************************/
/* STATIC recover_packet_head */
/*****************************************************************************/
static void
recover_packet_head(ebcot_decoder_ref self,
ebcot_precinct_info_ptr precinct,
block_master_ptr master,
int layer_idx, tag_buffer_ptr tags)
/* This function does quite a bit of the work of the function
`ebcot_get_packet_head_and_body'. It recovers the header information
for the packet, filling in the `new_passes' field of each relevant block,
as well as the relevant entries in the `passes' array for the
corresponding blocks. The caller should use this information to update
the `num_passes', `num_signalled_passes' and `total_bytes' fields for all
affected blocks and to recover the code bytes themselves. Upon entry,
the packet has been started and the initial bit of the header has already
been read to determine whether or not the packet contains any information.
If a problem is detected in the packet header, the function may not
actually return, but this exception will be caught by the caller as a
false return from `tag_buffer__try'. */
{
ebcot_precinct_band_info_ptr pband;
ebcot_block_info_ptr bpp, block;
int new_passes, save_new_passes, tag_val;
int b, r, c, k, pos;
for (b=precinct->min_band; b <= precinct->max_band; b++)
{
pband = precinct->bands + b;
if (!pband->valid_band)
continue;
for (pos=0, bpp=pband->blocks,
r=pband->blocks_high; r > 0; r--, bpp += pband->block_row_gap)
for (block=bpp, c=pband->blocks_wide; c > 0; c--, block++, pos++)
{
/* Recover inclusion information. */
if (block->num_signalled_passes == 0)
{ /* Not previously included. */
tag_val =
tag_tree__decode(pband->inclusion_tree+pos,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_signalled_passes == 0)
{
k = 1;
while (!tag_tree__decode(pband->insignificant_msbs_tree+pos,k,
tags))
k++;
block->insignificant_msbs = k-1;
/* Begin David T ER fix */
if ((block->insignificant_msbs*PASSES_PER_BITPLANE) >=
block->max_passes)
{ /* An error has occurred in the packet head; everything
from now on must be corrupt. */
precinct->packet_loss_encountered = 1;
return;
}
/* End David T ER fix */
mark_termination_points(block->passes,
block->insignificant_msbs,
block->max_passes,
master->terminate_each_pass,
master->full_effort_msbs);
}
/* Now recover information about the number of new passes. */
if (block->num_signalled_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;
}
}
}
}
if ((block->num_signalled_passes + new_passes) > block->max_passes)
{ /* Must be due to corruption in bit-stream. */
new_passes = block->max_passes - block->num_signalled_passes;
}
save_new_passes = new_passes;
if (new_passes > 0)
{ /* Recover the number of bytes between successive termination
and/or truncation points within these new passes. */
ebcot_pass_info_ptr layer_start_pass, seg_start_pass, scan;
int bytes_from_layer_start, num_bits;
/* Now for comma code identifying any required increment
in `byte_count_bits'. */
do {
tag_buffer__pull_bit(tags,tag_val);
#ifdef REPORT_LENGTH_SIGNALLING_COST
ebcot_total_length_signalling_bits++;
#endif /* REPORT_LENGTH_SIGNALLING_COST */
if (tag_val)
block->byte_count_bits++;
} while (tag_val);
layer_start_pass = seg_start_pass =
block->passes + block->num_signalled_passes;
if (block->num_signalled_passes == 0)
{
k = block->insignificant_msbs * PASSES_PER_BITPLANE;
seg_start_pass += k;
new_passes -= k;
}
bytes_from_layer_start = 0;
while (new_passes > 0)
{
scan = seg_start_pass;
for (k=0; k < (new_passes-1); k++, scan++)
if (scan->terminated)
break;
k++; /* Get number of new passes covered by length. */
new_passes -= k;
#ifdef REPORT_LENGTH_SIGNALLING_COST
ebcot_total_length_signalled_passes += k;
#endif /* REPORT_LENGTH_SIGNALLING_COST */
for (num_bits=block->byte_count_bits; k > 1; k>>=1)
num_bits++;
if (num_bits > 16)
{ /* Packet is corrupt. */
precinct->packet_loss_encountered = 1;
return;
}
#ifdef REPORT_LENGTH_SIGNALLING_COST
ebcot_total_length_signalling_bits += num_bits;
#endif /* REPORT_LENGTH_SIGNALLING_COST */
tag_val = tag_buffer__pull_bits(tags,num_bits);
bytes_from_layer_start += tag_val;
if (scan->terminated)
scan->special_length =
(std_ushort) bytes_from_layer_start;
seg_start_pass = scan+1;
}
scan = layer_start_pass;
scan->layer_idx = (std_ushort) layer_idx;
scan->layer_bytes = (std_ushort) bytes_from_layer_start;
for (scan++; scan < seg_start_pass; scan++)
{
scan->layer_idx = (std_ushort) layer_idx;
scan->layer_bytes = 0;
}
}
block->new_passes = save_new_passes;
}
}
}
/*****************************************************************************/
/* STATIC parse_packet */
/*****************************************************************************/
static void
parse_packet(ebcot_decoder_ref self, ebcot_precinct_info_ptr precinct,
int layer_idx, int max_bytes)
/* This function pares down the size of a packet in order to satisfy the
constraint imposed by the `max_bytes' bound. It should be
invoked packet by packet, starting with the least interesting packets,
until the constraint is satisfied. The function always removes whole
code bytes at a time, adjusting the `self->actual_bytes' count to
reflect the number of bytes which should be saved if this task were
performed by a separate bit-stream parsing tool. The actual number of
bytes which would be saved if the bit-stream were parsed correctly might
actually be somewhat more than that which is estimated by this function,
because we cannot correctly account for the saving in error detection
and/or correction codes which might be incurred at the bit-stream level.
If error resilience features are not utilized, then the simulation
of real bit-stream parsing should be accurate. */
{
ebcot_precinct_band_info_ptr pband;
ebcot_block_info_ptr block;
dst_heap_unit_ptr prev, scan;
int stripped_bytes, min_stripped_bytes, keeping_partial_packet;
int num_bytes, b, r, c, k;
min_stripped_bytes = self->actual_bytes - max_bytes;
assert(min_stripped_bytes > 0);
if (layer_idx >= precinct->recovered_layers)
return;
keeping_partial_packet = 0;
stripped_bytes = 0;
for (b=precinct->max_band;
(b >= precinct->min_band) && (!keeping_partial_packet);
b--)
{
pband = precinct->bands + b;
if (!pband->valid_band)
continue;
for (r=pband->blocks_high-1; (r >= 0) && (!keeping_partial_packet); r--)
for (c=pband->blocks_wide-1; c >= 0; c--)
{
block = pband->blocks + (c + r*pband->block_row_gap);
k = block->num_passes;
if ((k <= 0) || (block->passes[k-1].layer_idx < layer_idx))
continue;
if (stripped_bytes >= min_stripped_bytes)
{
keeping_partial_packet = 1;
break;
}
do {
k--;
assert(layer_idx == block->passes[k].layer_idx);
} while ((num_bytes=block->passes[k].layer_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 -= DST_HEAP_BYTES;
if (prev == NULL)
{
assert(block->total_bytes == 0);
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);
}
}
}
if (keeping_partial_packet)
self->actual_bytes -= stripped_bytes;
else
{ /* Remove entire packet. */
precinct->recovered_layers--;
assert(precinct->recovered_layers == layer_idx);
assert(precinct->layer_bytes[layer_idx] >= stripped_bytes);
self->actual_bytes -= precinct->layer_bytes[layer_idx];
}
}
/* ========================================================================= */
/* ---------------------------- External Functions ------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* EXTERN ebcot_create_tag_tree */
/*****************************************************************************/
tag_tree_node_ptr
ebcot_create_tag_tree(int rows, int cols)
/* Creates a tag-tree with an array of `rows'*`cols' leaf nodes, returning
a pointer to the top-left hand corner leaf node (the leaf nodes appear
at the head of the returned array, in scan-line order). */
{
tag_tree_node_ptr result, node, parents;
int elts, new_elts, next_rows, next_cols, r, c;
if ((rows == 0) || (cols == 0))
return(NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -