📄 hpdz_quant.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* Author: David Taubman */
/* Version: V2.0 */
/* Last Revised: 9/22/98 */
/*****************************************************************************/
#include <local_heap.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <line_block_ifc.h>
/* ========================================================================= */
/* ----------------- Implementation of deadzone quantizer ------------------ */
/* ========================================================================= */
#define MIN_IFC_INT (((ifc_int) 1)<<(IMPLEMENTATION_PRECISION-1))
typedef
struct quant_info {
float scale; /* Scaling factor for floating point data. */
ifc_int right_shift; /* Right shift for fixed-point data. May be -ve. */
} quant_info, *quant_info_ptr;
typedef
struct component_info {
int num_levels;
int num_bands; /* Number of bands per resolution level, per component. */
quant_info_ptr info;
float **tree_scales;
ifc_int **tree_shifts;
} component_info, *component_info_ptr;
typedef
struct dz_quantizer_obj {
quantizer_obj base;
int num_components;
int num_levels;
int num_bands; /* Number of bands per resolution level, per component. */
component_info_ptr components;
encoder_ref encoder;
} dz_quantizer_obj, *dz_quantizer_ref;
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(quantizer_ref base, int decomposition, int levels,
int components, int component_rows[], int component_cols[],
filter_info_ref info, encoder_ref encoder,
int argc, char *argv[])
{
dz_quantizer_ref self = (dz_quantizer_ref) base;
component_info_ptr comp_info;
quant_info_ptr qi;
int comp, n, b, b1, b2;
float step_size;
int exponent, extra_lsbs;
self->num_components = components;
self->num_levels = levels;
if (decomposition == DECOMPOSITION__MALLAT)
self->num_bands = 4;
else
{
assert(decomposition == DECOMPOSITION__SPACL);
self->num_bands = 16;
}
self->encoder = encoder;
self->components = (component_info_ptr)
local_malloc(sizeof(component_info)*(size_t) components);
memset(self->components,0,sizeof(component_info)*(size_t) components);
for (comp=0; comp < components; comp++)
{
comp_info = self->components + comp;
comp_info->num_levels = self->num_levels;
comp_info->num_bands = self->num_bands;
comp_info->info = qi = (quant_info_ptr)
local_malloc(sizeof(quant_info)*(size_t)(self->num_bands*levels+1));
for (n=0; n <= levels; n++)
for (b=0; b < comp_info->num_bands; b++)
{
b1 = (b&3);
b2 = (b>>2);
if (((n > 0) && (n < levels) && (b1==0)) ||
((n == levels) && (b > 0)))
continue;
info->get_quant_info(info,comp,n,b,&step_size,&exponent,
NULL,&extra_lsbs);
qi[self->num_bands*n+b].scale =
((float)(1<<extra_lsbs)) / step_size;
qi[self->num_bands*n+b].right_shift =
(ifc_int)(exponent - extra_lsbs);
}
}
}
/*****************************************************************************/
/* STATIC __print_usage */
/*****************************************************************************/
static void
__print_usage(quantizer_ref base, FILE *dest)
{
return; /* No special command-line options for this object. */
}
/*****************************************************************************/
/* 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)
{
dz_quantizer_ref self = (dz_quantizer_ref) base;
component_info_ptr comp_info;
float scale, *sp;
ifc_int *cast_buf, *dp, val;
int i;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(band_idx < comp_info->num_bands));
scale = comp_info->info[comp_info->num_bands*level_idx+band_idx].scale;
cast_buf = (ifc_int *) line_buf;
for (sp=line_buf, dp=cast_buf, i=width; i > 0; i--, sp++, dp++)
{
val = (ifc_int)(*sp * scale);
val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to sign-mag. */
*dp = val;
}
self->encoder->push_line(self->encoder,cast_buf,
component_idx,level_idx,band_idx,width);
}
/*****************************************************************************/
/* 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)
{
dz_quantizer_ref self = (dz_quantizer_ref) base;
component_info_ptr comp_info;
ifc_int *sp, shift, val;
int i;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(band_idx < comp_info->num_bands));
shift = comp_info->info[comp_info->num_bands*level_idx+band_idx].right_shift;
if (shift == 0)
for (sp=line_buf, i=width; i > 0; i--, sp++)
{ /* It can be shown that the `shift'=0 case occurs almost always. */
val = *sp;
val = (val<0)?(MIN_IFC_INT-val):val;
*sp = val;
}
else if (shift > 0)
for (sp=line_buf, i=width; i > 0; i--, sp++)
{
val = *sp;
if (val < 0)
val = MIN_IFC_INT + ((-val) >> shift);
else
val >>= shift;
*sp = val;
}
else
for (shift=-shift, sp=line_buf, i=width; i > 0; i--, sp++)
{
val = *sp;
if (val < 0)
val = MIN_IFC_INT + ((-val) << shift);
else
val <<= shift;
*sp = val;
}
self->encoder->push_line(self->encoder,line_buf,
component_idx,level_idx,band_idx,width);
}
/*****************************************************************************/
/* STATIC __push_block_float */
/*****************************************************************************/
static void
__push_block_float(quantizer_ref base, float **block_buf,
int component_idx, int level_idx, int band_idx,
int block_rows, int block_cols,
int top_row, int left_col)
{
dz_quantizer_ref self = (dz_quantizer_ref) base;
component_info_ptr comp_info;
float scale, *sp, **spp;
ifc_int **cast_buf, *dp, **dpp, val;
int i, j;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
(band_idx < comp_info->num_bands));
scale = comp_info->info[comp_info->num_bands*level_idx+band_idx].scale;
cast_buf = (ifc_int **) block_buf;
for (spp=block_buf, dpp=cast_buf, j=block_rows; j > 0; j--, spp++, dpp++)
for (sp=*spp, dp=*dpp, i=block_cols; i > 0; i--, sp++, dp++)
{
val = (ifc_int)(*sp * scale);
val = (val<0)?(MIN_IFC_INT-val):val;
*dp = val;
}
self->encoder->push_block(self->encoder,cast_buf,component_idx,level_idx,
band_idx,block_rows,block_cols,top_row,left_col);
}
/*****************************************************************************/
/* STATIC __push_block_fixed */
/*****************************************************************************/
static void
__push_block_fixed(quantizer_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)
{
dz_quantizer_ref self = (dz_quantizer_ref) base;
component_info_ptr comp_info;
ifc_int *sp, **spp, shift, val;
int i, j;
comp_info = self->components + component_idx;
assert((component_idx < self->num_components) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -