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

📄 jpeg-ls.cpp

📁 连续色调图像无损(近无损)压缩标准Jpeg_Ls源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		else if(B[Q]>0){
			B[Q]=B[Q]-N[Q];
			if(C[Q]<MAX_C)
				C[Q]=C[Q]+1;
			if(B[Q]>0)
				B[Q]=0;
		}
				}
//              **********************************
//              *      游程编码子程序的定义      *
//              **********************************
    void 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;
        AQ=A[Q];/*将当前A[Q]暂存,借用完LG(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;
   }

	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
//                  *************************************************
//                  *                    主程序                     *
//                  *************************************************

//     i,j:循环变量计数;
//	   _______________________
//     |   | Rc| Rb| Rd|   |
//     -----------------------           
//	   |   | Ra| Ix|   |   |
//	   -----------------------	
//     D1,D2,D3:当前梯度
//     x,y:图像的高度和宽度

void main()
{
	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;
 	printf("图象高度和宽度\n");
	scanf("%d,%d",&x,&y);
	ftime(&start_time);
	f=(int *)calloc((x+1)*(y+2),sizeof(int)); /*补零后的图像多两列,一行*/
 //  if((fp=fopen("E:\\felicia\\adata7.raw","rb"))==NULL)
    if((fp=fopen("e:\\felicia\\LENA128.RAW","rb"))==NULL)
	   {	  
		 printf("Error opening %s","e:\\felicia\\TU1.raw");
		 exit(0);
	   }
//            *********************************
//            *       计算各参数的值          *
//            *********************************	
	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);/*先求实际最大值*/
			
		}

		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;/*第一行及第二行第一个全为零*/
        
    fp=fopen("E:\\felicia\\Adata2","wb");
//    ************************	
//    *      读入变量        *
//    ************************
	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 0
	printf("出现Errval小于零%d次\n",z);
#endif
	if(cnt>0)
		code=code<<(8-cnt);
    fwrite(&code,1,1,fp);
	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);
//     ***************************
//     *      图像原始数据       *
//     ***************************
	fp=fopen("E:\\felicia\\Adata4.dat","w");
    for( i=0;i<=x;i++){
	    for(j=0;j<=y+1;j++)
			fprintf(fp,"%5d",*(f+i*(y+2)+j));
	        fprintf(fp,"\n");
	}
	fclose(fp);
/*	fp=fopen("E:\\felicia\\Adata6.dat","w");
    for(j=0;j<=y+1;j++){
	    for(i=0;i<=x;i++)
			fprintf(fp,"%5d",*(f+j*(x+1)+i));
	        fprintf(fp,"\n");
	}
	fclose(fp);*/
//	fp=fopen("E:\\felicia\\Adata5.dat","w");
//  for( i=0;i<=364;i++){
	   
//			fprintf(fp,"%5d\n",Nt[i]);
//	       	}
//	fclose(fp);
} 

⌨️ 快捷键说明

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