📄 jpeg-ls.cpp
字号:
else if(B[Q]>0){
B[Q]=B[Q]-N[Q];
if(C[Q]<MAX_C)
C[Q]=C[Q]+1;
if(B[Q]>0)
B[Q]=0;
}
}
// **********************************
// * 游程编码子程序的定义 *
// **********************************
void RunModeProcessing(int x,int y,int Ra,int Rb,int Rc,int Rd,int Ix)
{
int cnt1=0;
int RUNval=Ra;
int RUNcnt=0,TEMP,RItype;
int map,AQ,EMErrval,glimit,Errval,k,SIGN,Rx,Px;
unsigned interim;
output=0;
// ********************
// * 计算游程长度 *
// ********************
while(abs(Ix-RUNval)<=NEAR)
{
RUNcnt=RUNcnt+1;
Rx=RUNval;
*(f+LinX*(y+2)+RowX)=Rx;
if(EOLine==1)/*正好是最后一个,跳到长度编码*/
break;
else{
RowX=RowX+1;
if(RowX==y){
*(f+(LinX+1)*(y+2))=*(f+LinX*(y+2)+1);
*(f+LinX*(y+2)+y+1)=*(f+LinX*(y+2)+y);/*当前象素为本行最后一个时,对其Rd、下一行Ra赋值*/
EOLine=1;}
Rb=*(f+(LinX-1)*(y+2)+RowX);
Ix=*(f+LinX*(y+2)+RowX);
}
}
// ***************************************************
// * 对游程长度进行编码并向二进制文件中写入码流 *
// ***************************************************
while(RUNcnt>=(1<<J[RUNindex]))
{
output=(output<<1)+1;
cnt1++;
RUNcnt=RUNcnt-(1<<J[RUNindex]);
if(RUNindex<31)
RUNindex=RUNindex+1;
}/*当RUNlen小于整数值的rm时,跳出*/
if(EOLine==0||(EOLine==1&&(abs(Ix-RUNval)>NEAR)))/*情况1:被不同象素中断*/
{
output=output<<1;
cnt1++;
output=(output<<(J[RUNindex]))+RUNcnt;/*之前已经写入最逼近RUNlen的rm段,再左移一个rm段后,加入剩RUNlen下的部分*/
cnt1=cnt1+J[RUNindex];
if(RUNindex>0)
RUNindex--;
}
else if(RUNcnt>0)/*情况2:被行末尾中断*/
{
output=(output<<1)+1;
cnt1++;
}
pp=cnt;
cnt=cnt+cnt1;
writecode(&cnt,&pp,&output,&code);
if(EOLine==1&&(abs(Ix-RUNval)<=NEAR))
return;/*由于行的末尾终止,可正常结束,跳出此次游程模式*/
if(abs(Ra-Rb)<=NEAR)
RItype=1;
else
RItype=0;
if(RItype==1)
Px=Ra;
else
Px=Rb;
Errval=Ix-Px;
if((RItype==0)&&(Ra>Rb))
{
Errval=-Errval;
SIGN=-1;
}
else
SIGN=1;
if(NEAR>0){
if(Errval>0)
Errval=(Errval+NEAR)/(2*NEAR+1);
else
Errval=-(NEAR-Errval)/(2*NEAR+1);
Rx=Px+SIGN*Errval*(2*NEAR+1);
if(Rx<0)
Rx=0;
else if(Rx>MAXVAL)
Rx=MAXVAL;
}
else
Rx=Ix;
*(f+LinX*(y+2)+RowX)=Rx;
Errval=ModRange(Errval);
if(RItype==0)
TEMP=A[365];
else
TEMP=A[366]+(N[366]>>1);
Q=RItype+365;
AQ=A[Q];/*将当前A[Q]暂存,借用完LG(Q)后还可进行正常操作*/
A[Q]=TEMP;
k=LG(Q);
if((k==0)&&(Errval>0)&&(2*Nn[Q-365]<N[Q]))
map=1;
else if((Errval<0)&&(2*Nn[Q-365]>=N[Q]))
map=1;
else if((Errval<0)&&(k!=0))
map=1;
else
map=0;
EMErrval=2*abs(Errval)-RItype-map;/*游程中断编码*/
glimit=LIMIT-J[RUNindex]-1;
interim=EMErrval;
interim=interim>>k;
if(interim<((unsigned)(glimit-qbpp-1)))
{
unsigned b,c;
output=0;
c=~(~0<<k);
b=c&EMErrval;
output=(output<<(interim+1))+1;
output=output<<k;
output=output+b;
pp=cnt;
cnt=cnt+interim+1+k;
writecode(&cnt,&pp,&output,&code);
}
else
{
unsigned b,c;
output=0;
output=(output<<(glimit-qbpp))+1;
output=output<<qbpp;
c=~(~0<<qbpp);
b=c&(EMErrval-1);
output=output+b;
pp=cnt;
cnt=cnt+glimit;
writecode(&cnt,&pp,&output,&code);
}
// ***********************
// * 更新各个变量 *
// ***********************
if(Errval<0)
Nn[Q-365]=Nn[Q-365]+1;
A[Q]=AQ;
A[Q]=A[Q]+((EMErrval+1-RItype)>>1);
if(N[Q]==RESET)
{
A[Q]=A[Q]>>1;
N[Q]=N[Q]>>1;
Nn[Q-365]=Nn[Q-365]>>1;
}
N[Q]=N[Q]+1;
}
// *************************************************
// * 主程序 *
// *************************************************
// i,j:循环变量计数;
// _______________________
// | | Rc| Rb| Rd| |
// -----------------------
// | | Ra| Ix| | |
// -----------------------
// D1,D2,D3:当前梯度
// x,y:图像的高度和宽度
void main()
{
int i,j,Ra,Rb,Rc,Rd,Ix,D1,D2,D3;
int x,y;
int BASIC_T1=3,BASIC_T2=7,BASIC_T3=21;
float T1,T2,T3;
struct timeb start_time,end_time;
int second_d;
printf("图象高度和宽度\n");
scanf("%d,%d",&x,&y);
ftime(&start_time);
f=(int *)calloc((x+1)*(y+2),sizeof(int)); /*补零后的图像多两列,一行*/
// if((fp=fopen("E:\\felicia\\adata7.raw","rb"))==NULL)
if((fp=fopen("e:\\felicia\\LENA128.RAW","rb"))==NULL)
{
printf("Error opening %s","e:\\felicia\\TU1.raw");
exit(0);
}
// *********************************
// * 计算各参数的值 *
// *********************************
for(i=1;i<=x;i++)
for(j=1;j<=y;j++){
fread(f+i*(y+2)+j,1,1,fp);/*前面空一行,以作重建值。从第二行写起。此时补的行还是零,到后面预测时补入Rb等。*/
if(*(f+i*(y+2)+j)>MAXVAL)
MAXVAL=*(f+i*(y+2)+j);/*先求实际最大值*/
}
for(i=0;(1<<i)<=MAXVAL;i++);
MAXVAL=(1<<i)-1;/*规整到2的n次方故取大于实际MAXVAL的最小2的n次方*/
RANGE=((int)((MAXVAL+2*NEAR)/(2*NEAR+1)))+1;
qbpp=-(int)(floor(-log(RANGE)/log(2.0)));
bpp=__max(2,-(int)(floor(-log(MAXVAL+1)/log(2.0))));
LIMIT=2*(bpp+__max(8,bpp));
if(MAXVAL>=128){
T1=CLAMP_1((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T1-2)+2+3*NEAR);
T2=CLAMP_2((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T2-3)+3+5*NEAR,T1);
T3=CLAMP_3((float)((int)(__min(MAXVAL,4095)+128)/256)*(BASIC_T3-4)+4+7*NEAR,T2);}
else{
T1=CLAMP_1((float)__max(2,BASIC_T1/(int)(256/(MAXVAL+1))+3*NEAR));
T2=CLAMP_2((float)__max(3,BASIC_T2/(int)(256/(MAXVAL+1))+5*NEAR),T1);
T3=CLAMP_3((float)__max(4,BASIC_T3/(int)(256/(MAXVAL+1))+7*NEAR),T2);
}
// ******************************
// * 对各数组的初始化 *
// ******************************
for(j=0;j<365;j++)
{
A[j]=__max(2,(RANGE+(1<<5))/(1<<6));
N[j]=1;
B[j]=0;
C[j]=0;
}
A[365]=A[0];
A[366]=A[0];
N[365]=1;
N[366]=1;
for(i=0;i<y+3;i++)
*(f+i)=0;/*第一行及第二行第一个全为零*/
fp=fopen("E:\\felicia\\Adata2","wb");
// ************************
// * 读入变量 *
// ************************
while(RowX<=y&&LinX<=x)/*到计算时间之前为大循环,一个一个象素处理*/
{
Ra=(*(f+LinX*(y+2)+RowX-1));
Rb=(*(f+(LinX-1)*(y+2)+RowX));
Rc=(*(f+(LinX-1)*(y+2)+RowX-1));
Rd=(*(f+(LinX-1)*(y+2)+RowX+1));
Ix=(*(f+LinX*(y+2)+RowX));
D1=Rd-Rb;
D2=Rb-Rc;
D3=Rc-Ra;
// ******************************
// * 选择编码方式 *
// ******************************
if((abs(D1)<=NEAR)&&(abs(D2)<=NEAR)&&(abs(D3)<=NEAR))
RunModeProcessing(x,y,Ra,Rb,Rc,Rd,Ix);
else
RegularModeProcessing(y,Ra,Rb,Rc,Rd,Ix,D1,D2,D3,T1,T2,T3);
RowX++;
if(RowX==y)/*原图像一行的结尾(是补零后的倒数第二个象素)*/
{
*(f+(LinX+1)*(y+2))=*(f+LinX*(y+2)+1);/*处理下一行的第一个象素的上下文:将Rb赋给a*/
*(f+LinX*(y+2)+y+1)=*(f+LinX*(y+2)+y);/*处理当前行最后一个象素的上下文:将Rb赋给d*/
EOLine=1;
}
else
EOLine=0;
if(RowX>y)/*补零后的最后一个象素*/
{
RowX=RowX-y;/*也即rowx=1*/
LinX++;
}
}
#if 0
printf("出现Errval小于零%d次\n",z);
#endif
if(cnt>0)
code=code<<(8-cnt);
fwrite(&code,1,1,fp);
fclose(fp);
ftime(&end_time);
// **************************
// * 计算编码时间 *
// **************************
second_d=end_time.millitm-start_time.millitm;
second_d=second_d+(end_time.time-start_time.time)*1000;
printf("The encoding costs:%.3f seconds.\n",(float)second_d/1000.0);
// ***************************
// * 图像原始数据 *
// ***************************
fp=fopen("E:\\felicia\\Adata4.dat","w");
for( i=0;i<=x;i++){
for(j=0;j<=y+1;j++)
fprintf(fp,"%5d",*(f+i*(y+2)+j));
fprintf(fp,"\n");
}
fclose(fp);
/* fp=fopen("E:\\felicia\\Adata6.dat","w");
for(j=0;j<=y+1;j++){
for(i=0;i<=x;i++)
fprintf(fp,"%5d",*(f+j*(x+1)+i));
fprintf(fp,"\n");
}
fclose(fp);*/
// fp=fopen("E:\\felicia\\Adata5.dat","w");
// for( i=0;i<=364;i++){
// fprintf(fp,"%5d\n",Nt[i]);
// }
// fclose(fp);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -