📄 advancejpeg-lscode.cpp
字号:
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 + -