r328: *** empty log message ***
authorKevin M. Rosenberg <kevin@rosenberg.net>
Tue, 2 Jan 2001 05:34:57 +0000 (05:34 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Tue, 2 Jan 2001 05:34:57 +0000 (05:34 +0000)
26 files changed:
ChangeLog
NEWS
TODO
include/Makefile.am
include/array2dfile.h
include/ct.h
include/imagefile.h
include/procsignal.h
libctsim/Makefile.am
libctsim/array2dfile.cpp
libctsim/imagefile.cpp
libctsim/procsignal.cpp
libctsupport/mathfuncs.cpp
libctsupport/plotfile.cpp
msvc/ctsim/ctsim.plg
msvc/libctsim/libctsim.dsp
src/ctsim.cpp
src/ctsim.h
src/dialogs.cpp
src/dialogs.h
src/docs.cpp
src/docs.h
src/views.cpp
src/views.h
tools/phm2if.cpp
tools/phm2pj.cpp

index 9decb06..3a553b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,32 @@
-       TODO
-       Read PlotFile's.
-       Add to ctsim export of imagefiles to standard graphic formats.
+TODO
+       Be consistant with creation of new images
 
+       copy labels from original image to new images
+       
+3.0alpha2 - Released 1/02/01
+       
+       * ctsim: added generation of filter images
+
+       * ctsim: Added 2-image math functions (mul, add, div, sub)
 
-3.0alpha2 
+       * ctsim: Added export of imagefiles to graphic file formats
+
+       * ctsim: Added support for scaling imagefiles in new sizes
+
+       * ctsim: Added ability to save standard phantom definitions as
+       text files suitable for reading.
        
+       * ctsim: Add labels for image transformations and display of labels
+       when performing properties of images.
+
        * processsignal.cpp: Fixed "off by one" bug in
-       shuffleNaturalToFourierOrder when n is even.
+       shuffleNaturalToFourierOrder when n is even. Moved functions to
+       fourier.cpp
 
-       * imagefile: Added FFTW library to imagefile processing
+       * imagefile.cpp: Added FFTW library to imagefile processing. Converted
+       image math functions to complex-valued math.
 
-       * ctsim: added generation of filter images
+       * phantom.cpp: Added ability to save phantom files as ASCII text.
        
 3.0alpha1 - Released 12/29/00
 
diff --git a/NEWS b/NEWS
index efabc37..e2fd6c6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,17 @@
+Version 3.0alpha Features
+
+* Creation of arbitrary filter images
+
+* All features of command line tools are now in graphical ctsim program!
+
+* Complex-valued image files now supported, lots of image math
+ functions added including fourier transformations
+
+* Visual and statistical image comparision functions
+
+* 2D plots of row and column data of single and comparison images
+
 Version 2.5 of CTSim has been released!
 
 New Features of CTSim version 2.5:
diff --git a/TODO b/TODO
index 69aa217..588b906 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,10 +1,6 @@
 Add help button onto dialog's for reconstruction & projections.
-Consider use of wxWindows help file classes.
-
-Consider changing POL to to read tag tokens.
 
-Consider being able to write Phantom files as text and view as
-text in ctsim.
+Consider use of wxWindows help file classes.
 
-FFT filtering requires FFTW library. Add a basic FFT routine.
+FFT filtering requires FFTW library: add a basic FFT routine.
 
index bc6c111..f583054 100644 (file)
@@ -1,4 +1,4 @@
-noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream_subst scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h transformmatrix.h procsignal.h reconstruct.h plotfile.h hashtable.h
+noinst_HEADERS=ct.h ezplot.h pol.h sgp.h array2d.h imagefile.h backprojectors.h mpiworld.h fnetorderstream.h phantom.h timer.h sstream_subst scanner.h projections.h ctsupport.h filter.h array2dfile.h trace.h transformmatrix.h procsignal.h reconstruct.h plotfile.h hashtable.h fourier.h
 
 
 
index 22e8b61..e9d4ab2 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: array2dfile.h,v 1.14 2001/01/01 10:14:34 kevin Exp $
+**  $Id: array2dfile.h,v 1.15 2001/01/02 05:34:57 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
@@ -89,6 +89,7 @@ public:
     const std::string& getDateString () const;
 
     void print (std::ostream& os) const;
+    void printBrief (std::ostream& os) const;\r
 
     Array2dFileLabel (const Array2dFileLabel& rhs);
 
@@ -201,7 +202,11 @@ public:
   const std::string& getFilename (void) const 
       {  return m_filename; }
 
-  void printLabels (std::ostream& os) const;
+  void printLabels (std::ostream& os) const;\r
+  void printLabelsBrief (std::ostream& os) const;\r
+\r
+  unsigned int nLabels() const\r
+  { return m_labels.size(); }\r
 
   typedef std::vector<Array2dFileLabel*>::iterator labelIterator;
   typedef std::vector<Array2dFileLabel*>::const_iterator constLabelIterator;
index 652df0c..b618130 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ct.h,v 1.47 2000/12/19 21:37:51 kevin Exp $
+**  $Id: ct.h,v 1.48 2001/01/02 05:34:57 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
@@ -170,7 +170,8 @@ extern "C" {
 #include "phantom.h"
 #include "scanner.h"
 #include "backprojectors.h"
-#include "filter.h"
+#include "filter.h"\r
+#include "fourier.h"
 #include "procsignal.h"
 #include "projections.h"
 #include "reconstruct.h"
index 945bdbf..3587f1c 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: imagefile.h,v 1.26 2001/01/01 10:14:34 kevin Exp $
+**  $Id: imagefile.h,v 1.27 2001/01/02 05:34:57 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
@@ -119,8 +119,30 @@ typedef const kfloat32* ImageFileColumnConst;
 
 
 class ImageFile : public ImageFileBase
-{
- public:
+{\r
+private:\r
+\r
+  static const char* s_aszFormatName[];\r
+  static const char* s_aszFormatTitle[];\r
+  static const int s_iFormatCount;\r
+
+public:\r
+\r
+  static const int FORMAT_INVALID;\r
+  static const int FORMAT_PGM;\r
+  static const int FORMAT_PGMASCII;\r
+#if HAVE_PNG\r
+  static const int FORMAT_PNG;\r
+  static const int FORMAT_PNG16;\r
+#endif\r
+\r
+  static const int getFormatCount() {return s_iFormatCount;}\r
+  static const char** getFormatNameArray() {return s_aszFormatName;}\r
+  static const char** getFormatTitleArray() {return s_aszFormatTitle;}\r
+  static int convertFormatNameToID (const char* const formatName);\r
+  static const char* convertFormatIDToName (const int formatID);\r
+  static const char* convertFormatIDToTitle (const int formatID);\r
+
   ImageFile (int nx, int ny)
       : ImageFileBase (nx, ny)
   {}
@@ -132,7 +154,7 @@ class ImageFile : public ImageFileBase
   bool convertRealToComplex ();\r
   bool convertComplexToReal ();\r
 
-  void filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param);
+  void filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param, double dInputScale = 1., double dOutputScale = 1.);
 
   void statistics (double& min, double& max, double& mean, double& mode, double& median, double& stddev) const;\r
   void statistics (ImageFileArrayConst v, double& min, double& max, double& mean, double& mode, double& median, double& stddev) const;\r
@@ -146,6 +168,8 @@ class ImageFile : public ImageFileBase
   bool multiplyImages (const ImageFile& rRHS, ImageFile& result) const;\r
   bool divideImages (const ImageFile& rRHS, ImageFile& result) const;\r
 \r
+  bool scaleImage (ImageFile& result) const;\r
+\r
   bool invertPixelValues (ImageFile& result) const;\r
   bool sqrt (ImageFile& result) const;\r
   bool square (ImageFile& result) const;\r
@@ -162,15 +186,17 @@ class ImageFile : public ImageFileBase
 \r
   int display (void) const;
   int displayScaling (const int scaleFactor, ImageFileValue pmin, ImageFileValue pmax) const;
+\r
+  bool exportImage (const char* const pszFormat, const char* const pszFilename, int nxcell, int nycell, double densmin, double densmax);\r
 
 #if HAVE_PNG
-  void writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax);
+  bool writeImagePNG (const char* const outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax);
 #endif
 #if HAVE_GD
-  void writeImageGIF (const char *outfile, int nxcell, int nycell, double densmin, double densmax);
+  bool writeImageGIF (const char* const outfile, int nxcell, int nycell, double densmin, double densmax);
 #endif
-  void writeImagePGM (const char *outfile, int nxcell, int nycell, double densmin, double densmax);
-  void writeImagePGMASCII (const char *outfile, int nxcell, int nycell, double densmin, double densmax);
+  bool writeImagePGM (const char* const outfile, int nxcell, int nycell, double densmin, double densmax);
+  bool writeImagePGMASCII (const char* const outfile, int nxcell, int nycell, double densmin, double densmax);
 };
 
 
index 8eb98c6..2be3b7c 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: procsignal.h,v 1.10 2001/01/01 10:14:34 kevin Exp $
+**  $Id: procsignal.h,v 1.11 2001/01/02 05:34:57 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
@@ -105,14 +105,6 @@ class ProcessSignal {
     static void finiteFourierTransform (const double input[], std::complex<double> output[], const int n, const int direction);
     static void finiteFourierTransform (const std::complex<double> input[], std::complex<double> output[], const int n, const int direction);
     static void finiteFourierTransform (const std::complex<double> input[], double output[], const int n, const int direction);
-
-
-    static void shuffleNaturalToFourierOrder (float* pdVector, const int n);\r
-    static void shuffleNaturalToFourierOrder (double* pdVector, const int n);\r
-    static void shuffleNaturalToFourierOrder (std::complex<double>* pdVector, const int n);\r
-    static void shuffleFourierToNaturalOrder (float* pdVector, const int n);\r
-    static void shuffleFourierToNaturalOrder (double* pdVector, const int n);\r
-    static void shuffleFourierToNaturalOrder (std::complex<double>* pdVector, const int n);\r
 \r
 
  private:
index 28b3173..e8def37 100644 (file)
@@ -1,5 +1,5 @@
 noinst_LIBRARIES = libctsim.a 
-libctsim_a_SOURCES = filter.cpp scanner.cpp projections.cpp phantom.cpp imagefile.cpp backprojectors.cpp array2dfile.cpp trace.cpp procsignal.cpp reconstruct.cpp
+libctsim_a_SOURCES = filter.cpp scanner.cpp projections.cpp phantom.cpp imagefile.cpp backprojectors.cpp array2dfile.cpp trace.cpp procsignal.cpp reconstruct.cpp fourier.cpp
 
 INCLUDES=@my_includes@
 EXTRA_DIST=Makefile.nt
index d0f2d68..c450a0e 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: array2dfile.cpp,v 1.23 2001/01/01 10:14:34 kevin Exp $
+**  $Id: array2dfile.cpp,v 1.24 2001/01/02 05:34:57 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
@@ -137,23 +137,38 @@ Array2dFileLabel::operator= (const Array2dFileLabel& rhs)
   return (*this);
 }
 
-void
-Array2dFileLabel::print (std::ostream& os) const
-{
-  if (m_labelType == L_HISTORY) {
-    os << "History: " << std::endl;
-    os << "  " << m_strLabel << std::endl;
-    os << "  calc time = " << m_calcTime << " secs" << std::endl;
-    os << "  Timestamp = " << getDateString() << std::endl;
-  } else if (m_labelType == L_USER) {
-    os << "Note: " <<  m_strLabel << std::endl;
-    os << "  Timestamp = %s" << getDateString() << std::endl;
-  } else {
-    os << "Unknown (" << m_labelType << "): " <<  m_strLabel << std::endl;
-    os << "  Timestamp = %s" << getDateString() << std::endl;
-  }
-}
-
+void\r
+Array2dFileLabel::print (std::ostream& os) const\r
+{\r
+  if (m_labelType == L_HISTORY) {\r
+    os << "History: " << std::endl;\r
+    os << "  " << m_strLabel << std::endl;\r
+    os << "  calc time = " << m_calcTime << " secs" << std::endl;\r
+    os << "  Timestamp = " << getDateString() << std::endl;\r
+  } else if (m_labelType == L_USER) {\r
+    os << "Note: " <<  m_strLabel << std::endl;\r
+    os << "  Timestamp = %s" << getDateString() << std::endl;\r
+  } else {\r
+    os << "Unknown (" << m_labelType << "): " <<  m_strLabel << std::endl;\r
+    os << "  Timestamp = %s" << getDateString() << std::endl;\r
+  }\r
+}\r
+\r
+void\r
+Array2dFileLabel::printBrief (std::ostream& os) const\r
+{\r
+  if (m_labelType == L_HISTORY) {\r
+    os << "History (";\r
+    if (m_calcTime > 0)\r
+      os << m_calcTime << " secs, ";\r
+    os << getDateString() << "): " << m_strLabel << std::endl;\r
+  } else if (m_labelType == L_USER) {\r
+    os << "Note (" <<  getDateString() << "): " << m_strLabel << std::endl;\r
+  } else {\r
+    os << "Unknown (" << getDateString() << "): " << m_strLabel << std::endl;\r
+  }\r
+}\r
+\r
 
 ///////////////////////////////////////////////////////////////////////////
 // CLASS IMPLEMENTATION
@@ -660,17 +675,27 @@ Array2dFile::arrayDataClear (void)
   }\r
 }
 
-void
-Array2dFile::printLabels (std::ostream& os) const
-{
-  for (constLabelIterator l = m_labels.begin(); l != m_labels.end(); l++) {
-    const Array2dFileLabel& label = **l;
-    
-    label.print (os);
-    os << std::endl;
-  }
-}
-
+void\r
+Array2dFile::printLabels (std::ostream& os) const\r
+{\r
+  for (constLabelIterator l = m_labels.begin(); l != m_labels.end(); l++) {\r
+    const Array2dFileLabel& label = **l;\r
+    \r
+    label.print (os);\r
+    os << std::endl;\r
+  }\r
+}\r
+\r
+void\r
+Array2dFile::printLabelsBrief (std::ostream& os) const\r
+{\r
+  for (constLabelIterator l = m_labels.begin(); l != m_labels.end(); l++) {\r
+    const Array2dFileLabel& label = **l;\r
+    \r
+    label.printBrief (os);\r
+  }\r
+}\r
+\r
 
 const Array2dFileLabel&
 Array2dFile::labelGet (int i) const
index df647ce..0cbd678 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: imagefile.cpp,v 1.28 2001/01/01 10:14:34 kevin Exp $
+**  $Id: imagefile.cpp,v 1.29 2001/01/02 05:34:57 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
 
 #include "ct.h"
 
+const int ImageFile::FORMAT_INVALID = -1;\r
+const int ImageFile::FORMAT_PGM = 0;\r
+const int ImageFile::FORMAT_PGMASCII = 1;\r
+#ifdef HAVE_PNG\r
+const int ImageFile::FORMAT_PNG = 2;\r
+const int ImageFile::FORMAT_PNG16 = 3;\r
+#endif\r
+\r
+const char* ImageFile::s_aszFormatName[] = \r
+{\r
+  {"pgm"},\r
+  {"pgmascii"},\r
+#ifdef HAVE_PNG\r
+  {"png"},\r
+  {"png16"},\r
+#endif\r
+};\r
+\r
+const char* ImageFile::s_aszFormatTitle[] = \r
+{\r
+  {"PGM"},\r
+  {"PGM ASCII"},\r
+  {"PNG"},\r
+  {"PNG 16-bit"},\r
+};\r
+\r
+const int ImageFile::s_iFormatCount = sizeof(s_aszFormatName) / sizeof(const char*);\r
+\r
+\r
 
 F32Image::F32Image (int nx, int ny, int dataType)\r
 : Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32, dataType)\r
@@ -55,7 +84,7 @@ F64Image::F64Image (void)
 }\r
 
 void 
-ImageFile::filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param)
+ImageFile::filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param, double dInputScale, double dOutputScale)
 {\r
   ImageFileArray v = getArray();\r
   SignalFilter filter (filterName, domainName, bw, filt_param);\r
@@ -73,9 +102,9 @@ ImageFile::filterResponse (const char* const domainName, double bw, const char*
 \r
   for (int ix = 0; ix < m_nx; ix++)\r
     for (int iy = 0; iy < m_ny; iy++) {\r
-      long lD2 = (ix - iXCenter) * (ix - iXCenter) + (iy - iYCenter) * (iy - iYCenter);\r
-      double r = ::sqrt (static_cast<double>(lD2));\r
-      v[ix][iy] = filter.response (r);\r
+      long lD2 = ((ix - iXCenter) * (ix - iXCenter)) + ((iy - iYCenter) * (iy - iYCenter));\r
+      double r = ::sqrt (static_cast<double>(lD2)) * dInputScale;\r
+      v[ix][iy] = filter.response (r) * dOutputScale;\r
     }\r
 #else
   int hx = (m_nx - 1) / 2;
@@ -356,18 +385,29 @@ ImageFile::subtractImages (const ImageFile& rRHS, ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArrayConst vRHS = rRHS.getArray();\r
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in1 = vLHS[ix];\r
-    ImageFileColumnConst in2 = vRHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      *out++ = *in1++ - *in2++;\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      vResult[ix][iy] = vLHS[ix][iy] - vRHS[ix][iy];\r
+      if (result.isComplex()) {\r
+        vResultImag[ix][iy] = 0;\r
+        if (isComplex())\r
+          vResultImag[ix][iy] += vLHSImag[ix][iy];\r
+        if (rRHS.isComplex())\r
+          vResultImag[ix][iy] -= vRHSImag[ix][iy];\r
+      }\r
+    }\r
   }\r
-  \r
+    \r
   return true;\r
 }\r
 
@@ -379,16 +419,27 @@ ImageFile::addImages (const ImageFile& rRHS, ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArrayConst vRHS = rRHS.getArray();\r
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in1 = vLHS[ix];\r
-    ImageFileColumnConst in2 = vRHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      *out++ = *in1++ + *in2++;\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      vResult[ix][iy] = vLHS[ix][iy] + vRHS[ix][iy];\r
+      if (result.isComplex()) {\r
+        vResultImag[ix][iy] = 0;\r
+        if (isComplex())\r
+          vResultImag[ix][iy] += vLHSImag[ix][iy];\r
+        if (rRHS.isComplex())\r
+          vResultImag[ix][iy] += vRHSImag[ix][iy];\r
+      }\r
+    }\r
   }\r
   \r
   return true;\r
@@ -402,18 +453,34 @@ ImageFile::multiplyImages (const ImageFile& rRHS, ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArrayConst vRHS = rRHS.getArray();\r
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in1 = vLHS[ix];\r
-    ImageFileColumnConst in2 = vRHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      *out++ = *in1++ * *in2++;\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cRHS (vRHS[ix][iy], 0);\r
+        if (rRHS.isComplex())\r
+          cRHS.imag (vRHSImag[ix][iy]);\r
+        std::complex<double> cResult = cLHS * cRHS;\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else\r
+        vResult[ix][iy] = vLHS[ix][iy] * vRHS[ix][iy];\r
+    }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
@@ -425,22 +492,38 @@ ImageFile::divideImages (const ImageFile& rRHS, ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArrayConst vRHS = rRHS.getArray();\r
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in1 = vLHS[ix];\r
-    ImageFileColumnConst in2 = vRHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
     for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (*in2 != 0.)\r
-        *out++ = *in1++ / *in2++;\r
-      else\r
-        *out++ = 0;\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cRHS (vRHS[ix][iy], 0);\r
+        if (rRHS.isComplex())\r
+          cRHS.imag (vRHSImag[ix][iy]);\r
+        std::complex<double> cResult = cLHS / cRHS;\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else {\r
+        if (vRHS != 0)\r
+          vResult[ix][iy] = vLHS[ix][iy] / vRHS[ix][iy];\r
+        else\r
+          vResult[ix][iy] = 0;\r
+      }\r
     }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
@@ -453,6 +536,9 @@ ImageFile::invertPixelValues (ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
   ImageFileArray vResult = result.getArray();\r
   \r
@@ -473,20 +559,40 @@ ImageFile::sqrt (ImageFile& result) const
     sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
     return false;\r
   }\r
+\r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
   \r
+  bool bComplexOutput = result.isComplex();\r
   ImageFileArrayConst vLHS = getArray();\r
+  if (! bComplexOutput)   // check if should convert to complex output\r
+    for (unsigned int ix = 0; ix < m_nx; ix++)\r
+      for (unsigned int iy = 0; iy < m_ny; iy++)\r
+        if (! bComplexOutput && vLHS[ix][iy] < 0) {\r
+          result.convertRealToComplex();\r
+          bComplexOutput = true;\r
+          break;\r
+        }\r
+\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in = vLHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      if (*in < 0)\r
-        *out++ = -::sqrt(-*in++);\r
-      else\r
-        *out++ = ::sqrt(*in++);\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cResult = std::sqrt(cLHS);\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else\r
+        vResult[ix][iy] = ::sqrt (vLHS[ix][iy]);\r
+    }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
@@ -498,19 +604,29 @@ ImageFile::log (ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in = vLHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      if (*in <= 0)\r
-        *out++ = 0;\r
-      else\r
-        *out++ = ::log(*in++);\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cResult = std::log (cLHS);\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else\r
+        vResult[ix][iy] = ::log (vLHS[ix][iy]);\r
+    }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
@@ -521,95 +637,69 @@ ImageFile::exp (ImageFile& result) const
     sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
     return false;\r
   }\r
-  \r
+    \r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in = vLHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      *out++ = ::exp (*in++);\r
+    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cResult = std::exp (cLHS);\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else\r
+        vResult[ix][iy] = ::exp (vLHS[ix][iy]);\r
+    }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
-namespace ProcessImage {\r
-\r
-void\r
-shuffleFourierToNaturalOrder (ImageFile& im)\r
+bool\r
+ImageFile::scaleImage (ImageFile& result) const\r
 {\r
-  ImageFileArray vReal = im.getArray();\r
-  ImageFileArray vImag = im.getImaginaryArray();\r
-  unsigned int ix, iy;\r
-  unsigned int nx = im.nx();\r
-  unsigned int ny = im.ny();\r
-\r
-  // shuffle each column\r
-  for (ix = 0; ix < nx; ix++) {\r
-    ProcessSignal::shuffleFourierToNaturalOrder (vReal[ix], ny);\r
-    if (im.isComplex())\r
-      ProcessSignal::shuffleFourierToNaturalOrder (vImag[ix], ny);\r
-  }\r
+  unsigned int nx = m_nx;\r
+  unsigned int ny = m_ny;\r
+  unsigned int newNX = result.nx();\r
+  unsigned int newNY = result.ny();\r
 \r
-  // shuffle each row\r
-  float* pRow = new float [nx];\r
-  for (iy = 0; iy < ny; iy++) {\r
-    for (ix = 0; ix < nx; ix++)\r
-      pRow[ix] = vReal[ix][iy];\r
-    ProcessSignal::shuffleFourierToNaturalOrder (pRow, nx);\r
-    for (ix = 0; ix < nx; ix++)\r
-      vReal[ix][iy] = pRow[ix];\r
-    if (im.isComplex()) {\r
-      for (ix = 0; ix < nx; ix++)\r
-        pRow[ix] = vImag[ix][iy];\r
-      ProcessSignal::shuffleFourierToNaturalOrder (pRow, nx);;\r
-      for (ix = 0; ix < nx; ix++)\r
-        vImag[ix][iy] = pRow[ix];\r
-    }\r
-  }\r
-  delete pRow;\r
-}\r
\r
-void\r
-shuffleNaturalToFourierOrder (ImageFile& im)\r
-{\r
-  ImageFileArray vReal = im.getArray();\r
-  ImageFileArray vImag = im.getImaginaryArray();\r
-  unsigned int ix, iy;\r
-  unsigned int nx = im.nx();\r
-  unsigned int ny = im.ny();\r
-\r
-  // shuffle each x column\r
-  for (ix = 0; ix < nx; ix++) {\r
-    ProcessSignal::shuffleNaturalToFourierOrder (vReal[ix], ny);\r
-    if (im.isComplex())\r
-      ProcessSignal::shuffleNaturalToFourierOrder (vImag[ix], ny);\r
-  }\r
+  double dXScale = static_cast<double>(newNX) / static_cast<double>(nx);\r
+  double dYScale = static_cast<double>(newNY) / static_cast<double>(ny);\r
+\r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
 \r
-  // shuffle each y row\r
-  float* pRow = new float [nx];\r
-  for (iy = 0; iy < ny; iy++) {\r
-    for (ix = 0; ix < nx; ix++)\r
-      pRow[ix] = vReal[ix][iy];\r
-    ProcessSignal::shuffleNaturalToFourierOrder (pRow, nx);\r
-    for (ix = 0; ix < nx; ix++)\r
-      vReal[ix][iy] = pRow[ix];\r
-    if (im.isComplex()) {\r
-      for (ix = 0; ix < nx; ix++)\r
-        pRow[ix] = vImag[ix][iy];\r
-      ProcessSignal::shuffleNaturalToFourierOrder (pRow, nx);\r
-      for (ix = 0; ix < nx; ix++)\r
-        vImag[ix][iy] = pRow[ix];\r
+  ImageFileArrayConst vReal = getArray();\r
+  ImageFileArrayConst vImag = getImaginaryArray();\r
+  ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
+  \r
+  for (unsigned int ix = 0; ix < newNX; ix++) {\r
+    for (unsigned int iy = 0; iy < newNY; iy++) {\r
+      unsigned int scaleNX = static_cast<unsigned int> (ix / dXScale);\r
+      unsigned int scaleNY = static_cast<unsigned int> (iy / dYScale);\r
+      vResult[ix][iy] = vReal[scaleNX][scaleNY];\r
+      if (result.isComplex()) {\r
+        if (isComplex())\r
+          vResultImag[ix][iy] = vImag[scaleNX][scaleNY];\r
+        else\r
+        vResultImag[ix][iy] = 0;\r
+      }\r
     }\r
   }\r
-  delete [] pRow;\r
+  \r
+  return true;\r
 }\r
 \r
\r
-}; // namespace ProcessIamge\r
-\r
 #ifdef HAVE_FFTW\r
 bool\r
 ImageFile::fft (ImageFile& result) const\r
@@ -620,7 +710,7 @@ ImageFile::fft (ImageFile& result) const
   }\r
 \r
   if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.reallocRealToComplex ())\r
+    if (! result.convertRealToComplex ())\r
       return false;\r
   }\r
 \r
@@ -660,7 +750,7 @@ ImageFile::fft (ImageFile& result) const
   delete in;\r
 \r
 \r
-  ProcessImage::shuffleFourierToNaturalOrder (result);\r
+  Fourier::shuffleFourierToNaturalOrder (result);\r
 \r
   return true;\r
 }\r
@@ -675,7 +765,7 @@ ImageFile::ifft (ImageFile& result) const
   }\r
 \r
   if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.reallocRealToComplex ())\r
+    if (! result.convertRealToComplex ())\r
       return false;\r
   }\r
 \r
@@ -693,7 +783,7 @@ ImageFile::ifft (ImageFile& result) const
         vImagResult[ix][iy] = 0;\r
     }\r
 \r
-  ProcessImage::shuffleNaturalToFourierOrder (result);\r
+  Fourier::shuffleNaturalToFourierOrder (result);\r
 \r
   fftw_complex* in = new fftw_complex [m_nx * m_ny];\r
 \r
@@ -735,10 +825,9 @@ ImageFile::fourier (ImageFile& result) const
     return false;\r
   }\r
   \r
-  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.reallocRealToComplex ())\r
+  if (! result.isComplex())\r
+    if (! result.convertRealToComplex ())\r
       return false;\r
-  }\r
   \r
   ImageFileArrayConst vLHS = getArray();\r
   ImageFileArrayConst vLHSImag = getImaginaryArray();\r
@@ -787,33 +876,22 @@ ImageFile::fourier (ImageFile& result) const
       complexOut[ix][iy] = complexOutRow[ix];\r
   }\r
   delete [] pX;\r
-  \r
-  // shuffle each column\r
-  for (ix = 0; ix < m_nx; ix++)\r
-    ProcessSignal::shuffleFourierToNaturalOrder (complexOut[ix], m_ny);\r
-  \r
-  // shuffle each row\r
-  for (iy = 0; iy < m_ny; iy++) {\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      complexOutRow[ix] = complexOut[ix][iy];\r
-    ProcessSignal::shuffleFourierToNaturalOrder (complexOutRow, m_nx);;\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      complexOut[ix][iy] = complexOutRow[ix];\r
-    \r
-  }\r
   delete [] complexOutRow;\r
-  \r
+\r
   for (ix = 0; ix < m_nx; ix++)\r
     for (iy = 0; iy < m_ny; iy++) {\r
       vRealResult[ix][iy] = complexOut[ix][iy].real();\r
       vImagResult[ix][iy] = complexOut[ix][iy].imag();\r
     }\r
     \r
-    for (ix = 0; ix < m_nx; ix++)\r
-      delete [] complexOut[ix];\r
-    delete [] complexOut;\r
+  Fourier::shuffleFourierToNaturalOrder (result);\r
+\r
+  // delete complexOut matrix\r
+  for (ix = 0; ix < m_nx; ix++)\r
+    delete [] complexOut[ix];\r
+  delete [] complexOut;\r
     \r
-    return true;\r
+  return true;\r
 }\r
 \r
 bool\r
@@ -825,50 +903,40 @@ ImageFile::inverseFourier (ImageFile& result) const
   }\r
   \r
   if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.reallocRealToComplex ())\r
+    if (! result.convertRealToComplex ())\r
       return false;\r
   }\r
   \r
   ImageFileArrayConst vLHSReal = getArray();\r
   ImageFileArrayConst vLHSImag = getImaginaryArray();\r
+  ImageFileArray vRealResult = result.getArray();\r
+  ImageFileArray vImagResult = result.getImaginaryArray();\r
   \r
   unsigned int ix, iy;\r
-\r
   // alloc 2d complex output matrix\r
   CTSimComplex** complexOut = new CTSimComplex* [m_nx];\r
   for (ix = 0; ix < m_nx; ix++)\r
     complexOut[ix] = new CTSimComplex [m_ny];\r
 \r
-  // put input image into complexOut\r
+  // put input image into result\r
   for (ix = 0; ix < m_nx; ix++)\r
     for (iy = 0; iy < m_ny; iy++) {\r
-      complexOut[ix][iy].real (vLHSReal[ix][iy]);\r
+      vRealResult[ix][iy] = vLHSReal[ix][iy];\r
       if (isComplex())\r
-        complexOut[ix][iy].imag (vLHSImag[ix][iy]);\r
+        vImagResult[ix][iy] = vLHSImag[ix][iy];\r
       else\r
-        complexOut[ix][iy].imag (0);\r
+        vImagResult[ix][iy] = 0;\r
     }\r
 \r
-  // shuffle each x column\r
-  for (ix = 0; ix < m_nx; ix++)\r
-    ProcessSignal::shuffleNaturalToFourierOrder (complexOut[ix], m_ny);\r
-\r
-  // shuffle each y row\r
-  CTSimComplex* pComplexRow = new CTSimComplex [m_nx];\r
-  for (iy = 0; iy < m_ny; iy++) {\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      pComplexRow[ix] = complexOut[ix][iy];\r
-    ProcessSignal::shuffleNaturalToFourierOrder (pComplexRow, m_nx);\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      complexOut[ix][iy] = pComplexRow[ix];\r
-  }\r
-  delete [] pComplexRow;\r
+  Fourier::shuffleNaturalToFourierOrder (result);\r
 \r
   // ifourier each x column\r
   CTSimComplex* pCol = new CTSimComplex [m_ny];\r
   for (ix = 0; ix < m_nx; ix++) {\r
-    for (iy = 0; iy < m_ny; iy++)\r
-      pCol[iy] = complexOut[ix][iy];\r
+    for (iy = 0; iy < m_ny; iy++) {\r
+      pCol[iy].real (vRealResult[ix][iy]);\r
+      pCol[iy].imag (vImagResult[ix][iy]);\r
+    }\r
     ProcessSignal::finiteFourierTransform (pCol, complexOut[ix], m_ny,  ProcessSignal::BACKWARD);\r
   }\r
   delete [] pCol;\r
@@ -886,8 +954,6 @@ ImageFile::inverseFourier (ImageFile& result) const
   delete [] complexInRow;\r
   delete [] complexOutRow;\r
 \r
-  ImageFileArray vRealResult = result.getArray();\r
-  ImageFileArray vImagResult = result.getImaginaryArray();\r
   for (ix = 0; ix < m_nx; ix++)\r
     for (iy = 0; iy < m_ny; iy++) {\r
       vRealResult[ix][iy] = complexOut[ix][iy].real();\r
@@ -913,8 +979,8 @@ ImageFile::magnitude (ImageFile& result) const
   \r
   ImageFileArray vReal = getArray();\r
   ImageFileArray vImag = getImaginaryArray();\r
-  \r
   ImageFileArray vRealResult = result.getArray();\r
+\r
   for (unsigned int ix = 0; ix < m_nx; ix++)\r
     for (unsigned int iy = 0; iy < m_ny; iy++) {\r
       if (isComplex()) \r
@@ -924,7 +990,7 @@ ImageFile::magnitude (ImageFile& result) const
     }\r
 \r
   if (result.isComplex())\r
-    result.reallocComplexToReal();\r
+    result.convertComplexToReal();\r
   \r
     return true;\r
 }\r
@@ -939,8 +1005,8 @@ ImageFile::phase (ImageFile& result) const
   \r
   ImageFileArray vReal = getArray();\r
   ImageFileArray vImag = getImaginaryArray();\r
-  \r
   ImageFileArray vRealResult = result.getArray();\r
+\r
   for (unsigned int ix = 0; ix < m_nx; ix++)\r
     for (unsigned int iy = 0; iy < m_ny; iy++) {\r
       if (isComplex())\r
@@ -950,7 +1016,7 @@ ImageFile::phase (ImageFile& result) const
     }\r
     \r
   if (result.isComplex())\r
-    result.reallocComplexToReal();\r
+    result.convertComplexToReal();\r
   \r
   return true;\r
 }\r
@@ -963,24 +1029,92 @@ ImageFile::square (ImageFile& result) const
     return false;\r
   }\r
   \r
+  if (isComplex() && ! result.isComplex())\r
+    result.convertRealToComplex();\r
+\r
   ImageFileArrayConst vLHS = getArray();\r
+  ImageFileArrayConst vLHSImag = getImaginaryArray();\r
   ImageFileArray vResult = result.getArray();\r
+  ImageFileArray vResultImag = result.getImaginaryArray();\r
   \r
   for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumnConst in = vLHS[ix];\r
-    ImageFileColumn out = vResult[ix];\r
     for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      *out++ = *in * *in;\r
-      in++;\r
+      if (result.isComplex()) {\r
+        std::complex<double> cLHS (vLHS[ix][iy], 0);\r
+        if (isComplex())\r
+          cLHS.imag (vLHSImag[ix][iy]);\r
+        std::complex<double> cResult = cLHS * cLHS;\r
+        vResult[ix][iy] = cResult.real();\r
+        vResultImag[ix][iy] = cResult.imag();\r
+      } else\r
+        vResult[ix][iy] = vLHS[ix][iy] * vLHS[ix][iy];\r
     }\r
   }\r
   \r
+  \r
   return true;\r
 }\r
 \r
+int\r
+ImageFile::convertFormatNameToID (const char* const formatName)\r
+{\r
+  int formatID = FORMAT_INVALID;\r
 \r
-void 
-ImageFile::writeImagePGM (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
+  for (int i = 0; i < s_iFormatCount; i++)\r
+      if (strcasecmp (formatName, s_aszFormatName[i]) == 0) {\r
+         formatID = i;\r
+         break;\r
+      }\r
+\r
+  return (formatID);\r
+}\r
+\r
+const char*\r
+ImageFile::convertFormatIDToName (int formatID)\r
+{\r
+  static const char *formatName = "";\r
+\r
+  if (formatID >= 0 && formatID < s_iFormatCount)\r
+      return (s_aszFormatName[formatID]);\r
+\r
+  return (formatName);\r
+}\r
+\r
+const char*\r
+ImageFile::convertFormatIDToTitle (const int formatID)\r
+{\r
+  static const char *formatTitle = "";\r
+\r
+  if (formatID >= 0 && formatID < s_iFormatCount)\r
+      return (s_aszFormatTitle[formatID]);\r
+\r
+  return (formatTitle);\r
+}\r
+\r
+bool\r
+ImageFile::exportImage (const char* const pszFormat, const char* const pszFilename, int nxcell, int nycell, double densmin, double densmax)\r
+{\r
+  int iFormatID = convertFormatNameToID (pszFormat);\r
+  if (iFormatID == FORMAT_INVALID) {\r
+    sys_error (ERR_SEVERE, "Invalid format %s [ImageFile::exportImage]", pszFormat);\r
+    return false;\r
+  }\r
+\r
+  if (iFormatID == FORMAT_PGM)\r
+    return writeImagePGM (pszFilename, nxcell, nycell, densmin, densmax);\r
+  else if (iFormatID == FORMAT_PGMASCII)\r
+    return writeImagePGMASCII (pszFilename, nxcell, nycell, densmin, densmax);\r
+  else if (iFormatID == FORMAT_PNG)\r
+    return writeImagePNG (pszFilename, 8, nxcell, nycell, densmin, densmax);\r
+  else if (iFormatID == FORMAT_PNG16)\r
+    return writeImagePNG (pszFilename, 16, nxcell, nycell, densmin, densmax);\r
+\r
+  sys_error (ERR_SEVERE, "Invalid format %s [ImageFile::exportImage]", pszFormat);\r
+  return false;\r
+}\r
+\r
+bool
+ImageFile::writeImagePGM (const char* const outfile, int nxcell, int nycell, double densmin, double densmax)
 {
   FILE *fp;
   int nx = m_nx;
@@ -990,7 +1124,7 @@ ImageFile::writeImagePGM (const char *outfile, int nxcell, int nycell, double de
   unsigned char* rowp = new unsigned char [nx * nxcell];
   
   if ((fp = fopen (outfile, "wb")) == NULL)
-    return;
+    return false;
   
   fprintf(fp, "P5\n");
   fprintf(fp, "%d %d\n", nx, ny);
@@ -1012,11 +1146,13 @@ ImageFile::writeImagePGM (const char *outfile, int nxcell, int nycell, double de
   }
   \r
   delete rowp;
-  fclose(fp);
+  fclose(fp);\r
+\r
+  return true;
 }
 
-void 
-ImageFile::writeImagePGMASCII (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
+bool
+ImageFile::writeImagePGMASCII (const char* const outfile, int nxcell, int nycell, double densmin, double densmax)
 {
   FILE *fp;
   int nx = m_nx;
@@ -1026,7 +1162,7 @@ ImageFile::writeImagePGMASCII (const char *outfile, int nxcell, int nycell, doub
   unsigned char* rowp = new unsigned char [nx * nxcell];
   
   if ((fp = fopen (outfile, "wb")) == NULL)
-    return;
+    return false;
   
   fprintf(fp, "P2\n");
   fprintf(fp, "%d %d\n", nx, ny);
@@ -1049,17 +1185,16 @@ ImageFile::writeImagePGMASCII (const char *outfile, int nxcell, int nycell, doub
   }
   \r
   delete rowp;
-  fclose(fp);
+  fclose(fp);\r
+\r
+  return true;
 }
 
 
 #ifdef HAVE_PNG
-void 
-ImageFile::writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax)
+bool
+ImageFile::writeImagePNG (const char* const outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax)
 {
-  FILE *fp;
-  png_structp png_ptr;
-  png_infop info_ptr;
   double max_out_level = (1 << bitdepth) - 1;
   int nx = m_nx;
   int ny = m_ny;
@@ -1067,29 +1202,30 @@ ImageFile::writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nyc
   
   unsigned char* rowp = new unsigned char [nx * nxcell * (bitdepth / 8)];
   
-  if ((fp = fopen (outfile, "wb")) == NULL)
-    return;
+  FILE *fp = fopen (outfile, "wb");\r
+  if (! fp)
+    return false;
   
-  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+  png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
   if (! png_ptr)
-    return;
+    return false;
   
-  info_ptr = png_create_info_struct(png_ptr);
+  png_infop info_ptr = png_create_info_struct (png_ptr);
   if (! info_ptr) {
-    png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
-    fclose(fp);
-    return;
+    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
+    fclose (fp);
+    return false;
   }
   
-  if (setjmp(png_ptr->jmpbuf)) {
-    png_destroy_write_struct(&png_ptr, &info_ptr);
-    fclose(fp);
-    return;
+  if (setjmp (png_ptr->jmpbuf)) {
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    fclose (fp);
+    return false;
   }
   
   png_init_io(png_ptr, fp);
   
-  png_set_IHDR(png_ptr, info_ptr, nx * nxcell, ny * nycell, bitdepth, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_DEFAULT);
+  png_set_IHDR (png_ptr, info_ptr, nx * nxcell, ny * nycell, bitdepth, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_DEFAULT);
   
   png_write_info(png_ptr, info_ptr);
   for (int irow = ny - 1; irow >= 0; irow--) {
@@ -1115,11 +1251,13 @@ ImageFile::writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nyc
       png_write_rows (png_ptr, &row_pointer, 1);
   }
   
-  png_write_end(png_ptr, info_ptr);
-  png_destroy_write_struct(&png_ptr, &info_ptr);
+  png_write_end (png_ptr, info_ptr);
+  png_destroy_write_struct (&png_ptr, &info_ptr);
   delete rowp;\r
   
-  fclose(fp);
+  fclose(fp);\r
+\r
+  return true;
 }
 #endif
 
@@ -1127,21 +1265,17 @@ ImageFile::writeImagePNG (const char *outfile, int bitdepth, int nxcell, int nyc
 #include "gd.h"
 static const int N_GRAYSCALE=256;
 
-void
-ImageFile::writeImageGIF (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
+bool
+ImageFile::writeImageGIF (const char* const outfile, int nxcell, int nycell, double densmin, double densmax)
 {
-  gdImagePtr gif;
-  FILE *out;
   int gs_indices[N_GRAYSCALE];
   int nx = m_nx;
   int ny = m_ny;
   ImageFileArray v = getArray();
   
-  unsigned char rowp [nx * nxcell];
-  if (rowp == NULL)
-    return;
+  unsigned char* rowp = new unsigned char [nx * nxcell];
   
-  gif = gdImageCreate(nx * nxcell, ny * nycell);
+  gdImagePtr gif = gdImageCreate(nx * nxcell, ny * nycell);
   for (int i = 0; i < N_GRAYSCALE; i++)
     gs_indices[i] = gdImageColorAllocate(gif, i, i, i);
   
@@ -1161,13 +1295,18 @@ ImageFile::writeImageGIF (const char *outfile, int nxcell, int nycell, double de
     }
   }
   
-  if ((out = fopen(outfile,"w")) == NULL) {
+  FILE *out;\r
+  if ((out = fopen (outfile,"w")) == NULL) {
     sys_error(ERR_FATAL, "Error opening output file %s for writing", outfile);
-    return (1);
+    return false;
   }
   gdImageGif(gif,out);
   fclose(out);
-  gdImageDestroy(gif);
+  gdImageDestroy(gif);\r
+\r
+  delete rowp;\r
+\r
+  return true;
 }
 #endif
 
index 8c45da4..41895ac 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: procsignal.cpp,v 1.12 2001/01/01 10:14:34 kevin Exp $
+**  $Id: procsignal.cpp,v 1.13 2001/01/02 05:34:57 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
@@ -189,7 +189,7 @@ ProcessSignal::init (const int idFilter, const int idFilterMethod, double dBandw
         pEZPlot->plot (pSGP);
       }
 #endif     
-      shuffleNaturalToFourierOrder (adFrequencyFilter, m_nFilterPoints);
+      Fourier::shuffleNaturalToFourierOrder (adFrequencyFilter, m_nFilterPoints);
 #ifdef HAVE_SGP
       if (pEZPlot && m_traceLevel >= Trace::TRACE_PLOT) {
         pEZPlot->ezset ("title Filter Response: Fourier Order");
@@ -210,7 +210,7 @@ ProcessSignal::init (const int idFilter, const int idFilterMethod, double dBandw
         pEZPlot->plot (pSGP);
       }
 #endif
-      shuffleFourierToNaturalOrder (m_adFilter, m_nFilterPoints);
+      Fourier::shuffleFourierToNaturalOrder (m_adFilter, m_nFilterPoints);
 #ifdef HAVE_SGP
       if (pEZPlot && m_traceLevel >= Trace::TRACE_PLOT) {
         pEZPlot->ezset ("title Inverse Fourier Frequency: Natural Order");
@@ -304,7 +304,7 @@ ProcessSignal::init (const int idFilter, const int idFilterMethod, double dBandw
         pEZPlot->plot (pSGP);
       }
 #endif
-      shuffleNaturalToFourierOrder (m_adFilter, m_nFilterPoints);
+      Fourier::shuffleNaturalToFourierOrder (m_adFilter, m_nFilterPoints);
 #ifdef HAVE_SGP
       if (pEZPlot && m_traceLevel >= Trace::TRACE_PLOT) {
         pEZPlot->ezset ("title Filter Filter: Fourier Order");
@@ -855,200 +855,3 @@ ProcessSignal::finiteFourierTransform (const std::complex<double> input[], doubl
   }
 }
 
-// Odd Number of Points
-//   Natural Frequency Order: -(n-1)/2...-1,0,1...(n-1)/2
-//   Fourier Frequency Order: 0, 1..(n-1)/2,-(n-1)/2...-1
-// Even Number of Points
-//   Natural Frequency Order: -n/2...-1,0,1...((n/2)-1)
-//   Fourier Frequency Order: 0,1...((n/2)-1),-n/2...-1
-
-void\r
-ProcessSignal::shuffleNaturalToFourierOrder (double* pdVector, const int n)\r
-{\r
-  double* pdTemp = new double [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pdTemp[0] = pdVector[iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + 1 + iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pdTemp[0] = pdVector[iHalfN];\r
-#if USE_BROKEN_SHUFFLE\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-#else\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN] = pdVector[i];\r
-#endif\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pdVector[i] = pdTemp[i];\r
-  delete pdTemp;\r
-}\r
-\r
-void\r
-ProcessSignal::shuffleNaturalToFourierOrder (std::complex<double>* pdVector, const int n)\r
-{\r
-  std::complex<double>* pdTemp = new std::complex<double> [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pdTemp[0] = pdVector[iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + 1 + iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pdTemp[0] = pdVector[iHalfN];\r
-#if USE_BROKEN_SHUFFLE\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-#else\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN] = pdVector[i];\r
-#endif\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pdVector[i] = pdTemp[i];\r
-  delete [] pdTemp;\r
-}\r
-\r
-\r
-void\r
-ProcessSignal::shuffleNaturalToFourierOrder (float* pdVector, const int n)\r
-{\r
-  float* pdTemp = new float [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pdTemp[0] = pdVector[iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + 1 + iHalfN];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pdTemp[0] = pdVector[iHalfN];\r
-#if USE_BROKEN_SHUFFLE\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i];\r
-#else\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + 1] = pdVector[i + iHalfN + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + iHalfN] = pdVector[i];\r
-#endif\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pdVector[i] = pdTemp[i];\r
-  delete pdTemp;\r
-}\r
-\r
-\r
-\r
-void\r
-ProcessSignal::shuffleFourierToNaturalOrder (double* pdVector, const int n)\r
-{\r
-  double* pdTemp = new double [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pdTemp[iHalfN] = pdVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1 + iHalfN] = pdVector[i + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i] = pdVector[i + iHalfN + 1];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pdTemp[iHalfN] = pdVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i] = pdVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i+1];\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pdVector[i] = pdTemp[i];\r
-  delete pdTemp;\r
-}\r
-\r
-\r
-void\r
-ProcessSignal::shuffleFourierToNaturalOrder (std::complex<double>* pdVector, const int n)\r
-{\r
-  std::complex<double>* pdTemp = new std::complex<double> [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pdTemp[iHalfN] = pdVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i + 1 + iHalfN] = pdVector[i + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i] = pdVector[i + iHalfN + 1];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pdTemp[iHalfN] = pdVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pdTemp[i] = pdVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pdTemp[i + iHalfN + 1] = pdVector[i+1];\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pdVector[i] = pdTemp[i];\r
-  delete [] pdTemp;\r
-}\r
-\r
-\r
-\r
-\r
-void\r
-ProcessSignal::shuffleFourierToNaturalOrder (float* pVector, const int n)\r
-{\r
-  float* pTemp = new float [n];\r
-  int i;\r
-  if (n % 2) { // Odd\r
-    int iHalfN = (n - 1) / 2;\r
-    \r
-    pTemp[iHalfN] = pVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pTemp[i + 1 + iHalfN] = pVector[i + 1];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pTemp[i] = pVector[i + iHalfN + 1];\r
-  } else {     // Even\r
-    int iHalfN = n / 2;\r
-    pTemp[iHalfN] = pVector[0];\r
-    for (i = 0; i < iHalfN; i++)\r
-      pTemp[i] = pVector[i + iHalfN];\r
-    for (i = 0; i < iHalfN - 1; i++)\r
-      pTemp[i + iHalfN + 1] = pVector[i+1];\r
-  }\r
-  \r
-  for (i = 0; i < n; i++)\r
-    pVector[i] = pTemp[i];\r
-  delete [] pTemp;\r
-}\r
-\r
index 3604b2f..c9b18ac 100644 (file)
@@ -2,7 +2,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: mathfuncs.cpp,v 1.5 2001/01/01 10:14:34 kevin Exp $
+**  $Id: mathfuncs.cpp,v 1.6 2001/01/02 05:34:57 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
@@ -93,15 +93,12 @@ vectorNumericStatistics (std::vector<double> vec, const int nPoints, double& min
   min = vec[0];\r
   max = vec[0];\r
   int i;\r
-  int iMinPos = 0;\r
   for (i = 0; i < nPoints; i++) {\r
     double v = vec[i];\r
     if (v > max)\r
       max = v;\r
-    if (v < min) {\r
+    if (v < min)\r
       min = v;\r
-      iMinPos = i;\r
-    }\r
     mean += v;\r
   }\r
   mean /= nPoints;\r
index 16336ef..ef8d264 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: plotfile.cpp,v 1.7 2000/12/29 20:09:46 kevin Exp $
+**  $Id: plotfile.cpp,v 1.8 2001/01/02 05:34:57 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
@@ -40,7 +40,7 @@
 PlotFile::PlotFile (int nCurves, int nRecords)
 {
   initHeaders ();
-  setCurveSize (nCurves, nRecords);
+  setCurveSize (nCurves, nRecords);\r
 }
 
 PlotFile::PlotFile ()
@@ -57,7 +57,8 @@ PlotFile::initHeaders ()
 {
   m_iNumColumns = 0;
   m_iNumRecords = 0;
-  m_strDate = "";
+  time_t currentTime = time (NULL);\r
+  m_strDate = ctime (&currentTime);\r
   m_vecStrDescriptions.clear();\r
   m_vecStrEzsetCommands.clear();
 }
@@ -221,11 +222,32 @@ PlotFile::headerRead (std::iostream& fs)
   fs.seekg (0);\r
   bool bFinishedHeaders = false;\r
 \r
+  fs >> m_iNumColumns;\r
+  fs >> m_iNumRecords;\r
+\r
+  if (fs.fail() || m_iNumColumns == 0 || m_iNumRecords == 0)\r
+    return false;\r
+\r
   while (! bFinishedHeaders && ! fs.eof() && ! fs.fail()) {\r
     char line[1024];\r
     fs.getline (line, sizeof(line));\r
-    if (strstr (line, "<datapoints>") != NULL)\r
+    int iSP = 0;\r
+    while (line[iSP] == ' ')\r
+      iSP++;\r
+    if (line[iSP] == '\n' || ! line[iSP])\r
+      ;\r
+    else if (line[iSP] == '#') {\r
+      iSP++;\r
+      while (line[iSP] == ' ')\r
+        iSP++;\r
+      if (line[iSP] == '\n' || ! line[iSP])\r
+        ;\r
+      else\r
+        addDescription (&line[iSP]);\r
+    } else if (strstr (&line[iSP], "<datapoints>") != NULL) {\r
          bFinishedHeaders = true;\r
+    } else\r
+      addEzsetCommand (&line[iSP]);\r
   }\r
 
   return ! fs.fail();
@@ -241,27 +263,18 @@ PlotFile::headerWrite (std::iostream& fs)
   }
   
   fs.seekp (0);
-  fs << "<plotfile " << m_iNumColumns << " " << m_iNumRecords << " >\n";\r
-  
-  int iNEzset = m_vecStrEzsetCommands.size();\r
-  if (iNEzset > 0) {\r
-    fs << "<ezset>\n";\r
-    for (int i = 0; i < iNEzset; i++)\r
+  fs << m_iNumColumns << " " << m_iNumRecords << "\n";\r
+\r
+  int i;
+  for (i = 0; i < m_vecStrEzsetCommands.size(); i++)\r
       fs << m_vecStrEzsetCommands[i] << "\n";\r
-    fs << "</ezset>\n";\r
-  }\r
+  \r
+  for (i = 0; i < m_vecStrDescriptions.size(); i++)\r
+      fs << "# " << m_vecStrDescriptions[i] << "\n";\r
   \r
   if (! m_strDate.empty())
-    fs << "<date>" << m_strDate << "</date>\n";
-  
-  int iNDesc = m_vecStrDescriptions.size();\r
-  if (iNDesc > 0) {\r
-    fs << "<description>\n";
-    for (int i = 0; i < iNDesc; i++)
-      fs << m_vecStrDescriptions[i] << "\n";\r
-    fs << "</description>\n";\r
-  }
-  
+    fs << "# Date: " << m_strDate << "\n";
+    
   return ! fs.fail();
 }
 
@@ -299,8 +312,6 @@ PlotFile::columnsRead (std::iostream& fs)
     return false;
   }
   
-  return ! fs.fail();
-  
   if (m_iNumColumns == 0 || m_iNumRecords == 0) {
     sys_error (ERR_WARNING, "Called PlotFile::columnsRead with 0 columns or records");
     return false;
@@ -327,5 +338,12 @@ PlotFile::columnsRead (std::iostream& fs)
 
 void
 PlotFile::printHeaders (std::ostream& os) const
-{
+{\r
+  os << "EZSet Commands\n";\r
+  for (unsigned int iEZ = 0; iEZ < m_vecStrEzsetCommands.size(); iEZ++)\r
+    os << m_vecStrEzsetCommands[iEZ] << "\n";\r
+\r
+  os << "Descriptions\n";\r
+  for (unsigned int iDesc = 0; iDesc < m_vecStrDescriptions.size(); iDesc++)\r
+    os << m_vecStrDescriptions[iDesc] << "\n";
 }
index fb8f744..8035dcd 100644 (file)
@@ -3,78 +3,45 @@
 <pre>\r
 <h1>Build Log</h1>\r
 <h3>\r
---------------------Configuration: libctsim - Win32 Debug--------------------\r
+--------------------Configuration: ctsim - Win32 Release--------------------\r
 </h3>\r
 <h3>Command Lines</h3>\r
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29A.tmp" with contents\r
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP22A.tmp" with contents\r
 [\r
-/nologo /G6 /MTd /W3 /Gm /GR /GX /ZI /Od /I "..\..\..\zlib" /I "..\..\INCLUDE" /I "..\..\getopt" /I "..\..\..\lpng108" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /I "..\..\..\wx2\include" /D "_DEBUG" /D "HAVE_WXWIN" /D "HAVE_STRING_H" /D "HAVE_GETOPT_H" /D "WIN32" /D "_MBCS" /D "_LIB" /D "MSVC" /D "HAVE_FFTW" /D "HAVE_PNG" /D "HAVE_SGP" /D "HAVE_WXWINDOWS" /D "__WXMSW__" /FR"Debug/" /Fp"Debug/libctsim.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c \r
-"C:\ctsim-2.0.6\libctsim\imagefile.cpp"\r
+/nologo /G6 /MT /W3 /GR /GX /O2 /I "." /I "..\..\include" /I "..\..\getopt" /I "..\..\..\lpng108" /I "..\..\..\zlib" /I "..\..\..\fftw-2.1.3\fftw" /I "..\..\..\fftw-2.1.3\rfftw" /I "..\..\..\wx2\include" /D CTSIMVERSION=\"2.5.0\" /D "NDEBUG" /D "__WXWIN__" /D "__WXMSW__" /D "HAVE_SGP" /D "HAVE_PNG" /D "HAVE_WXWINDOWS" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "HAVE_STRING_H" /D "HAVE_FFTW" /D "HAVE_RFFTW" /D "HAVE_GETOPT_H" /D "MSVC" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FR"Release/" /Fp"Release/ctsim.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c \r
+"C:\ctsim-2.0.6\src\views.cpp"\r
 ]\r
-Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29A.tmp" \r
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29B.tmp" with contents\r
+Creating command line "cl.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP22A.tmp" \r
+Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP22B.tmp" with contents\r
 [\r
-/nologo /out:"Debug\libctsim.lib" \r
-".\Debug\array2dfile.obj"\r
-".\Debug\backprojectors.obj"\r
-".\Debug\clip.obj"\r
-".\Debug\consoleio.obj"\r
-".\Debug\ezplot.obj"\r
-".\Debug\ezset.obj"\r
-".\Debug\ezsupport.obj"\r
-".\Debug\filter.obj"\r
-".\Debug\fnetorderstream.obj"\r
-".\Debug\getopt.obj"\r
-".\Debug\getopt1.obj"\r
-".\Debug\hashtable.obj"\r
-".\Debug\imagefile.obj"\r
-".\Debug\mathfuncs.obj"\r
-".\Debug\phantom.obj"\r
-".\Debug\plotfile.obj"\r
-".\Debug\pol.obj"\r
-".\Debug\procsignal.obj"\r
-".\Debug\projections.obj"\r
-".\Debug\reconstruct.obj"\r
-".\Debug\scanner.obj"\r
-".\Debug\sgp.obj"\r
-".\Debug\strfuncs.obj"\r
-".\Debug\syserror.obj"\r
-".\Debug\trace.obj"\r
-".\Debug\transformmatrix.obj"\r
-".\Debug\xform.obj"\r
+kernel32.lib user32.lib wsock32.lib comctl32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libpng.lib zlib.lib /nologo /subsystem:windows /incremental:no /pdb:"Release/ctsim.pdb" /machine:I386 /out:"Release/ctsim.exe" /libpath:"..\..\..\lpng108\msvc\win32\libpng\lib" /libpath:"..\..\..\lpng108\msvc\win32\zlib\lib" \r
+".\Release\ctsim.obj"\r
+".\Release\dialogs.obj"\r
+".\Release\dlgprojections.obj"\r
+".\Release\dlgreconstruct.obj"\r
+".\Release\docs.obj"\r
+".\Release\views.obj"\r
+".\Release\wx.res"\r
+"\ctsim-2.0.6\msvc\libctsim\Release\libctsim.lib"\r
+"\fftw-2.1.3\Win32\FFTW2st\Release\FFTW2st.lib"\r
+"\fftw-2.1.3\Win32\RFFTW2st\Release\RFFTW2st.lib"\r
+"\wx2\lib\wx.lib"\r
 ]\r
-Creating command line "link.exe -lib @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29B.tmp"\r
+Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP22B.tmp"\r
 <h3>Output Window</h3>\r
 Compiling...\r
-imagefile.cpp\r
-Creating library...\r
-<h3>\r
---------------------Configuration: ctsim - Win32 Debug--------------------\r
-</h3>\r
-<h3>Command Lines</h3>\r
-Creating temporary file "C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29C.tmp" with contents\r
-[\r
-comctl32.lib winmm.lib rpcrt4.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ../libctsim/Debug/libctsim.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ..\..\..\lpng108\msvc\win32\libpng\lib_dbg\libpng.lib ..\..\..\lpng108\msvc\win32\zlib\lib_dbg\zlib.lib libcmtd.lib ..\..\..\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib ..\..\..\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib ../../../wx2/lib/wxd.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/ctsim.pdb" /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrtd.lib" /out:"Debug/ctsim.exe" /pdbtype:sept /libpath:"..\..\..\lpng108\msvc\win32\libpng\lib" /libpath:"..\..\..\lpng108\msvc\win32\zlib\lib" \r
-".\Debug\ctsim.obj"\r
-".\Debug\dialogs.obj"\r
-".\Debug\dlgprojections.obj"\r
-".\Debug\dlgreconstruct.obj"\r
-".\Debug\docs.obj"\r
-".\Debug\views.obj"\r
-".\Debug\wx.res"\r
-"\ctsim-2.0.6\msvc\libctsim\Debug\libctsim.lib"\r
-"\fftw-2.1.3\Win32\FFTW2st\Debug\FFTW2st.lib"\r
-"\fftw-2.1.3\Win32\RFFTW2st\Debug\RFFTW2st.lib"\r
-"\wx2\lib\wxd.lib"\r
-]\r
-Creating command line "link.exe @C:\DOCUME~1\kevin\LOCALS~1\Temp\RSP29C.tmp"\r
-<h3>Output Window</h3>\r
+views.cpp\r
 Linking...\r
+LINK : warning LNK4089: all references to "ADVAPI32.dll" discarded by /OPT:REF\r
+LINK : warning LNK4089: all references to "WSOCK32.dll" discarded by /OPT:REF\r
+Creating command line "bscmake.exe /nologo /o"Release/ctsim.bsc"  ".\Release\ctsim.sbr" ".\Release\dialogs.sbr" ".\Release\dlgprojections.sbr" ".\Release\dlgreconstruct.sbr" ".\Release\docs.sbr" ".\Release\views.sbr""\r
+Creating browse info file...\r
+<h3>Output Window</h3>\r
 \r
 \r
 \r
 <h3>Results</h3>\r
-ctsim.exe - 0 error(s), 0 warning(s)\r
+ctsim.exe - 0 error(s), 2 warning(s)\r
 </pre>\r
 </body>\r
 </html>\r
index bee0059..3d2fb65 100644 (file)
@@ -138,6 +138,10 @@ SOURCE=..\..\libctsupport\fnetorderstream.cpp
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\libctsim\fourier.cpp\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\getopt\getopt.c\r
 # End Source File\r
 # Begin Source File\r
@@ -246,6 +250,10 @@ SOURCE=..\..\include\fnetorderstream.h
 # End Source File\r
 # Begin Source File\r
 \r
+SOURCE=..\..\include\fourier.h\r
+# End Source File\r
+# Begin Source File\r
+\r
 SOURCE=..\..\getopt\getopt.h\r
 # End Source File\r
 # Begin Source File\r
index 172cda9..439ae4f 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ctsim.cpp,v 1.23 2001/01/01 10:14:34 kevin Exp $
+**  $Id: ctsim.cpp,v 1.24 2001/01/02 05:34:57 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
 #endif
 #endif
 \r
-static const char* rcsindent = "$Id: ctsim.cpp,v 1.23 2001/01/01 10:14:34 kevin Exp $";
+static const char* rcsindent = "$Id: ctsim.cpp,v 1.24 2001/01/02 05:34:57 kevin Exp $";
 
 class CTSimApp* theApp = NULL;
 
 struct option CTSimApp::ctsimOptions[] = 
 {
-    {"help", 0, 0, O_HELP},
-    {"version", 0, 0, O_VERSION},
-    {0, 0, 0, 0}
+  {"help", 0, 0, O_HELP},
+  {"version", 0, 0, O_VERSION},
+  {0, 0, 0, 0}
 };
 
 IMPLEMENT_APP(CTSimApp)
 
 CTSimApp::CTSimApp()
-  : m_docManager(NULL), m_pFrame(NULL)
+: m_docManager(NULL), m_pFrame(NULL)
 {
-    theApp = this;
+  theApp = this;
 }
 
 #ifdef HAVE_SYS_TIME_H
@@ -94,86 +94,86 @@ CTSimApp::OnInit()
 #ifdef HAVE_SETPRIORITY
   setpriority (PRIO_PROCESS, 0, 15);  // set to low scheduling priority
 #endif
-
-    // process options
-    while (1) {
-      int c = getopt_long (argc, argv, "", ctsimOptions, NULL);
-      if (c == -1)
-       break;
-
-      switch (c) {
-      case O_VERSION:
-                 std::cout << rcsindent << std::endl;\r
+  
+  // process options
+  while (1) {
+    int c = getopt_long (argc, argv, "", ctsimOptions, NULL);
+    if (c == -1)
+      break;
+    
+    switch (c) {
+    case O_VERSION:
+      std::cout << rcsindent << std::endl;\r
 #ifdef CTSIMVERSION\r
-                 std::cout << "Version: CTSIMVERSION" << std::endl;\r
+      std::cout << "Version: CTSIMVERSION" << std::endl;\r
 #elif defined(VERSION)\r
-                 std::cout << "Version: VERSION" << std::endl;\r
+      std::cout << "Version: VERSION" << std::endl;\r
 #endif
-         exit(0);
-      case O_HELP:
-      case '?':
-       usage (argv[0]);
-       exit (0);
-      default:
-       usage (argv[0]);
-       exit (1);
-      }
+      exit(0);
+    case O_HELP:
+    case '?':
+      usage (argv[0]);
+      exit (0);
+    default:
+      usage (argv[0]);
+      exit (1);
     }
-
-    m_docManager = new wxDocManager;
-    
-    new wxDocTemplate (m_docManager, "ImageFile", "*.if", "", "if", "ImageFile doc", "ImageFile View", CLASSINFO(ImageFileDocument), CLASSINFO(ImageFileView));
-
-    new wxDocTemplate (m_docManager, "ProjectionFile", "*.pj", "", "pj", "ProjectionFile doc", "ProjectionFile View", CLASSINFO(ProjectionFileDocument), CLASSINFO(ProjectionFileView));
-
-    new wxDocTemplate (m_docManager, "PhantomFile", "*.phm", "", "phm", "Phantom doc", "Phantom View", CLASSINFO(PhantomDocument), CLASSINFO(PhantomView));
-
-    new wxDocTemplate (m_docManager, "PlotFile", "*.plt", "", "plt", "Plot doc", "Plot View", CLASSINFO(PlotFileDocument), CLASSINFO(PlotFileView));
-
-    //// Create the main frame window
-    m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), wxSize(500, 400), wxDEFAULT_FRAME_STYLE);
-    
-    SetTopWindow (m_pFrame);
-    m_pFrame->Centre(wxBOTH);
-
-    m_pFrame->Show(true);
-
-    for (int i = optind + 1; i <= argc; i++) {
-      wxString filename = argv [i - 1];
-      m_docManager->CreateDocument (filename, wxDOC_SILENT);
-    }
-
-    return true;
+  }
+  
+  m_docManager = new wxDocManager;
+  
+  new wxDocTemplate (m_docManager, "ImageFile", "*.if", "", "if", "ImageFile doc", "ImageFile View", CLASSINFO(ImageFileDocument), CLASSINFO(ImageFileView));
+  
+  new wxDocTemplate (m_docManager, "ProjectionFile", "*.pj", "", "pj", "ProjectionFile doc", "ProjectionFile View", CLASSINFO(ProjectionFileDocument), CLASSINFO(ProjectionFileView));
+  
+  new wxDocTemplate (m_docManager, "PhantomFile", "*.phm", "", "phm", "Phantom doc", "Phantom View", CLASSINFO(PhantomDocument), CLASSINFO(PhantomView));
+  
+  new wxDocTemplate (m_docManager, "PlotFile", "*.plt", "", "plt", "Plot doc", "Plot View", CLASSINFO(PlotFileDocument), CLASSINFO(PlotFileView));
+  
+  //// Create the main frame window
+  m_pFrame = new MainFrame(m_docManager, (wxFrame *) NULL, -1, "CTSim", wxPoint(0, 0), wxSize(500, 400), wxDEFAULT_FRAME_STYLE);
+  
+  SetTopWindow (m_pFrame);
+  m_pFrame->Centre(wxBOTH);
+  
+  m_pFrame->Show(true);
+  
+  for (int i = optind + 1; i <= argc; i++) {
+    wxString filename = argv [i - 1];
+    m_docManager->CreateDocument (filename, wxDOC_SILENT);
+  }
+  
+  return true;
 }
 
 void
 CTSimApp::usage(const char* program)
 {
-       std::cout << "usage: " << fileBasename(program) << " [files-to-open...] [OPTIONS]\n";
-       std::cout << "Computed Tomography Simulator (Graphical Shell)\n";
-       std::cout << "\n";
-       std::cout << "  --version Display version\n";
-       std::cout << "  --help    Display this help message\n";
+  std::cout << "usage: " << fileBasename(program) << " [files-to-open...] [OPTIONS]\n";
+  std::cout << "Computed Tomography Simulator (Graphical Shell)\n";
+  std::cout << "\n";
+  std::cout << "  --version Display version\n";
+  std::cout << "  --help    Display this help message\n";
 }
 
 int
 CTSimApp::OnExit()
 {
-    delete m_docManager;
+  delete m_docManager;
 #ifdef HAVE_DMALLOC
-    dmalloc_shutdown();
+  dmalloc_shutdown();
 #endif
-    return 0;
+  return 0;
 }
 
 wxString
 CTSimApp::getUntitledFilename()
 {
   static int untitledNumber = 1;
-
+  
   wxString filename ("Untitled");
   filename << untitledNumber++;
-
+  
   return (filename);
 }
 
@@ -183,137 +183,159 @@ CTSimApp::getUntitledFilename()
 IMPLEMENT_CLASS(MainFrame, wxDocParentFrame)
 
 BEGIN_EVENT_TABLE(MainFrame, wxDocParentFrame)
-  EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
-  EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
-  EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom)\r
-  EVT_MENU(MAINMENU_FILE_CREATE_FILTER, MainFrame::OnCreateFilter)\r
-  EVT_MENU(MAINMENU_FILE_EXIT, MainFrame::OnExit)
-  EVT_MENU(MAINMENU_WINDOW_BASE, MainFrame::OnWindowMenu0)
-  EVT_MENU(MAINMENU_WINDOW_BASE+1, MainFrame::OnWindowMenu1)
-  EVT_MENU(MAINMENU_WINDOW_BASE+2, MainFrame::OnWindowMenu2)
-  EVT_MENU(MAINMENU_WINDOW_BASE+3, MainFrame::OnWindowMenu3)
-  EVT_MENU(MAINMENU_WINDOW_BASE+4, MainFrame::OnWindowMenu4)
-  EVT_MENU(MAINMENU_WINDOW_BASE+5, MainFrame::OnWindowMenu5)
-  EVT_MENU(MAINMENU_WINDOW_BASE+6, MainFrame::OnWindowMenu6)
-  EVT_MENU(MAINMENU_WINDOW_BASE+7, MainFrame::OnWindowMenu7)
-  EVT_MENU(MAINMENU_WINDOW_BASE+8, MainFrame::OnWindowMenu8)
-  EVT_MENU(MAINMENU_WINDOW_BASE+9, MainFrame::OnWindowMenu9)
-  EVT_MENU(MAINMENU_WINDOW_BASE+10, MainFrame::OnWindowMenu10)
-  EVT_MENU(MAINMENU_WINDOW_BASE+11, MainFrame::OnWindowMenu11)
-  EVT_MENU(MAINMENU_WINDOW_BASE+12, MainFrame::OnWindowMenu12)
-  EVT_MENU(MAINMENU_WINDOW_BASE+13, MainFrame::OnWindowMenu13)
-  EVT_MENU(MAINMENU_WINDOW_BASE+14, MainFrame::OnWindowMenu14)
-  EVT_MENU(MAINMENU_WINDOW_BASE+15, MainFrame::OnWindowMenu15)
-  EVT_MENU(MAINMENU_WINDOW_BASE+16, MainFrame::OnWindowMenu16)
-  EVT_MENU(MAINMENU_WINDOW_BASE+17, MainFrame::OnWindowMenu17)
-  EVT_MENU(MAINMENU_WINDOW_BASE+18, MainFrame::OnWindowMenu18)
-  EVT_MENU(MAINMENU_WINDOW_BASE+19, MainFrame::OnWindowMenu19)
-  EVT_UPDATE_UI_RANGE(MAINMENU_WINDOW_BASE, MAINMENU_WINDOW_BASE+20, MainFrame::OnUpdateUI)
+EVT_MENU(MAINMENU_HELP_ABOUT, MainFrame::OnAbout)
+EVT_MENU(MAINMENU_HELP_CONTENTS, MainFrame::OnHelpContents)
+EVT_MENU(MAINMENU_FILE_CREATE_PHANTOM, MainFrame::OnCreatePhantom)\r
+EVT_MENU(MAINMENU_FILE_CREATE_FILTER, MainFrame::OnCreateFilter)\r
+EVT_MENU(MAINMENU_FILE_EXIT, MainFrame::OnExit)
+EVT_MENU(MAINMENU_WINDOW_BASE, MainFrame::OnWindowMenu0)
+EVT_MENU(MAINMENU_WINDOW_BASE+1, MainFrame::OnWindowMenu1)
+EVT_MENU(MAINMENU_WINDOW_BASE+2, MainFrame::OnWindowMenu2)
+EVT_MENU(MAINMENU_WINDOW_BASE+3, MainFrame::OnWindowMenu3)
+EVT_MENU(MAINMENU_WINDOW_BASE+4, MainFrame::OnWindowMenu4)
+EVT_MENU(MAINMENU_WINDOW_BASE+5, MainFrame::OnWindowMenu5)
+EVT_MENU(MAINMENU_WINDOW_BASE+6, MainFrame::OnWindowMenu6)
+EVT_MENU(MAINMENU_WINDOW_BASE+7, MainFrame::OnWindowMenu7)
+EVT_MENU(MAINMENU_WINDOW_BASE+8, MainFrame::OnWindowMenu8)
+EVT_MENU(MAINMENU_WINDOW_BASE+9, MainFrame::OnWindowMenu9)
+EVT_MENU(MAINMENU_WINDOW_BASE+10, MainFrame::OnWindowMenu10)
+EVT_MENU(MAINMENU_WINDOW_BASE+11, MainFrame::OnWindowMenu11)
+EVT_MENU(MAINMENU_WINDOW_BASE+12, MainFrame::OnWindowMenu12)
+EVT_MENU(MAINMENU_WINDOW_BASE+13, MainFrame::OnWindowMenu13)
+EVT_MENU(MAINMENU_WINDOW_BASE+14, MainFrame::OnWindowMenu14)
+EVT_MENU(MAINMENU_WINDOW_BASE+15, MainFrame::OnWindowMenu15)
+EVT_MENU(MAINMENU_WINDOW_BASE+16, MainFrame::OnWindowMenu16)
+EVT_MENU(MAINMENU_WINDOW_BASE+17, MainFrame::OnWindowMenu17)
+EVT_MENU(MAINMENU_WINDOW_BASE+18, MainFrame::OnWindowMenu18)
+EVT_MENU(MAINMENU_WINDOW_BASE+19, MainFrame::OnWindowMenu19)
+EVT_UPDATE_UI_RANGE(MAINMENU_WINDOW_BASE, MAINMENU_WINDOW_BASE+20, MainFrame::OnUpdateUI)
 END_EVENT_TABLE()
 
 
 
 MainFrame::MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type)
-  : wxDocParentFrame(manager, frame, id, title, pos, size, type), m_pLog(NULL)
+: wxDocParentFrame(manager, frame, id, title, pos, size, type), m_pLog(NULL)
 {
-    m_pLog = new wxTextCtrl (this, -1, "Log Window\n", wxPoint(0, 250), wxSize(100,50), wxTE_MULTILINE | wxTE_READONLY);
-    wxLog::SetActiveTarget(new wxLogTextCtrl(m_pLog));
-    CreateStatusBar();
-    SetStatusText ("Welcome to CTSim");
-
-    //// Make a menubar
-    wxMenu *file_menu = new wxMenu;
-    
-    file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");\r
-    file_menu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...");\r
-    file_menu->Append(wxID_OPEN, "&Open...");
-    
-    file_menu->AppendSeparator();
-    file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
-    
-    //  history of files visited
-    m_docManager->FileHistoryUseMenu(file_menu);
-    
-    m_pWindowMenu = new wxMenu;
-    m_pWindowMenu->UpdateUI (this);
-
-    wxMenu* help_menu = new wxMenu;
-    help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
-    help_menu->AppendSeparator();
-    help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
-    
-    wxMenuBar* menu_bar = new wxMenuBar;
-    
-    menu_bar->Append(file_menu, "&File");
-    menu_bar->Append(m_pWindowMenu, "&Window");
-    menu_bar->Append(help_menu, "&Help");
-    
-    SetMenuBar(menu_bar);
-
-    for (int i = 0; i < MAX_WINDOW_MENUITEMS; i++) {
-      m_apWindowMenuItems[i] = new wxMenuItem (m_pWindowMenu, MAINMENU_WINDOW_BASE+i, wxString("<Empty>"));
-      m_pWindowMenu->Append (m_apWindowMenuItems[i]);
-      m_pWindowMenu->Enable (MAINMENU_WINDOW_BASE+i, false);
-    }
+  m_pLog = new wxTextCtrl (this, -1, "Log Window\n", wxPoint(0, 250), wxSize(100,50), wxTE_MULTILINE | wxTE_READONLY);
+  wxLog::SetActiveTarget(new wxLogTextCtrl(m_pLog));
+  CreateStatusBar();
+  SetStatusText ("Welcome to CTSim");
+  
+  //// Make a menubar
+  wxMenu *file_menu = new wxMenu;
+  
+  file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");\r
+  file_menu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...");\r
+  file_menu->Append(wxID_OPEN, "&Open...");
+  
+  file_menu->AppendSeparator();
+  file_menu->Append(MAINMENU_FILE_EXIT, "E&xit");
+  
+  //  history of files visited
+  m_docManager->FileHistoryUseMenu(file_menu);
+  
+  m_pWindowMenu = new wxMenu;
+  m_pWindowMenu->UpdateUI (this);
+  
+  wxMenu* help_menu = new wxMenu;
+  help_menu->Append(MAINMENU_HELP_CONTENTS, "&Contents");
+  help_menu->AppendSeparator();
+  help_menu->Append(MAINMENU_HELP_ABOUT, "&About");
+  
+  wxMenuBar* menu_bar = new wxMenuBar;
+  
+  menu_bar->Append(file_menu, "&File");
+  menu_bar->Append(m_pWindowMenu, "&Window");
+  menu_bar->Append(help_menu, "&Help");
+  
+  SetMenuBar(menu_bar);
+  
+  for (int i = 0; i < MAX_WINDOW_MENUITEMS; i++) {
+    m_apWindowMenuItems[i] = new wxMenuItem (m_pWindowMenu, MAINMENU_WINDOW_BASE+i, wxString("<Empty>"));
+    m_pWindowMenu->Append (m_apWindowMenuItems[i]);
+    m_pWindowMenu->Enable (MAINMENU_WINDOW_BASE+i, false);
+  }
+  \r
+  m_iDefaultPhantomID = Phantom::PHM_HERMAN;\r
+  m_iDefaultFilterID = SignalFilter::FILTER_BANDLIMIT;\r
+  m_iDefaultFilterDomainID = SignalFilter::DOMAIN_FREQUENCY;\r
+  m_iDefaultFilterXSize = 256;\r
+  m_iDefaultFilterYSize = 256;\r
+  m_dDefaultFilterParam = 1.;\r
+  m_dDefaultFilterBandwidth = 1.;\r
+  m_dDefaultFilterInputScale = 1.;\r
+  m_dDefaultFilterOutputScale = 1.;\r
+  \r
 }
 
 void 
 MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
 {\r
-       wxString msg = "CTSim\nThe Open Source Computed Tomography Simulator\n";\r
+  wxString msg = "CTSim\nThe Open Source Computed Tomography Simulator\n";\r
 #ifdef CTSIMVERSION\r
-       msg += "Version ";\r
-       msg += CTSIMVERSION;\r
-       msg += "\n\n";\r
+  msg += "Version ";\r
+  msg += CTSIMVERSION;\r
+  msg += "\n\n";\r
 #elif defined(VERSION)\r
-       msg << "Version: " <<  VERSION << "\n\n";\r
+  msg << "Version: " <<  VERSION << "\n\n";\r
 #endif\r
-       msg += "Author: Kevin Rosenberg <kevin@rosenberg.net>\nUsage: ctsim [files-to-open..] [--help]";\r
-
-    wxMessageBox(msg, "About CTSim", wxOK | wxICON_INFORMATION, this);
+  msg += "Author: Kevin Rosenberg <kevin@rosenberg.net>\nUsage: ctsim [files-to-open..] [--help]";\r
+  
+  wxMessageBox(msg, "About CTSim", wxOK | wxICON_INFORMATION, this);
 }
-
+\r
 void \r
 MainFrame::OnCreatePhantom(wxCommandEvent& WXUNUSED(event))\r
 {\r
-    DialogGetPhantom dialogPhantom (this, Phantom::PHM_HERMAN);\r
-    int dialogReturn = dialogPhantom.ShowModal();\r
-    if (dialogReturn == wxID_OK) {\r
-      wxString selection (dialogPhantom.getPhantom());\r
-      *theApp->getLog() << "Selected phantom " << selection.c_str() << "\n";\r
-      wxString filename = selection + ".phm";\r
-      theApp->getDocManager()->CreateDocument(filename, wxDOC_SILENT);\r
-    }\r
-    \r
+  DialogGetPhantom dialogPhantom (this, m_iDefaultPhantomID);\r
+  int dialogReturn = dialogPhantom.ShowModal();\r
+  if (dialogReturn == wxID_OK) {\r
+    wxString selection (dialogPhantom.getPhantom());\r
+    *theApp->getLog() << "Selected phantom " << selection.c_str() << "\n";\r
+    wxString filename = selection + ".phm";\r
+    m_iDefaultPhantomID = Phantom::convertNameToPhantomID (selection.c_str());\r
+    theApp->getDocManager()->CreateDocument(filename, wxDOC_SILENT);\r
+  }\r
+  \r
 }\r
 \r
 void \r
 MainFrame::OnCreateFilter (wxCommandEvent& WXUNUSED(event))\r
 {\r
-  DialogGetFilterParameters dialogFilter (this, 256, 256, SignalFilter::FILTER_BANDLIMIT, 1., 10., SignalFilter::DOMAIN_SPATIAL);\r
-    int dialogReturn = dialogFilter.ShowModal();\r
-    if (dialogReturn == wxID_OK) {\r
-      wxString strFilter (dialogFilter.getFilterName());\r
-      wxString strDomain (dialogFilter.getDomainName());\r
-      unsigned int nx = dialogFilter.getXSize();\r
-      unsigned int ny = dialogFilter.getYSize();\r
-      double dBandwidth = dialogFilter.getBandwidth();\r
-      double dFilterParam= dialogFilter.getFilterParam();\r
-      *theApp->getLog() << "Selected filter " << strFilter.c_str() << ", domain " << strDomain.c_str() << ", filterParam " << dFilterParam << ", bandwidth " << dBandwidth << "\n";\r
-      wxString filename = "untitled.if";\r
-      ImageFileDocument* pFilterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument ("untitled.if", wxDOC_SILENT));\r
-      if (! pFilterDoc) {\r
-        sys_error (ERR_SEVERE, "Unable to create filter image");\r
-        return;\r
-      }\r
-      ImageFile& rIF = pFilterDoc->getImageFile();\r
-      rIF.setArraySize (nx, ny);\r
-      rIF.filterResponse (strDomain.c_str(), dBandwidth, strFilter.c_str(), dFilterParam);\r
-      if (theApp->getSetModifyNewDocs())\r
-        pFilterDoc->Modify (true);\r
-      pFilterDoc->UpdateAllViews();\r
-      pFilterDoc->GetFirstView()->OnUpdate (NULL, NULL);\r
+  DialogGetFilterParameters dialogFilter (this, m_iDefaultFilterXSize, m_iDefaultFilterYSize, m_iDefaultFilterID, m_dDefaultFilterParam, m_dDefaultFilterBandwidth, m_iDefaultFilterDomainID, m_dDefaultFilterInputScale, m_dDefaultFilterOutputScale);\r
+  int dialogReturn = dialogFilter.ShowModal();\r
+  if (dialogReturn == wxID_OK) {\r
+    wxString strFilter (dialogFilter.getFilterName());\r
+    wxString strDomain (dialogFilter.getDomainName());\r
+    m_iDefaultFilterID = SignalFilter::convertFilterNameToID (strFilter.c_str());\r
+    m_iDefaultFilterDomainID = SignalFilter::convertDomainNameToID (strDomain.c_str());\r
+    m_iDefaultFilterXSize = dialogFilter.getXSize();\r
+    m_iDefaultFilterYSize = dialogFilter.getYSize();\r
+    m_dDefaultFilterBandwidth = dialogFilter.getBandwidth();\r
+    m_dDefaultFilterParam= dialogFilter.getFilterParam();\r
+    m_dDefaultFilterInputScale = dialogFilter.getInputScale();\r
+    m_dDefaultFilterOutputScale = dialogFilter.getOutputScale();\r
+    std::ostringstream os;\r
+    os << "Generate Filter=" << strFilter.c_str() \r
+      << ", size=(" << static_cast<int>(m_iDefaultFilterXSize) << "," << static_cast<int>(m_iDefaultFilterYSize) \r
+      << "), domain=" << strDomain.c_str() << ", filterParam=" << m_dDefaultFilterParam << ", bandwidth=" << m_dDefaultFilterBandwidth \r
+      << ", inputScale=" << m_dDefaultFilterInputScale << ", outputScale=" << m_dDefaultFilterOutputScale;\r
+    *theApp->getLog() << os.str().c_str() << "\n";\r
+    wxString filename = "untitled.if";\r
+    ImageFileDocument* pFilterDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument ("untitled.if", wxDOC_SILENT));\r
+    if (! pFilterDoc) {\r
+      sys_error (ERR_SEVERE, "Unable to create filter image");\r
+      return;\r
     }\r
+    ImageFile& rIF = pFilterDoc->getImageFile();\r
+    rIF.setArraySize (m_iDefaultFilterXSize, m_iDefaultFilterYSize);\r
+    rIF.filterResponse (strDomain.c_str(), m_dDefaultFilterBandwidth, strFilter.c_str(), m_dDefaultFilterParam, m_dDefaultFilterInputScale, m_dDefaultFilterOutputScale);\r
+    rIF.labelAdd (os.str().c_str());\r
+    if (theApp->getSetModifyNewDocs())\r
+      pFilterDoc->Modify (true);\r
+    pFilterDoc->UpdateAllViews();\r
+    pFilterDoc->GetFirstView()->OnUpdate (NULL, NULL);\r
+  }\r
 }\r
 \r
 void\r
@@ -337,13 +359,13 @@ CTSimApp::getCompatibleImages (const ImageFileDocument* pIFDoc, std::vector<Imag
 void 
 MainFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event) )
 {
-    wxMessageBox("No help available, refer to man pages of command-line tools");
+  wxMessageBox("No help available, refer to man pages of command-line tools");
 }
 
 void 
 MainFrame::OnExit (wxCommandEvent& WXUNUSED(event) )
 {
-    Close(true);
+  Close(true);
 }
 
 void
@@ -366,7 +388,7 @@ MainFrame::OnUpdateUI (wxUpdateUIEvent& rEvent)
     static_cast<wxMenuItemBase*>(m_apWindowMenuItems[i])->SetName (wxString("<Empty>"));
     m_apWindowMenuData[i] = NULL;
   }
-    
+  
 }
 
 void 
index 2055227..aa349c1 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: ctsim.h,v 1.16 2001/01/01 10:14:34 kevin Exp $
+**  $Id: ctsim.h,v 1.17 2001/01/02 05:34:57 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
@@ -53,6 +53,16 @@ private:
     enum { MAX_WINDOW_MENUITEMS = 20 };
     wxMenuItem* m_apWindowMenuItems[MAX_WINDOW_MENUITEMS];
     wxDocument* m_apWindowMenuData[MAX_WINDOW_MENUITEMS];
+\r
+    int m_iDefaultPhantomID;\r
+    int m_iDefaultFilterID;\r
+    int m_iDefaultFilterDomainID;\r
+    unsigned int m_iDefaultFilterXSize;    \r
+    unsigned int m_iDefaultFilterYSize;\r
+    double m_dDefaultFilterParam;\r
+    double m_dDefaultFilterBandwidth;\r
+    double m_dDefaultFilterInputScale;\r
+    double m_dDefaultFilterOutputScale;\r
 
 public:
     MainFrame(wxDocManager *manager, wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long type);
@@ -137,11 +147,12 @@ enum {
     MAINMENU_HELP_CONTENTS,
     MAINMENU_FILE_CREATE_PHANTOM,\r
     MAINMENU_FILE_CREATE_FILTER,
-    MAINMENU_FILE_EXIT,
+    MAINMENU_FILE_EXIT,\r
     IFMENU_FILE_PROPERTIES,
     PJMENU_FILE_PROPERTIES,
     PHMMENU_FILE_PROPERTIES,
     PJMENU_PROCESS_RECONSTRUCT,\r
+    IFMENU_FILE_EXPORT,\r
        IFMENU_PLOT_ROW,\r
        IFMENU_PLOT_COL,
     IFMENU_VIEW_SCALE_AUTO,
@@ -154,12 +165,19 @@ enum {
   IFMENU_PROCESS_SQUARE,\r
   IFMENU_PROCESS_LOG,\r
   IFMENU_PROCESS_EXP,\r
+  IFMENU_PROCESS_MULTIPLY,\r
+  IFMENU_PROCESS_SUBTRACT,\r
+  IFMENU_PROCESS_SCALESIZE,\r
+  IFMENU_PROCESS_DIVIDE,\r
+  IFMENU_PROCESS_ADD,\r
   IFMENU_PROCESS_FOURIER,\r
   IFMENU_PROCESS_INVERSE_FOURIER,\r
   IFMENU_PROCESS_FFT,\r
   IFMENU_PROCESS_IFFT,\r
   IFMENU_PROCESS_MAGNITUDE,\r
   IFMENU_PROCESS_PHASE,\r
+  IFMENU_PROCESS_SHUFFLENATURALTOFOURIERORDER,\r
+  IFMENU_PROCESS_SHUFFLEFOURIERTONATURALORDER,\r
     PHMMENU_PROCESS_RASTERIZE,
     PHMMENU_PROCESS_PROJECTIONS,\r
        PLOTMENU_VIEW_SCALE_MINMAX,\r
index 3e2d8fb..4802162 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: dialogs.cpp,v 1.22 2001/01/01 10:14:34 kevin Exp $
+**  $Id: dialogs.cpp,v 1.23 2001/01/02 05:34:57 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
@@ -821,7 +821,7 @@ DialogGetReconstructionParameters::getFilterGenerationName (void)
 /////////////////////////////////////////////////////////////////////\r
 \r
 \r
-DialogGetFilterParameters::DialogGetFilterParameters (wxFrame* pParent, int iDefaultXSize, int iDefaultYSize, int iDefaultFilterID, double dDefaultFilterParam,  double dDefaultBandwidth, int iDefaultDomainID)\r
+DialogGetFilterParameters::DialogGetFilterParameters (wxFrame* pParent, int iDefaultXSize, int iDefaultYSize, int iDefaultFilterID, double dDefaultFilterParam,  double dDefaultBandwidth, int iDefaultDomainID, double dDefaultInputScale, double dDefaultOutputScale)\r
 : wxDialog (pParent, -1, "Set Filter Parameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)\r
 {\r
   wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);\r
@@ -842,6 +842,12 @@ DialogGetFilterParameters::DialogGetFilterParameters (wxFrame* pParent, int iDef
   std::ostringstream osBandwidth;\r
   osBandwidth << dDefaultBandwidth;\r
   m_pTextCtrlBandwidth = new wxTextCtrl (this, -1, osBandwidth.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
+  std::ostringstream osInputScale;\r
+  osInputScale << dDefaultInputScale;\r
+  m_pTextCtrlInputScale = new wxTextCtrl (this, -1, osInputScale.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
+  std::ostringstream osOutputScale;\r
+  osOutputScale << dDefaultOutputScale;\r
+  m_pTextCtrlOutputScale = new wxTextCtrl (this, -1, osOutputScale.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
   \r
   wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (2);\r
   pGridSizer->Add (new wxStaticText (this, -1, "Filter"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5);\r
@@ -862,6 +868,10 @@ DialogGetFilterParameters::DialogGetFilterParameters (wxFrame* pParent, int iDef
   pGridSizer->Add (m_pTextCtrlFilterParam, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);\r
   pGridSizer->Add (new wxStaticText (this, -1, "Bandwidth"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
   pGridSizer->Add (m_pTextCtrlBandwidth, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (new wxStaticText (this, -1, "Axis (input) Scale"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (m_pTextCtrlInputScale, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (new wxStaticText (this, -1, "Filter Output Scale"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (m_pTextCtrlOutputScale, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);\r
   \r
   pTopSizer->Add (pGridSizer, 1, wxALL, 3);\r
   \r
@@ -931,6 +941,28 @@ DialogGetFilterParameters::getFilterParam (void)
     return (m_dDefaultFilterParam);\r
 }\r
 \r
+double\r
+DialogGetFilterParameters::getInputScale (void)\r
+{\r
+  wxString strCtrl = m_pTextCtrlInputScale->GetValue();\r
+  double dValue;\r
+  if (strCtrl.ToDouble (&dValue))\r
+    return dValue;\r
+  else\r
+    return (m_dDefaultInputScale);\r
+}\r
+\r
+double\r
+DialogGetFilterParameters::getOutputScale (void)\r
+{\r
+  wxString strCtrl = m_pTextCtrlOutputScale->GetValue();\r
+  double dValue;\r
+  if (strCtrl.ToDouble (&dValue))\r
+    return dValue;\r
+  else\r
+    return (m_dDefaultOutputScale);\r
+}\r
+\r
 const char*\r
 DialogGetFilterParameters::getFilterName (void)\r
 {\r
@@ -943,3 +975,117 @@ DialogGetFilterParameters::getDomainName (void)
   return m_pListBoxDomain->getSelectionStringValue();\r
 }\r
 \r
+\r
+///////////////////////////////////////////////////////////////////////\r
+// CLASS IMPLEMENTATION\r
+//    DialogExportParameters\r
+///////////////////////////////////////////////////////////////////////\r
+\r
+DialogExportParameters::DialogExportParameters (wxFrame* pParent, int iDefaultFormatID)\r
+: wxDialog (pParent, -1, "Select ExportParameters", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)\r
+{\r
+  wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);\r
+  \r
+  pTopSizer->Add (new wxStaticText (this, -1, "Select Export Format"), 0, wxALIGN_CENTER | wxALL, 5);\r
+  \r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxALL, 5);\r
+  \r
+  m_pListBoxFormat = new StringValueAndTitleListBox (this, ImageFile::getFormatCount(), ImageFile::getFormatTitleArray(), ImageFile::getFormatNameArray());\r
+  m_pListBoxFormat->SetSelection (iDefaultFormatID);\r
+  pTopSizer->Add (m_pListBoxFormat, 0, wxALL | wxALIGN_CENTER | wxEXPAND);\r
+  \r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);\r
+  \r
+  wxBoxSizer* pButtonSizer = new wxBoxSizer (wxHORIZONTAL);\r
+  wxButton* pButtonOk = new wxButton (this, wxID_OK, "Okay");\r
+  wxButton* pButtonCancel = new wxButton (this, wxID_CANCEL, "Cancel");\r
+  pButtonSizer->Add (pButtonOk, 0, wxEXPAND | wxALL, 10);\r
+  pButtonSizer->Add (pButtonCancel, 0, wxEXPAND | wxALL, 10);\r
+  \r
+  pTopSizer->Add (pButtonSizer, 0, wxALIGN_CENTER);\r
+  \r
+  SetAutoLayout (true);\r
+  SetSizer (pTopSizer);\r
+  pTopSizer->Fit (this);\r
+  pTopSizer->SetSizeHints (this);\r
+}\r
+\r
+const char*\r
+DialogExportParameters::getFormatName(void)\r
+{\r
+  return m_pListBoxFormat->getSelectionStringValue();\r
+}\r
+\r
+\r
+/////////////////////////////////////////////////////////////////////\r
+// CLASS DiaglogGetXYSize Implementation\r
+/////////////////////////////////////////////////////////////////////\r
+\r
+DialogGetXYSize::DialogGetXYSize (wxFrame* pParent, const char* const pszTitle, int iDefaultXSize, int iDefaultYSize)\r
+: wxDialog (pParent, -1, pszTitle, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxCAPTION)\r
+{\r
+  m_iDefaultXSize = iDefaultXSize;\r
+  m_iDefaultYSize = iDefaultYSize;\r
+\r
+  wxBoxSizer* pTopSizer = new wxBoxSizer (wxVERTICAL);\r
+  \r
+  pTopSizer->Add (new wxStaticText (this, -1, pszTitle), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5);\r
+  \r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);\r
+  \r
+  std::ostringstream os;\r
+  os << iDefaultXSize;\r
+  m_pTextCtrlXSize = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
+  std::ostringstream osYSize;\r
+  osYSize << iDefaultYSize;\r
+  m_pTextCtrlYSize = new wxTextCtrl (this, -1, osYSize.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0);\r
+  \r
+  wxFlexGridSizer *pGridSizer = new wxFlexGridSizer (2);\r
+  pGridSizer->Add (new wxStaticText (this, -1, "X Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (m_pTextCtrlXSize, 0, wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (new wxStaticText (this, -1, "Y Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);\r
+  pGridSizer->Add (m_pTextCtrlYSize, 0, wxALIGN_CENTER_VERTICAL);\r
+  pTopSizer->Add (pGridSizer, 1, wxALL, 10);\r
+  \r
+  pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5);\r
+  \r
+  wxBoxSizer* pButtonSizer = new wxBoxSizer (wxHORIZONTAL);\r
+  wxButton* pButtonOk = new wxButton (this, wxID_OK, "Okay");\r
+  wxButton* pButtonCancel = new wxButton (this, wxID_CANCEL, "Cancel");\r
+  pButtonSizer->Add (pButtonOk, 0, wxEXPAND | wxALL, 10);\r
+  pButtonSizer->Add (pButtonCancel, 0, wxEXPAND | wxALL, 10);\r
+  \r
+  pTopSizer->Add (pButtonSizer, 0, wxALIGN_CENTER);\r
+  \r
+  SetAutoLayout (true);\r
+  SetSizer (pTopSizer);\r
+  pTopSizer->Fit (this);\r
+  pTopSizer->SetSizeHints (this);\r
+}\r
+\r
+DialogGetXYSize::~DialogGetXYSize (void)\r
+{\r
+}\r
+\r
+unsigned int\r
+DialogGetXYSize::getXSize (void)\r
+{\r
+  wxString strCtrl = m_pTextCtrlXSize->GetValue();\r
+  long lValue;\r
+  if (strCtrl.ToLong (&lValue))\r
+    return lValue;\r
+  else\r
+    return (m_iDefaultXSize);\r
+}\r
+\r
+unsigned int\r
+DialogGetXYSize::getYSize (void)\r
+{\r
+  wxString strCtrl = m_pTextCtrlYSize->GetValue();\r
+  long lValue;\r
+  if (strCtrl.ToLong (&lValue))\r
+    return lValue;\r
+  else\r
+    return (m_iDefaultYSize);\r
+}\r
+\r
index 3546021..baf9a2f 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: dialogs.h,v 1.17 2001/01/01 10:14:34 kevin Exp $
+**  $Id: dialogs.h,v 1.18 2001/01/02 05:34:57 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
@@ -87,7 +87,6 @@ class DialogGetComparisonImage : public wxDialog
 };\r
 \r
 
-
 class ImageFile;
 class DialogGetMinMax : public wxDialog
 {
@@ -211,7 +210,7 @@ class DialogGetReconstructionParameters : public wxDialog
 class DialogGetFilterParameters : public wxDialog\r
 {\r
  public:\r
-    DialogGetFilterParameters (wxFrame* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, int iDefaultFilterID = SignalFilter::FILTER_BANDLIMIT, double dDefaultFilterParam = 1., double dDefaultBandwidth = 1., int iDefaultDomain = SignalFilter::DOMAIN_SPATIAL);\r
+    DialogGetFilterParameters (wxFrame* pParent, int iDefaultXSize = 0, int iDefaultYSize = 0, int iDefaultFilterID = SignalFilter::FILTER_BANDLIMIT, double dDefaultFilterParam = 1., double dDefaultBandwidth = 1., int iDefaultDomain = SignalFilter::DOMAIN_SPATIAL, double dDefaultInputScale = 1., double dDefaultOutputScale = 1.);\r
     virtual ~DialogGetFilterParameters ();\r
 \r
     unsigned int getXSize();\r
@@ -219,12 +218,16 @@ class DialogGetFilterParameters : public wxDialog
     const char* getFilterName();\r
     const char* getDomainName();\r
     double getFilterParam();\r
+    double getInputScale();\r
+    double getOutputScale();\r
     double getBandwidth();\r
 \r
  private:\r
     wxTextCtrl* m_pTextCtrlXSize;\r
     wxTextCtrl* m_pTextCtrlYSize;\r
     wxTextCtrl* m_pTextCtrlFilterParam;\r
+    wxTextCtrl* m_pTextCtrlOutputScale;\r
+    wxTextCtrl* m_pTextCtrlInputScale;\r
     wxTextCtrl* m_pTextCtrlBandwidth;\r
 \r
     StringValueAndTitleListBox* m_pListBoxFilter;\r
@@ -234,9 +237,23 @@ class DialogGetFilterParameters : public wxDialog
     int m_iDefaultYSize;\r
     double m_dDefaultFilterParam;\r
     double m_dDefaultBandwidth;\r
+    double m_dDefaultOutputScale;\r
+    double m_dDefaultInputScale;\r
     int m_iDefaultDomain;\r
 };\r
 \r
+class DialogExportParameters : public wxDialog\r
+{\r
+ public:\r
+    DialogExportParameters (wxFrame* pParent, int iDefaultFormatID);\r
+    virtual ~DialogExportParameters () {}\r
+\r
+    const char* getFormatName();\r
+\r
+ private:\r
+    StringValueAndTitleListBox* m_pListBoxFormat;\r
+};\r
+\r
 class DialogAutoScaleParameters : public wxDialog
 {
  public:
@@ -255,6 +272,24 @@ class DialogAutoScaleParameters : public wxDialog
     wxTextCtrl* m_pTextCtrlStdDevFactor;
     wxListBox* m_pListBoxCenter;
 };
+\r
+class DialogGetXYSize : public wxDialog\r
+{\r
+ public:\r
+    DialogGetXYSize (wxFrame* pParent, const char* const pszTitle, int iDefaultXSize = 1, int iDefaultYSize = 1);\r
+    virtual ~DialogGetXYSize ();\r
+\r
+    unsigned int getXSize ();\r
+    unsigned int getYSize ();\r
+\r
+ private:\r
+    wxTextCtrl* m_pTextCtrlXSize;\r
+    wxTextCtrl* m_pTextCtrlYSize;\r
+\r
+    unsigned int m_iDefaultXSize;\r
+    unsigned int m_iDefaultYSize;\r
+};\r
+\r
 
 #endif
 
index bab1d13..69b5954 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: docs.cpp,v 1.9 2000/12/29 15:45:06 kevin Exp $
+**  $Id: docs.cpp,v 1.10 2001/01/02 05:34:57 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
@@ -180,6 +180,17 @@ bool PhantomDocument::OnOpenDocument(const wxString& filename)
   return true;
 }
 
+bool PhantomDocument::OnSaveDocument(const wxString& filename)\r
+{\r
+  if (! m_phantom.fileWrite (filename.c_str())) {\r
+    *theApp->getLog() << "Unable to write phantom file " << filename << "\n";\r
+    return false;\r
+  }\r
+  *theApp->getLog() << "Wrote phantom file " << filename << "\n";\r
+  Modify(false);\r
+  return true;\r
+}\r
+\r
 bool PhantomDocument::OnCloseDocument ()
 {
   bool bReturn = wxDocument::OnCloseDocument();
@@ -229,6 +240,7 @@ bool PlotFileDocument::OnOpenDocument(const wxString& filename)
   }
   Modify (false);
   UpdateAllViews();\r
+  GetFirstView()->OnUpdate (NULL, NULL);\r
 
   return true;
 }
index 3729ce4..c1da82a 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: docs.h,v 1.9 2000/12/27 03:16:02 kevin Exp $
+**  $Id: docs.h,v 1.10 2001/01/02 05:34:57 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
@@ -117,6 +117,7 @@ public:
        { return m_phantom; }
 
     virtual bool OnOpenDocument (const wxString& filename);
+    virtual bool OnSaveDocument (const wxString& filename);\r
     virtual bool OnCloseDocument ();
     virtual bool IsModified () const;
     virtual void Modify (bool mod);
index 93d49b3..3ec3b6b 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: views.cpp,v 1.43 2001/01/01 10:14:34 kevin Exp $
+**  $Id: views.cpp,v 1.44 2001/01/02 05:34:57 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
@@ -165,7 +165,8 @@ ImageFileCanvas::OnMouseEvent(wxMouseEvent& event)
 
 IMPLEMENT_DYNAMIC_CLASS(ImageFileView, wxView)
 
-BEGIN_EVENT_TABLE(ImageFileView, wxView)
+BEGIN_EVENT_TABLE(ImageFileView, wxView)\r
+EVT_MENU(IFMENU_FILE_EXPORT, ImageFileView::OnExport)
 EVT_MENU(IFMENU_FILE_PROPERTIES, ImageFileView::OnProperties)
 EVT_MENU(IFMENU_VIEW_SCALE_MINMAX, ImageFileView::OnScaleMinMax)
 EVT_MENU(IFMENU_VIEW_SCALE_AUTO, ImageFileView::OnScaleAuto)\r
@@ -177,8 +178,15 @@ EVT_MENU(IFMENU_PROCESS_SQUARE, ImageFileView::OnSquare)
 EVT_MENU(IFMENU_PROCESS_SQRT, ImageFileView::OnSquareRoot)\r
 EVT_MENU(IFMENU_PROCESS_LOG, ImageFileView::OnLog)\r
 EVT_MENU(IFMENU_PROCESS_EXP, ImageFileView::OnExp)\r
+EVT_MENU(IFMENU_PROCESS_ADD, ImageFileView::OnAdd)\r
+EVT_MENU(IFMENU_PROCESS_SUBTRACT, ImageFileView::OnSubtract)\r
+EVT_MENU(IFMENU_PROCESS_MULTIPLY, ImageFileView::OnMultiply)\r
+EVT_MENU(IFMENU_PROCESS_DIVIDE, ImageFileView::OnDivide)\r
 EVT_MENU(IFMENU_PROCESS_FOURIER, ImageFileView::OnFourier)\r
+EVT_MENU(IFMENU_PROCESS_SCALESIZE, ImageFileView::OnScaleSize)\r
 EVT_MENU(IFMENU_PROCESS_INVERSE_FOURIER, ImageFileView::OnInverseFourier)\r
+EVT_MENU(IFMENU_PROCESS_SHUFFLEFOURIERTONATURALORDER, ImageFileView::OnShuffleFourierToNaturalOrder)\r
+EVT_MENU(IFMENU_PROCESS_SHUFFLENATURALTOFOURIERORDER, ImageFileView::OnShuffleNaturalToFourierOrder)\r
 #ifdef HAVE_FFTW\r
 EVT_MENU(IFMENU_PROCESS_FFT, ImageFileView::OnFFT)\r
 EVT_MENU(IFMENU_PROCESS_IFFT, ImageFileView::OnIFFT)\r
@@ -191,7 +199,8 @@ END_EVENT_TABLE()
 
 ImageFileView::ImageFileView(void) 
 : wxView(), m_canvas(NULL), m_frame(NULL), m_bMinSpecified(false), m_bMaxSpecified(false)
-{
+{\r
+  m_iDefaultExportFormatID = ImageFile::FORMAT_PNG;\r
 }
 
 ImageFileView::~ImageFileView(void)
@@ -221,6 +230,10 @@ ImageFileView::OnProperties (wxCommandEvent& event)
       rIF.statistics (rIF.getImaginaryArray(), min, max, mean, mode, median, stddev);\r
       os << "\nImaginary: min: "<<min<<"\nmax: "<<max<<"\nmean: "<<mean<<"\nmedian: "<<median<<"\nmode: "<<mode<<"\nstddev: "<<stddev << "\n";\r
     }\r
+    if (rIF.nLabels() > 0) {\r
+      os << "\n";\r
+      rIF.printLabelsBrief (os);\r
+    }\r
     *theApp->getLog() << os.str().c_str();
     wxMessageDialog dialogMsg (m_frame, os.str().c_str(), "Imagefile Properties", wxOK | wxICON_INFORMATION);
     dialogMsg.ShowModal();
@@ -292,7 +305,7 @@ ImageFileView::OnCompare (wxCommandEvent& event)
       rIF.statistics (min, max, mean, mode, median, stddev);\r
       os << rIF.getFilename() << ": minimum=" << min << ", maximum=" << max << ", mean=" << mean << ", mode=" << mode << ", median=" << median << ", stddev=" << stddev << "\n";\r
       rCompareIF.statistics (min, max, mean, mode, median, stddev);\r
-      os << pCompareDoc->GetTitle().c_str() << ": minimum=" << min << ", maximum=" << max << ", mean=" << mean << ", mode=" << mode << ", median=" << median << ", stddev=" << stddev << "\n";\r
+      os << pCompareDoc->GetFirstView()->GetFrame()->GetTitle().c_str() << ": minimum=" << min << ", maximum=" << max << ", mean=" << mean << ", mode=" << mode << ", median=" << median << ", stddev=" << stddev << "\n";\r
       os << "\n";\r
       double d, r, e;\r
       rIF.comparativeStatistics (rCompareIF, d, r, e);\r
@@ -327,6 +340,7 @@ ImageFileView::OnInvertValues (wxCommandEvent& event)
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   rIF.invertPixelValues (rIF);\r
+  rIF.labelAdd ("Invert Pixel Values");\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
@@ -337,6 +351,7 @@ ImageFileView::OnSquare (wxCommandEvent& event)
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   rIF.square (rIF);\r
+  rIF.labelAdd ("Square Pixel Values");\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
@@ -347,6 +362,7 @@ ImageFileView::OnSquareRoot (wxCommandEvent& event)
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   rIF.sqrt (rIF);\r
+  rIF.labelAdd ("Square-root Pixel Values");\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
@@ -357,6 +373,7 @@ ImageFileView::OnLog (wxCommandEvent& event)
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   rIF.log (rIF);\r
+  rIF.labelAdd ("Logrithm base-e Pixel Values");\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
@@ -367,24 +384,125 @@ ImageFileView::OnExp (wxCommandEvent& event)
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   rIF.exp (rIF);\r
+  rIF.labelAdd ("Exponent base-e Pixel Values");\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
 }\r
 \r
 void\r
-ImageFileView::OnFourier (wxCommandEvent& event)\r
+ImageFileView::OnAdd (wxCommandEvent& event)\r
 {\r
-  ImageFile& rIF = GetDocument()->getImageFile();\r
-  wxProgressDialog dlgProgress (wxString("Fourier"), wxString("Fourier Progress"), 1, m_frame, wxPD_APP_MODAL);\r
-  rIF.fourier (rIF);\r
-  m_bMinSpecified = false;\r
-  m_bMaxSpecified = false;\r
-  if (theApp->getSetModifyNewDocs())\r
-    GetDocument()->Modify(TRUE);\r
-  GetDocument()->UpdateAllViews(this);\r
+  std::vector<ImageFileDocument*> vecIF;\r
+  theApp->getCompatibleImages (GetDocument(), vecIF);\r
+  \r
+  if (vecIF.size() == 0) {\r
+    wxMessageBox ("There are no compatible image files open for comparision", "No comparison images");\r
+  } else {\r
+    DialogGetComparisonImage dialogGetCompare (m_frame, "Get Image to Add", vecIF, false);\r
+    \r
+    if (dialogGetCompare.ShowModal() == wxID_OK) {\r
+      ImageFile& rIF = GetDocument()->getImageFile();\r
+      ImageFileDocument* pRHSDoc = dialogGetCompare.getImageFileDocument();\r
+      const ImageFile& rRHSIF = pRHSDoc->getImageFile();\r
+      rIF.addImages (rRHSIF, rIF);\r
+      std::ostringstream os;\r
+      os << "Add image " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str() << " and " \r
+        << pRHSDoc->GetFirstView()->GetFrame()->GetTitle().c_str();\r
+      rIF.labelAdd (os.str().c_str());\r
+      *theApp->getLog() << os.str().c_str() << "\n";\r
+      if (theApp->getSetModifyNewDocs())\r
+        GetDocument()->Modify(TRUE);\r
+      GetDocument()->UpdateAllViews(this);\r
+    }\r
+  }\r
 }\r
 \r
+void\r
+ImageFileView::OnSubtract (wxCommandEvent& event)\r
+{\r
+  std::vector<ImageFileDocument*> vecIF;\r
+  theApp->getCompatibleImages (GetDocument(), vecIF);\r
+  \r
+  if (vecIF.size() == 0) {\r
+    wxMessageBox ("There are no compatible image files open for comparision", "No comparison images");\r
+  } else {\r
+    DialogGetComparisonImage dialogGetCompare (m_frame, "Get Image to Subtract", vecIF, false);\r
+    \r
+    if (dialogGetCompare.ShowModal() == wxID_OK) {\r
+      ImageFile& rIF = GetDocument()->getImageFile();\r
+      ImageFileDocument* pRHSDoc = dialogGetCompare.getImageFileDocument();\r
+      const ImageFile& rRHSIF = pRHSDoc->getImageFile();\r
+      rIF.subtractImages (rRHSIF, rIF);\r
+      std::ostringstream os;\r
+      os << "Subtract image " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str() \r
+        << " and " << pRHSDoc->GetFirstView()->GetFrame()->GetTitle().c_str();\r
+      rIF.labelAdd (os.str().c_str());\r
+      *theApp->getLog() << os.str().c_str() << "\n";\r
+      if (theApp->getSetModifyNewDocs())\r
+        GetDocument()->Modify(TRUE);\r
+      GetDocument()->UpdateAllViews(this);\r
+    }\r
+  }\r
+}\r
+\r
+void\r
+ImageFileView::OnMultiply (wxCommandEvent& event)\r
+{\r
+  std::vector<ImageFileDocument*> vecIF;\r
+  theApp->getCompatibleImages (GetDocument(), vecIF);\r
+  \r
+  if (vecIF.size() == 0) {\r
+    wxMessageBox ("There are no compatible image files open for comparision", "No comparison images");\r
+  } else {\r
+    DialogGetComparisonImage dialogGetCompare (m_frame, "Get Image to Multiply", vecIF, false);\r
+    \r
+    if (dialogGetCompare.ShowModal() == wxID_OK) {\r
+      ImageFile& rIF = GetDocument()->getImageFile();\r
+      ImageFileDocument* pRHSDoc = dialogGetCompare.getImageFileDocument();\r
+      const ImageFile& rRHSIF = pRHSDoc->getImageFile();\r
+      rIF.multiplyImages (rRHSIF, rIF);\r
+      std::ostringstream os;\r
+      os << "Multiply image " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str() \r
+        << " and " << pRHSDoc->GetFirstView()->GetFrame()->GetTitle().c_str();\r
+      rIF.labelAdd (os.str().c_str());\r
+      *theApp->getLog() << os.str().c_str() << "\n";\r
+      if (theApp->getSetModifyNewDocs())\r
+        GetDocument()->Modify(TRUE);\r
+      GetDocument()->UpdateAllViews(this);\r
+    }\r
+  }\r
+}\r
+\r
+void\r
+ImageFileView::OnDivide (wxCommandEvent& event)\r
+{\r
+  std::vector<ImageFileDocument*> vecIF;\r
+  theApp->getCompatibleImages (GetDocument(), vecIF);\r
+  \r
+  if (vecIF.size() == 0) {\r
+    wxMessageBox ("There are no compatible image files open for comparision", "No comparison images");\r
+  } else {\r
+    DialogGetComparisonImage dialogGetCompare (m_frame, "Get Image to Divide", vecIF, false);\r
+    \r
+    if (dialogGetCompare.ShowModal() == wxID_OK) {\r
+      ImageFile& rIF = GetDocument()->getImageFile();\r
+      ImageFileDocument* pRHSDoc = dialogGetCompare.getImageFileDocument();\r
+      const ImageFile& rRHSIF = pRHSDoc->getImageFile();\r
+      rIF.divideImages (rRHSIF, rIF);\r
+      std::ostringstream os;\r
+      os << "Divide image " << GetDocument()->GetFirstView()->GetFrame()->GetTitle().c_str() \r
+        << " by " << pRHSDoc->GetFirstView()->GetFrame()->GetTitle().c_str();\r
+      rIF.labelAdd (os.str().c_str());\r
+      *theApp->getLog() << os.str().c_str() << "\n";\r
+      if (theApp->getSetModifyNewDocs())\r
+        GetDocument()->Modify(TRUE);\r
+      GetDocument()->UpdateAllViews(this);\r
+    }\r
+  }\r
+}\r
+\r
+\r
 #ifdef HAVE_FFTW\r
 void\r
 ImageFileView::OnFFT (wxCommandEvent& event)\r
@@ -392,6 +510,7 @@ ImageFileView::OnFFT (wxCommandEvent& event)
   ImageFile& rIF = GetDocument()->getImageFile();\r
   wxProgressDialog dlgProgress (wxString("FFT"), wxString("FFT Progress"), 1, m_frame, wxPD_APP_MODAL);\r
   rIF.fft (rIF);\r
+  rIF.labelAdd ("FFT Image");\r
   m_bMinSpecified = false;\r
   m_bMaxSpecified = false;\r
   if (theApp->getSetModifyNewDocs())\r
@@ -405,6 +524,7 @@ ImageFileView::OnIFFT (wxCommandEvent& event)
   ImageFile& rIF = GetDocument()->getImageFile();\r
   wxProgressDialog dlgProgress (wxString("IFFT"), wxString("IFFT Progress"), 1, m_frame, wxPD_APP_MODAL);\r
   rIF.ifft (rIF);\r
+  rIF.labelAdd ("IFFT Image");\r
   m_bMinSpecified = false;\r
   m_bMaxSpecified = false;\r
   if (theApp->getSetModifyNewDocs())\r
@@ -413,12 +533,52 @@ ImageFileView::OnIFFT (wxCommandEvent& event)
 }\r
 #endif\r
 \r
+void\r
+ImageFileView::OnFourier (wxCommandEvent& event)\r
+{\r
+  ImageFile& rIF = GetDocument()->getImageFile();\r
+  wxProgressDialog dlgProgress (wxString("Fourier"), wxString("Fourier Progress"), 1, m_frame, wxPD_APP_MODAL);\r
+  rIF.fourier (rIF);\r
+  rIF.labelAdd ("Fourier Image");\r
+  m_bMinSpecified = false;\r
+  m_bMaxSpecified = false;\r
+  if (theApp->getSetModifyNewDocs())\r
+    GetDocument()->Modify(TRUE);\r
+  GetDocument()->UpdateAllViews(this);\r
+}\r
 void\r
 ImageFileView::OnInverseFourier (wxCommandEvent& event)\r
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
   wxProgressDialog dlgProgress (wxString("Inverse Fourier"), wxString("Inverse Fourier Progress"), 1, m_frame, wxPD_APP_MODAL);\r
   rIF.inverseFourier (rIF);\r
+  rIF.labelAdd ("Inverse Fourier Image");\r
+  m_bMinSpecified = false;\r
+  m_bMaxSpecified = false;\r
+  if (theApp->getSetModifyNewDocs())\r
+    GetDocument()->Modify(TRUE);\r
+  GetDocument()->UpdateAllViews(this);\r
+}\r
+\r
+void\r
+ImageFileView::OnShuffleNaturalToFourierOrder (wxCommandEvent& event)\r
+{\r
+  ImageFile& rIF = GetDocument()->getImageFile();\r
+  Fourier::shuffleNaturalToFourierOrder (rIF);\r
+  rIF.labelAdd ("Shuffle Natural To Fourier Order");\r
+  m_bMinSpecified = false;\r
+  m_bMaxSpecified = false;\r
+  if (theApp->getSetModifyNewDocs())\r
+    GetDocument()->Modify(TRUE);\r
+  GetDocument()->UpdateAllViews(this);\r
+}\r
+\r
+void\r
+ImageFileView::OnShuffleFourierToNaturalOrder (wxCommandEvent& event)\r
+{\r
+  ImageFile& rIF = GetDocument()->getImageFile();\r
+  Fourier::shuffleFourierToNaturalOrder (rIF);\r
+  rIF.labelAdd ("Shuffle Fourier To Natural Order");\r
   m_bMinSpecified = false;\r
   m_bMaxSpecified = false;\r
   if (theApp->getSetModifyNewDocs())\r
@@ -430,24 +590,30 @@ void
 ImageFileView::OnMagnitude (wxCommandEvent& event)\r
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
-  rIF.magnitude (rIF);\r
+  if (rIF.isComplex()) {\r
+    rIF.magnitude (rIF);\r
+    rIF.labelAdd ("Magnitude of complex-image");\r
   m_bMinSpecified = false;\r
   m_bMaxSpecified = false;\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
+  }\r
 }\r
 \r
 void\r
 ImageFileView::OnPhase (wxCommandEvent& event)\r
 {\r
   ImageFile& rIF = GetDocument()->getImageFile();\r
-  rIF.phase (rIF);\r
+  if (rIF.isComplex()) {\r
+    rIF.phase (rIF);\r
+    rIF.labelAdd ("Phase of complex-image");\r
   m_bMinSpecified = false;\r
   m_bMaxSpecified = false;\r
   if (theApp->getSetModifyNewDocs())\r
     GetDocument()->Modify(TRUE);\r
   GetDocument()->UpdateAllViews(this);\r
+  }\r
 }\r
 \r
 \r
@@ -481,8 +647,9 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   file_menu->Append(wxID_SAVEAS, "Save &As...");
   file_menu->Append(wxID_CLOSE, "&Close");
   
-  file_menu->AppendSeparator();
+  file_menu->AppendSeparator();\r
   file_menu->Append(IFMENU_FILE_PROPERTIES, "P&roperties");
+  file_menu->Append(IFMENU_FILE_EXPORT, "&Export...");\r
   
   file_menu->AppendSeparator();
   file_menu->Append(wxID_PRINT, "&Print...");
@@ -500,6 +667,13 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   process_menu->Append (IFMENU_PROCESS_LOG, "&Log");\r
   process_menu->Append (IFMENU_PROCESS_EXP, "&Exp");\r
   process_menu->AppendSeparator();\r
+  process_menu->Append (IFMENU_PROCESS_ADD, "&Add");\r
+  process_menu->Append (IFMENU_PROCESS_SUBTRACT, "Su&btract");\r
+  process_menu->Append (IFMENU_PROCESS_MULTIPLY, "&Multiply");\r
+  process_menu->Append (IFMENU_PROCESS_DIVIDE, "&Divide");\r
+  process_menu->AppendSeparator();\r
+  process_menu->Append (IFMENU_PROCESS_SCALESIZE, "S&cale Size...");\r
+  process_menu->AppendSeparator();\r
 #ifdef HAVE_FFTW\r
   process_menu->Append (IFMENU_PROCESS_FFT, "&FFT");\r
   process_menu->Append (IFMENU_PROCESS_IFFT, "&IFFT");\r
@@ -509,6 +683,8 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
   process_menu->Append (IFMENU_PROCESS_FOURIER, "&Fourier");\r
   process_menu->Append (IFMENU_PROCESS_INVERSE_FOURIER, "&Inverse Fourier");\r
 #endif\r
+  process_menu->Append (IFMENU_PROCESS_SHUFFLEFOURIERTONATURALORDER, "S&huffle Fourier to Natural Order");\r
+  process_menu->Append (IFMENU_PROCESS_SHUFFLENATURALTOFOURIERORDER, "Shu&ffle Natural to Fourier Order");\r
   process_menu->Append (IFMENU_PROCESS_MAGNITUDE, "&Magnitude");\r
   process_menu->Append (IFMENU_PROCESS_PHASE, "&Phase");\r
 \r
@@ -542,7 +718,7 @@ ImageFileView::CreateChildFrame(wxDocument *doc, wxView *view)
 
 
 bool 
-ImageFileView::OnCreate(wxDocument *doc, long WXUNUSED(flags) )
+ImageFileView::OnCreate (wxDocument *doc, long WXUNUSED(flags) )
 {
   m_frame = CreateChildFrame(doc, this);
   SetFrame (m_frame);
@@ -645,6 +821,80 @@ ImageFileView::OnClose (bool deleteWindow)
   return true;
 }
 \r
+void\r
+ImageFileView::OnExport (wxCommandEvent& event)\r
+{\r
+  ImageFile& rIF = dynamic_cast<ImageFileDocument*>(GetDocument())->getImageFile();\r
+  ImageFileArrayConst v = rIF.getArray();\r
+  int nx = rIF.nx();\r
+  int ny = rIF.ny();\r
+  if (v != NULL && nx != 0 && ny != 0) {\r
+    if (! m_bMinSpecified || ! m_bMaxSpecified) {\r
+      double min, max;\r
+      rIF.getMinMax (min, max);\r
+      if (! m_bMinSpecified)\r
+        m_dMinPixel = min;\r
+      if (! m_bMaxSpecified)\r
+        m_dMaxPixel = max;\r
+    }\r
+\r
+    DialogExportParameters dialogExport (m_frame, m_iDefaultExportFormatID);\r
+    if (dialogExport.ShowModal() == wxID_OK) {\r
+      wxString strFormatName (dialogExport.getFormatName ());\r
+      m_iDefaultExportFormatID = ImageFile::convertFormatNameToID (strFormatName.c_str());\r
+\r
+      wxString strExt;\r
+      wxString strWildcard;\r
+      if (m_iDefaultExportFormatID == ImageFile::FORMAT_PGM || m_iDefaultExportFormatID == ImageFile::FORMAT_PGMASCII) {\r
+        strExt = ".pgm";\r
+        strWildcard = "PGM Files (*.pgm)|*.pgm";\r
+      }\r
+#ifdef HAVE_PNG\r
+      else if (m_iDefaultExportFormatID == ImageFile::FORMAT_PNG || m_iDefaultExportFormatID == ImageFile::FORMAT_PNG16) {\r
+        strExt = ".png";\r
+        strWildcard = "PNG Files (*.png)|*.png";\r
+      }\r
+#endif\r
+\r
+      const wxString& strFilename = wxFileSelector (wxString("Export Filename"), wxString(""), \r
+        wxString(""), strExt, strWildcard, wxOVERWRITE_PROMPT | wxHIDE_READONLY | wxSAVE);\r
+      if (strFilename) {\r
+        rIF.exportImage (strFormatName.c_str(), strFilename.c_str(), 1, 1, m_dMinPixel, m_dMaxPixel);\r
+        *theApp->getLog() << "Exported file " << strFilename << "\n";\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+void\r
+ImageFileView::OnScaleSize (wxCommandEvent& event)\r
+{\r
+  ImageFile& rIF = GetDocument()->getImageFile();\r
+  unsigned int iOldNX = rIF.nx();\r
+  unsigned int iOldNY = rIF.ny();\r
+\r
+  DialogGetXYSize dialogGetXYSize (m_frame, "Set New X & Y Dimensions", iOldNX, iOldNY);\r
+  if (dialogGetXYSize.ShowModal() == wxID_OK) {\r
+    unsigned int iNewNX = dialogGetXYSize.getXSize();\r
+    unsigned int iNewNY = dialogGetXYSize.getYSize();\r
+    std::ostringstream os;\r
+    os << "Scale Size from (" << iOldNX << "," << iOldNY << ") to (" << iNewNX << "," << iNewNY << ")";\r
+    ImageFileDocument* pScaledDoc = dynamic_cast<ImageFileDocument*>(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT));\r
+    if (! pScaledDoc) {\r
+      sys_error (ERR_SEVERE, "Unable to create image file");\r
+      return;\r
+    }\r
+    ImageFile& rScaledIF = pScaledDoc->getImageFile();\r
+    rScaledIF.setArraySize (iNewNX, iNewNY);\r
+    rScaledIF.labelAdd (os.str().c_str());\r
+    rIF.scaleImage (rScaledIF);\r
+    *theApp->getLog() << os.str().c_str() << "\n";\r
+    if (theApp->getSetModifyNewDocs())\r
+      pScaledDoc->Modify(TRUE);\r
+    pScaledDoc->UpdateAllViews (this);\r
+    pScaledDoc->GetFirstView()->OnUpdate (this, NULL);\r
+  }\r
+}\r
 \r
 void\r
 ImageFileView::OnPlotRow (wxCommandEvent& event)\r
@@ -896,7 +1146,7 @@ PhantomCanvas::PhantomCanvas (PhantomView* v, wxFrame *frame, const wxPoint& pos
 }
 
 void 
-PhantomCanvas::OnDraw(wxDC& dc)
+PhantomCanvas::OnDraw (wxDC& dc)
 {
   if (m_pView)
     m_pView->OnDraw(& dc);
@@ -936,12 +1186,14 @@ PhantomView::OnProperties (wxCommandEvent& event)
   const int idPhantom = GetDocument()->getPhantomID();
   const wxString& namePhantom = GetDocument()->getPhantomName();
   std::ostringstream os;
-  os << "Phantom " << namePhantom.c_str() << " (" << idPhantom << ")\n";
-  *theApp->getLog() << os.str().c_str();
+  os << "Phantom " << namePhantom.c_str() << " (" << idPhantom << ")" << "\n";\r
+  const Phantom& rPhantom = GetDocument()->getPhantom();\r
+  rPhantom.printDefinitions (os);
 #if DEBUG
-  const Phantom& rPhantom = GetDocument()->getPhantom();
-  rPhantom.print();
+  rPhantom.print (os);
 #endif
+  *theApp->getLog() << os.str().c_str() << "\n";\r
+  wxMessageBox (os.str().c_str(), "Phantom Properties");\r
 }
 
 
@@ -1102,7 +1354,8 @@ PhantomView::CreateChildFrame(wxDocument *doc, wxView *view)
   
   file_menu->Append(MAINMENU_FILE_CREATE_PHANTOM, "Cr&eate Phantom...");
   file_menu->Append(MAINMENU_FILE_CREATE_FILTER, "Create &Filter...");\r
-  file_menu->Append(wxID_OPEN, "&Open...");
+  file_menu->Append(wxID_OPEN, "&Open...");\r
+  file_menu->Append(wxID_SAVEAS, "Save &As...");\r
   file_menu->Append(wxID_CLOSE, "&Close");
   
   file_menu->AppendSeparator();
@@ -1571,9 +1824,10 @@ PlotFileView::~PlotFileView(void)
 void
 PlotFileView::OnProperties (wxCommandEvent& event)
 {
-  const PlotFile& rProj = GetDocument()->getPlotFile();
+  const PlotFile& rPlot = GetDocument()->getPlotFile();
   std::ostringstream os;\r
-  os << "Columns: " << rProj.getNumColumns() << ", Records: " << rProj.getNumRecords() << "\n";
+  os << "Columns: " << rPlot.getNumColumns() << ", Records: " << rPlot.getNumRecords() << "\n";\r
+  rPlot.printHeaders (os);
   *theApp->getLog() << os.str().c_str();
   wxMessageDialog dialogMsg (m_frame, os.str().c_str(), "Plot File Properties", wxOK | wxICON_INFORMATION);
   dialogMsg.ShowModal();
@@ -1605,9 +1859,10 @@ void
 PlotFileView::OnScaleMinMax (wxCommandEvent& event)\r
 {\r
   const PlotFile& rPlotFile = GetDocument()->getPlotFile();\r
-  double min, max;\r
-  \r
-  if (! m_bMinSpecified && ! m_bMaxSpecified) {\r
+  double min;\r
+  double max;\r
+\r
+  if (! m_bMinSpecified || ! m_bMaxSpecified) {\r
     if (! rPlotFile.getMinMax (1, min, max)) {\r
       *theApp->getLog() << "Error: unable to find Min/Max\n";\r
       return;\r
@@ -1739,7 +1994,6 @@ PlotFileView::OnDraw (wxDC* dc)
 void 
 PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
 {
-  if (m_canvas) {
     const PlotFile& rPlotFile = GetDocument()->getPlotFile();\r
     const int iNColumns = rPlotFile.getNumColumns();\r
     const int iNRecords = rPlotFile.getNumRecords();\r
@@ -1779,9 +2033,9 @@ PlotFileView::OnUpdate (wxView *WXUNUSED(sender), wxObject *WXUNUSED(hint) )
       delete pdXaxis;\r
       delete pdY;\r
     }\r
-    \r
-    m_canvas->Refresh();\r
-  }
+\r
+    if (m_canvas)\r
+      m_canvas->Refresh();\r
 }
 
 bool 
index 8d46ae3..024b885 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: views.h,v 1.20 2001/01/01 10:14:34 kevin Exp $
+**  $Id: views.h,v 1.21 2001/01/02 05:34:57 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
@@ -55,6 +55,8 @@ private:
     double m_dMinPixel;
     double m_dMaxPixel;
     double m_dAutoScaleFactor;
+\r
+    int m_iDefaultExportFormatID;\r
 
 public:
     ImageFileView(void);
@@ -63,7 +65,10 @@ public:
     bool OnCreate(wxDocument *doc, long flags);
     void OnDraw(wxDC* dc);
     void OnUpdate(wxView *sender, wxObject *hint = NULL);
-    bool OnClose (bool deleteWindow = true);
+    bool OnClose (bool deleteWindow = true);\r
+\r
+    void OnScaleSize (wxCommandEvent& event);
+    void OnExport (wxCommandEvent& event);\r
     void OnProperties (wxCommandEvent& event);
     void OnCompare (wxCommandEvent& event);\r
     void OnInvertValues (wxCommandEvent& event);\r
@@ -71,8 +76,14 @@ public:
     void OnSquareRoot (wxCommandEvent& event);\r
     void OnLog (wxCommandEvent& event);\r
     void OnExp (wxCommandEvent& event);\r
+    void OnAdd (wxCommandEvent& event);\r
+    void OnSubtract (wxCommandEvent& event);\r
+    void OnMultiply (wxCommandEvent& event);\r
+    void OnDivide (wxCommandEvent& event);\r
     void OnFourier (wxCommandEvent& event);\r
     void OnInverseFourier (wxCommandEvent& event);\r
+    void OnShuffleNaturalToFourierOrder (wxCommandEvent& event);\r
+    void OnShuffleFourierToNaturalOrder (wxCommandEvent& event);\r
 #ifdef HAVE_FFTW\r
     void OnFFT (wxCommandEvent& event);\r
     void OnIFFT (wxCommandEvent& event);\r
index e00e84e..e0ca9c8 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2if.cpp,v 1.16 2000/12/17 23:30:48 kevin Exp $
+**  $Id: phm2if.cpp,v 1.17 2001/01/02 05:34:57 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
@@ -50,7 +50,7 @@ static struct option my_options[] =
   {0, 0, 0, 0}
 };
 
-static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.16 2000/12/17 23:30:48 kevin Exp $";
+static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.17 2001/01/02 05:34:57 kevin Exp $";
 
 void 
 phm2if_usage (const char *program)
@@ -354,10 +354,11 @@ phm2if_main (int argc, char* argv[])
       double dmin, dmax;
       int nscale;
       
-      printf ("Enter display size scale (nominal = 1): ");
-      scanf ("%d", &nscale);
-      printf ("Enter minimum and maximum densities (min, max): ");
-      scanf ("%lf %lf", &dmin, &dmax);
+      std::cout << "Enter display size scale (nominal = 1): ";
+      std::cin >> nscale;
+      std::cout ("Enter minimum and maximum densities (min, max): ";
+      std::cin >> dmin;\r
+      std::cin >> dmax;
       pImGlobal->displayScaling (nscale, dmin, dmax);
     }
   }
index c47eec9..9d53148 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: phm2pj.cpp,v 1.19 2000/12/18 00:09:59 kevin Exp $
+**  $Id: phm2pj.cpp,v 1.20 2001/01/02 05:34:57 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
@@ -50,7 +50,7 @@ static struct option phm2pj_options[] =
   {0, 0, 0, 0}
 };
 
-static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.19 2000/12/18 00:09:59 kevin Exp $";
+static const char* g_szIdStr = "$Id: phm2pj.cpp,v 1.20 2001/01/02 05:34:57 kevin Exp $";
 
 
 void 
@@ -353,13 +353,13 @@ phm2pj_main (int argc, char* argv[])
       pjGlobal.setRemark (opt_desc);
       pjGlobal.write (opt_outfile);
       if (opt_verbose) {
-       phm.print();
-       std::cout << std::endl;
-       std::ostringstream os;
-       pjGlobal.printScanInfo (os);
-       std::cout << os.str() << std::endl;
-       std::cout << "  Remark: " << pjGlobal.remark() << std::endl;
-       std::cout << "Run time: " << pjGlobal.calcTime() << " seconds\n";
+        phm.print (std::cout);
+       std::cout << std::endl;
+             std::ostringstream os;
+             pjGlobal.printScanInfo (os);
+             std::cout << os.str() << std::endl;
+             std::cout << "  Remark: " << pjGlobal.remark() << std::endl;
+             std::cout << "Run time: " << pjGlobal.calcTime() << " seconds\n";
       }
     }