?? ac_en.h
字號:
/////////////////////////////////////////////
//
// AC_En.h
// 文件內容:算術編碼
//
// 作 者:丁貴廣
// 制作日期:2003.7.26
// 西安電子科技大學 AI Lab
//
/////////////////////////////////////////////
# include "stdlib.h"
# include "stdio.h"
# include "math.h"
/**************************************************************************
定義算術編碼的概率模型表
**************************************************************************/
static unsigned short qe_value[47]=
{0x5601,0x3401,0x1801,0x0ac1,0x0521,0x0221,0x5601,0x5401,
0x4801,0x3801,0x3001,0x2401,0x1c01,0x1601,0x5601,0x5401,
0x5101,0x4801,0x3801,0x3401,0x3001,0x2801,0x2401,0x2201,
0x1c01,0x1801,0x1601,0x1401,0x1201,0x1101,0x0ac1,0x09c1,
0x08a1,0x0521,0x0441,0x02a1,0x0221,0x0141,0x0111,0x0085,
0x0049,0x0025,0x0015,0x0009,0x0005,0x0001,0x5601};
static unsigned short 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 short 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};
static unsigned short flag[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};
static unsigned short a_register,ct,mps[20],index[20];
static unsigned long c_register,bp,b0,b1,CC;
static FILE *fp_out;
static FILE *fp_in;
static long BytesLimit,sc,TByteLimit; // size limited by compressed image size.
static long num_of_packed_bytes=0; // total bytes written out.
static long num_of_unpacked_bytes=0; // total bytes read in.
long pack1(short,short,short);
void byteout();
/**************************************************************************
Init_AC_QM_Encoder(void)
完成算術編碼的初始化
**************************************************************************/
void Init_AC_QM_Encoder(void)
{ short i;
a_register=0x8000;
c_register=0;
ct=12;
bp=0;
sc=0;
for(i=0;i<20;i++){
index[i]=0;
mps[i]=0;
if(i==0) index[i]=4;
if(i==17) index[i]=3;
if((i==18)||(i==19)) index[i]=46;
}
}
/**************************************************************************
pack1()
算術編碼的主函數
**************************************************************************/
long pack1(
short bit_num,
short bit_value,
short con)
{
short i,f_bit;
for(i=0;i<bit_num;i++){
f_bit=bit_value>>i;
if((f_bit&1)==mps[con]){
a_register-=qe_value[index[con]];
if((a_register&0x8000)==0){
if(a_register<qe_value[index[con]]) a_register=qe_value[index[con]];
else c_register+=qe_value[index[con]];
index[con]=nmps[index[con]];
do{
a_register<<=1;
c_register<<=1;
ct--;
if (ct==0) {
byteout();
if(sc>=BytesLimit) return -1;
}
}while ((a_register&0x8000)==0);
}
else c_register+=qe_value[index[con]];
}
else {
a_register-=qe_value[index[con]];
if(a_register<qe_value[index[con]]) c_register+=qe_value[index[con]];
else a_register=qe_value[index[con]];
if (flag[index[con]]==1) mps[con]=1-mps[con];
index[con]=nlps[index[con]];
do{
a_register<<=1;
c_register<<=1;
ct--;
if (ct==0) {
byteout();
if(sc>=BytesLimit) return -1;
}
}while ((a_register&0x8000)==0);
}
}
return 0;
}
/**************************************************************************
pack1()
算術編碼的字節輸出函數
**************************************************************************/
void byteout( void)
{
if(bp==0){
b0=c_register>>19;
bp++;
c_register&=0x7ffff;
ct=8;
}
else{
if (b0==0xff) {
b1=c_register>>20;
bp++;
c_register&=0xfffff;
ct=7;
}
else{
if (c_register>=0x8000000){
b0++;
c_register&=0x7ffffff;
if(b0==0xff){
b1=c_register>>20;
bp++;
c_register&=0xfffff;
ct=7;
}
else{
b1=c_register>>19;
bp++;
c_register&=0x7ffff;
ct=8;
}
}
else{
b1=c_register>>19;
bp++;
c_register&=0x7ffff;
ct=8;
}
}
fwrite(&b0,sizeof(char),1,fp_out);
sc++;
b0=b1;
}
}
/**************************************************************************
flush()
算術編碼的終止函數
**************************************************************************/
void flush(void)
{
unsigned long tempc;
tempc=c_register+a_register;
c_register|=0xffff;
if (c_register>=tempc) c_register-=0x8000;
c_register<<=ct;
byteout();
c_register<<=ct;
byteout();
if (b0!=0xff) fwrite(&b0,sizeof(char),1,fp_out);
else bp--;
}
/**************************************************************************
MaxinMatrix()
功能:返回圖像中的最大值
**************************************************************************/
short MaxinMatrix(BYTE *image, short x_size, short y_size)
{
short i,j,max;
max=abs(image[0]);
for(i=0;i<y_size;i++)
for(j=0;j<x_size;j++)
if(abs(image[i*x_size+j])>max) max=abs(image[i*x_size+j]);
return max;
}
/**************************************************************************
Bitplane_coding()
功能:編碼一個位平面
**************************************************************************/
short Bitplane_coding(BYTE *image,short n,short x_size,short y_size)
{
short i,j,Sn;
for(i=0;i<x_size;i++)
for(j=0;j<y_size;j++)
{
Sn=(abs(image[i*x_size+j])>>n)&1;
pack1(1,Sn,0);
}
return 0;
}
/**************************************************************************
Encoding_Pass()
功能:編碼整幅圖像
**************************************************************************/
short Encoding_Pass(
BYTE *image,
short x_size,
short y_size)
{
short n;
n=(short)(log10(MaxinMatrix(image,x_size,y_size))/log10(2));
if(pack1(4,n,0)==-1) return -1;
while(n>=0)
{
if(Bitplane_coding(image,n,x_size,y_size)==-1) return -1;
n--;
}
return 0;
}
/**************************************************************************
AC_code()
功能:算術編碼入口函數
**************************************************************************/
void AC_code(
BYTE *image,
short x_size,
short y_size)
{
BytesLimit=(long)(x_size*y_size); // lossless.
Init_AC_QM_Encoder();
if(Encoding_Pass(image,x_size,y_size)==-1) goto END;
END:flush();
fclose(fp_out);
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -