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

📄 ac.cpp

📁 《Visual C++小波变换技术与工程实践》靳济芳编著的光盘程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
  register low,high;
  register long range;
  register bitCount;
  //static int count=0;
  if (sym<0 || sym>=acm->nsym)
    errorHandler("Invalid symbol passed to mzte_ac_encode_symbol " \
		 "(sym=%d while nsym=%d)", 
		 sym,acm->nsym);

  low = ace->low;
  high = ace->high;
  range = (long) (high - low) + 1;
 // printf("%d %d %d %d\n", count++, sym, acm->cfreq[0], acm->cfreq[1]);
  high=low+(range*(Int)acm->cfreq[sym])/(Int)acm->cfreq[0] - 1;
  low=low+(range*(Int)acm->cfreq[sym+1])/(Int)acm->cfreq[0];

  bitCount = ace->bitCount;
  while (1) {
    if (high < Half)  {
      mzte_bit_plus_follow(ace,0);
    }
    else if (low >= Half)  {
      mzte_bit_plus_follow(ace,1);
      low -= Half;
      high -= Half;
    }
    else if ((low >= firstQtr) && (high < thirdQtr)) {
      ++(ace->followBits);
      low -= firstQtr;
      high -= firstQtr;
    }
    else
      break;
    low = 2*low;
    high = 2*high + 1;
  }
  ace->low = low;
  ace->high = high;

  if (acm->adapt)
    mzte_update_model(acm,sym);

  return ace->bitCount - bitCount;
}


/************************************************************************/
/*                            Bit Input                                 */
/************************************************************************/

/*********************************************************/
/* Modified to be consistant with the functions in       */
/* bitpack.c, i.e., using nextinputbit() to get the new  */
/* bits from the bit stream.                             */
/*                                                       */
/* Included remove stuffing bits, refer to 				 */
/* mzte_output_bit() for more details.                   */
/*********************************************************/

Int CVTCDecoder::mzte_input_bit(ac_decoder *acd)
{
	register t;

	if (!(acd->bitsLeft))
		acd->bitsLeft = 8;

	t = nextinputbit();
	--(acd->bitsLeft);
	++(acd->bitCount);

	/* remove stuffing bits */
	zeroStrLen+=(!t)?1:-zeroStrLen;
	if(zeroStrLen==STUFFING_CNT) {
		if (!mzte_input_bit(acd))
			errorHandler("Error in decoding stuffing bits " \
                         "(must be 1 after %d 0's)",STUFFING_CNT);
		zeroStrLen=0;
	}
	return(t);
}


/************************************************************************/
/*                             Decoder                                  */
/************************************************************************/

Void CVTCDecoder::mzte_ac_decoder_init(ac_decoder *acd)
{
	register long i,value=0;

	//Added by Sarnoff for error resilience, 3/5/99
	if(!mzte_codec.m_usErrResiDisable)
		STUFFING_CNT=15;
	//End Added by Sarnoff for error resilience, 3/5/99

	/* remove first stuffing bit */
	if(!get_X_bits(1))
		errorHandler("Error in extracting the stuffing bit at the\n"\
                        "beginning of arithmetic decoding"\
                        "refer mzte_encoder_init in ac.c)");
	
	zeroStrLen=0;
	i = codeValueBits;
	do {
		value <<= 1;
		value += mzte_input_bit(acd);
	} while (--i);
	acd->value = value;
	acd->low = 0;
	acd->high = peakValue;
	acd->bitCount = 0;
	acd->bitsLeft = 0;
	return;
}


/*******************************************************/
/* Added restore_arithmetic_offset() called to recover */
/* the extra bits read in by decoder. This routine is  */
/* defined in bitpack.c                                */
/*******************************************************/
Void CVTCDecoder::mzte_ac_decoder_done(ac_decoder *acd)
{
	restore_arithmetic_offset(acd->bitsLeft);	
	acd->bitCount += acd->bitsLeft;
	if ((acd->bitCount)%8)
		errorHandler("Did not get alignment in arithmetic decoding");
}

Int CVTCDecoder::mzte_ac_decode_symbol(ac_decoder *acd,ac_model *acm)
{
  register Int high,low,value;
  register long range;
  register cum;
  Int sym;
  Int modify=0;
 // static int count=0;
  high=acd->high; low=acd->low; value=acd->value;
  range = (long)(high-low)+1;
  
  cum = (((long)(value-low)+1)*(Int)(acm->cfreq[0])-1)/range;
  for (sym=0; (Int)(acm->cfreq[sym+1])>cum; sym++)
    /* do nothing */ ;
  high = low + (range*(Int)(acm->cfreq[sym]))/(Int)(acm->cfreq[0])-1;
  low  = low + (range*(Int)(acm->cfreq[sym+1]))/(Int)(acm->cfreq[0]);
  modify = acm->adapt; 
 // printf("%d %d %d %d\n", count++,sym, acm->cfreq[0], acm->cfreq[1]);
  while (1) {
    if (high < Half) {
      /* do nothing */
    } else if (low >= Half) {
      value -= Half;
      low -= Half;
      high -= Half;
    }
    else if ((low >= firstQtr) && (high < thirdQtr))  {
      value -= firstQtr;
      low -= firstQtr;
      high -= firstQtr;
    }
    else
      break;
    low <<= 1;
    high = (high<<1)+1;
    value = (value<<1) + mzte_input_bit(acd);
  }
  acd->high = high;
  acd->low = low;
  acd->value = value;
  if (modify)
    mzte_update_model(acm,sym);
  
  return sym;
}


/************************************************************************/
/*                       Probability Model                              */
/************************************************************************/

Void CVTCCommon::mzte_ac_model_init(ac_model *acm,Int nsym,SHORTTYPE *ifreq,Int adapt,
Int inc)
{
	register Int i;
	register UShort tmpFreq=0;

	acm->inc = inc;
	acm->nsym = nsym;
	acm->adapt = adapt;

  if ((acm->freq=(UShort *)malloc(nsym*sizeof(UShort)))==NULL)
    errorHandler("Can't allocate %d bytes for acm->freq in " \
		 "mzte_ac_model_init.",
		 nsym*sizeof(UShort));

  if  ((acm->cfreq=(UShort *) malloc((nsym+1)*sizeof(UShort)))==NULL)
    errorHandler("Can't allocate %d bytes for acm->cfreq in " \
		 "mzte_ac_model_init.",
		 (nsym+1)*sizeof(UShort));
  
	if (ifreq) {
		acm->cfreq[nsym] = 0;
		for (i=nsym-1; i>=0; i--) {
			acm->freq[i] = ifreq[i];
			acm->cfreq[i] = tmpFreq + ifreq[i];
			tmpFreq = acm->cfreq[i];
		}
		/* NOTE: This check won't always work for mixture of models */
		if (acm->cfreq[0] > acm->Max_frequency) {
			register Int cum=0;
			acm->cfreq[nsym] = 0;
			for (i=nsym-1; i>=0; i--)  {
				acm->freq[i] = ((Int) ifreq[i] + 1)/2;
				cum += (ifreq[i] + 1)/2;
				acm->cfreq[i] = cum;
			}
		}
		if (acm->cfreq[0] > acm->Max_frequency)
			errorHandler("error in acm->cfreq[0]");
	}
	else {
		for (i=0; i < nsym; i++) {
			acm->freq[i] = 1;
			acm->cfreq[i] = nsym - i;
		}
		acm->cfreq[nsym] = 0;
	}
}

Void CVTCCommon::mzte_ac_model_done(ac_model *acm)
{
	acm->nsym = 0;
	free(acm->freq);
	acm->freq = NULL;
	free(acm->cfreq);
	acm->cfreq = NULL;
}

Void CVTCCommon::mzte_update_model(ac_model *acm,Int sym)
{
  register SHORTTYPE *freq,*cfreq;
  register i;
  register inc;

  freq = acm->freq;
  cfreq = acm->cfreq;
  /* scale freq count down */
  if (cfreq[0] == acm->Max_frequency) {
    register cum=0,nsym;
    nsym = acm->nsym;
    cfreq[nsym] = 0;
    for (i=nsym-1; i>=0; i--) {
      freq[i] = ((Int)freq[i] + 1)/2;
      cum += freq[i];
      cfreq[i] = cum;
    }
  }
  inc = acm->inc;
  freq[sym] += inc;
  for (i=sym; i>=0; i--)
    cfreq[i] += inc;
}

⌨️ 快捷键说明

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