⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ebcot_common.c

📁 JPEG2000实现的源码
💻 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 + -