⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dct.cpp

📁 可以选择各种压缩方式对读入的图像进行压缩和解压
💻 CPP
字号:
#include "dct.h"

#define PI 3.141593



//double (*Dct)[8][8];
//int N=(width/8)*(height/8);
//Dct=new double[N][8][8];
////delete []Dct;
////Dct=NULL;

blstype dctqt(ptype **P,unsigned int width, unsigned int height, btype  (*&Q)[8][8], int mode, int level, bool adaptor, btype QTable[8][8]) {
	//construct double dct[][][]
	double (*dct)[8][8]=NULL;
	blstype n=DivisionFdct(P,width,height,dct);
	//if mode==3 hestigram dct->construct btype Q[][][]
	Q=new btype[n][8][8];
    if (3==mode) {
       HistQuan(dct,Q,n,6);
       for (int i=0; i<8; i++)
           for (int j=0; j<8; j++)
               QTable[i][j]=1;
       QTable[0][0]=16;
    }
    else {
       mode2table(mode,65,QTable);
       if (adaptor) {
          modifyQTable(dct,n,QTable);
       }
       Quantization(dct, Q, QTable, n);
    }
	//else { choose mode (qtable)
	//			  if adaptor modify(qtable) according to dct[][][]
	//			  quantify dct->construct btype Q[][][]
	//           send out qtable, n
	//         }
	//send out Q
	delete []dct;
    return n;
}

int	idctqt(btype Q[][8][8],  ptype ** &P, unsigned int height, unsigned int width,
			   int mode, btype QTable[8][8]){
      //if mode==4 ihestigram Q2[][8][8]  only dc
      //else iquantization with the giving qtable Q2[][][]
      //idct -> **p
//      if (4==mode) {
//          HistIQuan(

	P = new ptype *[height];
	if (!P) {
		printf("Allocate height error.\n");
		return 1;
	}
	for (unsigned int j=0; j<height; j++) {
		P[j]=new ptype [width];
		if (!P[j]) {
			printf("Allocate width error.\n");
			return 1;
		}
	}

	double va[8][8];
	ptype vb[8][8];

	unsigned int nrow=height/8;
	unsigned int ncolumn=width/8;
	blstype NM=nrow*ncolumn;

	for(unsigned int i=0;i<NM;i++)
	{
		for(int u=0;u<8;u++)
			for(int v=0;v<8;v++)
				va[u][v]=Q[i][u][v]*QTable[u][v];
        
		Idct(va,vb);

		for(int u=0;u<8;u++)
			for(int v=0;v<8;v++)
			    P[i/ncolumn*8+u][i%ncolumn*8+v]=vb[u][v]; //[(i/ncolumn*8+u)*column+i%ncolumn*8+v]
	}
	return 0;
}
      


void modifyQTable(double dct[][8][8], blstype N, btype QTable[8][8]) {
     
double sum_of_ac[8][8];//交流系数和
double avg_of_ac[8][8];//交流系数平均值
double max_of_acavg=0;//AC平均值中的最大值
//double Q2[8][8]={{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1}};//定义一个量化表
//double Q[8][8]={{16,11,10,16,24,40,51,61},{12,12,14,19,26,58,60,55},{4,13,16,24,40,57,69,56},{14,17,22,29,51,87,80,62},{18,22,37,56,68,109,103,77},{24,35,55,64,81,104,113,92},{49,64,78,87,103,121,120,101},{72,92,95,98,112,100,103,99}};//定义一个量化表
double modifac[8][8];//矫正系数
//double Q_modified[8][8];//修正后的量化表

for(int i=0;i<8;i++)
{
	for(int j=0;j<8;j++) 
	{
		sum_of_ac[i][j]=0;
        for(blstype n=0;n<N;n++)
		{
			if((i+j)!=0)
			{
			 sum_of_ac[i][j]+=abs(dct[n][i][j]);
			}
			else
			{
		     sum_of_ac[i][j]=0;
			}
		}
		avg_of_ac[i][j]=sum_of_ac[i][j]/double(N);
		if (avg_of_ac[i][j]>max_of_acavg)
		   max_of_acavg=avg_of_ac[i][j];
	}
}
for(int i=0;i<8;i++)
{
	for(int j=0;j<8;j++)
	{
		if(avg_of_ac[i][j]!=0)
			{
			 modifac[i][j]=avg_of_ac[i][j]*sqrt(double(i*i+j*j))/max_of_acavg;
		     QTable[i][j]=btype(QTable[i][j]/modifac[i][j]);
			}
	}
}
}



blstype DivisionFdct(ptype **a, unsigned int width, unsigned int height, double  (* &Dct)[8][8])
{
	unsigned int nrow,ncolumn;
	btype va[8][8];
	nrow=height/8;
	ncolumn=width/8;
	blstype NM=nrow*ncolumn;
	Dct=new double[NM][8][8];

	for(unsigned int i=0;i<NM;i++)
	{
		for(int j=0;j<8;j++)
		{
			for(int k=0;k<8;k++)
			{
				va[j][k]=a[i/ncolumn*8+j][i%ncolumn*8+k]; 
			}
		}

		Fdct(va,Dct[i]);

	}
	return NM;
}

void AcdseeTable(btype QTable[8][8],int n)
{
 int Table[8][8]={  20, 13, 12, 20, 30, 50, 63, 76,
                    15, 15, 17, 23, 32, 72, 75, 68,
                    17, 16, 20, 30, 50, 71, 86, 70,
                    17, 21, 27, 36, 63,108,100, 77,
                    22, 27, 46, 70, 85,136,128, 96,
                    30, 43, 68, 80,101,130,141,115,
                    61, 80, 97,108,8,151,150,126,
                    90,115,118,122,140,125,128,123};
 char Jpeg[8][8]={ 16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,
                   14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,
			       18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,
			       49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99};
 for(int i=0;i<8;i++)
 {
	 for(int j=0;j<8;j++)
	 {
		 if((n<0)||(n>100))
			 QTable[i][j]=btype(Jpeg[i][j]);
		 else
			 QTable[i][j]=btype(1+(Table[i][j]-1)*n/100);
	 }
 }
}

void mode2table(int mode, int level, btype QTable[8][8]){
	switch (mode) {
	case 1: 
		for (int i=0;i<8;i++)
			for (int j=0;j<8;j++)
				QTable[i][j]=level; //均匀
		break;
	case 2: 
		for (int i=0;i<8;i++)
			for (int j=0;j<8;j++)
				QTable[i][j]=10+8*(i+j); //变步长
		break;
	//case 3:
	//	AcdseeTable(QTable,level);
	//	break;
	default: 
		AcdseeTable(QTable,101);
		//for (int i=0;i<8;i++)
		//	for (int j=0;j<8;j++)
		//		QTable[i][j]=JPEGTable[i][j];//标准量化表
	}
}

void Quantization(double Dct[][8][8], btype QuanTable[][8][8], btype QTable[8][8], blstype NM)
{
	for(blstype i=0;i<NM;i++)
	{
		for(int j=0;j<8;j++)
		{
			for(int k=0;k<8;k++)
			{
				if(Dct[i][j][k]>0)
					QuanTable[i][j][k]=btype(Dct[i][j][k]/QTable[j][k]+0.5);
				else
					QuanTable[i][j][k]=btype(Dct[i][j][k]/QTable[j][k]-0.5);
			}
		}
	}
}


void HistQuan(double va[][8][8],btype vb[][8][8],blstype NM,int grade)
{
	for(blstype i=0;i<NM;i++)
		Histogram(va[i],vb[i],grade);
}


//BOOL IQuantization(btype (*QuanTable)[8][8], double (*Dct)[8][8], btype QTable[8][8], blstype NM)
//{
//	for(unsigned int i=0;i<NM;i++)
//	{
//		for(int u=0;u<8;u++)
//			for(int v=0;v<8;v++)
//			    Dct[i][u][v]=QuanTable[i][u][v]*QTable[u][v]; 
//	}
//	return true;
//}
//
//BOOL IdctCombination(double (*Dct)[8][8], ptype **a, unsigned int width, unsigned int height)
//{
//	unsigned int nrow=height/8;
//	unsigned int ncolumn=width/8;
//	blstype NM=nrow*ncolumn;
//
//	for(unsigned int i=0;i<NM;i++)
//	{
//		ptype vb[8][8];
//		Idct(Dct[i],vb);
//		for(int u=0;u<8;u++)
//			for(int v=0;v<8;v++)
//			    a[i/ncolumn*8+u][i%ncolumn*8+v]=vb[u][v]; 
//	}
//	return true;
//}



void Fdct(btype va[][8],double vb[][8])
 {
	double c;
	double CosTable[8][8]={1.0,0.98078528040323,0.92387953251129,0.83146961230255,0.70710678118655,0.55557023301960,0.38268343236509,0.19509032201613,
                           1.0,0.83146961230255,0.38268343236509,-0.19509032201613,-0.70710678118655,-0.98078528040323,-0.92387953251129,-0.55557023301960,
                           1.0,0.55557023301960,-0.38268343236509,-0.98078528040323,-0.70710678118655,0.19509032201613,0.92387953251129,0.83146961230255,
                           1.0,0.19509032201613,-0.92387953251129,-0.55557023301960,0.70710678118655,0.83146961230255,-0.38268343236509,-0.98078528040323,
                           1.0,-0.19509032201613,-0.92387953251129,0.55557023301960,0.70710678118655,-0.83146961230255,-0.38268343236509,0.98078528040323,
                           1.0,-0.55557023301960,-0.38268343236509,0.98078528040323,-0.70710678118655,-0.19509032201613,0.92387953251129,-0.83146961230255,
                           1.0,-0.83146961230255,0.38268343236509,0.19509032201613,-0.70710678118655,0.98078528040323,-0.92387953251129,0.55557023301960,
                           1.0,-0.98078528040323,0.92387953251129,-0.83146961230255,0.70710678118655,-0.55557023301960,0.38268343236509,-0.19509032201613};
	for(int u=0;u<8;u++)
	{
		for(int v=0;v<8;v++)
		{
			vb[u][v]=0.0;
			for(int j=0;j<8;j++)
				for(int k=0;k<8;k++)
					   vb[u][v]=vb[u][v]+va[j][k]*CosTable[j][u]*CosTable[k][v];
			if((0==u)&&(0==v))
				c=0.5;
			else if((0==u)||(0==v))
				c=1/sqrt(2.0);
			else
				c=1.0;
			vb[u][v]=c*vb[u][v]/4.0;
		}
	}
 }

 void Idct(double va[8][8],ptype vb[][8])
 {
	double c,d;
	double CosTable[8][8]={1.0,0.98078528040323,0.92387953251129,0.83146961230255,0.70710678118655,0.55557023301960,0.38268343236509,0.19509032201613,
                           1.0,0.83146961230255,0.38268343236509,-0.19509032201613,-0.70710678118655,-0.98078528040323,-0.92387953251129,-0.55557023301960,
                           1.0,0.55557023301960,-0.38268343236509,-0.98078528040323,-0.70710678118655,0.19509032201613,0.92387953251129,0.83146961230255,
                           1.0,0.19509032201613,-0.92387953251129,-0.55557023301960,0.70710678118655,0.83146961230255,-0.38268343236509,-0.98078528040323,
                           1.0,-0.19509032201613,-0.92387953251129,0.55557023301960,0.70710678118655,-0.83146961230255,-0.38268343236509,0.98078528040323,
                           1.0,-0.55557023301960,-0.38268343236509,0.98078528040323,-0.70710678118655,-0.19509032201613,0.92387953251129,-0.83146961230255,
                           1.0,-0.83146961230255,0.38268343236509,0.19509032201613,-0.70710678118655,0.98078528040323,-0.92387953251129,0.55557023301960,
                           1.0,-0.98078528040323,0.92387953251129,-0.83146961230255,0.70710678118655,-0.55557023301960,0.38268343236509,-0.19509032201613};
	for(int j=0;j<8;j++)
	{
		for(int k=0;k<8;k++)
		{
			d=0.0;
			for(int u=0;u<8;u++)
			{
				for(int v=0;v<8;v++)
				{
					if((0==u)&&(0==v))
						c=0.5;
					else if((0==u)||(0==v))
						c=1/sqrt(2.0);
					else
						c=1.0;
					d=d+c*va[u][v]*CosTable[j][u]*CosTable[k][v];
				}
			}
			if(d<=0)
				vb[j][k]=0;
			else {
				d=d/4+0.5;
				if (d>255)
					vb[j][k]=255;
				else
					vb[j][k]=ptype(d);
			}
		}
	}
 }





void Histogram(double va[][8],btype vb[][8],int grade)
{
	int n=0;  
	int m=0; 
	double sum=0; 
	//grade=6;  
	double positive[64];
	int positive1[64];
	double negative[64];
	int negative1[64];

	for(int i=0;i<8;i++)
		for(int j=0;j<8;j++)
			vb[i][j]=0;

	for(int i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			if(va[i][j]<0)
			{
				negative[m]=va[i][j];
				negative1[m]=i*8+j; 
				m++;
				sum=sum-va[i][j];
			}
			else
			{
				positive[n]=va[i][j];
				positive1[n]=i*8+j;  
				n++;
				sum=sum+va[i][j];
			}
		}
	}
	if(va[0][0]<0)  
		sum=sum+va[0][0];
	else
		sum=sum-va[0][0];
	sum=sum/(grade-1.0);

	for(int i=0;i<n-1;i++)
	{
		int taxisover=0;
		for(int j=0;j<n-1-i;j++)
		{
			if(positive[j]>positive[j+1])
			{
				double tem=positive[j];
				positive[j]=positive[j+1];
				positive[j+1]=tem;
				int tem1=positive1[j];
				positive1[j]=positive1[j+1];
				positive1[j+1]=tem1;
				taxisover=1;
			}
		}
		if(!taxisover)
			break;
	}
	for(int i=0;i<m-1;i++)
	{
		int taxisover=0;
		for(int j=0;j<m-1-i;j++)
		{
			if(negative[j]<negative[j+1])
			{
				double tem=negative[j];
				negative[j]=negative[j+1];
				negative[j+1]=tem;
				int tem1=negative1[j];
				negative1[j]=negative1[j+1];
				negative1[j+1]=tem1;
				taxisover=1;
			}
		}
		if(!taxisover)
			break;
	}

	if(positive[n-1]>(-negative[m-1]))  
		n--;
	else
		m--;

	int nn=0;
	int mm=0;
	int position;
	double sum1=0;
	while(sum1<sum)
	{
		if(nn>=n)
		{
			sum1=sum1-negative[mm];
			position=negative1[mm];
			vb[position/8][position%8]=0;
			mm++;
		}
		else if(mm>=m)
		{
			sum1=sum1+positive[nn];
			position=positive1[nn];
			vb[position/8][position%8]=0;
			nn++;
		}
		else if(positive[nn]<(-negative[mm]))
		{
			sum1=sum1+positive[nn];
			position=positive1[nn];
			vb[position/8][position%8]=0;
			nn++;
		}
		else
		{
			sum1=sum1-negative[mm];
			position=negative1[mm];
			vb[position/8][position%8]=0;
			mm++;
		}
		if((nn>=n)&&(mm>=m))
			break;
	}

	if(va[0][0]>0)
		vb[0][0]=btype(va[0][0]/16+0.5);
	else
		vb[0][0]=btype(va[0][0]/16-0.5);

	sum1=0;
	for(int i=nn;i<n;i++)
		sum1=sum1+positive[i];
	sum1=sum1/sum;
	int positivegrade=int(sum1+0.5);
	int negativegrade=grade-2-positivegrade; 

	for(int k=0;k<positivegrade;k++)
	{
		if(nn>=n)
		{
			position=positive1[n-1];
			vb[position/8][position%8]=btype(positive[n-1]+0.5);
			break;
		}
		if(k==(positivegrade-1))
		{
			sum1=0;
			for(int i=nn;i<n;i++)
				sum1=sum1+positive[i];
			sum1=sum1/(n-nn);
			for(;nn<n;nn++)
			{
				position=positive1[nn];
			    vb[position/8][position%8]=btype(sum1+0.5);
			}
			break;
		}
		sum1=0;
		int nnn=nn;
		for(;nn<n;)
		{
			sum1=sum1+positive[nn];
			nn++;
			if(sum1>sum)
				break;
		}
		btype dd=btype(sum1/(nn-nnn)+0.5);
		for(int i=nnn;i<nn;i++)
		{
			position=positive1[i];
			vb[position/8][position%8]=dd;
		}
	}

	for(int k=0;k<negativegrade;k++)
	{
		if(mm>=m)
		{
			position=negative1[m-1];
			vb[position/8][position%8]=btype(negative[m-1]-0.5);
			break;
		}
		if(k==(negativegrade-1))
		{
			sum1=0;
			for(int i=mm;i<m;i++)
				sum1=sum1+negative[i];
			sum1=sum1/(m-mm);
			for(;mm<m;mm++)
			{
				position=negative1[mm];
			    vb[position/8][position%8]=btype(sum1-0.5);
			}
			break;
		}
		sum1=0;
		int mmm=mm;
		for(;mm<m;)
		{
			sum1=sum1+negative[mm];
			mm++;
			if((-sum1)>sum)
				break;
		}
		btype dd=btype(sum1/(mm-mmm)-0.5);
		for(int i=mmm;i<mm;i++)
		{
			position=negative1[i];
			vb[position/8][position%8]=dd;
		}
	}
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -