X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=include%2Fimagefile.h;h=3587f1cde01e5cc90b905ea5bafd9874200ca4d5;hp=70c3fe40b4f914b1364fd33c235a81f7cc1b83c1;hb=9b2bb510160bdb56f04847f5b55ab61dd8a47976;hpb=a62ba7c54d39fcf1e469c8df169018fa60ae7c3b diff --git a/include/imagefile.h b/include/imagefile.h index 70c3fe4..3587f1c 100644 --- a/include/imagefile.h +++ b/include/imagefile.h @@ -1,690 +1,203 @@ -#ifndef IDF_H -#define IDF_H - +/***************************************************************************** +** FILE IDENTIFICATION +** +** Name: imagefile.h +** Purpose: imagefile class header +** Programmer: Kevin Rosenberg +** Date Started: June 2000 +** +** This is part of the CTSim program +** Copyright (C) 1983-2000 Kevin Rosenberg +** +** $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 +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + +#ifndef IMAGEFILE_H +#define IMAGEFILE_H + +#ifndef MSVC +#include +#endif #include -#include "kstddef.h" #include -#include -#include - -using namespace std; - -class Array2dFileLabel -{ -private: - void init (void); - Array2dFileLabel (const Array2dFileLabel&); - Array2dFileLabel& operator= (const Array2dFileLabel&); - -public: - kfloat64 calc_time; - kuint16 label_type; - kuint16 year; - kuint16 month; - kuint16 day; - kuint16 hour; - kuint16 minute; - kuint16 second; - string label_str; - - static const int L_EMPTY = 0; - static const int L_HISTORY = 1; - static const int L_USER = 2; - - Array2dFileLabel(); - - Array2dFileLabel(const char* const str, double ctime = 0.); - - Array2dFileLabel(const int type, const char* const str, double ctime = 0.); - - ~Array2dFileLabel(); - - string getLabelString (void) const - { return label_str; } - - kfloat64 getCalcTime (void) const - { return calc_time; } - - kfloat64 getLabelType (void) const - { return label_type; } - - string& setLabelString (const char* const str) - { label_str = str; return (label_str); } - - string& setLabelString (const string& str) - { label_str = str; return (label_str); } - - void getDateString (string& str) const; -}; - - -template -class Array2dFile -{ -private: - void init (void); - kuint16 signature; - kuint16 num_labels; - kuint16 headersize; - string filename; - int file_id; - iostream *io; - bool bHeaderWritten; - bool bDataWritten; - - bool headerWrite (void); - - bool headerRead (void); - - bool arrayDataRead (void); - - bool labelSeek (unsigned int label_num); - - kuint16 mPixelSize; - kuint16 axis_increment_known; - kfloat64 mIncX, mIncY; - kuint16 axis_extent_known; - kfloat64 mMinX, mMaxX, mMinY, mMaxY; - kfloat64 mOffsetPV, mScalePV; - kuint16 mPixelType; - kuint32 mNX; - kuint32 mNY; - - Array2dFile (const Array2dFile&); - Array2dFile& operator= (const Array2dFile&); - -public: - - Array2d array; - - static const int INT8 = 1; - static const int UINT8 = 2; - static const int INT16 = 3; - static const int UINT16 = 4; - static const int INT32 = 5; - static const int UINT32 = 6; - static const int FLOAT32 = 7; - static const int FLOAT64 = 8; - - Array2dFile (unsigned int nx, unsigned int ny); - Array2dFile (const char* const filename); - Array2dFile (const char* const filename, unsigned int nx, unsigned int ny); - ~Array2dFile (); - - unsigned int getNumLabels (void) const - { return num_labels; } - - bool labelRead (Array2dFileLabel& label, unsigned int label_num); - - void labelAdd (const Array2dFileLabel& label); - - void labelAdd (const char* const label_str, double calc_time=0.); - - void labelAdd (int type, const char* const label_str, double calc_time=0.); - - void labelsCopy (Array2dFile& file, const char* const idStr = NULL); - - void fileClose (void); - - void setPixelType (int type) - { mPixelType = type; } - - kuint32 nx (void) const - { return mNX; } - - kuint32 ny (void) const - { return mNY; } - - void setAxisIncrement (double mIncX, double mIncY); - - void setAxisExtent (double mMinX, double mMaxX, double mMinY, double mMaxY); - - void getPixelValueRange (T& pvmin, T& pvmax) const; - - void doPixelOffsetScale (double offset, double scale); - - T** getArray (void) const - { return (array.getArray()); } - - bool arrayDataWrite (void); - - void arrayDataClear (void); - - bool fileRead (void); - - bool fileCreate (void); - - const string& GetFilename (void) const - { return filename; } -}; - - -template -Array2dFile::Array2dFile (unsigned int x, unsigned int y) -{ - init(); - mNX = x; - mNY = y; - array.initSetSize(mNX, mNY); -} - -template -Array2dFile::Array2dFile (const char * const str, unsigned int x, unsigned int y) - : filename(str) -{ - init(); - mNX = x; - mNY = y; - array.initSetSize(mNX, mNY); -} - -template -Array2dFile::Array2dFile (const char * const str) - : filename(str) -{ - init(); -} - -template -void -Array2dFile::init (void) -{ - mPixelSize = sizeof(T); - signature = ('I' * 256 + 'F'); - file_id = -1; - mNX = 0; - mNY = 0; - headersize = 0; - num_labels = 0; - axis_increment_known = false; - axis_extent_known = false; - mIncX = mMinY = 0; - mMinX = mMaxX = mMinY = mMaxY = 0; - mOffsetPV = 0; - mScalePV = 1; - io = NULL; - -#if 0 - const type_info& t_id = typeid(T); - cout << t_id.name() << endl; - const type_info& comp_id = typeid(T); - - if (t_id == comp_id) - mPixelType = FLOAT64; - else if (t_id == typeid(kfloat32)) - mPixelType = FLOAT32; - else if (t_id == typeid(kint32)) - mPixelType = INT32; - else if (t_id == typeid(kuint32)) - mPixelType = UINT32; - else if (t_id == typeid(kint16)) - mPixelType = INT16; - else if (t_id == typeid(kuint16)) - mPixelType = UINT16; - else if (t_id == typeid(kint8)) - mPixelType = INT8; - else if (t_id == typeid(kuint8)) - mPixelType = UINT8; - else -#endif - mPixelType = 0; - - bHeaderWritten = false; - bDataWritten = false; -} - -template -Array2dFile::~Array2dFile (void) -{ - fileClose (); -} - - -template -void -Array2dFile::fileClose (void) -{ - if (file_id >= 0) { - headerWrite (); - close (file_id); - file_id = -1; - } -} - -template -bool -Array2dFile::fileCreate (void) -{ - // io = new iostream(filename, ios::out | ios::in | ios::trunc | io::binary); - if ((file_id = open (filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { - sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str()); - return (false); - } - headerWrite(); - return (true); -} - -template -bool -Array2dFile::fileRead (void) -{ - // io = new iostream(filename, ios::out | ios::in | io::binary); - if ((file_id = open (filename.c_str(), O_RDONLY | O_BINARY)) < 0) { - sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str()); - return (false); - } - - headerRead(); - - array.initSetSize(mNX, mNY); - - arrayDataRead(); - - return (true); -} - -template -void -Array2dFile::setAxisIncrement (double incX, double incY) -{ - axis_increment_known = true; - mIncX = incX; - mIncY = incY; -} - -template -void -Array2dFile::setAxisExtent (double minX, double maxX, double minY, double maxY) -{ - axis_extent_known = true; - mMinX = minX; - mMaxY = maxX; - mMinX = minX; - mMaxY = maxY; -} - -template -void -Array2dFile::getPixelValueRange (T& pvmin, T& pvmax) const -{ - T** da = array.getArray(); - if (da) { - pvmax = pvmin = da[0][0]; - for (int ix = 0; ix < mNX; ix++) - for (int iy = 0; iy < mNY; iy++) - if (pvmax < da[ix][iy]) - pvmax = da[ix][iy]; - else if (pvmin > da[ix][iy]) - pvmin = da[ix][iy]; - } -} - -template -void -Array2dFile::doPixelOffsetScale (double offset, double scale) -{ - T** ad = array.getArray(); - if (ad) { - mOffsetPV = offset; - mScalePV = scale; - - for (unsigned int ix = 0; ix < mNX; ix++) - for (unsigned int iy = 0; iy < mNY; iy++) - ad[ix][iy] = (ad[ix][iy] - offset) * scale; - } -} - -template -bool -Array2dFile::headerRead (void) -{ - if (file_id < 0) { - sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]"); - return (false); - } - - lseek (file_id, 0, SEEK_SET); - kuint16 file_signature; - kuint16 file_mPixelSize; - kuint16 file_mPixelType; - - read_nint16 (&headersize, file_id); - read_nint16 (&file_signature, file_id); - read_nint16 (&num_labels, file_id); - read_nint16 (&file_mPixelType, file_id); - read_nint16 (&file_mPixelSize, file_id); - read_nint32 (&mNX, file_id); - read_nint32 (&mNY, file_id); - read_nint16 (&axis_increment_known, file_id); - read_nfloat64 (&mIncX, file_id); - read_nfloat64 (&mIncY, file_id); - read_nint16 (&axis_extent_known, file_id); - read_nfloat64 (&mMinX, file_id); - read_nfloat64 (&mMaxX, file_id); - read_nfloat64 (&mMinY, file_id); - read_nfloat64 (&mMaxY, file_id); - read_nfloat64 (&mOffsetPV, file_id); - read_nfloat64 (&mScalePV, file_id); - - int read_headersize = lseek (file_id, 0, SEEK_CUR); - if (read_headersize != headersize) { - sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize); - return (false); - } - if (file_signature != signature) { - sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature); - return (false); - } - if (file_mPixelType != mPixelType) { - sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType); - return (false); - } - if (file_mPixelSize != mPixelSize) { - sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize); - return (false); - } - - return (true); -} - -template -bool -Array2dFile::headerWrite (void) -{ - if (file_id < 0) { - sys_error (ERR_WARNING, "Tried to write header with file closed"); - return (false); - } - - lseek (file_id, 0, SEEK_SET); - write_nint16 (&headersize, file_id); - write_nint16 (&signature, file_id); - write_nint16 (&num_labels, file_id); - write_nint16 (&mPixelType, file_id); - write_nint16 (&mPixelSize, file_id); - write_nint32 (&mNX, file_id); - write_nint32 (&mNY, file_id); - write_nint16 (&axis_increment_known, file_id); - write_nfloat64 (&mIncX, file_id); - write_nfloat64 (&mIncY, file_id); - write_nint16 (&axis_extent_known, file_id); - write_nfloat64 (&mMinX, file_id); - write_nfloat64 (&mMaxX, file_id); - write_nfloat64 (&mMinY, file_id); - write_nfloat64 (&mMaxY, file_id); - write_nfloat64 (&mOffsetPV, file_id); - write_nfloat64 (&mScalePV, file_id); - - headersize = lseek (file_id, 0, SEEK_CUR); - lseek (file_id, 0, SEEK_SET); - write_nint16 (&headersize, file_id); - - return (true); -} - -template -bool -Array2dFile::arrayDataWrite (void) -{ - if (file_id < 0) { - sys_error (ERR_WARNING, "Tried to arrayDataWrite with file_id < 0"); - return (false); - } - - T** da = array.getArray(); - if (! da) - return (false); - - lseek (file_id, headersize, SEEK_SET); - for (unsigned int ix = 0; ix < mNX; ix++) - for (unsigned int iy = 0; iy < mNY; iy++) { - T value = da[ix][iy]; - ConvertReverseNetworkOrder (&value, sizeof(T)); - write (file_id, &value, mPixelSize); - } - - return (true); -} - -template -bool -Array2dFile::arrayDataRead (void) -{ - if (file_id < 0) { - sys_error (ERR_WARNING, "Tried to arrayDataRead with file_id < 0"); - return (false); - } - - T** da = array.getArray(); - if (! da) - return (false); - - lseek (file_id, headersize, SEEK_SET); - T pixelBuffer; - for (int ix = 0; ix < mNX; ix++) - for (unsigned int iy = 0; iy < mNY; iy++) { - read (file_id, &pixelBuffer, mPixelSize); - ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T)); - da[ix][iy] = pixelBuffer; - } - - return (true); -} - -template -bool -Array2dFile::labelSeek (unsigned int label_num) -{ - if (label_num > num_labels) { - sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]"); - return (false); - } - - if (array.getArray() == NULL) { // Could not have written data if array not allocated - sys_error (ERR_WARNING, "array == NULL [labelSeek]"); - return (false); - } - - off_t pos = headersize + array.sizeofArray(); - if (lseek (file_id, pos, SEEK_SET) != pos) { - sys_error (ERR_WARNING, "Can't seek to end of data array"); - return (false); - } - - for (int i = 0; i < label_num; i++) - { - pos += 22; // Skip to string length - if (lseek (file_id, pos, SEEK_SET) != pos) { - sys_error (ERR_WARNING, "Can't seek to string length"); - return (false); - } - kuint16 strlength; - read_nint16 (&strlength, file_id); - pos += 2 + strlength; // Skip label string length + data - if (lseek (file_id, pos, SEEK_SET) != pos) { - sys_error (ERR_WARNING, "Can't seek past label string"); - return (false); - } - } - - return (true); -} - -template -bool -Array2dFile::labelRead (Array2dFileLabel& label, unsigned int label_num) -{ - if (label_num >= num_labels) { - sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]"); - return (false); - } - - if (! labelSeek (label_num)) { - sys_error (ERR_WARNING, "Error calling labelSeek"); - return (false); - } - - read_nint16 (&label.label_type, file_id); - read_nint16 (&label.year, file_id); - read_nint16 (&label.month, file_id); - read_nint16 (&label.day, file_id); - read_nint16 (&label.hour, file_id); - read_nint16 (&label.minute, file_id); - read_nint16 (&label.second, file_id); - read_nfloat64 (&label.calc_time, file_id); - - kuint16 strlength; - read_nint16 (&strlength, file_id); - char *str = new char [strlength+1]; - read (file_id, str, strlength); - label.label_str = str; - - return (true); -} - - -template -void -Array2dFile::labelAdd (const char* const lstr, double calc_time=0.) -{ - labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time); -} - -template -void -Array2dFile::labelAdd (int type, const char* const lstr, double calc_time=0.) -{ - Array2dFileLabel label (type, lstr, calc_time); - - labelAdd (label); -} - -template -void -Array2dFile::labelAdd (const Array2dFileLabel& label) -{ - labelSeek (num_labels); - - write_nint16 (&label.label_type, file_id); - write_nint16 (&label.year, file_id); - write_nint16 (&label.month, file_id); - write_nint16 (&label.day, file_id); - write_nint16 (&label.hour, file_id); - write_nint16 (&label.minute, file_id); - write_nint16 (&label.second, file_id); - write_nfloat64 (&label.calc_time, file_id); - kuint16 strlength = label.label_str.length(); - write_nint16 (&strlength, file_id); - write (file_id, static_cast(label.label_str.c_str()), strlength); - - num_labels++; - - headerWrite(); - fsync(file_id); -} - -template -void -Array2dFile::labelsCopy (Array2dFile& copyFile, const char* const idStr) -{ - string id = idStr; - for (int i = 0; i < copyFile.getNumLabels(); i++) { - Array2dFileLabel l; - copyFile.labelRead (l, i); - string lstr = l.getLabelString(); - lstr = idStr + lstr; - l.setLabelString (lstr); - labelAdd (l); - } -} - -template -void -Array2dFile::arrayDataClear (void) -{ - T** v = array.getArray(); - if (v) { - for (unsigned int ix = 0; ix < mNX; ix++) - for (unsigned int iy = 0; iy < mNY; iy++) - v[ix][iy] = 0; - } -} - +#include +#include +#include "ctsupport.h" +#include "fnetorderstream.h" +#include "array2dfile.h" #ifdef HAVE_MPI #include #endif -class F32Image : public Array2dFile +class F32Image : public Array2dFile { public: - F32Image (const char* const fname, unsigned int nx, unsigned int ny) - : Array2dFile::Array2dFile (fname, nx, ny) - { - setPixelType (FLOAT32); - } - - F32Image (unsigned int nx, unsigned int ny) - : Array2dFile::Array2dFile (nx, ny) - { - setPixelType (FLOAT32); - } - - F32Image (const char* const fname) - : Array2dFile::Array2dFile (fname) - { - setPixelType (FLOAT32); - } - + F32Image (int nx, int ny, int dataType = Array2dFile::DATA_TYPE_REAL); + F32Image (void); + + kfloat32** getArray (void) + { return (kfloat32**) (m_arrayData); } + + kfloat32** const getArray (void) const + { return (kfloat32** const) (m_arrayData); } + + kfloat32** getImaginaryArray (void) + { return (kfloat32**) (m_imaginaryArrayData); } + + kfloat32** const getImaginaryArray (void) const + { return (kfloat32** const) (m_imaginaryArrayData); } + #ifdef HAVE_MPI MPI::Datatype getMPIDataType (void) const { return MPI::FLOAT; } #endif + + private: + F32Image (const F32Image& rhs); //copy constructor + F32Image& operator= (const F32Image& rhs); // assignment operator }; -class F64Image : public Array2dFile +class F64Image : public Array2dFile { public: - F64Image (const char* const fname, unsigned int nx, unsigned int ny) - : Array2dFile::Array2dFile (fname, nx, ny) - { - setPixelType (FLOAT64); - } - - F64Image (unsigned int nx, unsigned int ny) - : Array2dFile::Array2dFile (nx, ny) - { - setPixelType (FLOAT64); - } - - F64Image (const char* const fname) - : Array2dFile::Array2dFile (fname) - { - setPixelType (FLOAT64); - } - + F64Image (int nx, int ny, int dataType = Array2dFile::DATA_TYPE_REAL); + F64Image (void); + + kfloat64** getArray (void) + { return (kfloat64**) (m_arrayData); } + + kfloat64** const getArray (void) const + { return (kfloat64** const) (m_arrayData); } + + kfloat64** getImaginaryArray (void) + { return (kfloat64**) (m_imaginaryArrayData); } + + kfloat64** const getImaginaryArray (void) const + { return (kfloat64** const) (m_imaginaryArrayData); } + #ifdef HAVE_MPI MPI::Datatype getMPIDataType (void) const { return MPI::DOUBLE; } #endif + private: + F64Image (const F64Image& rhs); //copy constructor + F64Image& operator= (const F64Image& rhs); // assignment operator }; -#define IMAGEFILE_64_BITS 1 +#undef IMAGEFILE_64_BITS #ifdef IMAGEFILE_64_BITS -typedef F64Image ImageFile; +typedef F64Image ImageFileBase; typedef kfloat64 ImageFileValue; typedef kfloat64* ImageFileColumn; typedef kfloat64** ImageFileArray; +typedef kfloat64** const ImageFileArrayConst; +typedef const kfloat64* ImageFileColumnConst; #else -typedef F32Image ImageFile; +typedef F32Image ImageFileBase; typedef kfloat32 ImageFileValue; typedef kfloat32* ImageFileColumn; typedef kfloat32** ImageFileArray; +typedef kfloat32** const ImageFileArrayConst; +typedef const kfloat32* ImageFileColumnConst; #endif -#endif +class ImageFile : public ImageFileBase +{ +private: + + static const char* s_aszFormatName[]; + static const char* s_aszFormatTitle[]; + static const int s_iFormatCount; + +public: + + static const int FORMAT_INVALID; + static const int FORMAT_PGM; + static const int FORMAT_PGMASCII; +#if HAVE_PNG + static const int FORMAT_PNG; + static const int FORMAT_PNG16; +#endif + + static const int getFormatCount() {return s_iFormatCount;} + static const char** getFormatNameArray() {return s_aszFormatName;} + static const char** getFormatTitleArray() {return s_aszFormatTitle;} + static int convertFormatNameToID (const char* const formatName); + static const char* convertFormatIDToName (const int formatID); + static const char* convertFormatIDToTitle (const int formatID); + + ImageFile (int nx, int ny) + : ImageFileBase (nx, ny) + {} + + ImageFile (void) + : ImageFileBase () + {} + + bool convertRealToComplex (); + bool convertComplexToReal (); + + 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; + void statistics (ImageFileArrayConst v, double& min, double& max, double& mean, double& mode, double& median, double& stddev) const; + void getMinMax (double& min, double& max) const; + void printStatistics (std::ostream& os) const; + bool comparativeStatistics (const ImageFile& imComp, double& d, double& r, double& e) const; + bool printComparativeStatistics (const ImageFile& imComp, std::ostream& os) const; + + bool subtractImages (const ImageFile& rRHS, ImageFile& result) const; + bool addImages (const ImageFile& rRHS, ImageFile& result) const; + bool multiplyImages (const ImageFile& rRHS, ImageFile& result) const; + bool divideImages (const ImageFile& rRHS, ImageFile& result) const; + + bool scaleImage (ImageFile& result) const; + + bool invertPixelValues (ImageFile& result) const; + bool sqrt (ImageFile& result) const; + bool square (ImageFile& result) const; + bool log (ImageFile& result) const; + bool exp (ImageFile& result) const; + bool fourier (ImageFile& result) const; + bool inverseFourier (ImageFile& result) const; +#ifdef HAVE_FFTW + bool fft (ImageFile& result) const; + bool ifft (ImageFile& result) const; +#endif + bool magnitude (ImageFile& result) const; + bool phase (ImageFile& result) const; + + int display (void) const; + int displayScaling (const int scaleFactor, ImageFileValue pmin, ImageFileValue pmax) const; + + bool exportImage (const char* const pszFormat, const char* const pszFilename, int nxcell, int nycell, double densmin, double densmax); + +#if HAVE_PNG + bool writeImagePNG (const char* const outfile, int bitdepth, int nxcell, int nycell, double densmin, double densmax); +#endif +#if HAVE_GD + bool writeImageGIF (const char* const outfile, int nxcell, int nycell, double densmin, double densmax); +#endif + 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); +}; +#endif