📄 hpdz_dequant.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 <string.h>
#include <math.h>
#include <assert.h>
#include <line_block_ifc.h>
static ifc_int low_seven_3_8_lut[128];
static ifc_int high_seven_3_8_lut[128];
#if (IMPLEMENTATION_PRECISION == 32)
static ifc_int very_high_seven_3_8_lut[256];
static ifc_int ultra_high_seven_3_8_lut[256];
#endif /* IMPLEMENTATION_PRECISION */
/* ========================================================================= */
/* ---------------- Implementation of deadzone dequantizer ----------------- */
/* ========================================================================= */
#define MIN_IFC_INT (((ifc_int) 1)<<(IMPLEMENTATION_PRECISION-1))
#define MAX_IFC_MAG ((ifc_int)(~MIN_IFC_INT))
typedef
struct quant_info {
float scale; /* Scaling factor for floating point data. */
ifc_int left_shift; /* Left 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_dequantizer_obj {
dequantizer_obj base;
int num_components;
int num_levels;
int num_bands; /* Number of bands per resolution level, per component. */
component_info_ptr components;
int three_eighths; /* true if using 3/8 rule for representation levels. */
decoder_ref decoder;
} dz_dequantizer_obj, *dz_dequantizer_ref;
/* ========================================================================= */
/* --------------------------- Functional Macros --------------------------- */
/* ========================================================================= */
#if (IMPLEMENTATION_PRECISION == 16)
# define three_eighths_convert(_val) \
{ \
if (_val) \
{ \
if (_val & 0x007F) \
_val += low_seven_3_8_lut[_val & 0x007F]; \
else \
_val += high_seven_3_8_lut[(_val>>7) & 0x007F]; \
} \
}
#else
# define three_eighths_convert(_val) \
{ \
if (_val) \
{ \
if (_val & 0x0000007F) \
_val += low_seven_3_8_lut[_val & 0x0000007F]; \
else if ((_val>>7) & 0x0000007F) \
_val += high_seven_3_8_lut[(_val>>7) & 0x0000007F]; \
else if ((_val>>14) & 0x000000FF) \
_val += very_high_seven_3_8_lut[(_val>>14) & 0x000000FF]; \
else \
_val += ultra_high_seven_3_8_lut[(_val>>22) & 0x000000FF]; \
} \
}
#endif /* IMPLEMENTATION_PRECISION */
/*****************************************************************************/
/* STATIC initialize_3_8_luts */
/*****************************************************************************/
static void
initialize_3_8_luts(void)
{
ifc_int lsb, c, *lut, offset;
lut = low_seven_3_8_lut;
for (lut[0]=0, c=1; c < 128; c++)
lut[c] = 1; /* Until we set real values. */
for (lsb=0; lsb < 7; lsb++)
{
offset = -(1<<lsb); /* Offset to remove the signalling bit (1/2). */
if (lsb < 2)
offset += 1<<lsb; /* Add 1/2. */
else
offset += 3<<(lsb-2); /* Add 3/8. */
for (c=0; c < (1<<(6-lsb)); c++)
lut[(c+c+1)<<lsb] = offset;
}
for (c=0; c < 128; c++)
assert(lut[c] <= 0);
lut = high_seven_3_8_lut;
for (lut[0]=0, c=1; c < 128; c++)
lut[c] = 1; /* Until we set real values. */
for (lsb=0; lsb < 7; lsb++)
{
offset = -(1<<(lsb+7)); /* Offset to remove the signalling bit (1/2). */
offset += 3<<(lsb+7-2); /* Add 3/8. */
for (c=0; c < (1<<(6-lsb)); c++)
lut[(c+c+1)<<lsb] = offset;
}
for (c=0; c < 128; c++)
assert(lut[c] <= 0);
#if (IMPLEMENTATION_PRECISION == 32)
lut = very_high_seven_3_8_lut;
for (lut[0]=0, c=1; c < 256; c++)
lut[c] = 1; /* Until we set real values. */
for (lsb=0; lsb < 8; lsb++)
{
offset = -(1<<(lsb+14)); /* Offset to remove the signalling bit (1/2). */
offset += 3<<(lsb+14-2); /* Add 3/8. */
for (c=0; c < (1<<(7-lsb)); c++)
lut[(c+c+1)<<lsb] = offset;
}
for (c=0; c < 256; c++)
assert(lut[c] <= 0);
lut = ultra_high_seven_3_8_lut;
for (lut[0]=0, c=1; c < 256; c++)
lut[c] = 1; /* Until we set real values. */
for (lsb=0; lsb < 8; lsb++)
{
offset = -(1<<(lsb+22)); /* Offset to remove the signalling bit (1/2). */
offset += 3<<(lsb+22-2); /* Add 3/8. */
for (c=0; c < (1<<(7-lsb)); c++)
lut[(c+c+1)<<lsb] = offset;
}
for (c=0; c < 256; c++)
assert(lut[c] <= 0);
#endif /* IMPLEMENTATION_PRECISION == 32 */
}
/*****************************************************************************/
/* STATIC __initialize */
/*****************************************************************************/
static void
__initialize(dequantizer_ref base, int decomposition, int levels,
int components, int component_rows[], int component_cols[],
filter_info_ref info, decoder_ref decoder,
int argc, char *argv[])
{
dz_dequantizer_ref self = (dz_dequantizer_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->three_eighths = 0;
for (n=0; n < argc; n++)
if (strcmp(argv[n],"-Q3_8") == 0)
{
argv[n] = "";
self->three_eighths = 1;
}
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->decoder = decoder;
if (self->three_eighths)
initialize_3_8_luts();
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);
if (extra_lsbs > 0)
step_size = step_size / ((float)(1<<extra_lsbs));
else if (extra_lsbs < 0)
step_size = step_size * ((float)(1<<-extra_lsbs));
qi[self->num_bands*n+b].scale = step_size;
qi[self->num_bands*n+b].left_shift =
(ifc_int)(exponent - extra_lsbs);
}
}
}
/*****************************************************************************/
/* STATIC __print_usage */
/*****************************************************************************/
static void
__print_usage(dequantizer_ref base, FILE *dest)
{
fprintf(dest,">> HP Deadzone Dequantizer arguments:\n"
" -Q3_8 -- forces representation levels to 3/8 of a\n"
" step above the threshold, rather than midway\n"
" between one threshold and the next.\n");
}
/*****************************************************************************/
/* STATIC __pull_line_float */
/*****************************************************************************/
static void
__pull_line_float(dequantizer_ref base, float *line_buf,
int component_idx, int level_idx, int band_idx, int width)
{
dz_dequantizer_ref self = (dz_dequantizer_ref) base;
component_info_ptr comp_info;
float scale, *dp;
ifc_int *cast_buf, *sp, 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;
self->decoder->pull_line(self->decoder,cast_buf,
component_idx,level_idx,band_idx,width);
if (self->three_eighths)
for (i=width, dp=line_buf+i-1, sp=cast_buf+i-1; i > 0; i--, sp--, dp--)
{
val = *sp;
three_eighths_convert(val);
val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to two's-complement. */
*dp = ((float) val) * scale;
}
else
for (i=width, dp=line_buf+i-1, sp=cast_buf+i-1; i > 0; i--, sp--, dp--)
{
val = *sp;
val = (val<0)?(MIN_IFC_INT-val):val; /* Convert to two's-complement. */
*dp = ((float) val) * scale;
}
}
/*****************************************************************************/
/* STATIC __pull_line_fixed */
/*****************************************************************************/
static void
__pull_line_fixed(dequantizer_ref base, ifc_int *line_buf,
int component_idx, int level_idx, int band_idx, int width)
{
dz_dequantizer_ref self = (dz_dequantizer_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].left_shift;
self->decoder->pull_line(self->decoder,line_buf,
component_idx,level_idx,band_idx,width);
if (self->three_eighths)
{
if (shift == 0)
for (sp=line_buf, i=width; i > 0; i--, sp++)
{ /* The `shift'=0 case occurs almost always in practice. */
val = *sp;
three_eighths_convert(val);
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;
three_eighths_convert(val);
if (val < 0)
val = - ((val & MAX_IFC_MAG) << shift);
else
val <<= shift;
*sp = val;
}
else
for (shift=-shift, sp=line_buf, i=width; i > 0; i--, sp++)
{
val = *sp;
three_eighths_convert(val);
if (val < 0)
val = - ((val & MAX_IFC_MAG) >> shift);
else
val >>= shift;
*sp = val;
}
}
else
{
if (shift == 0)
for (sp=line_buf, i=width; i > 0; i--, sp++)
{ /* The `shift'=0 case occurs almost always in practice. */
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 = - ((val & MAX_IFC_MAG) << 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 = - ((val & MAX_IFC_MAG) >> shift);
else
val >>= shift;
*sp = val;
}
}
}
/*****************************************************************************/
/* STATIC __pull_block_float */
/*****************************************************************************/
static void
__pull_block_float(dequantizer_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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -