📄 hp_dummy_encoder.c
字号:
if (levels > 0)
lev->max_band = -1;
}
for (b=lev->min_band; b <= lev->max_band; b++)
{
int extra_bits;
info->get_quant_info(info,comp,n,b,NULL,NULL,NULL,&extra_bits);
lev->bands[b].extra_bits = (ifc_int) extra_bits;
}
}
n--; lev--;
lev->bands[0].rows = rows; lev->bands[0].cols = cols;
for (n--, lev--; n >= 0; n--, lev--)
{
lev->bands[HL_BAND].cols = lev->bands[HH_BAND].cols = cols >> 1;
lev->bands[LL_BAND].cols = lev->bands[LH_BAND].cols = (cols+1)>>1;
lev->bands[LH_BAND].rows = lev->bands[HH_BAND].rows = rows >> 1;
lev->bands[LL_BAND].rows = lev->bands[HL_BAND].rows = (rows+1)>>1;
rows = lev->bands[LL_BAND].rows;
cols = lev->bands[LL_BAND].cols;
}
}
}
/*****************************************************************************/
/* STATIC __print_usage */
/*****************************************************************************/
static void
__print_usage(encoder_ref base, FILE *dest)
{
return; /* No special command-line options for this object. */
}
/*****************************************************************************/
/* STATIC __push_line */
/*****************************************************************************/
static void
__push_line(encoder_ref base, ifc_int *line_buf, int component_idx,
int level_idx, int band_idx, int width)
{
the_encoder_ref self = (the_encoder_ref) base;
component_info_ptr comp_info;
ifc_int extra_bits, val, mag, num_bytes, sign, n;
band_info_ptr band;
assert(component_idx < self->num_components);
comp_info = self->components + component_idx;
band = comp_info->levels[level_idx].bands + band_idx;
extra_bits = band->extra_bits;
/* Perform simple run-length coding and push bytes out to bit-stream. */
assert(width == band->cols);
num_bytes = (IMPLEMENTATION_PRECISION - extra_bits + 7) >> 3;
sign = (ifc_int)(1<<((num_bytes<<3)-1));
for (; width > 0; width--, line_buf++)
{
val = *line_buf;
mag = val & MAX_IFC_MAG;
mag >>= extra_bits;
if (mag || (band->run == 255))
{
output_byte(self,band,band->run);
val = (val<0)?(mag|sign):mag;
for (n=num_bytes; n > 0; n--, val >>= 8)
output_byte(self,band,(val & 0x00FF));
band->run = 0;
}
else
band->run++;
}
}
/*****************************************************************************/
/* STATIC __push_block */
/*****************************************************************************/
static void
__push_block(encoder_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 blocks up into lines and ultimately calls the
`__push_line' function. 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 arrival pattern for the subband data. */
{
the_encoder_ref self = (the_encoder_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;
assert(component_idx < self->num_components);
comp_info = self->components + component_idx;
band = comp_info->levels[level_idx].bands + band_idx;
next_row = 0;
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->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->unfilled_blocks = band->blocks.blocks_per_row;
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;
}
else
bp = bp->next;
}
assert((bp->first_row == top_row) && (bp->unfilled_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 (sp=block_buf[r], dp=bp->rows[r]+left_col, c=block_cols; c > 0; c--)
*(dp++) = *(sp++);
/* Check for completed rows of blocks. */
bp->unfilled_blocks--;
while ((bp->unfilled_blocks == 0) && (bp == band->blocks.head))
{ /* Push all block rows and then shuffle the record to the tail. */
for (r=0; r < block_rows; r++)
__push_line(base,bp->rows[r],
component_idx,level_idx,band_idx,band->cols);
bp->first_row = band->blocks.tail->first_row + band->blocks.block_rows;
bp->unfilled_blocks = band->blocks.blocks_per_row;
band->blocks.tail->next = bp;
band->blocks.tail = bp;
band->blocks.head = bp->next;
bp->next = NULL;
bp = band->blocks.head;
}
}
/*****************************************************************************/
/* STATIC __push_tree */
/*****************************************************************************/
static void
__push_tree(encoder_ref base, ifc_int **tree_buf, int levels,
int component_idx, int root_row, int root_col)
{
the_encoder_ref self = (the_encoder_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;
assert(component_idx < self->num_components);
comp_info = self->components + component_idx;
assert(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<<comp_info->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;
__push_block(base,row_ptrs,component_idx,lev,b,
rows,cols,top_row,left_col);
}
}
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(encoder_ref base)
{
the_encoder_ref self = (the_encoder_ref) base;
heap_group_ptr group;
int right_endian; /* True if the MSB appears first in each word. */
right_endian = 1;
*((std_byte *)(&right_endian)) = 0;
if (self->components)
{
component_info_ptr comp_info;
level_info_ptr lev;
int comp, n, max_n, b;
max_n = self->num_levels - 1;
if (max_n < 0)
max_n = 0;
for (n=0; n <= max_n; n++)
{
for (comp=0; comp < self->num_components; comp++)
{
comp_info = self->components + comp;
lev = comp_info->levels + n;
for (b=lev->min_band; b <= lev->max_band; b++)
{ /* Push out the code words for this band. */
heap_unit_ptr up;
band_info_ptr band;
int push_bytes;
std_int word;
band = lev->bands + b;
destroy_block_buffering(&(band->blocks));
/* Push out last run. */
output_byte(self,band,band->run);
band->run = 0;
if (band->num_bytes & 3)
{ /* Flush partial word. */
band->word <<= 8*(4 - (band->num_bytes & 3));
output_word(self,band);
}
word = band->num_bytes;
if (!right_endian)
reverse_words(&word,1);
self->output->push_bytes(self->output,(std_byte *)(&word),4);
while ((push_bytes = band->num_bytes) > 0)
{
if (push_bytes > HEAP_BYTES)
push_bytes = HEAP_BYTES;
up = band->store;
if (!right_endian)
reverse_words(up->words,(push_bytes+3)>>2);
self->output->push_bytes(self->output,
(std_byte *)(up->words),
push_bytes);
band->store = up->next;
return_heap_unit(self,up);
band->num_bytes -= push_bytes;
}
}
}
}
for (comp=0; comp < self->num_components; comp++)
{
comp_info = self->components + comp;
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);
}
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_dummy_encoder */
/*****************************************************************************/
encoder_ref
create_dummy_encoder(void)
{
the_encoder_ref result;
result = (the_encoder_ref)
local_malloc(sizeof(the_encoder_obj));
memset(result,0,sizeof(the_encoder_obj));
result->base.initialize = __initialize;
result->base.print_usage = __print_usage;
result->base.push_line = __push_line;
result->base.push_block = __push_block;
result->base.push_tree = __push_tree;
result->base.terminate = __terminate;
return((encoder_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -