📄 ac.cpp
字号:
{
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 + -