//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.h>
#include "Matrix.h"
#include "nr.h"
#include "Unit1.h"

#pragma hdrstop

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
BITMAPINFO bmi;
unsigned char *bits;
Graphics::TBitmap *bmp;
Graphics::TBitmap* Dib;
matrix* Macierz;
int DispMode=2;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::WczytajClick(TObject *Sender)
{
if(OpenDialog1->Execute())
  {

   bmp = Image1->Picture->Bitmap;
   bmp->LoadFromFile(OpenDialog1->FileName);
   bmp->PixelFormat=pf8bit;

   };        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ZamknijClick(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::PoliczFFTClick(TObject *Sender)
{

int isig=1;
//matrix* Macierz;
Macierz=MatrixFromDib(bmp);
Fft2(Macierz->x(), Macierz->n()/2, Macierz->m(), isig);
SortMatrix(Macierz);
try {
FillDibWithMatrix(Image2->Picture->Bitmap,DispMode,0.001,Macierz); }
catch(...){
ShowMessage ("Nie pracuje");};

}
//---------------------------------------------------------------------------
matrix* __fastcall TForm1::MatrixFromDib(Graphics::TBitmap *bmp)
{

   unsigned int *data,*tmp;
   int W=bmp->Width;
   int H=bmp->Height;
   int newH,newW;
   newH=newW=1;
	while(H>newH) newH*=2;
 	while(W>newW) newW*=2;
   data = new unsigned int [newW*newH*2];
   memset(data, 0,newW*newH*2*sizeof(unsigned int));


   tmp=data;

   unsigned char* ptr;


   unsigned int info_size = 0, bits_size = 0;     // Ustal rozmiar nag��wka mapy DIB
   GetDIBSizes(bmp->Handle, info_size, bits_size);// (BITMAPINFOHEADER + tablica kolor�w)
                                                  // oraz rozmiar samej mapy (tablicy pikseli).

   bits = new unsigned char[bits_size];  // Przydziel pami�� na tablic� pikseli.

   try
    {
        if(GetDIB(bmp->Handle, bmp->Palette, &bmi, bits)) // Odczytaj nag��wek BITMAPINFOHEADER,
        {                                                 //  tablic� kolor�w i tablic� pikseli.
         for (int j = 0; j<H ; j++){
              ptr = (unsigned char *)bmp->ScanLine[j];
              for (int i = 0; i < W ; i++){
               	 *tmp++ = ptr[i];
                  tmp++ ;
          //        Memo1->Lines->Add(IntToStr(ptr[i]));
              }
              for(int k=W;k<newW;k++){
             	tmp++;
                tmp++;
              }
         }

        }
      else ShowMessage("Nie udalo sie !");
    }
   catch(...)
    {
     ShowMessage("Blad");
    };

       //  for (int i=1;i<= newW*newH*2;i++)
        //       Memo1->Lines->Add(IntToStr(data[i]));   //????

   matrix* m=new matrix(newH,newW*2,data);
   delete[] data;
return m;

}

//---------------------------------------------------------------------------


void __fastcall TForm1::Fft2(double data[], int nx, int ny, int isign){
unsigned long nn[2];
//nn[0]=0;                    ////????????????
nn[1]=(unsigned long) nx;
nn[2]=(unsigned long) ny;
fourn (data-1, nn, 2, isign);
if (isign==-1){
        double c= double(1.0)/double(nn[1]*nn[2]);
        for( unsigned long i=0;i<0*nn[1]*nn[2];i++ ) data[i]*=c;
        };

//for (int i=1;i<=nx*ny*2;i++)
//Memo1->Lines->Add(FloatToStr(data[i]));   KONTROLNE do data[]
};


//---------------------------------------------------------------------------

void __fastcall TForm1::FillDibWithMatrix(Graphics::TBitmap* Dib,int DispMode,double gain,matrix* M){

if(!M  || !Dib ) return;

   int i,j;
   int W=M->n()/2;
   int H=M->m();
   double r,im,max,tmp;
   Dib->HandleType = bmDIB;
   Dib->PixelFormat = pf8bit;
   Dib->Palette = GrayPalette();
   Dib->Height = H;
   Dib->Width = W;
  // Image2->Picture->Bitmap = Dib;         ///?????to dodalam
   double *v = M->x();
   unsigned char *ptr;

   switch(DispMode){
      	case /*DIB_DISP_REAL*/ 0:
                         for (j = 0; j < H; j++){
                         ptr=(unsigned char *)Dib->ScanLine[j];
                         for (i = 0; i < W; i++){
                         ptr[i] = (unsigned char) floor( gain*fabs( *v++)) ;
                                v++;
      	                }
                  }
                break;
      case /*DIB_DISP_IMAG*/ 1:
                 v++;
 		for (j = 0; j < H; j++){
                         ptr=(unsigned char *)Dib->ScanLine[j];
                         for (i = 0; i < W; i++){
                         ptr[i] = (unsigned char) floor( gain*fabs( *v++ )) ;
                                v++;
                        }
                }
                break;

      case /*DIB_DISP_MODULE*/ 2:
		for (j = 0; j < H; j++){
                ptr=(unsigned char *)Dib->ScanLine[j];
                for (i = 0; i < W; i++){
                r = *v++;
                im = *v++;
                tmp = floor( gain*sqrt(r*r+im*im));
                                if(tmp>255)
				  ptr[i] = 255;
                                else
                                  ptr[i] = tmp;
              	      }
		}
            break;
      case /*DIB_DISP_POWER*/ 3:
       	    for (j = 0; j < H ; j++){
            ptr=(unsigned char *)Dib->ScanLine[j];
             	    	for (i = 0; i < W; i++){
                        r = *v++;
   	          	im = *v++;
                        tmp = floor( gain*(r*r+im*im) );
                                if(tmp>255)
				  ptr[i] = 255;
                                else
                                  ptr[i] = (unsigned char)tmp;

      	      }
	    }
            break;
            }
}
//-------------------------------------------------------------------------

HPALETTE __fastcall TForm1::GrayPalette()
 {
 HPALETTE hpal;
 WORD nColors=256;
 LOGPALETTE* logPal = (LOGPALETTE*) new unsigned char[sizeof(LOGPALETTE)+(nColors-1)*sizeof(PALETTEENTRY)];
 logPal->palVersion = 0x300;
 logPal->palNumEntries = nColors;
 for(int i=0; i<nColors;i++){
 logPal->palPalEntry[i].peRed   = i;
 logPal->palPalEntry[i].peGreen = i;
 logPal->palPalEntry[i].peBlue  = i;
 logPal->palPalEntry[i].peFlags = 0; }
 hpal = CreatePalette(logPal);
 delete[] logPal;
 return hpal;
 }
 //------------------------------------------------------------------------
 void __fastcall TForm1::SortMatrix(matrix* Matrix) {
 int j;
 int H=Matrix->m();
 int W=Matrix->n();
 double *p1,*p2,*tmp;
 // Najpierw przestawiamy kolumny
 tmp = new double[W/2];

   for (j = 0; j < H ; j++){
       p1 = Matrix->x() + j*W;
       p2 = p1+W/2 ;
        memcpy(tmp,p1,sizeof(double)*W/2);
        memcpy(p1,p2,sizeof(double)*W/2);
        memcpy(p2,tmp,sizeof(double)*W/2);
  }
   delete[] tmp;

  //Przestawiamy wiersze
   tmp = new double[W*H/2];
   p1= Matrix->x();
   p2= p1+W*H/2;
   memcpy(tmp,p1,sizeof(double)*W*H/2);
   memcpy(p1,p2,sizeof(double)*W*H/2);
   memcpy(p2,tmp,sizeof(double)*W*H/2);
   delete[] tmp;
}
//-------------------------------------------------------------------------