?? arithdec.c
字號:
/*****************************************************************************
// 程序: ebcot 編碼
// 版本: V0.0
// 作者: 胡運平
// 最后修改時間 : 30, 6, 2005
// 功能描述:
Context variables made global, rather than access via pointers.
Manually inlined the CodeMPS and CodeLPS functions.
Implements mq 解碼,實現(xiàn)MQ解碼所需要的參數(shù)
****************************************************************************/
#include <stdio.h>
#include"mq_code.h"
// Set this to inline to make all internal functions inline.
#define inline
typedef struct
//上下文狀態(tài)的相關(guān)信息
{
unsigned char I; //values in the range 0..46
unsigned char MPS; //MPS(either 0 or 1
} ArithDecContext;
//算術(shù)編碼器所需要的狀態(tài)信息
static long int C; //下限寄存器
static long int A; //間隔長度寄存器
static long int CT; //向下計數(shù)器
static unsigned char B; // The byte that is currently being assembled
static int firstByte;
//1 if the current byte is the first output byte, otherwise 0
//static int L;//代表到當(dāng)前為止所產(chǎn)生的編碼字節(jié)數(shù)
//static uint8 T;//臨時字節(jié)緩沖器
//用 static來聲明一個變量的作用有兩個,一是對局部變量用static聲明,則為該變量分配
//的空間在整個程序執(zhí)行期間始終存在。二是全局變量用static聲明,則該變量的作用域只限于
//本文件模塊。
// The array of allowable context states
#define MAXCONTEXT 18
static ArithDecContext contexts[MAXCONTEXT+1];//19個(I,MPS)
// Special context labels
#define RUNLENGTH_CX 17
#define UNIFORM_CX 18
/*****************************************************************************
Define these inputs to have different data types
******************************************************************************/
static long int Qe[47] =
{//Qe值的十六進(jìn)制表示
0x5601UL, 0x3401UL, 0x1801UL, 0x0ac1UL, 0x0521UL, 0x0221UL, 0x5601UL,
0x5401UL, 0x4801UL, 0x3801UL, 0x3001UL, 0x2401UL, 0x1c01UL, 0x1601UL,
0x5601UL, 0x5401UL, 0x5101UL, 0x4801UL, 0x3801UL, 0x3401UL, 0x3001UL,
0x2801UL, 0x2401UL, 0x2201UL, 0x1c01UL, 0x1801UL, 0x1601UL, 0x1401UL,
0x1201UL, 0x1101UL, 0x0ac1UL, 0x09c1UL, 0x08a1UL, 0x0521UL, 0x0441UL,
0x02a1UL, 0x0221UL, 0x0141UL, 0x0111UL, 0x0085UL, 0x0049UL, 0x0025UL,
0x0015UL, 0x0009UL, 0x0005UL, 0x0001UL, 0x5601UL
};
static unsigned char SWITCH[47] =
{
1, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static unsigned char NMPS[47] =
{
1 , 2 , 3 , 4 , 5 , 38 ,
7 , 8 , 9 , 10 , 11 , 12 , 13 , 29 ,
15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 ,
23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 ,
31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 ,
39 , 40 , 41 , 42 , 43 , 44 , 45 , 45 ,
46
};
static unsigned char NLPS[47] =
{
1 , 6 , 9 , 12 , 29 , 33 ,
6 , 14 , 14 , 14 , 17 , 18 , 20 , 21 ,
14 , 14 , 15 , 16 , 17 , 18 , 19 , 19 ,
20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 ,
28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 ,
36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 ,
46
};
/*****************************************************************************
//輸入字節(jié)Write in bytes, allowing for 0xFF stuffing.
*****************************************************************************/
static inline void byte_in(unsigned char b1)
{
/* This test sequence might speed up process */
if (B == 0xFF)//
{
// b1 = ReceiveByte(FILE *context);
if (b1 > 0x8F)
{
C += 0xFF00;
CT = 8;
}
else
{
C += (B<<=9);//B是C寄存器中的8個b
CT = 7;
}
}
else//B != 0XFF;
{
// B = ReceiveByte(FILE *context);
C += (B<<=8);//B是C寄存器中的8個b
CT = 8;
}
}
/******************************************************************************
//初始化算術(shù)解碼器
******************************************************************************/
void ArithDecInit()
{
C = 0;
// B = ReceiveByte(FILE *context);
C += B << 16;
byte_in(B);
C <<= 7;
CT -= 7;
A = 0x8000;
}
/*****************************************************************************
編碼中的重新歸一化直到概率區(qū)間A的大小超過0.75
*****************************************************************************/
static inline void Renorme(void)
{
do
{//Check that there will be no overflow with these shifts
if (CT == 0)
byte_in(B);
A <<= 1;
C <<= 1;
CT -= 1;
}while (A <= 0x8000);//while((A && 0x8000)==0)
}
/*****************************************************************************
//Encode a bit using the given context.Output bits will be written to the file
given to ArithEncInit().
param: D - The bit to encode, either 0 or 1.
param: CX - The number of the context to use.
*****************************************************************************/
unsigned char ArithDecode(unsigned char CD,unsigned char CX)
{
ArithDecContext *pCX;//指向ArithDecContext的指針
unsigned char I;
unsigned char D;
long int QeI;
unsigned char MPS;
pCX = &(contexts[CX]);
//Put the current context into globals, and write them back later
I = pCX->I;//索引號0--46
MPS = pCX->MPS;//二進(jìn)制數(shù)據(jù)。0 1
QeI = Qe[I];//概率估計值
if (pCX->MPS == CD)
{/* CodeMPS */
A -= QeI;
if ((C>>16)<QeI)//
{
if(A < QeI)
{
A = QeI;
D = MPS;
I = NMPS[I];
}
else
{
A = QeI;
D = 1- MPS;
if(SWITCH[I] == 1)
{
MPS = 1 - MPS;
}
I = NLPS[I];
}
Renorme();
}
else
{
C -= QeI<<16;
if (A >= 0x8000u)
D = MPS;
else
{
if(A < QeI)
{
D = 1- MPS;
if(SWITCH[I] == 1)
{
MPS = 1 - MPS;
}
I = NLPS[I];
}
else
{
D = MPS;
I = NMPS[I];
}
Renorme();
}
}
}
else
{/* CodeLPS */
A -= QeI;
if ((C>>16)<QeI)//
{
if(A < QeI)
{
A = QeI;
D = MPS;
I = NMPS[I];
}
else
{
A = QeI;
D = 1- MPS;
if(SWITCH[I] == 1)
{
MPS = 1 - MPS;
}
I = NLPS[I];
}
Renorme();
}
else
{
C -= QeI<<16;
if (A >= 0x8000u)
D = MPS;
else
{
if(A < QeI)
{
D = 1- MPS;
if(SWITCH[I] == 1)
{
MPS = 1 - MPS;
}
I = NLPS[I];
}
else
{
D = MPS;
I = NMPS[I];
}
Renorme();
}
}
}
pCX->I = I;
pCX->MPS = MPS;
return D;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -