consinconvertdlg.cpp

来自「《Visual C++视频技术方案宝典》配套光盘」· C++ 代码 · 共 510 行

CPP
510
字号
// ConsinConvertDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ConsinConvert.h"
#include "ConsinConvertDlg.h"
#include "math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

const  double pi = 3.1415926535;

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConsinConvertDlg dialog

CConsinConvertDlg::CConsinConvertDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CConsinConvertDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CConsinConvertDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_Convert = FALSE;
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
}

void CConsinConvertDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CConsinConvertDlg)
	DDX_Control(pDX, IDC_NEWIMAGE, m_NewImage);
	DDX_Control(pDX, IDC_SOURCE, m_Source);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CConsinConvertDlg, CDialog)
	//{{AFX_MSG_MAP(CConsinConvertDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_CONVERT, OnConvert)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConsinConvertDlg message handlers

BOOL CConsinConvertDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	m_hBmp = (HBITMAP) LoadImage(NULL,".\\Source.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

	m_Source.SetBitmap(m_hBmp);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CConsinConvertDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CConsinConvertDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CConsinConvertDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CConsinConvertDlg::OnOK() 
{


}

//RapidTrans函数用于实现快速傅立叶变换
//参数tData表示时域变量,fData表示频域变量,num表示循环次数
void CConsinConvertDlg::RapidTrans(complex<float> * tData,complex<float>* fData,int num)
{
	long  numbers= 1<< num;  //变换点数
	int   m,n,i,size,pData;
	float angle;
	
	//临时缓冲区
	complex<float> *Sec1,*Sec2,*Sec3,*Sec4;
	
	Sec1 = new complex<float>[numbers/2];
	Sec2 = new complex<float>[numbers];
	Sec3 = new complex<float>[numbers];

	for ( m = 0; m<numbers /2; m++)
	{
		angle = -m*pi*2/numbers;   //计算角度
		Sec1[m]= complex<float>(cos(angle),sin(angle));
	}
	memcpy(Sec2,tData,sizeof(complex<float>)*numbers);
	//按蝶形算法进行快速傅立叶变换
	for (i = 0; i<num; i++)
	{
		for (n = 0; n<1 << i;n++)
		{
			size = 1 << (num-i);
			for (m = 0; m<size/2; m++)
			{
				pData = n*size;
				Sec3[pData+m] = Sec2[m+pData]+ Sec2[m+pData+size/2];
				Sec3[m+pData+size/2] = (Sec2[m+pData]-Sec2[m+pData+size/2])* Sec1[m* (1 << i)];		
			}
		}
	
		Sec4 = Sec2;
		Sec2 = Sec3;
		Sec3 = Sec4;
	}
	//重新排序
	
	for (n = 0; n<numbers; n++)
	{
		pData = 0;
		for (m = 0 ; m<num; m++)
		{
			if (n&( 1 << m))
			{
				pData+= 1 << (num-m-1);
			}
		}
		
		fData[n]= Sec2[pData];
	}

	delete Sec1;
	delete Sec2;
	delete Sec3;
}

//实现离散余弦变换
void CConsinConvertDlg::DCT(float *tData, float *fData ,int num)
{
	long  numbers = 1 << num;  //变换点数
	int   m;
	float temp;
	complex<float>* Sec;

	Sec = new complex<float>[numbers*2];
	memset(Sec,0,sizeof(complex<float>)*numbers*2);
	
	for (m = 0; m<numbers;m++)
	{
		Sec[m] = complex<float>(tData[m],0);
	}

	RapidTrans(Sec,Sec,num+1);
	temp = 1/sqrt(numbers);
	
	//计算fData[0]
	fData[0] = Sec[0].real()*temp;
	temp *= sqrt(2);
	//计算fData[u]
	for (m = 1; m<numbers; m++)
	{
		fData[m]= (Sec[m].real()* cos (m*pi/(numbers*2)) + Sec[m].imag()* sin(m*pi/(numbers*2)))*temp;
	}
	free(Sec);
}

#define WIDTH(num)    (((num) + 31) / 32 * 4)
//将位图数据进行离散余弦变换
void CConsinConvertDlg::BmpDCT(LPSTR  pBits, int bWidth, int bHeight,int bLines)
{
	long  x,y;
	long  fwidth,fheight;  //傅立叶变换的宽度和高度
	float temp;

	fwidth = fheight = 1;
	
	long wtemp = 0;
	long htemp = 0;

	bLines = WIDTH(bWidth *8);

	while (fwidth*2<= bWidth)
	{
		fwidth*= 2;
		wtemp ++;
	}
	
	while (fheight*2 <= bHeight)
	{
		fheight *=2;
		htemp ++;
	}

	float* tData = new float[fwidth*fheight];
	float* fData = new float[fwidth*fheight];

	unsigned char* pTempData= NULL;
	for (x = 0; x<fheight; x++)
	{
		for (y = 0; y<fwidth; y++)
		{
			pTempData = (unsigned char*)pBits + bLines* (bHeight-1-x)+y;
			tData[y+x*fwidth] = *(pTempData);
		}
	}

	for (x = 0 ; x< fheight; x++)
	{
		DCT(&tData[fwidth*x],&fData[fwidth*x],wtemp);
	}

	for (x = 0; x<fheight; x++)
	{
		for (y = 0; y<fwidth; y++)
		{
			tData[y*fheight+x] = fData[y+fwidth*x];
		}
	}

	for (y = 0; y<fwidth; y++)
	{
		DCT(&tData[y*fheight],&fData[y*fheight],htemp);
	}

	for (x = 0; x<fheight; x++)
	{
		for (y = 0; y<fwidth;y++)
		{
			temp = fabs(fData[y*fheight+x]);
			if (temp>255)
				temp = 255;
			pTempData = (unsigned char*) pBits+bLines* (bHeight-1-x)+y;
			*(pTempData) = (BYTE)temp;
		}
	}
	free(tData);
	free(fData);
}

void CConsinConvertDlg::OnConvert() 
{
	if (!m_Convert)
	{
		CBitmap bmp;
		bmp.Attach(m_hBmp);

		BITMAPINFO bInfo;
		bmp.GetObject(sizeof(bInfo),&bInfo);
		
		BITMAP bMap;
		bmp.GetBitmap(&bMap);

		CFile file;
		file.Open(".\\Source.bmp",CFile::modeReadWrite);
		int len = file.GetLength();

		HGLOBAL	 hData =  GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,len);

		LPSTR pFile=  (LPSTR) GlobalLock(hData);

		file.Read(pFile,sizeof(BITMAPFILEHEADER));
		
		LPSTR tmp = pFile;

		tmp+=sizeof(BITMAPFILEHEADER);
		file.ReadHuge(tmp,len-sizeof(BITMAPFILEHEADER));

		LPSTR pTemp = pFile;

		pTemp +=14;
		BITMAPINFOHEADER bHeader;
		memcpy(&bHeader,pTemp,40);

		pTemp +=sizeof(BITMAPINFOHEADER);
		int panelsize = 0;
		if (bHeader.biBitCount<16)
			panelsize = pow(2,bHeader.biBitCount)*sizeof(RGBQUAD);
		pTemp += panelsize;
		file.Close();
		BmpDCT(pTemp,bInfo.bmiHeader.biWidth,bInfo.bmiHeader.biHeight,bInfo.bmiHeader.biBitCount);


		file.Open(".\\new.bmp",CFile::modeReadWrite);
		file.Seek(54+panelsize,CFile::begin);

		file.WriteHuge(pTemp,bInfo.bmiHeader.biWidth*bInfo.bmiHeader.biHeight);
		file.Close();
		
		GlobalFree(hData);
		m_NewImage.SetBitmap( (HBITMAP) LoadImage(NULL,".\\new.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE));
		m_Convert = TRUE;
	}
}

//参数描述: pInput表示输入矩阵,8*8大小,pOutput表示输出矩阵
void FDCT(float *pInput,float *pOutput)
 {
	float  data0,data1,data2,data3,data4,data5,data6,data7;
	float  data10,data11,data12,data13;
	float  iData1,iData2,iData3,iData4,iData5,iData11,iData13;

	float *pData;
	float Data[64];
	float tData;
	for (int i=0;i<64;i++)
	{
		Data[i]=pInput[i]; 
	}
	pData=Data; 
	//对行进行计算
	for ( i = 0; i<8; i++) 
	{ 
		data0 = pData[0] + pData[7];
		data7 = pData[0] - pData[7]; 
		data1 = pData[1] + pData[6];
		data6 = pData[1] - pData[6]; 

		data2 = pData[2] + pData[5];
		data5 = pData[2] - pData[5];
		data3 = pData[3] + pData[4];
		data4 = pData[3] - pData[4];

		data10 = data0+ data3;
		data13 = data0-data3;
		data11 = data1+data2;
		data12 = data1-data2;
		
		pData[0] = data10+data11;
		pData[4] = data10- data11;

		iData1 = (data12 + data13) * ((float) 0.707106781); 
		pData[2] =data13 + iData1;
		pData[6] = data13 - iData1; 

		data10 = data4 + data5;
		data11 = data5 + data6; 
		data12 = data6 + data7; 

		iData5 = (data10 - data12) * ((float) 0.382683433); 
		iData2 = ((float) 0.541196100) * data10 + iData5; 
		iData4 = ((float) 1.306562965) * data12 + iData5; 
		iData3 = data11 * ((float) 0.707106781);
		iData11 = data7 + iData3; 
		iData13 = data7 - iData3; 
		pData[5] = iData13 + iData2; 
		pData[3] = iData13 - iData2; 
		pData[1] = iData11 + iData4;
		pData[7] = iData11 - iData4; 
		pData += 8; //移动到下一行 
	}

	pData = Data;

	for (i = 0; i<8; i++)
	{ 
		data0 = pData[0] + pData[56]; 
		data7 = pData[0] - pData[56]; 
		data1 = pData[8] + pData[48];
		data6 = pData[8] - pData[48];
		data2 = pData[16]+ pData[40];
		data5 = pData[16] -pData[40];
		data3 = pData[24] + pData[32];
		data4 = pData[24] - pData[32];

		data10 = data0 + data3;
		data13 = data0 - data3; 
		data11 = data1 + data2; 
		data12 = data1 - data2;

		pData[0] = data10 + data11;
		
		pData[32] = data10 - data11; 
		iData1 = (data12 + data13) * ((float) 0.707106781); 
		pData[16] = data13 + iData1; 
		pData[48] = data13 - iData1; 

		data10 = data4 + data5;
		data11 = data5 + data6;
		data12 = data6 + data7; 

		iData5 = (data10 - data12) * ((float) 0.382683433);
		iData2 = ((float) 0.541196100) * data10 + iData5; 
		iData4 = ((float) 1.306562965) * data12 + iData5;
		iData3 = data11 * ((float) 0.707106781); 
		iData11 = data7 + iData3;
		iData13 = data7 - iData3; 
		pData[40] = iData13 + iData2; 
		pData[24] = iData13 - iData2; 
		pData[8]  = iData11 + iData4;
		pData[56] = iData11 - iData4;
		pData++; //移动到下一列
	} 
	for (i = 0; i < 64; i++)
	{ 
		pOutput[i] = Data[i]; 
	} 
}

⌨️ 快捷键说明

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