+}
+\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 (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumn vCol = vImag[ix];\r
+ for (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 (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumn vRealCol = vReal[ix];\r
+ ImageFileColumn vImagCol = vImag[ix];\r
+ for (int iy = 0; iy < m_ny; iy++) {\r
+ std::complex<double> 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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArrayConst vRHS = rRHS.getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in1 = vLHS[ix];\r
+ ImageFileColumnConst in2 = vRHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ *out++ = *in1++ - *in2++;\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArrayConst vRHS = rRHS.getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in1 = vLHS[ix];\r
+ ImageFileColumnConst in2 = vRHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ *out++ = *in1++ + *in2++;\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArrayConst vRHS = rRHS.getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in1 = vLHS[ix];\r
+ ImageFileColumnConst in2 = vRHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ *out++ = *in1++ * *in2++;\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArrayConst vRHS = rRHS.getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in1 = vLHS[ix];\r
+ ImageFileColumnConst in2 = vRHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++) {\r
+ if (*in2 != 0.)\r
+ *out++ = *in1++ / *in2++;\r
+ else\r
+ *out++ = 0;\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in = vLHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in = vLHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ if (*in < 0)\r
+ *out++ = -::sqrt(-*in++);\r
+ else\r
+ *out++ = ::sqrt(*in++);\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in = vLHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ if (*in <= 0)\r
+ *out++ = 0;\r
+ else\r
+ *out++ = ::log(*in++);\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in = vLHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ *out++ = ::exp (*in++);\r
+ }\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
+ return true;\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.dataType() == Array2dFile::DATA_TYPE_REAL) {\r
+ if (! result.reallocRealToComplex ())\r
+ return false;\r
+ }\r
+\r
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vRealResult = result.getArray();\r
+ ImageFileArray vImagResult = result.getImaginaryArray();\r
+\r
+ int ix, iy;\r
+ double* pY = new double [m_ny];\r
+ std::complex<double>** complexOut = new std::complex<double>* [m_nx];\r
+ for (ix = 0; ix < m_nx; ix++)\r
+ complexOut[ix] = new std::complex<double> [m_ny];\r
+\r
+ for (ix = 0; ix < m_nx; ix++) {\r
+ for (iy = 0; iy < m_ny; iy++)\r
+ pY[iy] = vLHS[ix][iy];\r
+ ProcessSignal::finiteFourierTransform (pY, complexOut[ix], m_ny, ProcessSignal::FORWARD);\r
+ }\r
+ delete pY;\r
+\r
+ std::complex<double>* pX = new std::complex<double> [m_nx];\r
+ std::complex<double>* complexOutCol = new std::complex<double> [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, complexOutCol, m_nx, ProcessSignal::FORWARD);\r
+ for (ix = 0; ix < m_nx; ix++)\r
+ complexOut[ix][iy] = complexOutCol[ix];\r
+ }\r
+ delete [] pX;\r
+\r
+ for (ix = 0; ix < m_nx; ix++)\r
+ ProcessSignal::shuffleFourierToNaturalOrder (complexOut[ix], m_ny);\r
+\r
+ \r
+ for (iy = 0; iy < m_ny; iy++) {\r
+ for (ix = 0; ix < m_nx; ix++)\r
+ complexOutCol[ix] = complexOut[ix][iy];\r
+ ProcessSignal::shuffleFourierToNaturalOrder (complexOutCol, m_nx);;\r
+ for (ix = 0; ix < m_nx; ix++)\r
+ complexOut[ix][iy] = complexOutCol[ix];\r
+\r
+ }\r
+ delete [] complexOutCol;\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
+\r
+ delete [] complexOut;\r
+\r
+ return true;\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 = NULL;\r
+ if (dataType() == Array2dFile::DATA_TYPE_COMPLEX)\r
+ vImag = getImaginaryArray();\r
+\r
+ ImageFileArray vRealResult = result.getArray();\r
+ if (result.dataType() == Array2dFile::DATA_TYPE_COMPLEX) {\r
+ ImageFileArray vImagResult = result.getImaginaryArray();\r
+ for (int ix = 0; ix < m_nx; ix++)\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ vImagResult[ix][iy] = 0;\r
+ }\r
+\r
+ for (int ix = 0; ix < m_nx; ix++)\r
+ for (int iy = 0; iy < m_ny; iy++) {\r
+ if (dataType() == Array2dFile::DATA_TYPE_COMPLEX) \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
+ 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 = NULL;\r
+ if (dataType() == Array2dFile::DATA_TYPE_COMPLEX)\r
+ vImag = getImaginaryArray();\r
+\r
+ ImageFileArray vRealResult = result.getArray();\r
+ if (result.dataType() == Array2dFile::DATA_TYPE_COMPLEX) {\r
+ ImageFileArray vImagResult = result.getImaginaryArray();\r
+ for (int ix = 0; ix < m_nx; ix++)\r
+ for (int iy = 0; iy < m_ny; iy++)\r
+ vImagResult[ix][iy] = 0;\r
+ }\r
+\r
+ for (int ix = 0; ix < m_nx; ix++)\r
+ for (int iy = 0; iy < m_ny; iy++) {\r
+ if (dataType() == Array2dFile::DATA_TYPE_COMPLEX) \r
+ vRealResult[ix][iy] = ::atan (vImag[ix][iy] / vReal[ix][iy]);\r
+ else\r
+ vRealResult[ix][iy] = vReal[ix][iy];\r
+ }\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
+ ImageFileArrayConst vLHS = getArray();\r
+ ImageFileArray vResult = result.getArray();\r
+\r
+ for (int ix = 0; ix < m_nx; ix++) {\r
+ ImageFileColumnConst in = vLHS[ix];\r
+ ImageFileColumn out = vResult[ix];\r
+ for (int iy = 0; iy < m_ny; iy++) {\r
+ *out++ = *in * *in;\r
+ in++;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+\r
+void
+ImageFile::writeImagePGM (const char *outfile, int nxcell, int nycell, double densmin, double densmax)
+{
+ FILE *fp;
+ int nx = m_nx;
+ int ny = m_ny;
+ ImageFileArray v = getArray();
+
+ unsigned char* rowp = new unsigned char [nx * nxcell];
+
+ if ((fp = fopen (outfile, "wb")) == NULL)
+ return;
+
+ fprintf(fp, "P5\n");
+ fprintf(fp, "%d %d\n", nx, ny);
+ fprintf(fp, "255\n");
+
+ for (int irow = ny - 1; irow >= 0; irow--) {
+ for (int icol = 0; icol < nx; icol++) {
+ int pos = icol * nxcell;
+ double dens = (v[icol][irow] - densmin) / (densmax - densmin);
+ dens = clamp (dens, 0., 1.);
+ for (int p = pos; p < pos + nxcell; p++) {
+ rowp[p] = static_cast<unsigned int> (dens * 255.);
+ }
+ }
+ for (int ir = 0; ir < nycell; ir++) {
+ for (int ic = 0; ic < nx * nxcell; ic++)
+ fputc( rowp[ic], fp );
+ }
+ }
+ \r
+ delete rowp;
+ fclose(fp);
+}