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

📄 quant.cpp

📁 《Visual C++小波变换技术与工程实践》靳济芳编著的光盘程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}




/*--------------- INVERSE QUANTIZATION --------------------------*/

/* 
   Function:
   ---------
   initInvQuantSingleStage - Initialization of the single-stage inverse
     quantizer for a given Q index.

   Arguments:
   ----------
   quantState *state - PoInter to the state data structure.
   Int *statePrevQ - PoInter to previous quantized value state.

   Return Value:
   -------------
   <None>

   Description:
   ------------
   This must be called prior to single-stage inverse quantization. A seperate
   state structure must be kept for each value that is quantized in parallel.
   Single-stage inverse quantization is just successive calls to 
   invQuantSingleStage. For each value,  need only be called once, before
   the first call to invQuantSingleStage.
*/

Void CVTCCommon::initInvQuantSingleStage(quantState *state, Int *statePrevQ)
{
  state->residualValue = 0;
  state->partitionType = 0x2; /* fromReduced = 0 and fromDeadZone  = 1 */
  *statePrevQ          = 0;
}

#define QLEVMID(q) (((q))/2)   // 1124


/* Mapping of start of quantization level, sign, and quantization level size
   to specific value.
*/
#define GETVAL(start, sgn, q) ((start) \
			       ? ((start) + (sgn)*QLEVMID((q))) \
			       : 0)

/* 
   Function:
   ---------
   invQuantSingleStage - Single-stage inverse quantizer.

   Arguments:
   ----------
   QIndex - Quantized value for this stage.
   Q     - Quantization value. Represents desired quantization level size.
   state - State of quantizer.
   Int *statePrevQ - PoInter to previous quantized value state.
   Int updatePrevQ - 0 means don't update the statePrevQ variable. !0 means
     update it.

   Return Value:
   -------------
   Inverse quantization value for this stage.

   Description:
   ------------
   initInvQuantSingleStage must be called prior to using this function the
   first time for a given value. It will compute the new, updated value
   based on the current index and state associated with the value.
*/

Int CVTCCommon::invQuantSingleStage(Int QIndex, Int Q, quantState *state, Int *statePrevQ,
			Int updatePrevQ)
{
  Int refLevs; /* how many refinement levels in new stage */
  Int val;     /* new value to return for this stage */
  Int sgn;

  /*--------------- INITIAL QUANTIZATION STAGE -------------------*/
  if (*statePrevQ==0)
  {
    val = QIndex*Q + SGN(QIndex)*(QIndex ? QLEVMID(Q) : 0);

    /* update state */
    state->residualValue = QIndex*Q;
    CLR_fromReduced(state->partitionType);
    if (QIndex)
      CLR_fromDeadZone(state->partitionType);
    else
      SET_fromDeadZone(state->partitionType);

    if (updatePrevQ)
      *statePrevQ = Q;

    return val;
  }


  /*--------------- NON-INITIAL QUANTIZATION STAGES -------------------*/

  /* get the number of refinement levels from lastQUsed state */
  refLevs = IROUND(*statePrevQ,Q);

  /* Catch condition where there's no refinement being done.
     State information is not changed.
  */
  sgn = (state->residualValue < 0 || QIndex < 0) ? -1 : 1;      
  if (refLevs<=1)
    val = GETVAL(state->residualValue,sgn,*statePrevQ);
  else
  {
    Int inDeadZone;  /* are we still in the dead zone */
    Int lastQUsed;   /* The "real" Q value last used */
    Int lastLevSize; /* Size of quantization level used last */
    Int newQUsed, newStateQ;
    Int excess;
    Int absQIndex;

    /* Initialize the last quant value used */
    lastQUsed = *statePrevQ;
    
    /* update new Q value state */
    newStateQ = newQUsed = ICEIL(lastQUsed,refLevs);
    if (updatePrevQ)
      *statePrevQ = newStateQ;

    /* Get last level size */
    lastLevSize = lastQUsed-fromReduced(state->partitionType);

    /* check if a reduced level can span the last level */
    if (refLevs*(newQUsed-1) >= lastLevSize)
    {
      --newQUsed;

      /* might overshoot (?) but can't reduce anymore */
      excess=0;
#if 1
      if (lastLevSize-refLevs*newQUsed)
	fprintf(stderr,"Excess in reduced partition\n");
#endif
    }
    else
      /* get excess (overshoot) */
      excess=lastLevSize-refLevs*newQUsed;

    /* Set dead zone indicator */
    inDeadZone = fromDeadZone(state->partitionType);

    /*--- Calculate val. Update residualValue and fromReduced states ---*/
    absQIndex = abs(QIndex);
    if (excess==0)
    {
      if (newQUsed < newStateQ)
	SET_fromReduced(state->partitionType);
      else
	CLR_fromReduced(state->partitionType);
      state->residualValue += sgn*absQIndex*newQUsed;
    }
    else
    {
      Int reducedIdx;
      Int fullLevs;

      fullLevs = refLevs+excess;
      if (absQIndex >= fullLevs)
      {
	SET_fromReduced(state->partitionType);
	state->residualValue += sgn*fullLevs*newQUsed;

	--newQUsed;
	
	reducedIdx = absQIndex-fullLevs;
	state->residualValue += sgn*reducedIdx*newQUsed;
      }
      else
      {
	CLR_fromReduced(state->partitionType);
	state->residualValue += sgn*absQIndex*newQUsed;
      }
    }

    val = GETVAL(state->residualValue, sgn, newQUsed);
    
    if (inDeadZone && QIndex)
      CLR_fromDeadZone(state->partitionType);
  }

  return val;
}



/*--------- DERIVED QUANTIZATION VALUES AND REFINEMENT LEVELS ----------*/


/*
函数输入:
Int curQ:		当前输入的量化值;
Int *lastQUsed:	上一次量化修正后的量化值,它将在函数中完成更新;
Int whichQ:		量化器所处的量化级。
函数返回值:
量化系数的级别数。
函数功能描述:
计算得到在给定量化级条件下的细化级别数并更新量化值。


  */

Int CVTCCommon::quantRefLev(Int curQ, Int *lastQUsed, Int whichQ)
{
	Int refLevs;
	Int newQUsed;

	//计算得到量化细化的级别数
	refLevs = IROUND(*lastQUsed,curQ);
		
	if (whichQ==0 || refLevs>1)
	{
		//新的级别数
		newQUsed = ICEIL(*lastQUsed,refLevs);

		//更新量化值
		*lastQUsed = newQUsed;
	}

	return refLevs;
}




⌨️ 快捷键说明

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