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

📄 ebcot_lite_decode_passes.c

📁 JPEG2000 EBCOT算法源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/
/* File name: "ebcot_lite_decode_passes.c"                                   */
/* Author: David Taubman                                                     */
/* Copyright 1998, Hewlett-Packard Company                                   */
/* All rights reserved                                                       */
/*****************************************************************************/
#include <local_heap.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <line_block_ifc.h>
#include <ebcot_common.h>
#include "ebcot_decoder.h"
#include "ebcot_arith_decoder.h"

/* ========================================================================= */
/* --------------------------- Internal Functions -------------------------- */
/* ========================================================================= */

/*****************************************************************************/
/* STATIC                       first_pass_func                              */
/*****************************************************************************/

static void
  first_pass_func(block_master_ptr master)

 /* This function must be applied once, at the start of each quantization
    layer (bit plane).  It looks for all samples whose context word has the
    IS_REFINED flag turned off.  These samples are brought up to date with
    the current bit plane, while all other samples simply have their
    IS_REFINED flag turned off in preparation for future passes.  Note that
    bringing samples up to date with the current bit plane never involves
    magnitude refinement. */

{
  register std_int *d_cp;
  register std_short *cp;
  register ifc_int *dp;
  register int c;
  register std_short ctxt;
  register ifc_int shift;
  register arith_state_ptr state;
  register std_int A, C, word;
  register context_state_ptr csp;
  register ifc_int val, symbol;
  std_short avail;
  ifc_int lsb;
  std_byte *zc_lut;
  int rows, cols, row_gap, half_inter_row, r;
  std_short *context;
  ifc_int *data;
  context_state_ptr csp_base;
  code_subblock_ptr subblock, last_subblock;

  assert(master->bit_idx > 0);
  shift = master->bit_idx;
  lsb = 1 << shift;
  data = master->sample_buffer;
  context = master->context_buffer;
  row_gap = master->row_gap;
  assert(!(row_gap & 1));
  state = &(master->coder_state);
  A=state->A; C=state->C; word=state->word; avail=state->available_bits;
  csp_base = state->contexts;
  zc_lut = master->zc_lut;
  last_subblock = master->last_subblock;
  for (subblock=master->first_subblock; subblock <= last_subblock; subblock++)
    if (subblock->significant)
      {
        rows = subblock->rows;
        cols = subblock->cols;
        half_inter_row = (row_gap-cols)>>1;
        dp = data + subblock->offset;
        cp = context + subblock->offset;
        d_cp = (std_int *) cp;
        for (r=rows; r > 0; r--, dp+=half_inter_row<<1, cp+=half_inter_row<<1,
             d_cp+=half_inter_row)
          for (c=cols; c > 0; c-=2, dp+=2, cp+=2, d_cp++)
            {
              if ((d_cp[0] == 0) && (d_cp[1] == 0) && (c > 2))
                { /* Special processing to reduce average symbol count. */
                  csp = csp_base + AGG_OFFSET;
                  get_symbol(state,A,C,word,avail,symbol,csp);
                  if (!symbol)
                    { c -= 2; dp += 2; cp += 2; d_cp++; continue; }
                  else
                    { /* Get the run-length and sign bit and jump into the
                         right location to ensure that we move on from the
                         end of the run. */
                      get_uniform_symbol(state,A,C,word,avail,symbol);
                      ctxt = symbol<<1;
                      get_uniform_symbol(state,A,C,word,avail,symbol);
                      ctxt |= symbol;
                      get_uniform_symbol(state,A,C,word,avail,symbol);
                      dp[ctxt] =
                        lsb + (lsb>>1) + (symbol<<(IMPLEMENTATION_PRECISION-1));
                      cp += ctxt;
                      cp[0] = SELF_SIG;
                      cp[-row_gap-2] |= FAR_SIG;
                      cp[-row_gap-1] |= BR_SIG;
                      cp[-row_gap+1] |= BL_SIG;
                      cp[-row_gap+2] |= FAR_SIG;
                      cp[row_gap-2]  |= FAR_SIG;
                      cp[row_gap-1]  |= TR_SIG;
                      cp[row_gap+1]  |= TL_SIG;
                      cp[row_gap+2]  |= FAR_SIG;
                      cp[-2]         |= FAR_SIG;
                      cp[2]          |= FAR_SIG;
                      if (symbol)
                        { /* Negative sample. */
                          cp[-1]         |= CR_SIG | H_NVE_SIG;
                          cp[1]          |= CL_SIG | H_NVE_SIG;
                          cp[-row_gap]   |= BC_SIG | V_NVE_SIG;
                          cp[row_gap]    |= TC_SIG | V_NVE_SIG;
                        }
                      else
                        { /* Positive sample. */
                          cp[-1]         |= CR_SIG | H_PVE_SIG;
                          cp[1]          |= CL_SIG | H_PVE_SIG;
                          cp[-row_gap]   |= BC_SIG | V_PVE_SIG;
                          cp[row_gap]    |= TC_SIG | V_PVE_SIG;
                        }
                      cp -= ctxt;
                      if (ctxt == 0)
                        goto skip1;
                      else if (ctxt == 3)
                        { c -= 2; dp += 2; cp += 2; d_cp++; continue; }
                      else
                        continue;
                    }
                }

              ctxt = cp[0];
              if (ctxt & IS_REFINED)
                cp[0] = ctxt & ~IS_REFINED;
              else if (!(ctxt & (SELF_SIG | OUT_OF_BOUNDS)))
                {
                  csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]);
                  get_symbol(state,A,C,word,avail,symbol,csp);
                  if (symbol)
                    { /* New significant value; update contexts & get sign. */
                      val = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF];
                      csp = csp_base + SC_OFFSET + (val & 0x000F);
                      val &= MIN_IFC_INT;
                      get_symbol(state,A,C,word,avail,symbol,csp);
                      val ^= (symbol << (IMPLEMENTATION_PRECISION-1));
                      cp[0]            = ctxt | SELF_SIG;
                      cp[-row_gap-2+0] |= FAR_SIG;
                      cp[-row_gap-1+0] |= BR_SIG;
                      cp[-row_gap+1+0] |= BL_SIG;
                      cp[-row_gap+2+0] |= FAR_SIG;
                      cp[row_gap-2+0]  |= FAR_SIG;
                      cp[row_gap-1+0]  |= TR_SIG;
                      cp[row_gap+1+0]  |= TL_SIG;
                      cp[row_gap+2+0]  |= FAR_SIG;
                      cp[-2+0]         |= FAR_SIG;
                      cp[2+0]          |= FAR_SIG;
                      if (val)
                        { /* Negative sample. */
                          cp[-1+0]         |= CR_SIG | H_NVE_SIG;
                          cp[1+0]          |= CL_SIG | H_NVE_SIG;
                          cp[-row_gap+0]   |= BC_SIG | V_NVE_SIG;
                          cp[row_gap+0]    |= TC_SIG | V_NVE_SIG;
                        }
                      else
                        { /* Positive sample. */
                          cp[-1+0]         |= CR_SIG | H_PVE_SIG;
                          cp[1+0]          |= CL_SIG | H_PVE_SIG;
                          cp[-row_gap+0]   |= BC_SIG | V_PVE_SIG;
                          cp[row_gap+0]    |= TC_SIG | V_PVE_SIG;
                        }
                      val |= lsb + (lsb>>1);
                      dp[0] = val; /* Write new non-zero value back to buffer. */
                    }
                }
skip1:
              ctxt = cp[1];
              if (ctxt & IS_REFINED)
                cp[1] = ctxt & ~IS_REFINED;
              else if (!(ctxt & (SELF_SIG | OUT_OF_BOUNDS)))
                {
                  csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]);
                  get_symbol(state,A,C,word,avail,symbol,csp);
                  if (symbol)
                    { /* New significant value; update contexts & get sign. */
                      val = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF];
                      csp = csp_base + SC_OFFSET + (val & 0x000F);
                      val &= MIN_IFC_INT;
                      get_symbol(state,A,C,word,avail,symbol,csp);
                      val ^= (symbol << (IMPLEMENTATION_PRECISION-1));
                      cp[1]            = ctxt | SELF_SIG;
                      cp[-row_gap-2+1] |= FAR_SIG;
                      cp[-row_gap-1+1] |= BR_SIG;
                      cp[-row_gap+1+1] |= BL_SIG;
                      cp[-row_gap+2+1] |= FAR_SIG;
                      cp[row_gap-2+1]  |= FAR_SIG;
                      cp[row_gap-1+1]  |= TR_SIG;
                      cp[row_gap+1+1]  |= TL_SIG;
                      cp[row_gap+2+1]  |= FAR_SIG;
                      cp[-2+1]         |= FAR_SIG;
                      cp[2+1]          |= FAR_SIG;
                      if (val)
                        { /* Negative sample. */
                          cp[-1+1]         |= CR_SIG | H_NVE_SIG;
                          cp[1+1]          |= CL_SIG | H_NVE_SIG;
                          cp[-row_gap+1]   |= BC_SIG | V_NVE_SIG;
                          cp[row_gap+1]    |= TC_SIG | V_NVE_SIG;
                        }
                      else
                        { /* Positive sample. */
                          cp[-1+1]         |= CR_SIG | H_PVE_SIG;
                          cp[1+1]          |= CL_SIG | H_PVE_SIG;
                          cp[-row_gap+1]   |= BC_SIG | V_PVE_SIG;
                          cp[row_gap+1]    |= TC_SIG | V_PVE_SIG;
                        }
                      val |= lsb + (lsb>>1);
                      dp[1] = val; /* Write new non-zero value back to buffer. */
                    }
                }
            }
      }
  state->A=A; state->C=C; state->word=word; state->available_bits=avail;
}

/*****************************************************************************/
/* STATIC                  zero_refinement_pass_func                         */
/*****************************************************************************/

static void
  zero_refinement_pass_func(block_master_ptr master)

 /* This function refines all samples which have not yet been found to be
    significant and whose context word matches that supplied by the
    `context_mask' field in `master', setting the IS_REFINED flag in the
    cntext word for all samples which are refined in this way.  The function
    ignores all samples for which the IS_REFINED flag is already set. */

{
  register std_int *d_cp;
  register std_int d_mask;
  register int c;
  register std_short *cp;
  register ifc_int *dp;
  register std_short ctxt, context_mask;
  register ifc_int shift;
  register arith_state_ptr state;
  register std_int A, C, word;
  register context_state_ptr csp;
  std_short avail;
  ifc_int val, symbol, lsb;
  std_byte *zc_lut;
  int rows, cols, row_gap, half_inter_row, r;
  std_short *context;
  ifc_int *data;
  context_state_ptr csp_base;
  code_subblock_ptr subblock, last_subblock;

  shift = master->bit_idx - 1;
  assert(shift > 0);
  lsb = 1 << shift;
  context_mask = master->context_mask;
  d_mask = context_mask; d_mask <<= 16; d_mask |= context_mask;
  data = master->sample_buffer;
  context = master->context_buffer;
  row_gap = master->row_gap;
  assert(!(row_gap & 1));
  state = &(master->coder_state);
  A=state->A; C=state->C; word=state->word; avail=state->available_bits;
  csp_base = state->contexts;
  zc_lut = master->zc_lut;
  last_subblock = master->last_subblock;
  for (subblock=master->first_subblock; subblock <= last_subblock; subblock++)
    if (subblock->significant)
      {
        rows = subblock->rows;
        cols = subblock->cols;
        half_inter_row = (row_gap-cols)>>1;
        dp = data + subblock->offset;
        cp = context + subblock->offset;
        d_cp = (std_int *) cp;
        for (r=rows; r > 0; r--, dp+=half_inter_row<<1, cp+=half_inter_row<<1,
             d_cp+=half_inter_row)
          for (c=cols; c > 0; c-=2, dp+=2, cp+=2, d_cp++)
            {
              if (((*d_cp) & d_mask) == 0)
                continue;
              ctxt = cp[0];
              if ((ctxt & context_mask) &&
                  !(ctxt & (IS_REFINED | SELF_SIG | OUT_OF_BOUNDS)))
                {
                  ctxt |= IS_REFINED;
                  csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]);
                  get_symbol(state,A,C,word,avail,symbol,csp);
                  if (symbol)
                    { /* New significant value; update contexts & code sign */
                      val = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF];
                      csp = csp_base + SC_OFFSET + (val & 0x000F);
                      val &= MIN_IFC_INT;
                      get_symbol(state,A,C,word,avail,symbol,csp);
                      val ^= (symbol << (IMPLEMENTATION_PRECISION-1));
                      ctxt           |= SELF_SIG;
                      cp[-row_gap-2] |= FAR_SIG;
                      cp[-row_gap-1] |= BR_SIG;
                      cp[-row_gap+1] |= BL_SIG;
                      cp[-row_gap+2] |= FAR_SIG;
                      cp[row_gap-2]  |= FAR_SIG;
                      cp[row_gap-1]  |= TR_SIG;
                      cp[row_gap+1]  |= TL_SIG;
                      cp[row_gap+2]  |= FAR_SIG;
                      cp[-2]         |= FAR_SIG;
                      cp[2]          |= FAR_SIG;
                      if (val)
                        { /* Negative sample. */
                          cp[-1]         |= CR_SIG | H_NVE_SIG;
                          cp[1]          |= CL_SIG | H_NVE_SIG;
                          cp[-row_gap]   |= BC_SIG | V_NVE_SIG;
                          cp[row_gap]    |= TC_SIG | V_NVE_SIG;
                        }
                      else
                        { /* Positive sample. */
                          cp[-1]         |= CR_SIG | H_PVE_SIG;
                          cp[1]          |= CL_SIG | H_PVE_SIG;
                          cp[-row_gap]   |= BC_SIG | V_PVE_SIG;
                          cp[row_gap]    |= TC_SIG | V_PVE_SIG;
                        }
                      val |= lsb + (lsb>>1);
                      dp[0] = val;
                    }
                  cp[0] = ctxt;
                }
              ctxt = cp[1];
              if ((ctxt & context_mask) &&
                  !(ctxt & (IS_REFINED | SELF_SIG | OUT_OF_BOUNDS)))
                {
                  ctxt |= IS_REFINED;
                  csp = csp_base + (ZC_OFFSET + zc_lut[ctxt & ZC_MASK]);
                  get_symbol(state,A,C,word,avail,symbol,csp);
                  if (symbol)
                    { /* New significant value; update contexts & code sign */
                      val = ebcot_sc_lut[(ctxt>>SIGN_POS)&0x00FF];
                      csp = csp_base + SC_OFFSET + (val & 0x000F);
                      val &= MIN_IFC_INT;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -