r91: Made ImageFile inherit from Array2dFile
[ctsim.git] / include / imagefile.h
index 0c2f8b5c990c0ce8c88d6a35c1ee290520fe42e2..7c0952c2acc568e8b96897a011637ac77074baa5 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <string>
 #include "kstddef.h"
+#include <sys/types.h>
+#include <unistd.h>
 #include <array2d.h>
 
 using namespace std;
@@ -35,7 +37,7 @@ public:
 
     ~Array2dFileLabel();
 
-    const string& getLabelString (void) const
+    string getLabelString (void) const
        { return label_str; }
 
     kfloat64 getCalcTime (void) const
@@ -44,6 +46,12 @@ public:
     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;
 };
 
@@ -70,19 +78,19 @@ private:
 
   bool labelSeek (unsigned int label_num);
 
-public:
-  kuint16 pixel_size;
-  kuint16 pixel_type;
-  kuint32 nx;
-  kuint32 ny;
-
+  kuint16 mPixelSize;
   kuint16 axis_increment_known;
-  kfloat64 xinc, yinc;
+  kfloat64 mIncX, mIncY;
   kuint16 axis_extent_known;
-  kfloat64 xmin, xmax, ymin, ymax;
-  kfloat64 pv_offset, pv_scale;
+  kfloat64 mMinX, mMaxX, mMinY, mMaxY;
+  kfloat64 mOffsetPV, mScalePV;
+  kuint16 mPixelType;
+  kuint32 mNX;
+  kuint32 mNY;
 
-  Array2d<T> *array;
+public:
+
+  Array2d<T> array;
 
   static const int INT8 = 1;
   static const int UINT8 = 2;
@@ -98,30 +106,45 @@ public:
   Array2dFile (const char* const filename, unsigned int nx, unsigned int ny);
   ~Array2dFile ();
 
-  virtual unsigned int getNumLabels (void) const
-  { return num_labels; }
+  unsigned int getNumLabels (void) const
+      { return num_labels; }
 
   bool labelRead (Array2dFileLabel& label, unsigned int label_num);
 
-  bool labelAdd (const char* const label_str, double calc_time=0.);
+  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.);
 
-  bool 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 set_axis_increment (double xinc, double yinc);
+  void setPixelType (int type)
+      { mPixelType = type; }
 
-  void set_axis_extent (double xmin, double xmax, double ymin, double ymax);
+  kuint32 nx (void) const
+      { return mNX; }
 
-  void get_pixel_extent (T& pvmin, T& pvmax);
+  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 set_pixel_offset_extent (double offset, double scale);
+  void doPixelOffsetScale (double offset, double scale);
 
   T** getArray (void) const
-      { return (array == NULL ? NULL : array->getArray()); }
+      { return (array.getArray()); }
 
   bool arrayDataWrite (void);
 
+  void arrayDataClear (void);
+
   bool fileRead (void);
 
   bool fileCreate (void);
@@ -132,67 +155,48 @@ public:
 
 
 template<class T>
-void
-Array2dFile<T>::set_axis_increment (double xinc, double yinc)
-{
-    axis_increment_known = true;
-    this.xinc = xinc;
-    this.yinc = yinc;
-}
-
-template<class T>
-void 
-Array2dFile<T>::set_axis_extent (double xmin, double xmax, double ymin, double ymax)
+Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
 {
-    axis_extent_known = true;
-    this.xmin = xmin;
-    this.ymax = xmax;
-    this.xmin = xmin;
-    this.ymax = ymax;
+    init();
+    mNX = x;
+    mNY = y;
+    array.initSetSize(mNX, mNY);
 }
 
 template<class T>
-void 
-Array2dFile<T>::get_pixel_extent (T& pvmin, T& pvmax)
+Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
+  : filename(str)
 {
-      if (array != NULL) {
-       T** da = array.GetArray();
-       pvmax = pvmin = da[0][0];
-         for (int ix = 0; ix < nx; ix++)
-             for (int iy = 0; iy < ny; iy++)
-                 if (pvmax < da[ix][iy])
-                     pvmax = da[ix][iy];
-                 else if (pvmin > da[ix][iy])
-                   pvmin = da[ix][iy];
-      }
+    init();
+    mNX = x;
+    mNY = y;
+    array.initSetSize(mNX, mNY);
 }
 
 template<class T>
-void
-Array2dFile<T>::set_pixel_offset_extent (double offset, double scale)
+Array2dFile<T>::Array2dFile (const char * const str)
+  : filename(str)
 {
-      pv_offset = offset;
-      pv_scale = scale;
+    init();
 }
 
 template<class T>
 void
 Array2dFile<T>::init (void)
 {
-  pixel_size = sizeof(T);
+  mPixelSize = sizeof(T);
   signature = ('I' * 256 + 'F');
   file_id = -1;
-  nx = 0;
-  ny = 0;
+  mNX = 0;
+  mNY = 0;
   headersize = 0;
   num_labels = 0;
   axis_increment_known = false;
   axis_extent_known = false;
-  xinc = ymin = 0;
-  xmin = xmax = ymin = ymax = 0;
-  pv_offset = 0;
-  pv_scale = 1;
-  array = NULL;
+  mIncX = mMinY = 0;
+  mMinX = mMaxX = mMinY = mMaxY = 0;
+  mOffsetPV = 0;
+  mScalePV = 1;
   io = NULL;
 
 #if 0
@@ -201,53 +205,45 @@ Array2dFile<T>::init (void)
   const type_info& comp_id = typeid(T);
 
   if (t_id == comp_id)
-      pixel_type = FLOAT64;
+      mPixelType = FLOAT64;
   else if (t_id == typeid(kfloat32))
-    pixel_type = FLOAT32;
+    mPixelType = FLOAT32;
   else if (t_id == typeid(kint32))
-    pixel_type = INT32;
+    mPixelType = INT32;
   else if (t_id == typeid(kuint32))
-    pixel_type = UINT32;
+    mPixelType = UINT32;
   else if (t_id == typeid(kint16))
-    pixel_type = INT16;
+    mPixelType = INT16;
   else if (t_id == typeid(kuint16))
-    pixel_type = UINT16;
+    mPixelType = UINT16;
   else if (t_id == typeid(kint8))
-    pixel_type = INT8;
+    mPixelType = INT8;
   else if (t_id == typeid(kuint8))
-    pixel_type = UINT8;
+    mPixelType = UINT8;
   else
 #endif
-      pixel_type = 0;
+      mPixelType = 0;
 
   bHeaderWritten = false;
   bDataWritten = false;
 }
 
 template<class T>
-Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
+Array2dFile<T>::~Array2dFile (void)
 {
-    init();
-    nx = x;
-    ny = y;
-    array = new Array2d<T> (nx, ny);
+    fileClose ();
 }
 
-template<class T>
-Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
-  : filename(str)
-{
-    init();
-    nx = x;
-    ny = y;
-    array = new Array2d<T> (nx, ny);
-}
 
 template<class T>
-Array2dFile<T>::Array2dFile (const char * const str)
-  : filename(str)
+void
+Array2dFile<T>::fileClose (void)
 {
-    init();
+  if (file_id >= 0) {
+      headerWrite ();
+      close (file_id);
+      file_id = -1;
+  }
 }
 
 template<class T>
@@ -274,16 +270,65 @@ Array2dFile<T>::fileRead (void)
   }
 
   headerRead();
-  if (array != NULL)
-    delete array;
 
-  array = new Array2d<T> (nx, ny);
+  array.initSetSize(mNX, mNY);
 
   arrayDataRead();
 
   return (true);
 }
 
+template<class T>
+void
+Array2dFile<T>::setAxisIncrement (double incX, double incY)
+{
+    axis_increment_known = true;
+    mIncX = incX;
+    mIncY = incY;
+}
+
+template<class T>
+void 
+Array2dFile<T>::setAxisExtent (double minX, double maxX, double minY, double maxY)
+{
+    axis_extent_known = true;
+    mMinX = minX;
+    mMaxY = maxX;
+    mMinX = minX;
+    mMaxY = maxY;
+}
+
+template<class T>
+void 
+Array2dFile<T>::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<class T>
+void
+Array2dFile<T>::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<class T>
 bool
 Array2dFile<T>::headerRead (void)
@@ -295,26 +340,26 @@ Array2dFile<T>::headerRead (void)
 
   lseek (file_id, 0, SEEK_SET);
   kuint16 file_signature;
-  kuint16 file_pixel_size;
-  kuint16 file_pixel_type;
+  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_pixel_type, file_id);
-  read_nint16 (&file_pixel_size, file_id);
-  read_nint32 (&nx, file_id);
-  read_nint32 (&ny, 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 (&xinc, file_id);
-  read_nfloat64 (&yinc, file_id);
+  read_nfloat64 (&mIncX, file_id);
+  read_nfloat64 (&mIncY, file_id);
   read_nint16 (&axis_extent_known, file_id);
-  read_nfloat64 (&xmin, file_id);
-  read_nfloat64 (&xmax, file_id);
-  read_nfloat64 (&ymin, file_id);
-  read_nfloat64 (&ymax, file_id);
-  read_nfloat64 (&pv_offset, file_id);
-  read_nfloat64 (&pv_scale, 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) {
@@ -325,12 +370,12 @@ Array2dFile<T>::headerRead (void)
     sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature);
     return (false);
   }
-  if (file_pixel_type != pixel_type) {
-    sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_pixel_type, pixel_type);
+  if (file_mPixelType != mPixelType) {
+    sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType);
     return (false);
   }
-  if (file_pixel_size != pixel_size) {
-    sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_pixel_size, pixel_size);
+  if (file_mPixelSize != mPixelSize) {
+    sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize);
     return (false);
   }
 
@@ -350,20 +395,20 @@ Array2dFile<T>::headerWrite (void)
   write_nint16 (&headersize, file_id);
   write_nint16 (&signature, file_id);
   write_nint16 (&num_labels, file_id);
-  write_nint16 (&pixel_type, file_id);
-  write_nint16 (&pixel_size, file_id);
-  write_nint32 (&nx, file_id);
-  write_nint32 (&ny, 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 (&xinc, file_id);
-  write_nfloat64 (&yinc, file_id);
+  write_nfloat64 (&mIncX, file_id);
+  write_nfloat64 (&mIncY, file_id);
   write_nint16 (&axis_extent_known, file_id);
-  write_nfloat64 (&xmin, file_id);
-  write_nfloat64 (&xmax, file_id);
-  write_nfloat64 (&ymin, file_id);
-  write_nfloat64 (&ymax, file_id);
-  write_nfloat64 (&pv_offset, file_id);
-  write_nfloat64 (&pv_scale, 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);
@@ -381,34 +426,21 @@ Array2dFile<T>::arrayDataWrite (void)
     return (false);
   }
 
+  T** da = array.getArray();
+  if (! da) 
+      return (false);
+
   lseek (file_id, headersize, SEEK_SET);
-  for (int ix = 0; ix < nx; ix++)
-    {
-      write (file_id, array->array_data[ix], ny * pixel_size);
-    }
+  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<class T>
-void
-Array2dFile<T>::fileClose (void)
-{
-  headerWrite ();
-  if (file_id >= 0 && array != NULL) {
-    arrayDataWrite ();
-    close (file_id);
-    file_id = -1;
-  }
-}
-
-template<class T>
-Array2dFile<T>::~Array2dFile (void)
-{
-    fileClose ();
-}
-
-
 template<class T>
 bool
 Array2dFile<T>::arrayDataRead (void)
@@ -418,11 +450,18 @@ Array2dFile<T>::arrayDataRead (void)
     return (false);
   }
 
+  T** da = array.getArray();
+  if (! da) 
+      return (false);
+
   lseek (file_id, headersize, SEEK_SET);
-  for (int ix = 0; ix < nx; ix++) 
-    {
-      read (file_id, array->array_data[ix], ny * pixel_size);
-    }
+  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);
 }
@@ -436,12 +475,12 @@ Array2dFile<T>::labelSeek (unsigned int label_num)
     return (false);
   }
 
-  if (array == NULL) {    // Could not have written data if array not allocated
+  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();
+  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);
@@ -500,18 +539,25 @@ Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
 
 
 template<class T>
-bool
+void
 Array2dFile<T>::labelAdd (const char* const lstr, double calc_time=0.)
 {
   labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
 }
 
 template<class T>
-bool
+void
 Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
 {
   Array2dFileLabel label (type, lstr, calc_time);
 
+  labelAdd (label);
+}
+
+template<class T>
+void
+Array2dFile<T>::labelAdd (const Array2dFileLabel& label)
+{
   labelSeek (num_labels);
   
   write_nint16 (&label.label_type, file_id);
@@ -532,52 +578,108 @@ Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
   fsync(file_id);
 }
 
+template<class T>
+void
+Array2dFile<T>::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<class T>
+void 
+Array2dFile<T>::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;
+    }
+}
 
-#endif
 
+#ifdef HAVE_MPI
+#include <mpi++.h>
+#endif
 
-class F32Image
+class F32Image : public Array2dFile<kfloat32>
 {
 public:
-  Array2dFile<kfloat32> idf;
-
-  F32Image (const char* const fname, unsigned int nx, unsigned int ny) : idf (fname, nx, ny)
+  F32Image (const char* const fname, unsigned int nx, unsigned int ny)
+      : Array2dFile<kfloat32>::Array2dFile (fname, nx, ny)
   {
-      idf.pixel_type = Array2dFile<kfloat32>::FLOAT32;
+      setPixelType (FLOAT32);
   }
 
-  F32Image (unsigned int nx, unsigned int ny) : idf (nx, ny)
+  F32Image (unsigned int nx, unsigned int ny)
+      : Array2dFile<kfloat32>::Array2dFile (nx, ny)
   {
-      idf.pixel_type = Array2dFile<kfloat32>::FLOAT32;
+      setPixelType (FLOAT32);
   }
 
-  F32Image (const char* const fname) : idf (fname)
+  F32Image (const char* const fname)
+      : Array2dFile<kfloat32>::Array2dFile (fname)
   {
-      idf.pixel_type = Array2dFile<kfloat32>::FLOAT32;
+      setPixelType (FLOAT32);
   }
+
+#ifdef HAVE_MPI
+  MPI::Datatype getMPIDataType (void) const
+      { return MPI::FLOAT; }
+#endif
 };
 
-class F64Image 
+
+class F64Image : public Array2dFile<kfloat64>
 {
-public:
-  Array2dFile<kfloat64> idf;
+ public:
 
-  F64Image (const char* const fname, unsigned int nx, unsigned int ny) : idf (fname, nx, ny)
+  F64Image (const char* const fname, unsigned int nx, unsigned int ny)
+      : Array2dFile<kfloat64>::Array2dFile (fname, nx, ny)
   {
-      idf.pixel_type = Array2dFile<kfloat64>::FLOAT64;
+      setPixelType (FLOAT64);
   }
 
-  F64Image (unsigned int nx, unsigned int ny) : idf (nx, ny)
+  F64Image (unsigned int nx, unsigned int ny)
+      : Array2dFile<kfloat64>::Array2dFile (nx, ny)
   {
-      idf.pixel_type = Array2dFile<kfloat64>::FLOAT64;
+      setPixelType (FLOAT64);
   }
 
-  F64Image (const char* const fname) : idf (fname)
+  F64Image (const char* const fname)
+      : Array2dFile<kfloat64>::Array2dFile (fname)
   {
-      idf.pixel_type = Array2dFile<kfloat64>::FLOAT64;
+      setPixelType (FLOAT64);
   }
+
+#ifdef HAVE_MPI
+  MPI::Datatype getMPIDataType (void) const
+      { return MPI::DOUBLE; }
+#endif
 };
 
-typedef F64Image ImageFile;
+#define IMAGEFILE_64_BITS 1
+#ifdef IMAGEFILE_64_BITS
+typedef F64Image   ImageFile;
+typedef kfloat64   ImageFileValue;
+typedef kfloat64*  ImageFileColumn;
+typedef kfloat64** ImageFileArray;
+#else
+typedef F32Image   ImageFile;
+typedef kfloat32   ImageFileValue;
+typedef kfloat32*  ImageFileColumn;
+typedef kfloat32** ImageFileArray;
+#endif
+
+#endif
+