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

📄 membitmap.cpp

📁 主要是应用VC进行傅立叶变换和反变换的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

float memBitmap::GetScale()
{
	return Scale;
}

void memBitmap::Release()
{
	if(flag==1)delete bData;
	flag=0;
}

BOOL memBitmap::JpegToBmp(BYTE *buf,long int lenth)
{
	BitData JpegData(buf,lenth);
	BYTE tag[2];
	JpegData.GetBit(8,tag[0]);
	JpegData.GetBit(8,tag[1]);
	if(tag[0]!=0xff||tag[1]!=0xD8) //0xFFD8为jpg标志
	{
		AfxMessageBox("不是合法的Jpeg文件");
		return FALSE;
	}
	TagFlag=FALSE;
	ImageHeight=0;

	while(1)
	{
		if(!JpegData.GetBit(8,tag[0]))return FALSE;
		switch(tag[0])
		{
		case 0xff:
			TagFlag=TRUE;   //如为0xFF,则可能为交换格式
			break;
		case 0xc0:			//SOF0
			if(TagFlag==TRUE)
			{
				BYTE temp;
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				if(temp!=0x08)  //是否baseline
				{
					AfxMessageBox("不是合法的Jpeg文件");
					return FALSE;
				}
				JpegData.GetBit(8,temp); //图象高度
				ImageHeight=temp;
				ImageHeight<<=8;
				JpegData.GetBit(8,temp);
				ImageHeight|=temp;
				JpegData.GetBit(8,temp); //图象宽度
				ImageWidth=temp;
				ImageWidth<<=8;
				JpegData.GetBit(8,temp);
				ImageWidth|=temp;
				JpegData.GetBit(8,CnNum);//成分数
				for(int i=0;i<CnNum;i++)
				{
					JpegData.GetBit(8,CnTable[i]); //成分编号
					JpegData.GetBit(4,CnHSample[i]);//成分水平采样比例
					JpegData.GetBit(4,CnVSample[i]);//成分垂直采样比例
					JpegData.GetBit(8,QuanNum[i]);//成分所用量化表
				}
				TagFlag=FALSE;
			}break;
		case 0xDB:	//DQT,量化表数据
			if(TagFlag==TRUE)
			{
				BYTE temp;
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				JpegData.GetBit(4,temp);
				if(temp!=0)  //是否baseline
				{
					AfxMessageBox("本系统只支持DCT-baseline格式");
					return FALSE;
				}
				JpegData.GetBit(4,temp);
				for(int i=0;i<64;i++)
				{
					JpegData.GetBit(8,QuanTable[temp][i]); //成分编号
				}
				TagFlag=FALSE;
			}break;
		case 0xE0:
			if(TagFlag==TRUE)
			{
				BYTE temp,flag[4];
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				for(int i=0;i<4;i++)
					JpegData.GetBit(8,flag[i]);
				if(flag[0]!='J'&&flag[1]!='F'&&\
					flag[2]!='I'&&flag[3]!='F')  //是否JFIF
				{
					AfxMessageBox("本系统只支持JFIF格式");
					return FALSE;
				}
				TagFlag=FALSE;
			}break;
		case 0xDC:
			if(TagFlag==TRUE)
			{
				if(ImageHeight==0)
				//如在SOF中未定义图象高度,则在此处赋值
				{
					BYTE temp;
					JpegData.GetBit(8,temp);
					JpegData.GetBit(8,temp);
					JpegData.GetBit(8,temp);
					ImageHeight=temp; 
					ImageHeight<<=8;
					JpegData.GetBit(8,temp);
					ImageHeight|=temp;	
				}
				TagFlag=FALSE;
			}break;
		case 0xDD:
			if(TagFlag==TRUE)	//定义重入间隔
			{
				BYTE temp;
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				ReEnterInterval=temp;
				ReEnterInterval<<=8;
				JpegData.GetBit(8,temp);
				ReEnterInterval|=temp;	
				TagFlag=FALSE;
			}break;
		case 0xc4:
			if(TagFlag==TRUE)
			{
				BYTE temp;
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				BYTE DcAc,TableNum;
				JpegData.GetBit(4,DcAc);
				JpegData.GetBit(4,TableNum);
				if(DcAc==0)	//为DC系数所使用的霍夫曼数据
				{
					BYTE num=0;
					for(int i=0;i<16;i++)
					{
						JpegData.GetBit(8,HuffDCBits[TableNum][i]);
						HuffDCPtr[TableNum][i]=num;
						num+=HuffDCBits[TableNum][i];
					}
					for(i=0;i<num;i++)
					{
						JpegData.GetBit(8,HuffDCVar[TableNum][i]);
					}
					int code=0; num=0;
					for(i=0;i<16;i++)
					{
						if(HuffDCBits[TableNum][i]==0)
						{
							HuffDCMinCode[TableNum][i]=0;
							HuffDCMaxCode[TableNum][i]=-1;
							code<<=1;
						}
						else
						{
							HuffDCMinCode[TableNum][i]=code;
							for(int j=0;j<HuffDCBits[TableNum][i];j++)
							{
								HuffDCTable[TableNum][num]=code;
								code++;
								num++;
							}
							//code--;
							HuffDCMaxCode[TableNum][i]=code-1;
							code<<=1;
						}
					}
				}
				else	//AC系数所用霍夫曼数据
				{
					BYTE num=0;
					for(int i=0;i<16;i++)
					{
						JpegData.GetBit(8,HuffACBits[TableNum][i]);
						HuffACPtr[TableNum][i]=num;
						num+=HuffACBits[TableNum][i];
					}
					for(i=0;i<num;i++)
					{
						JpegData.GetBit(8,HuffACVar[TableNum][i]);
					}
					int code=0; num=0;
					for(i=0;i<16;i++)
					{
						if(HuffACBits[TableNum][i]==0)
						{
							HuffACMinCode[TableNum][i]=0;
							HuffACMaxCode[TableNum][i]=-1;
							code<<=1;
						}
						else
						{
							HuffACMinCode[TableNum][i]=code;
							for(int j=0;j<HuffACBits[TableNum][i];j++)
							{
								HuffACTable[TableNum][num]=code;
								code++;
								num++;
							}
							//code--;
							HuffACMaxCode[TableNum][i]=code-1;
							code<<=1;
						}
					}
				}
			}break;
		case 0xDA:
			if(TagFlag==TRUE)
			{
				if(ImageHeight==0)
				{
					AfxMessageBox("不是合法的Jpeg文件");
					return FALSE;
				}
				//分配相应的bmp数据
				if(!CreateDirect(ImageWidth,ImageHeight))
					return FALSE;
				for(int k=0;k<ImageWidth;k++)
					for(int j=0;j<ImageHeight;j++)
						SetPixel(k,j,RGB(0,0,0));
				BYTE temp;
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				if(temp!=CnNum)
				{
					AfxMessageBox("成分(Components)个数不一致");
					return FALSE;
				}
				for(int i=0;i<CnNum;i++)
				{
					JpegData.GetBit(8,temp);
					BYTE CurPtr;
					for(int j=0;j<CnNum;j++)
					{
						if(temp==CnTable[j])CurPtr=j;
					}
					JpegData.GetBit(4,CnDCHuffNum[CurPtr]);
					JpegData.GetBit(4,CnACHuffNum[CurPtr]);
				}
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				JpegData.GetBit(8,temp);
				if(!EnCode(JpegData))
					return FALSE;
				else 
					return TRUE;
				//JpegData.BitPtr=0;
				//TagFlag=FALSE;
			}//break;
		case 0xD9:
			if(TagFlag==TRUE)
			{
				return TRUE;
			}
		default:
			TagFlag=FALSE;
		}
	}
	return TRUE;
}

BOOL memBitmap::EnCode(BitData &JpegData)
{
	int i,j;
	MCUnumber=0;
	xRes=0;
	yRes=0;
	for(i=0;i<CnNum;i++)
	{
		if(CnHSample[i]>xRes)xRes=CnHSample[i];
		if(CnVSample[i]>yRes)yRes=CnVSample[i];
	}
	xRes*=8;yRes*=8;
	int xf,yf;
	if(ImageWidth%xRes!=0)xf=(ImageWidth+xRes)/xRes;
	else xf=ImageWidth/xRes;
	if(ImageHeight%yRes!=0)yf=(ImageHeight+yRes)/yRes;
	else yf=ImageHeight/yRes;
	MCUnumber=xf*yf;
	MCUcount=0;
	for(i=0;i<CnNum;i++)//将成分所需数据按成分编号重新排序
	{
		for(j=i;j<CnNum;j++)
		{
			if(CnTable[j]<CnTable[i])
			{
				BYTE temp;
				temp=CnHSample[j];
				CnHSample[j]=CnHSample[i];
				CnHSample[i]=temp;
				temp=CnVSample[j];
				CnVSample[j]=CnVSample[i];
				CnVSample[i]=temp;
				temp=QuanNum[j];
				QuanNum[j]=QuanNum[i];
				QuanNum[i]=temp;
				temp=CnDCHuffNum[j];
				CnDCHuffNum[j]=CnDCHuffNum[i];
				CnDCHuffNum[i]=temp;
				temp=CnACHuffNum[j];
				CnACHuffNum[j]=CnACHuffNum[i];
				CnACHuffNum[i]=temp;
				temp=CnTable[j];
				CnTable[j]=CnTable[i];
				CnTable[i]=temp;
			}
		}
	}
	for(i=0;i<3;i++)Pred[i]=0;
/*	for(i=0;i<8;i++)
	{
		for(int j=0;j<8;j++)
		{
			DctVar[i][j]=(float)cos((2*j+1)*i*PIE/16);
			if(i==0)DctVar[i][j]/=(float)sqrt(2.0);
		}
	}
*/
	for(i=0;i<8;i++)
	{
		DctVar1[0][i]=sqrt(2)/4;
		DctVar2[i][0]=DctVar1[0][i];
	}

	for(i=1;i<8;i++)
		for(j=0;j<8;j++)
		{
			DctVar1[i][j]=0.5*cos((2*j+1)*i*PIE/16);
			DctVar2[j][i]=DctVar1[i][j];
		}

	int PixelX[10],PixelY[10];
	int DotX[10],DotY[10];
	for(i=0;i<CnNum;i++)
	{
		PixelX[i]=xRes/CnHSample[i];
		PixelY[i]=yRes/CnVSample[i];
		DotX[i]=(xRes/8)/CnHSample[i];
		DotY[i]=(yRes/8)/CnVSample[i];
	}
	int PieceOriX=0;
	int PieceOldX=0;
	while(MCUcount<MCUnumber)
	{
		int i,j,k;
		int CurX=(MCUcount*xRes-PieceOriX)%ImageWidth;
		int CurY=(MCUcount*xRes-PieceOriX)/ImageWidth*yRes;
		for(i=0;i<CnNum;i++)
		{
			for(j=0;j<CnVSample[i];j++)
			{
				for(k=0;k<CnHSample[i];k++)
				{
					if(!EnCodeMCU(JpegData,i,k+CnVSample[i]*j))
						return FALSE;
				}
			}
		}
		for(i=0;i<yRes;i++)
		{
			for(j=0;j<xRes;j++)
			{
				if( (CurX+j<ImageWidth)&&(CurY+i<ImageHeight) )
				{
					double Y,Cb,Cr;
					int Seg=(i/PixelY[0])*CnVSample[0]+j/PixelX[0];
					int xOff=(j/DotX[0])%8;
					int yOff=(i/DotY[0])%8;
					Y=IDct[0][Seg][yOff][xOff];

					Seg=(i/PixelY[1])*CnVSample[1]+j/PixelX[1];
					xOff=(j/DotX[1])%8;
					yOff=(i/DotY[1])%8;
					Cb=IDct[1][Seg][yOff][xOff];

					Seg=(i/PixelY[2])*CnVSample[2]+j/PixelX[2];
					xOff=(j/DotX[2])%8;
					yOff=(i/DotY[2])%8;
					Cr=IDct[2][Seg][yOff][xOff];

					BYTE r,g,b;
					double r1=Y+1.402*(Cr-128);
					double g1=Y-0.34414*(Cb-128)-0.71414*(Cr-128);
					double b1=Y+1.772*(Cb-128);
					if(r1<0)r=0;
					else if(r1>255)r=255;
					else r=(BYTE)r1;
					if(g1<0)g=0;
					else if(g1>255)g=255;
					else g=(BYTE)g1;
					if(b1<0)b=0;
					else if(b1>255)b=255;
					else b=(BYTE)b1;
					SetPixel(CurX+j,CurY+i,RGB(r,g,b));
				}
				else if( CurX+j>=ImageWidth )
				{
					PieceOldX=xRes-(ImageWidth-CurX-PieceOriX);
				}
			}
		}
		PieceOriX=PieceOldX;
		MCUcount++;
	}
	return TRUE;
}

BOOL memBitmap::EnCodeMCU(BitData &JpegData,BYTE Num,BYTE MCUnum)
{
	BYTE HuffDC,HuffAC,Quan;//当前表
	int DotCount=0;
	int iVal=0;			//读出的码值
	BYTE temp,CodeLenth=0;//码长-1
	HuffDC=CnDCHuffNum[Num];
	HuffAC=CnACHuffNum[Num];
	Quan=QuanNum[Num];
	int MCU[64];		//存放霍夫曼解码后的数据
	int MCUQuan[64];	//存放量化后的数据
	int i,j;
	static BYTE DctPosition[8][8]=\
	{	{0,1,5,6,14,15,27,28},\
		{2,4,7,13,16,26,29,42},\
		{3,8,12,17,25,30,41,43},\
		{9,11,18,24,31,40,44,53},\
		{10,19,23,32,39,45,52,54},\
		{20,22,33,38,46,51,55,60},\
		{21,34,37,47,50,56,59,61},\
		{35,36,48,49,57,58,62,63}
	};

	while(1)
	{
		JpegData.GetBit(temp);
		iVal|=temp;
		if(iVal<=HuffDCMaxCode[HuffDC][CodeLenth])break;
		iVal<<=1;
		CodeLenth++;
		if(CodeLenth>8)
		{
			AfxMessageBox("直流数据错");
			return FALSE;
		}
	}
	iVal-=HuffDCMinCode[HuffDC][CodeLenth];
	iVal+=HuffDCPtr[HuffDC][CodeLenth];
	int value=0;
	if(HuffDCVar[HuffDC][iVal]!=0)
	{
		for(i=0;i<HuffDCVar[HuffDC][iVal];i++)
		{
			JpegData.GetBit(temp);
			value<<=1;
			value|=temp;
		}
		if(value>>(HuffDCVar[HuffDC][iVal]-1)==0)//为负值
		{
			value=~value;
			int x=0xffff>>(16-HuffDCVar[HuffDC][iVal]);
			value&=x;
			value=-value;
		}
	}
	Pred[Num]+=value;
	MCU[0]=Pred[Num];
	DotCount=1;
	while(DotCount<64)
	{
		iVal=0;
		CodeLenth=0;
		while(1)
		{
			JpegData.GetBit(temp);
			iVal|=temp;
			if(iVal<=HuffACMaxCode[HuffAC][CodeLenth])break;
			iVal<<=1;
			CodeLenth++;
			if(CodeLenth>=16)
			{
				AfxMessageBox("交流数据错");
				return FALSE;
			}
		}
		iVal-=HuffACMinCode[HuffAC][CodeLenth];
		iVal+=HuffACPtr[HuffAC][CodeLenth];
		BYTE RRRRSSSS=HuffACVar[HuffAC][iVal];
		BYTE RRRR=(RRRRSSSS>>4)&0xf;
		BYTE SSSS=RRRRSSSS&0xf;
		if(RRRRSSSS==0xf0)
		{
			for(int i=0;i<16;i++)
			{
				MCU[DotCount]=0;
				DotCount++;
			}
			continue;
		}
		else if(RRRRSSSS==0)
		{
			for(int i=DotCount;i<64;i++)
			{
				MCU[DotCount]=0;
				DotCount++;
			}
			continue;
		}
		if(SSSS==0)
		{
			AfxMessageBox("不合法的AC系数");
			return FALSE;
		}
		value=0;
		for(i=0;i<SSSS;i++)
		{
			JpegData.GetBit(temp);
			value<<=1;
			value|=temp;
		}
		if((value>>(SSSS-1)==0))//为负值
		{
			value=~value;
			int x=0xffff>>(16-SSSS);
			value&=x;
			value=-value;
		}
		for(int i=0;i<RRRR;i++)
		{
			MCU[DotCount]=0;
			DotCount++;
		}
		MCU[DotCount]=value;
		DotCount++;
	}
	for(i=0;i<64;i++)
	{
		MCUQuan[i]=MCU[i]*QuanTable[Quan][i];
	}

	int DctValue[8][8];
	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
		{
			DctValue[i][j]=MCUQuan[DctPosition[i][j]];
		}
	}

/*	for(int x=0;x<8;x++)
	{
		for(int y=0;y<8;y++)
		{
			double temp=0.0;
			for(int i=0;i<8;i++)
			{
				for(int j=0;j<8;j++)
				{
					temp+=DctVar[i][x]*DctVar[j][y]*DctValue[i][j];
				}
			}
			temp/=4;
			IDct[Num][MCUnum][x][y]=temp+128;
		}
	}*/

	double TempMatrix[8][8];
	for(int x=0;x<8;x++)
	{
		for(int y=0;y<8;y++)
		{
			TempMatrix[x][y]=0;
			for(int k=0;k<8;k++)
				TempMatrix[x][y]+=DctVar2[x][k]*DctValue[k][y];
		}
	}
	for(x=0;x<8;x++)
	{
		for(int y=0;y<8;y++)
		{
			IDct[Num][MCUnum][x][y]=0;
			for(int k=0;k<8;k++)
				IDct[Num][MCUnum][x][y]+=TempMatrix[x][k]*DctVar1[k][y];
			IDct[Num][MCUnum][x][y]+=128;
		}
	}
	return TRUE;
}

void memBitmap::DataToView(class memBitmap &bmp1)
//生成显示用的其他比例文件
//采用双线性插值技术
{
	int width=GetWidth();
	int height=GetHeight();
	int i,j;
	if(Scale==(double)1)
	{
		bmp1.Release();
		bmp1.CreateDirect(width,height);
		for(i=0;i<width;i++)
		{
			for(j=0;j<height;j++)
			{
				COLORREF color=GetPixel(i,j);
				bmp1.SetPixel(i,j,color);
			}
		}
		return;	
	}

	int NewWidth=int((double)width*Scale);
	int NewHeight=int((double)height*Scale);
	bmp1.Release();
	bmp1.CreateDirect(NewWidth,NewHeight);
	
	for(i=0;i<NewWidth;i++)
	{
		for(j=0;j<NewHeight;j++)
		{
			double x,y;
			x=(double)i/Scale;
			y=(double)j/Scale;
			if(x<=0)x=0;
			if(x>=width-1)x=width-1;
			if(y<=0)y=0;
			if(y>=height-1)y=height-1;
			if( ((int)x==0)||((int)x==width-1)||((int)y==0)||((int)y==height-1) )
			{
				COLORREF color=GetPixel((int)x,(int)y);
				bmp1.SetPixel(i,j,color);
			}
			else
			{
				double r1,r2,r3,r4;
				double g1,g2,g3,g4;
				double b1,b2,b3,b4;
				COLORREF c1,c2,c3,c4;
				c1=GetPixel((int)x,(int)y);
				c2=GetPixel((int)x+1,(int)y);
				c3=GetPixel((int)x,(int)y+1);
				c4=GetPixel((int)x+1,(int)y+1);
				double dis1=x-(int)x;
				double dis2=1-x+(int)x;
				double dis3=y-(int)y;
				double dis4=1-y+(int)y;
				r1=GetRValue(c1);
				g1=GetGValue(c1);
				b1=GetBValue(c1);
				r2=GetRValue(c2);
				g2=GetGValue(c2);
				b2=GetBValue(c2);
				r3=GetRValue(c3);
				g3=GetGValue(c3);
				b3=GetBValue(c3);
				r4=GetRValue(c4);
				g4=GetGValue(c4);
				b4=GetBValue(c4);

				int r=int(dis4*(r1*dis2+r2*dis1)+dis3*(r3*dis2+r4*dis1));
				if(r>255)r=255;
				int g=int(dis4*(g1*dis2+g2*dis1)+dis3*(g3*dis2+g4*dis1));
				if(g>255)g=255;
				int b=int(dis4*(b1*dis2+b2*dis1)+dis3*(b3*dis2+b4*dis1));
				if(b>255)b=255;
				
				bmp1.SetPixel(i,j,RGB((BYTE)r,(BYTE)g,(BYTE)b));

//				COLORREF color=GetPixel(int(x+0.5),int(y+0.5));
//				bmp1.SetPixel(i,j,color);			
			}
		}
	}

}

⌨️ 快捷键说明

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