?? jpeg_ls.cpp
字號:
// JPEG_LS.cpp: implementation of the JPEG_LS class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HIC.h"
#include "JPEG_LS.h"
#include "math.h"
#include <time.h>
#include <sys\types.h>
#include <sys\timeb.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define RESET 64
#define NEAR 0
#define MIN_C -1000
#define MAX_C 20000
int J[32]={0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,7,8,9,10,11,12,13,14,15};
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
JPEG_LS::JPEG_LS()
{
}
JPEG_LS::~JPEG_LS()
{
}
int JPEG_LS::LG(int Q)
{
int i;
for(i=0;(N[Q]<<i)<A[Q];i++);
return(i);
}
float JPEG_LS::CLAMP_1(float i)
{
if(i>MAXVAL||i<NEAR+1)
return(NEAR+1);
else
return(i);
}
float JPEG_LS::CLAMP_2(float i, float T1)
{
if(i>MAXVAL||i<T1)
return(T1);
else
return(i);
}
float JPEG_LS::CLAMP_3(float i, float T2)
{
if(i>MAXVAL||i<T2)
return(T2);
else
return(i);
}
void JPEG_LS::JPEG_LSCompress()
{
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;
x=256;y=256;
CT=0;
Initial();
ftime(&start_time);
f=(int *)calloc((x+1)*(y+2),sizeof(int)); /*補零后的圖像多兩列,一行*/
if((fp=fopen("E:\\girl256.raw","rb"))==NULL)
{
AfxMessageBox("Can not Open File!");
return;
}
// 計算各參數的值
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);/*先求實際最大值*/
}
fclose(fp);
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;/*第一行及第二行第一個全為零*/
if((fp=fopen("E:\\girl.raw","wb"))==NULL)
{
AfxMessageBox("Can not Open File!");
return;
}
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(cnt>0)
code=code<<(8-cnt);
fwrite(&code,1,1,fp);
CT=CT+1;
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);
}
/***************************************************
游程編碼子程序的定義
****************************************************/
void JPEG_LS::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;
/*將當前A[Q]暫存,借用完LG(Q)后還可進行正常操作*/
AQ=A[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;
}
int JPEG_LS::ModRange(int a)
{
if(a<((0-RANGE)/2))
a=a+RANGE;
if(a>=((1+RANGE)/2))
a=a-RANGE;
return(a);
}
void JPEG_LS::writecode(int *cnt, int *pp, unsigned long *output, int *code)
{
unsigned long c;
if((*cnt)<8)
*code=(*code<<(*cnt-*pp))+(*output);/*以1byte為單位處理。把之前的碼流向前推當前碼流的長度,加入當前輸出的碼流*/
else{
while(*cnt>=8)
{
if(*cnt>32)/*以4byte為存儲器最大值*/
{
*code=(*code<<(8-*pp));
fwrite(code,1,1,fp);/*把code指向的1×1個字節輸出到fp所指的文件中*/
CT=CT+1;
counter++;
*code=0;
*cnt=*cnt-8;
}
else
{
*code=(*code<<(8-*pp))+(255&(*output>>(*cnt-8)));
fwrite(code,1,1,fp);
CT=CT+1;
counter++;
*code=0;
*cnt=*cnt-8;
}
}
c=~(~0<<*cnt);
*code=c&(*output);
}
}
void JPEG_LS::RunModeProcessing(int qbpp, int Ra, int Rb, int y)
{
int decode1=0;
int cnt=0,i;
unsigned long j;
int RItype,TEMP,AQ,Errval,EMErrval,flag,map,SIGN,k,Px,Rx,Q;
// 從碼流中恢復EMErrval
if(size==0)
{
fread(&buffer,1,1,fp);
decode=buffer;
size=8;}/*以8bit為一個處理單位*/
size--;
while((1&(decode>>size))==1)
{
size--;
i=0;
while(i<(1<<J[RUNindex]))/*寫一個Ra*/
{
*(f+LinX*(y+2)+RowX)=Ra;
RowX++;
if(RowX>y)
{
RowX--;
flag1=1;
}
i++;
if(flag1==1)
break;
}
if((i==(1<<J[RUNindex]))&&RUNindex<31)
RUNindex++;
if(size<0&&flag1==0)
{
fread(&buffer,1,1,fp);
decode=buffer;
size=7;
}/*一個單元處理完且游程仍未結束,處理下一個單元*/
if(flag1==1)
break;
}
//在已處理的位上置零
if(RowX==y&&flag1==1){/*情況1:在行末*/
if(size==-1)/*正好處理完一個單元且游程未結束*/
decode=0;/*處理器清零,完成游程解碼*/
else/*對單元未處理完就已到行末*/
decode=(decode<<(32-size-1))>>(32-size-1);/*當被行末中斷時,其剩下的rk位1前綴是1,所以也被前面的處理過size+1是未處理的,所以32-size-1表示在當前處理范圍內已處理的。此操作表示將已處理的位置零*/
size=size+1;/*待處理的位數是size+1*/
flag1=0;
return;}/*游程解碼結束*/
if(size==0)/*情況2:非行末,正好一個單元的最后一個是不同象素*/
decode2=0;
else
decode2=(decode<<(32-size))>>(32-size);/*剩下size個元素待處理*/
/***對長度小于rm的分段碼字的處理***/
if(J[RUNindex]<=size)/*當有剩余比特出現時,且在當前處理單元內*/
{
output=(decode2>>(size-J[RUNindex]));/*將待處理的數據移至最右側,即得到待處理的數據*/
if(J[RUNindex]==size)
decode=0;
else
decode=((decode<<(32-size+J[RUNindex]))>>(32-size+J[RUNindex]));/*將處理過的位置零*/
size=size-J[RUNindex];
}
else/*當前處理單元剩余的比特小于rk時*/
{
fread(&buffer,1,1,fp);
if(J[RUNindex]-size<=8)/*rk在下一個處理單元之內*/
decode1=decode2<<(J[RUNindex]-size);/*加入下一個單元中剩下部分的空間*/
while(J[RUNindex]-size>8)
{
decode1=decode1+(decode2<<(J[RUNindex]-size))+(buffer<<(J[RUNindex]-size-8));/*讀入后面幾個單元中rk部分.注意這里的加并不表示長度相加,而是在同一原點上疊加*/
J[RUNindex]=J[RUNindex]-8;
fread(&buffer,1,1,fp);
decode2=0;
}
output=decode1+(buffer>>(8+size-J[RUNindex]));/*右邊第二項是當rk-size<8時,得到當前單元的剩余的rk,以接到n個滿單元之后*/
if(J[RUNindex]-size==8)
decode=0;
else
decode=(buffer<<(32-8+J[RUNindex]-size))>>(32-8+J[RUNindex]-size);/*對前面已經處理過的(n個滿單元及當前單元剩余rk)位置零*/
size=8-J[RUNindex]+size;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -