?? jpeg-ls.cpp
字號:
// ******************************************************************
// * JPEG-LS源程序清單 *
// ******************************************************************
// ************
// *包含庫文件*
// ************
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys\types.h>
#include <sys\timeb.h>
// ************
// * 宏定義 *
// ************
//RESET: threshold value at which A,B,and N are halved
//NEAR: difference bound for near-lossless coding
//MIN_C: minimum allowed value of C[0..364],equal to -128
//MAX_C: maximum allowed value of C[0..364],equal to 127
#define RESET 64
#define NEAR 0
#define MIN_C -128
#define MAX_C 127
// ************************************
// * 全局變量初始化 *
// ************************************
//MAXVAL: maximum possible image sample value ove all component of a scan
//RUNindex: index for run mode order
//qbpp: number of bits needed to represent a mapped error value
//bpp: number of bits needed to represent MAXVAL,with a minimum of 2
//LIMIT: the value of glimit for a sample encoded in regular mode
//Q: context determined from Q1,Q2,Q3
//RANGE: range of prediction error representation
//A[0..366]:367 counters for the accumulated preditection error magnitude
//B[0..364]:365 counters for computing the bias
//C[0..364]:365 counters storing prediction coreection values
//J[0..31]: 32 variables indicating order of run-length codes
//N[0..366]:367 counters for frequency of occurrence of each context
//Nn[365..366]:2 counters for negative prediction error for run interruption
//EOLine: end of line indicator,used in run mode
//Errval: prediction error
//EMErrval: Errval mapped to non-negative integers in run interruption mode
//MErrval: Errval mapped to non-negative integers in regular mode
//--------------------------------------------------------------------------------
// LinX:當前行號
// RowX:當前列號
// *f:指向碼流的指針
// *fp:文件指針
// counter:計算編碼文件長度
// output:編碼的數值
// cnt:當前碼流的長度
// code:當前碼流的數值
// pp:前一碼流的長度
int MAXVAL=0;
unsigned long output=0;//輸出碼流
static int cnt=0,code=0,pp=0;//計數器
int LinX=1,RowX=1; //當前點的行列值
static int RUNindex=0;
int qbpp,bpp,*f;
static int B[365],C[365];
int LIMIT,Q,RANGE;
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};
int A[367],N[367];
int Nn[2]={0};
int EOLine=0;
long int counter=0;
FILE *fp;
// **********************************
// * 計算T1,T2,T3值的子程序 *
// **********************************
float CLAMP_1(float i)
{
if(i>MAXVAL||i<NEAR+1)
return(NEAR+1);
else
return(i);
}
float CLAMP_2(float i,float T1)
{
if(i>MAXVAL||i<T1)
return(T1);
else
return(i);
}
float CLAMP_3(float i,float T2)
{
if(i>MAXVAL||i<T2)
return(T2);
else
return(i);
}
// ******************************
// * 求算術編碼的長度的子程序 *
// ******************************
int LG(int Q)
{
int i;
for(i=0;(N[Q]<<i)<A[Q];i++);
return(i);
}
// ******************************
// * 規整Errval的值 *
// ******************************
int ModRange(int a)
{
if(a<((0-RANGE)/2))
a=a+RANGE;
if(a>=((1+RANGE)/2))
a=a-RANGE;
return(a);
}
// **************************************
// * 寫碼流的子程序 *
// **************************************
void 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所指的文件中*/
counter++;
*code=0;
*cnt=*cnt-8;
}
else
{
*code=(*code<<(8-*pp))+(255&(*output>>(*cnt-8)));
fwrite(code,1,1,fp);
counter++;
*code=0;
*cnt=*cnt-8;
}
}
c=~(~0<<*cnt);
*code=c&(*output);
}
}
// ****************************************
// * 常規編碼過程的子程序 *
// ****************************************
void RegularModeProcessing(int y,int Ra,int Rb,int Rc,int Rd,int Ix,int D1,int D2,int D3,float T1,float T2,float T3)
{
// ********************
// * 當地梯度的量化 *
// ********************
int Di[4]={0,D1,D2,D3};
int Qi[4],Errval,MErrval;
int i,k,SIGN,Rx,Px;
unsigned interim;
output=0;
for(i=1;i<4;i++)
{
if(Di[i]<=-T3) Qi[i]=-4;
else if(Di[i]<=-T2) Qi[i]=-3;
else if(Di[i]<=-T1) Qi[i]=-2;
else if(Di[i]<-NEAR)Qi[i]=-1;
else if(Di[i]<=NEAR)Qi[i]=0;
else if(Di[i]<T1) Qi[i]=1;
else if(Di[i]<T2) Qi[i]=2;
else if(Di[i]<T3) Qi[i]=3;
else Qi[i]=4;
}
// **********************************************
// * 完成從矢量(Q1,Q2,Q3)到Q的一一對應的映射 *
// **********************************************
if((Qi[1]<0)||((Qi[1]==0)&&(Qi[2]<0))||(((Qi[1]==0)&&(Qi[2]==0))&&(Qi[3]<0)))
SIGN=-1;
else SIGN=1;
if(SIGN==-1)
{
for(i=1;i<4;i++)
Qi[i]=Qi[i]*SIGN;
}
Q=(Qi[1]*9+Qi[2])*9+Qi[3];/*人為設定*/
// *****************************
// * 計算Px的值(預測) *
// *****************************
if(Rc>=__max(Ra,Rb))
Px=__min(Ra,Rb);
else{
if(Rc<=__min(Ra,Rb))
Px=__max(Ra,Rb);
else
Px=Ra+Rb-Rc;
}/*邊緣檢測*/
/* if(Rc<=__max(Ra,Rb)){
if(Rc<=__min(Ra,Rb)){
if((10<=(Rd-Rb))&&(abs(Ra-Rb))<=10&&(__min(Ra,Rb)-Rc)>=5&&(Rd-Rb)<=50)
Px=Rd/2+__max(Ra,Rb)/2;
else
Px=__max(Ra,Rb);}
else
Px=Ra+Rb-Rc;}
else{
if(Rc-Ra>=10&&Rd<Rb&&Ra-Rb<=5)
Px=Rd/2+__min(Ra,Rb)/2;
else
Px=__min(Ra,Rb);
} */
if(SIGN==1)
Px=Px+C[Q];
else
Px=Px-C[Q];
// **********************************
// * 將Px規整到(0..MAXVAL)的范圍 *
// **********************************
if(Px>MAXVAL)
Px=MAXVAL;
else if(Px<0)
Px=0;/*預測修正*/
// ********************
// * 計算Errval *
// ********************
Errval=Ix-Px;
if(SIGN==-1)
Errval=-Errval;
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;
*(f+LinX*(y+2)+RowX)=Rx;/*用重建值代替實際值*/
// ******************************************************
// * 將Errval規整到[-(RANGE-1)/2..+RANGE/2)的范圍 *
// ******************************************************
Errval=ModRange(Errval);
// ***********************************
// * 將Errval映射到MErrval *
// ***********************************
k=LG(Q);
if((NEAR==0)&&(k==0)&&(2*B[Q]<=-N[Q]))
{
if(Errval>=0)
MErrval=2*Errval+1;
else
MErrval=-2*(Errval+1);
}
else{
if(Errval>=0)
MErrval=2*Errval;
else
MErrval=-2*Errval-1;
}
// **********************************
// * 對MErrval進行編碼 *
// **********************************
interim=MErrval;
interim=interim>>k;/*除最低k位以外的高位*/
if(interim<((unsigned)(LIMIT-qbpp-1)))
{
unsigned b,c;
c=~(~0<<k);
b=c&MErrval;/*截取MErrval的最低k位*/
output=(output<<(interim+1))+1;/*左移interim+1得到interim+1個零,加一后即interim個零接一個1*/
output=output<<k;
output=output+b;
// *******************************
// * 向二進制文件寫碼流 *
// *******************************
pp=cnt;
cnt=cnt+interim+1+k;
writecode(&cnt,&pp,&output,&code);
}
else
{
unsigned b,c;
output=(output<<(LIMIT-qbpp))+1;/*當前碼流為:LIMIT-qbpp-1個零,一個1*/
output=output<<qbpp;/*后接qbpp位的數字*/
c=~(~0<<qbpp);
b=c&(MErrval-1);/*取MErrval-1的后qbpp位*/
output=output+b;
pp=cnt;
cnt=cnt+LIMIT;
writecode(&cnt,&pp,&output,&code);
}
// *********************************
// * 更新各個變量 *
// *********************************
B[Q]=B[Q]+Errval*(2*NEAR+1);
A[Q]=A[Q]+abs(Errval);
if(N[Q]==RESET)
{
A[Q]=A[Q]>>1;
B[Q]=B[Q]>>1;
N[Q]=N[Q]>>1;
}
N[Q]=N[Q]+1;/*N[Q]指此種上下文出現的次數,最多為64次*/
// Nt[Q]=Nt[Q]+1;
if(B[Q]<=-N[Q]){
B[Q]=B[Q]+N[Q];
if(C[Q]>MIN_C)
C[Q]=C[Q]-1;
if(B[Q]<=-N[Q])
B[Q]=-N[Q]+1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -