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

📄 advancejpeg-lscode.cpp

📁 改进的JPEG-LS算法
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			
			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(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)//可能产生大误差象素数
	{
		EncodeDoubleError();//对每行游程编码中的象素大误差的符号编码。
		ii=0;//用于二级大误差可能象素的计数
		if(DErrN>0)for(i=0;i<DoubleErrN;i++)
		{//修正当前象素
			j=lpDoubleErrList[i].PixSeat;//大误差的位置
			if(lpDoubleErrList[i].Sign>=1)
			{//正向大误差时
				lpDoubleErrList[ii++]=lpDoubleErrList[i];//作为二级大误差可能的象素
				lpCurrentLine[j]+=MaxErrAdjust1;
				if(lpCurrentLine[j]<0)lpCurrentLine[j]=0;
				else if(lpCurrentLine[j]>MAXVAL)lpCurrentLine[j]=MAXVAL;
			}
			else if(lpDoubleErrList[i].Sign<=-1)
			{
				lpDoubleErrList[ii++]=lpDoubleErrList[i];
				lpCurrentLine[j]-=MaxErrAdjust1;
				if(lpCurrentLine[j]<0)lpCurrentLine[j]=0;
				else if(lpCurrentLine[j]>MAXVAL)lpCurrentLine[j]=MAXVAL;
			}
		}
		if((DErrN=ii)>0)
		{
			EncodeDDoubleError();//对每行游程编码中的象素大误差的符号编码。
			if(DDErrN>0)for(i=0;i<DErrN;i++)
			{//修正当前象素
				j=lpDoubleErrList[i].PixSeat;
				if(lpDoubleErrList[i].Sign>=2)
				{
					lpCurrentLine[j]+=MaxErrAdjust2;
					if(lpCurrentLine[j]<0)lpCurrentLine[j]=0;
					else if(lpCurrentLine[j]>MAXVAL)lpCurrentLine[j]=MAXVAL;
				}
				else if(lpDoubleErrList[i].Sign<=-2)
				{
					lpCurrentLine[j]-=MaxErrAdjust2;
					if(lpCurrentLine[j]<0)lpCurrentLine[j]=0;
					else if(lpCurrentLine[j]>MAXVAL)lpCurrentLine[j]=MAXVAL;
				}
			}
		}
		DoubleErrN=0;
		DErrN=0;
		DDErrN=0;
	}
	//构造重建图像
	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;
	}
	if(lpErrorMse!=NULL)
	{
		*lpErrorMse=0;
		for(i=0;i<X;i++)
		{
			lpImage[i]=(*((int *)(lpImageBuf+OneSampleBytes*i)))&AndCode;
			j=lpImage[i]-lpReconstructCurrentLine[i];
			*lpErrorMse+=j*j;
		}
	}
	LineN++;//行计数
	return CodeBitcp-CompressBitcp;
}
void CAdvanceJepgLSOneLineCode::ResetContext(int Seat)
{
	if(Seat>=2)
	{
		Raa=lpCurrentLine[Seat-2];
		Ra=lpCurrentLine[Seat-1];
		Rc=lpPrecedingLine[Seat-1];
	}
	else if(Seat>=1)
	{
		Rc=lpPrecedingLine[Seat-1];
		Ra=lpCurrentLine[Seat-1];
		Raa=lpPrecedingLine[Seat-1];
	}
	else
	{
		Rc=lpThirdLine[0];
		Raa=Ra=lpPrecedingLine[0];
	}
	Rb=lpPrecedingLine[Seat];
	if(x<X-1)Rd=lpPrecedingLine[Seat+1];
	else Rd=lpPrecedingLine[X-1];
}
int CAdvanceJepgLSOneLineCode::RunPredicate()
{
	int D_up_down,D_left_right,Sv,Sh;
//由梯度决定预测的两参量的分配
	if((D_up_down=((Rb-lpThirdLine[x])*3+Ra-Rc)/4)<0)D_up_down=-D_up_down;
	if((D_left_right=((Ra-Raa)*3+Rb-Rc)/4)<0)D_left_right=-D_left_right;
	D_left_right+=2;
	D_up_down+=2;
	Sv=Rb-lpThirdLine[x];
	Sh=Ra-Raa;
	Px=((Rb-Sv/4)*D_left_right+(Ra-Sh/4)*D_up_down)/(D_left_right+D_up_down);

	if(Px<0)Px=0;
	else if(Px>MAXVAL)Px=MAXVAL;
	return Px;
}
void CAdvanceJepgLSOneLineCode::AppendRunEncode(int Bgx,int Runl)
{
	int i,ii,j,n,j1,k,RunB,RunL,d1l,d1r,d2l,d2r,d1,d2,Winn;
	int Me,IIx,err,AdjustWinL,WinL,AdjustN,TwoAdjustN,*lpTwoAdjust,*lpAdjust,AdjustRate;
	BOOL Modify=FALSE,OpenTwoAdjust=FALSE,OpenAdjust=FALSE;
	RunB=Bgx;RunL=Runl;

	if(RunL<=0)return;//游程不是正数时不动作
	Modify=FALSE;//置修改标志为否
	if(RunL>=AdjustWinLength&&TestErrorMeLimen!=0)
	{//可以调节
		Modify=TRUE;
		if(AllTestNumber>20)
		{//调节率的计算是AdjustNumber比实际数大100倍.
			AdjustRate=AdjustNumber/AllTestNumber;
		}
		else AdjustRate=50;
		//计算调节窗长
		if(RunL<(AdjustWinLength*2))AdjustWinL=RunL;//2倍窗长以下时,取序列长
		else if(RunL<(AdjustWinLength*4))AdjustWinL=RunL/2;//4倍窗长以下时取半序列长
		else //4倍以上窗长时
		{
			if(RunL<(AdjustWinLength*12))AdjustWinL=AdjustWinLength*2;//12倍以下窗长取2倍
			else AdjustWinL=AdjustWinLength*3;//12倍以上取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));
		for(i=0,AdjustN=0,Winn=0,TwoAdjustN=0;i<RunL;Winn++)
		{//调节序列的检测
			if((RunL-i)<AdjustWinL*3/2)WinL=RunL-i;//剩余象素数不足窗长的3/2时,最后一段窗口取序剩余列长
			else WinL=AdjustWinL;
			for(j=0,Me=0,n=0;j<WinL;j++)
			{
				err=lpImage[RunB+i+j]-lpCurrentLine[RunB+i+j];
				if(err<=qNEAR&&err>=-qNEAR)
				{
					Me+=err;
				}
				else 
				{//大误差时要限制其在均值中的作用
					if(err>0)Me+=(qNEAR/2+(err-qNEAR/2)/3);
					else Me-=(qNEAR/2-(qNEAR/2+err)/3);
				}
				n++;
			}
			if(n>3)Me/=n;
			else Me=0;
			if(Me>TestErrorMeLimen)
			{//作正向调节
				lpAdjust[Winn]=1;//保存的是调节状态
				if(OpenAdjust==FALSE)AppendToBitStream(0x1,1);//直接变成比特输出
				if(OpenTwoAdjust==TRUE)
				{//二级编码时
					if(Me<(TestErrorMeLimen+MAdjustErrMe(TestErrorMeLimen)))
					{
						AdjustErrorMe=MAdjustErrMe(TestErrorMeLimen);
					}
					else
					{
						AdjustErrorMe=MAdjustErrMe2(TestErrorMeLimen);
						lpTwoAdjust[AdjustN]=1;//状态由一级调节数索引
						TwoAdjustN++;//二级调节数累加
					}
				}
				else AdjustErrorMe=MAdjustErrMe(TestErrorMeLimen);
				AdjustN++;
				if(OpenAdjust==FALSE)AppendToBitStream(0x1,1);//直接编码时输出符号
				AdjustNumber+=100;//调节次数,按100倍累计
				AllTestNumber++;
				Me=AdjustErrorMe;
				for(j=0;j<WinL;j++)
				{//窗内调节
						k=lpCurrentLine[RunB+i+j]+Me;
						if(k<0)k=0;
						else if(k>MAXVAL)k=MAXVAL;
						lpCurrentLine[RunB+i+j]=k;
				}
				if(Winn>0&&lpAdjust[Winn-1]==0&&TestErrorMeLimen>=3)
				{//当前窗被调节时,如果前面的窗口未被调节,而且,检测门限大于等于3,
				// 则前面未调节的窗口按检测门限的1/3调节.
					Me=TestErrorMeLimen/3;
					for(j=0;j<AdjustWinL;j++)
					{
						k=lpCurrentLine[RunB+i+j-AdjustWinL]+Me;
						if(k<0)k=0;
						else if(k>MAXVAL)k=MAXVAL;
						lpCurrentLine[RunB+i+j-AdjustWinL]=k;
					}
				}
			}
			else if(Me<-TestErrorMeLimen)
			{//作负向调节
				lpAdjust[Winn]=-1;//该序列中含有符号信息
				if(OpenAdjust==FALSE)AppendToBitStream(0x1,1);
				if(OpenTwoAdjust==TRUE)
				{
					if(Me>-(TestErrorMeLimen+MAdjustErrMe(TestErrorMeLimen)))
					{
						AdjustErrorMe=MAdjustErrMe(TestErrorMeLimen);
					}
					else
					{
						AdjustErrorMe=MAdjustErrMe2(TestErrorMeLimen);
						lpTwoAdjust[AdjustN]=1;TwoAdjustN++;
					}
				}
				else AdjustErrorMe=MAdjustErrMe(TestErrorMeLimen);
				AdjustN++;
				if(OpenAdjust==FALSE)AppendToBitStream(0x0,1);
				AdjustNumber+=100;
				AllTestNumber++;
				Me=-AdjustErrorMe;
				for(j=0;j<WinL;j++)
				{
						k=lpCurrentLine[RunB+i+j]+Me;
						if(k<0)k=0;
						else if(k>MAXVAL)k=MAXVAL;
						lpCurrentLine[RunB+i+j]=k;
				}
				if(Winn>0&&lpAdjust[Winn-1]==0&&TestErrorMeLimen>=3)
				{
					Me=-TestErrorMeLimen/3;
					for(j=0;j<AdjustWinL;j++)
					{
						k=lpCurrentLine[RunB+i+j-AdjustWinL]+Me;
						if(k<0)k=0;
						else if(k>MAXVAL)k=MAXVAL;
						lpCurrentLine[RunB+i+j-AdjustWinL]=k;
					}
				}
			}
			else 
			{//不调节
				AllTestNumber++;
				if(OpenAdjust==FALSE)AppendToBitStream(0,1);
				if(Winn>0&&lpAdjust[Winn-1]!=0&&TestErrorMeLimen>=3)
				{//若前面的窗口作了调节,则,当前窗口作些微调
					Me=lpAdjust[Winn-1]*(TestErrorMeLimen/3);
					for(j=0;j<WinL;j++)
					{
						k=lpCurrentLine[RunB+i+j]+Me;
						if(k<0)k=0;
						else if(k>MAXVAL)k=MAXVAL;
						lpCurrentLine[RunB+i+j]=k;
					}
				}
			}
			i+=WinL;
		}
		if(OpenAdjust==TRUE)
		{//一级调节游程编码
			EncodeAdjust(lpAdjust,Winn,AdjustN);
		}
		delete lpAdjust;
		if(OpenTwoAdjust==TRUE)
		{//二级调节游程编码
			if(AdjustN>0)EncodeTwoAdjust(lpTwoAdjust,AdjustN,TwoAdjustN);
			delete lpTwoAdjust;
		}
	}
	if(RunL>=AdjustWinLength)
	{//作平滑滤波处理
		int *pLin=new int[RunL];
		j=lpCurrentLine[RunB];
		j1=lpCurrentLine[RunB-1];
		for(i=1;i<RunL-2;i++)
		{
			//根据重建信号的前后梯度决定
			d1l=lpCurrentLine[RunB+i]-j;
			if(d1l<0)d1l=-d1l;
			d1r=lpCurrentLine[RunB+i]-lpCurrentLine[RunB+i+1];
			if(d1r<0)d1r=-d1r;
			if(i>=2)d2l=lpCurrentLine[RunB+i]-j1;
			else d2l=MFilterGradeLimen(qNEAR)+1;
			if(d2l<0)d2l=-d2l;
			if(i<RunL-2)d2r=lpCurrentLine[RunB+i]-lpCurrentLine[RunB+i+2];
			else d2r=MFilterGradeLimen(qNEAR)+1;
			if(d2r<0)d2r=-d2r;
			d1=(d1l>d1r)?d1l:d1r;
			d2=(d2l>d2r)?d2l:d2r;
			if(d1<MFilterGradeLimen(qNEAR))
			{
				if(d2<MFilterGradeLimen(qNEAR))
				{
					if(i>=2&&i<RunL-2)
					{
						k=(lpCurrentLine[RunB+i]*2+
							j+
							lpCurrentLine[RunB+i+1]+
							j1+
							lpCurrentLine[RunB+i+2])/6;
						Modify=TRUE;
					}
					else k=lpCurrentLine[RunB+i];
				}
				else
				{
					k=(lpCurrentLine[RunB+i]*2+
						j+
						lpCurrentLine[RunB+i+1])/4;
					Modify=TRUE;
				}
			}
			else k=lpCurrentLine[RunB+i];
			j1=j;
			j=lpCurrentLine[RunB+i];

			if(k<0)k=0;
			else if(k>MAXVAL)k=MAXVAL;
			pLin[i]=k;
		}
		for(i=1;i<RunL-2;i++)lpCurrentLine[RunB+i]=pLin[i];
		delete pLin;
	}
	if(Modify==TRUE||DoubleMaxError>qNEAR)
	{//大误差检测,大误差序列全部从此处生成
		for(j=0,i=0,ii=0;j<RunL;j++)
		{//i计大误差数,ii计二级大误差数
			IIx=lpImage[RunB+j];
			IIx-=lpCurrentLine[RunB+j];
			lpDoubleErrList[DoubleErrN].PixSeat=RunB+j;//保存可能产生大误差象素的位置
			if(IIx>qNEAR)
			{//正向大误差时
				i++;
				if(IIx-MaxErrAdjust1>=qNEAR)
				{
					lpDoubleErrList[DoubleErrN].Sign=2;//二级大误差状态
					ii++;
				}
				else lpDoubleErrList[DoubleErrN].Sign=1;//一级大误差状态
			}
			else if(IIx<-qNEAR)
			{//负向大误差时
				i++;
				if(IIx+MaxErrAdjust1<=-qNEAR)
				{
					lpDoubleErrList[DoubleErrN].Sign=-2;
					ii++;
				}

⌨️ 快捷键说明

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