r120: *** empty log message ***
[ctsim.git] / include / imagefile.h
index 7c0952c2acc568e8b96897a011637ac77074baa5..7c6c84a93782d6aea4f2f96a24d30c3f901ba808 100644 (file)
@@ -2,28 +2,30 @@
 #define IDF_H
 
 #include <string>
-#include "kstddef.h"
 #include <sys/types.h>
 #include <unistd.h>
-#include <array2d.h>
+#include <fstream>
+#include <iostream>
+#include "ctsupport.h"
+#include "fnetorderstream.h"
+#include "array2d.h"
 
 using namespace std;
 
+
 class Array2dFileLabel
 {
-private:
-    void init (void);
-
 public:
-    kfloat64 calc_time;
-    kuint16 label_type;
-    kuint16 year;
-    kuint16 month;
-    kuint16 day;
-    kuint16 hour;
-    kuint16 minute;
-    kuint16 second;
-    string label_str;
+    kfloat64 m_calcTime;
+    kuint16 m_labelType;
+    kuint16 m_year;
+    kuint16 m_month;
+    kuint16 m_day;
+    kuint16 m_hour;
+    kuint16 m_minute;
+    kuint16 m_second;
+    string m_strLabel;
+    mutable string m_strDate;
 
     static const int L_EMPTY = 0;
     static const int L_HISTORY = 1;
@@ -37,22 +39,27 @@ public:
 
     ~Array2dFileLabel();
 
-    string getLabelString (void) const
-       { return label_str; }
+    const string& getLabelString (void) const
+       { return m_strLabel; }
 
     kfloat64 getCalcTime (void) const
-       { return calc_time; }
+       { return m_calcTime; }
 
     kfloat64 getLabelType (void) const
-       { return label_type; }
+       { return m_labelType; }
 
     string& setLabelString (const char* const str)
-       { label_str = str; return (label_str); }
+       { m_strLabel = str; return (m_strLabel); }
 
     string& setLabelString (const string& str)
-       { label_str = str; return (label_str); }
+       { m_strLabel = str; return (m_strLabel); }
 
-    void getDateString (string& str) const;
+    const string& getDateString () const;
+
+private:
+    void init (void);
+    Array2dFileLabel (const Array2dFileLabel&);
+    Array2dFileLabel& operator= (const Array2dFileLabel&);
 };
 
 
@@ -61,14 +68,6 @@ 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);
 
@@ -78,6 +77,19 @@ private:
 
   bool labelSeek (unsigned int label_num);
 
+  Array2dFile (const Array2dFile& rhs);        // copy constructor
+  Array2dFile& operator= (const Array2dFile&); // assignment operator
+
+ protected:
+  kuint16 signature;
+  kuint16 num_labels;
+  kuint16 headersize;
+  string  filename;
+  int file_id;
+  frnetorderstream *m_pFS;
+  bool bHeaderWritten;
+  bool bDataWritten;
+
   kuint16 mPixelSize;
   kuint16 axis_increment_known;
   kfloat64 mIncX, mIncY;
@@ -88,6 +100,7 @@ private:
   kuint32 mNX;
   kuint32 mNY;
 
+
 public:
 
   Array2d<T> array;
@@ -113,9 +126,9 @@ public:
 
   void labelAdd (const Array2dFileLabel& label);
 
-  void labelAdd (const char* const label_str, double calc_time=0.);
+  void labelAdd (const char* const m_strLabel, double calc_time=0.);
 
-  void labelAdd (int type, const char* const label_str, double calc_time=0.);
+  void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
 
   void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
 
@@ -138,6 +151,8 @@ public:
       
   void doPixelOffsetScale (double offset, double scale);
 
+  void printLabels (ostream& os);
+
   T** getArray (void) const
       { return (array.getArray()); }
 
@@ -186,7 +201,6 @@ Array2dFile<T>::init (void)
 {
   mPixelSize = sizeof(T);
   signature = ('I' * 256 + 'F');
-  file_id = -1;
   mNX = 0;
   mNY = 0;
   headersize = 0;
@@ -197,7 +211,7 @@ Array2dFile<T>::init (void)
   mMinX = mMaxX = mMinY = mMaxY = 0;
   mOffsetPV = 0;
   mScalePV = 1;
-  io = NULL;
+  m_pFS = NULL;
 
 #if 0
   const type_info& t_id = typeid(T);
@@ -239,10 +253,10 @@ template<class T>
 void
 Array2dFile<T>::fileClose (void)
 {
-  if (file_id >= 0) {
+  if (m_pFS) {
       headerWrite ();
-      close (file_id);
-      file_id = -1;
+      m_pFS->close ();
+      m_pFS = NULL;
   }
 }
 
@@ -250,11 +264,11 @@ template<class T>
 bool
 Array2dFile<T>::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);
-    }
+  m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::trunc | ios::binary);
+  if (! m_pFS) {
+      sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str());
+      return (false);
+  }
   headerWrite();
   return (true);
 }
@@ -263,13 +277,14 @@ template<class T>
 bool
 Array2dFile<T>::fileRead (void)
 {
-  // io = new iostream(filename, ios::out | ios::in | io::binary);
-  if ((file_id = open (filename.c_str(), O_RDONLY | O_BINARY)) < 0) {
+  m_pFS = new frnetorderstream (filename.c_str(), ios::out | ios::in | ios::binary | ios::nocreate);
+  if (m_pFS->fail()) {
     sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str());
     return (false);
   }
 
-  headerRead();
+  if (! headerRead())
+      return false;
 
   array.initSetSize(mNX, mNY);
 
@@ -333,35 +348,35 @@ template<class T>
 bool
 Array2dFile<T>::headerRead (void)
 {
-  if (file_id < 0) {
+  if (! m_pFS) {
     sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
     return (false);
   }
 
-  lseek (file_id, 0, SEEK_SET);
+  m_pFS->seekg (0);
   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);
+  m_pFS->readInt16 (headersize);
+  m_pFS->readInt16 (file_signature);
+  m_pFS->readInt16 (num_labels);
+  m_pFS->readInt16 (file_mPixelType);
+  m_pFS->readInt16 (file_mPixelSize);
+  m_pFS->readInt32 (mNX);
+  m_pFS->readInt32 (mNY);
+  m_pFS->readInt16 (axis_increment_known);
+  m_pFS->readFloat64 (mIncX);
+  m_pFS->readFloat64 (mIncY);
+  m_pFS->readInt16 (axis_extent_known);
+  m_pFS->readFloat64 (mMinX);
+  m_pFS->readFloat64 (mMaxX);
+  m_pFS->readFloat64 (mMinY);
+  m_pFS->readFloat64 (mMaxY);
+  m_pFS->readFloat64 (mOffsetPV);
+  m_pFS->readFloat64 (mScalePV);
+
+  int read_headersize = m_pFS->tellg();
   if (read_headersize != headersize) {
     sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize);
     return (false);
@@ -386,33 +401,32 @@ template<class T>
 bool
 Array2dFile<T>::headerWrite (void)
 {
-  if (file_id < 0) {
+  if (! m_pFS) {
     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);
+  m_pFS->seekp (0);
+  m_pFS->writeInt16 (headersize);
+  m_pFS->writeInt16 (signature);
+  m_pFS->writeInt16 (num_labels);
+  m_pFS->writeInt16 (mPixelType);
+  m_pFS->writeInt16 (mPixelSize);
+  m_pFS->writeInt32 (mNX);
+  m_pFS->writeInt32 (mNY);
+  m_pFS->writeInt16 (axis_increment_known);
+  m_pFS->writeFloat64 (mIncX);
+  m_pFS->writeFloat64 (mIncY);
+  m_pFS->writeInt16 (axis_extent_known);
+  m_pFS->writeFloat64 (mMinX);
+  m_pFS->writeFloat64 (mMaxX);
+  m_pFS->writeFloat64 (mMinY);
+  m_pFS->writeFloat64 (mMaxY);
+  m_pFS->writeFloat64 (mOffsetPV);
+  m_pFS->writeFloat64 (mScalePV);
+
+  headersize = m_pFS->tellp();
+  m_pFS->writeInt16 (headersize);
   
   return (true);
 }
@@ -421,8 +435,8 @@ template<class T>
 bool
 Array2dFile<T>::arrayDataWrite (void)
 {
-  if (file_id < 0) {
-    sys_error (ERR_WARNING, "Tried to arrayDataWrite with file_id < 0");
+  if (! m_pFS) {
+    sys_error (ERR_WARNING, "Tried to arrayDataWrite with !m_pFS");
     return (false);
   }
 
@@ -430,13 +444,17 @@ Array2dFile<T>::arrayDataWrite (void)
   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);
-      }
+  m_pFS->seekp (headersize);
+  for (unsigned int ix = 0; ix < mNX; ix++) {
+      if (NativeBigEndian()) {
+         for (unsigned int iy = 0; iy < mNY; iy++) {
+             T value = da[ix][iy];
+             ConvertReverseNetworkOrder (&value, sizeof(T));
+             m_pFS->write (&value, mPixelSize);
+         }
+      } else 
+         m_pFS->write (da[ix], sizeof(T) * mNY);
+  }
 
   return (true);
 }
@@ -445,8 +463,8 @@ template<class T>
 bool
 Array2dFile<T>::arrayDataRead (void)
 {
-  if (file_id < 0) {
-    sys_error (ERR_WARNING, "Tried to arrayDataRead with file_id < 0");
+  if (! m_pFS) {
+    sys_error (ERR_WARNING, "Tried to arrayDataRead with !m_pFS");
     return (false);
   }
 
@@ -454,14 +472,19 @@ Array2dFile<T>::arrayDataRead (void)
   if (! da) 
       return (false);
 
-  lseek (file_id, headersize, SEEK_SET);
+  m_pFS->seekg (headersize);
   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;
-      }
+  for (int ix = 0; ix < mNX; ix++) {
+      if (NativeBigEndian()) {
+         for (unsigned int iy = 0; iy < mNY; iy++) {
+             m_pFS->read (&pixelBuffer, mPixelSize);
+             ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T));
+             da[ix][iy] = pixelBuffer;
+         } 
+      } else
+         m_pFS->read (da[ix], sizeof(T) * mNY);
+  }
+
 
   return (true);
 }
@@ -481,26 +504,21 @@ Array2dFile<T>::labelSeek (unsigned int label_num)
   }
 
   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);
-  }
+  m_pFS->seekg (pos);
 
   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);
-         }
+         m_pFS->seekg (pos);
+             
          kuint16 strlength;
-         read_nint16 (&strlength, file_id);
+         m_pFS->readInt16 (strlength);
          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);
-         }
+         m_pFS->seekg (pos);
       }
+  
+  if (! m_pFS)
+      return false;
 
   return (true);
 }
@@ -519,20 +537,21 @@ Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
     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);
+  m_pFS->readInt16 (label.m_labelType);
+  m_pFS->readInt16 (label.m_year);
+  m_pFS->readInt16 (label.m_month);
+  m_pFS->readInt16 (label.m_day);
+  m_pFS->readInt16 (label.m_hour);
+  m_pFS->readInt16 (label.m_minute);
+  m_pFS->readInt16 (label.m_second);
+  m_pFS->readFloat64 (label.m_calcTime);
 
   kuint16 strlength;
-  read_nint16 (&strlength, file_id);
-  char *str = new char [strlength+1];
-  read (file_id, str, strlength);
-  label.label_str = str;
+  m_pFS->readInt16 (strlength);
+  char str [strlength+1];
+  m_pFS->read (str, strlength);
+  str[strlength] = 0;
+  label.m_strLabel = str;
 
   return (true);
 }
@@ -560,22 +579,21 @@ Array2dFile<T>::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<const void*>(label.label_str.c_str()), strlength);
+  m_pFS->writeInt16 (label.m_labelType);
+  m_pFS->writeInt16 (label.m_year);
+  m_pFS->writeInt16 (label.m_month);
+  m_pFS->writeInt16 (label.m_day);
+  m_pFS->writeInt16 (label.m_hour);
+  m_pFS->writeInt16 (label.m_minute);
+  m_pFS->writeInt16 (label.m_second);
+  m_pFS->writeFloat64 (label.m_calcTime);
+  kuint16 strlength = label.m_strLabel.length();
+  m_pFS->writeInt16 (strlength);
+  m_pFS->write (label.m_strLabel.c_str(), strlength);
 
   num_labels++;
 
   headerWrite();
-  fsync(file_id);
 }
 
 template<class T>
@@ -605,6 +623,28 @@ Array2dFile<T>::arrayDataClear (void)
     }
 }
 
+template<class T>
+void
+Array2dFile<T>::printLabels (ostream& os)
+{
+    int nlabels = getNumLabels();
+
+    for (int i = 0; i < nlabels; i++) {
+       Array2dFileLabel label;
+       labelRead (label, i);
+
+       if (label.getLabelType() == Array2dFileLabel::L_HISTORY) {
+           os << "History: " << endl;
+           os << "  " << label.getLabelString() << endl;
+           os << "  calc time = " << label.getCalcTime() << " secs" << endl;
+           os << "  Timestamp = " << label.getDateString() << endl;
+       } else if (label.getLabelType() == Array2dFileLabel::L_USER) {
+           os << "Note: " <<  label.getLabelString() << endl;
+           os << "  Timestamp = %s" << label.getDateString() << endl;
+       }
+       os << endl;
+    }
+}
 
 #ifdef HAVE_MPI
 #include <mpi++.h>
@@ -635,6 +675,10 @@ public:
   MPI::Datatype getMPIDataType (void) const
       { return MPI::FLOAT; }
 #endif
+
+ private:
+  F32Image (const F32Image& rhs);             //copy constructor
+  F32Image& operator= (const F32Image& rhs);  // assignment operator
 };
 
 
@@ -664,21 +708,57 @@ class F64Image : public Array2dFile<kfloat64>
   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;
 #else
-typedef F32Image   ImageFile;
+typedef F32Image   ImageFileBase;
 typedef kfloat32   ImageFileValue;
 typedef kfloat32*  ImageFileColumn;
 typedef kfloat32** ImageFileArray;
 #endif
 
+
+class ImageFile : public ImageFileBase
+{
+ public:
+  ImageFile (const char* const fname, unsigned int nx, unsigned int ny)
+      : ImageFileBase (fname, nx, ny)
+  {}
+
+  ImageFile (unsigned int nx, unsigned int ny)
+      : ImageFileBase (nx, ny)
+  {}
+
+  ImageFile (const char* const fname)
+      : ImageFileBase (fname)
+  {}
+
+  void filterResponse (const char* const domainName, double bw, const char* const filterName, double filt_param);
+
+  void statistics (double& min, double& max, double& mean, double& mode, double& median, double& stddev) const;
+
+  void printStatistics (ostream& os) const;
+
+  bool comparativeStatistics (const ImageFile& imComp, double& d, double& r, double& e) const;
+
+  bool printComparativeStatistics (const ImageFile& imComp, ostream& os) const;
+
+  int display (void);
+
+  int displayScaling (const int scaleFactor, ImageFileValue pmin, ImageFileValue pmax);
+
+};
+
+
 #endif