📄 ebcot_common.c
字号:
/*****************************************************************************/
/* File name: "ebcot_common.c" */
/* Author: David Taubman */
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/*****************************************************************************/
#include <local_heap.h>
#include <math.h>
#include <assert.h>
#include <string.h>
#include <line_block_ifc.h>
#include <ebcot_constants.h>
#include <ebcot_common.h>
std_byte ebcot_main_zc_lut[ZC_MASK+1];
std_byte ebcot_diag_zc_lut[ZC_MASK+1];
ifc_int ebcot_sc_lut[16];
std_short ebcot_p0_lut[1<<CONTEXT_STATE_BITS];
std_short ebcot_initial_mse_lut[(1<<MSE_LUT_BITS)];
std_short ebcot_refinement_mse_lut[(1<<MSE_LUT_BITS)];
#ifdef COUNT_SYMBOLS
int ebcot_total_symbol_count = 0;
#endif
/* ========================================================================= */
/* --------------------------- Internal Functions -------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC initialize_zc_luts */
/*****************************************************************************/
static void
initialize_zc_luts(void)
{
std_short idx, ctxt, v1, v2, v3, v4;
for (idx=0; idx <= ZC_MASK; idx++)
{
/* First, form the context map for the horizontal and vertical bands.
These both use the same context map, because the horizontally
high-pass band is physically transposed before encoding. */
v1 = ((idx>>CL_POS)&1) + ((idx>>CR_POS)&1);
v2 = ((idx>>TC_POS)&1) + ((idx>>BC_POS)&1);
v3 = ((idx>>TL_POS)&1) + ((idx>>TR_POS)&1) +
((idx>>BL_POS)&1) + ((idx>>BR_POS)&1);
v4 = (idx>>FAR_POS) & 1;
if (v1 == 2)
ctxt = 9;
else if (v1 == 1)
{
if (v2)
ctxt = 8;
else if (v3)
ctxt = 7;
else
ctxt = 6;
}
else
{
if (v2)
ctxt = 3+v2;
else if (v3)
ctxt = 1 + ((v3>2)?2:v3);
else
ctxt = v4;
}
assert(ctxt < ZC_CONTEXTS);
ebcot_main_zc_lut[idx] = (std_byte) ctxt;
/* Finally, form the contexts for the diagonal band. */
v1 = ((idx>>TL_POS)&1) + ((idx>>TR_POS)&1) +
((idx>>BL_POS)&1) + ((idx>>BR_POS)&1);
v2 = ((idx>>CL_POS)&1) + ((idx>>CR_POS)&1) +
((idx>>TC_POS)&1) + ((idx>>BC_POS)&1);
v4 = (idx>>FAR_POS) & 1;
if (v1 >= 3)
ctxt = 9;
else if (v1 == 2)
{
if (v2 >= 1)
ctxt = 8;
else
ctxt = 7;
}
else if (v1 == 1)
ctxt = 4 + ((v2>2)?2:v2);
else if (v2)
ctxt = 1 + ((v2>2)?2:v2);
else
ctxt = v4;
assert(ctxt < ZC_CONTEXTS);
ebcot_diag_zc_lut[idx] = (std_byte) ctxt;
}
}
/*****************************************************************************/
/* STATIC initialize_sc_lut */
/*****************************************************************************/
static void
initialize_sc_lut(void)
{
ifc_int idx, vpos, vneg, hpos, hneg, ctxt, predict, v1, v2;
for (idx=0; idx < 16; idx++)
{
vpos = (idx >> (V_PVE_POS-SIGN_POS)) & 1;
vneg = (idx >> (V_NVE_POS-SIGN_POS)) & 1;
hpos = (idx >> (H_PVE_POS-SIGN_POS)) & 1;
hneg = (idx >> (H_NVE_POS-SIGN_POS)) & 1;
v1 = hpos-hneg;
v2 = vpos-vneg;
predict = 0;
if (v1 < 0)
{
predict = MIN_IFC_INT;
v1 = -v1;
v2 = -v2;
}
if (v1 == 0)
{
if (v2 < 0)
{
predict = MIN_IFC_INT;
v2 = -v2;
}
ctxt = v2;
}
else
ctxt = 3 + v2;
assert((ctxt >= 0) && (ctxt < SC_CONTEXTS));
ebcot_sc_lut[idx] = ctxt | predict;
}
}
/*****************************************************************************/
/* STATIC initialize_p0_lut */
/*****************************************************************************/
static void
initialize_p0_lut(void)
{
std_short idx;
std_int s, n, p1;
for (idx=0; (idx>>CONTEXT_STATE_BITS) == 0; idx++)
{
s = idx & S_MASK;
n = idx >> S_BITS;
assert(n < (1<<N_BITS));
if (s == 0)
p1 = 0; /* Flags illegal probability. */
else
{
p1 = ((1<<P_BITS)-1) / s;
if (n == 0)
p1 >>= 1;
else
p1 *= n;
}
if ((p1 <= 0) || (p1 >= (1<<P_BITS)))
p1 = 0; /* Flags illegal probability. */
ebcot_p0_lut[idx] = (std_short)((1<<P_BITS)-p1);
}
}
/*****************************************************************************/
/* STATIC initialize_mse_luts */
/*****************************************************************************/
static void
initialize_mse_luts(void)
/* Fills out the `ebcot_initial_mse_lut' and `ebcot_refinement_mse_lut' arrays
to assist in computing the change in MSE which may be attributed to new
information which is encoded in any block coding pass. Both LUT's take
MSE_LUT_BITS indices, where the most significant bit of the index
corresponds to the bit-plane for which information is being coded. In
the case of the `ebcot_initial_mse_lut', the most significant bit of the
index must always be 1, because the sample has just been found to be
significant in the current bit-plane; thus, half the table is actually
redundant, but this regular organization improves the readability of the
implementation of the block coding algorithm.
MSE changes are normalized so that a value of 2^13 correspnds to D^2,
where D is the step size associated with the relevant bit-plane (i.e.
a change in the most significant bit of the index supplied to the LUT). */
{
ifc_int idx;
double val, mse_tmp, delta_mse;
for (idx=0; idx < (1<<MSE_LUT_BITS); idx++)
{
val = ((double) idx) / ((double)(1<<(MSE_LUT_BITS-1)));
/* First fill out the `ebcot_initial_mse_lut' entry. */
mse_tmp = val;
delta_mse = mse_tmp*mse_tmp;
mse_tmp = val - 1.5;
delta_mse -= mse_tmp*mse_tmp;
ebcot_initial_mse_lut[idx] = (std_short)
floor(0.5 + delta_mse*((double)(1<<13)));
/* Now fill out the `ebcot_refinement_mse_lut' entry. */
mse_tmp = val - 1.0;
delta_mse = mse_tmp*mse_tmp;
mse_tmp = (val>=1.0)?(val-1.5):(val-0.5);
delta_mse -= mse_tmp*mse_tmp;
ebcot_refinement_mse_lut[idx] = (std_short)
floor(0.5 + delta_mse*((double)(1<<13)));
}
}
/* ========================================================================= */
/* ----------------- Implementation of `sample_buffer_heap' ---------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC sample_buffer_heap__get_buffer */
/*****************************************************************************/
static ifc_int *
sample_buffer_heap__get_buffer(sample_buffer_heap_ref self)
{
ifc_int *buf;
if (self->free_buffers == 0)
{
if (self->num_buffers == self->max_buffers)
{
int n;
self->max_buffers += 1 + self->max_buffers;
self->buffers = (ifc_int **)
local_realloc(self->buffers,
sizeof(ifc_int *)*(size_t)(self->max_buffers));
for (n=self->num_buffers; n < self->max_buffers; n++)
self->buffers[n] = NULL;
}
self->buffers[self->free_buffers] = (ifc_int *)
local_malloc(sizeof(ifc_int)*(size_t)(self->row_gap*self->max_rows));
self->num_buffers++;
self->free_buffers++;
}
self->free_buffers--;
buf = self->buffers[self->free_buffers];
self->buffers[self->free_buffers] = NULL;
return(buf);
}
/*****************************************************************************/
/* STATIC sample_buffer_heap__return_buffer */
/*****************************************************************************/
static void
sample_buffer_heap__return_buffer(sample_buffer_heap_ref self,
ifc_int *buf)
{
assert(self->free_buffers < self->num_buffers);
self->buffers[self->free_buffers++] = buf;
}
/*****************************************************************************/
/* STATIC sample_buffer_heap__terminate */
/*****************************************************************************/
static void
sample_buffer_heap__terminate(sample_buffer_heap_ref self)
{
int n;
assert(self->num_buffers == self->free_buffers);
for (n=0; n < self->free_buffers; n++)
local_free(self->buffers[n]);
local_free(self->buffers);
local_free(self);
}
/* ========================================================================= */
/* --------------------------- External Functions -------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* EXTERN ebcot_initialize_global_luts */
/*****************************************************************************/
void
ebcot_initialize_global_luts(void)
{
initialize_zc_luts();
initialize_sc_lut();
initialize_p0_lut();
initialize_mse_luts();
}
/*****************************************************************************/
/* EXTERN ebcot_create_sample_buffer_heap */
/*****************************************************************************/
sample_buffer_heap_ref
ebcot_create_sample_buffer_heap(int max_rows, int row_gap)
{
sample_buffer_heap_ref result;
int n;
result = (sample_buffer_heap_ref)
local_malloc(sizeof(sample_buffer_heap_obj));
memset(result,0,sizeof(sample_buffer_heap_obj));
result->get_buffer = sample_buffer_heap__get_buffer;
result->return_buffer = sample_buffer_heap__return_buffer;
result->terminate = sample_buffer_heap__terminate;
result->max_rows = max_rows;
result->row_gap = row_gap;
result->max_buffers = 16;
result->buffers = (ifc_int **)
local_malloc(sizeof(ifc_int *) * (size_t)(result->max_buffers));
for (n=0; n < result->max_buffers; n++)
result->buffers[n] = NULL;
return(result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -