r641: no message
[ctsim.git] / src / views.cpp
index 6c59f8eb586a3303fd55c2a41034036dbb844a8f..4de349ef9166d95ddb071674fd1f94bae0cb87fc 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (c) 1983-2001 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.139 2001/03/18 18:08:26 kevin Exp $
+**  $Id: views.cpp,v 1.140 2001/03/21 21:45:31 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -241,6 +241,8 @@ EVT_MENU(IFMENU_FILTER_IFFT_COLS, ImageFileView::OnIFFTCols)
 #endif
 EVT_MENU(IFMENU_FILTER_MAGNITUDE, ImageFileView::OnMagnitude)
 EVT_MENU(IFMENU_FILTER_PHASE, ImageFileView::OnPhase)
+EVT_MENU(IFMENU_FILTER_REAL, ImageFileView::OnReal)
+EVT_MENU(IFMENU_FILTER_IMAGINARY, ImageFileView::OnImaginary)
 EVT_MENU(IFMENU_PLOT_ROW, ImageFileView::OnPlotRow)
 EVT_MENU(IFMENU_PLOT_COL, ImageFileView::OnPlotCol)
 #ifdef HAVE_FFT
@@ -251,7 +253,7 @@ EVT_MENU(IFMENU_PLOT_HISTOGRAM, ImageFileView::OnPlotHistogram)
 END_EVENT_TABLE()
 
 ImageFileView::ImageFileView() 
-: wxView(), m_pFrame(NULL), m_pCanvas(NULL), m_pFileMenu(0), m_bMinSpecified(false), m_bMaxSpecified(false)
+: wxView(), m_pFrame(NULL), m_pCanvas(NULL), m_pFileMenu(0), m_pFilterMenu(0), m_bMinSpecified(false), m_bMaxSpecified(false)
 {
   m_iDefaultExportFormatID = ImageFile::EXPORT_FORMAT_PNG;
 }
@@ -817,6 +819,38 @@ ImageFileView::OnPhase (wxCommandEvent& event)
   GetDocument()->Activate();
 }
 
+void
+ImageFileView::OnReal (wxCommandEvent& event)
+{
+  ImageFile& rIF = GetDocument()->getImageFile();
+  if (rIF.isComplex()) {
+    rIF.real (rIF);
+    rIF.labelAdd ("Real component of complex-image");
+    m_bMinSpecified = false;
+    m_bMaxSpecified = false;
+    if (theApp->getAskDeleteNewDocs())
+      GetDocument()->Modify (true);
+    GetDocument()->UpdateAllViews (this);
+  }
+  GetDocument()->Activate();
+}
+
+void
+ImageFileView::OnImaginary (wxCommandEvent& event)
+{
+  ImageFile& rIF = GetDocument()->getImageFile();
+  if (rIF.isComplex()) {
+    rIF.imaginary (rIF);
+    rIF.labelAdd ("Imaginary component of complex-image");
+    m_bMinSpecified = false;
+    m_bMaxSpecified = false;
+    if (theApp->getAskDeleteNewDocs())
+      GetDocument()->Modify (true);
+    GetDocument()->UpdateAllViews (this);
+  }
+  GetDocument()->Activate();
+}
+
 
 ImageFileCanvas* 
 ImageFileView::CreateCanvas (wxFrame* parent)
@@ -849,7 +883,6 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   theApp->setIconForFrame (subframe);
   
   m_pFileMenu = new wxMenu;
-  
   m_pFileMenu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...\tCtrl-P");
   m_pFileMenu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...\tCtrl-F");
   m_pFileMenu->Append(wxID_OPEN, "&Open...\tCtrl-O");
@@ -886,30 +919,33 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   view_menu->Append(IFMENU_VIEW_SCALE_AUTO, "Display Scale &Auto...\tCtrl-A");
   view_menu->Append(IFMENU_VIEW_SCALE_FULL, "Display F&ull Scale\tCtrl-U");
   
-  wxMenu* filter_menu = new wxMenu;
-  filter_menu->Append (IFMENU_FILTER_INVERTVALUES, "In&vert Values");
-  filter_menu->Append (IFMENU_FILTER_SQUARE, "&Square");
-  filter_menu->Append (IFMENU_FILTER_SQRT, "Square &Root");
-  filter_menu->Append (IFMENU_FILTER_LOG, "&Log");
-  filter_menu->Append (IFMENU_FILTER_EXP, "&Exp");
-  filter_menu->AppendSeparator();
+  m_pFilterMenu = new wxMenu;
+  m_pFilterMenu->Append (IFMENU_FILTER_INVERTVALUES, "In&vert Values");
+  m_pFilterMenu->Append (IFMENU_FILTER_SQUARE, "&Square");
+  m_pFilterMenu->Append (IFMENU_FILTER_SQRT, "Square &Root");
+  m_pFilterMenu->Append (IFMENU_FILTER_LOG, "&Log");
+  m_pFilterMenu->Append (IFMENU_FILTER_EXP, "E&xp");
+  m_pFilterMenu->AppendSeparator();
 #ifdef HAVE_FFT
-  filter_menu->Append (IFMENU_FILTER_FFT, "2-D &FFT");
-  filter_menu->Append (IFMENU_FILTER_IFFT, "2-D &IFFT");
-  filter_menu->Append (IFMENU_FILTER_FFT_ROWS, "FFT Rows");
-  filter_menu->Append (IFMENU_FILTER_IFFT_ROWS, "IFFT Rows");
-  filter_menu->Append (IFMENU_FILTER_FFT_COLS, "FFT Columns");
-  filter_menu->Append (IFMENU_FILTER_IFFT_COLS, "IFFT Columns");
-  filter_menu->Append (IFMENU_FILTER_FOURIER, "2-D F&ourier");
-  filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "2-D Inverse Fo&urier");
+  m_pFilterMenu->Append (IFMENU_FILTER_FFT, "2-D &FFT\tCtrl-2");
+  m_pFilterMenu->Append (IFMENU_FILTER_IFFT, "2-D &IFFT\tAlt-2");
+  m_pFilterMenu->Append (IFMENU_FILTER_FFT_ROWS, "FFT Rows");
+  m_pFilterMenu->Append (IFMENU_FILTER_IFFT_ROWS, "IFFT Rows");
+  m_pFilterMenu->Append (IFMENU_FILTER_FFT_COLS, "FFT Columns");
+  m_pFilterMenu->Append (IFMENU_FILTER_IFFT_COLS, "IFFT Columns");
+  m_pFilterMenu->Append (IFMENU_FILTER_FOURIER, "2-D F&ourier");
+  m_pFilterMenu->Append (IFMENU_FILTER_INVERSE_FOURIER, "2-D Inverse Fo&urier");
 #else
-  filter_menu->Append (IFMENU_FILTER_FOURIER, "&Fourier");
-  filter_menu->Append (IFMENU_FILTER_INVERSE_FOURIER, "&Inverse Fourier");
+  m_pFilterMenu->Append (IFMENU_FILTER_FOURIER, "&Fourier");
+  m_pFilterMenu->Append (IFMENU_FILTER_INVERSE_FOURIER, "&Inverse Fourier");
 #endif
-  filter_menu->Append (IFMENU_FILTER_SHUFFLEFOURIERTONATURALORDER, "S&huffle Fourier to Natural Order");
-  filter_menu->Append (IFMENU_FILTER_SHUFFLENATURALTOFOURIERORDER, "Shu&ffle Natural to Fourier Order");
-  filter_menu->Append (IFMENU_FILTER_MAGNITUDE, "&Magnitude");
-  filter_menu->Append (IFMENU_FILTER_PHASE, "&Phase");
+  m_pFilterMenu->Append (IFMENU_FILTER_SHUFFLEFOURIERTONATURALORDER, "Shuffl&e Fourier to Natural Order");
+  m_pFilterMenu->Append (IFMENU_FILTER_SHUFFLENATURALTOFOURIERORDER, "Shuffle &Natural to Fourier Order");
+  m_pFilterMenu->AppendSeparator();
+  m_pFilterMenu->Append (IFMENU_FILTER_MAGNITUDE, "&Magnitude");
+  m_pFilterMenu->Append (IFMENU_FILTER_PHASE, "&Phase");
+  m_pFilterMenu->Append (IFMENU_FILTER_REAL, "Re&al");
+  m_pFilterMenu->Append (IFMENU_FILTER_IMAGINARY, "Ima&ginary");
   
   wxMenu* image_menu = new wxMenu;
   image_menu->Append (IFMENU_IMAGE_ADD, "&Add...");
@@ -952,7 +988,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   menu_bar->Append(edit_menu, "&Edit");
   menu_bar->Append(view_menu, "&View");
   menu_bar->Append(image_menu, "&Image");
-  menu_bar->Append(filter_menu, "Fi&lter");
+  menu_bar->Append(m_pFilterMenu, "Fi&lter");
   menu_bar->Append(m_pMenuAnalyze, "&Analyze");
   menu_bar->Append(help_menu, "&Help");
   
@@ -960,7 +996,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   subframe->Centre(wxBOTH);
   
-  wxAcceleratorEntry accelEntries[8];
+  wxAcceleratorEntry accelEntries[10];
   accelEntries[0].Set (wxACCEL_CTRL, static_cast<int>('A'), IFMENU_VIEW_SCALE_AUTO);
   accelEntries[1].Set (wxACCEL_CTRL, static_cast<int>('U'), IFMENU_VIEW_SCALE_FULL);
   accelEntries[2].Set (wxACCEL_CTRL, static_cast<int>('E'), IFMENU_VIEW_SCALE_MINMAX);
@@ -968,12 +1004,15 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   accelEntries[4].Set (wxACCEL_CTRL, static_cast<int>('C'), IFMENU_EDIT_COPY);
   accelEntries[5].Set (wxACCEL_CTRL, static_cast<int>('X'), IFMENU_EDIT_CUT);
   accelEntries[6].Set (wxACCEL_CTRL, static_cast<int>('V'), IFMENU_EDIT_PASTE);
+  int iEntry = 7;
+#ifdef HAVE_FFT
+  accelEntries[iEntry++].Set (wxACCEL_CTRL, static_cast<int>('2'), IFMENU_FILTER_FFT);
+  accelEntries[iEntry++].Set (wxACCEL_ALT,  static_cast<int>('2'), IFMENU_FILTER_IFFT);
+#endif
 #ifdef wxUSE_GLCANVAS
-  accelEntries[7].Set (wxACCEL_CTRL, static_cast<int>('3'), IFMENU_IMAGE_CONVERT3D);
-  wxAcceleratorTable accelTable (8, accelEntries);
-#else
-  wxAcceleratorTable accelTable (7, accelEntries);
+  accelEntries[iEntry++].Set (wxACCEL_CTRL, static_cast<int>('3'), IFMENU_IMAGE_CONVERT3D);
 #endif
+  wxAcceleratorTable accelTable (iEntry, accelEntries);
   
   subframe->SetAcceleratorTable (accelTable);
   
@@ -1026,6 +1065,17 @@ void
 ImageFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
 {
   const ImageFile& rIF = GetDocument()->getImageFile();
+  if (m_pFilterMenu && rIF.isComplex()) {
+    m_pFilterMenu->Enable(IFMENU_FILTER_REAL, true);
+    m_pFilterMenu->Enable(IFMENU_FILTER_IMAGINARY, true);
+    m_pFilterMenu->Enable(IFMENU_FILTER_PHASE, true);
+    m_pFilterMenu->Enable(IFMENU_FILTER_MAGNITUDE, true);
+  } else {
+    m_pFilterMenu->Enable(IFMENU_FILTER_REAL, false);
+    m_pFilterMenu->Enable(IFMENU_FILTER_IMAGINARY, false);
+    m_pFilterMenu->Enable(IFMENU_FILTER_PHASE, false);
+    m_pFilterMenu->Enable(IFMENU_FILTER_MAGNITUDE, false);
+  }
   ImageFileArrayConst v = rIF.getArray();
   int nx = rIF.nx();
   int ny = rIF.ny();
@@ -1142,17 +1192,26 @@ ImageFileView::OnEditPaste (wxCommandEvent& event)
     
     int nx = rIF.nx();
     int ny = rIF.ny();
+    bool bMonochrome = false;
+
     if (bitmap.Ok() == true && bitmap.GetWidth() == nx && bitmap.GetHeight() == ny) {
       wxImage image (bitmap);
+      double dScale3 = 3 * 255;
       unsigned char* pixels = image.GetData();
       ImageFileArray v = rIF.getArray();
       for (int ix = 0; ix < rIF.nx(); ix++) {
         for (int iy = 0; iy < rIF.ny(); iy++) {
           unsigned int iBase = 3 * (iy * nx + ix);
-          double dR = pixels[iBase] / 255.;
-          double dG = pixels[iBase+1] / 255.;
-          double dB = pixels[iBase+2] / 255.;
-          v[ix][ny - 1 - iy] = ImageFile::colorToGrayscale (dR, dG, dB);
+          if (ix == 0 && iy == 0 && (pixels[iBase] == pixels[iBase+1] && pixels[iBase+1] == pixels[iBase+2]))
+            bMonochrome = true;
+          if (bMonochrome) {
+            v[ix][ny - 1 - iy] = (pixels[iBase]+pixels[iBase+1]+pixels[iBase+2]) / dScale3;
+          } else {
+            double dR = pixels[iBase] / 255.;
+            double dG = pixels[iBase+1] / 255.;
+            double dB = pixels[iBase+2] / 255.;
+            v[ix][ny - 1 - iy] = ImageFile::colorToGrayscale (dR, dG, dB);
+          }
         }
       }
       OnUpdate(this, NULL);
@@ -1472,7 +1531,7 @@ ImageFileView::OnPlotFFTRow (wxCommandEvent& event)
         pcIn[i].im = 0;
     }
     
-    fftw_plan plan = fftw_create_plan (nx, FFTW_FORWARD, FFTW_IN_PLACE);
+    fftw_plan plan = fftw_create_plan (nx, FFTW_FORWARD, FFTW_IN_PLACE | FFTW_ESTIMATE | FFTW_USE_WISDOM);
     fftw_one (plan, pcIn, NULL);
     fftw_destroy_plan (plan);
     
@@ -1482,8 +1541,8 @@ ImageFileView::OnPlotFFTRow (wxCommandEvent& event)
     double* pYMag = new double [nx];
     for (i = 0; i < nx; i++) {
       pX[i] = i;
-      pYReal[i] = pcIn[i].re;
-      pYImag[i] = pcIn[i].im;
+      pYReal[i] = pcIn[i].re / nx;
+      pYImag[i] = pcIn[i].im / nx;
       pYMag[i] = ::sqrt (pcIn[i].re * pcIn[i].re + pcIn[i].im * pcIn[i].im);
     }
     Fourier::shuffleFourierToNaturalOrder (pYReal, nx);
@@ -1575,7 +1634,7 @@ ImageFileView::OnPlotFFTCol (wxCommandEvent& event)
     for (i = 0; i < ny; i++)
       pcIn[i].im = pdTemp[i];
     
-    fftw_plan plan = fftw_create_plan (ny, FFTW_BACKWARD, FFTW_IN_PLACE);
+    fftw_plan plan = fftw_create_plan (ny, FFTW_BACKWARD, FFTW_IN_PLACE | FFTW_ESTIMATE | FFTW_USE_WISDOM);
     fftw_one (plan, pcIn, NULL);
     fftw_destroy_plan (plan);
     
@@ -1585,8 +1644,8 @@ ImageFileView::OnPlotFFTCol (wxCommandEvent& event)
     double* pYMag = new double [ny];
     for (i = 0; i < ny; i++) {
       pX[i] = i;
-      pYReal[i] = pcIn[i].re;
-      pYImag[i] = pcIn[i].im;
+      pYReal[i] = pcIn[i].re / ny;
+      pYImag[i] = pcIn[i].im / ny;
       pYMag[i] = ::sqrt (pcIn[i].re * pcIn[i].re + pcIn[i].im * pcIn[i].im);
     }