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

📄 jpeg_ls.cpp

📁 图像无损压缩 TI常用例程 希望能对大家有所帮助
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// JPEG_LS.cpp: implementation of the JPEG_LS class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HIC.h"
#include "JPEG_LS.h"
#include "math.h"
#include <time.h>
#include <sys\types.h>
#include <sys\timeb.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define RESET 64
#define NEAR 0
#define MIN_C -1000
#define MAX_C 20000



int	J[32]={0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,7,8,9,10,11,12,13,14,15};


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

JPEG_LS::JPEG_LS()
{
	
 
}

JPEG_LS::~JPEG_LS()
{

}





int JPEG_LS::LG(int Q)
{
	int i;		
	for(i=0;(N[Q]<<i)<A[Q];i++);
	return(i);

}

float JPEG_LS::CLAMP_1(float i)
{
	if(i>MAXVAL||i<NEAR+1)
		return(NEAR+1);
	else
		return(i);

}

float JPEG_LS::CLAMP_2(float i, float T1)
{
		if(i>MAXVAL||i<T1)
		return(T1);
	else
		return(i);

}

float JPEG_LS::CLAMP_3(float i, float T2)
{
		if(i>MAXVAL||i<T2)
		return(T2);
	else
		return(i);

}

void JPEG_LS::JPEG_LSCompress()
{
	int i,j,Ra,Rb,Rc,Rd,Ix,D1,D2,D3;
	int x,y;
    int BASIC_T1=3,BASIC_T2=7,BASIC_T3=21;
	float T1,T2,T3;
	struct timeb start_time,end_time;
	int second_d;
   	x=256;y=256;
	CT=0;

	Initial();

 	ftime(&start_time);
	f=(int *)calloc((x+1)*(y+2),sizeof(int)); /*补零后的图像多两列,一行*/
    if((fp=fopen("E:\\girl256.raw","rb"))==NULL)
	{	  
	 	AfxMessageBox("Can not Open File!");
	    return;
	}

//  计算各参数的值 
	for(i=1;i<=x;i++)
		for(j=1;j<=y;j++)
		{
			fread(f+i*(y+2)+j,1,1,fp);/*前面空一行,以作重建值。从第二行写起。此时补的行还是零,到后面预测时补入Rb等。*/
            if(*(f+i*(y+2)+j)>MAXVAL)
				MAXVAL=*(f+i*(y+2)+j);/*先求实际最大值*/
		}
		fclose(fp);
	
		for(i=0;(1<<i)<=MAXVAL;i++);
		MAXVAL=(1<<i)-1;/*规整到2的n次方故取大于实际MAXVAL的最小2的n次方*/
	    RANGE=((int)((MAXVAL+2*NEAR)/(2*NEAR+1)))+1;
        qbpp=-(int)(floor(-log(RANGE)/log(2.0)));
	    bpp=__max(2,-(int)(floor(-log(MAXVAL+1)/log(2.0))));
        LIMIT=2*(bpp+__max(8,bpp));	
	    if(MAXVAL>=128){
		T1=CLAMP_1((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T1-2)+2+3*NEAR);
        T2=CLAMP_2((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T2-3)+3+5*NEAR,T1);
        T3=CLAMP_3((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T3-4)+4+7*NEAR,T2);}
		else{
			T1=CLAMP_1((float)__max(2,BASIC_T1/(int)(256/(MAXVAL+1))+3*NEAR));
			T2=CLAMP_2((float)__max(3,BASIC_T2/(int)(256/(MAXVAL+1))+5*NEAR),T1);
            T3=CLAMP_3((float)__max(4,BASIC_T3/(int)(256/(MAXVAL+1))+7*NEAR),T2);
		}		
 
// 对各数组的初始化  
   for(j=0;j<365;j++)
	{
		A[j]=__max(2,(RANGE+(1<<5))/(1<<6));         
		N[j]=1;
		B[j]=0;
		C[j]=0;
	}
	A[365]=A[0];
	A[366]=A[0];
	N[365]=1;
	N[366]=1;
	
	for(i=0;i<y+3;i++)
		*(f+i)=0;/*第一行及第二行第一个全为零*/
        
    if((fp=fopen("E:\\girl.raw","wb"))==NULL)
	{	  
	 	AfxMessageBox("Can not Open File!");
	    return;
	}


	while(RowX<=y&&LinX<=x)/*到计算时间之前为大循环,一个一个象素处理*/
	{   
    Ra=(*(f+LinX*(y+2)+RowX-1));
	Rb=(*(f+(LinX-1)*(y+2)+RowX));
    Rc=(*(f+(LinX-1)*(y+2)+RowX-1));
	Rd=(*(f+(LinX-1)*(y+2)+RowX+1));
	Ix=(*(f+LinX*(y+2)+RowX));
    D1=Rd-Rb;
	D2=Rb-Rc;
	D3=Rc-Ra;

 // 选择编码方式       
	if((abs(D1)<=NEAR)&&(abs(D2)<=NEAR)&&(abs(D3)<=NEAR))
		RunModeProcessing(x,y,Ra,Rb,Rc,Rd,Ix);
    	else
		RegularModeProcessing(y,Ra,Rb,Rc,Rd,Ix,D1,D2,D3,T1,T2,T3);
	    RowX++;
		if(RowX==y)/*原图像一行的结尾(是补零后的倒数第二个象素)*/
      	{
		*(f+(LinX+1)*(y+2))=*(f+LinX*(y+2)+1);/*处理下一行的第一个象素的上下文:将Rb赋给a*/
    	*(f+LinX*(y+2)+y+1)=*(f+LinX*(y+2)+y);/*处理当前行最后一个象素的上下文:将Rb赋给d*/
		 EOLine=1;
		}
		else
        EOLine=0;   
    	if(RowX>y)/*补零后的最后一个象素*/
		{
		RowX=RowX-y;/*也即rowx=1*/
		LinX++;
		}
	}

	if(cnt>0)
		code=code<<(8-cnt);
    fwrite(&code,1,1,fp);
	CT=CT+1;
	fclose(fp);
	ftime(&end_time);

// 计算编码时间   
	second_d=end_time.millitm-start_time.millitm;
	second_d=second_d+(end_time.time-start_time.time)*1000;
//	printf("The encoding costs:%.3f seconds.\n",(float)second_d/1000.0);

}

/***************************************************
   游程编码子程序的定义      
****************************************************/
void JPEG_LS::RunModeProcessing(int x, int y, int Ra, int Rb, int Rc, int Rd, int Ix)
{
       int cnt1=0;
		int RUNval=Ra;
		int RUNcnt=0,TEMP,RItype;
		int map,AQ,EMErrval,glimit,Errval,k,SIGN,Rx,Px;
        unsigned interim; 
        output=0;

//计算游程长度 
		while(abs(Ix-RUNval)<=NEAR)
		{
			RUNcnt=RUNcnt+1;
			Rx=RUNval;
		   	*(f+LinX*(y+2)+RowX)=Rx;
			if(EOLine==1)/*正好是最后一个,跳到长度编码*/
			   break;
			else{
			 RowX=RowX+1;
           if(RowX==y)
		   {
			  *(f+(LinX+1)*(y+2))=*(f+LinX*(y+2)+1);
			  *(f+LinX*(y+2)+y+1)=*(f+LinX*(y+2)+y);/*当前象素为本行最后一个时,对其Rd、下一行Ra赋值*/
	           EOLine=1;
		   }
            Rb=*(f+(LinX-1)*(y+2)+RowX);
	        Ix=*(f+LinX*(y+2)+RowX);
			}
		}

/*对游程长度进行编码并向二进制文件中写入码流*/
		while(RUNcnt>=(1<<J[RUNindex]))
		{			
			output=(output<<1)+1;
			cnt1++;
            RUNcnt=RUNcnt-(1<<J[RUNindex]);
            if(RUNindex<31)
				RUNindex=RUNindex+1;
		}/*当RUNlen小于整数值的rm时,跳出*/
		if(EOLine==0||(EOLine==1&&(abs(Ix-RUNval)>NEAR)))/*情况1:被不同象素中断*/
		{
		output=output<<1;
		cnt1++;
        output=(output<<(J[RUNindex]))+RUNcnt;/*之前已经写入最逼近RUNlen的rm段,再左移一个rm段后,加入剩RUNlen下的部分*/
		cnt1=cnt1+J[RUNindex];
		if(RUNindex>0)
			RUNindex--;
		}
		else if(RUNcnt>0)/*情况2:被行末尾中断*/
		{
			output=(output<<1)+1;
			cnt1++;
		}
	    pp=cnt;
		cnt=cnt+cnt1; 		
        writecode(&cnt,&pp,&output,&code);
	    if(EOLine==1&&(abs(Ix-RUNval)<=NEAR))
			return;/*由于行的末尾终止,可正常结束,跳出此次游程模式*/
		if(abs(Ra-Rb)<=NEAR)
			RItype=1;
		else
			RItype=0;
		if(RItype==1)
			Px=Ra;
		else
			Px=Rb;
		Errval=Ix-Px;    
        if((RItype==0)&&(Ra>Rb))
		{
	     Errval=-Errval;
	     SIGN=-1;
		}
        else		
			SIGN=1;
		if(NEAR>0){
		 if(Errval>0)
		   Errval=(Errval+NEAR)/(2*NEAR+1);
	     else
		   Errval=-(NEAR-Errval)/(2*NEAR+1);
	     Rx=Px+SIGN*Errval*(2*NEAR+1);
	        if(Rx<0)
		     Rx=0;
        	else if(Rx>MAXVAL)
				Rx=MAXVAL;
		}
		else
			Rx=Ix;
         *(f+LinX*(y+2)+RowX)=Rx;
        Errval=ModRange(Errval);
	    if(RItype==0)
		TEMP=A[365];
    	else
		TEMP=A[366]+(N[366]>>1);
	    Q=RItype+365;
		/*将当前A[Q]暂存,借用完LG(Q)后还可进行正常操作*/
        AQ=A[Q];	
	    A[Q]=TEMP;
		k=LG(Q);
	   
	   
		if((k==0)&&(Errval>0)&&(2*Nn[Q-365]<N[Q]))
			map=1;
		else if((Errval<0)&&(2*Nn[Q-365]>=N[Q]))
			map=1;
		else if((Errval<0)&&(k!=0))
			map=1;
		else 
			map=0;
        
	    EMErrval=2*abs(Errval)-RItype-map;/*游程中断编码*/
	    glimit=LIMIT-J[RUNindex]-1;
	    interim=EMErrval;
 		interim=interim>>k;
		if(interim<((unsigned)(glimit-qbpp-1)))
		{
			unsigned b,c;
			output=0;
			c=~(~0<<k);
			b=c&EMErrval;
   			output=(output<<(interim+1))+1;
   			output=output<<k;
			output=output+b;
            pp=cnt;
			cnt=cnt+interim+1+k; 		
            writecode(&cnt,&pp,&output,&code); 
		}
		else
		{
			unsigned b,c;
			output=0;
			output=(output<<(glimit-qbpp))+1;
			output=output<<qbpp;
			c=~(~0<<qbpp);
			b=c&(EMErrval-1);
			output=output+b;
            pp=cnt;
			cnt=cnt+glimit; 		
            writecode(&cnt,&pp,&output,&code);
		}
	
// 更新各个变量  
		if(Errval<0)
			Nn[Q-365]=Nn[Q-365]+1;
		A[Q]=AQ;
		A[Q]=A[Q]+((EMErrval+1-RItype)>>1);
		if(N[Q]==RESET)
		{
			A[Q]=A[Q]>>1;
			N[Q]=N[Q]>>1;
			Nn[Q-365]=Nn[Q-365]>>1;
		}
		N[Q]=N[Q]+1;
}

int JPEG_LS::ModRange(int a)
{
	 if(a<((0-RANGE)/2))
		 a=a+RANGE;
	  if(a>=((1+RANGE)/2))
		  a=a-RANGE;
	  return(a);

}

void JPEG_LS::writecode(int *cnt, int *pp, unsigned long *output, int *code)
{
	 unsigned long c;
	  if((*cnt)<8)
	*code=(*code<<(*cnt-*pp))+(*output);/*以1byte为单位处理。把之前的码流向前推当前码流的长度,加入当前输出的码流*/
	  else{
			while(*cnt>=8)
			{
				if(*cnt>32)/*以4byte为存储器最大值*/
					{
			 		*code=(*code<<(8-*pp));
					fwrite(code,1,1,fp);/*把code指向的1×1个字节输出到fp所指的文件中*/
					CT=CT+1;
					counter++;
					*code=0;
					*cnt=*cnt-8;
					
					} 
				else        
					{
					*code=(*code<<(8-*pp))+(255&(*output>>(*cnt-8)));
					fwrite(code,1,1,fp);
						CT=CT+1;
					counter++;
					*code=0;
					*cnt=*cnt-8;
					}
			}
            c=~(~0<<*cnt);
			*code=c&(*output);
		}

}

void JPEG_LS::RunModeProcessing(int qbpp, int Ra, int Rb, int y)
{
	 int decode1=0;
	 int cnt=0,i;
	 unsigned long j;
	 int RItype,TEMP,AQ,Errval,EMErrval,flag,map,SIGN,k,Px,Rx,Q;

//  从码流中恢复EMErrval   

	 if(size==0)
	 {   
	     fread(&buffer,1,1,fp);
		 decode=buffer;
   	     size=8;}/*以8bit为一个处理单位*/
         size--;
	 while((1&(decode>>size))==1)
		 {
			 size--;		     
			 i=0;
			 while(i<(1<<J[RUNindex]))/*写一个Ra*/
			 {
				 *(f+LinX*(y+2)+RowX)=Ra;
               
 				 RowX++;
				 if(RowX>y)
				 {
                     RowX--;
					 flag1=1;
				}
				 i++; 
				 if(flag1==1)
					 break;
       		 }
			 if((i==(1<<J[RUNindex]))&&RUNindex<31)
				 RUNindex++;
			 if(size<0&&flag1==0)
				 {
					 fread(&buffer,1,1,fp);
					 decode=buffer;
   				     size=7;
				 }/*一个单元处理完且游程仍未结束,处理下一个单元*/
			if(flag1==1)
				break;
				 
		 }
					//在已处理的位上置零
		         if(RowX==y&&flag1==1){/*情况1:在行末*/
                 if(size==-1)/*正好处理完一个单元且游程未结束*/
					 decode=0;/*处理器清零,完成游程解码*/
				 else/*对单元未处理完就已到行末*/
				 decode=(decode<<(32-size-1))>>(32-size-1);/*当被行末中断时,其剩下的rk位1前缀是1,所以也被前面的处理过size+1是未处理的,所以32-size-1表示在当前处理范围内已处理的。此操作表示将已处理的位置零*/
				 size=size+1;/*待处理的位数是size+1*/
                 flag1=0;
				 return;}/*游程解码结束*/
         if(size==0)/*情况2:非行末,正好一个单元的最后一个是不同象素*/
				decode2=0;
         else      
			   decode2=(decode<<(32-size))>>(32-size);/*剩下size个元素待处理*/
					/***对长度小于rm的分段码字的处理***/
		   if(J[RUNindex]<=size)/*当有剩余比特出现时,且在当前处理单元内*/
		   {
           output=(decode2>>(size-J[RUNindex]));/*将待处理的数据移至最右侧,即得到待处理的数据*/
		   if(J[RUNindex]==size)
			   decode=0;
		   else
		   decode=((decode<<(32-size+J[RUNindex]))>>(32-size+J[RUNindex]));/*将处理过的位置零*/
		   size=size-J[RUNindex];
		   }
		   else/*当前处理单元剩余的比特小于rk时*/
		   {
			   fread(&buffer,1,1,fp);
			   
			   if(J[RUNindex]-size<=8)/*rk在下一个处理单元之内*/
				   decode1=decode2<<(J[RUNindex]-size);/*加入下一个单元中剩下部分的空间*/
			   while(J[RUNindex]-size>8)
			   {
				   decode1=decode1+(decode2<<(J[RUNindex]-size))+(buffer<<(J[RUNindex]-size-8));/*读入后面几个单元中rk部分.注意这里的加并不表示长度相加,而是在同一原点上叠加*/
                   J[RUNindex]=J[RUNindex]-8;
				   fread(&buffer,1,1,fp);
				   decode2=0;
			   }
			   output=decode1+(buffer>>(8+size-J[RUNindex]));/*右边第二项是当rk-size<8时,得到当前单元的剩余的rk,以接到n个满单元之后*/
			   if(J[RUNindex]-size==8)
				   decode=0;
			   else
			       decode=(buffer<<(32-8+J[RUNindex]-size))>>(32-8+J[RUNindex]-size);/*对前面已经处理过的(n个满单元及当前单元剩余rk)位置零*/
			       size=8-J[RUNindex]+size;

⌨️ 快捷键说明

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