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

📄 jpeg-ls.cpp

📁 连续色调图像无损(近无损)压缩标准Jpeg_Ls源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//            ******************************************************************           
//            *                      JPEG-LS源程序清单                         *
//            ******************************************************************

//     ************ 
//     *包含库文件* 
//     ************ 

#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys\types.h>
#include <sys\timeb.h>
//     ************ 
//     *  宏定义  * 
//     ************ 
//RESET:  threshold value at which A,B,and N are halved
//NEAR:   difference bound for near-lossless coding
//MIN_C:  minimum allowed value of C[0..364],equal to -128
//MAX_C:  maximum allowed value of C[0..364],equal to 127
#define RESET 64
#define NEAR 0
#define MIN_C -128
#define MAX_C 127

//     ************************************
//     *           全局变量初始化         *    
//     ************************************ 
//MAXVAL:   maximum possible image sample value ove all component of a scan
//RUNindex: index for run mode order
//qbpp:     number of bits needed to represent a mapped error value
//bpp:      number of bits needed to represent MAXVAL,with a minimum of 2
//LIMIT:    the value of glimit for a sample encoded in regular mode
//Q:        context determined from Q1,Q2,Q3
//RANGE:    range of prediction error representation
//A[0..366]:367 counters for the accumulated preditection error magnitude
//B[0..364]:365 counters for computing the bias
//C[0..364]:365 counters storing prediction coreection values
//J[0..31]: 32 variables indicating order of run-length codes
//N[0..366]:367 counters for frequency of occurrence of each context
//Nn[365..366]:2 counters for negative prediction error for run interruption
//EOLine:   end of line indicator,used in run mode 
//Errval:   prediction error
//EMErrval: Errval mapped to non-negative integers in run interruption mode
//MErrval:  Errval mapped to non-negative integers in regular mode
//--------------------------------------------------------------------------------
//    LinX:当前行号
//    RowX:当前列号
//    *f:指向码流的指针
//    *fp:文件指针   
//    counter:计算编码文件长度
//    output:编码的数值
//    cnt:当前码流的长度
//    code:当前码流的数值
//    pp:前一码流的长度    
    int MAXVAL=0; 
    unsigned long  output=0;//输出码流
    static int cnt=0,code=0,pp=0;//计数器
	int LinX=1,RowX=1; //当前点的行列值
	static int RUNindex=0; 
	int qbpp,bpp,*f;
	static int B[365],C[365];
	int LIMIT,Q,RANGE;
	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};
	int A[367],N[367];
	int Nn[2]={0};
	int EOLine=0;
	long int counter=0;
	FILE *fp;
//     **********************************
//     *      计算T1,T2,T3值的子程序    *
//     **********************************	
	float CLAMP_1(float i)
	{
	if(i>MAXVAL||i<NEAR+1)
		return(NEAR+1);
	else
		return(i);
	}
    float CLAMP_2(float i,float T1)
	{
	if(i>MAXVAL||i<T1)
		return(T1);
	else
		return(i);
	}
   float CLAMP_3(float i,float T2)
   {
	if(i>MAXVAL||i<T2)
		return(T2);
	else
		return(i);
   }	
//     ******************************	
//     *  求算术编码的长度的子程序  *
//     ******************************
  int LG(int Q)
		{
	     int i;		
	     for(i=0;(N[Q]<<i)<A[Q];i++);
	     return(i);
		}
//      ******************************
//      *      规整Errval的值        *
//      ****************************** 
  int ModRange(int a)
  {
	  if(a<((0-RANGE)/2))
		 a=a+RANGE;
	  if(a>=((1+RANGE)/2))
		  a=a-RANGE;
	  return(a);
  }
//        **************************************
//        *         写码流的子程序             *
//        **************************************
  void 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所指的文件中*/
					counter++;
					*code=0;
					*cnt=*cnt-8;
					
					} 
				else        
					{
					*code=(*code<<(8-*pp))+(255&(*output>>(*cnt-8)));
					fwrite(code,1,1,fp);
					counter++;
					*code=0;
					*cnt=*cnt-8;
					}
			}
            c=~(~0<<*cnt);
			*code=c&(*output);
		}
  }
//          ****************************************     
//          *        常规编码过程的子程序          *
//          ****************************************  
  void  RegularModeProcessing(int y,int Ra,int Rb,int Rc,int Rd,int Ix,int D1,int D2,int D3,float T1,float T2,float T3)
	{
//       ********************
//       *  当地梯度的量化  *
//       ********************
		int Di[4]={0,D1,D2,D3};
		int Qi[4],Errval,MErrval;
		int i,k,SIGN,Rx,Px;
        unsigned interim;
		output=0;
		
	
			for(i=1;i<4;i++)
		{
			if(Di[i]<=-T3)      Qi[i]=-4;
			else if(Di[i]<=-T2) Qi[i]=-3;
			else if(Di[i]<=-T1) Qi[i]=-2;
			else if(Di[i]<-NEAR)Qi[i]=-1;
			else if(Di[i]<=NEAR)Qi[i]=0;
			else if(Di[i]<T1)   Qi[i]=1;
			else if(Di[i]<T2)   Qi[i]=2;
			else if(Di[i]<T3)   Qi[i]=3;
			else Qi[i]=4;
		}
//         ********************************************** 
//         *  完成从矢量(Q1,Q2,Q3)到Q的一一对应的映射  *
//         **********************************************
		    if((Qi[1]<0)||((Qi[1]==0)&&(Qi[2]<0))||(((Qi[1]==0)&&(Qi[2]==0))&&(Qi[3]<0)))
			SIGN=-1;
			else     SIGN=1;
			if(SIGN==-1)
			{  
				for(i=1;i<4;i++)
			        Qi[i]=Qi[i]*SIGN;
			}
			Q=(Qi[1]*9+Qi[2])*9+Qi[3];/*人为设定*/
//          ***************************** 			 
//          *    计算Px的值(预测)     *
//          *****************************			
	if(Rc>=__max(Ra,Rb))
		Px=__min(Ra,Rb);
	else{
		if(Rc<=__min(Ra,Rb))
			Px=__max(Ra,Rb);
		else
			Px=Ra+Rb-Rc;
	}/*边缘检测*/
/*		if(Rc<=__max(Ra,Rb)){
				if(Rc<=__min(Ra,Rb)){
					if((10<=(Rd-Rb))&&(abs(Ra-Rb))<=10&&(__min(Ra,Rb)-Rc)>=5&&(Rd-Rb)<=50)
						Px=Rd/2+__max(Ra,Rb)/2;
					else 
						Px=__max(Ra,Rb);}
				else
					Px=Ra+Rb-Rc;}
			else{
				if(Rc-Ra>=10&&Rd<Rb&&Ra-Rb<=5)
					Px=Rd/2+__min(Ra,Rb)/2;
				else 
					Px=__min(Ra,Rb);
			}	*/	
	if(SIGN==1)
		Px=Px+C[Q];
	else
		Px=Px-C[Q];
//       **********************************	
//       *  将Px规整到(0..MAXVAL)的范围  *
//       **********************************
	if(Px>MAXVAL)
		Px=MAXVAL;
	else if(Px<0) 
		Px=0;/*预测修正*/
//       ******************** 	
//       *    计算Errval    *
//       ********************
   	Errval=Ix-Px;

	if(SIGN==-1)
		Errval=-Errval;

	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;
    *(f+LinX*(y+2)+RowX)=Rx;/*用重建值代替实际值*/
//        ******************************************************	
//        *   将Errval规整到[-(RANGE-1)/2..+RANGE/2)的范围     *
//        ******************************************************
	Errval=ModRange(Errval);
//        ***********************************	
//        *    将Errval映射到MErrval        *
//        *********************************** 
	k=LG(Q);
	if((NEAR==0)&&(k==0)&&(2*B[Q]<=-N[Q]))
	{
		if(Errval>=0)
			MErrval=2*Errval+1;
		else
			MErrval=-2*(Errval+1);
	}
	else{
		if(Errval>=0)
			MErrval=2*Errval;
		else
			MErrval=-2*Errval-1;
	}
//        **********************************	
//        *      对MErrval进行编码         *
//        **********************************
	    interim=MErrval;
		interim=interim>>k;/*除最低k位以外的高位*/
		if(interim<((unsigned)(LIMIT-qbpp-1)))
		{
			unsigned b,c;
 			c=~(~0<<k);
			b=c&MErrval;/*截取MErrval的最低k位*/
			output=(output<<(interim+1))+1;/*左移interim+1得到interim+1个零,加一后即interim个零接一个1*/
   			output=output<<k;
			output=output+b;
//         *******************************   
//         *     向二进制文件写码流      *
//         *******************************			
		    pp=cnt;
			cnt=cnt+interim+1+k; 		
            writecode(&cnt,&pp,&output,&code);
			
		}
		else
		{
			unsigned b,c;
			output=(output<<(LIMIT-qbpp))+1;/*当前码流为:LIMIT-qbpp-1个零,一个1*/
			output=output<<qbpp;/*后接qbpp位的数字*/
			c=~(~0<<qbpp);
			b=c&(MErrval-1);/*取MErrval-1的后qbpp位*/
			output=output+b;
	        pp=cnt;
			cnt=cnt+LIMIT; 		
            writecode(&cnt,&pp,&output,&code);

		}
//      *********************************		
//      *        更新各个变量           *
//      *********************************		
		B[Q]=B[Q]+Errval*(2*NEAR+1);
		A[Q]=A[Q]+abs(Errval);
		if(N[Q]==RESET)
		{
			A[Q]=A[Q]>>1;
			B[Q]=B[Q]>>1;
			N[Q]=N[Q]>>1;
		}
		N[Q]=N[Q]+1;/*N[Q]指此种上下文出现的次数,最多为64次*/
//		Nt[Q]=Nt[Q]+1;
		if(B[Q]<=-N[Q]){
			B[Q]=B[Q]+N[Q];
			if(C[Q]>MIN_C)
				C[Q]=C[Q]-1;
			if(B[Q]<=-N[Q])
				B[Q]=-N[Q]+1;
		}

⌨️ 快捷键说明

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