?? advancejpeg-lscode.cpp
字號:
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 + -