📄 ebcot_common.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* File: "ebcot_common.c" */
/* Description: Common functions for the EBCOT encoder and decoder */
/* Author: David Taubman */
/* Affiliation: Hewlett-Packard and */
/* The University of New South Wales, Australia */
/* Version: VM5.0 */
/* Last Revised: 1 August, 1999 */
/*****************************************************************************/
/*****************************************************************************/
/* Modified to combine entropy coders */
/* Copyright 1999 Science Applications International Corporation (SAIC). */
/* Copyright 1999 University of Arizona, Arizona Board of Regents. */
/* All Rights Reserved for modified parts. */
/*****************************************************************************/
#include <local_services.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <ifc.h>
#include "ebcot_constants.h"
#include "ebcot_common.h"
std_byte ebcot_horz_zc_lut[ZC_MASK+1];
std_byte ebcot_vert_zc_lut[ZC_MASK+1];
std_byte ebcot_diag_zc_lut[ZC_MASK+1];
ifc_int ebcot_sc_lut[16];
std_short ebcot_initial_mse_lut[(1<<MSE_LUT_BITS)];
std_short ebcot_refinement_mse_lut[(1<<MSE_LUT_BITS)];
std_short ebcot_lossless_initial_mse_lut[(1<<MSE_LUT_BITS)];
std_short ebcot_lossless_refinement_mse_lut[(1<<MSE_LUT_BITS)];
dst_context_state initial_mq_contexts[EBCOT_TOTAL_CONTEXTS];
#ifdef EBCOT_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;
for (idx=0; idx <= ZC_MASK; idx++)
{
/* First, form the context map for the vertically high-pass band. */
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);
if (v1 == 2)
ctxt = 8;
else if (v1 == 1)
{
if (v2)
ctxt = 7;
else if (v3)
ctxt = 6;
else
ctxt = 5;
}
else
{
if (v2)
ctxt = 2+v2;
else
ctxt = 0 + ((v3>2)?2:v3);
}
assert(ctxt < ZC_CONTEXTS);
ebcot_vert_zc_lut[idx] = (std_byte) ctxt;
/* Now form the context map for the horizontally high-pass band. */
v1 = ((idx>>TC_POS)&1) + ((idx>>BC_POS)&1);
v2 = ((idx>>CL_POS)&1) + ((idx>>CR_POS)&1);
v3 = ((idx>>TL_POS)&1) + ((idx>>TR_POS)&1) +
((idx>>BL_POS)&1) + ((idx>>BR_POS)&1);
if (v1 == 2)
ctxt = 8;
else if (v1 == 1)
{
if (v2)
ctxt = 7;
else if (v3)
ctxt = 6;
else
ctxt = 5;
}
else
{
if (v2)
ctxt = 2+v2;
else
ctxt = 0 + ((v3>2)?2:v3);
}
assert(ctxt < ZC_CONTEXTS);
ebcot_horz_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);
if (v1 >= 3)
ctxt = 8;
else if (v1 == 2)
{
if (v2 >= 1)
ctxt = 7;
else
ctxt = 6;
}
else if (v1 == 1)
ctxt = 3 + ((v2>2)?2:v2);
else
ctxt = 0 + ((v2>2)?2:v2);
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_mse_luts */
/*****************************************************************************/
static void
initialize_mse_luts(void)
/* Fills out the `ebcot_initial_mse_lut' and `ebcot_refinement_mse_lut' arrays
and the lossless versions of these 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 the 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).
The lossless variants of the LUT's are to be used only when coding
the least significant bit of a lossless representation of the subband
samples, i.e. in reversible systems. These LUT's are a little
different because the representation levels must be the quantizer
thresholds themselves here, rather than the mid-points between the
thresholds. */
{
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;
ebcot_lossless_initial_mse_lut[idx] = (std_short)
floor(0.5 + delta_mse*((double)(1<<13)));
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;
ebcot_lossless_refinement_mse_lut[idx] = (std_short)
floor(0.5 + delta_mse*((double)(1<<13)));
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(EBCOT_MEM_KEY,
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);
}
/*****************************************************************************/
/* STATIC initialize_initial_mq_contexts */
/*****************************************************************************/
static void
initialize_initial_mq_contexts(void)
{
int n;
for (n=0; n < EBCOT_TOTAL_CONTEXTS; n++)
initial_mq_contexts[n] = INIT_MQSTATE;
initial_mq_contexts[UNI_OFFSET] = UNI_INIT_MQSTATE;
initial_mq_contexts[AGG_OFFSET] = RUN_INIT_MQSTATE;
initial_mq_contexts[ZC_OFFSET] = ZERO_INIT_MQSTATE;
}
/* ========================================================================= */
/* --------------------------- External Functions -------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* EXTERN ebcot_initialize_global_luts */
/*****************************************************************************/
void
ebcot_initialize_global_luts(void)
{
initialize_zc_luts();
initialize_sc_lut();
initialize_mse_luts();
initialize_initial_mq_contexts();
}
/*****************************************************************************/
/* 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(EBCOT_MEM_KEY,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(EBCOT_MEM_KEY,
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 + -