r348: fix linefeed problem
[ctsim.git] / libctsim / imagefile.cpp
index cc7e23489af837a9b99ef30f9f42369abce3b090..df0e51ec073981d312bdf265891a909d7125cc3a 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2000 Kevin Rosenberg
 **
-**  $Id: imagefile.cpp,v 1.32 2001/01/02 10:23:46 kevin Exp $
+**  $Id: imagefile.cpp,v 1.33 2001/01/02 16:02:13 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
+const int ImageFile::FORMAT_INVALID = -1;
+const int ImageFile::FORMAT_PGM = 0;
+const int ImageFile::FORMAT_PGMASCII = 1;
+#ifdef HAVE_PNG
+const int ImageFile::FORMAT_PNG = 2;
+const int ImageFile::FORMAT_PNG16 = 3;
+#endif
+
+const char* ImageFile::s_aszFormatName[] = 
+{
+  {"pgm"},
+  {"pgmascii"},
+#ifdef HAVE_PNG
+  {"png"},
+  {"png16"},
+#endif
+};
+
+const char* ImageFile::s_aszFormatTitle[] = 
+{
+  {"PGM"},
+  {"PGM ASCII"},
+  {"PNG"},
+  {"PNG 16-bit"},
+};
+
+const int ImageFile::s_iFormatCount = sizeof(s_aszFormatName) / sizeof(const char*);
 
-F32Image::F32Image (int nx, int ny, int dataType)\r
-: Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32, dataType)\r
-{\r
-}\r
-\r
-F32Image::F32Image (void)\r
-: Array2dFile()\r
-{\r
-  setPixelFormat (Array2dFile::PIXEL_FLOAT32);\r
-  setPixelSize (sizeof(kfloat32));\r
-  setDataType (Array2dFile::DATA_TYPE_REAL);\r
-}\r
-\r
-F64Image::F64Image (int nx, int ny, int dataType)\r
-: Array2dFile (nx, ny, sizeof(kfloat64), Array2dFile::PIXEL_FLOAT64, dataType)\r
-{\r
-}\r
-\r
-F64Image::F64Image (void)\r
-: Array2dFile ()\r
-{\r
-  setPixelFormat (PIXEL_FLOAT64);\r
-  setPixelSize (sizeof(kfloat64));\r
-  setDataType (Array2dFile::DATA_TYPE_REAL);\r
-}\r
+
+
+F32Image::F32Image (int nx, int ny, int dataType)
+: Array2dFile (nx, ny, sizeof(kfloat32), Array2dFile::PIXEL_FLOAT32, dataType)
+{
+}
+
+F32Image::F32Image (void)
+: Array2dFile()
+{
+  setPixelFormat (Array2dFile::PIXEL_FLOAT32);
+  setPixelSize (sizeof(kfloat32));
+  setDataType (Array2dFile::DATA_TYPE_REAL);
+}
+
+F64Image::F64Image (int nx, int ny, int dataType)
+: Array2dFile (nx, ny, sizeof(kfloat64), Array2dFile::PIXEL_FLOAT64, dataType)
+{
+}
+
+F64Image::F64Image (void)
+: Array2dFile ()
+{
+  setPixelFormat (PIXEL_FLOAT64);
+  setPixelSize (sizeof(kfloat64));
+  setDataType (Array2dFile::DATA_TYPE_REAL);
+}
 
 void 
 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
-  \r
-  int iXCenter, iYCenter;\r
-  if (isEven (m_nx))\r
-    iXCenter = m_nx / 2;\r
-  else\r
-    iXCenter = (m_nx - 1) / 2;\r
-  if (isEven (m_ny))\r
-    iYCenter = m_ny / 2;\r
-  else\r
-    iYCenter = (m_ny - 1) / 2;\r
-  \r
-  for (unsigned int ix = 0; ix < m_nx; ix++)\r
-    for (unsigned 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)) * dInputScale;\r
-      v[ix][iy] = filter.response (r) * dOutputScale;\r
-    }\r
+{
+  ImageFileArray v = getArray();
+  SignalFilter filter (filterName, domainName, bw, filt_param);
+  
+  int iXCenter, iYCenter;
+  if (isEven (m_nx))
+    iXCenter = m_nx / 2;
+  else
+    iXCenter = (m_nx - 1) / 2;
+  if (isEven (m_ny))
+    iYCenter = m_ny / 2;
+  else
+    iYCenter = (m_ny - 1) / 2;
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++)
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      long lD2 = ((ix - iXCenter) * (ix - iXCenter)) + ((iy - iYCenter) * (iy - iYCenter));
+      double r = ::sqrt (static_cast<double>(lD2)) * dInputScale;
+      v[ix][iy] = filter.response (r) * dOutputScale;
+    }
 }
 
 int
@@ -250,58 +250,58 @@ ImageFile::printStatistics (std::ostream& os) const
 {
   double min, max, mean, mode, median, stddev;
   
-  statistics (min, max, mean, mode, median, stddev);\r
-  if (isComplex())\r
-    os << "Real Component Statistics" << std::endl;\r
+  statistics (min, max, mean, mode, median, stddev);
+  if (isComplex())
+    os << "Real Component Statistics" << std::endl;
   
   os << "   min: " << min << std::endl;
   os << "   max: " << max << std::endl;
   os << "  mean: " << mean << std::endl;
   os << "  mode: " << mode << std::endl;
   os << "median: " << median << std::endl;
-  os << "stddev: " << stddev << std::endl;\r
-  \r
-  if (isComplex()) {\r
-    statistics (getImaginaryArray(), min, max, mean, mode, median, stddev);\r
+  os << "stddev: " << stddev << std::endl;
+  
+  if (isComplex()) {
+    statistics (getImaginaryArray(), min, max, mean, mode, median, stddev);
     os << std::endl << "Imaginary Component Statistics" << std::endl;
-    os << "   min: " << min << std::endl;\r
-    os << "   max: " << max << std::endl;\r
-    os << "  mean: " << mean << std::endl;\r
-    os << "  mode: " << mode << std::endl;\r
-    os << "median: " << median << std::endl;\r
-    os << "stddev: " << stddev << std::endl;\r
-  }\r
+    os << "   min: " << min << std::endl;
+    os << "   max: " << max << std::endl;
+    os << "  mean: " << mean << std::endl;
+    os << "  mode: " << mode << std::endl;
+    os << "median: " << median << std::endl;
+    os << "stddev: " << stddev << std::endl;
+  }
 }
 
 
 void
 ImageFile::statistics (double& min, double& max, double& mean, double& mode, double& median, double& stddev) const
-{\r
-  ImageFileArrayConst v = getArray();\r
-  statistics (v, min, max, mean, mode, median, stddev);\r
+{
+  ImageFileArrayConst v = getArray();
+  statistics (v, min, max, mean, mode, median, stddev);
 }
 
 
-void\r
-ImageFile::statistics (ImageFileArrayConst v, double& min, double& max, double& mean, double& mode, double& median, double& stddev) const\r
-{\r
-  int nx = m_nx;\r
-  int ny = m_ny;\r
-  \r
-  if (v == NULL || nx == 0 || ny == 0)\r
-    return;\r
-  \r
-  std::vector<double> vecImage;\r
-  int iVec = 0;\r
-  vecImage.resize (nx * ny);\r
-  for (int ix = 0; ix < nx; ix++) {\r
-    for (int iy = 0; iy < ny; iy++)\r
-      vecImage[iVec++] = v[ix][iy];\r
-  }\r
-  \r
-  vectorNumericStatistics (vecImage, nx * ny, min, max, mean, mode, median, stddev);\r
-}\r
-\r
+void
+ImageFile::statistics (ImageFileArrayConst v, double& min, double& max, double& mean, double& mode, double& median, double& stddev) const
+{
+  int nx = m_nx;
+  int ny = m_ny;
+  
+  if (v == NULL || nx == 0 || ny == 0)
+    return;
+  
+  std::vector<double> vecImage;
+  int iVec = 0;
+  vecImage.resize (nx * ny);
+  for (int ix = 0; ix < nx; ix++) {
+    for (int iy = 0; iy < ny; iy++)
+      vecImage[iVec++] = v[ix][iy];
+  }
+  
+  vectorNumericStatistics (vecImage, nx * ny, min, max, mean, mode, median, stddev);
+}
+
 void
 ImageFile::getMinMax (double& min, double& max) const
 {
@@ -323,796 +323,796 @@ ImageFile::getMinMax (double& min, double& max) const
     }
   }
 }
-\r
-bool\r
-ImageFile::convertRealToComplex ()\r
-{\r
-  if (dataType() != Array2dFile::DATA_TYPE_REAL)\r
-    return false;\r
-  \r
-  if (! reallocRealToComplex())\r
-    return false;\r
-  \r
-  ImageFileArray vImag = getImaginaryArray();\r
-  for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumn vCol = vImag[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++)\r
-      *vCol++ = 0;\r
-  }\r
-  \r
-  return true;\r
-}\r
-\r
-bool\r
-ImageFile::convertComplexToReal ()\r
-{\r
-  if (dataType() != Array2dFile::DATA_TYPE_COMPLEX)\r
-    return false;\r
-  \r
-  ImageFileArray vReal = getArray();\r
-  ImageFileArray vImag = getImaginaryArray();\r
-  for (unsigned int ix = 0; ix < m_nx; ix++) {\r
-    ImageFileColumn vRealCol = vReal[ix];\r
-    ImageFileColumn vImagCol = vImag[ix];\r
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      CTSimComplex c (*vRealCol, *vImagCol);\r
-      *vRealCol++ = std::abs (c);\r
-      vImagCol++;\r
-    }\r
-  }\r
-  \r
-  return reallocComplexToReal();\r
-}\r
-\r
-bool\r
-ImageFile::subtractImages (const ImageFile& rRHS, ImageFile& result) const\r
-{\r
-  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");\r
-    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
-    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
-}\r
 
-bool\r
-ImageFile::addImages (const ImageFile& rRHS, ImageFile& result) const\r
-{\r
-  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");\r
-    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
-    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
-}\r
-\r
-bool\r
-ImageFile::multiplyImages (const ImageFile& rRHS, ImageFile& result) const\r
-{\r
-  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");\r
-    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
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (result.isComplex()) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        std::complex<double> cLHS (vLHS[ix][iy], dImag);\r
-        dImag = 0;\r
-        if (rRHS.isComplex())\r
-          dImag = vRHSImag[ix][iy];\r
-        std::complex<double> cRHS (vRHS[ix][iy], dImag);\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
-bool\r
-ImageFile::divideImages (const ImageFile& rRHS, ImageFile& result) const\r
-{\r
-  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");\r
-    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
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (result.isComplex()) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        std::complex<double> cLHS (vLHS[ix][iy], dImag);\r
-        dImag = 0;\r
-        if (rRHS.isComplex())\r
-          dImag = vRHSImag[ix][iy];\r
-        std::complex<double> cRHS (vRHS[ix][iy], dImag);\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
-  return true;\r
-}\r
-\r
-\r
-bool\r
-ImageFile::invertPixelValues (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    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
-  ImageFileArrayConst vLHS = getArray();\r
-  ImageFileArray vResult = result.getArray();\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++;\r
-  }\r
-  \r
-  return true;\r
-}\r
-\r
-bool\r
-ImageFile::sqrt (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    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
-          for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-            if (result.isComplex()) {\r
-              double dImag = 0;\r
-              if (isComplex())\r
-                dImag = vLHSImag[ix][iy];\r
-              std::complex<double> cLHS (vLHS[ix][iy], dImag);\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
-bool\r
-ImageFile::log (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    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
-  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
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (result.isComplex()) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        std::complex<double> cLHS (vLHS[ix][iy], dImag);\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
-bool\r
-ImageFile::exp (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    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
-  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
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (result.isComplex()) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        std::complex<double> cLHS (vLHS[ix][iy], dImag);\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
-bool\r
-ImageFile::scaleImage (ImageFile& result) const\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
-  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
-  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
-      double dXPos = ix / dXScale;\r
-      double dYPos = iy / dYScale;\r
-      unsigned int scaleNX = static_cast<unsigned int> (dXPos);\r
-      unsigned int scaleNY = static_cast<unsigned int> (dYPos);\r
-      double dXFrac = dXPos - scaleNX;\r
-      double dYFrac = dYPos - scaleNY;\r
-      if (scaleNX >= nx - 1 || scaleNY >= ny - 1) {\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
-      } else {\r
-        vResult[ix][iy] = vReal[scaleNX][scaleNY] + \r
-          dXFrac * (vReal[scaleNX+1][scaleNY] - vReal[scaleNX][scaleNY]) + \r
-          dYFrac * (vReal[scaleNX][scaleNY+1] - vReal[scaleNX][scaleNY]);\r
-        if (result.isComplex()) {\r
-          if (isComplex())\r
-            vResultImag[ix][iy] = vImag[scaleNX][scaleNY] + \r
-            dXFrac * (vImag[scaleNX+1][scaleNY] - vImag[scaleNX][scaleNY]) + \r
-            dYFrac * (vImag[scaleNX][scaleNY+1] - vImag[scaleNX][scaleNY]);\r
-          else\r
-            vResultImag[ix][iy] = 0;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  \r
-  return true;\r
-}\r
-\r
-#ifdef HAVE_FFTW\r
-bool\r
-ImageFile::fft (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.convertRealToComplex ())\r
-      return false;\r
-  }\r
-  \r
-  fftw_complex* in = new fftw_complex [m_nx * m_ny];\r
-  \r
-  ImageFileArrayConst vReal = getArray();\r
-  ImageFileArrayConst vImag = getImaginaryArray();\r
-  \r
-  unsigned int ix, iy;\r
-  unsigned int iArray = 0;\r
-  for (ix = 0; ix < m_nx; ix++)\r
-    for (iy = 0; iy < m_ny; iy++) {\r
-      in[iArray].re = vReal[ix][iy];\r
-      if (isComplex())\r
-        in[iArray].im = vImag[ix][iy];\r
-      else\r
-        in[iArray].im = 0;\r
-      iArray++;\r
-    }\r
-    \r
-    fftwnd_plan plan = fftw2d_create_plan (m_nx, m_ny, FFTW_FORWARD, FFTW_IN_PLACE);\r
-    \r
-    fftwnd_one (plan, in, NULL);\r
-    \r
-    ImageFileArray vRealResult = result.getArray();\r
-    ImageFileArray vImagResult = result.getImaginaryArray();\r
-    iArray = 0;\r
-    unsigned int iScale = m_nx * m_ny;\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      for (iy = 0; iy < m_ny; iy++) {\r
-        vRealResult[ix][iy] = in[iArray].re / iScale;\r
-        vImagResult[ix][iy] = in[iArray].im / iScale;\r
-        iArray++;\r
-      }\r
-      \r
-      fftwnd_destroy_plan (plan);\r
-      delete in;\r
-      \r
-      \r
-      Fourier::shuffleFourierToNaturalOrder (result);\r
-      \r
-      return true;\r
-}\r
-\r
-\r
-bool\r
-ImageFile::ifft (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
-    if (! result.convertRealToComplex ())\r
-      return false;\r
-  }\r
-  \r
-  ImageFileArrayConst vReal = getArray();\r
-  ImageFileArrayConst vImag = getImaginaryArray();\r
-  ImageFileArray vRealResult = result.getArray();\r
-  ImageFileArray vImagResult = result.getImaginaryArray();\r
-  unsigned int ix, iy;\r
-  for (ix = 0; ix < m_nx; ix++)\r
-    for (iy = 0; iy < m_ny; iy++) {\r
-      vRealResult[ix][iy] = vReal[ix][iy];\r
-      if (isComplex()) \r
-        vImagResult[ix][iy] = vImag[ix][iy];\r
-      else\r
-        vImagResult[ix][iy] = 0;\r
-    }\r
-    \r
-    Fourier::shuffleNaturalToFourierOrder (result);\r
-    \r
-    fftw_complex* in = new fftw_complex [m_nx * m_ny];\r
-    \r
-    unsigned int iArray = 0;\r
-    for (ix = 0; ix < m_nx; ix++)\r
-      for (iy = 0; iy < m_ny; iy++) {\r
-        in[iArray].re = vRealResult[ix][iy];\r
-        in[iArray].im = vImagResult[ix][iy];\r
-        iArray++;\r
-      }\r
-      \r
-      fftwnd_plan plan = fftw2d_create_plan (m_nx, m_ny, FFTW_BACKWARD, FFTW_IN_PLACE);\r
-      \r
-      fftwnd_one (plan, in, NULL);\r
-      \r
-      iArray = 0;\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        for (iy = 0; iy < m_ny; iy++) {\r
-          vRealResult[ix][iy] = in[iArray].re;\r
-          vImagResult[ix][iy] = in[iArray].im;\r
-          iArray++;\r
-        }\r
-        \r
-        fftwnd_destroy_plan (plan);\r
-        \r
-        delete in;\r
-        \r
-        return true;\r
-}\r
-#endif // HAVE_FFTW\r
-\r
-\r
-\r
-bool\r
-ImageFile::fourier (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  if (! result.isComplex())\r
-    if (! result.convertRealToComplex ())\r
-      return false;\r
-    \r
-    ImageFileArrayConst vLHS = getArray();\r
-    ImageFileArrayConst vLHSImag = getImaginaryArray();\r
-    ImageFileArray vRealResult = result.getArray();\r
-    ImageFileArray vImagResult = result.getImaginaryArray();\r
-    \r
-    unsigned int ix, iy;\r
-    \r
-    // alloc 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
-    // fourier each x column\r
-    CTSimComplex* pY = new CTSimComplex [m_ny];\r
-    for (ix = 0; ix < m_nx; ix++) {\r
-      for (iy = 0; iy < m_ny; iy++) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        pY[iy] = std::complex<double>(vLHS[ix][iy], dImag);\r
-      } \r
-      ProcessSignal::finiteFourierTransform (pY, complexOut[ix], m_ny,  ProcessSignal::FORWARD);\r
-    }\r
-    delete [] pY;\r
-    \r
-    // fourier each y row\r
-    CTSimComplex* pX = new CTSimComplex [m_nx];\r
-    CTSimComplex* complexOutRow = new CTSimComplex [m_nx];\r
-    for (iy = 0; iy < m_ny; iy++) {\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        pX[ix] = complexOut[ix][iy];\r
-      ProcessSignal::finiteFourierTransform (pX, complexOutRow, m_nx, ProcessSignal::FORWARD);\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        complexOut[ix][iy] = complexOutRow[ix];\r
-    }\r
-    delete [] pX;\r
-    delete [] complexOutRow;\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
-      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
-}\r
-\r
-bool\r
-ImageFile::inverseFourier (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {\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
-  // 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 result\r
-  for (ix = 0; ix < m_nx; ix++)\r
-    for (iy = 0; iy < m_ny; iy++) {\r
-      vRealResult[ix][iy] = vLHSReal[ix][iy];\r
-      if (isComplex())\r
-        vImagResult[ix][iy] = vLHSImag[ix][iy];\r
-      else\r
-        vImagResult[ix][iy] = 0;\r
-    }\r
-    \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] = std::complex<double> (vRealResult[ix][iy], vImagResult[ix][iy]);\r
-      }\r
-      ProcessSignal::finiteFourierTransform (pCol, complexOut[ix], m_ny,  ProcessSignal::BACKWARD);\r
-    }\r
-    delete [] pCol;\r
-    \r
-    // ifourier each y row\r
-    CTSimComplex* complexInRow = new CTSimComplex [m_nx];\r
-    CTSimComplex* complexOutRow = new CTSimComplex [m_nx];\r
-    for (iy = 0; iy < m_ny; iy++) {\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        complexInRow[ix] = complexOut[ix][iy];\r
-      ProcessSignal::finiteFourierTransform (complexInRow, complexOutRow, m_nx, ProcessSignal::BACKWARD);\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        complexOut[ix][iy] = complexOutRow[ix];\r
-    }\r
-    delete [] complexInRow;\r
-    delete [] complexOutRow;\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
-      // delete complexOut matrix\r
-      for (ix = 0; ix < m_nx; ix++)\r
-        delete [] complexOut[ix];\r
-      delete [] complexOut;\r
-      \r
-      return true;\r
-}\r
-\r
-\r
-bool\r
-ImageFile::magnitude (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  ImageFileArray vReal = getArray();\r
-  ImageFileArray vImag = getImaginaryArray();\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
-        vRealResult[ix][iy] = ::sqrt (vReal[ix][iy] * vReal[ix][iy] + vImag[ix][iy] * vImag[ix][iy]);\r
-      else\r
-        vRealResult[ix][iy] = vReal[ix][iy];\r
-    }\r
-    \r
-    if (result.isComplex())\r
-      result.convertComplexToReal();\r
-    \r
-    return true;\r
-}\r
-\r
-bool\r
-ImageFile::phase (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");\r
-    return false;\r
-  }\r
-  \r
-  ImageFileArray vReal = getArray();\r
-  ImageFileArray vImag = getImaginaryArray();\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
-        vRealResult[ix][iy] = ::atan2 (vImag[ix][iy], vReal[ix][iy]);\r
-      else\r
-        vRealResult[ix][iy] = 0;\r
-    }\r
-    \r
-    if (result.isComplex())\r
-      result.convertComplexToReal();\r
-    \r
-    return true;\r
-}\r
-\r
-bool\r
-ImageFile::square (ImageFile& result) const\r
-{\r
-  if (m_nx != result.nx() || m_ny != result.ny()) {\r
-    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
-  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
-    for (unsigned int iy = 0; iy < m_ny; iy++) {\r
-      if (result.isComplex()) {\r
-        double dImag = 0;\r
-        if (isComplex())\r
-          dImag = vLHSImag[ix][iy];\r
-        std::complex<double> cLHS (vLHS[ix][iy], dImag);\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
-  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::convertRealToComplex ()
+{
+  if (dataType() != Array2dFile::DATA_TYPE_REAL)
+    return false;
+  
+  if (! reallocRealToComplex())
+    return false;
+  
+  ImageFileArray vImag = getImaginaryArray();
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    ImageFileColumn vCol = vImag[ix];
+    for (unsigned int iy = 0; iy < m_ny; iy++)
+      *vCol++ = 0;
+  }
+  
+  return true;
+}
+
+bool
+ImageFile::convertComplexToReal ()
+{
+  if (dataType() != Array2dFile::DATA_TYPE_COMPLEX)
+    return false;
+  
+  ImageFileArray vReal = getArray();
+  ImageFileArray vImag = getImaginaryArray();
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    ImageFileColumn vRealCol = vReal[ix];
+    ImageFileColumn vImagCol = vImag[ix];
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      CTSimComplex c (*vRealCol, *vImagCol);
+      *vRealCol++ = std::abs (c);
+      vImagCol++;
+    }
+  }
+  
+  return reallocComplexToReal();
+}
+
+bool
+ImageFile::subtractImages (const ImageFile& rRHS, ImageFile& result) const
+{
+  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");
+    return false;
+  }
+  
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArrayConst vRHS = rRHS.getArray();
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      vResult[ix][iy] = vLHS[ix][iy] - vRHS[ix][iy];
+      if (result.isComplex()) {
+        vResultImag[ix][iy] = 0;
+        if (isComplex())
+          vResultImag[ix][iy] += vLHSImag[ix][iy];
+        if (rRHS.isComplex())
+          vResultImag[ix][iy] -= vRHSImag[ix][iy];
+      }
+    }
+  }
+  
+  return true;
+}
+
+bool
+ImageFile::addImages (const ImageFile& rRHS, ImageFile& result) const
+{
+  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");
+    return false;
+  }
+  
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArrayConst vRHS = rRHS.getArray();
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      vResult[ix][iy] = vLHS[ix][iy] + vRHS[ix][iy];
+      if (result.isComplex()) {
+        vResultImag[ix][iy] = 0;
+        if (isComplex())
+          vResultImag[ix][iy] += vLHSImag[ix][iy];
+        if (rRHS.isComplex())
+          vResultImag[ix][iy] += vRHSImag[ix][iy];
+      }
+    }
+  }
+  
+  return true;
+}
+
+bool
+ImageFile::multiplyImages (const ImageFile& rRHS, ImageFile& result) const
+{
+  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");
+    return false;
+  }
+  
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArrayConst vRHS = rRHS.getArray();
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (result.isComplex()) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        std::complex<double> cLHS (vLHS[ix][iy], dImag);
+        dImag = 0;
+        if (rRHS.isComplex())
+          dImag = vRHSImag[ix][iy];
+        std::complex<double> cRHS (vRHS[ix][iy], dImag);
+        std::complex<double> cResult = cLHS * cRHS;
+        vResult[ix][iy] = cResult.real();
+        vResultImag[ix][iy] = cResult.imag();
+      } else
+        vResult[ix][iy] = vLHS[ix][iy] * vRHS[ix][iy];
+    }
+  }
+  
+  
+  return true;
+}
+
+bool
+ImageFile::divideImages (const ImageFile& rRHS, ImageFile& result) const
+{
+  if (m_nx != rRHS.nx() || m_ny != rRHS.ny() || m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::subtractImage]");
+    return false;
+  }
+  
+  if (isComplex() || rRHS.isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArrayConst vRHS = rRHS.getArray();
+  ImageFileArrayConst vRHSImag = rRHS.getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (result.isComplex()) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        std::complex<double> cLHS (vLHS[ix][iy], dImag);
+        dImag = 0;
+        if (rRHS.isComplex())
+          dImag = vRHSImag[ix][iy];
+        std::complex<double> cRHS (vRHS[ix][iy], dImag);
+        std::complex<double> cResult = cLHS / cRHS;
+        vResult[ix][iy] = cResult.real();
+        vResultImag[ix][iy] = cResult.imag();
+      } else {
+        if (vRHS != 0)
+          vResult[ix][iy] = vLHS[ix][iy] / vRHS[ix][iy];
+        else
+          vResult[ix][iy] = 0;
+      }
+    }
+  }
+  
+  return true;
+}
+
+
+bool
+ImageFile::invertPixelValues (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArray vResult = result.getArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    ImageFileColumnConst in = vLHS[ix];
+    ImageFileColumn out = vResult[ix];
+    for (unsigned int iy = 0; iy < m_ny; iy++)
+      *out++ = - *in++;
+  }
+  
+  return true;
+}
+
+bool
+ImageFile::sqrt (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  bool bComplexOutput = result.isComplex();
+  ImageFileArrayConst vLHS = getArray();
+  if (! bComplexOutput)   // check if should convert to complex output
+    for (unsigned int ix = 0; ix < m_nx; ix++)
+      for (unsigned int iy = 0; iy < m_ny; iy++)
+        if (! bComplexOutput && vLHS[ix][iy] < 0) {
+          result.convertRealToComplex();
+          bComplexOutput = true;
+          break;
+        }
+        
+        ImageFileArrayConst vLHSImag = getImaginaryArray();
+        ImageFileArray vResult = result.getArray();
+        ImageFileArray vResultImag = result.getImaginaryArray();
+        
+        for (unsigned int ix = 0; ix < m_nx; ix++) {
+          for (unsigned int iy = 0; iy < m_ny; iy++) {
+            if (result.isComplex()) {
+              double dImag = 0;
+              if (isComplex())
+                dImag = vLHSImag[ix][iy];
+              std::complex<double> cLHS (vLHS[ix][iy], dImag);
+              std::complex<double> cResult = std::sqrt(cLHS);
+              vResult[ix][iy] = cResult.real();
+              vResultImag[ix][iy] = cResult.imag();
+            } else
+              vResult[ix][iy] = ::sqrt (vLHS[ix][iy]);
+          }
+        }
+        
+        
+        return true;
+}
+
+bool
+ImageFile::log (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (result.isComplex()) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        std::complex<double> cLHS (vLHS[ix][iy], dImag);
+        std::complex<double> cResult = std::log (cLHS);
+        vResult[ix][iy] = cResult.real();
+        vResultImag[ix][iy] = cResult.imag();
+      } else
+        vResult[ix][iy] = ::log (vLHS[ix][iy]);
+    }
+  }
+  
+  
+  return true;
+}
+
+bool
+ImageFile::exp (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (result.isComplex()) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        std::complex<double> cLHS (vLHS[ix][iy], dImag);
+        std::complex<double> cResult = std::exp (cLHS);
+        vResult[ix][iy] = cResult.real();
+        vResultImag[ix][iy] = cResult.imag();
+      } else
+        vResult[ix][iy] = ::exp (vLHS[ix][iy]);
+    }
+  }
+  
+  
+  return true;
+}
+
+bool
+ImageFile::scaleImage (ImageFile& result) const
+{
+  unsigned int nx = m_nx;
+  unsigned int ny = m_ny;
+  unsigned int newNX = result.nx();
+  unsigned int newNY = result.ny();
+  
+  double dXScale = static_cast<double>(newNX) / static_cast<double>(nx);
+  double dYScale = static_cast<double>(newNY) / static_cast<double>(ny);
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vReal = getArray();
+  ImageFileArrayConst vImag = getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < newNX; ix++) {
+    for (unsigned int iy = 0; iy < newNY; iy++) {
+      double dXPos = ix / dXScale;
+      double dYPos = iy / dYScale;
+      unsigned int scaleNX = static_cast<unsigned int> (dXPos);
+      unsigned int scaleNY = static_cast<unsigned int> (dYPos);
+      double dXFrac = dXPos - scaleNX;
+      double dYFrac = dYPos - scaleNY;
+      if (scaleNX >= nx - 1 || scaleNY >= ny - 1) {
+        vResult[ix][iy] = vReal[scaleNX][scaleNY];
+        if (result.isComplex()) {
+          if (isComplex())
+            vResultImag[ix][iy] = vImag[scaleNX][scaleNY];
+          else
+            vResultImag[ix][iy] = 0;
+        }
+      } else {
+        vResult[ix][iy] = vReal[scaleNX][scaleNY] + 
+          dXFrac * (vReal[scaleNX+1][scaleNY] - vReal[scaleNX][scaleNY]) + 
+          dYFrac * (vReal[scaleNX][scaleNY+1] - vReal[scaleNX][scaleNY]);
+        if (result.isComplex()) {
+          if (isComplex())
+            vResultImag[ix][iy] = vImag[scaleNX][scaleNY] + 
+            dXFrac * (vImag[scaleNX+1][scaleNY] - vImag[scaleNX][scaleNY]) + 
+            dYFrac * (vImag[scaleNX][scaleNY+1] - vImag[scaleNX][scaleNY]);
+          else
+            vResultImag[ix][iy] = 0;
+        }
+      }
+    }
+  }
+  
+  return true;
+}
+
+#ifdef HAVE_FFTW
+bool
+ImageFile::fft (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {
+    if (! result.convertRealToComplex ())
+      return false;
+  }
+  
+  fftw_complex* in = new fftw_complex [m_nx * m_ny];
+  
+  ImageFileArrayConst vReal = getArray();
+  ImageFileArrayConst vImag = getImaginaryArray();
+  
+  unsigned int ix, iy;
+  unsigned int iArray = 0;
+  for (ix = 0; ix < m_nx; ix++)
+    for (iy = 0; iy < m_ny; iy++) {
+      in[iArray].re = vReal[ix][iy];
+      if (isComplex())
+        in[iArray].im = vImag[ix][iy];
+      else
+        in[iArray].im = 0;
+      iArray++;
+    }
+    
+    fftwnd_plan plan = fftw2d_create_plan (m_nx, m_ny, FFTW_FORWARD, FFTW_IN_PLACE);
+    
+    fftwnd_one (plan, in, NULL);
+    
+    ImageFileArray vRealResult = result.getArray();
+    ImageFileArray vImagResult = result.getImaginaryArray();
+    iArray = 0;
+    unsigned int iScale = m_nx * m_ny;
+    for (ix = 0; ix < m_nx; ix++)
+      for (iy = 0; iy < m_ny; iy++) {
+        vRealResult[ix][iy] = in[iArray].re / iScale;
+        vImagResult[ix][iy] = in[iArray].im / iScale;
+        iArray++;
+      }
+      
+      fftwnd_destroy_plan (plan);
+      delete in;
+      
+      
+      Fourier::shuffleFourierToNaturalOrder (result);
+      
+      return true;
+}
+
+
+bool
+ImageFile::ifft (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {
+    if (! result.convertRealToComplex ())
+      return false;
+  }
+  
+  ImageFileArrayConst vReal = getArray();
+  ImageFileArrayConst vImag = getImaginaryArray();
+  ImageFileArray vRealResult = result.getArray();
+  ImageFileArray vImagResult = result.getImaginaryArray();
+  unsigned int ix, iy;
+  for (ix = 0; ix < m_nx; ix++)
+    for (iy = 0; iy < m_ny; iy++) {
+      vRealResult[ix][iy] = vReal[ix][iy];
+      if (isComplex()) 
+        vImagResult[ix][iy] = vImag[ix][iy];
+      else
+        vImagResult[ix][iy] = 0;
+    }
+    
+    Fourier::shuffleNaturalToFourierOrder (result);
+    
+    fftw_complex* in = new fftw_complex [m_nx * m_ny];
+    
+    unsigned int iArray = 0;
+    for (ix = 0; ix < m_nx; ix++)
+      for (iy = 0; iy < m_ny; iy++) {
+        in[iArray].re = vRealResult[ix][iy];
+        in[iArray].im = vImagResult[ix][iy];
+        iArray++;
+      }
+      
+      fftwnd_plan plan = fftw2d_create_plan (m_nx, m_ny, FFTW_BACKWARD, FFTW_IN_PLACE);
+      
+      fftwnd_one (plan, in, NULL);
+      
+      iArray = 0;
+      for (ix = 0; ix < m_nx; ix++)
+        for (iy = 0; iy < m_ny; iy++) {
+          vRealResult[ix][iy] = in[iArray].re;
+          vImagResult[ix][iy] = in[iArray].im;
+          iArray++;
+        }
+        
+        fftwnd_destroy_plan (plan);
+        
+        delete in;
+        
+        return true;
+}
+#endif // HAVE_FFTW
+
+
+
+bool
+ImageFile::fourier (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (! result.isComplex())
+    if (! result.convertRealToComplex ())
+      return false;
+    
+    ImageFileArrayConst vLHS = getArray();
+    ImageFileArrayConst vLHSImag = getImaginaryArray();
+    ImageFileArray vRealResult = result.getArray();
+    ImageFileArray vImagResult = result.getImaginaryArray();
+    
+    unsigned int ix, iy;
+    
+    // alloc output matrix
+    CTSimComplex** complexOut = new CTSimComplex* [m_nx];
+    for (ix = 0; ix < m_nx; ix++)
+      complexOut[ix] = new CTSimComplex [m_ny];
+    
+    // fourier each x column
+    CTSimComplex* pY = new CTSimComplex [m_ny];
+    for (ix = 0; ix < m_nx; ix++) {
+      for (iy = 0; iy < m_ny; iy++) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        pY[iy] = std::complex<double>(vLHS[ix][iy], dImag);
+      } 
+      ProcessSignal::finiteFourierTransform (pY, complexOut[ix], m_ny,  ProcessSignal::FORWARD);
+    }
+    delete [] pY;
+    
+    // fourier each y row
+    CTSimComplex* pX = new CTSimComplex [m_nx];
+    CTSimComplex* complexOutRow = new CTSimComplex [m_nx];
+    for (iy = 0; iy < m_ny; iy++) {
+      for (ix = 0; ix < m_nx; ix++)
+        pX[ix] = complexOut[ix][iy];
+      ProcessSignal::finiteFourierTransform (pX, complexOutRow, m_nx, ProcessSignal::FORWARD);
+      for (ix = 0; ix < m_nx; ix++)
+        complexOut[ix][iy] = complexOutRow[ix];
+    }
+    delete [] pX;
+    delete [] complexOutRow;
+    
+    for (ix = 0; ix < m_nx; ix++)
+      for (iy = 0; iy < m_ny; iy++) {
+        vRealResult[ix][iy] = complexOut[ix][iy].real();
+        vImagResult[ix][iy] = complexOut[ix][iy].imag();
+      }
+      
+      Fourier::shuffleFourierToNaturalOrder (result);
+      
+      // delete complexOut matrix
+      for (ix = 0; ix < m_nx; ix++)
+        delete [] complexOut[ix];
+      delete [] complexOut;
+      
+      return true;
+}
+
+bool
+ImageFile::inverseFourier (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (result.dataType() == Array2dFile::DATA_TYPE_REAL) {
+    if (! result.convertRealToComplex ())
+      return false;
+  }
+  
+  ImageFileArrayConst vLHSReal = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArray vRealResult = result.getArray();
+  ImageFileArray vImagResult = result.getImaginaryArray();
+  
+  unsigned int ix, iy;
+  // alloc 2d complex output matrix
+  CTSimComplex** complexOut = new CTSimComplex* [m_nx];
+  for (ix = 0; ix < m_nx; ix++)
+    complexOut[ix] = new CTSimComplex [m_ny];
+  
+  // put input image into result
+  for (ix = 0; ix < m_nx; ix++)
+    for (iy = 0; iy < m_ny; iy++) {
+      vRealResult[ix][iy] = vLHSReal[ix][iy];
+      if (isComplex())
+        vImagResult[ix][iy] = vLHSImag[ix][iy];
+      else
+        vImagResult[ix][iy] = 0;
+    }
+    
+    Fourier::shuffleNaturalToFourierOrder (result);
+    
+    // ifourier each x column
+    CTSimComplex* pCol = new CTSimComplex [m_ny];
+    for (ix = 0; ix < m_nx; ix++) {
+      for (iy = 0; iy < m_ny; iy++) {
+        pCol[iy] = std::complex<double> (vRealResult[ix][iy], vImagResult[ix][iy]);
+      }
+      ProcessSignal::finiteFourierTransform (pCol, complexOut[ix], m_ny,  ProcessSignal::BACKWARD);
+    }
+    delete [] pCol;
+    
+    // ifourier each y row
+    CTSimComplex* complexInRow = new CTSimComplex [m_nx];
+    CTSimComplex* complexOutRow = new CTSimComplex [m_nx];
+    for (iy = 0; iy < m_ny; iy++) {
+      for (ix = 0; ix < m_nx; ix++)
+        complexInRow[ix] = complexOut[ix][iy];
+      ProcessSignal::finiteFourierTransform (complexInRow, complexOutRow, m_nx, ProcessSignal::BACKWARD);
+      for (ix = 0; ix < m_nx; ix++)
+        complexOut[ix][iy] = complexOutRow[ix];
+    }
+    delete [] complexInRow;
+    delete [] complexOutRow;
+    
+    for (ix = 0; ix < m_nx; ix++)
+      for (iy = 0; iy < m_ny; iy++) {
+        vRealResult[ix][iy] = complexOut[ix][iy].real();
+        vImagResult[ix][iy] = complexOut[ix][iy].imag();
+      }
+      
+      // delete complexOut matrix
+      for (ix = 0; ix < m_nx; ix++)
+        delete [] complexOut[ix];
+      delete [] complexOut;
+      
+      return true;
+}
+
+
+bool
+ImageFile::magnitude (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  ImageFileArray vReal = getArray();
+  ImageFileArray vImag = getImaginaryArray();
+  ImageFileArray vRealResult = result.getArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++)
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (isComplex()) 
+        vRealResult[ix][iy] = ::sqrt (vReal[ix][iy] * vReal[ix][iy] + vImag[ix][iy] * vImag[ix][iy]);
+      else
+        vRealResult[ix][iy] = vReal[ix][iy];
+    }
+    
+    if (result.isComplex())
+      result.convertComplexToReal();
+    
+    return true;
+}
+
+bool
+ImageFile::phase (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  ImageFileArray vReal = getArray();
+  ImageFileArray vImag = getImaginaryArray();
+  ImageFileArray vRealResult = result.getArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++)
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (isComplex())
+        vRealResult[ix][iy] = ::atan2 (vImag[ix][iy], vReal[ix][iy]);
+      else
+        vRealResult[ix][iy] = 0;
+    }
+    
+    if (result.isComplex())
+      result.convertComplexToReal();
+    
+    return true;
+}
+
+bool
+ImageFile::square (ImageFile& result) const
+{
+  if (m_nx != result.nx() || m_ny != result.ny()) {
+    sys_error (ERR_WARNING, "Difference sizes of images [ImageFile::invertPixelValues]");
+    return false;
+  }
+  
+  if (isComplex() && ! result.isComplex())
+    result.convertRealToComplex();
+  
+  ImageFileArrayConst vLHS = getArray();
+  ImageFileArrayConst vLHSImag = getImaginaryArray();
+  ImageFileArray vResult = result.getArray();
+  ImageFileArray vResultImag = result.getImaginaryArray();
+  
+  for (unsigned int ix = 0; ix < m_nx; ix++) {
+    for (unsigned int iy = 0; iy < m_ny; iy++) {
+      if (result.isComplex()) {
+        double dImag = 0;
+        if (isComplex())
+          dImag = vLHSImag[ix][iy];
+        std::complex<double> cLHS (vLHS[ix][iy], dImag);
+        std::complex<double> cResult = cLHS * cLHS;
+        vResult[ix][iy] = cResult.real();
+        vResultImag[ix][iy] = cResult.imag();
+      } else
+        vResult[ix][iy] = vLHS[ix][iy] * vLHS[ix][iy];
+    }
+  }
+  
+  
+  return true;
+}
+
+int
+ImageFile::convertFormatNameToID (const char* const formatName)
+{
+  int formatID = FORMAT_INVALID;
+  
+  for (int i = 0; i < s_iFormatCount; i++)
+    if (strcasecmp (formatName, s_aszFormatName[i]) == 0) {
+      formatID = i;
+      break;
+    }
+    
+    return (formatID);
+}
+
+const char*
+ImageFile::convertFormatIDToName (int formatID)
+{
+  static const char *formatName = "";
+  
+  if (formatID >= 0 && formatID < s_iFormatCount)
+    return (s_aszFormatName[formatID]);
+  
+  return (formatName);
+}
+
+const char*
+ImageFile::convertFormatIDToTitle (const int formatID)
+{
+  static const char *formatTitle = "";
+  
+  if (formatID >= 0 && formatID < s_iFormatCount)
+    return (s_aszFormatTitle[formatID]);
+  
+  return (formatTitle);
+}
+
+bool
+ImageFile::exportImage (const char* const pszFormat, const char* const pszFilename, int nxcell, int nycell, double densmin, double densmax)
+{
+  int iFormatID = convertFormatNameToID (pszFormat);
+  if (iFormatID == FORMAT_INVALID) {
+    sys_error (ERR_SEVERE, "Invalid format %s [ImageFile::exportImage]", pszFormat);
+    return false;
+  }
+  
+  if (iFormatID == FORMAT_PGM)
+    return writeImagePGM (pszFilename, nxcell, nycell, densmin, densmax);
+  else if (iFormatID == FORMAT_PGMASCII)
+    return writeImagePGMASCII (pszFilename, nxcell, nycell, densmin, densmax);
+  else if (iFormatID == FORMAT_PNG)
+    return writeImagePNG (pszFilename, 8, nxcell, nycell, densmin, densmax);
+  else if (iFormatID == FORMAT_PNG16)
+    return writeImagePNG (pszFilename, 16, nxcell, nycell, densmin, densmax);
+  
+  sys_error (ERR_SEVERE, "Invalid format %s [ImageFile::exportImage]", pszFormat);
+  return false;
+}
+
 bool
 ImageFile::writeImagePGM (const char* const outfile, int nxcell, int nycell, double densmin, double densmax)
 {
@@ -1144,10 +1144,10 @@ ImageFile::writeImagePGM (const char* const outfile, int nxcell, int nycell, dou
         fputc( rowp[ic], fp );
     }
   }
-  \r
+  
   delete rowp;
-  fclose(fp);\r
-  \r
+  fclose(fp);
+  
   return true;
 }
 
@@ -1183,10 +1183,10 @@ ImageFile::writeImagePGMASCII (const char* const outfile, int nxcell, int nycell
       fprintf(fp, "\n");
     }
   }
-  \r
+  
   delete rowp;
-  fclose(fp);\r
-  \r
+  fclose(fp);
+  
   return true;
 }
 
@@ -1202,7 +1202,7 @@ ImageFile::writeImagePNG (const char* const outfile, int bitdepth, int nxcell, i
   
   unsigned char* rowp = new unsigned char [nx * nxcell * (bitdepth / 8)];
   
-  FILE *fp = fopen (outfile, "wb");\r
+  FILE *fp = fopen (outfile, "wb");
   if (! fp)
     return false;
   
@@ -1253,10 +1253,10 @@ ImageFile::writeImagePNG (const char* const outfile, int bitdepth, int nxcell, i
   
   png_write_end (png_ptr, info_ptr);
   png_destroy_write_struct (&png_ptr, &info_ptr);
-  delete rowp;\r
+  delete rowp;
+  
+  fclose(fp);
   
-  fclose(fp);\r
-  \r
   return true;
 }
 #endif
@@ -1295,17 +1295,17 @@ ImageFile::writeImageGIF (const char* const outfile, int nxcell, int nycell, dou
     }
   }
   
-  FILE *out;\r
+  FILE *out;
   if ((out = fopen (outfile,"w")) == NULL) {
     sys_error(ERR_FATAL, "Error opening output file %s for writing", outfile);
     return false;
   }
   gdImageGif(gif,out);
   fclose(out);
-  gdImageDestroy(gif);\r
-  \r
-  delete rowp;\r
-  \r
+  gdImageDestroy(gif);
+  
+  delete rowp;
+  
   return true;
 }
 #endif