📄 tcq_quant.c
字号:
forward_info_ref info, encoder_ref encoder,
stream_out_ref stream, cmdl_ref cmdl)
{
tcq_quantizer_ref self = (tcq_quantizer_ref) base;
int choice = 2;
stream->declare_marker_elt(stream,-1,MARKER_QCD_WHICH,0,2,1);
stream->set_marker_val(stream,-1,MARKER_QCD_WHICH,0,choice,0);
self->num_components = num_components;
self->encoder = encoder;
self->stream = stream;
self->info = info;
self->components = (tcq_component_info_ptr)
local_malloc(TCQ_MEM_KEY,sizeof(tcq_component_info)*num_components);
/* SAIC General Decomp. Begin */
{
canvas_dims tile_dims;
int max_hp_descent;
int num_levels;
int b, n, p, ptiles;
char **params;
if ((p = cmdl->extract(cmdl,"-Xwt_output",-1,¶ms)) >= 0) {
if ((ptiles = cmdl->extract(cmdl,"-Ftiles",-1,¶ms)) >= 0) {
local_printf(0, 80, "The `-Xwt_output' option should not be used with "
"`-Ftiles'. Therefore, `-Xwt_output' is ignored");
}
else {
if (p != 1)
local_error("The `-Xwt_output' argument requires on parameter!");
self->wt_output_file = params[0];
/* Begin Aerospace MCT mods */
self->info->get_fixed_tile_info(self->info, 0, 0, NULL, NULL, &tile_dims,
NULL, NULL, NULL, NULL,NULL,NULL,NULL);
/* End Aerospace MCT mods */
self->wt_output = (float **)
local_malloc(TCQ_MEM_KEY, tile_dims.rows*sizeof(float *));
self->wt_output -= tile_dims.top_row;
self->wt_output[tile_dims.top_row] = (float *)
local_malloc(TCQ_MEM_KEY, tile_dims.rows * tile_dims.cols *
sizeof(float));
self->wt_output[tile_dims.top_row] -= tile_dims.left_col;
for (n=(tile_dims.top_row+1); n<(tile_dims.top_row+tile_dims.rows); n++) {
self->wt_output[n] = self->wt_output[n-1] + tile_dims.cols;
}
num_levels = info->get_var_tile_info(info,0,NULL,NULL,NULL,NULL,NULL);
self->min_band = (int *)
local_malloc(TCQ_MEM_KEY, (num_levels+1)*sizeof(int));
self->max_band = (int *)
local_malloc(TCQ_MEM_KEY, (num_levels+1)*sizeof(int));
self->band_dims = (canvas_dims **)
local_malloc(TCQ_MEM_KEY, (num_levels+1)*sizeof(canvas_dims *));
self->current_band_line = (int **)
local_malloc(TCQ_MEM_KEY, (num_levels+1)*sizeof(int *));
self->valid_band = (int **)
local_malloc(TCQ_MEM_KEY, (num_levels+1)*sizeof(int *));
for (n=0; n<(num_levels+1); n++) {
if (n == 0)
self->min_band[n] = self->max_band[n] = LL_BAND;
else {
info->get_level_info(self->info,0,n,NULL, &max_hp_descent,NULL,NULL);
self->min_band[n] = 1 << (max_hp_descent+max_hp_descent-2);
self->max_band[n] = (1<<(max_hp_descent+max_hp_descent)) - 1;
}
self->band_dims[n] = (canvas_dims *)
local_malloc(TCQ_MEM_KEY, sizeof(canvas_dims)*(self->max_band[n]+1));
self->current_band_line[n] = (int *)
local_malloc(TCQ_MEM_KEY, sizeof(int)*(self->max_band[n]+1));
self->valid_band[n] = (int *)
local_malloc(TCQ_MEM_KEY, sizeof(int)*(self->max_band[n]+1));
for (b=self->min_band[n]; b<=self->max_band[n];
b++) {
self->info->get_band_info(info,0,n,b,NULL,NULL,NULL,NULL,NULL,NULL,&(self->valid_band[n][b]));
if (!self->valid_band[n][b])
continue;
self->info->get_band_location_info(info,0,n,b,&(self->band_dims[n][b]));
}
}
}
}
}
/* SAIC General Decomp. End */
start_tile(self);
}
/*****************************************************************************/
/* STATIC __get_usage */
/*****************************************************************************/
static char **
__get_usage(quantizer_ref base)
{
static char *args[] =
{ "-Qtcq",
"Use trellis coded quantization on entropy coder blocks.",
NULL };
return(args);
}
/*****************************************************************************/
/* STATIC __next_tile */
/*****************************************************************************/
static void
__next_tile(quantizer_ref base)
{
tcq_quantizer_ref self = (tcq_quantizer_ref) base;
self->encoder->next_tile(self->encoder); /* Must force encoder to become
current with new tile first since we need to access its block dims. */
self->tnum++;
start_tile(self);
}
/*****************************************************************************/
/* STATIC __push_line_float */
/*****************************************************************************/
static void
__push_line_float(quantizer_ref base, float *line_buf,
int component_idx, int level_idx, int band_idx, int width)
{
tcq_quantizer_ref self = (tcq_quantizer_ref) base;
tcq_component_info_ptr comp;
tcq_level_info_ptr lev;
tcq_band_info_ptr band;
float scale, **block_buffer;
int extra_lsbs, num_lines, n;
int block_width, block_height, block_offset;
assert(component_idx < self->num_components);
comp = self->components + component_idx;
lev = comp->levels + level_idx;
assert((band_idx >= lev->min_band) && (band_idx <= lev->max_band));
assert(level_idx <= comp->num_levels);
band = lev->bands + band_idx;
num_lines = band->num_lines;
block_height = band->current_block_height;
assert(num_lines < block_height);
if (band->line_buffer == NULL)
{
assert(band->num_lines == 0);
band->line_buffer = AllocateBlockBuffer(width,band->block_height);
}
block_buffer = band->line_buffer;
memcpy(block_buffer[num_lines],line_buf,sizeof(float)*width);
num_lines++;
/* SAIC General Decomp. Begin */
if (self->wt_output_file != NULL) {
int line_num;
int j;
line_num = self->band_dims[level_idx][band_idx].top_row+
self->current_band_line[level_idx][band_idx];
assert(self->band_dims[level_idx][band_idx].cols == width);
assert(self->current_band_line[level_idx][band_idx] <
self->band_dims[level_idx][band_idx].rows);
for (j=self->band_dims[level_idx][band_idx].left_col;
j<self->band_dims[level_idx][band_idx].left_col +
self->band_dims[level_idx][band_idx].cols; j++) {
self->wt_output[line_num][j] =
line_buf[j-self->band_dims[level_idx][band_idx].left_col];
}
self->current_band_line[level_idx][band_idx]++;
}
/* SAIC General Decomp. End */
if (num_lines < block_height)
{
band->num_lines = num_lines;
return;
}
scale = band->scale;
extra_lsbs = band->extra_lsbs;
block_width = band->first_block_width;
block_offset = 0;
while (block_width > 0)
{
TCQBlock(block_buffer,block_width,block_height,
block_offset,scale,extra_lsbs,self);
block_offset += block_width;
block_width = width - block_offset;
if (block_width > band->block_width)
block_width = band->block_width;
}
for (n=0; n < block_height; n++)
{
ifc_int *cast_buf;
cast_buf = (ifc_int *)(block_buffer[n]);
#if (IMPLEMENTATION_PRECISION != 32)
{
int m;
std_int *sp, val;
ifc_int *dp;
for (sp=(std_int *) cast_buf, dp=cast_buf, m=width; m > 0; m--)
{
val = *(sp++);
if (val < 0)
*(dp++) = MIN_IFC_INT + (ifc_int)(val & MAX_IFC_INT);
else
*(dp++) = (ifc_int)(val & MAX_IFC_INT);
}
}
#endif /* IMPLEMENTATION_PRECISION */
self->encoder->push_line(self->encoder,cast_buf,
component_idx,level_idx,band_idx,width);
}
band->num_lines = 0;
band->remaining_tile_height -= band->current_block_height;
band->current_block_height = band->block_height;
if (band->current_block_height > band->remaining_tile_height)
band->current_block_height = band->remaining_tile_height;
}
/*****************************************************************************/
/* STATIC __push_line_fixed */
/*****************************************************************************/
static void
__push_line_fixed(quantizer_ref base, ifc_int *line_buf,
int component_idx, int level_idx, int band_idx, int width)
{
/* SAIC General Decomp. Begin */
tcq_quantizer_ref self = (tcq_quantizer_ref) base;
/* SAIC General Decomp. End */
register int i;
float *tmpbuf;
tmpbuf = (float *)local_malloc(TCQ_MEM_KEY,sizeof(float)*width);
/* SAIC General Decomp. Begin */
if (self->wt_output_file != NULL) {
int line_num;
int j;
line_num = self->band_dims[level_idx][band_idx].top_row+
self->current_band_line[level_idx][band_idx];
assert(self->band_dims[level_idx][band_idx].cols == width);
assert(self->current_band_line[level_idx][band_idx] <
self->band_dims[level_idx][band_idx].rows);
for (j=self->band_dims[level_idx][band_idx].left_col;
j<self->band_dims[level_idx][band_idx].left_col +
self->band_dims[level_idx][band_idx].cols; j++) {
self->wt_output[line_num][j] = (float)
line_buf[j-self->band_dims[level_idx][band_idx].left_col];
}
self->current_band_line[level_idx][band_idx]++;
}
/* SAIC General Decomp. End */
for (i = 0;i < width; i++)
tmpbuf[i] = (float)line_buf[i];
__push_line_float(base,tmpbuf,component_idx,level_idx,band_idx,width);
local_free(tmpbuf);
}
/*****************************************************************************/
/* STATIC __terminate */
/*****************************************************************************/
static void
__terminate(quantizer_ref base)
{
tcq_quantizer_ref self = (tcq_quantizer_ref) base;
int c;
/* SAIC General Decomp. Begin */
if (self->wt_output_file != NULL) {
canvas_dims tile_dims;
tcq_component_info_ptr comp;
tcq_level_info_ptr lev;
float max, min;
int num_levels;
int i, j, n, b;
unsigned char **usc_wt_output;
FILE *fp;
comp = self->components;
num_levels = comp->num_levels;
/* Begin Aerospace MCT mods */
self->info->get_fixed_tile_info(self->info, 0, 0, NULL, NULL, &tile_dims,
NULL, NULL, NULL, NULL,NULL,NULL,NULL);
/* End Aerospace MCT mods */
usc_wt_output = (unsigned char **)
local_malloc(TCQ_MEM_KEY, tile_dims.rows * sizeof(unsigned char *));
usc_wt_output[0] = (unsigned char *)
local_malloc(TCQ_MEM_KEY, tile_dims.rows * tile_dims.cols *
sizeof(unsigned char));
for (i=1; i<tile_dims.rows; i++) {
usc_wt_output[i] = usc_wt_output[i-1] + tile_dims.cols;
}
for (n=0; n<=num_levels; n++) {
lev = comp->levels + n;
for (b=lev->min_band; b<=lev->max_band; b++) {
if (!self->valid_band[n][b])
continue;
max = min =
self->wt_output[self->band_dims[n][b].top_row]
[self->band_dims[n][b].left_col];
for (i=self->band_dims[n][b].top_row;
i<self->band_dims[n][b].top_row +
self->band_dims[n][b].rows; i++) {
for (j=self->band_dims[n][b].left_col;
j<self->band_dims[n][b].left_col +
self->band_dims[n][b].cols; j++) {
if (self->wt_output[i][j] > max)
max = self->wt_output[i][j];
if (self->wt_output[i][j] < min)
min = self->wt_output[i][j];
}
}
for (i=self->band_dims[n][b].top_row;
i<self->band_dims[n][b].top_row +
self->band_dims[n][b].rows; i++) {
for (j=self->band_dims[n][b].left_col;
j<self->band_dims[n][b].left_col +
self->band_dims[n][b].cols; j++) {
if (n == 0) {
self->wt_output[i][j] =
255*(self->wt_output[i][j] - min)/(max - min);
}
else {
self->wt_output[i][j] = (float)
(1024*fabs(self->wt_output[i][j])/MAX(fabs(min), fabs(max)));
if (self->wt_output[i][j] > 255)
self->wt_output[i][j] = 255;
}
usc_wt_output[i-tile_dims.top_row][j-tile_dims.left_col] =
(unsigned char) self->wt_output[i][j];
}
}
}
local_free(self->valid_band[n]);
local_free(self->current_band_line[n]);
local_free(self->band_dims[n]);
}
local_free(self->valid_band);
local_free(self->current_band_line);
local_free(self->band_dims);
local_free(self->min_band);
local_free(self->max_band);
fp = fopen(self->wt_output_file, "wb");
fprintf(fp, "P5\n%d %d\n255\n", tile_dims.cols, tile_dims.rows);
fwrite(usc_wt_output[0], sizeof(unsigned char), tile_dims.rows * tile_dims.cols, fp);
fclose(fp);
self->wt_output[tile_dims.top_row] += tile_dims.left_col;
local_free(self->wt_output[tile_dims.top_row]);
self->wt_output += tile_dims.top_row;
local_free(self->wt_output);
local_free(usc_wt_output[0]);
local_free(usc_wt_output);
}
/* SAIC General Decomp. End */
if (self->components != NULL)
{
for (c=0; c < self->num_components; c++)
destroy_component_structures(self->components + c);
local_free(self->components);
}
TCQBlock(NULL,0,0,0,0.0F,0,NULL); /* Force deallocation of static resources;
ideally, these should be removed to make the
code re-entrant. */
local_free(self);
}
/*****************************************************************************/
/* EXTERN create_tcq_quantizer */
/*****************************************************************************/
quantizer_ref
create_tcq_quantizer(void)
{
tcq_quantizer_ref result;
result = (tcq_quantizer_ref)
local_malloc(TCQ_MEM_KEY,sizeof(tcq_quantizer_obj));
result->base.initialize = __initialize;
result->base.get_usage = __get_usage;
result->base.push_line_float = __push_line_float;
result->base.push_line_fixed = __push_line_fixed;
result->base.next_tile = __next_tile;
result->base.terminate = __terminate;
return((quantizer_ref) result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -