ebcot_send_bits.c
来自「JPEG2000实现的源码」· C语言 代码 · 共 1,604 行 · 第 1/5 页
C
1,604 行
int tnum_start, int tnum_end,
int pnum_start, int pnum_end,
int last_tnum_header_written)
/* This function helps implement a reduced memory buffer by determining a
rate-distortion slope threshold to use in truncating bit-plane passes from
entropy encoded quantized indices. The method for determining which passes
to truncate is based on the optimize_bitstream_layer() routine. The main
iterative loop is still the same, but the element_idx start and end
parameters for this routine specify a window of elements which should be
included in the reduced memory buffer. */
{
ebcot_tile_ptr tile;
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_precinct_info_ptr precinct;
ebcot_precinct_band_info_ptr pband;
ebcot_band_info_ptr band;
ebcot_block_info_ptr block;
ebcot_sequence_ptr seq;
rd_slope_type min_rd_threshold, rd_threshold;
int c, n, b, p;
int tnum, pnum_end2;
int actual_bytes;
min_rd_threshold = 0;
/* Start by saving the state of the tag trees. */
if (layer_idx != 0)
{ /* Start by saving the state of the tag trees. */
for (tnum=tnum_start; tnum <= tnum_end; 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;
}
}
}
}
}
}
/* 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_buffer_size_bytes;
for (tnum = tnum_start; tnum <= tnum_end; tnum++) {
tile = self->tiles + tnum;
pnum_end2 = pnum_end;
if (tnum < tnum_end)
pnum_end2 = tile->total_packets - 1;
if ((tnum > last_tnum_header_written) && (layer_idx == 0))
{
int tpart;
for (tpart=0; tpart < tile->num_tparts; tpart++)
actual_bytes +=
stream->write_tpart_header(stream,tnum,tile->num_tparts,
tpart,1,0);
}
for (p=pnum_start; p <= pnum_end2; p++) {
seq = tile->packet_sequence + p;
if (seq->layer_idx != layer_idx)
continue;
precinct = seq->precinct;
actual_bytes +=
form_packet(precinct,rd_threshold,stream,1,layer_idx,tags);
}
}
if (actual_bytes > max_buffer_size_bytes)
min_rd_threshold = rd_threshold;
else
max_rd_threshold = rd_threshold;
/* Avoid potential infinite loop if min_rd_threshold is too large */
/* Not sure this is actually needed. */
if (min_rd_threshold == max_rd_threshold) min_rd_threshold >>= 1;
rd_threshold = (rd_slope_type)
((((std_int) min_rd_threshold) + ((std_int) max_rd_threshold) + 1) >> 1);
/* Finish up by restoring the state to that of the previous layer. */
if (layer_idx != 0) {
for (tnum=tnum_start; tnum <= tnum_end; 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 end */
/* ========================================================================= */
/* --------------------------- Threshold Estimation ------------------------ */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC estimate_layer_threshold */
/*****************************************************************************/
static rd_slope_type
estimate_layer_threshold(int target_bytes, std_int *rd_slope_rates,
ebcot_layer_info_ptr last_layer)
/* This function attempts to estimate a rate-distortion threshold which will
achieve a target number of code bytes close to the supplied `target_bytes'
value. It uses information of two types in order to do this. First,
the `rd_slope_rates' array contains summary information collected while
encoding the code blocks (see definition of `ebcot_encoder' in
"ebcot_encoder.h" for more information on this). Secondly, the
`last_layer' structure contains the rate-distortion threshold and the
actual number of bytes written to the bit-stream up to and including the
last generated bit-stream layer. */
{
std_short max_exponent, max_mantissa, exponent, mantissa, n1, n2;
rd_slope_type last_threshold;
double t1, t2, r1, r2, r, t;
max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;
/* Find the smallest index into the `rd_slope_rates' table which yields a
larger threshold than that used in the last layer. */
last_threshold = last_layer->rd_threshold;
for (n1=max_exponent-1;
(n1 >= 0) && ((n1<<RD_SLOPE_MANTISSA_BITS) >= last_threshold);
n1--);
n1++;
n2 = n1-1;
/* Begin David T fix. */
if ((n2 >= 0) && (rd_slope_rates[n1] != rd_slope_rates[n2]))
{ /* Can hope for a reasonable estimate of the error due to linear
interpolation. We will use this error to refine our estimates. */
double offset;
n2 = n1-1;
r = (double)(last_layer->actual_cumulative_bytes);
r1 = (double)(rd_slope_rates[n1]);
r2 = (double)(rd_slope_rates[n2]);
if (r1 == 0.0) /* Take care of pathological cases. */
{ r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
r1 = log(r1); r2 = log(r2); r = log(r); /* log of all rates. */
t1 = (double) n1; /* log_2 of first slope threshold. */
t2 = (double) n2; /* log_2 of second slope threshold. */
t = ((double)(last_threshold>>RD_SLOPE_MANTISSA_BITS)) +
log(((double)(last_threshold & max_mantissa)) /
((double)(max_mantissa+1)) + 1.0) /
log(2.0); /* log_2 of last slope threshold. */
offset = r - (r1 + (t-t1)*(r2-r1)/(t2-t1));
if (offset > 0.0)
{ /* Actual rate tends to be higher than that predicted from the
`rd_slope_rates' table presumably as a result of overhead.
Factor this overhead into a new lower target rate which does
not include the overhead. */
r = (double) target_bytes;
r = log(r) - offset;
target_bytes = (int) exp(r);
}
}
/* End David T fix. */
/* Now find the two adjacent indices into the `slope_rates' table whose
rates are closest to the target bit-rate. */
for (n2=n1; n2 >= 0; n2--)
if (rd_slope_rates[n2] > target_bytes)
break;
if (n2 == max_exponent)
n2 = max_exponent-1;
n1 = n2+1;
/* Begin David T fix. */
if ((n2 < 0) || (rd_slope_rates[n1] == rd_slope_rates[n2]))
return(n1<<RD_SLOPE_MANTISSA_BITS);
/* End David T fix. */
/* Finally, use linear interpolation to estimate log_2 of the rate-distortion
threshold */
r = (double) target_bytes;
r1 = (double)(rd_slope_rates[n1]);
r2 = (double)(rd_slope_rates[n2]);
if (r1 == 0.0) /* Take care of pathological cases. */
{ r1 += 1.0 + r2; r += 1.0 + r2; r2 += 1.0 + r2; }
r1 = log(r1); r2 = log(r2); r = log(r); /* log of all rates. */
t1 = (double) n1; /* log_2 of first slope threshold. */
t2 = (double) n2; /* log_2 of second slope threshold. */
t = t1 + (r-r1)*(t2-t1)/(r2-r1);
/* Finally, convert back to an `rd_slope_type' representation. */
exponent = (std_short) floor(t);
t -= (double) exponent; /* This gives log_2(1+2^(-Mbits)*`mantissa'). */
t = exp(t * log(2.0));
t -= 1.0;
t *= (double)(max_mantissa+1);
mantissa = (std_short) floor(t+0.5);
if (mantissa < 0)
mantissa = 0;
if (mantissa > max_mantissa)
{
assert(mantissa == (max_mantissa+1));
mantissa = 0;
exponent++;
}
assert((exponent >= 0) && (exponent <= max_exponent));
return((exponent << RD_SLOPE_MANTISSA_BITS) + mantissa);
}
/* CRIL Technology/SAIC Scan Buffer begin */
/*****************************************************************************/
/* STATIC scan_element_filled */
/*****************************************************************************/
int scan_element_filled(ebcot_encoder_ref self)
/* This function checks to see if enough coder blocks have been processed to
fill up a scan element. If not, 0 is returned. If so, then this function
checks to see if enough scan elements have been processed to fill up the
reduced memory buffer. If not, value 1 is returned. If enough scan
elements are available, value 2 is returned. */
{
ebcot_tile_ptr tile;
ebcot_component_info_ptr comp_info;
ebcot_level_info_ptr lev;
ebcot_band_info_ptr band;
int c, n, b;
tile = self->tiles + self->current_tile_idx;
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 (b = lev->min_band; b <= lev->max_band; b++) {
band = lev->bands + b;
if (!band->valid_band)
continue;
if (band->scan_buffer_lines < band->max_scan_buffer_lines) {
return(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 (b = lev->min_band; b <= lev->max_band; b++) {
band = lev->bands + b;
if (!band->valid_band)
continue;
band->scan_buffer_lines -= band->max_scan_buffer_lines;
if (self->buffer_end == (self->num_scan_elements - 2)) {
band->max_scan_buffer_lines = band->dims.rows -
(self->buffer_end + 1) * band->max_scan_buffer_lines;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?