📄 hp_dummy_decoder.c
字号:
comp_info = self->components + comp;
lev = comp_info->levels + n;
for (b=lev->min_band; b <= lev->max_band; b++)
{ /* Read in the bit-stream for this subband. */
int pull_bytes;
std_int word;
band = lev->bands + b;
word = 0x7FFFFFFF;
if (input->pull_bytes(input,(std_byte *)(&word),4) < 4)
{ word = 0; discard = 1; }
else
{
if (!right_endian)
reverse_words(&word,1);
if (!discard)
actual_bytes += 4;
}
if (discard)
band->num_bytes = 0;
else
{
band->num_bytes = word;
actual_bytes += band->num_bytes;
}
while ((pull_bytes = word) > 0)
{
heap_unit_ptr unit;
if (pull_bytes > HEAP_BYTES)
pull_bytes = HEAP_BYTES;
unit = get_heap_unit(self);
unit->next = NULL;
if (band->tail == NULL)
band->store = band->tail = unit;
else
band->tail = band->tail->next = unit;
if (input->pull_bytes(input,(std_byte *)(unit->words),
pull_bytes) != pull_bytes)
break; /* Bit-stream terminated early. */
if (!right_endian)
reverse_words(unit->words,(pull_bytes+3)>>2);
word -= pull_bytes;
}
if ((word != 0) || (actual_bytes > max_extra_bytes))
discard = 1;
if (discard)
{ /* Bit-stream terminated early or subband should be
parsed out */
actual_bytes -= band->num_bytes; /* Could be parsed out. */
band->num_bytes = 0;
while ((band->tail = band->store) != NULL)
{
band->store = band->tail->next;
return_heap_unit(self,band->tail);
}
}
else
band->run = input_byte(self,band);
}
}
}
self->actual_bytes = actual_bytes;
}
/*****************************************************************************/
/* STATIC __print_usage */
/*****************************************************************************/
static void
__print_usage(decoder_ref base, FILE *dest)
{
return; /* No special command-line options for this object. */
}
/*****************************************************************************/
/* STATIC __pull_line */
/*****************************************************************************/
static void
__pull_line(decoder_ref base, ifc_int *line_buf, int component_idx,
int level_idx, int band_idx, int width)
{
the_decoder_ref self = (the_decoder_ref) base;
component_info_ptr comp_info;
ifc_int extra_bits, val, half_bit;
std_int big_val, num_bytes, n, down_shift, up_shift;
band_info_ptr band;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(level_idx < comp_info->num_levels));
band = comp_info->levels[level_idx].bands + band_idx;
assert(width == band->cols);
extra_bits = band->extra_bits;
if (band->consumed_bytes >= band->num_bytes)
{
for (; width > 0; width--)
*(line_buf++) = 0;
return;
}
/* Perform simple run-length decoding. */
num_bytes = (IMPLEMENTATION_PRECISION - extra_bits + 7) >> 3;
down_shift = (4-num_bytes)<<3;
up_shift = 0;
if (extra_bits < 1)
{
down_shift += -extra_bits;
half_bit = 1;
}
else
{
up_shift = extra_bits;
half_bit = (ifc_int)(1<<(extra_bits-1));
}
for (; width > 0; width--, line_buf++)
{
if (band->run)
{
*line_buf = 0;
band->run--;
}
else
{
big_val=0;
for (n=num_bytes; n > 0; n--)
{
big_val = (big_val >> 8) & 0x00FFFFFF;
big_val |= input_byte(self,band) << 24;
}
if (big_val < 0)
{
big_val &= 0x7FFFFFFF;
big_val >>= down_shift;
big_val <<= up_shift;
val = MIN_IFC_INT | ((ifc_int) big_val);
}
else
{
big_val >>= down_shift;
big_val <<= up_shift;
val = (ifc_int) big_val;
}
val &= (ifc_int)(~1);
val |= half_bit;
*line_buf = val;
band->run = input_byte(self,band);
}
}
band->lines_decoded++;
}
/*****************************************************************************/
/* STATIC __pull_block */
/*****************************************************************************/
static void
__pull_block(decoder_ref base, ifc_int **block_buf, int component_idx,
int level_idx, int band_idx, int block_rows, int block_cols,
int top_row, int left_col)
/* This function buffers up lines retrieved from `__pull_line' in order
to satisfy block requests. Any line-based coder would probably
duplicate this implementation. Block-based coders may choose to
implement the function more efficiently in order to optimally
utilize the block-oriented consumption pattern for the subband data. */
{
the_decoder_ref self = (the_decoder_ref) base;
component_info_ptr comp_info;
band_info_ptr band;
row_of_blocks_ptr bp;
ifc_int *sp, *dp;
int next_row, r, c;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(level_idx < comp_info->num_levels));
band = comp_info->levels[level_idx].bands + band_idx;
bp = band->blocks.tail;
if (bp == NULL)
{ /* First call. */
band->blocks.block_rows = block_rows;
band->blocks.block_cols = block_cols;
band->blocks.blocks_per_row = 1 + (band->cols-1)/block_cols;
next_row = 0;
}
else
next_row = bp->first_row + band->blocks.block_rows;
bp = band->blocks.head;
while ((bp == NULL) || (bp->unfetched_blocks < 0) ||
(bp->first_row < top_row))
{
if (bp == NULL)
{
bp = (row_of_blocks_ptr) local_malloc(sizeof(row_of_blocks));
bp->first_row = next_row;
next_row += band->blocks.block_rows;
bp->unfetched_blocks = -1; /* Indicates undecoded. */
bp->rows = (ifc_int **)
local_malloc(sizeof(ifc_int *) *
(size_t)(band->blocks.block_rows));
for (r=0; r < band->blocks.block_rows; r++)
bp->rows[r] = (ifc_int *)
local_malloc(sizeof(ifc_int)*(size_t)(band->cols));
bp->next = NULL;
if (band->blocks.tail == NULL)
band->blocks.head = band->blocks.tail = bp;
else
band->blocks.tail = band->blocks.tail->next = bp;
}
if (bp->unfetched_blocks < 0)
{ /* Decode all rows in the row of blocks. */
int current_rows;
bp->unfetched_blocks = band->blocks.blocks_per_row;
current_rows = band->rows - bp->first_row;
if (current_rows > band->blocks.block_rows)
current_rows = band->blocks.block_rows;
for (r=0; r < current_rows; r++)
__pull_line(base,bp->rows[r],component_idx,
level_idx,band_idx,band->cols);
}
else
bp = bp->next;
}
assert((bp->first_row == top_row) && (bp->unfetched_blocks > 0) &&
(block_rows <= band->blocks.block_rows) &&
(block_cols <= band->blocks.block_cols) &&
((block_rows+top_row) <= band->rows) &&
((block_cols+left_col) <= band->cols));
/* Copy block contents. */
for (r=0; r < block_rows; r++)
for (dp=block_buf[r], sp=bp->rows[r]+left_col, c=block_cols; c > 0; c--)
*(dp++) = *(sp++);
/* Check for completed rows of blocks. */
bp->unfetched_blocks--;
while ((bp->unfetched_blocks == 0) && (bp == band->blocks.head))
{ /* Shuffle the record to the tail. */
bp->first_row = band->blocks.tail->first_row + band->blocks.block_rows;
bp->unfetched_blocks = -1; /* Rows have yet to be pulled out. */
band->blocks.tail->next = bp;
band->blocks.tail = bp;
band->blocks.head = bp->next;
bp->next = NULL;
bp = band->blocks.head;
}
}
/*****************************************************************************/
/* STATIC __pull_tree */
/*****************************************************************************/
static void
__pull_tree(decoder_ref base, ifc_int **tree_buf, int levels,
int component_idx, int root_row, int root_col)
{
the_decoder_ref self = (the_decoder_ref) base;
component_info_ptr comp_info;
int lev, b, top_row, left_col, rows, cols, max_dim, r, r_off, c_off;
level_info_ptr li;
band_info_ptr band;
ifc_int **row_ptrs;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(levels <= comp_info->num_levels));
if (comp_info->tree_to_block_map == NULL)
comp_info->tree_to_block_map = (ifc_int **)
local_malloc(sizeof(ifc_int *)*(size_t)(1<<self->num_levels));
row_ptrs = comp_info->tree_to_block_map;
for (lev=0; lev < levels; lev++)
{
li = comp_info->levels + lev;
top_row = root_row << lev;
left_col = root_col << lev;
max_dim = 1<<lev;
for (b=li->min_band; b <= li->max_band; b++)
{
band = li->bands + b;
rows = band->rows - top_row;
cols = band->cols - left_col;
if (rows > max_dim)
rows = max_dim;
if (cols > max_dim)
cols = max_dim;
switch (b) {
case LL_BAND: r_off = c_off = 0; break;
case HL_BAND: r_off = 0; c_off = 1<<lev; break;
case LH_BAND: r_off = 1<<lev; c_off = 0; break;
case HH_BAND: r_off = 1<<lev; c_off = 1<<lev; break;
default: assert(0);
}
for (r=0; r < rows; r++)
row_ptrs[r] = tree_buf[r+r_off] + c_off;
__pull_block(base,row_ptrs,component_idx,lev,b,
rows,cols,top_row,left_col);
}
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static int
__terminate(decoder_ref base)
{
the_decoder_ref self = (the_decoder_ref) base;
component_info_ptr comp_info;
heap_group_ptr group;
int result, comp;
if (self->components != NULL)
{
for (comp=0; comp < self->num_components; comp++)
{
int b, n;
band_info_ptr band;
comp_info = self->components + comp;
for (n=0; n <= comp_info->num_levels; n++)
for (b=0; b < 4; b++)
{
band = comp_info->levels[n].bands + b;
destroy_block_buffering(&(band->blocks));
}
local_free(comp_info->levels);
if (comp_info->tree_to_block_map != NULL)
local_free(comp_info->tree_to_block_map);
}
local_free(self->components);
}
/* Free the entire bitstream heap. */
while ((group=self->heap) != NULL)
{
self->heap = group->next;
local_free(group);
}
result = self->actual_bytes;
local_free(self);
return(result);
}
/*****************************************************************************/
/* EXTERN create_dummy_decoder */
/*****************************************************************************/
decoder_ref
create_dummy_decoder(void)
{
the_decoder_ref result;
result = (the_decoder_ref)
local_malloc(sizeof(the_decoder_obj));
memset(result,0,sizeof(the_decoder_obj));
result->base.initialize = __initialize;
result->base.print_usage = __print_usage;
result->base.pull_line = __pull_line;
result->base.pull_block = __pull_block;
result->base.pull_tree =__pull_tree;
result->base.terminate = __terminate;
return((decoder_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -