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