📄 ebcot_send_bits.c
字号:
}
}
}
}
if (self->buffer_end < (self->num_scan_elements_in_buffer - 1))
return(1); /* New complete scan element available, but don't release
bytes until enough scan elements are available to fill
up the scan buffer. */
return(2);
}
/* CRIL Technology/SAIC Scan Buffer end */
/* ========================================================================= */
/* ---------------------------- 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);
elts = 0;
next_rows = rows;
next_cols = cols;
do {
new_elts = next_rows*next_cols;
elts += new_elts;
next_rows = (1+next_rows)>>1;
next_cols = (1+next_cols)>>1;
} while (new_elts > 1);
result = node = (tag_tree_node_ptr)
local_malloc(EBCOT_MEM_KEY,sizeof(tag_tree_node)*elts);
do {
elts = rows*cols;
parents = node + elts;
if (elts == 1)
parents = NULL;
next_rows = (1+rows)>>1;
next_cols = (1+cols)>>1;
for (r=0; r < rows; r++)
for (c=0; c < cols; c++, node++)
{
node->value = INT_MAX;
node->lower_bound = 0;
node->value_known = 0;
node->child = NULL;
node->parent = NULL;
if (parents != NULL)
node->parent = parents + ((r>>1)*next_cols + (c>>1));
}
rows = next_rows;
cols = next_cols;
} while (elts > 1);
return(result);
}
/*****************************************************************************/
/* EXTERN ebcot_destroy_tag_tree */
/*****************************************************************************/
void
ebcot_destroy_tag_tree(tag_tree_node_ptr tree)
{
if (tree != NULL)
local_free(tree);
}
/*****************************************************************************/
/* EXTERN ebcot_send_bit_stream */
/*****************************************************************************/
void
ebcot_send_bit_stream(ebcot_encoder_ref self)
{
rd_slope_type rd_threshold;
std_int max_exponent, max_mantissa;
ebcot_tile_ptr tile;
ebcot_precinct_info_ptr precinct;
ebcot_sequence_ptr seq;
int tnum, p, tpart, tinc, tbeyond;
int layer_idx, packet_bytes, total_bytes, max_bytes;
int tpart_bytes=0; /* TJF: =0 to avoid warnings */
ebcot_layer_info_ptr layer;
tag_buffer_ptr tags;
stream_out_ref stream;
tags = create_tag_buffer();
max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;
rd_threshold = (max_exponent << RD_SLOPE_MANTISSA_BITS) + max_mantissa;
stream = self->stream;
total_bytes = 0;
for (layer_idx=0; layer_idx < self->num_layers; layer_idx++)
{
layer = self->layer_info + layer_idx;
max_bytes = layer->max_cumulative_bytes;
if (self->vpw_info != NULL)
ebcot_vpw__set_layer_weights(self->vpw_info,self,max_bytes);
if ((layer->optimize) || (self->vpw_info != NULL))
{
/* W. Zeng vpw fix, if vpw, always use optimize_bitstream_layer,
since estimate_layer_threshold won't give a good estimate */
rd_threshold =
optimize_bitstream_layer(self,stream,layer_idx,rd_threshold,tags,
max_bytes,total_bytes);
}
else
{
assert(layer_idx > 0);
rd_threshold =
estimate_layer_threshold(max_bytes,self->rd_slope_rates,layer-1);
}
for (tnum=0; tnum < self->num_tiles; tnum++)
{
tile = self->tiles + tnum;
/* Begin DST POC mod */
for (tpart=-1, p=0; p < tile->total_packets; p++)
{
seq = tile->packet_sequence + p;
while (seq->tpart > tpart)
{
if (tpart >= 0)
{
tile->tpart_bytes[tpart] += tpart_bytes;
total_bytes += tpart_bytes;
}
tpart++;
tpart_bytes = 0;
if (layer_idx == 0)
tpart_bytes =
stream->write_tpart_header(stream,tnum,tile->num_tparts,
tpart,1,0);
}
assert(seq->tpart == tpart);
if (seq->layer_idx != layer_idx)
continue;
precinct = seq->precinct;
packet_bytes = precinct->layer_bytes[layer_idx] =
form_packet(precinct,rd_threshold,stream,1,layer_idx,tags);
tpart_bytes += packet_bytes;
}
tile->tpart_bytes[tpart] += tpart_bytes;
total_bytes += tpart_bytes;
/* End DST POC mod */
}
layer->rd_threshold = rd_threshold;
layer->actual_cumulative_bytes = total_bytes;
}
/* Finally, we output all packets to the codestream in the prescribed
sequence. */
total_bytes = 0;
if (self->reverse_tiles)
{ tnum = self->num_tiles-1; tinc = -1; tbeyond = -1; }
else
{ tnum = 0; tinc = 1; tbeyond = self->num_tiles; }
for (; tnum != tbeyond; tnum += tinc)
{
tile = self->tiles + tnum;
/* Begin DST POC mod */
for (tpart=-1, p=0; p < tile->total_packets; p++)
{
seq = tile->packet_sequence + p;
layer_idx = seq->layer_idx;
layer = self->layer_info + layer_idx;
max_bytes = layer->max_cumulative_bytes;
/* Begin David T VPW fix. */
if (self->vpw_info != NULL)
ebcot_vpw__set_layer_weights(self->vpw_info,self,max_bytes);
/* End David T VPW fix. */
rd_threshold = layer->rd_threshold;
while (seq->tpart > tpart)
{
if (tpart >= 0)
assert(tpart_bytes == tile->tpart_bytes[tpart]);
tpart++;
tpart_bytes = tile->tpart_bytes[tpart];
if (self->omit_last_tile_length &&
(tnum+tinc == tbeyond) && ((tpart+1) == tile->num_tparts))
tpart_bytes = 0;
tpart_bytes =
stream->write_tpart_header(stream,tnum,tile->num_tparts,
tpart,0,tpart_bytes);
total_bytes += tpart_bytes;
}
assert(seq->tpart == tpart);
precinct = seq->precinct;
packet_bytes =
form_packet(precinct,rd_threshold,stream,0,layer_idx,tags);
if (packet_bytes != precinct->layer_bytes[layer_idx])
local_error("Error made during packet simulation by `stream_out' "
"object: simulated bytes = %d; actual bytes = %d!",
precinct->layer_bytes[layer_idx],packet_bytes);
tpart_bytes += packet_bytes;
total_bytes += packet_bytes;
}
assert(tpart_bytes == tile->tpart_bytes[tpart]);
/* End DST POC mod */
}
tag_buffer__destroy(tags);
}
/* CRIL Technology/SAIC Scan Buffer begin */
/*****************************************************************************/
/* EXTERN ebcot_send_scan_buffer_bit_stream */
/*****************************************************************************/
void
ebcot_send_scan_buffer_bit_stream(ebcot_encoder_ref self)
{
rd_slope_type rd_threshold;
ebcot_layer_info_ptr layer;
ebcot_tile_ptr tile;
ebcot_sequence_ptr seq;
ebcot_precinct_info_ptr precinct;
stream_out_ref stream;
tag_buffer_ptr tags;
float desired_bpp;
float max_bytes_multiplier;
long *scan_element_pixel_cnt;
long buffer_size_bytes, orig_buffer_size_bytes, new_buffer_size_bytes;
long total_bytes, packet_bytes, tile_bytes, no_excess_bytes_released;
long last_max_cumulative_bytes, max_bytes;
long desired_file_size;
long image_size;
short max_exponent, max_mantissa;
int p, c, n, k;
int tnum;
int num_scan_elements;
int *tile_start, *precinct_start, *tile_end, *precinct_end;
int buffer_start, buffer_end;
int no_bytes_in_buffer, no_bytes_released = 0;
int num_scan_elements_in_buffer;
int first_seg_tnum_start, first_seg_tnum_end;
int first_seg_pnum_start, first_seg_pnum_end, pnum_end2;
int last_seg_tnum_end, last_seg_pnum_end;
int last_tnum_header_written;
int insertion_index;
int no_bytes_to_release;
int layer_idx;
int flush_buffer;
flush_buffer = scan_element_filled(self);
if (flush_buffer < 2) {
if (flush_buffer == 1)
self->buffer_end++;
return;
}
tags = create_tag_buffer();
max_exponent = (1<<RD_SLOPE_EXPONENT_BITS) - 1;
max_mantissa = (1<<RD_SLOPE_MANTISSA_BITS) - 1;
stream = self->stream;
desired_bpp = self->desired_bpp;
desired_file_size = self->desired_file_size;
image_size = self->image_size;
scan_element_pixel_cnt = self->scan_element_pixel_cnt;
orig_buffer_size_bytes = self->orig_buffer_size_bytes;
num_scan_elements = self->num_scan_elements;
num_scan_elements_in_buffer = self->num_scan_elements_in_buffer;
tile_start = self->tile_start;
precinct_start = self->precinct_start;
tile_end = self->tile_end;
precinct_end = self->precinct_end;
buffer_end = self->buffer_end;
buffer_start = self->buffer_start;
no_excess_bytes_released = self->no_excess_bytes_released;
last_tnum_header_written = self->last_tnum_header_written;
insertion_index = buffer_end - (self->num_scan_elements_in_buffer - 1);
if (insertion_index == 0) {
/* Do a little more initialization which can't be done in the encoder's
initialize() function*/
int header_bytes;
stream->release_global_header(stream);
header_bytes = stream->get_global_header_size(stream);
if (self->vpw_info != NULL)
ebcot_vpw__complete(self->vpw_info,self->max_component_cols,
self->max_component_rows,header_bytes);
for (n=0; n < self->num_layers; n++)
self->layer_info[n].max_cumulative_bytes +=
ESTIMATED_HEADER_BYTES - header_bytes;
self->desired_file_size = desired_file_size =
stream->get_max_remaining_bytes(stream);
self->desired_bpp = desired_bpp = ((float) desired_file_size) * 8.0F /
((float) image_size);
}
buffer_size_bytes = orig_buffer_size_bytes;
new_buffer_size_bytes = 0;
/* Adjust buffer_size_bytes to achieve constant quality for all scan
elements */
for (n=buffer_end - num_scan_elements_in_buffer + 1; n<=buffer_end; n++) {
new_buffer_size_bytes += (long) (((float) scan_element_pixel_cnt[n]) *
desired_bpp / 8.0F);
}
if (new_buffer_size_bytes < buffe
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -