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