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

📄 arithcoding.cpp

📁 本程序使用VC++编写
💻 CPP
字号:
// ARITHCoding.cpp: implementation of the CARITHCoding class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HIC.h"
#include "ARITHCoding.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

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 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.
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CARITHCoding::CARITHCoding()
{

}

CARITHCoding::~CARITHCoding()
{

}
/**************************************************************************
 完成算术编码的初始化 MQ_EncoderInit()
 **************************************************************************/
void CARITHCoding::MQ_EncoderInit()
{
	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 CARITHCoding::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;

}


/**************************************************************************
 算术编码的字节输出函数byteout()
*************************************************************************/
void CARITHCoding::byteout()
{
	 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 CARITHCoding::flush()
{
	  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 CARITHCoding::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;

}



short CARITHCoding::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;

}



short CARITHCoding::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 CARITHCoding::AC_code(BYTE *image, short x_size, short y_size)
{
	 	  
	  BytesLimit=(long)(x_size*y_size);           
	  MQ_EncoderInit();
	  if(Encoding_Pass(image,x_size,y_size)==-1) 
	  goto END;
      END:flush();
	  fclose(fp_out);
	  return;

}

void CARITHCoding::Init_AC_QM_Decoder()
{
	 short i;
     a_register=0x8000;
     c_register=0;
     ct=12;
     bp=0;
     sc=0;
     fread(&b0,sizeof(char),1,fp_in);
	 sc=1;
	 c_register=b0<<16;
	 bytein();
	 c_register<<=7;
	 ct-=7;
	 a_register=0x8000;
	 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;
	 }

}

short CARITHCoding::Decoding_Pass(BYTE *image, short x_size, short y_size)
{
	 short n;
	 if(unpack1(4,&n,0)==-1) return -1;
	  while(n>=0)
	  {
		  if(Decodepass(image,n,x_size,y_size)==-1) 
		  return -1;
		  n--;
	  }

	 return 0;

}

short CARITHCoding::Decodepass(BYTE *image, short n, short x_size, short y_size)
{
	int Bit,i,j;
	short Sn;
	Bit=1<<n;
    for (i=0;i<x_size;i++)
	   for(j=0;j<y_size;j++)
	 {
		 if(unpack1(1,&Sn,0)==-1)
		 return -1;
		 if(Sn)
		 image[i*x_size+j]|=Bit;
	 }
	return 0;

}

void CARITHCoding::bytein()
{
  fread(&b1,sizeof(char),1,fp_in);
  sc++;
  if(b0==0xff){
	  if(b1>0x8f) {
		  c_register+=0xff00;
		  ct=8;
		}
	  else{
		  bp++;
		  c_register+=b1<<9;
		  ct=7;
	  }
	}
  else{
	  bp++;
	  c_register+=b1<<8;
	  ct=8;
	}
  b0=b1;


}

long CARITHCoding::unpack1(short bit_num, short *bit_value, short con)
{
	unsigned short i,d;
    unsigned long chigh;
	*bit_value=0;
	for(i=0;i<bit_num;i++) 
	{
	  chigh=c_register>>16;
	  a_register-=qe_value[index[con]];
	  if(chigh<qe_value[index[con]])
	  {
		if(a_register<qe_value[index[con]])
		{
	        a_register=qe_value[index[con]];
			d=mps[con];
			index[con]=nmps[index[con]];
		}
		else 
		{
		    a_register=qe_value[index[con]];
			d=1-mps[con];
			if(flag[index[con]]==1)  mps[con]=1-mps[con];
			index[con]=nlps[index[con]];
		 }
		do
		{
			if(ct==0)
			{
			   bytein();
			   if(sc>=BytesLimit) return -1;
			 }
			a_register<<=1;
			c_register<<=1;
			ct--;
		}
		while((a_register&0x8000)==0);
		}
	  else
	  {
		 chigh-=qe_value[index[con]];
		 c_register&=0xffff;
		 c_register+=chigh<<16;

		 if((a_register&0x8000)==0)
		 {
			if(a_register<qe_value[index[con]])
			{
			  d=1-mps[con];
			  if(flag[index[con]]==1) mps[con]=1-mps[con];
			  index[con]=nlps[index[con]];
			}
			else
			{
				  d=mps[con];
				  index[con]=nmps[index[con]];
			}
		  do{
			  if(ct==0)
			  {
			    bytein();
			    if(sc>=BytesLimit) return -1;
			  }
			  a_register<<=1;
			  c_register<<=1;
			  ct--;
			  }
		  while((a_register&0x8000)==0);
		}
	  else d=mps[con];
	 }
	*bit_value+=(short)(d<<i);
	}
     return 0;

}

BYTE* CARITHCoding::AC_decode(short x_size, short y_size)
{
	 BYTE *image;
	  short i,j,mark;
	  BytesLimit=(long)(x_size*y_size);            
	  image=(BYTE *)new BYTE [x_size*y_size];
	  Init_AC_QM_Decoder();
	  for(i=0;i<x_size;++i)
		for(j=0;j<y_size;++j)
			image[i*x_size+j]=0;
	  mark=Decoding_Pass(image,x_size,y_size);
	  if(mark==-1) 
	  goto END;
END:
	  for(i=0;i<y_size;i++)
	  {
	    	fwrite(&image[i*x_size],sizeof(unsigned char),y_size,fp_out);
	  }
	fclose(fp_out);
	fclose(fp_in);
    return image;

}

⌨️ 快捷键说明

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