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

📄 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 adapornot, btype QTable[8][8]) {
	//construct double dct[][][]
	//if mode==4 hestigram dct->construct btype Q[][][]
	//else { choose mode (qtable)
	//			  if adaptor modify(qtable) according to dct[][][]
	//			  quantify dct->construct btype Q[][][]
	//           send out qtable, n
	//         }
	//send out Q
}

void	idctqt(btype Q2[][8][8], blstype n, ptype & **P2, unsigned int height, unsigned int width,
			   int mode, int level, bool adapornot);






blystype 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=65, 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);
			}
		}
	}
}

int IQuantization(ptype & **IQuanTable,  btype a[][8][8], unsigned int height, unsigned int width, btype QTable[8][8])
{
	IQuanTable = new ptype *[height];
	if (!IQuanTable) {
		printf("Allocate height error.\n");
		return 1;
	}
	for (unsigned int j=0; j<height; j++) {
		IQuanTable[j]=new ptype [width];
		if (!IQuanTable[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]=a[i][u][v]*QTable[u][v];

		Idct(va,vb);

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

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

void HistIQuan(double va[][8][8],btype (*vb)[8][8],blstype NM)
{
	for(int i=0;i++;i<NM)
		va[i][0][0]=vb[i][0][0]*16;
}

//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(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(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(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(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(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 + -