?? 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 + -