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

📄 ebcot_common.c

📁 JPEG2000 EBCOT算法源码
💻 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 + -