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

📄 ebcot_lite_decode_passes.c

📁 JPEG2000实现的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            dst_get_symbol(areg,creg,ct,state,symbol,csp);
            val ^= ((1-symbol)<<shift);
            val |= half_lsb;
            dp[2] = val; /* Write new non-zero value back to buffer. */
          }

        ctxt = cp[3];
        if ((ctxt & SELF_SIG) && !(ctxt & IS_REFINED))
          {
            val = dp[3];
            symbol = (val & MAX_IFC_INT) >> shift;
            csp = csp_base + MAG_OFFSET;
            if (symbol < 4)
              {
                if (ctxt & 0x00FF)
                  csp++;
              }
            else
              csp += 2;
            dst_get_symbol(areg,creg,ct,state,symbol,csp);
            val ^= ((1-symbol)<<shift);
            val |= half_lsb;
            dp[3] = val; /* Write new non-zero value back to buffer. */
          }
      }
  state->mqd.areg = areg; state->mqd.creg = creg; state->mqd.ct = ct;
}


/* ========================================================================= */
/* -------------------- Speedup Decoding Pass Functions -------------------- */
/* ========================================================================= */
   /* The following functions are implemented with the aid of several
      software tricks to further enhance execution speed; one of these
      tricks involves hypothesis testing of the MQ coder state registers,
      which may not be appropriate if the MQ coder is already implemented
      efficiently, say, in the form of a special "multimedia" instruction.
      the fact that these functions are equivalent to the more dydactic
      versions of the functions above, is not necessarily all that easy
      to understand. */

/*****************************************************************************/
/* STATIC                     su_first_pass_func                             */
/*****************************************************************************/

static void
  su_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 su_flags;
  register int i;
  register std_int cum_delta, thresh;
  register std_int d_ctxt_0, d_ctxt_1; /* Merge these if you have 64 bits */
  register std_int *d_cp;
  register std_int agg_delta;
      /* Note: it is most beneficial if the above eight variables are
         held in registers. */
  register ifc_int *dp;
  register ifc_int shift;
  register dst_arith_state_ptr state;
  register dst_context_state_ptr csp;
  register ifc_int val, symbol;
  register unsigned long creg;
  register std_int areg;
  int ct;
  ifc_int lsb;
  std_int *supp, *sup;
  std_int non_causal;
  std_byte *zc_lut;
  int eighth_cols, d_stripe_gap, sup_gap, r, c;
  dst_context_state_ptr csp_base;

  state = &(master->coder_state);
  if (!state->mqd.active)
    dst_arith_coder__activate(state);

  assert((master->bit_idx > 0) &&
         ((master->interleaved_row_gap & 3) == 0));
  shift = master->bit_idx;
  lsb = 1 << shift;
  areg = state->mqd.areg; creg = state->mqd.creg; ct = state->mqd.ct;
  dst_compute_ac_thresh(areg,creg,thresh); cum_delta = 0;
  csp_base = state->contexts;
  agg_delta = csp_base[AGG_OFFSET+DST_ARITH_MAX_CTXTS];
  zc_lut = master->zc_lut;
  non_causal = 1 - master->causal;
  eighth_cols = (master->width+7)>>3;
  d_stripe_gap = (master->interleaved_row_gap >> 1);
  sup_gap = master->speed_up_row_gap;
  d_cp = (std_int *)(master->interleaved_context_buffer);
  dp = master->interleaved_sample_buffer;
  supp = master->speed_up_buffer;
  for (r=master->stripes; r > 0; r--,
       dp+=(d_stripe_gap<<1)-(eighth_cols<<5),
       d_cp+=d_stripe_gap-(eighth_cols<<4),
       supp+=sup_gap)
    {
      sup = supp;
      su_flags = *(sup++);
      for (c=eighth_cols; c > 0; c--)
        {
          su_flags |= *(sup++) << 8;
          if ((su_flags & 0x00001FF80) == 0)
            { /* Next 8 columns have all zero neighbourhoods.  Check to
                 see if we can decode all the relevant significance
                 information at once. */
              cum_delta += agg_delta<<3;
              if (cum_delta <= thresh)
                {
                  _addto_symbol_count(8);
#ifdef DST_LOG_SYMBOLS
                  for (symbol=8; symbol > 0; symbol--)
                    dst_arith_coder__check_logged_symbol(state,
                                                  (csp_base+AGG_OFFSET),0);
#endif /* DST_LOG_SYMBOLS */
                  dp += 32; d_cp += 16; su_flags >>= 8;
                  continue;
                }
              cum_delta -= agg_delta<<3;
            }
          for (i=8; i > 0; i--, dp+=4, d_cp+=2, su_flags>>=1)
            {
              if ((su_flags & 0x00000380) == 0)
                {
                  {
                    _addto_symbol_count(1);
                    cum_delta += agg_delta;
                    if (cum_delta <= thresh)
                      {
#ifdef DST_LOG_SYMBOLS
                        dst_arith_coder__check_logged_symbol(state,
                                               (csp_base+AGG_OFFSET),0);
#endif /* DST_LOG_SYMBOLS */
                        continue;
                      }
                    cum_delta -= agg_delta;
                    areg -= cum_delta;
                    creg -= ((unsigned) cum_delta) << 16;
                    cum_delta = 0;
                    csp = csp_base + AGG_OFFSET;
                    dst_complete_get_symbol(areg,creg,ct,state,
                                            symbol,csp,agg_delta);
                    dst_compute_ac_thresh(areg,creg,thresh);
                    agg_delta = csp_base[AGG_OFFSET+DST_ARITH_MAX_CTXTS];
#ifdef DST_LOG_SYMBOLS
                    dst_arith_coder__check_logged_symbol(state,csp,symbol);
#endif
                  }
                  if (!symbol)
                    continue;
                  else
                    { /* Get the run-length and jump into the appropriate
                         location in the regular decoding procedure. */
                      csp = csp_base + UNI_OFFSET;
                      dst_get_symbol_skewed(areg,creg,thresh,cum_delta,
                                            ct,state,symbol,csp);
                      val = symbol<<1;
                      dst_get_symbol_skewed(areg,creg,thresh,cum_delta,
                                            ct,state,symbol,csp);
                      val |= symbol;
                      d_ctxt_0 = d_cp[0]; d_ctxt_1 = d_cp[1];
                      switch (val) {
                        case 0: goto new_sig0;
                        case 1: goto new_sig1;
                        case 2: goto new_sig2;
                        case 3: goto new_sig3;
                        }
                    }
                }

              d_ctxt_0 = d_cp[0]; d_ctxt_1 = d_cp[1];
              if (!(d_ctxt_0 & (SELF_SIG_0 | OUT_OF_BOUNDS_0 | IS_REFINED_0)))
                {
                  csp = csp_base +
                    (ZC_OFFSET + zc_lut[(d_ctxt_0 >> ZC_SHIFT_0) & 0x00FF]);
                  cum_delta += csp[DST_ARITH_MAX_CTXTS];
                  if (cum_delta <= thresh)
                    {
                      _addto_symbol_count(1);
#ifdef DST_LOG_SYMBOLS
                      dst_arith_coder__check_logged_symbol(state,csp,0);
#endif
                      goto skip0;
                    }
                  dst_get_symbol_skewed_failed(areg,creg,thresh,cum_delta,
                                               ct,state,symbol,csp);
                  if (!symbol)
                    goto skip0;
new_sig0:         /* New significant value; update contexts & get sign. */
                  val = ebcot_sc_lut[(d_ctxt_0>>SIGN_POS_0)&0x000F];
                  csp = csp_base + SC_OFFSET + (val & 0x000F);
                  val &= MIN_IFC_INT;
                  dst_get_symbol_skewed(areg,creg,thresh,cum_delta,
                                        ct,state,symbol,csp);
                  val ^= (symbol << (IMPLEMENTATION_PRECISION-1));
                  su_flags |= 0x100;
                  if (val)
                    { /* Negative sample. */
                      d_ctxt_0     |= SELF_SIG_0 | TC_SIG_1 | V_NVE_SIG_1;
                      d_cp[-2]     |= TR_SIG_1 | CR_SIG_0 | H_NVE_SIG_0;
                      d_cp[2]      |= TL_SIG_1 | CL_SIG_0 | H_NVE_SIG_0;
                      if (non_causal)
                        {
                          d_cp[-d_stripe_gap-1] |= BR_SIG_1;
                          d_cp[-d_stripe_gap+1] |= BC_SIG_1 | V_NVE_SIG_1;
                          d_cp[-d_stripe_gap+3] |= BL_SIG_1;
                          sup[-sup_gap-2] |= 1<<(16-i);
                        }
                    }
                  else
                    { /* Positive sample. */
                      d_ctxt_0     |= SELF_SIG_0 | TC_SIG_1 | V_PVE_SIG_1;
                      d_cp[-2]     |= TR_SIG_1 | CR_SIG_0 | H_PVE_SIG_0;
                      d_cp[2]      |= TL_SIG_1 | CL_SIG_0 | H_PVE_SIG_0;
                      if (non_causal)
                        {
                          d_cp[-d_stripe_gap-1] |= BR_SIG_1;
                          d_cp[-d_stripe_gap+1] |= BC_SIG_1 | V_PVE_SIG_1;
                          d_cp[-d_stripe_gap+3] |= BL_SIG_1;
                          sup[-sup_gap-2] |= 1<<(16-i);
                        }
                    }
                  val |= lsb + (lsb>>1);
                  dp[0] = val; /* Write new non-zero value to buffer */
                }
skip0:              
              if (!(d_ctxt_0 & (SELF_SIG_1 | OUT_OF_BOUNDS_1 | IS_REFINED_1)))
                {
                  csp = csp_base +
                    (ZC_OFFSET + zc_lut[(d_ctxt_0 >> ZC_SHIFT_1) & 0x00FF]);
                  cum_delta += csp[DST_ARITH_MAX_CTXTS];
                  if (cum_delta <= thresh)
                    {
                      _addto_symbol_count(1);
#ifdef DST_LOG_SYMBOLS
                      dst_arith_coder__check_logged_symbol(state,csp,0);
#endif
                      goto skip1;
                    }
                  dst_get_symbol_skewed_failed(areg,creg,thresh,cum_delta,
                                               ct,state,symbol,csp);
                  if (!symbol)
                    goto skip1;
new_sig1:         /* New significant value; update contexts & get sign. */
                  val = ebcot_sc_lut[(d_ctxt_0>>SIGN_POS_1)&0x000F];
                  csp = csp_base + SC_OFFSET + (val & 0x000F);
                  val &= MIN_IFC_INT;
                  dst_get_symbol_skewed(areg,creg,thresh,cum_delta,
                                        ct,state,symbol,csp);
                  val ^= (symbol << (IMPLEMENTATION_PRECISION-1));
                  su_flags |= 0x100;
                  if (val)
                    { /* Negative sample. */
                      d_ctxt_0     |= SELF_SIG_1 | BC_SIG_0 | V_NVE_SIG_0;
                      d_ctxt_1     |= TC_SIG_0 | V_NVE_SIG_0;
                      d_cp[-2]     |= BR_SIG_0 | CR_SIG_1 | H_NVE_SIG_1;
                      d_cp[-1]     |= TR_SIG_0;
                      d_cp[2]      |= BL_SIG_0 | CL_SIG_1 | H_NVE_SIG_1;
                      d_cp[3]      |= TL_SIG_0;
                    }
                  else
                    { /* Positive sample. */
                      d_ctxt_0     |= SELF_SIG_1 | BC_SIG_0 | V_PVE_SIG_0;
                      d_ctxt_1     |= TC_SIG_0 | V_PVE_SIG_0;
                      d_cp[-2]     |= BR_SIG_0 | CR_SIG_1 | H_PVE_SIG_1;
                      d_cp[-1]     |= TR_SIG_0;
                      d_cp[2]      |= BL_SIG_0 | CL_SIG_1 | H_PVE_SIG_1;
                      d_cp[3]      |= TL_SIG_0;
                    }
                  val |= lsb + (lsb>>1);
                  dp[1] = val; /* Write new non-zero value to buffer. */
                }
skip1:
              d_ctxt_0 &= ~(IS_REFINED_0 | IS_REFINED_1);
              if (!(d_ctxt_1 & (SELF_SIG_0 | OUT_OF_BOUNDS_0 | IS_REFINED_0)))
                {
                  csp = csp_base +
                    (ZC_OFFSET + zc_lut[(d_ctxt_1 >> ZC_SHIFT_0) & 0x00FF]);
                  cum_delta += csp[DST_ARITH_MAX_CTXTS];
                  if (cum_delta <= thresh)
                    {
                      _addto_symbol_count(1);
#ifdef DST_LOG_SYMBOLS
                      dst_arith_coder__check_logged_symbol(state,csp,0);
#endif
                      goto skip2;
                    }
                  dst_get_symbol_skewed_failed(areg,creg,thresh,cum_delta,
                                               ct,state,symbol,csp);
                  if (!symbol)

⌨️ 快捷键说明

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