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

📄 advancejpeg-lscode.cpp

📁 改进的JPEG-LS算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				else
//		c.	If R='0' then 
				{
//			i)	Read J[RUNindex] bits from the bit stream and fill the image with
//				the value Ra for as many samples as the number formed by these
//				bits (MSB first).
					R=GetFromBitStream(J[RUNindex]);
					RUNcnt+=R;
					if(R>0)
					{//此域编码是非行尾情况
						for(i=0;i<R;i++)
						{
							lpCurrentLine[x]=Rx=RUNval;
							SetNextSample();
							Px=RUNval=RunPredicate();
						}
					}
					if(RUNindex>0)RUNindex--;
					if(EOLine==TRUE)EOLine=FALSE;//可能存在达最后一个象素的情况(行尾标志被设置)
//			ii)	If RUNindex>0 decrement RUNindex by one.
					break;
				}
			}
			ResetContext(x);
			if(EOLine==TRUE&&RUNcnt!=0)
			{
				if(RUNcnt>1&&TestErrorMeLimen>0)AppendRunDecode(X-RUNcnt,RUNcnt);
				continue;
			}
			if(RUNcnt>1&&TestErrorMeLimen>0)
			{
				AppendRunDecode(x-RUNcnt,RUNcnt);
			}

//Run interruption sample encoding: perform the operations in A.7.2
//1.	Compute the index RItype, which defines the context, as indicated in Figure A.17.

			i=Ra-Rb;
			if(i<=qNEAR&&i>=(-qNEAR))RItype=1;//index for run interruption coding
			else RItype=0;

//2.	Compute the prediction error, as indicated in Figure A.18

			ResetContext(x);
			if(RItype==0)TEMP=A[365];
			else TEMP=A[366]+(N[366]>>1);

			Q=RItype+365;//取值:1 or 0
			for(K=0;(N[Q]<<K)<TEMP;K++);
			
			glimit=LIMIT-J[RUNindex]-1;
			j=ReturnZeroBitNumber();
			if(j<(glimit-qbpp-1))
			{
				CodeBitcp+=j;//加上j个0
				GetFromBitStream(1);
				EMErrval=GetFromBitStream(K);
				EMErrval+=(j<<K);
			}
			else
			{
				CodeBitcp+=j;//加上j个0
				GetFromBitStream(1);
				EMErrval=GetFromBitStream(qbpp)+1;
			}

			if(RItype==1)//从EMErrval的奇偶求map
			{
				if(EMErrval&1)map=0;
				else map=1;
			}
			else
			{
				if(EMErrval&1)map=1;
				else map=0;
			}
			Errval=(EMErrval+RItype+map)/2;//是绝对值

			if(map==0)
			{
				if(K!=0||(2*Nn[Q-365])>=N[Q]);//Errval>=0
				else Errval=-Errval;//Errval<=0
			}
			else
			{
				if(K!=0||(2*Nn[Q-365])>=N[Q])Errval=-Errval;//Errval<0
			}

			if(Errval<0)Nn[Q-365]++;

			A[Q]+=((EMErrval+1-RItype)>>1);

			if(N[Q]==RESET)
			{
				A[Q]>>=1;
				N[Q]>>=1;
				Nn[Q-365]>>=1;
			}
			N[Q]++;

			if(RItype==0&&Ra>Rb)
			{
				SIGN=-1;
			}
			else SIGN=1;//SIGN在象素重建时有用
			Errval*=(SIGN*(qNEAR+qNEAR+1));

			Rx=Errval+Px;
			if(Rx<-qNEAR)
			{
				Rx+=(RANGE*(qNEAR+qNEAR+1));//用重建值的区间限制来识别对Error所作的取模操作
			}
			else if(Rx>(MAXVAL+qNEAR))
			{
				Rx-=(RANGE*(qNEAR+qNEAR+1));
			}

			if(Rx<0)Rx=0;
			else if(Rx>MAXVAL)Rx=MAXVAL;
			lpCurrentLine[x]=Rx;

//			iv)	Go to Step 17.
		}
	}
	//调节门限参数的优化
	if(AllTestNumber>20)
	{//由象素调节率,优化象素调节门限
		i=AdjustNumber/AllTestNumber;
		if(i>=55)
		{
			if(TestErrorMeLimen<=MaxMTestErrMeLimen(qNEAR))
			{//加大调节门限
				TestErrorMeLimen++;
				RunContext=SetRunContext[RunTestThresholdStep];
				DoubleMaxError=SetDoubleMaxError[RunTestThresholdStep];
			}
		}
		else if(i<=30)
		{//减小调节门限
			if(TestErrorMeLimen>MinMTestErrMeLimen(qNEAR)&&TestErrorMeLimen>1)
			{
				TestErrorMeLimen--;
				if(TestErrorMeLimen==0)
				{
					RunContext=qNEAR;
					DoubleMaxError=qNEAR;
				}
			}
		}
		if(AllTestNumber>0x10000)
		{
			AdjustNumber/=2;
			AllTestNumber/=2;
		}
	}
	int ii;
	if(DoubleErrN!=0)
	{
		DecodeDoubleError();//对每行游程编码中的象素大误差的符号译码,位置已在该行译码时产生。
		ii=0;
		if(DErrN>0)for(i=0;i<DoubleErrN;i++)
		{//修正当前象素
			if(lpDoubleErrList[i].Sign>=1)
			{
				lpDoubleErrList[ii++]=lpDoubleErrList[i];
				lpCurrentLine[lpDoubleErrList[i].PixSeat]+=MaxErrAdjust1;
				if(lpCurrentLine[lpDoubleErrList[i].PixSeat]<0)lpCurrentLine[lpDoubleErrList[i].PixSeat]=0;
				else if(lpCurrentLine[lpDoubleErrList[i].PixSeat]>MAXVAL)lpCurrentLine[lpDoubleErrList[i].PixSeat]=MAXVAL;
			}
			else if(lpDoubleErrList[i].Sign<=-1)
			{
				lpDoubleErrList[ii++]=lpDoubleErrList[i];
				lpCurrentLine[lpDoubleErrList[i].PixSeat]-=MaxErrAdjust1;
				if(lpCurrentLine[lpDoubleErrList[i].PixSeat]<0)lpCurrentLine[lpDoubleErrList[i].PixSeat]=0;
				else if(lpCurrentLine[lpDoubleErrList[i].PixSeat]>MAXVAL)lpCurrentLine[lpDoubleErrList[i].PixSeat]=MAXVAL;
			}
		}
		if((DErrN=ii)>0)
		{
			DecodeDDoubleError();//对每行游程编码中的象素大误差的符号译码,位置已在该行译码时产生。
			if(DDErrN>0)for(i=0;i<DErrN;i++)
			{//修正当前象素
				if(lpDoubleErrList[i].Sign>=2)
				{
					lpCurrentLine[lpDoubleErrList[i].PixSeat]+=MaxErrAdjust2;
					if(lpCurrentLine[lpDoubleErrList[i].PixSeat]<0)lpCurrentLine[lpDoubleErrList[i].PixSeat]=0;
					else if(lpCurrentLine[lpDoubleErrList[i].PixSeat]>MAXVAL)lpCurrentLine[lpDoubleErrList[i].PixSeat]=MAXVAL;
				}
				else if(lpDoubleErrList[i].Sign<=-2)
				{
					lpCurrentLine[lpDoubleErrList[i].PixSeat]-=MaxErrAdjust2;
					if(lpCurrentLine[lpDoubleErrList[i].PixSeat]<0)lpCurrentLine[lpDoubleErrList[i].PixSeat]=0;
					else if(lpCurrentLine[lpDoubleErrList[i].PixSeat]>MAXVAL)lpCurrentLine[lpDoubleErrList[i].PixSeat]=MAXVAL;
				}
			}
		}
	}
	DoubleErrN=0;
	DErrN=0;
	DDErrN=0;
	//构造重建图像
	int pp,pc,ppx;
	if(AllowBandPrediction==TRUE)
	{
		if(OpenOffBandPrediction==FALSE)
		{
			MoveMemory(lpReconstructCurrentLine,lpCurrentLine,X*sizeof(int));
		}
		else//重建时要考虑波段预测因素
		{
			for(i=0;i<X;i++)//在新起一行时将当前重建象素行保存到重建图像缓冲中
			{
				pp=lpPredictionBandCode->lpReconstructCurrentLine[i];
				if((ppx=(A_Mul*pp/UNIFORM_FLOAT_TO_INT_MUL+B_Add))>Pixel_ADD)ppx=pp;
				pc=lpCurrentLine[i]+ppx-Pixel_ADD;
				if(pc<0)pc=0;
				else if(pc>(MAXVAL>>2))pc=(MAXVAL>>2);
				lpReconstructCurrentLine[i]=pc;
			}
		}
		//更新预测系数与相关系数
		UpdateBandPrediction();
	}
	else
	{
		lpReconstructCurrentLine=lpCurrentLine;
	}
	//输出重建图像
	for(i=0;i<X;i++)
	{
		(*((int *)(lpImageBuf+OneSampleBytes*i)))=lpReconstructCurrentLine[i];
	}
	LineN++;//行计数
	return CodeBitcp-CompressBitcp;
}
int CAdvanceJepgLSOneLineCode::GetFromBitStream(int b)
{//在当前的码流位置上取出 b 比特,比特放入低位作为返回值。一般不能大24比特。
	if(b<=0)return 0;
	int a=0,i;
	for(i=b-1;i>=0;i--)
	{
		if(*(lpCodeStream+(CodeBitcp>>3))&(1<<(CodeBitcp&7)))a|=(1<<i);
		++CodeBitcp;
	}
	return a;
}
int CAdvanceJepgLSOneLineCode::ReturnZeroBitNumber()
{//在当前的码流位置上,检查连续'0'的个数。
	int a,i,j;
	a=(*((int *)(lpCodeStream+(CodeBitcp>>3)))>>(CodeBitcp&7))&0xffffff;
	if(a==0)
	{//说明"0"的个数大于24
		i=24;
		a=(*((int *)(lpCodeStream+(CodeBitcp>>3)+3))>>(CodeBitcp&7))&0xffffff;
		if(a==0)
		{//说明'0'的个数大于48.
			i+=24;
			a=(*((int *)(lpCodeStream+(CodeBitcp>>3)+6))>>(CodeBitcp&7))&0xffffff;
			for(j=1;(a&j)==0&&j<0x1000000;j<<=1,i++);//'0'的个数总应小于72
		}
		else for(j=1;(a&j)==0&&j<0x1000000;j<<=1,i++);//'0'的个数大于24并小于48时
	}
	else for(j=1,i=0;(a&j)==0&&j<0x1000000;j<<=1,i++);//"0"的个数小于24时
	return i;
}
void CAdvanceJepgLSOneLineCode::DecodeDoubleError()
{//一级大误差译码
	//先译大误差数DErrN,已知大误差象素数DoubleErrN,序列存放在lpDoubleErrList中
	int b,d,bit,bitn,RunL,N;
	//大误差数译码
	DErrN=lpDErrNumberFastCoding->OneDecodePass(DoubleErrN,lpCodeStream,CodeBitcp,bitn);
	CodeBitcp+=bitn;
	if(DErrN>0)
	{//存在大误差时,译码每个大误差对应的位置
		for(b=0,d=0,N=DoubleErrN;d<DErrN;d++)
		{//'b'当前序列译码位置,'d'译码大误差计数,'N'剩余象素数
			//译码当前非大误差游程长度
			RunL=lpDErrRunFastCoding->OneDecodePass(N,DErrN-d,lpCodeStream,CodeBitcp,bitn);//当前游程编码
			CodeBitcp+=bitn;
			//取出下一比特决定当前大误差的符号
			bit=GetFromBitStream(1);
			if(bit==1)
			{
				lpDoubleErrList[b+RunL].Sign=1;
			}
			else
			{
				lpDoubleErrList[b+RunL].Sign=-1;
			}
			b+=(RunL+1);//下一个游程编码的象素位置
			N=DoubleErrN-b;//余下的象素数
		}
	}
}
void CAdvanceJepgLSOneLineCode::DecodeDDoubleError()
{//二级大误差译码
	//先译二级大误差数DDErrN,已知一级大误差数DErrN,序列存放在lpDoubleErrList中
	int b,d,bitn,RunL,N;
	//二级大误差数译码
	DDErrN=lpDDErrNumberFastCoding->OneDecodePass(DErrN,lpCodeStream,CodeBitcp,bitn);
	CodeBitcp+=bitn;
	if(DDErrN>0)
	{//存在二级大误差时,译码每个大误差对应的位置
		for(b=0,d=0,N=DErrN;d<DDErrN;d++)
		{//'b'当前序列译码位置,'d'译码二级大误差计数,'N'剩余一级大误差数
			//译码当前非二级大误差游程长度
			RunL=lpDDErrRunFastCoding->OneDecodePass(N,DDErrN-d,lpCodeStream,CodeBitcp,bitn);//当前游程编码
			CodeBitcp+=bitn;
			lpDoubleErrList[b+RunL].Sign*=2;
			b+=(RunL+1);//下一个游程编码的象素位置
			N=DErrN-b;//余下的象素数
		}
	}
}
void CAdvanceJepgLSOneLineCode::AppendRunDecode(int Bgx,int Runl)
{
	int i,j,j1,k,RunB,RunL,d1l,d1r,d2l,d2r,d1,d2;
	int Me,AdjustWinL,WinL,*lpTwoAdjust,*lpAdjust,AdjustN,TwoAdjustN,Winn,AdjustRate;
	RunB=Bgx;RunL=Runl;
	BOOL Modify=FALSE,OpenTwoAdjust=FALSE,OpenAdjust=FALSE;
	if(RunL<=0)return;
	Modify=FALSE;
	if(RunL>=AdjustWinLength&&TestErrorMeLimen!=0)
	{
		Modify=TRUE;
		//求调节率
		if(AllTestNumber>20)
		{
			AdjustRate=AdjustNumber/AllTestNumber;
		}
		else AdjustRate=50;
		//计算调节窗长
		if(RunL<(AdjustWinLength*2))AdjustWinL=RunL;
		else if(RunL<(AdjustWinLength*4))AdjustWinL=RunL/2;
		else
		{
			if(RunL<(AdjustWinLength*12))AdjustWinL=AdjustWinLength*2;
			else AdjustWinL=AdjustWinLength*3;
			if(RunL>=AdjustWinL*8&&AdjustRate>10)
			{//在序列足够长并且调节率很低时启动两级调节
				OpenTwoAdjust=TRUE;
			}
			if(RunL>=AdjustWinL*8&&AdjustRate<30)
			{//在序列足够长并且调节率较低时启动游程编码
				OpenAdjust=TRUE;
			}
		}
		if(OpenTwoAdjust==TRUE)
		{
			lpTwoAdjust=new int[RunL/AdjustWinL+2];
			ZeroMemory(lpTwoAdjust,sizeof(int)*(RunL/AdjustWinL+2));
		}
		lpAdjust=new int[RunL/AdjustWinL+2];
		ZeroMemory(lpAdjust,sizeof(int)*(RunL/AdjustWinL+2));
		if(OpenAdjust==FALSE)
		{//不用游程编码时,直接从码流中取出比特作为调节状态
			for(i=0,AdjustN=0,Winn=0;i<RunL;Winn++)
			{
				if((RunL-i)<AdjustWinL*3/2)WinL=RunL-i;
				else WinL=AdjustWinL;
				if(GetFromBitStream(1)==1)
				{
					AdjustNumber+=100;
					AllTestNumber++;
					AdjustErrorMe=MAdjustErrMe(TestErrorMeLimen);
					Me=AdjustErrorMe;
					if(GetFromBitStream(1)==0)
					{
						Me=-Me;
					}
					lpAdjust[Winn]=Me;//设置相应单元的调节量
					AdjustN++;
				}
				else AllTestNumber++;
				i+=WinL;
			}
		}
		else
		{//采用游程编码时,先译码游程,取得调节单元的位置
			for(i=0,Winn=0;i<RunL;Winn++)
			{//计算单元数
				if((RunL-i)<AdjustWinL*3/2)WinL=RunL-i;
				else WinL=AdjustWinL;
				i+=WinL;
			}
			AdjustN=DecodeAdjust(lpAdjust,Winn);//译码调节状态
			for(i=0,Winn=0;i<RunL;Winn++)
			{//根据调节状态,对应单元的调节量
				if((RunL-i)<AdjustWinL*3/2)WinL=RunL-i;
				else WinL=AdjustWinL;
				if(lpAdjust[Winn])
				{
					AdjustNumber+=100;
					AllTestNumber++;
					lpAdjust[Winn]*=MAdjustErrMe(TestErrorMeLimen);
				}
				else AllTestNumber++;
				i+=WinL;
			}
		}
		if(OpenTwoAdjust==TRUE)
		{//二级调节允许时,译码二级调节状态
			if(AdjustN>0)
			{
				TwoAdjustN=DecodeTwoAdjust(lpTwoAdjust,AdjustN);
				if(TwoAdjustN>0)for(i=0,j=0;i<Winn;i++)
				{
					if(lpAdjust[i])
					{
						if(lpTwoAdjust[j++])
						{
							if(lpAdjust[i]>0)lpAdjust[i]=MAdjustErrMe2(TestErrorMeLimen);
							else lpAdjust[i]=-MAdjustErrMe2(TestErrorMeLimen);
						}
					}
				}
			}
			delete lpTwoAdjust;
		}
		for(i=0,AdjustN=0;i<RunL;AdjustN++)
		{//根据调节序列及调节量,对各单元的象素进行调节
			if((RunL-i)<AdjustWinL*3/2)WinL=RunL-i;
			else Win

⌨️ 快捷键说明

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