📄 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 Reservedi 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_SYMBOLSint 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 + -