📄 ebcot_send_bits.c
字号:
tmp_prev_bytes += signal_bytes;
tmp_extra_passes -= k;
tmp_first_new_pass += k;
for (num_bits=block->byte_count_bits; k > 1; k>>=1)
num_bits++;
while (signal_bytes >= (1<<num_bits))
{
num_bits++;
block->byte_count_bits++;
tag_buffer__push_bit(tags,1);
}
if (num_bits > 16)
local_error("Too many code bytes in a single bit-stream "
"layer for one or more blocks! Use smaller "
"code blocks or more layers (SNR "
"progressive)!");
}
tag_buffer__push_bit(tags,0);
}
/* Generate tag information for the number of bytes between
successive termination and/or truncation points within
this new number of passes. */
while (extra_passes > 0)
{
int signal_bytes, num_bits;
for (k=0; k < (extra_passes-1); k++)
if (block->passes[first_new_pass+k].terminated)
break;
signal_bytes =
block->passes[first_new_pass+k].cumulative_bytes-prev_bytes;
k++; /* Get number of new passes covered by length. */
prev_bytes += signal_bytes;
extra_passes -= k;
first_new_pass += k;
for (num_bits=block->byte_count_bits; k > 1; k>>=1)
num_bits++;
assert (signal_bytes < (1<<num_bits));
tag_buffer__push_bits(tags,signal_bytes,num_bits);
}
}
}
head_bytes = tag_buffer__flush(tags);
stream->start_packet(stream,layer_idx,head_bytes,body_bytes,body_parts,
simulation);
tag_buffer__output(tags,stream);
/* Now send the code bytes themselves, for each block for which
information is being included. */
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++)
{
int offset, remaining;
dst_heap_unit_ptr heap;
std_byte *buf;
if (block->num_passes <= block->old_passes)
continue;
block_bytes = block->passes[block->num_passes-1].cumulative_bytes;
offset = 0;
if ((k=block->old_passes) > 0)
offset = block->passes[k-1].cumulative_bytes;
block_bytes -= offset;
assert(block_bytes > 0);
heap = block->first_unit;
remaining = (DST_HEAP_WORDS - block->first_pos) << 2;
buf = ((std_byte *) heap->words) + DST_HEAP_BYTES - remaining;
while (offset > 0)
{
if (remaining >= offset)
{
buf += offset;
remaining -= offset;
offset = 0;
}
else
{
offset -= remaining;
heap = heap->next;
remaining = DST_HEAP_BYTES;
buf = (std_byte *)(heap->words);
}
}
while (block_bytes > 0)
{
if (remaining >= block_bytes)
{
stream->push_body_bytes(stream,buf,block_bytes);
block_bytes = 0;
}
else
{
stream->push_body_bytes(stream,buf,remaining);
block_bytes -= remaining;
heap = heap->next;
remaining = DST_HEAP_BYTES;
buf = (std_byte *)(heap->words);
}
}
}
}
packet_bytes = stream->end_packet(stream);
return(packet_bytes);
}
/*****************************************************************************/
/* STATIC optimize_bitstream_layer */
/*****************************************************************************/
static rd_slope_type
optimize_bitstream_layer(ebcot_encoder_ref self, stream_out_ref stream,
int layer_idx, rd_slope_type max_rd_threshold,
tag_buffer_ptr tags, int max_cumulative_bytes,
int previous_cumulative_bytes)
/* This function implements the rate-distortion optimization algorithm.
It saves the state of any previously generated quality layers and
then invokes `form_bitstream_layer' as often as necessary to find the
smallest rate-distortion threshold such that the total number of bytes
required to represent the layer does not exceed `max_cumulative_bytes'
minus `previous_cumulative_bytes'. It then restores the state of any
previously generated bit-stream layers and returns the threshold. The
caller must invoke `form_packet' directly with this threshold
to actually generate the packets which constitute the new bit-stream
layer. In the extreme case, this function can be used to generate all
bit-stream layers. Normally, however, it will be used only to generate
a small number of layers which are of special interest, while any
intervening layers can be generated directly from some approximate
threshold values. The `stream' object must be supplied, because the
actual size of a packet can only be reliably computed with the aid
of its interface functions, since additional error correction and/or
detection codes may be added at the bit-stream level. */
{
int tnum, tpart, c, n, b, p, actual_bytes;
ebcot_tile_ptr tile;
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_band_info_ptr band;
ebcot_precinct_info_ptr precinct;
ebcot_precinct_band_info_ptr pband;
ebcot_block_info_ptr block;
rd_slope_type min_rd_threshold, rd_threshold;
std_short max_exponent, exponent;
std_int max_mantissa; /* added by W. Zeng, for vpw fix */
if (layer_idx > 0)
{ /* Start by saving the state of the tag trees. */
for (tnum=0; tnum < self->num_tiles; tnum++)
{
tile = self->tiles + tnum;
for (c=0; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
for (b=precinct->min_band; b <= precinct->max_band; b++)
{
pband = precinct->bands + b;
if (!pband->valid_band)
continue;
tag_tree__copy(pband->inclusion_tree,
pband->inclusion_tree_copy);
tag_tree__copy(pband->insignificant_msbs_tree,
pband->insignificant_msbs_tree_copy);
}
}
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
if (!band->valid_band)
continue;
for (block=band->blocks,
p=band->total_blocks; p > 0; p--, block++)
{
block->old_passes = block->num_passes;
block->old_byte_count_bits = block->byte_count_bits;
}
}
}
}
}
}
/* Estimate `min_rd_threshold' from summary information collected during
compression. */
max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
/* Begin W. Zeng vpw fix */
if (self->vpw_info == NULL)
{
for (exponent=max_exponent; exponent > 0; exponent--)
if (self->rd_slope_rates[exponent] >= max_cumulative_bytes)
break;
min_rd_threshold = exponent << RD_SLOPE_MANTISSA_BITS;
if ((min_rd_threshold >= max_rd_threshold) && (exponent > 0))
{
exponent--;
min_rd_threshold = exponent << RD_SLOPE_MANTISSA_BITS;
}
}
else
{ /**** using vpw ****/
max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;
max_rd_threshold = (max_exponent << RD_SLOPE_MANTISSA_BITS) +
max_mantissa;
min_rd_threshold= 0;
}
/* End W. Zeng vpw fix */
/* Now for the main iterative loop. */
rd_threshold = (rd_slope_type)
((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);
do {
actual_bytes = previous_cumulative_bytes;
for (tnum=0; tnum < self->num_tiles; tnum++)
{
tile = self->tiles + tnum;
if (layer_idx == 0)
for (tpart=0; tpart < tile->num_tparts; tpart++)
actual_bytes +=
stream->write_tpart_header(stream,tnum,tile->num_tparts,
tpart,1,0);
for (c=0; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
actual_bytes +=
form_packet(precinct,rd_threshold,stream,1,
layer_idx,tags);
}
}
}
}
if (actual_bytes > max_cumulative_bytes)
min_rd_threshold = rd_threshold;
else
max_rd_threshold = rd_threshold;
rd_threshold = (rd_slope_type)
((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);
if (layer_idx > 0)
{ /* Finish up by restoring the state to that of the previous layer. */
for (tnum=0; tnum < self->num_tiles; tnum++)
{
tile = self->tiles + tnum;
for (c=0; c < tile->num_components; c++)
{
comp_info = tile->components + c;
for (n=0; n <= comp_info->num_levels; n++)
{
lev = comp_info->levels + n;
for (p=0; p < lev->total_precincts; p++)
{
precinct = lev->precincts + p;
for (b=precinct->min_band;
b <= precinct->max_band; b++)
{
pband = precinct->bands + b;
if (!pband->valid_band)
continue;
tag_tree__copy(pband->inclusion_tree_copy,
pband->inclusion_tree);
tag_tree__copy(pband->insignificant_msbs_tree_copy,
pband->insignificant_msbs_tree);
}
}
for (b=lev->min_band; b <= lev->max_band; b++)
{
band = lev->bands + b;
if (!band->valid_band)
continue;
for (block=band->blocks,
p=band->total_blocks; p > 0; p--, block++)
{
block->num_passes = block->old_passes;
block->byte_count_bits=block->old_byte_count_bits;
}
}
}
}
}
}
} while (rd_threshold < max_rd_threshold);
return(rd_threshold);
}
/* CRIL Technology/SAIC Scan Buffer begin */
/*****************************************************************************/
/* STATIC set_buffer_threshold */
/*****************************************************************************/
static rd_slope_type
set_buffer_threshold(ebcot_encoder_ref self, stream_out_ref stream,
int layer_idx, rd_slope_type max_rd_threshold,
tag_buffer_ptr tags,
int max_buffer_size_bytes,
int previous_buffer_size_bytes,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -