📄 ebcot_decoder.c
字号:
else
{ /* This is a refinement pass for this group of siblings. */
for (feasible_pos=15, n=0; n < 4; n++, feasible_pos--)
if (((flags >> feasible_pos) & 1) == 0)
{ /* Otherwise, the node's significance is already known. */
get_uniform_symbol(state,A,C,word,avail,symbol);
if (symbol)
{
flags |= (1<<feasible_pos);
*(scan->node_update[n]) |= QUAD_PARENT_SIGNIFICANT;
}
}
}
scan->flags = flags;
}
state->A=A; state->C=C; state->word=word; state->available_bits=avail;
}
/*****************************************************************************/
/* STATIC reset_block_contexts */
/*****************************************************************************/
static void
reset_block_contexts(std_short *ctxt, int rows, int cols, int row_gap)
{
register int c;
int outside;
outside = (4-cols) & 3;
row_gap -= (cols + outside);
assert(row_gap > 0);
for (; rows > 0; rows--, ctxt += row_gap)
{
for (c=cols; c > 0; c--)
*(ctxt++) = 0;
for (c=outside; c > 0; c--)
*(ctxt++) = OUT_OF_BOUNDS;
}
}
/*****************************************************************************/
/* STATIC decode_block */
/*****************************************************************************/
static void
decode_block(the_decoder_ref self, ifc_int *sample_buffer,
band_info_ptr band, block_info_ptr info)
/* Decodes a single block of sample values. The actual dimensions of the
block may be found in the `info' structure. The `sample_buffer' array
receives the samples organized in lexicographical fashion, with
consecutive rows of block samples separated by `self->master.row_gap'
samples, which is always larger than the block width. */
{
block_master_ptr master = &(self->master);
code_subblock_ptr sblk;
int block_rows, block_cols;
int bitplane_idx, last_bitplane, pass_idx, n;
int max_significant_bit_idx, significant, msb_first;
clock_t cpu_time = 0;
master->bit_idx = IMPLEMENTATION_PRECISION-2;
max_significant_bit_idx = master->bit_idx - info->insignificant_msbs;
last_bitplane = master->bit_idx - band->extra_lsbs;
if (band->extra_lsbs < 1)
{ /* Cannot decode all bit-planes with current implementation precision.
Adjust `last_bitplane' and `info->num_passes'. */
last_bitplane = master->bit_idx-1;
pass_idx = last_bitplane * PASSES_PER_BITPLANE; /* Last allowable pass */
if (pass_idx < info->num_passes)
info->num_passes = pass_idx+1;
}
if (info->total_bytes == 0)
{
memset(sample_buffer,0,sizeof(ifc_int)*master->row_gap*info->rows);
return;
}
assert(info->num_passes > 0);
/* 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 account for the fact that word buffers were read
from the bit-stream as byte buffers. */
heap_unit_ptr heap;
int heap_remnant;
std_int word, *wp;
heap = info->first_unit;
wp = heap->words;
heap_remnant = HEAP_WORDS;
for (n=(info->total_bytes+3)>>2; 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 = HEAP_WORDS; heap=heap->next; wp=heap->words; }
}
}
/* Start of timed section. */
if (master->cpu_time >= 0)
cpu_time = clock();
/* Get ready for the decoding passes. */
if (band->band_idx == HL_BAND)
{
master->sample_buffer =
self->sample_buffer_heap_mgr->get_buffer(
self->sample_buffer_heap_mgr);
block_rows = info->cols;
block_cols = info->rows;
}
else
{
master->sample_buffer = sample_buffer;
block_rows = info->rows;
block_cols = info->cols;
}
memset(master->sample_buffer,0,sizeof(ifc_int)*block_rows*master->row_gap);
for (sblk=master->first_subblock; sblk <= master->last_subblock; sblk++)
{
sblk->significant = 0;
sblk->rows = block_rows - sblk->top_row;
sblk->cols = block_cols - sblk->left_col;
if (sblk->rows > master->max_sub_dim)
sblk->rows = master->max_sub_dim;
if (sblk->cols > master->max_sub_dim)
sblk->cols = master->max_sub_dim;
}
master->zc_lut = band->zc_lut;
initialize_quadtree(master);
ebcot_arith_coder__initialize(&(master->coder_state),info->first_unit,
info->total_bytes);
#ifdef LOG_SYMBOLS
master->coder_state.symbol_log = start_symbol_log(band,info);
#endif /* LOG_SYMBOLS */
reset_block_contexts(master->context_buffer,block_rows,block_cols,
master->row_gap);
/* Perform the decoding passes. */
for (significant=0, bitplane_idx=0, pass_idx=0;
bitplane_idx <= last_bitplane; bitplane_idx++, master->bit_idx--)
{
if (pass_idx == info->num_passes)
break;
assert(master->bit_idx > 0);
if ((!significant) && (master->bit_idx <= max_significant_bit_idx))
{
significant = 1;
master->block_update[0] |= QUAD_PARENT_SIGNIFICANT;
}
if (significant)
decode_quadtree(master);
for (n=0; n < PASSES_PER_BITPLANE; n++, pass_idx++)
{
block_coding_pass_func pass_function;
if (pass_idx == info->num_passes)
break;
if (significant)
{
pass_function = band->pass_funcs[n];
master->context_mask = band->pass_masks[n];
pass_function(master);
if (n == 0)
ebcot_arith_coder__renormalize(&(master->coder_state));
}
}
}
#ifdef SYMBOL_LOG
fclose(master->coder_state.symbol_log);
master->coder_state.symbol_log = NULL;
#endif /* SYMBOL_LOG */
if (master->sample_buffer != sample_buffer)
{
transpose_sample_buffer(master->sample_buffer,sample_buffer,
block_rows,block_cols,master->row_gap);
self->sample_buffer_heap_mgr->return_buffer(self->sample_buffer_heap_mgr,
master->sample_buffer);
}
/* End of timed section. */
if (master->cpu_time >= 0)
master->cpu_time += (long int)(clock()-cpu_time);
}
/* ========================================================================= */
/* ------------------------- Interface Implementation ---------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(decoder_ref base, int decomposition, int levels,
int components, int component_rows[], int component_cols[],
filter_info_ref info, int profile, int dedicated_bytes,
int max_extra_bytes, int max_levels, int max_components,
bitstream_source_ref input, int argc, char *argv[])
{
the_decoder_ref self = (the_decoder_ref) base;
component_info_ptr comp;
level_info_ptr lev;
code_subblock_ptr subblock;
int block_dim, block_width, block_height, subblock_dim;
int num_subs, subs_total, context_size;
int rows, cols;
int comp_idx, n, b, r, c, top_row, left_col;
if (decomposition != DECOMPOSITION__MALLAT)
{
fprintf(stderr,"The current implementation of the EBCOT decoder "
"object\n does not support anything other than Mallat-style "
"decompositions!\n");
exit(-1);
}
self->extra_header_bytes = 0;
self->input = input;
self->profile = profile;
get_block_dimensions(self);
get_layer_info(self);
self->max_bytes = max_extra_bytes - self->extra_header_bytes;
block_dim = self->master.max_dim;
subblock_dim = self->master.max_sub_dim;
block_width = block_dim;
block_height = self->max_block_height;
assert(block_height <= block_dim);
self->num_levels = levels;
self->max_levels = max_levels;
self->num_components = components;
self->max_components = max_components;
assert((max_levels <= levels) && (max_components <= components));
self->components = (component_info_ptr)
local_malloc(sizeof(component_info)*(size_t) components);
for (comp_idx=0; comp_idx < components; comp_idx++)
{
comp = self->components + comp_idx;
rows = component_rows[comp_idx];
cols = component_cols[comp_idx];
comp->levels = (level_info_ptr)
local_malloc(sizeof(level_info)*(size_t)(levels+1));
memset(comp->levels,0,sizeof(level_info)*(size_t)(levels+1));
for (lev=comp->levels, n=0; n <= levels; n++, lev++)
{
lev->component_idx = comp_idx;
lev->level_idx = n;
lev->min_band = (n==0)?0:1;
lev->max_band = 3;
if (n == levels)
{ /* Special level for whole image to cover degenerate case of a
zero level transform. */
lev->min_band = lev->max_band = 0;
if (levels > 0)
lev->max_band = -1;
}
lev->layer_tag_bytes = (std_short *)
local_malloc(sizeof(std_short)*(size_t)(self->bitstream_layers));
memset(lev->layer_tag_bytes,0,
sizeof(std_short)*(size_t)(self->bitstream_layers));
}
n = levels; lev = comp->levels + n;
lev->bands[0].band_rows = rows; lev->bands[0].band_cols = cols;
while (n > 0)
{
n--; lev--;
lev->bands[HL_BAND].band_cols =
lev->bands[HH_BAND].band_cols = cols >> 1;
lev->bands[LL_BAND].band_cols =
lev->bands[LH_BAND].band_cols = (cols+1)>>1;
lev->bands[LH_BAND].band_rows =
lev->bands[HH_BAND].band_rows = rows >> 1;
lev->bands[LL_BAND].band_rows =
lev->bands[HL_BAND].band_rows = (rows+1)>>1;
rows = lev->bands[LL_BAND].band_rows;
cols = lev->bands[LL_BAND].band_cols;
}
for (n=0, lev=comp->levels; n <= levels; n++, lev++)
for (b=lev->min_band; b <= lev->max_band; b++)
{ /* Complete band initialization. */
band_info_ptr band = lev->bands + b;
block_info_ptr block;
pass_info_ptr passes;
float step_wmse;
int extra_lsbs, total_blocks, max_passes;
band->component_idx = comp_idx;
band->level_idx = n;
band->band_idx = b;
info->get_quant_info(info,comp_idx,n,b,
NULL,NULL,&step_wmse,&extra_lsbs);
max_passes =
(IMPLEMENTATION_PRECISION-2-extra_lsbs)*PASSES_PER_BITPLANE + 1;
band->blocks_high = 1 + ((band->band_rows-1) / block_height);
band->blocks_wide = 1 + ((band->band_cols-1) / block_width);
band->band_blocks = total_blocks =
band->blocks_high*band->blocks_wide;
band->blocks = block = (block_info_ptr)
local_malloc(sizeof(block_info)*(size_t) total_blocks);
memset(block,0,sizeof(block_info)*(size_t) total_blocks);
passes = (pass_info_ptr)
local_malloc(sizeof(pass_info)*
(size_t)(total_blocks*max_passes));
memset(passes,0,
sizeof(pass_info)*(size_t)(total_blocks*max_passes));
for (top_row=0, r=0; r < band->blocks_high;
r++, top_row+=block_height)
for (left_col=0, c=0; c < band->blocks_wide;
c++, left_col+=block_width, block++, passes+=max_passes)
{ /* Complete block initialization. */
block->top_row = top_row;
block->left_col = left_col;
block->rows = band->band_rows - top_row;
if (block->rows > block_height)
block->rows = block_height;
block->cols = band->band_cols - left_col;
if (block->cols > block_width)
block->cols = block_width;
block->passes = passes;
block->max_passes = max_passes;
}
if (b == HH_BAND)
band->zc_lut = ebcot_diag_zc_lut;
else
band->zc_lut = ebcot_main_zc_lut;
ebcot_set_pass_funcs_and_masks(band,b);
band->step_wmse = step_wmse;
band->extra_lsbs = extra_lsbs;
band->lines.num_lines = 0;
band->lines.info = NULL;
band->lines.buffers = NULL;
}
}
num_subs = 1 + ((block_dim-1) / subblock_dim);
subs_total = num_subs * num_subs;
self->master.row_gap = block_dim + 2;
self->master.first_subblock = subblock = (code_subblock_ptr)
local_malloc(sizeof(code_subblock)*(size_t) subs_total);
self->master.last_subblock = subblock + subs_total - 1;
create_quadtree(num_subs,num_subs,subblock,
&(self->master.first_quad),&(self->master.last_quad));
self->master.block_update = (std_short *) self->master.first_quad;
if (self->master.block_update == NULL)
{
assert(num_subs == 1);
self->master.block_update = (std_short *) subblock;
}
memset(subblock,0,sizeof(code_subblock)*(size_t) subs_total);
for (top_row=0, r=0; r < num_subs; r++, top_row+=subblock_dim)
for (left_col=0, c=0; c < num_subs;
c++, left_col+=subblock_dim, subblock++)
{
subblock->top_row = top_row;
subblock->left_col = left_col;
subblock->offset = top_row*self->master.row_gap + left_col;
}
context_size = self->master.row_gap * (block_dim+2) + 2;
self->master.context_buffer = (std_short *)
local_malloc(sizeof(std_short)*(size_t) context_size);
self->master.context_buffer += self->master.row_gap + 2;
self->master.coder_state.contexts = self->master.contexts;
self->master.cpu_time = -1;
for (r=0; r < argc; r++)
if (strcmp(argv[r],"-Ccpu") == 0)
{
argv[r] = "";
self->master.cpu_time = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -