📄 ebcot_encoder.c
字号:
significant = (master->block_mag >> master->bit_idx) & 1;
if (significant)
{ /* Significant for the first time. */
master->first_bit_idx = master->bit_idx;
mark_termination_points(info->passes,info->insignificant_msbs,
info->max_passes,
master->terminate_each_pass,
master->full_effort_msbs);
}
}
if (!significant)
info->insignificant_msbs++;
for (n=0; n < PASSES_PER_BITPLANE; n++, pass_idx++)
{
block_coding_pass_func pass_function;
if (pass_idx == info->max_passes)
{ bitplane_idx = last_bitplane; break; }
if (pass_idx == first_lossless_pass)
{ /* Switch to MSE LUT's which correctly estimate distortion
reduction when processing the LSB of a lossless sample
value representation. */
master->initial_mse_lut = ebcot_lossless_initial_mse_lut;
master->refinement_mse_lut = ebcot_lossless_refinement_mse_lut;
}
if (significant)
{
pass_function = band->pass_funcs[n];
if (master->reset)
dst_arith_coder__model_init(&(master->coder_state),
initial_mq_contexts);
/* Begin David T Cvis mod */
for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap)
for (i=cells_wide; i--; cell++)
cell->delta_mse = 0;
pass_function(master);
for (cell=master->d_cells, j=cells_high; j--; cell+=cell_gap)
for (i=cells_wide; i--; cell++)
{
double wmse_inc;
wmse_inc = (double)(cell->delta_mse);
wmse_inc *= scale_wmse;
if (n == 0)
wmse_inc *= 4.0;
wmse_inc *= cell->visibility_factor;
delta_wmse += wmse_inc;
}
/* End David T Cvis mod */
if (master->segmark && (n==0))
insert_segment_marker(master);
master->saved_states[pass_idx] = master->coder_state;
if (info->passes[pass_idx].terminated)
info->passes[pass_idx].cumulative_bytes =
dst_arith_coder__deactivate(&(master->coder_state),
master->easy_termination);
}
else
info->passes[pass_idx].cumulative_bytes = 0;
master->cumulative_wmse[pass_idx] = delta_wmse;
}
}
dst_arith_coder__flush(&(master->coder_state));
#ifdef DST_LOG_SYMBOLS
fclose(master->coder_state.symbol_log);
master->coder_state.symbol_log = NULL;
#endif /* DST_LOG_SYMBOLS */
/* Update state information in `info' and `band' to reflect operations. */
info->first_unit = heap;
info->first_pos = heap_pos;
last_bytes = 0;
last_terminated_bytes = 0;
for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++)
if (info->passes[n].terminated)
break;
if (n < pass_idx)
next_terminated_bytes = info->passes[n].cumulative_bytes;
for (n=info->insignificant_msbs*PASSES_PER_BITPLANE; n < pass_idx; n++)
{
if (!info->passes[n].terminated)
{
info->passes[n].cumulative_bytes =
dst_arith_coder__get_minimum_bytes(master->saved_states+n,
heap,heap_pos,
last_terminated_bytes,
next_terminated_bytes);
}
else
{
int m;
assert(next_terminated_bytes ==
(int) info->passes[n].cumulative_bytes);
last_terminated_bytes = next_terminated_bytes;
for (m=n+1; m < pass_idx; m++)
if (info->passes[m].terminated)
{
next_terminated_bytes = info->passes[m].cumulative_bytes;
break;
}
}
assert(last_bytes <= info->passes[n].cumulative_bytes);
last_bytes = info->passes[n].cumulative_bytes;
}
assert(last_bytes <= (master->coder_state.saved_words<<2));
compute_rd_slopes(pass_idx,master->cumulative_wmse,
info->passes,self->rd_slope_rates);
/* SAIC TCQ begin */ /* Force last three bit-planes to be included at same time */
if (master->include_all_passes && (pass_idx > 2) && significant) {
info->passes[pass_idx-2].rd_slope = -1;
info->passes[pass_idx-3].rd_slope = -1;
}
/* SAIC TCQ begin */
/* SAIC TCQ begin mods */
if (band->quant_to_zero) {
for (n=0; n<pass_idx; n++) {
info->passes[n].rd_slope = -1;
}
}
else if ((band->lossless || master->include_all_passes) && (pass_idx > 0) &&
(info->passes[pass_idx-1].rd_slope <= 0) &&
significant) /* Force inclusion of all bitplane passes */
{ /* Must include all significant coding passes in lossless mode to
comply with the JPEG2000 standard, even if the last pass is
not required to achieve 0 distortion under the assumption that the
dequantizer will round to the midpoint of the quantization
thresholds. This requirement is introduced to avoid dependence on
the dequantizer's rounding strategy. */
info->passes[pass_idx-1].rd_slope = 1; /* Least desirable legal slope. */
/* Now make sure we have not violated the requirement that slopes
for points on the convex hull be strictly decreasing and have
strictly increasing lengths. */
for (n=pass_idx-2; n >= 0; n--)
if (info->passes[n].rd_slope > 0)
{ /* Otherwise not on the convex hull. */
if ((info->passes[n].rd_slope == 1) ||
(info->passes[n].cumulative_bytes ==
info->passes[pass_idx-1].cumulative_bytes))
{
info->passes[pass_idx-1].rd_slope = info->passes[n].rd_slope;
info->passes[n].rd_slope = 0;
}
break;
}
}
/* SAIC TCQ end mods */
for (; pass_idx < info->max_passes; pass_idx++)
{
info->passes[pass_idx].cumulative_bytes = last_bytes;
info->passes[pass_idx].rd_slope = -1;
}
band->heap_tail = master->coder_state.heap;
band->next_heap_pos = master->coder_state.next_heap_pos;
/* CRIL Technology/SAIC Scan Buffer begin */
info->next_unit = master->coder_state.heap;
info->next_unit_used = master->coder_state.next_heap_pos;
/* CRIL Technology/SAIC Scan Buffer end */
/* End of timed section. */
if (self->cpu_time >= 0)
self->cpu_time += (std_int)(clock()-cpu_time);
/* See if code word byte order needs to be reversed. */
msb_first = 1; *((std_byte *)(&msb_first)) = 0;
if (!msb_first)
{ /* Least significant byte appears first in each code word. Need to
reverse this to allow the word buffers to be written out as byte
buffers later when we generate the bit-stream. */
std_int word, *wp;
int heap_remnant;
wp = heap->words + heap_pos;
heap_remnant = DST_HEAP_WORDS - heap_pos;
assert(heap_remnant > 0);
for (n=master->coder_state.saved_words; n > 0; n--)
{
word = *wp;
word = ((word >> 24) & 0x000000FF) | ((word >> 8) & 0x0000FF00) |
((word << 8) & 0x00FF0000) | ((word << 24) & 0xFF000000);
*(wp++) = word;
if ((--heap_remnant) == 0)
{ heap_remnant = DST_HEAP_WORDS; heap=heap->next; wp=heap->words; }
}
}
}
/* ========================================================================= */
/* ---------------------- Layer Construction Functions --------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC get_layer_specs */
/*****************************************************************************/
static void
get_layer_specs(ebcot_encoder_ref self, cmdl_ref cmdl,
int max_bytes, int rows, int cols)
/* This function determines the total number of bit-stream layers, based
on information supplied via the `-Clayers' argument, if any, and uses
this information to construct an initial `layer_info' array for the
object referenced by `self'. The contents of this array may change
and the number of layers may be reduced when the
`complete_quality_layers' function is called.
For the moment, the `max_cumulative_bytes' field of each
`ebcot_layer_info' record will be set to the total number of bytes
for the entire code-stream which should be devoted to the relevant layer,
plus all previous layers and the global header itself. During the call
to `complete_quality_layers', the global header size
will be subtracted from the `max_cumulative_bytes' field of each
`ebcot_layer_info' record. */
{
double rate;
char **params;
int p, extra_layers, n, last_max_bytes;
self->num_layers = 1;
self->layer_info = (ebcot_layer_info_ptr)
local_malloc(EBCOT_MEM_KEY,sizeof(ebcot_layer_info)*2);
if ((p = cmdl->extract(cmdl,"-Clayers",-1,¶ms)) < 0)
{ /* Install only one layer. */
self->layer_info->max_cumulative_bytes = max_bytes;
self->layer_info->actual_cumulative_bytes = 0;
self->layer_info->optimize = 1;
self->layer_info->rd_threshold = 0;
return;
}
if (p == 0)
{ /* Install default SNR scalable rate specs. */
self->num_layers = 60;
self->layer_info = (ebcot_layer_info_ptr)
local_realloc(self->layer_info,
sizeof(ebcot_layer_info)*self->num_layers);
memset(self->layer_info,0,
sizeof(ebcot_layer_info)*(size_t)(self->num_layers));
rate = 0.015;
self->layer_info[0].max_cumulative_bytes = (int)
(rate * 0.125 * (double)(rows*cols));
self->layer_info[0].optimize = 1;
rate = 2.0;
self->layer_info[49].max_cumulative_bytes = (int)
(rate * 0.125 * (double)(rows*cols));
self->layer_info[49].optimize = 1;
}
else
{
if ((sscanf(*params,"%lf",&rate) == 0) || (rate <= 0.0))
local_error("The `-Clayers' argument must have zero or more "
"specification blocks, each starting with a valid "
"positive bit-rate parameter; found \"%s\" instead!",
*params);
params++; p--;
last_max_bytes = 0; n = 0;
do {
extra_layers = 0;
if ((p > 0) && ((*params)[0] == '+'))
{
if ((sscanf((*params)+1,"%d",&extra_layers)==0) ||
(extra_layers < 0))
local_error("The `-Clayers' argument contains an "
"incorrectly formatted parameter identifying "
"extra bit-stream layers!");
params++; p--;
}
self->num_layers += 1 + extra_layers;
self->layer_info = (ebcot_layer_info_ptr)
local_realloc(self->layer_info,
sizeof(ebcot_layer_info)*self->num_layers);
self->layer_info[n].max_cumulative_bytes = (int)
(rate * 0.125 * (double)(rows*cols));
if (self->layer_info[n].max_cumulative_bytes <= 0)
self->layer_info[n].max_cumulative_bytes = 1; /* Keep it legal. */
if (last_max_bytes >= self->layer_info[n].max_cumulative_bytes)
local_error("The bit-rates supplied to `-Clayers' must appear "
"in increasing order!");
last_max_bytes = self->layer_info[n].max_cumulative_bytes;
self->layer_info[n].actual_cumulative_bytes = 0;
self->layer_info[n].optimize = 1;
self->layer_info[n].rd_threshold = 0;
n++;
for (; extra_layers > 0; extra_layers--, n++)
{
self->layer_info[n].max_cumulative_bytes = 0;
/* Fill in true value in `complete_bit_stream_layers'. */
self->layer_info[n].actual_cumulative_bytes = 0;
self->layer_info[n].optimize = 0;
self->layer_info[n].rd_threshold = 0;
}
} while (((p--) > 0) && (sscanf(*(params++),"%lf",&rate) == 1));
}
n = self->num_layers - 1;
self->layer_info[n].max_cumulative_bytes = max_bytes;
self->layer_info[n].actual_cumulative_bytes = 0;
self->layer_info[n].optimize = 1;
self->layer_info[n].rd_threshold = 0;
}
/*****************************************************************************/
/* STATIC complete_quality_layers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -