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

📄 arisimageroutines1.cpp

📁 用于声音图像的FFC变换源码
💻 CPP
字号:
// ArisImageRoutines1.cpp: implementation of the ArisImageRoutines class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ArisImageRoutines.h"
#include "ArisImageRoutines1.h"
#include "Complex.h"
#include "FFT2D.h"
#include "FFT1D.h"
#include "DCT2D.h"

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


#define Sqrt2 1.4142136
#define log2(x) (3.321928*log10(x))
#define SWAP(a,b) tempr=(a); (a)=(b); (b)=tempr
#define Pi  3.1415926536

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//this acts like CEvent class
BOOL ThreadFinished[3] = {FALSE};
static int id = 0;

ArisImageRoutines::ArisImageRoutines()
{
	for(int x=0;x<3;x++)
		ThreadFinished[3] = FALSE;
}

ArisImageRoutines::~ArisImageRoutines()
{

}

bool ArisImageRoutines::IsPowerOfTwo (unsigned int x)
{
    if ( x < 2 )
        return false;

    if ( x & (x-1) )        // Thanks to 'byang' for this cute trick!
        return false;

    return true;
}

BOOL ArisImageRoutines::FFT
(
 //input
 CMatrix *ReInput, 
 CMatrix *ImInput /*=NULL*/, 

 //output
 CMatrix *ReOutput /*=NULL*/, 
 CMatrix *ImOutput /*=NULL*/, 

 //direction
 int dir /*=1*/
)
{
	if(ReInput == NULL && ImInput == NULL)
	{
		TRACE("Both input can't be NULL");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Both input can't be NULL");
#endif
		return FALSE;
	}
	
	unsigned int w = ReInput->GetNumColumns();
	unsigned int h = ReInput->GetNumRows();

	unsigned int y,x;

	if(dir != -1 && dir != 1)
	{
		//TRACE("Invalid Direction!");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Invalid Direction!");
#endif
		return FALSE;
	}

	if(!IsPowerOfTwo(w) || !IsPowerOfTwo(h))
	{
		//TRACE("Cannot perform other than 2^n dimension");

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Cannot perform other than 2^n dimension");
#endif
		return FALSE;
	}

	// ok, now we're ready to start

	CFFT2D fft(w, h);

	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			if(ImInput)
			{
				if(!fft.SetInputAt(x,y,(double)ReInput->GetElement(x,y),(double)ImInput->GetElement(x,y)))
				{
					//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
					AfxMessageBox("Cannot set input Value");
#endif
					return FALSE;
				}

			}
			else if(!fft.SetInputAt(x,y,(double)ReInput->GetElement(x,y),0.0))
			{
				//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
				AfxMessageBox("Cannot set input Value");
#endif
					return FALSE;
			}

		}

	//do the core !!!
	if(dir == 1)
	{
		fft.ForwardTransform();
	}
	else if(dir == -1)
	{
		fft.ReverseTransform();
	}
	
	if(ImOutput == NULL || ReOutput == NULL)
	//if Output is NULL, then we do an in-place transform
	{
		
		for(x = 0; x<w ; x++)
			for(y = 0; y<h; y++)
			{
				CComplex complex_result;

				complex_result = fft.GetInputAt(x,y);
					
				//if ImInput is NULL, than the result in ReInput is the magnitude
				if(ImInput == NULL)
					ReInput->SetElement(x,y,complex_result.GetAbs());
				else
				{
					ReInput->SetElement(x,y,complex_result.GetReal());
					ImInput->SetElement(x,y,complex_result.GetImag());
				}
			}
	}
	else
	//if Output is not NULL, then we do an out-place transform
	{
		for(x = 0; x<w ; x++)
			for(y = 0; y<h; y++)
			{
				CComplex complex_result;

				complex_result = fft.GetInputAt(x,y);
					
				ReOutput->SetElement(x,y,complex_result.GetReal());
				ImOutput->SetElement(x,y,complex_result.GetImag());
				
			}
	}

	return TRUE;
}



// I forgot the original author
// but this one is not my work
// I just modified it so that it's more C++
BOOL ArisImageRoutines::DCT
(
 CMatrix *Source, 
 CMatrix *Destination /*=NULL*/, 
 int dir /*=1*/
)
{
	if(Source == NULL)
	{
		//TRACE("Input can't be NULL");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Both input can't be NULL");
#endif
		return FALSE;
	}
	
	int w = Source->GetNumColumns();
	int h = Source->GetNumRows();

	if(w <2 || h <2)
	{
		//TRACE("Matrix too small");

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Matrix too small");
#endif
		return FALSE;
	}

	if(dir != -1 && dir != 1)
	{
		//TRACE("Invalid Direction!");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Invalid Direction!");
#endif
		return FALSE;
	}

	CDCT2D dct(w, h);

	int x,y;
	
	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			if(!dct.SetInputAt(x,y,(double)Source->GetElement(x,y)))
			{
				//TRACE("Cannot set input Value");
#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
				AfxMessageBox("Cannot set input Value");
#endif
					return FALSE;
			}

		}

	//do the core !!!
	if(dir == 1)
	{
		dct.ForwardTransform();
	}
	else if(dir == -1)
	{
		dct.ReverseTransform();
	}
	
	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			if(Destination)
			{
				Destination->SetElement(x,y,dct.GetInputAt(x,y));
			}
			else
			{
				Source->SetElement(x,y,dct.GetInputAt(x,y));
			}
		}


	return TRUE;
}

//threads
UINT fft_thread(void* param)
{
	CFFT2D *fft = (CFFT2D*) param;
	fft->ForwardTransform();
	ThreadFinished[id++] = TRUE;
	return 0;
}

UINT ifft_thread(void* param)
{
	CFFT2D *fft = (CFFT2D*) param;
	fft->ReverseTransform();
	ThreadFinished[id++] = TRUE;
	return 0;
}

BOOL ArisImageRoutines::TRUEFFT
(
	CMatrix *ReInput[3], 
	CMatrix *ImInput[3] /*= NULL*/, 
	CMatrix *ReOutput[3]/* = NULL*/, 
	CMatrix *ImOutput[3]/*= NULL*/,
	int dir /*= 1*/
)
{
	
	//check inputs
	if
	(
		ReInput[0] == NULL && 
		ImInput[0] == NULL &&
		ReInput[0] == NULL && 
		ImInput[0] == NULL &&
		ReInput[0] == NULL && 
		ImInput[0] == NULL
	)
	{
		//TRACE("Both input can't be NULL");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Both input can't be NULL");
#endif
		return FALSE;
	}
	
	unsigned int w = ReInput[0]->GetNumColumns();
	unsigned int h = ReInput[0]->GetNumRows();

	unsigned int y,x,z;

	//check direction
	if(dir != -1 && dir != 1)
	{
		TRACE("Invalid Direction!");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Invalid Direction!");
#endif
		return FALSE;
	}

	//chek dimension
	if(!IsPowerOfTwo(w) || !IsPowerOfTwo(h))
	{
		//TRACE("Cannot perform other than 2^n dimension");

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Cannot perform other than 2^n dimension");
#endif
		return FALSE;
	}

	CFFT2D *fft[3];

	fft[0] = new CFFT2D(w,h);//R
	fft[1] = new CFFT2D(w,h);//G
	fft[2] = new CFFT2D(w,h);//B

	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			for(z = 0;z<3;z++)
				if(ImInput[0] && ImInput[1] && ImInput[2])
				{
					if(!fft[z]->SetInputAt(x,y,(double)ReInput[z]->GetElement(x,y),(double)ImInput[z]->GetElement(x,y)))
					{
						//TRACE("Cannot set input Value");
						#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
							AfxMessageBox("Cannot set input Value");
						#endif
						return FALSE;
					}

				}
				else if(!fft[z]->SetInputAt(x,y,(double)ReInput[z]->GetElement(x,y),0.0))
				{
					//TRACE("Cannot set input Value");
					#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
						AfxMessageBox("Cannot set input Value");
					#endif
						return FALSE;
				}

		}

	//do the core !!!
	if(dir == 1)
	{
		::AfxBeginThread(fft_thread,fft[0],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(fft_thread,fft[1],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(fft_thread,fft[2],THREAD_PRIORITY_NORMAL);
	}
	else if(dir == -1)
	{
		::AfxBeginThread(ifft_thread,fft[0],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(ifft_thread,fft[1],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(ifft_thread,fft[2],THREAD_PRIORITY_NORMAL);
	}
	
	while(!(ThreadFinished[0] || ThreadFinished[1] || ThreadFinished [2]))
		Sleep(500);

	if(ImOutput == NULL || ReOutput == NULL)
	//if Output is NULL, then we do an in-place transform
	{
		
		for(x = 0; x<w ; x++)
			for(y = 0; y<h; y++)
			{
				for(z = 0;z<3;z++)
				{
					CComplex complex_result;

					complex_result = fft[z]->GetInputAt(x,y);
						
					//if ImInput is NULL, than the result in ReInput is the magnitude
					if(ImInput[z] == NULL)
						ReInput[z]->SetElement(x,y,complex_result.GetAbs());
					else
					{
						ReInput[z]->SetElement(x,y,complex_result.GetReal());
						ImInput[z]->SetElement(x,y,complex_result.GetImag());
					}
				}
			}
	}
	else
	//if Output is not NULL, then we do an out-place transform
	{
		for(x = 0; x<w ; x++)
			for(y = 0; y<h; y++)
			{
				for(z = 0;z<3;z++)
				{
					CComplex complex_result;

					complex_result = fft[z]->GetInputAt(x,y);
						
					ReOutput[z]->SetElement(x,y,complex_result.GetReal());
					ImOutput[z]->SetElement(x,y,complex_result.GetImag());
				}
				
			}
	}

	//cleanup

	for(z=0;z<3;z++)
	{
		if(fft[z])
		{
			delete fft[z];
			fft[z] = NULL;
		}
	}

	return TRUE;
}

//threads
static UINT dct_thread(void* param)
{
	CDCT2D *dct = (CDCT2D*) param;
	dct->ForwardTransform();
	ThreadFinished[id++] = TRUE;
	return 0;
}

static UINT idct_thread(void* param)
{
	CDCT2D *dct = (CDCT2D*) param;
	dct->ReverseTransform();
	ThreadFinished[id++] = TRUE;
	return 0;
}

BOOL ArisImageRoutines::TRUEDCT
(
CMatrix *Source[3], 
CMatrix *Destination[3] /*= NULL*/,
int dir /*= 1*/
)
{
	if(Source[0] == NULL || Source[1] == NULL || Source[2] == NULL)
	{
		//TRACE("Input can't be NULL");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Both input can't be NULL");
#endif
		return FALSE;
	}
	
	int w = Source[0]->GetNumColumns();
	int h = Source[0]->GetNumRows();

	if(w <2 || h <2)
	{
		//TRACE("Matrix too small");

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Matrix too small");
#endif
		return FALSE;
	}

	if(dir != -1 && dir != 1)
	{
		//TRACE("Invalid Direction!");		

#ifdef USE_MESSAGE_BOX_FOR_FAILURE
		AfxMessageBox("Invalid Direction!");
#endif
		return FALSE;
	}

	CDCT2D* dct[3];
	dct[0] = new CDCT2D(w,h);
	dct[1] = new CDCT2D(w,h);
	dct[2] = new CDCT2D(w,h);

	int x,y,z;
	
	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			
			for(z = 0;z<3;z++)
			{
				if(!dct[z]->SetInputAt(x,y,(double)Source[z]->GetElement(x,y)))
				{
					//TRACE("Cannot set input Value");
					#ifdef USE_MESSAGE_BOX_FOR_FAILURE					
						AfxMessageBox("Cannot set input Value");
					#endif
					return FALSE;
				}
			}
		}

	//do the core !!!
	if(dir == 1)
	{
		::AfxBeginThread(dct_thread,dct[0],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(dct_thread,dct[1],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(dct_thread,dct[2],THREAD_PRIORITY_NORMAL);


	}
	else if(dir == -1)
	{
		::AfxBeginThread(idct_thread,dct[0],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(idct_thread,dct[1],THREAD_PRIORITY_NORMAL);
		::AfxBeginThread(idct_thread,dct[2],THREAD_PRIORITY_NORMAL);
	}

	while(!(ThreadFinished[0] || ThreadFinished[1] || ThreadFinished [2]))
		Sleep(500);

	for(x = 0; x<w ; x++)
		for(y = 0; y<h; y++)
		{
			for(z = 0;z<3;z++)
			{
				if(Destination[z])
				{
					Destination[z]->SetElement(x,y,dct[z]->GetInputAt(x,y));
				}
				else
				{
					Source[z]->SetElement(x,y,dct[z]->GetInputAt(x,y));
				}
			}
		}

	for(z=0;z<3;z++)
	{
		if(dct[z])
		{
			delete dct[z];
			dct[z] = NULL;
		}
	}

	return TRUE;
}

⌨️ 快捷键说明

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