Repository: InsightSoftwareConsortium/ITK (language: python)

Issue:
MetaIO 2024-06-20 (eb952d5b)
Code extracted from:

    https://github.com/Kitware/MetaIO.git

at commit eb952d5b2dbbccc27a99cc1b4cb27410f5267981 (master).

Extensive (yet backward compatible) changes to MetaIO to fix support for SpatialObjects and support UTF-8 filenames.

See https://github.com/Kitware/MetaIO/issues/127 and https://github.com/Kitware/MetaIO/issues/68


MetaIO 2024-06-20 (eb952d5b)
Code extracted from:

    https://github.com/Kitware/MetaIO.git

at commit eb952d5b2dbbccc27a99cc1b4cb27410f5267981 (master).

Extensive (yet backward compatible) changes to MetaIO to fix support for SpatialObjects and support UTF-8 filenames.

See https://github.com/Kitware/MetaIO/issues/127 and https://github.com/Kitware/MetaIO/issues/68




Discussion / hints:

Fix patch:
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/CMakeLists.txt b/Modules/ThirdParty/MetaIO/src/MetaIO/src/CMakeLists.txt
index a3535174409..c3dcf4f510c 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/CMakeLists.txt
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/CMakeLists.txt
@@ -122,16 +122,15 @@ else ()
     ${sources}
     ${headers}
   )
+  if (METAIO_FOR_ITK)
+    target_link_libraries(${METAIO_TARGET} PUBLIC
+      itksys
+    )
+  endif (METAIO_FOR_ITK)
 endif ()
 
 include_regular_expression("^.*$")
 
-# Need nsl to resolve gethostbyname on SunOS-5.8
-# and socket also
-if(CMAKE_SYSTEM MATCHES "SunOS.*")
-  target_link_libraries(${METAIO_TARGET} PRIVATE socket nsl)
-endif()
-
 target_link_libraries(${METAIO_TARGET} PUBLIC
   ${METAIO_LIBXML2_LIBRARIES}
   ${METAIO_ZLIB_LIBRARIES}
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/localMetaConfiguration.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/localMetaConfiguration.h
index 7b3ee3cd3b7..662bee389a6 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/localMetaConfiguration.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/localMetaConfiguration.h
@@ -21,26 +21,30 @@
 
 #include "metaIOConfig.h"
 
-#if defined(METAIO_FOR_ITK) || !defined(METAIO_FOR_VTK)
+#if defined(METAIO_FOR_ITK)
 // ITK
 
 #  define METAIO_USE_NAMESPACE 0
 #  define METAIO_NAMESPACE ITKMetaIO
+#  define METAIO_STREAM itksys
 
-#  include "itk_zlib.h"
+#  include <itksys/FStream.hxx>
+#  include <itk_zlib.h>
 
 #  include <iostream>
 #  include <fstream>
 
 #  define METAIO_EXPORT
 
-#else
+#elif defined(METAIO_FOR_VTK)
 // VTK
 
 #  define METAIO_USE_NAMESPACE 1
 #  define METAIO_NAMESPACE vtkmetaio
+#  define METAIO_STREAM vtksys
 
-#  include "vtk_zlib.h"
+#  include <vtksys/FStream.hxx>
+#  include <vtk_zlib.h>
 
 #  include <iostream>
 #  include <fstream>
@@ -57,5 +61,18 @@
 #    define METAIO_EXPORT
 #  endif
 
-// end VTK/ITK
+#else
+// Independent of ITK and VTK
+
+#  define METAIO_USE_NAMESPACE 0
+#  define METAIO_NAMESPACE metaio
+#  define METAIO_STREAM std
+
+#  include "itk_zlib.h"
+
+#  include <iostream>
+#  include <fstream>
+
+#  define METAIO_EXPORT
+
 #endif
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.cxx
index 797fec06592..9c42c127dde 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.cxx
@@ -552,13 +552,9 @@ MetaArray::CanRead(const char * _headerName) const
   }
 
   // Now check the file content
-  std::ifstream inputStream;
+  METAIO_STREAM::ifstream inputStream;
 
-#ifdef __sgi
-  inputStream.open(_headerName, std::ios::in);
-#else
   inputStream.open(_headerName, std::ios::in | std::ios::binary);
-#endif
 
   if (!inputStream.rdbuf()->is_open())
   {
@@ -581,13 +577,9 @@ MetaArray::Read(const char * _headerName, bool _readElements, void * _elementDat
     m_FileName = _headerName;
   }
 
-  auto * tmpStream = new std::ifstream;
+  auto * tmpStream = new METAIO_STREAM::ifstream;
 
-#ifdef __sgi
-  tmpStream->open(m_FileName, std::ios::in);
-#else
-  tmpStream->open(m_FileName, std::ios::in | std::ios::binary);
-#endif
+  tmpStream->open(m_FileName.c_str(), std::ios::in | std::ios::binary);
 
   if (!tmpStream->rdbuf()->is_open())
   {
@@ -612,7 +604,7 @@ MetaArray::Read(const char * _headerName, bool _readElements, void * _elementDat
 
 
 bool
-MetaArray::CanReadStream(std::ifstream * _stream) const
+MetaArray::CanReadStream(METAIO_STREAM::ifstream * _stream) const
 {
   if (!strncmp(MET_ReadForm(*_stream).c_str(), "Array", 5))
   {
@@ -622,7 +614,7 @@ MetaArray::CanReadStream(std::ifstream * _stream) const
 }
 
 bool
-MetaArray::ReadStream(std::ifstream * _stream, bool _readElements, void * _elementDataBuffer, bool _autoFreeElementData)
+MetaArray::ReadStream(METAIO_STREAM::ifstream * _stream, bool _readElements, void * _elementDataBuffer, bool _autoFreeElementData)
 {
   META_DEBUG_PRINT( "MetaArray: ReadStream" );
 
@@ -671,13 +663,9 @@ MetaArray::ReadStream(std::ifstream * _stream, bool _readElements, void * _eleme
       {
         fName = m_ElementDataFileName;
       }
-      auto * readStreamTemp = new std::ifstream;
+      auto * readStreamTemp = new METAIO_STREAM::ifstream;
 
-#ifdef __sgi
-      readStreamTemp->open(fName, std::ios::in);
-#else
-      readStreamTemp->open(fName, std::ios::binary | std::ios::in);
-#endif
+      readStreamTemp->open(fName.c_str(), std::ios::binary | std::ios::in);
       if (!readStreamTemp->rdbuf()->is_open())
       {
         std::cout << "MetaArray: Read: Cannot open data file" << '\n';
@@ -756,19 +744,9 @@ MetaArray::Write(const char * _headName, const char * _dataName, bool _writeElem
     }
   }
 
-  auto * tmpWriteStream = new std::ofstream;
+  auto * tmpWriteStream = new METAIO_STREAM::ofstream;
 
-// Some older sgi compilers have a error in the ofstream constructor
-// that requires a file to exist for output
-#ifdef __sgi
-  {
-    std::ofstream tFile(m_FileName, std::ios::out);
-    tFile.close();
-  }
-  tmpWriteStream->open(m_FileName, std::ios::out);
-#else
-  tmpWriteStream->open(m_FileName, std::ios::binary | std::ios::out);
-#endif
+  tmpWriteStream->open(m_FileName.c_str(), std::ios::binary | std::ios::out);
 
   if (!tmpWriteStream->rdbuf()->is_open())
   {
@@ -795,7 +773,7 @@ MetaArray::Write(const char * _headName, const char * _dataName, bool _writeElem
 }
 
 bool
-MetaArray::WriteStream(std::ofstream * _stream, bool _writeElements, const void * _constElementData)
+MetaArray::WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements, const void * _constElementData)
 {
   if (m_WriteStream != nullptr)
   {
@@ -989,7 +967,7 @@ MetaArray::M_Read()
 }
 
 bool
-MetaArray::M_ReadElements(std::ifstream * _fstream, void * _data, int _dataQuantity)
+MetaArray::M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data, int _dataQuantity)
 {
   META_DEBUG_PRINT( "MetaArray: M_ReadElements" );
 
@@ -1044,10 +1022,10 @@ MetaArray::M_ReadElements(std::ifstream * _fstream, void * _data, int _dataQuant
 }
 
 bool
-MetaArray::M_WriteElements(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
+MetaArray::M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
 {
   bool            localData;
-  std::ofstream * tmpWriteStream;
+  METAIO_STREAM::ofstream * tmpWriteStream;
   if (m_ElementDataFileName == "LOCAL")
   {
     localData = true;
@@ -1056,7 +1034,7 @@ MetaArray::M_WriteElements(std::ofstream * _fstream, const void * _data, std::st
   else
   {
     localData = false;
-    tmpWriteStream = new std::ofstream;
+    tmpWriteStream = new METAIO_STREAM::ofstream;
 
     std::string dataFileName;
     std::string pathName;
@@ -1070,17 +1048,7 @@ MetaArray::M_WriteElements(std::ofstream * _fstream, const void * _data, std::st
       dataFileName = m_ElementDataFileName;
     }
 
-// Some older sgi compilers have a error in the ofstream constructor
-// that requires a file to exist for output
-#ifdef __sgi
-    {
-      std::ofstream tFile(dataFileName, std::ios::out);
-      tFile.close();
-    }
-    tmpWriteStream->open(dataFileName, std::ios::out);
-#else
-    tmpWriteStream->open(dataFileName, std::ios::binary | std::ios::out);
-#endif
+    tmpWriteStream->open(dataFileName.c_str(), std::ios::binary | std::ios::out);
   }
 
   if (!m_BinaryData)
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.h
index b50abaf120b..7fd42ed7c66 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArray.h
@@ -159,10 +159,10 @@ class METAIO_EXPORT MetaArray : public MetaForm
        bool         _autoFreeElementData = false);
 
   virtual bool
-  CanReadStream(std::ifstream * _stream) const;
+  CanReadStream(METAIO_STREAM::ifstream * _stream) const;
 
   virtual bool
-  ReadStream(std::ifstream * _stream,
+  ReadStream(METAIO_STREAM::ifstream * _stream,
              bool            _readElements = true,
              void *          _elementDataBuffer = nullptr,
              bool            _autoFreeElementData = false);
@@ -174,7 +174,7 @@ class METAIO_EXPORT MetaArray : public MetaForm
         const void * _constElementData = nullptr);
 
   virtual bool
-  WriteStream(std::ofstream * _stream, bool _writeElements = true, const void * _constElementData = nullptr);
+  WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements = true, const void * _constElementData = nullptr);
 
   // PROTECTED
 protected:
@@ -205,10 +205,10 @@ class METAIO_EXPORT MetaArray : public MetaForm
   M_Read() override;
 
   bool
-  M_ReadElements(std::ifstream * _fstream, void * _data, int _dataQuantity);
+  M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data, int _dataQuantity);
 
   bool
-  M_WriteElements(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
+  M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
 };
 
 #  if (METAIO_USE_NAMESPACE)
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.cxx
index da1273c5c5e..0aaefe28770 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.cxx
@@ -50,7 +50,7 @@ MetaArrow::MetaArrow(unsigned int dim)
 {
   META_DEBUG_PRINT( "MetaArrow()" );
   MetaArrow::Clear();
-  m_NDims = dim;
+  MetaObject::InitializeEssential(dim);
 }
 
 //
@@ -64,11 +64,17 @@ void
 MetaArrow::PrintInfo() const
 {
   MetaObject::PrintInfo();
-  std::cout << "Length = " << M_Length << '\n';
+  std::cout << "Length = " << m_Length << '\n';
+  std::cout << "Position = ";
+  for (int i = 0; i < m_NDims; i++)
+  {
+    std::cout << m_Position[i] << " ";
+  }
+  std::cout << '\n';
   std::cout << "Direction = ";
   for (int i = 0; i < m_NDims; i++)
   {
-    std::cout << M_Direction[i] << " ";
+    std::cout << m_Direction[i] << " ";
   }
   std::cout << '\n';
 }
@@ -91,11 +97,16 @@ MetaArrow::CopyInfo(const MetaObject * _object)
     }
     if (arrow)
     {
-      M_Length = arrow->Length();
+      m_Length = arrow->Length();
       const double * direction = arrow->Direction();
       for (int i = 0; i < m_NDims; i++)
       {
-        M_Direction[i] = direction[i];
+        m_Direction[i] = direction[i];
+      }
+      const double * position = arrow->Position();
+      for (int i = 0; i < m_NDims; i++)
+      {
+        m_Position[i] = position[i];
       }
     }
   }
@@ -105,13 +116,13 @@ MetaArrow::CopyInfo(const MetaObject * _object)
 void
 MetaArrow::Length(float length)
 {
-  M_Length = length;
+  m_Length = length;
 }
 
 float
 MetaArrow::Length() const
 {
-  return M_Length;
+  return m_Length;
 }
 
 void
@@ -119,14 +130,69 @@ MetaArrow::Direction(const double * direction)
 {
   for (int i = 0; i < m_NDims; i++)
   {
-    M_Direction[i] = direction[i];
+    m_Direction[i] = direction[i];
   }
 }
 
 const double *
 MetaArrow::Direction() const
 {
-  return M_Direction;
+  return m_Direction;
+}
+
+const double *
+MetaArrow::Position() const
+{
+  if (m_APIVersion == 1)
+  {
+    return m_Position;
+  }
+  else
+  {
+    return MetaObject::Position();
+  }
+}
+
+double
+MetaArrow::Position(int _i) const
+{
+  if (m_APIVersion == 1)
+  {
+    return m_Position[_i];
+  }
+  else
+  {
+    return MetaObject::Position(_i);
+  }
+}
+
+void
+MetaArrow::Position(const double * position)
+{
+  if (m_APIVersion == 1)
+  {
+    for (int i = 0; i < m_NDims; i++)
+    {
+      m_Position[i] = position[i];
+    }
+  }
+  else
+  {
+    MetaObject::Position(position);
+  }
+}
+
+void
+MetaArrow::Position(int _i, double value)
+{
+  if (m_APIVersion == 1)
+  {
+    m_Position[_i] = value;
+  }
+  else
+  {
+    MetaObject::Position(_i, value);
+  }
 }
 
 /** Clear Arrow information */
@@ -138,11 +204,13 @@ MetaArrow::Clear()
 
   strcpy(m_ObjectTypeName, "Arrow");
 
-  M_Length = 1;
+  m_Length = 1;
 
   // zero out direction then set to (1,0,0)
-  memset(M_Direction, 0, 10 * sizeof(double));
-  M_Direction[0] = 1.0;
+  memset(m_Direction, 0, 10 * sizeof(double));
+  m_Direction[0] = 1.0;
+
+  memset(m_Position, 0, 10 * sizeof(double));
 }
 
 /** Set Read fields */
@@ -162,6 +230,10 @@ MetaArrow::M_SetupReadFields()
 
   int nDimsRecordNumber = MET_GetFieldRecordNumber("NDims", &m_Fields);
 
+  mF = new MET_FieldRecordType;
+  MET_InitReadField(mF, "Position", MET_DOUBLE_ARRAY, false, nDimsRecordNumber);
+  m_Fields.push_back(mF);
+
   mF = new MET_FieldRecordType;
   MET_InitReadField(mF, "Direction", MET_DOUBLE_ARRAY, true, nDimsRecordNumber);
   mF->terminateRead = true;
@@ -176,15 +248,21 @@ MetaArrow::M_SetupWriteFields()
   MET_FieldRecordType * mF;
 
   mF = new MET_FieldRecordType;
-  MET_InitWriteField(mF, "Length", MET_FLOAT, M_Length);
+  MET_InitWriteField(mF, "Length", MET_FLOAT, m_Length);
   m_Fields.push_back(mF);
 
+  if (m_APIVersion == 1)
+  {
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "Position", MET_DOUBLE_ARRAY, static_cast<size_t>(m_NDims), m_Position);
+    m_Fields.push_back(mF);
+  }
+
   mF = new MET_FieldRecordType;
-  MET_InitWriteField(mF, "Direction", MET_DOUBLE_ARRAY, static_cast<size_t>(m_NDims), M_Direction);
+  MET_InitWriteField(mF, "Direction", MET_DOUBLE_ARRAY, static_cast<size_t>(m_NDims), m_Direction);
   m_Fields.push_back(mF);
 }
 
-
 bool
 MetaArrow::M_Read()
 {
@@ -198,20 +276,57 @@ MetaArrow::M_Read()
 
   META_DEBUG_PRINT( "MetaArrow: M_Read: Parsing Header" );
 
-  MET_FieldRecordType * mF_length;
-  mF_length = MET_GetFieldRecord("Length", &m_Fields);
-  if (mF_length->defined)
+  MET_FieldRecordType * mF;
+  mF = MET_GetFieldRecord("Length", &m_Fields);
+  if (mF && mF->defined)
+  {
+    m_Length = static_cast<float>(mF->value[0]);
+  }
+
+  mF = MET_GetFieldRecord("Position", &m_Fields);
+  if (mF && mF->defined)
   {
-    M_Length = static_cast<float>(mF_length->value[0]);
+    if (m_APIVersion == 1)
+    {
+      for (int i = 0; i < m_NDims; i++)
+      {
+        m_Position[i] = mF->value[i];
+      }
+      if (m_FileFormatVersion == 0)
+      {
+        for (int i = 0; i < m_NDims; i++)
+        {
+          m_Offset[i] = 0;
+        }
+      }
+    }
+  }
+  else
+  {
+    if (m_FileFormatVersion == 1)
+    {
+      std::cout << "MetaArrow: M_Read: Position not found" << '\n';
+      return false;
+    }
+    else // Old file format
+    {
+      if (m_APIVersion == 1) // new API - move offset to position
+      {
+        for (int i = 0; i < m_NDims; i++)
+        {
+          m_Position[i] = m_Offset[i];
+          m_Offset[i] = 0;
+        }
+      }
+    }
   }
 
-  MET_FieldRecordType * mF_direction;
-  mF_direction = MET_GetFieldRecord("Direction", &m_Fields);
-  if (mF_direction->defined)
+  mF = MET_GetFieldRecord("Direction", &m_Fields);
+  if (mF && mF->defined)
   {
     for (int i = 0; i < m_NDims; i++)
     {
-      M_Direction[i] = mF_direction->value[i];
+      m_Direction[i] = mF->value[i];
     }
   }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.h
index 7cfdbcf6f73..727f097fa14 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaArrow.h
@@ -85,6 +85,15 @@ class METAIO_EXPORT MetaArrow : public MetaObject
   const double *
   Direction() const;
 
+  const double *
+  Position() const override;
+  double
+  Position(int _i) const override;
+  void
+  Position(const double * position) override;
+  void
+  Position(int _i, double _value) override;
+
 
   // PROTECTED
 protected:
@@ -97,9 +106,11 @@ class METAIO_EXPORT MetaArrow : public MetaObject
   bool
   M_Read() override;
 
-  float M_Length{1.0}; // default 1.0
+  float m_Length{1.0}; // default 1.0
+
+  double m_Direction[10]{};
 
-  double M_Direction[10]{};
+  double m_Position[10]{};
 };
 
 #  if (METAIO_USE_NAMESPACE)
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaBlob.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaBlob.cxx
index cfa402d486a..52ee7b315f9 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaBlob.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaBlob.cxx
@@ -245,20 +245,20 @@ MetaBlob::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("NPoints", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NPoints = static_cast<size_t>(mF->value[0]);
   }
 
   mF = MET_GetFieldRecord("ElementType", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
   }
 
 
   mF = MET_GetFieldRecord("PointDim", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     strcpy(m_PointDim, reinterpret_cast<char *>(mF->value));
   }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaCommand.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaCommand.cxx
index c82ebc4d070..731e9779e03 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaCommand.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaCommand.cxx
@@ -1363,7 +1363,7 @@ MetaCommand::ExportGAD(bool dynamic)
   std::string filename = m_Name;
   filename += ".gad.xml";
 
-  std::ofstream file;
+  METAIO_STREAM::ofstream file;
 #ifdef __sgi
   file.open(filename.c_str(), std::ios::out);
 #else
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaContour.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaContour.cxx
index 498f4864478..b2b55243e54 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaContour.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaContour.cxx
@@ -338,7 +338,7 @@ MetaContour::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("Closed", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     if (mF->value[0] != 0.0)
     {
@@ -347,7 +347,7 @@ MetaContour::M_Read()
   }
 
   mF = MET_GetFieldRecord("DisplayOrientation", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     if (mF->value[0] != 0.0)
     {
@@ -356,7 +356,7 @@ MetaContour::M_Read()
   }
 
   mF = MET_GetFieldRecord("PinToSlice", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     if (mF->value[0] != 0.0)
     {
@@ -365,13 +365,13 @@ MetaContour::M_Read()
   }
 
   mF = MET_GetFieldRecord("NControlPoints", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NControlPoints = static_cast<int>(mF->value[0]);
   }
 
   mF = MET_GetFieldRecord("ControlPointDim", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     strcpy(m_ControlPointDim, reinterpret_cast<char *>(mF->value));
   }
@@ -690,7 +690,7 @@ MetaContour::M_Read()
       delete[] v;
 
       char c = ' ';
-      while ((c != '\n') && (!m_ReadStream->eof()))
+      while ((c != '\n') && (c != -1) && (!m_ReadStream->eof()))
       {
         c = static_cast<char>(m_ReadStream->get()); // to avoid unrecognize charactere
       }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaEllipse.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaEllipse.cxx
index 779d174283e..db60b5cfb15 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaEllipse.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaEllipse.cxx
@@ -188,7 +188,7 @@ MetaEllipse::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("Radius", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     for (int i = 0; i < m_NDims; i++)
     {
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.cxx
index 8ce1224933b..1eaca976163 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.cxx
@@ -546,12 +546,8 @@ MetaForm::Read(const char * _fileName)
 
   std::cout << "Read FileName = _" << m_FileName << "_" << '\n';
 
-  auto * tmpReadStream = new std::ifstream;
-#ifdef __sgi
-  tmpReadStream->open(m_FileName, std::ios::in);
-#else
-  tmpReadStream->open(m_FileName, std::ios::binary | std::ios::in);
-#endif
+  auto * tmpReadStream = new METAIO_STREAM::ifstream;
+  tmpReadStream->open(m_FileName.c_str(), std::ios::binary | std::ios::in);
 
   if (!tmpReadStream->rdbuf()->is_open())
   {
@@ -576,7 +572,7 @@ MetaForm::Read(const char * _fileName)
 }
 
 bool
-MetaForm::CanReadStream(std::ifstream * _stream)
+MetaForm::CanReadStream(METAIO_STREAM::ifstream * _stream)
 {
   if (_stream)
   {
@@ -589,7 +585,7 @@ MetaForm::CanReadStream(std::ifstream * _stream)
 }
 
 bool
-MetaForm::ReadStream(std::ifstream * _stream)
+MetaForm::ReadStream(METAIO_STREAM::ifstream * _stream)
 {
   META_DEBUG_PRINT( "MetaForm: ReadStream" );
 
@@ -623,18 +619,9 @@ MetaForm::Write(const char * _fileName)
 
   std::cout << "Write FileName = _" << m_FileName << "_" << '\n';
 
-  auto * tmpWriteStream = new std::ofstream;
+  auto * tmpWriteStream = new METAIO_STREAM::ofstream;
 
-#ifdef __sgi
-  {
-    // Create the file. This is required on some older sgi's
-    std::ofstream tFile(m_FileName, std::ios::out);
-    tFile.close();
-  }
-  tmpWriteStream->open(m_FileName, std::ios::out);
-#else
-  tmpWriteStream->open(m_FileName, std::ios::binary | std::ios::out);
-#endif
+  tmpWriteStream->open(m_FileName.c_str(), std::ios::binary | std::ios::out);
 
   if (!tmpWriteStream->rdbuf()->is_open())
   {
@@ -653,7 +640,7 @@ MetaForm::Write(const char * _fileName)
 }
 
 bool
-MetaForm::WriteStream(std::ofstream * _stream)
+MetaForm::WriteStream(METAIO_STREAM::ofstream * _stream)
 {
   M_SetupWriteFields();
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.h
index 21938c4719f..818c490813d 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaForm.h
@@ -159,23 +159,23 @@ class METAIO_EXPORT MetaForm
   Read(const char * _fileName = nullptr);
 
   static bool
-  CanReadStream(std::ifstream * _stream) ;
+  CanReadStream(METAIO_STREAM::ifstream * _stream) ;
 
   bool
-  ReadStream(std::ifstream * _stream);
+  ReadStream(METAIO_STREAM::ifstream * _stream);
 
   bool
   Write(const char * _fileName = nullptr);
 
   bool
-  WriteStream(std::ofstream * _stream);
+  WriteStream(METAIO_STREAM::ofstream * _stream);
 
   // PROTECTED
 protected:
   typedef std::vector<MET_FieldRecordType *> FieldsContainerType;
 
-  std::ifstream * m_ReadStream;
-  std::ofstream * m_WriteStream;
+  METAIO_STREAM::ifstream * m_ReadStream;
+  METAIO_STREAM::ofstream * m_WriteStream;
 
   std::string m_FileName;
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.cxx
index 10a06909234..5940e6def79 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.cxx
@@ -35,42 +35,21 @@ namespace
 {
 
 void
-openReadStream(std::ifstream & inputStream, const std::string & fname)
+openReadStream(METAIO_STREAM::ifstream & inputStream, const std::string & fname)
 {
-#ifdef __sgi
-  inputStream.open(fname, std::ios::in);
-#else
-  inputStream.open(fname, std::ios::in | std::ios::binary);
-#endif
+  inputStream.open(fname.c_str(), std::ios::in | std::ios::binary);
 }
 
 void
-openWriteStream(std::ofstream & outputStream, const std::string & fname, bool append)
+openWriteStream(METAIO_STREAM::ofstream & outputStream, const std::string & fname, bool append)
 {
-// Some older sgi compilers have a error in the ofstream constructor
-// that requires a file to exist for output
-#ifdef __sgi
-  {
-    std::ofstream tFile(fname, std::ios::out);
-    tFile.close();
-  }
-#endif
-
   if (!append)
   {
-#ifdef __sgi
-    outputStream.open(fname, std::ios::out);
-#else
-    outputStream.open(fname, std::ios::binary | std::ios::out);
-#endif
+    outputStream.open(fname.c_str(), std::ios::binary | std::ios::out);
   }
   else
   {
-#ifdef __sgi
-    outputStream.open(fname, std::ios::app | std::ios::out);
-#else
-    outputStream.open(fname, std::ios::binary | std::ios::app | std::ios::out);
-#endif
+    outputStream.open(fname.c_str(), std::ios::binary | std::ios::app | std::ios::out);
   }
 }
 
@@ -318,6 +297,20 @@ MetaImage::PrintInfo() const
   }
   std::cout << '\n';
 
+  std::cout << "ElementOrigin = ";
+  for (i = 0; i < m_NDims; i++)
+  {
+    std::cout << m_ElementOrigin[i] << " ";
+  }
+  std::cout << '\n';
+
+  std::cout << "ElementDirection = ";
+  for (i = 0; i < m_NDims*m_NDims; i++)
+  {
+    std::cout << m_ElementDirection[i] << " ";
+  }
+  std::cout << '\n';
+
   std::cout << "ElementSizeValid = " << static_cast<int>(m_ElementSizeValid) << '\n';
   std::cout << "ElementSize = ";
   for (i = 0; i < m_NDims; i++)
@@ -385,6 +378,9 @@ MetaImage::CopyInfo(const MetaObject * _object)
         ElementSize(im->ElementSize());
       }
 
+      ElementDirection(im->ElementDirection());
+      ElementOrigin(im->ElementOrigin());
+
       ElementMinMaxValid(im->ElementMinMaxValid());
       if (im->ElementMinMaxValid())
       {
@@ -412,6 +408,13 @@ MetaImage::Clear()
 
   m_HeaderSize = 0;
 
+  memset(m_ElementOrigin, 0, sizeof(m_ElementOrigin));
+  memset(m_ElementDirection, 0, sizeof(m_ElementDirection));
+  for (int i = 0; i < m_NDims; i++)
+  {
+    m_ElementDirection[i*m_NDims+i] = 1;
+  }
+
   memset(m_SequenceID, 0, sizeof(m_SequenceID));
 
   m_ElementSizeValid = false;
@@ -467,7 +470,8 @@ MetaImage::InitializeEssential(int               _nDims,
                                MET_ValueEnumType _elementType,
                                int               _elementNumberOfChannels,
                                void *            _elementData,
-                               bool              _allocElementMemory)
+                               bool              _allocElementMemory,
+                               bool              _initializePosition)
 {
   // Only consider at most 10 element of spacing:
   // See MetaObject::InitializeEssential(_nDims)
@@ -478,7 +482,7 @@ MetaImage::InitializeEssential(int               _nDims,
     tmpElementSpacing[i] = static_cast<double>(_elementSpacing[i]);
   }
   return InitializeEssential(
-    _nDims, _dimSize, tmpElementSpacing, _elementType, _elementNumberOfChannels, _elementData, _allocElementMemory);
+    _nDims, _dimSize, tmpElementSpacing, _elementType, _elementNumberOfChannels, _elementData, _allocElementMemory, _initializePosition);
 }
 
 bool
@@ -488,11 +492,19 @@ MetaImage::InitializeEssential(int               _nDims,
                                MET_ValueEnumType _elementType,
                                int               _elementNumberOfChannels,
                                void *            _elementData,
-                               bool              _allocElementMemory)
+                               bool              _allocElementMemory,
+                               bool              _initializePosition)
 {
   META_DEBUG_PRINT( "MetaImage: Initialize" );
 
-  MetaObject::InitializeEssential(_nDims);
+  if (_nDims != m_NDims)
+  {
+    // This conditional avoids overwriting _elementSpacing when
+    //   InitializeEssential is called using m_ElementSpacing as
+    //   an argument (that is passed by reference). MetaObject::InitializeEssential
+    //   overwrites m_ElementSpacing with 1s.
+    MetaObject::InitializeEssential(_nDims);
+  }
 
   int i;
   if (!m_CompressionTable)
@@ -503,7 +515,10 @@ MetaImage::InitializeEssential(int               _nDims,
   }
   m_SubQuantity[0] = 1;
   m_Quantity = 1;
-  m_ElementSizeValid = false;
+  m_ElementType = _elementType;
+  m_ElementNumberOfChannels = _elementNumberOfChannels;
+
+  m_ElementSizeValid = true;
   for (i = 0; i < m_NDims; i++)
   {
     m_DimSize[i] = _dimSize[i];
@@ -516,17 +531,28 @@ MetaImage::InitializeEssential(int               _nDims,
     if (m_ElementSize[i] == 0)
     {
       m_ElementSize[i] = m_ElementSpacing[i];
+      m_ElementSizeValid = false;
     }
-    else
+  }
+  if (_initializePosition)
+  {
+    for (i = 0; i < m_NDims; i++)
     {
-      m_ElementSizeValid = true;
-    }
+      m_ElementOrigin[i] = 0;
+      for (int j = 0; j < m_NDims; j++)
+      {
+        if (i != j)
+        {
+          m_ElementDirection[i*m_NDims+j] = 0;
+        }
+        else
+        {
+          m_ElementDirection[i*m_NDims+j] = 1;
+        }
+      }
+    } 
   }
 
-  m_ElementType = _elementType;
-
-  m_ElementNumberOfChannels = _elementNumberOfChannels;
-
   if (_elementData != nullptr)
   {
     m_AutoFreeElementData = false;
@@ -680,6 +706,68 @@ MetaImage::ElementSize(int _i, double _value)
   m_ElementSizeValid = true;
 }
 
+const double *
+MetaImage::ElementOrigin() const
+{
+  return m_ElementOrigin;
+}
+
+double
+MetaImage::ElementOrigin(int _i) const
+{
+  return m_ElementOrigin[_i];
+}
+
+void
+MetaImage::ElementOrigin(const double * _elementOrigin)
+{
+  memcpy(m_ElementOrigin, _elementOrigin, m_NDims * sizeof(*m_ElementOrigin));
+}
+
+void
+MetaImage::ElementOrigin(const float * _elementOrigin)
+{
+  for (int i = 0; i < m_NDims; ++i)
+  {
+    m_ElementOrigin[i] = static_cast<double>(_elementOrigin[i]);
+  }
+}
+
+
+void
+MetaImage::ElementOrigin(int _i, double _value)
+{
+  m_ElementOrigin[_i] = _value;
+}
+
+const double *
+MetaImage::ElementDirection() const
+{
+  return m_ElementDirection;
+}
+
+double
+MetaImage::ElementDirection(int _i, int _j) const
+{
+  return m_ElementDirection[_i * m_NDims + _j];
+}
+
+void
+MetaImage::ElementDirection(const double * _direction)
+{
+  int i;
+  for (i = 0; i < m_NDims * m_NDims; i++)
+  {
+    m_ElementDirection[i] = _direction[i];
+  }
+}
+
+void
+MetaImage::ElementDirection(int _i, int _j, double _value)
+{
+  m_ElementDirection[_i * m_NDims + _j] = _value;
+}
+
 MET_ValueEnumType
 MetaImage::ElementType() const
 {
@@ -1111,7 +1199,7 @@ MetaImage::CanRead(const char * _headerName)
   }
 
   // Now check the file content
-  std::ifstream inputStream;
+  METAIO_STREAM::ifstream inputStream;
 
   openReadStream(inputStream, fname);
 
@@ -1143,7 +1231,7 @@ MetaImage::CanRead(const char * _headerName)
 bool
 MetaImage::Read(const char * _headerName, bool _readElements, void * _buffer)
 {
-MetaObject::M_Destroy();
+  M_Destroy();
 
   Clear();
 
@@ -1156,7 +1244,7 @@ MetaObject::M_Destroy();
 
   M_PrepareNewReadStream();
 
-  auto * tmpReadStream = new std::ifstream;
+  auto * tmpReadStream = new METAIO_STREAM::ifstream;
 
   openReadStream(*tmpReadStream, m_FileName);
 
@@ -1181,7 +1269,7 @@ MetaObject::M_Destroy();
 }
 
 bool
-MetaImage::CanReadStream(std::ifstream * _stream)
+MetaImage::CanReadStream(METAIO_STREAM::ifstream * _stream)
 {
   if (!strncmp(MET_ReadType(*_stream).c_str(), "Image", 5))
   {
@@ -1192,7 +1280,7 @@ MetaImage::CanReadStream(std::ifstream * _stream)
 
 
 bool
-MetaImage::ReadStream(int _nDims, std::ifstream * _stream, bool _readElements, void * _buffer)
+MetaImage::ReadStream(int _nDims, METAIO_STREAM::ifstream * _stream, bool _readElements, void * _buffer)
 {
   if (!MetaObject::ReadStream(_nDims, _stream))
   {
@@ -1205,12 +1293,12 @@ MetaImage::ReadStream(int _nDims, std::ifstream * _stream, bool _readElements, v
     if (_buffer == nullptr)
     {
       InitializeEssential(
-        m_NDims, m_DimSize, m_ElementSpacing, m_ElementType, m_ElementNumberOfChannels, nullptr, true);
+        m_NDims, m_DimSize, m_ElementSpacing, m_ElementType, m_ElementNumberOfChannels, nullptr, true, false);
     }
     else
     {
       InitializeEssential(
-        m_NDims, m_DimSize, m_ElementSpacing, m_ElementType, m_ElementNumberOfChannels, _buffer, false);
+        m_NDims, m_DimSize, m_ElementSpacing, m_ElementType, m_ElementNumberOfChannels, _buffer, false, false);
     }
 
     int         i;
@@ -1249,7 +1337,7 @@ MetaImage::ReadStream(int _nDims, std::ifstream * _stream, bool _readElements, v
         fileImageDim = m_NDims - 1;
       }
       std::string s;
-      auto *      readStreamTemp = new std::ifstream;
+      auto *      readStreamTemp = new METAIO_STREAM::ifstream;
       int         elementSize;
       MET_SizeOfType(m_ElementType, &elementSize);
       elementSize *= m_ElementNumberOfChannels;
@@ -1310,7 +1398,7 @@ MetaImage::ReadStream(int _nDims, std::ifstream * _stream, bool _readElements, v
       int         maxV = m_DimSize[m_NDims - 1];
       int         stepV = 1;
       std::string s;
-      auto *      readStreamTemp = new std::ifstream;
+      auto *      readStreamTemp = new METAIO_STREAM::ifstream;
       MET_StringToWordArray(m_ElementDataFileName.c_str(), &nWrds, &wrds);
       if (nWrds >= 2)
       {
@@ -1422,7 +1510,7 @@ MetaImage::ReadStream(int _nDims, std::ifstream * _stream, bool _readElements, v
         fName = m_ElementDataFileName;
       }
 
-      auto * readStreamTemp = new std::ifstream;
+      auto * readStreamTemp = new METAIO_STREAM::ifstream;
 
       const char * extensions[] = { "", ".gz", ".Z", nullptr };
       for (unsigned ii = 0; extensions[ii] != nullptr; ii++)
@@ -1537,7 +1625,7 @@ MetaImage::Write(const char * _headName,
     }
   }
 
-  auto * tmpWriteStream = new std::ofstream;
+  auto * tmpWriteStream = new METAIO_STREAM::ofstream;
 
   openWriteStream(*tmpWriteStream, m_FileName, _append);
 
@@ -1567,7 +1655,7 @@ MetaImage::Write(const char * _headName,
 }
 
 bool
-MetaImage::WriteStream(std::ofstream * _stream, bool _writeElements, const void * _constElementData)
+MetaImage::WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements, const void * _constElementData)
 {
   if (m_WriteStream != nullptr)
   {
@@ -1675,8 +1763,8 @@ MetaImage::WriteROI(int *        _indexMin,
     }
 
     // Find the start of the data
-    auto * readStream = new std::ifstream;
-    readStream->open(m_FileName, std::ios::binary | std::ios::in);
+    auto * readStream = new METAIO_STREAM::ifstream;
+    readStream->open(m_FileName.c_str(), std::ios::binary | std::ios::in);
 
     // File must be readable
     if (!MetaObject::ReadStream(m_NDims, readStream))
@@ -1731,7 +1819,7 @@ MetaImage::WriteROI(int *        _indexMin,
       filename = pathName + filename;
     }
 
-    auto * tmpWriteStream = new std::ofstream;
+    auto * tmpWriteStream = new METAIO_STREAM::ofstream;
     tmpWriteStream->open(filename.c_str(), std::ios::binary | std::ios::in | std::ios::out);
 
     if (!tmpWriteStream->is_open())
@@ -1843,7 +1931,7 @@ MetaImage::WriteROI(int *        _indexMin,
       }
     }
 
-    auto * tmpWriteStream = new std::ofstream;
+    auto * tmpWriteStream = new METAIO_STREAM::ofstream;
 
     openWriteStream(*tmpWriteStream, m_FileName, _append);
 
@@ -1927,7 +2015,7 @@ MetaImage::WriteROI(int *        _indexMin,
 }
 
 bool
-MetaImage::M_WriteElementsROI(std::ofstream * _fstream,
+MetaImage::M_WriteElementsROI(METAIO_STREAM::ofstream * _fstream,
                               const void *    _data,
                               std::streampos  _dataPos,
                               const int *     _indexMin,
@@ -2038,7 +2126,7 @@ MetaImage::M_ResetValues()
   delete m_CompressionTable;
   m_CompressionTable = nullptr;
 
-  MetaObject::M_Destroy();
+  M_Destroy();
 }
 
 void
@@ -2054,7 +2142,6 @@ MetaImage::M_SetupReadFields()
 
   mF = new MET_FieldRecordType;
   MET_InitReadField(mF, "DimSize", MET_INT_ARRAY, true, nDimsRecNum);
-  mF->required = true;
   m_Fields.push_back(mF);
 
   mF = new MET_FieldRecordType;
@@ -2069,6 +2156,19 @@ MetaImage::M_SetupReadFields()
   MET_InitReadField(mF, "ImagePosition", MET_FLOAT_ARRAY, false, nDimsRecNum);
   m_Fields.push_back(mF);
 
+  bool fieldRequired = false;
+  if (m_FileFormatVersion == 1)
+  {
+    fieldRequired = true;
+  }
+  mF = new MET_FieldRecordType;
+  MET_InitReadField(mF, "ElementOrigin", MET_FLOAT_ARRAY, fieldRequired, nDimsRecNum);
+  m_Fields.push_back(mF);
+
+  mF = new MET_FieldRecordType;
+  MET_InitReadField(mF, "ElementDirection", MET_FLOAT_MATRIX, fieldRequired, nDimsRecNum);
+  m_Fields.push_back(mF);
+
   mF = new MET_FieldRecordType;
   MET_InitReadField(mF, "SequenceID", MET_INT_ARRAY, false, nDimsRecNum);
   m_Fields.push_back(mF);
@@ -2089,7 +2189,7 @@ MetaImage::M_SetupReadFields()
   MET_InitReadField(mF, "ElementSize", MET_FLOAT_ARRAY, false, nDimsRecNum);
   m_Fields.push_back(mF);
 
-  mF = new MET_FieldRecordType; // Set but not used...
+  mF = new MET_FieldRecordType; // Handled as with DICOM: set, but not used...
   MET_InitReadField(mF, "ElementNBits", MET_INT, false);
   m_Fields.push_back(mF);
 
@@ -2166,6 +2266,67 @@ MetaImage::M_SetupWriteFields()
     m_Fields.push_back(mF);
   }
 
+  // Determine if new API was used...
+  if (m_APIVersion == 0)
+  {
+    // Using old API, and writing old format
+    for (i = 0; i < m_NDims; i++)
+    {
+      if (m_ElementOrigin[i] != 0)
+      {
+        std::cout << "Warning: ElementOrigin is not supported in MetaIO API version 0" << '\n';
+        std::cout << "      ElementOrigin will not be written to file." << '\n';
+        std::cout << "      Use MetaImage::APIVersion to select API version 1 otherwise" << '\n';
+        std::cout << "      information will be lost." << '\n';
+        break;
+      }
+      for (int j = 0; j < m_NDims; j++)
+      {
+        if ((i != j && m_ElementDirection[i*m_NDims+j] != 0) ||
+            (i == j && m_ElementDirection[i*m_NDims+j] != 1 && m_ElementDirection[i*m_NDims+j] != 0))
+        {
+          std::cout << "Warning: ElementDirection is not supported in MetaIO API version 0" << '\n';
+          std::cout << "      ElementDirection will not be written to file." << '\n';
+          std::cout << "      Use MetaImage::APIVersion to select API version 1 otherwise" << '\n';
+          std::cout << "      information will be lost." << '\n';
+          i = m_NDims;
+          break;
+        }
+      }
+    }
+  }
+
+  // Dev wants to write old file format
+  if (m_FileFormatVersion == 0)
+  {
+    // Developer used old API
+    if (m_APIVersion == 0)
+    {
+      // Old behavior
+      // Do not write ElementOrigin or ElementDirection
+    }
+    else // Developer used new API, so convert to old file format
+    {
+      // Convert to old format
+      // Will result in loss of ObjectToParent transform, if used in a scene
+      mF = MET_GetFieldRecord("Offset", &m_Fields);
+      MET_InitWriteField(mF, "Offset", MET_FLOAT_ARRAY, static_cast<size_t>(m_NDims), m_ElementOrigin);
+
+      mF = MET_GetFieldRecord("TransformMatrix", &m_Fields);
+      MET_InitWriteField(mF, "TransformMatrix", MET_FLOAT_MATRIX, static_cast<size_t>(m_NDims), m_ElementDirection);
+    }
+  }
+  else // Dev wants to Write new file format, so don't change anything
+  {
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "ElementOrigin", MET_FLOAT_ARRAY, static_cast<size_t>(m_NDims), m_ElementOrigin);
+    m_Fields.push_back(mF);
+
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "ElementDirection", MET_FLOAT_MATRIX, static_cast<size_t>(m_NDims), m_ElementDirection);
+    m_Fields.push_back(mF);
+  }
+
   if (m_ElementMinMaxValid)
   {
     mF = new MET_FieldRecordType;
@@ -2225,11 +2386,10 @@ MetaImage::M_Read()
   META_DEBUG_PRINT( "MetaImage: M_Read: Parsing Header" );
   MET_FieldRecordType * mF;
 
-  META_DEBUG_PRINT( "metaImage: M_Read: elementSpacing[" << 0 << "] = " << m_ElementSpacing[0] );
+  int i;
   mF = MET_GetFieldRecord("DimSize", &m_Fields);
   if (mF && mF->defined)
   {
-    int i;
     for (i = 0; i < m_NDims; i++)
     {
       m_DimSize[i] = static_cast<int>(mF->value[i]);
@@ -2252,23 +2412,102 @@ MetaImage::M_Read()
   mF = MET_GetFieldRecord("SequenceID", &m_Fields);
   if (mF && mF->defined)
   {
-    int i;
     for (i = 0; i < m_NDims; i++)
     {
       m_SequenceID[i] = static_cast<float>(mF->value[i]);
     }
   }
 
+  // ImagePosition is not written by MetaIO library, so it is probably
+  // unused unless someone wrote a custom MetaIO writer.  Will maintain this
+  // usage/definition to maintain backward compatibility.
   mF = MET_GetFieldRecord("ImagePosition", &m_Fields);
   if (mF && mF->defined)
   {
-    int i;
     for (i = 0; i < m_NDims; i++)
     {
       m_Offset[i] = mF->value[i];
     }
   }
 
+  if (m_FileFormatVersion == 0)
+  {
+    // Old file was read, but developer wants to use the new API,
+    //   so convert old fields to new variables...
+    if (m_APIVersion == 1)
+    {
+      for (i = 0; i < m_NDims; i++)
+      {
+        m_ElementOrigin[i] = m_Offset[i];
+        m_Offset[i] = 0;
+      }
+      for (i = 0; i < m_NDims; i++)
+      {
+        for (int j = 0; j < m_NDims; j++)
+        {
+          m_ElementDirection[i*m_NDims+j] = m_TransformMatrix[i*m_NDims+j];
+          if (i != j)
+          {
+            m_TransformMatrix[i*m_NDims+j] = 0;
+          }
+          else
+          {
+            m_TransformMatrix[i*m_NDims+j] = 1;
+          }
+        }
+      }
+    }
+    // otherwise do nothing
+  }
+  else // New file was read
+  {
+    // New file was read, but developer wants to use the old API,
+    //   so convert new fields to old variables...
+    // May result in loss of ObjectToParentTransform for images that
+    //   were stored as part of a scene.
+    if (m_APIVersion == 0)
+    {
+      mF = MET_GetFieldRecord("ElementOrigin", &m_Fields);
+      if (mF && mF->defined)
+      {
+        for (i = 0; i < m_NDims; i++)
+        {
+          m_Offset[i] = mF->value[i];
+        }
+      }
+    
+      mF = MET_GetFieldRecord("ElementDirection", &m_Fields);
+      if (mF && mF->defined)
+      {
+        for (i = 0; i < m_NDims*m_NDims; i++)
+        {
+          m_TransformMatrix[i] = mF->value[i];
+        }
+      }
+    }
+    else
+    // New file was read, and developer wants to use the new API,
+    {
+      mF = MET_GetFieldRecord("ElementOrigin", &m_Fields);
+      if (mF && mF->defined)
+      {
+        for (i = 0; i < m_NDims; i++)
+        {
+          m_ElementOrigin[i] = mF->value[i];
+        }
+      }
+    
+      mF = MET_GetFieldRecord("ElementDirection", &m_Fields);
+      if (mF && mF->defined)
+      {
+        for (i = 0; i < m_NDims*m_NDims; i++)
+        {
+          m_ElementDirection[i] = mF->value[i];
+        }
+      }
+    }
+  }
+
   mF = MET_GetFieldRecord("ElementMin", &m_Fields);
   if (mF && mF->defined)
   {
@@ -2292,13 +2531,12 @@ MetaImage::M_Read()
   if (mF && mF->defined)
   {
     m_ElementSizeValid = true;
-    int i;
     for (i = 0; i < m_NDims; i++)
     {
       m_ElementSize[i] = mF->value[i];
     }
     mF = MET_GetFieldRecord("ElementSpacing", &m_Fields);
-    if (mF && !mF->defined)
+    if (!mF || !(mF->defined))
     {
       for (i = 0; i < m_NDims; i++)
       {
@@ -2308,7 +2546,6 @@ MetaImage::M_Read()
   }
   else
   {
-    int i;
     m_ElementSizeValid = false;
     for (i = 0; i < m_NDims; i++)
     {
@@ -2345,7 +2582,7 @@ MetaImage::M_Read()
 }
 
 bool
-MetaImage::M_ReadElements(std::ifstream * _fstream, void * _data, std::streamoff _dataQuantity)
+MetaImage::M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data, std::streamoff _dataQuantity)
 {
   META_DEBUG_PRINT( "MetaImage: M_ReadElements" );
 
@@ -2424,7 +2661,7 @@ MetaImage::M_ReadElements(std::ifstream * _fstream, void * _data, std::streamoff
 }
 
 bool
-MetaImage::M_WriteElements(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
+MetaImage::M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
 {
 
   if (m_ElementDataFileName == "LOCAL")
@@ -2457,7 +2694,7 @@ MetaImage::M_WriteElements(std::ofstream * _fstream, const void * _data, std::st
       std::streamoff elementNumberOfBytes = elementSize * m_ElementNumberOfChannels;
       std::streamoff sliceNumberOfBytes = m_SubQuantity[m_NDims - 1] * elementNumberOfBytes;
 
-      auto * writeStreamTemp = new std::ofstream;
+      auto * writeStreamTemp = new METAIO_STREAM::ofstream;
       for (i = 1; i <= m_DimSize[m_NDims - 1]; i++)
       {
         fName = string_format(dataFileName, i);
@@ -2506,7 +2743,7 @@ MetaImage::M_WriteElements(std::ofstream * _fstream, const void * _data, std::st
     }
     else // write the image in one unique other file
     {
-      auto * writeStreamTemp = new std::ofstream;
+      auto * writeStreamTemp = new METAIO_STREAM::ofstream;
       openWriteStream(*writeStreamTemp, dataFileName, false);
 
       if (!MetaImage::M_WriteElementData(writeStreamTemp, _data, _dataQuantity))
@@ -2526,7 +2763,7 @@ MetaImage::M_WriteElements(std::ofstream * _fstream, const void * _data, std::st
 
 
 bool
-MetaImage::M_WriteElementData(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
+MetaImage::M_WriteElementData(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity)
 {
   if (!m_BinaryData)
   {
@@ -2596,7 +2833,7 @@ MetaImage::ReadROI(int *        _indexMin,
                    void *       _buffer,
                    unsigned int subSamplingFactor)
 {
-MetaObject::M_Destroy();
+  M_Destroy();
 
   Clear();
 
@@ -2609,7 +2846,7 @@ MetaObject::M_Destroy();
 
   M_PrepareNewReadStream();
 
-  auto * tmpReadStream = new std::ifstream;
+  auto * tmpReadStream = new METAIO_STREAM::ifstream;
 
   openReadStream(*tmpReadStream, m_FileName);
 
@@ -2638,7 +2875,7 @@ bool
 MetaImage::ReadROIStream(int *           _indexMin,
                          int *           _indexMax,
                          int             _nDims,
-                         std::ifstream * _stream,
+                         METAIO_STREAM::ifstream * _stream,
                          bool            _readElements,
                          void *          _buffer,
                          unsigned int    subSamplingFactor)
@@ -2694,7 +2931,7 @@ MetaImage::ReadROIStream(int *           _indexMin,
       }
       delete[] wrds;
       char   s[1024];
-      auto * readStreamTemp = new std::ifstream;
+      auto * readStreamTemp = new METAIO_STREAM::ifstream;
       int    elementSize;
       MET_SizeOfType(m_ElementType, &elementSize);
       elementSize *= m_ElementNumberOfChannels;
@@ -2781,7 +3018,7 @@ MetaImage::ReadROIStream(int *           _indexMin,
       int         maxV;
       int         stepV = 1;
       std::string s;
-      auto *      readStreamTemp = new std::ifstream;
+      auto *      readStreamTemp = new METAIO_STREAM::ifstream;
       MET_StringToWordArray(m_ElementDataFileName.c_str(), &nWrds, &wrds);
       if (nWrds >= 2)
       {
@@ -2914,7 +3151,7 @@ MetaImage::ReadROIStream(int *           _indexMin,
         fName = m_ElementDataFileName;
       }
 
-      auto * readStreamTemp = new std::ifstream;
+      auto * readStreamTemp = new METAIO_STREAM::ifstream;
 
       const char * extensions[] = { "", ".gz", ".Z", nullptr };
       for (unsigned ii = 0; extensions[ii] != nullptr; ii++)
@@ -2960,7 +3197,7 @@ MetaImage::ReadROIStream(int *           _indexMin,
 
 /** Read an ROI */
 bool
-MetaImage::M_ReadElementsROI(std::ifstream * _fstream,
+MetaImage::M_ReadElementsROI(METAIO_STREAM::ifstream * _fstream,
                              void *          _data,
                              std::streamoff  _dataQuantity,
                              int *           _indexMin,
@@ -3286,7 +3523,7 @@ MetaImage::M_ReadElementsROI(std::ifstream * _fstream,
 
 
 bool
-MetaImage::M_ReadElementData(std::ifstream * _fstream, void * _data, std::streamoff _dataQuantity)
+MetaImage::M_ReadElementData(METAIO_STREAM::ifstream * _fstream, void * _data, std::streamoff _dataQuantity)
 {
   // NOTE: this method is different from WriteElementData
   std::streamoff gc = 0;
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.h
index 6a7d3afd42a..4e18824f957 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaImage.h
@@ -122,7 +122,8 @@ class METAIO_EXPORT MetaImage : public MetaObject
                       MET_ValueEnumType _elementType,
                       int               _elementNumberOfChannels = 1,
                       void *            _elementData = nullptr,
-                      bool              _allocElementMemory = true);
+                      bool              _allocElementMemory = true,
+                      bool              _initializePosition = true);
 
   bool
   InitializeEssential(int               _nDims,
@@ -131,7 +132,8 @@ class METAIO_EXPORT MetaImage : public MetaObject
                       MET_ValueEnumType _elementType,
                       int               _elementNumberOfChannels = 1,
                       void *            _elementData = nullptr,
-                      bool              _allocElementMemory = true);
+                      bool              _allocElementMemory = true,
+                      bool              _initializePosition = true);
 
   int
   HeaderSize() const;
@@ -251,6 +253,60 @@ class METAIO_EXPORT MetaImage : public MetaObject
   void
   ElementToIntensityFunctionOffset(double _elementOffset);
 
+  // (Copied from ITK's definition of Direction and Origin)
+  //
+  //  The position and orientation of an image is defined by its "Origin"
+  // and its "Directions".  The "Origin" is the physical position of the
+  // pixel whose "Index" is all zeros. The "Direction" of an image is a
+  // matrix whose columns indicate the direction in physical space that
+  // each dimension of the image traverses. The first column defines the
+  // direction that the fastest moving index in the image traverses in
+  // physical space while the last column defines the direction that the
+  // slowest moving index in the image traverses in physical space.
+  // 
+  // Set the direction cosines of the image. The direction cosines
+  // are vectors that point from one pixel to the next.
+  //
+  // Each column of the matrix indicates the direction cosines of the unit vector
+  // that is parallel to the lines of the image grid corresponding to that
+  // dimension. For example, an image with Direction matrix
+  //
+  //    0.866   0.500
+  //   -0.500   0.866
+  //
+  // has an image grid were the fastest changing index (dimension[0]) walks
+  // over a line that in physical space is oriented parallel to the vector
+  // (0.866, -0.5). The second fastest changing index (dimension[1]) walks along
+  // a line that in Physical space is oriented parallel to the vector
+  // (0.5, 0.866)
+  //
+  // The columns of the Direction matrix are expected to form an
+  // orthogonal right handed coordinate system.  But this is not
+  // checked nor enforced in itk::ImageBase.
+  //
+  // For details, please see:
+  //
+  // https://www.itk.org/Wiki/Proposals:Orientation#Some_notes_on_the_DICOM_convention_and_current_ITK_usage
+  const double *
+  ElementOrigin() const;
+  double
+  ElementOrigin(int _i) const;
+  void
+  ElementOrigin(const double * _position);
+  void
+  ElementOrigin(const float * _position);
+  void
+  ElementOrigin(int _i, double _value);
+
+  const double *
+  ElementDirection() const;
+  double
+  ElementDirection(int _i, int _j) const;
+  void
+  ElementDirection(const double * _direction);
+  void
+  ElementDirection(int _i, int _j, double _value);
+
   bool
   AutoFreeElementData() const;
   void
@@ -303,16 +359,16 @@ class METAIO_EXPORT MetaImage : public MetaObject
 
 
   static bool
-  CanReadStream(std::ifstream * _stream) ;
+  CanReadStream(METAIO_STREAM::ifstream * _stream) ;
 
   bool
-  ReadStream(int _nDims, std::ifstream * _stream, bool _readElements = true, void * _buffer = nullptr);
+  ReadStream(int _nDims, METAIO_STREAM::ifstream * _stream, bool _readElements = true, void * _buffer = nullptr);
 
   bool
   ReadROIStream(int *           _indexMin,
                 int *           _indexMax,
                 int             _nDims,
-                std::ifstream * _stream,
+                METAIO_STREAM::ifstream * _stream,
                 bool            _readElements = true,
                 void *          _buffer = nullptr,
                 unsigned int    subSamplingFactor = 1);
@@ -340,7 +396,7 @@ class METAIO_EXPORT MetaImage : public MetaObject
            bool         _append = false);
 
   bool
-  WriteStream(std::ofstream * _stream, bool _writeElements = true, const void * _constElementData = nullptr);
+  WriteStream(METAIO_STREAM::ofstream * _stream, bool _writeElements = true, const void * _constElementData = nullptr);
 
 
   bool
@@ -380,6 +436,9 @@ class METAIO_EXPORT MetaImage : public MetaObject
   double m_ElementToIntensityFunctionSlope{};
   double m_ElementToIntensityFunctionOffset{};
 
+  double m_ElementOrigin[10]{};     // "ElementOrigin = "          0,0,0
+  double m_ElementDirection[100]{}; // "ElementDirection = " 1,0,0,0,1,0,0,0,1
+                                   
   bool m_AutoFreeElementData{};
 
   void * m_ElementData{};
@@ -402,13 +461,13 @@ class METAIO_EXPORT MetaImage : public MetaObject
   // _dataQuantity is expressed in number of pixels. Internally it will be
   // scaled by the number of components and number of bytes per component.
   bool
-  M_ReadElements(std::ifstream * _fstream, void * _data, std::streamoff _dataQuantity);
+  M_ReadElements(METAIO_STREAM::ifstream * _fstream, void * _data, std::streamoff _dataQuantity);
 
   // _totalDataQuantity and _dataQuantity are expressed in number of pixels.
   // Internally they will be scaled by the number of components and number of
   // bytes per component.
   bool
-  M_ReadElementsROI(std::ifstream * _fstream,
+  M_ReadElementsROI(METAIO_STREAM::ifstream * _fstream,
                     void *          _data,
                     std::streamoff  _dataQuantity,
                     int *           _indexMin,
@@ -417,20 +476,20 @@ class METAIO_EXPORT MetaImage : public MetaObject
                     std::streamoff  _totalDataQuantity = 0);
 
   bool
-  M_ReadElementData(std::ifstream * _fstream, void * _data, std::streamoff _dataQuantity);
+  M_ReadElementData(METAIO_STREAM::ifstream * _fstream, void * _data, std::streamoff _dataQuantity);
 
   bool
-  M_WriteElements(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
+  M_WriteElements(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
 
   bool
-  M_WriteElementsROI(std::ofstream * _fstream,
+  M_WriteElementsROI(METAIO_STREAM::ofstream * _fstream,
                      const void *    _data,
                      std::streampos  _dataPos,
                      const int *     _indexMin,
                      const int *     _indexMax);
 
   bool
-  M_WriteElementData(std::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
+  M_WriteElementData(METAIO_STREAM::ofstream * _fstream, const void * _data, std::streamoff _dataQuantity);
 
   static bool
   M_FileExists(const char * filename) ;
@@ -450,6 +509,7 @@ class METAIO_EXPORT MetaImage : public MetaObject
              MET_ValueEnumType _elementType,
              int               _elementNumberOfChannels,
              void *            _elementData);
+
 };
 
 #  if (METAIO_USE_NAMESPACE)
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLandmark.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLandmark.cxx
index 3da80fb7140..fec57bd077b 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLandmark.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLandmark.cxx
@@ -245,20 +245,20 @@ MetaLandmark::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("NPoints", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NPoints = static_cast<int>(mF->value[0]);
   }
 
   mF = MET_GetFieldRecord("ElementType", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
   }
 
 
   mF = MET_GetFieldRecord("PointDim", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     strcpy(m_PointDim, reinterpret_cast<char *>(mF->value));
   }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLine.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLine.cxx
index 91abb87436d..37a7b4aae70 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLine.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaLine.cxx
@@ -255,19 +255,19 @@ MetaLine::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("NPoints", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NPoints = static_cast<int>(mF->value[0]);
   }
 
   mF = MET_GetFieldRecord("ElementType", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
   }
 
   mF = MET_GetFieldRecord("PointDim", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     strcpy(m_PointDim, reinterpret_cast<char *>(mF->value));
   }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaMesh.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaMesh.h
index 66bd02cdf0d..8545af6664c 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaMesh.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaMesh.h
@@ -115,7 +115,7 @@ class METAIO_EXPORT MeshDataBase
   virtual ~MeshDataBase() = default;
 
   virtual void
-  Write(std::ofstream * stream) = 0;
+  Write(METAIO_STREAM::ofstream * stream) = 0;
   virtual unsigned int
   GetSize() = 0;
   virtual MET_ValueEnumType
@@ -123,8 +123,8 @@ class METAIO_EXPORT MeshDataBase
   int m_Id;
 
 protected:
-  std::ifstream * m_ReadStream{};
-  std::ofstream * m_WriteStream{};
+  METAIO_STREAM::ifstream * m_ReadStream{};
+  METAIO_STREAM::ofstream * m_WriteStream{};
 };
 
 /** Mesh point data class for basic types (i.e int, float ... ) */
@@ -142,7 +142,7 @@ class METAIO_EXPORT MeshData : public MeshDataBase
   }
 
   void
-  Write(std::ofstream * stream) override
+  Write(METAIO_STREAM::ofstream * stream) override
   {
     // char* id = new char[sizeof(int)];
     // The file is written as LSB by default
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.cxx
index c105433ba07..11f8a7303c8 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.cxx
@@ -31,13 +31,16 @@ namespace METAIO_NAMESPACE
 MetaObject::MetaObject()
 {
   m_NDims = 0;
-  this->ClearFields();
-  this->ClearUserFields();
-  this->ClearAdditionalFields();
+  m_Fields.clear();
+  m_UserDefinedReadFields.clear();
+  m_UserDefinedWriteFields.clear();
+  m_AdditionalReadFields.clear();
   MetaObject::Clear();
   m_ReadStream = nullptr;
   m_WriteStream = nullptr;
-  m_FileName[0] = '\0';
+  m_FileFormatVersion = 0;
+  m_APIVersion = 0;
+  m_FileName = "";
   m_Event = nullptr;
   m_DoublePrecision = METAIO_MAX_DIGITS10;
   m_DistanceUnits = MET_DISTANCE_UNITS_UNKNOWN;
@@ -46,9 +49,10 @@ MetaObject::MetaObject()
 MetaObject::MetaObject(const char * _fileName)
 {
   m_NDims = 0;
-  this->ClearFields();
-  this->ClearUserFields();
-  this->ClearAdditionalFields();
+  m_Fields.clear();
+  m_UserDefinedReadFields.clear();
+  m_UserDefinedWriteFields.clear();
+  m_AdditionalReadFields.clear();
   MetaObject::Clear();
   m_ReadStream = nullptr;
   m_WriteStream = nullptr;
@@ -61,14 +65,17 @@ MetaObject::MetaObject(const char * _fileName)
 MetaObject::MetaObject(unsigned int dim)
 {
   m_NDims = 0;
-  this->ClearFields();
-  this->ClearUserFields();
-  this->ClearAdditionalFields();
-  MetaObject::Clear();
+  m_Fields.clear();
+  m_UserDefinedReadFields.clear();
+  m_UserDefinedWriteFields.clear();
+  m_AdditionalReadFields.clear();
   m_ReadStream = nullptr;
   m_WriteStream = nullptr;
+  m_FileFormatVersion = 0;
+  m_APIVersion = 0;
   m_FileName[0] = '\0';
   InitializeEssential(dim);
+  MetaObject::Clear();
   m_Event = nullptr;
   m_DoublePrecision = METAIO_MAX_DIGITS10;
   m_DistanceUnits = MET_DISTANCE_UNITS_UNKNOWN;
@@ -77,7 +84,7 @@ MetaObject::MetaObject(unsigned int dim)
 
 MetaObject::~MetaObject()
 {
-MetaObject::M_Destroy();
+  MetaObject::M_Destroy();
   delete m_ReadStream;
   delete m_WriteStream;
 
@@ -163,10 +170,20 @@ MetaObject ::ClearUserFields()
   {
     MET_FieldRecordType * field = *it;
     ++it;
+    auto it2 = m_Fields.begin();
+    auto end2 = m_Fields.end();
+    while (it2 != end2)
+    {
+      if (*it2 == field)
+      {
+        m_Fields.erase(it2);
+        break;
+      }
+      ++it2;
+    }
     delete field;
   }
 
-
   // Clear read field
   it = m_UserDefinedReadFields.begin();
   end = m_UserDefinedReadFields.end();
@@ -192,6 +209,17 @@ MetaObject ::ClearUserFields()
 
     if (!deleted)
     {
+      auto it2 = m_Fields.begin();
+      auto end2 = m_Fields.end();
+      while (it2 != end2)
+      {
+        if (*it2 == field)
+        {
+          m_Fields.erase(it2);
+          break;
+        }
+        ++it2;
+      }
       delete field;
     }
   }
@@ -217,6 +245,30 @@ MetaObject ::ClearAdditionalFields()
   m_AdditionalReadFields.clear();
 }
 
+void
+MetaObject::FileFormatVersion(unsigned int _fileFormatVersion)
+{
+  m_FileFormatVersion = _fileFormatVersion;
+}
+
+unsigned int
+MetaObject::FileFormatVersion() const
+{
+  return m_FileFormatVersion;
+}
+
+void
+MetaObject::APIVersion(unsigned int _APIVersion)
+{
+  m_APIVersion = _APIVersion;
+}
+
+unsigned int
+MetaObject::APIVersion() const
+{
+  return m_APIVersion;
+}
+
 void
 MetaObject::FileName(const char * _fileName)
 {
@@ -243,6 +295,8 @@ MetaObject::CopyInfo(const MetaObject * _object)
     std::cout << "MetaObject: CopyInfo: Warning: NDims not same size" << '\n';
   }
 
+  FileFormatVersion(_object->FileFormatVersion());
+  APIVersion(_object->APIVersion());
   FileName(_object->FileName());
   Comment(_object->Comment());
   ObjectTypeName(_object->ObjectTypeName());
@@ -271,13 +325,9 @@ MetaObject::Read(const char * _fileName)
     m_FileName = _fileName;
   }
 
-  auto * tmpReadStream = new std::ifstream;
+  auto * tmpReadStream = new METAIO_STREAM::ifstream;
 
-#ifdef __sgi
-  tmpReadStream->open(m_FileName, std::ios::in);
-#else
-  tmpReadStream->open(m_FileName, std::ios::binary | std::ios::in);
-#endif
+  tmpReadStream->open(m_FileName.c_str(), std::ios::binary | std::ios::in);
 
   if (!tmpReadStream->rdbuf()->is_open())
   {
@@ -301,11 +351,11 @@ MetaObject::Read(const char * _fileName)
 
 
 bool
-MetaObject::ReadStream(int _nDims, std::ifstream * _stream)
+MetaObject::ReadStream(int _nDims, METAIO_STREAM::ifstream * _stream)
 {
   META_DEBUG_PRINT( "MetaObject: ReadStream" );
 
-MetaObject::M_Destroy();
+  MetaObject::M_Destroy();
 
   fflush(nullptr);
 
@@ -344,17 +394,10 @@ MetaObject::Write(const char * _fileName)
 
   if (!m_WriteStream)
   {
-    m_WriteStream = new std::ofstream;
+    m_WriteStream = new METAIO_STREAM::ofstream;
   }
 
-#ifdef __sgi
-  // Create the file. This is required on some older sgi's
-  std::ofstream tFile(m_FileName, std::ios::out);
-  tFile.close();
-  m_WriteStream->open(m_FileName, std::ios::out);
-#else
-  m_WriteStream->open(m_FileName, std::ios::binary | std::ios::out);
-#endif
+  m_WriteStream->open(m_FileName.c_str(), std::ios::binary | std::ios::out);
 
   if (!m_WriteStream->rdbuf()->is_open())
   {
@@ -376,10 +419,12 @@ MetaObject::PrintInfo() const
   int i;
   int j;
 
-  std::cout << "FileName = _" << m_FileName << "_" << '\n';
-  std::cout << "Comment = _" << m_Comment << "_" << '\n';
   std::cout << "ObjectType = _" << m_ObjectTypeName << "_" << '\n';
   std::cout << "ObjectSubType = _" << m_ObjectSubTypeName << "_" << '\n';
+  std::cout << "FileFormatVersion = " << m_FileFormatVersion << '\n';
+  std::cout << "APIVersion = " << m_APIVersion << '\n';
+  std::cout << "FileName = _" << m_FileName << "_" << '\n';
+  std::cout << "Comment = _" << m_Comment << "_" << '\n';
   std::cout << "NDims = " << m_NDims << '\n';
   std::cout << "Name = " << m_Name << '\n';
   std::cout << "ID = " << m_ID << '\n';
@@ -453,60 +498,30 @@ MetaObject::PrintInfo() const
   std::cout << "DistanceUnits = " << this->DistanceUnitsName() << '\n';
 
   // Print User's fields :
-  auto                                itw = m_UserDefinedWriteFields.begin();
-  auto                                itr = m_UserDefinedReadFields.begin();
-  auto                                endw = m_UserDefinedWriteFields.end();
-  FieldsContainerType::const_iterator it;
+  auto itw = m_UserDefinedWriteFields.begin();
+  auto endw = m_UserDefinedWriteFields.end();
+  std::cout << "UserDefinedWriteFields:" << '\n'
+            << "Number of fields = " << m_UserDefinedWriteFields.size() << '\n';
+  std::cout << "***" << '\n';
   while (itw != endw)
   {
-    if ((*itw)->defined)
-    {
-      it = itw;
-    }
-    else
-    {
-      it = itr;
-    }
-
-    printf("%s: ", (*it)->name);
-
-    if ((*it)->type == MET_STRING)
-    {
-      printf("%s", reinterpret_cast<char *>((*it)->value));
-    }
-    else if ((*it)->type == MET_ASCII_CHAR || (*it)->type == MET_CHAR || (*it)->type == MET_UCHAR ||
-             (*it)->type == MET_SHORT || (*it)->type == MET_USHORT || (*it)->type == MET_LONG ||
-             (*it)->type == MET_ULONG || (*it)->type == MET_INT || (*it)->type == MET_UINT ||
-             (*it)->type == MET_FLOAT || (*it)->type == MET_DOUBLE)
-    {
-      printf("%s : %f\n", (*it)->name, (*it)->value[0]);
-    }
-    else if ((*it)->type == MET_CHAR_ARRAY || (*it)->type == MET_UCHAR_ARRAY || (*it)->type == MET_SHORT_ARRAY ||
-             (*it)->type == MET_USHORT_ARRAY || (*it)->type == MET_INT_ARRAY || (*it)->type == MET_UINT_ARRAY ||
-             (*it)->type == MET_FLOAT_ARRAY || (*it)->type == MET_DOUBLE_ARRAY)
-    {
-      for (i = 0; i < (*it)->length; i++)
-      {
-        printf("%f ", (*it)->value[i]);
-      }
-    }
-    else if ((*it)->type == MET_FLOAT_MATRIX)
-    {
-      std::cout << '\n';
-      for (i = 0; i < (*it)->length * (*it)->length; i++)
-      {
-        printf("%f ", (*it)->value[i]);
-        if (i == (*it)->length - 1)
-        {
-          std::cout << '\n';
-        }
-      }
-    }
-    std::cout << '\n';
-
+    MET_PrintFieldRecord(std::cout, *itw);
+    std::cout << "***" << '\n';
     ++itw;
+  }
+
+  auto itr = m_UserDefinedReadFields.begin();
+  auto endr = m_UserDefinedReadFields.end();
+  std::cout << "UserDefinedReadFields:" << '\n'
+            << "Number of fields = " << m_UserDefinedReadFields.size() << '\n';
+  std::cout << "***" << '\n';
+  while (itr != endr)
+  {
+    MET_PrintFieldRecord(std::cout, *itr);
+    std::cout << "***" << '\n';
     ++itr;
   }
+
 }
 
 const char *
@@ -583,18 +598,30 @@ MetaObject::Offset(int _i, double _value)
 const double *
 MetaObject::Position() const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Position is deprecated, please use Offset" << '\n';
+  }
   return m_Offset;
 }
 
 double
 MetaObject::Position(int _i) const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Position is deprecated, please use Offset" << '\n';
+  }
   return m_Offset[_i];
 }
 
 void
 MetaObject::Position(const double * _position)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Position is deprecated, please use Offset" << '\n';
+  }
   int i;
   for (i = 0; i < m_NDims; i++)
   {
@@ -605,24 +632,40 @@ MetaObject::Position(const double * _position)
 void
 MetaObject::Position(int _i, double _value)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Position is deprecated, please use Offset" << '\n';
+  }
   m_Offset[_i] = _value;
 }
 
 const double *
 MetaObject::Origin() const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Origin is deprecated, please use Offset" << '\n';
+  }
   return m_Offset;
 }
 
 double
 MetaObject::Origin(int _i) const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Origin is deprecated, please use Offset" << '\n';
+  }
   return m_Offset[_i];
 }
 
 void
 MetaObject::Origin(const double * _position)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Origin is deprecated, please use Offset" << '\n';
+  }
   int i;
   for (i = 0; i < m_NDims; i++)
   {
@@ -633,6 +676,10 @@ MetaObject::Origin(const double * _position)
 void
 MetaObject::Origin(int _i, double _value)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Origin is deprecated, please use Offset" << '\n';
+  }
   m_Offset[_i] = _value;
 }
 
@@ -667,18 +714,30 @@ MetaObject::TransformMatrix(int _i, int _j, double _value)
 const double *
 MetaObject::Rotation() const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Rotation is deprecated, please use TransformMatrix" << '\n';
+  }
   return m_TransformMatrix;
 }
 
 double
 MetaObject::Rotation(int _i, int _j) const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Rotation is deprecated, please use TransformMatrix" << '\n';
+  }
   return m_TransformMatrix[_i * m_NDims + _j];
 }
 
 void
 MetaObject::Rotation(const double * _orientation)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Rotation is deprecated, please use TransformMatrix" << '\n';
+  }
   int i;
   for (i = 0; i < m_NDims * m_NDims; i++)
   {
@@ -689,24 +748,41 @@ MetaObject::Rotation(const double * _orientation)
 void
 MetaObject::Rotation(int _i, int _j, double _value)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Rotation is deprecated, please use TransformMatrix" << '\n';
+  }
   m_TransformMatrix[_i * m_NDims + _j] = _value;
 }
 
 const double *
 MetaObject::Orientation() const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Orientation is deprecated, please use TransformMatrix" << '\n';
+  }
   return m_TransformMatrix;
 }
 
+
 double
 MetaObject::Orientation(int _i, int _j) const
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Orientation is deprecated, please use TransformMatrix" << '\n';
+  }
   return m_TransformMatrix[_i * m_NDims + _j];
 }
 
 void
 MetaObject::Orientation(const double * _orientation)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Orientation is deprecated, please use TransformMatrix" << '\n';
+  }
   int i;
   for (i = 0; i < m_NDims * m_NDims; i++)
   {
@@ -717,6 +793,10 @@ MetaObject::Orientation(const double * _orientation)
 void
 MetaObject::Orientation(int _i, int _j, double _value)
 {
+  if (m_APIVersion == 1)
+  {
+    std::cerr << "MetaIO: Orientation is deprecated, please use TransformMatrix" << '\n';
+  }
   m_TransformMatrix[_i * m_NDims + _j] = _value;
 }
 
@@ -1041,7 +1121,6 @@ MetaObject::Clear()
   memset(m_Offset, 0, sizeof(m_Offset));
   memset(m_TransformMatrix, 0, sizeof(m_TransformMatrix));
   memset(m_CenterOfRotation, 0, sizeof(m_CenterOfRotation));
-  memset(m_Color, 0, sizeof(m_Color));
 
   m_ID = -1;
   m_Color[0] = 1.0F;
@@ -1060,24 +1139,15 @@ MetaObject::Clear()
   m_DistanceUnits = MET_DISTANCE_UNITS_UNKNOWN;
 
   META_DEBUG_PRINT( "MetaObject: Clear: m_NDims=" << m_NDims );
-  int i;
-  for (i = 0; i < 10; i++)
+  if (m_NDims < 10)
   {
-    m_ElementSpacing[i] = 1;
-    m_AnatomicalOrientation[i] = MET_ORIENTATION_UNKNOWN;
+    for (int i = 0; i < m_NDims; i++)
+    {
+      m_ElementSpacing[i] = 1;
+      m_TransformMatrix[i * m_NDims + i] = 1;
+      m_AnatomicalOrientation[i] = MET_ORIENTATION_UNKNOWN;
+    }
   }
-  /*
-    std::vector<MET_FieldRecordType *>::iterator fieldIter;
-    for(fieldIter=m_Fields.begin(); fieldIter!=m_Fields.end(); fieldIter++)
-      {
-      if(META_DEBUG) std::cout << "field = " << (*fieldIter)->name << std::endl;
-      MET_FieldRecordType* field = *fieldIter;
-      delete field;
-      field = nullptr;
-      if(META_DEBUG) std::cout << " has been deleted." << std::endl;
-      }
-    m_Fields.clear();*/
-  this->ClearFields();
 }
 
 bool
@@ -1085,7 +1155,7 @@ MetaObject::InitializeEssential(int _nDims)
 {
   META_DEBUG_PRINT( "MetaObject: Initialize" );
 
-MetaObject::M_Destroy();
+  MetaObject::M_Destroy();
 
   if (_nDims > 10)
   {
@@ -1103,6 +1173,15 @@ MetaObject::M_Destroy();
 
   m_NDims = _nDims;
 
+  memset(m_Offset, 0, sizeof(m_Offset));
+  memset(m_TransformMatrix, 0, sizeof(m_TransformMatrix));
+  for (int i = 0; i < m_NDims; i++)
+  {
+    m_ElementSpacing[i] = 1;
+    m_TransformMatrix[i * m_NDims + i] = 1;
+    m_AnatomicalOrientation[i] = MET_ORIENTATION_UNKNOWN;
+  }
+
   return true;
 }
 
@@ -1115,30 +1194,34 @@ MetaObject::M_Destroy()
 void
 MetaObject::M_SetupReadFields()
 {
-  this->ClearFields();
   META_DEBUG_PRINT( "MetaObject: M_SetupReadFields" );
 
+  this->ClearFields();
+
   MET_FieldRecordType * mF;
 
   mF = new MET_FieldRecordType;
-  MET_InitReadField(mF, "Comment", MET_STRING, false);
+  MET_InitReadField(mF, "ObjectType", MET_STRING, false);
   m_Fields.push_back(mF);
 
   mF = new MET_FieldRecordType;
-  MET_InitReadField(mF, "AcquisitionDate", MET_STRING, false);
+  MET_InitReadField(mF, "ObjectSubType", MET_STRING, false);
   m_Fields.push_back(mF);
 
   mF = new MET_FieldRecordType;
-  MET_InitReadField(mF, "ObjectType", MET_STRING, false);
+  MET_InitReadField(mF, "FileFormatVersion", MET_UINT, false);
   m_Fields.push_back(mF);
 
   mF = new MET_FieldRecordType;
-  MET_InitReadField(mF, "ObjectSubType", MET_STRING, false);
+  MET_InitReadField(mF, "Comment", MET_STRING, false);
+  m_Fields.push_back(mF);
+
+  mF = new MET_FieldRecordType;
+  MET_InitReadField(mF, "AcquisitionDate", MET_STRING, false);
   m_Fields.push_back(mF);
 
   mF = new MET_FieldRecordType;
   MET_InitReadField(mF, "NDims", MET_INT, true);
-  mF->required = true;
   m_Fields.push_back(mF);
 
   int nDimsRecordNumber = MET_GetFieldRecordNumber("NDims", &m_Fields);
@@ -1221,7 +1304,6 @@ MetaObject::M_SetupReadFields()
 
   mF = new MET_FieldRecordType;
   MET_InitReadField(mF, "ElementSpacing", MET_FLOAT_ARRAY, false, nDimsRecordNumber);
-  mF->required = false;
   m_Fields.push_back(mF);
 
   // Add User's field
@@ -1234,7 +1316,6 @@ MetaObject::M_SetupReadFields()
   }
 }
 
-
 void
 MetaObject::M_SetupWriteFields()
 {
@@ -1246,13 +1327,6 @@ MetaObject::M_SetupWriteFields()
 
   MET_FieldRecordType * mF;
 
-  if (strlen(m_Comment) > 0)
-  {
-    mF = new MET_FieldRecordType;
-    MET_InitWriteField(mF, "Comment", MET_STRING, strlen(m_Comment), m_Comment);
-    m_Fields.push_back(mF);
-  }
-
   mF = new MET_FieldRecordType;
   MET_InitWriteField(mF, "ObjectType", MET_STRING, strlen(m_ObjectTypeName), m_ObjectTypeName);
   m_Fields.push_back(mF);
@@ -1264,6 +1338,20 @@ MetaObject::M_SetupWriteFields()
     m_Fields.push_back(mF);
   }
 
+  if (m_FileFormatVersion > 0)
+  {
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "FileFormatVersion", MET_UINT, m_FileFormatVersion);
+    m_Fields.push_back(mF);
+  }
+
+  if (strlen(m_Comment) > 0)
+  {
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "Comment", MET_STRING, strlen(m_Comment), m_Comment);
+    m_Fields.push_back(mF);
+  }
+
   mF = new MET_FieldRecordType;
   MET_InitWriteField(mF, "NDims", MET_INT, m_NDims);
   m_Fields.push_back(mF);
@@ -1428,33 +1516,43 @@ MetaObject::M_Read()
 
   MET_FieldRecordType * mF;
 
-  mF = MET_GetFieldRecord("Comment", &m_Fields);
+  mF = MET_GetFieldRecord("NDims", &m_Fields);
   if (mF && mF->defined)
   {
-    strcpy(m_Comment, reinterpret_cast<char *>(mF->value));
+    m_NDims = static_cast<int>(mF->value[0]);
+  }
+  if (m_NDims > 0)
+  {
+    MetaObject::InitializeEssential(m_NDims);
+    Clear();
   }
 
-  mF = MET_GetFieldRecord("ObjectType", &m_Fields);
+  mF = MET_GetFieldRecord("FileFormatVersion", &m_Fields);
   if (mF && mF->defined)
   {
-    strcpy(m_ObjectTypeName, reinterpret_cast<char *>(mF->value));
+    m_FileFormatVersion = static_cast<unsigned int>(mF->value[0]);
+  }
+  else
+  {
+    m_FileFormatVersion = 0;
   }
 
-  mF = MET_GetFieldRecord("ObjectSubType", &m_Fields);
+  mF = MET_GetFieldRecord("Comment", &m_Fields);
   if (mF && mF->defined)
   {
-    strcpy(m_ObjectSubTypeName, reinterpret_cast<char *>(mF->value));
+    strcpy(m_Comment, reinterpret_cast<char *>(mF->value));
   }
 
-  mF = MET_GetFieldRecord("NDims", &m_Fields);
+  mF = MET_GetFieldRecord("ObjectType", &m_Fields);
   if (mF && mF->defined)
   {
-    m_NDims = static_cast<int>(mF->value[0]);
+    strcpy(m_ObjectTypeName, reinterpret_cast<char *>(mF->value));
   }
 
-  if (m_NDims > 0)
+  mF = MET_GetFieldRecord("ObjectSubType", &m_Fields);
+  if (mF && mF->defined)
   {
-    MetaObject::InitializeEssential(m_NDims);
+    strcpy(m_ObjectSubTypeName, reinterpret_cast<char *>(mF->value));
   }
 
   mF = MET_GetFieldRecord("Name", &m_Fields);
@@ -1545,87 +1643,70 @@ MetaObject::M_Read()
 
   int i;
   mF = MET_GetFieldRecord("Color", &m_Fields);
-  if (mF)
+  if (mF && mF->defined)
   {
-    if (mF->defined)
+    for (i = 0; i < mF->length && i < 4; i++)
     {
-      for (i = 0; i < mF->length && i < 4; i++)
-      {
-        m_Color[i] = static_cast<float>(mF->value[i]);
-      }
-    }
-    else
-    {
-      for (i = 0; i < mF->length && i < 4; i++)
-      {
-        m_Color[i] = static_cast<unsigned int>(1);
-      }
+      m_Color[i] = static_cast<float>(mF->value[i]);
     }
   }
 
-  mF = MET_GetFieldRecord("Position", &m_Fields);
+  mF = MET_GetFieldRecord("Offset", &m_Fields);
   if (mF && mF->defined)
   {
-    for (i = 0; i < mF->length; i++)
+    for (i = 0; i < mF->length && i < m_NDims; i++)
     {
       m_Offset[i] = mF->value[i];
     }
   }
-  mF = MET_GetFieldRecord("Offset", &m_Fields);
-  if (mF && mF->defined)
+
+  if (m_FileFormatVersion == 0)
   {
-    for (i = 0; i < mF->length; i++)
+    mF = MET_GetFieldRecord("Position", &m_Fields);
+    if (mF && mF->defined)
     {
-      m_Offset[i] = mF->value[i];
+      for (i = 0; i < mF->length && i < m_NDims; i++)
+      {
+        m_Offset[i] = mF->value[i];
+      }
     }
-  }
-  mF = MET_GetFieldRecord("Origin", &m_Fields);
-  if (mF && mF->defined)
-  {
-    for (i = 0; i < mF->length; i++)
+    mF = MET_GetFieldRecord("Origin", &m_Fields);
+    if (mF && mF->defined)
     {
-      m_Offset[i] = mF->value[i];
+      for (i = 0; i < mF->length && i < m_NDims; i++)
+      {
+        m_Offset[i] = mF->value[i];
+      }
     }
-  }
-
-  bool transformMatrixDefined = false;
-  mF = MET_GetFieldRecord("Orientation", &m_Fields);
-  if (mF && mF->defined)
-  {
-    transformMatrixDefined = true;
-    int len = mF->length;
-    for (i = 0; i < len * len; i++)
+    mF = MET_GetFieldRecord("Orientation", &m_Fields);
+    if (mF && mF->defined)
     {
-      m_TransformMatrix[i] = mF->value[i];
+      int len = mF->length;
+      for (i = 0; i < len*len && i < m_NDims*m_NDims; i++)
+      {
+        m_TransformMatrix[i] = mF->value[i];
+      }
     }
-  }
-  mF = MET_GetFieldRecord("Rotation", &m_Fields);
-  if (mF && mF->defined)
-  {
-    transformMatrixDefined = true;
-    int len = mF->length;
-    for (i = 0; i < len * len; i++)
+    mF = MET_GetFieldRecord("Rotation", &m_Fields);
+    if (mF && mF->defined)
     {
-      m_TransformMatrix[i] = mF->value[i];
+      int len = mF->length;
+      for (i = 0; i < len*len && i < m_NDims*m_NDims; i++)
+      {
+        m_TransformMatrix[i] = mF->value[i];
+      }
     }
   }
+
   mF = MET_GetFieldRecord("TransformMatrix", &m_Fields);
   if (mF && mF->defined)
   {
-    transformMatrixDefined = true;
     int len = mF->length;
-    for (i = 0; i < len * len; i++)
+    for (i = 0; i < len*len && i < m_NDims*m_NDims; i++)
     {
       m_TransformMatrix[i] = mF->value[i];
     }
   }
-  if (!transformMatrixDefined)
-  {
-    for (i = 0; i < m_NDims; i++)
-    {
-      m_TransformMatrix[i + i * m_NDims] = 1;
-    }
-  }
 
   mF = MET_GetFieldRecord("CenterOfRotation", &m_Fields);
   if (mF && mF->defined)
@@ -1635,13 +1716,6 @@ MetaObject::M_Read()
       m_CenterOfRotation[i] = mF->value[i];
     }
   }
-  else
-  {
-    for (i = 0; i < m_NDims; i++)
-    {
-      m_CenterOfRotation[i] = 0;
-    }
-  }
 
   mF = MET_GetFieldRecord("DistanceUnits", &m_Fields);
   if (mF && mF->defined)
@@ -1656,44 +1730,39 @@ MetaObject::M_Read()
   }
 
   mF = MET_GetFieldRecord("ElementSpacing", &m_Fields);
-  if (mF)
+  if (mF && mF->defined)
   {
-    if (mF->defined)
-    {
-      for (i = 0; i < mF->length && i < 10; i++)
-      {
-        m_ElementSpacing[i] = mF->value[i];
-        META_DEBUG_PRINT( "metaObject: M_Read: elementSpacing[" << i << "] = " << m_ElementSpacing[i] );
-      }
-    }
-    else
+    for (i = 0; i < mF->length && i < 10; i++)
     {
-      for (i = 0; i < mF->length && i < 10; i++)
-      {
-        m_ElementSpacing[i] = 1;
-        META_DEBUG_PRINT( "metaObject: M_Read: elementSpacing[" << i << "] = " << m_ElementSpacing[i] );
-      }
+      m_ElementSpacing[i] = mF->value[i];
+      META_DEBUG_PRINT( "metaObject: M_Read: elementSpacing[" << i << "] = " << m_ElementSpacing[i] );
     }
   }
 
-  // Set the read record field in the m_UserDefinedWriteFields
+  // If a field is read, add it to the list of fields to be written
   auto it = m_UserDefinedReadFields.begin();
   auto end = m_UserDefinedReadFields.end();
   while (it != end)
   {
     mF = MET_GetFieldRecord((*it)->name, &m_Fields);
-    // DON'T put the same cross-linked element from the UD readFields
-    // into the userDefined write fields more than once. That
-    // causes a double free, and an abort.
+    if( !mF )
+    {
+        ++it;
+        continue;
+    }
+    
+    // Don't add a read field to the write fields if it is already in the write fields
+    bool found = false;
     FieldsContainerType::iterator dup;
     for (dup = m_UserDefinedWriteFields.begin(); dup != m_UserDefinedWriteFields.end(); ++dup)
     {
       if ((*dup) == mF)
       {
+        found = true;
         break;
       }
     }
-    if (dup == m_UserDefinedWriteFields.end())
+    if (!found)
     {
       m_UserDefinedWriteFields.push_back(mF);
     }
@@ -1732,27 +1801,16 @@ MetaObject ::Append(const char * _headName)
 
   if (!m_WriteStream)
   {
-    m_WriteStream = new std::ofstream;
+    m_WriteStream = new METAIO_STREAM::ofstream;
   }
 
-#ifdef __sgi
-  m_WriteStream->open(m_FileName, std::ios::out | std::ios::in);
-  if (!m_WriteStream->rdbuf()->is_open())
-  {
-    delete m_WriteStream;
-    m_WriteStream = 0;
-    return false;
-  }
-  m_WriteStream->seekp(0, std::ios::end);
-#else
-  m_WriteStream->open(m_FileName, std::ios::binary | std::ios::out | std::ios::app);
+  m_WriteStream->open(m_FileName.c_str(), std::ios::binary | std::ios::out | std::ios::app);
   if (!m_WriteStream->rdbuf()->is_open())
   {
     delete m_WriteStream;
     m_WriteStream = nullptr;
     return false;
   }
-#endif
 
   M_Write();
 
@@ -1768,10 +1826,15 @@ MetaObject ::Append(const char * _headName)
 void *
 MetaObject ::GetUserField(const char * _name)
 {
-  auto it = m_UserDefinedWriteFields.begin();
-  auto end = m_UserDefinedWriteFields.end();
+  auto it = m_UserDefinedReadFields.begin();
+  auto end = m_UserDefinedReadFields.end();
   while (it != end)
   {
+    if (*it == nullptr)
+    {
+      ++it;
+      continue;
+    }
     int eSize;
     MET_SizeOfType((*it)->type, &eSize);
     const auto itLength = static_cast<unsigned int>((*it)->length);
@@ -1837,6 +1900,16 @@ MetaObject ::GetAdditionalReadFieldValueLength(int i)
 bool
 MetaObject ::AddUserField(const char * _fieldName, MET_ValueEnumType _type, int _length, bool _required, int _dependsOn)
 {
+  auto it = m_UserDefinedReadFields.begin();
+  auto end = m_UserDefinedReadFields.end();
+  while (it != end)
+  {
+    if (!strcmp((*it)->name, _fieldName))
+    {
+      return false;
+    }
+    ++it;
+  }
   auto * mFr = new MET_FieldRecordType;
   MET_InitReadField(mFr, _fieldName, _type, _required, _dependsOn, static_cast<size_t>(_length));
   m_UserDefinedReadFields.push_back(mFr);
@@ -1856,7 +1929,7 @@ MetaObject::M_PrepareNewReadStream()
   }
   else
   {
-    m_ReadStream = new std::ifstream;
+    m_ReadStream = new METAIO_STREAM::ifstream;
   }
 }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.h
index 128bd69f297..5d6a9f9d910 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaObject.h
@@ -35,6 +35,7 @@ class METAIO_EXPORT MetaObject
   // PROTECTED
 protected:
   std::set<std::string> m_ReservedKeywords = {
+    "FileFormatVersion",
     "ObjectType",
     "ObjectSubType",
     "NDims",
@@ -56,14 +57,17 @@ class METAIO_EXPORT MetaObject
 
   typedef std::vector<MET_FieldRecordType *> FieldsContainerType;
 
-  std::ifstream * m_ReadStream;
-  std::ofstream * m_WriteStream;
+  METAIO_STREAM::ifstream * m_ReadStream;
+  METAIO_STREAM::ofstream * m_WriteStream;
 
   FieldsContainerType m_Fields;
   FieldsContainerType m_UserDefinedWriteFields;
   FieldsContainerType m_UserDefinedReadFields;
   FieldsContainerType m_AdditionalReadFields;
 
+  unsigned int m_FileFormatVersion;
+  unsigned int m_APIVersion;
+
   std::string m_FileName;
 
   char m_Comment[255]{}; // "Comment = "       ""
@@ -142,6 +146,16 @@ class METAIO_EXPORT MetaObject
   std::set<std::string>
   GetReservedKeywords() const;
 
+  void
+  FileFormatVersion(unsigned int _fileFormatVersion);
+  unsigned int
+  FileFormatVersion() const;
+
+  void
+  APIVersion(unsigned int _APIVersion);
+  unsigned int
+  APIVersion() const;
+
   void
   FileName(const char * _fileName);
   const char *
@@ -154,7 +168,7 @@ class METAIO_EXPORT MetaObject
   Read(const char * _fileName = nullptr);
 
   bool
-  ReadStream(int _nDims, std::ifstream * _stream);
+  ReadStream(int _nDims, METAIO_STREAM::ifstream * _stream);
 
   virtual bool
   Write(const char * _fileName = nullptr);
@@ -204,21 +218,21 @@ class METAIO_EXPORT MetaObject
   Offset(const double * _position);
   void
   Offset(int _i, double _value);
-  const double *
+  virtual const double *
   Position() const;
-  double
+  virtual double
   Position(int _i) const;
-  void
+  virtual void
   Position(const double * _position);
-  void
+  virtual void
   Position(int _i, double _value);
-  const double *
+  virtual const double *
   Origin() const;
-  double
+  virtual double
   Origin(int _i) const;
-  void
+  virtual void
   Origin(const double * _position);
-  void
+  virtual void
   Origin(int _i, double _value);
 
   //    TransformMatrix(...)
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaScene.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaScene.cxx
index 2ca9be4cdf8..e28b544ac94 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaScene.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaScene.cxx
@@ -115,7 +115,7 @@ MetaScene::Read(const char * _headerName)
     strcpy(suf, &_headerName[i]);
   }
 
-MetaObject::M_Destroy();
+  MetaObject::M_Destroy();
 
   Clear();
 
@@ -130,7 +130,7 @@ MetaObject::M_Destroy();
 
   M_PrepareNewReadStream();
 
-  m_ReadStream->open(m_FileName, std::ios::binary | std::ios::in);
+  m_ReadStream->open(m_FileName.c_str(), std::ios::binary | std::ios::in);
 
   if (!m_ReadStream->rdbuf()->is_open())
   {
@@ -172,6 +172,7 @@ MetaObject::M_Destroy();
       if (!strncmp(subtype, "Vessel", 6))
       {
         auto * vesseltube = new MetaVesselTube();
+        vesseltube->APIVersion(m_APIVersion);
         vesseltube->SetEvent(m_Event);
         vesseltube->ReadStream(m_NDims, m_ReadStream);
         m_ObjectList.push_back(vesseltube);
@@ -179,6 +180,7 @@ MetaObject::M_Destroy();
       else if (!strncmp(subtype, "DTI", 3))
       {
         auto * dtitube = new MetaDTITube();
+        dtitube->APIVersion(m_APIVersion);
         dtitube->SetEvent(m_Event);
         dtitube->ReadStream(m_NDims, m_ReadStream);
         m_ObjectList.push_back(dtitube);
@@ -186,6 +188,7 @@ MetaObject::M_Destroy();
       else
       {
         auto * tube = new MetaTube();
+        tube->APIVersion(m_APIVersion);
         tube->SetEvent(m_Event);
         tube->ReadStream(m_NDims, m_ReadStream);
         m_ObjectList.push_back(tube);
@@ -196,6 +199,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Transform", 9))
     {
       auto * transform = new MetaTransform();
+      transform->APIVersion(m_APIVersion);
       transform->SetEvent(m_Event);
       transform->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(transform);
@@ -204,6 +208,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "TubeGraph", 9))
     {
       auto * tubeGraph = new MetaTubeGraph();
+      tubeGraph->APIVersion(m_APIVersion);
       tubeGraph->SetEvent(m_Event);
       tubeGraph->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(tubeGraph);
@@ -212,6 +217,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Ellipse", 7) || ((objectType.empty()) && !strcmp(suf, "elp")))
     {
       auto * ellipse = new MetaEllipse();
+      ellipse->APIVersion(m_APIVersion);
       ellipse->SetEvent(m_Event);
       ellipse->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(ellipse);
@@ -220,6 +226,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Contour", 7) || ((objectType.empty()) && !strcmp(suf, "ctr")))
     {
       auto * contour = new MetaContour();
+      contour->APIVersion(m_APIVersion);
       contour->SetEvent(m_Event);
       contour->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(contour);
@@ -228,6 +235,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Arrow", 5))
     {
       auto * arrow = new MetaArrow();
+      arrow->APIVersion(m_APIVersion);
       arrow->SetEvent(m_Event);
       arrow->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(arrow);
@@ -236,6 +244,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Gaussian", 8) || ((objectType.empty()) && !strcmp(suf, "gau")))
     {
       auto * gaussian = new MetaGaussian();
+      gaussian->APIVersion(m_APIVersion);
       gaussian->SetEvent(m_Event);
       gaussian->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(gaussian);
@@ -245,6 +254,7 @@ MetaObject::M_Destroy();
              ((objectType.empty()) && (!strcmp(suf, "mhd") || !strcmp(suf, "mha"))))
     {
       auto * image = new MetaImage();
+      image->APIVersion(m_APIVersion);
       image->SetEvent(m_Event);
       image->ReadStream(m_NDims, m_ReadStream);
       image->ElementByteOrderFix();
@@ -254,6 +264,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Blob", 4) || ((objectType.empty()) && !strcmp(suf, "blb")))
     {
       auto * blob = new MetaBlob();
+      blob->APIVersion(m_APIVersion);
       blob->SetEvent(m_Event);
       blob->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(blob);
@@ -262,6 +273,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Landmark", 8) || ((objectType.empty()) && !strcmp(suf, "ldm")))
     {
       auto * landmark = new MetaLandmark();
+      landmark->APIVersion(m_APIVersion);
       landmark->SetEvent(m_Event);
       landmark->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(landmark);
@@ -270,6 +282,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Surface", 5) || ((objectType.empty()) && !strcmp(suf, "suf")))
     {
       auto * surface = new MetaSurface();
+      surface->APIVersion(m_APIVersion);
       surface->SetEvent(m_Event);
       surface->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(surface);
@@ -278,6 +291,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Line", 4) || ((objectType.empty()) && !strcmp(suf, "lin")))
     {
       auto * line = new MetaLine();
+      line->APIVersion(m_APIVersion);
       line->SetEvent(m_Event);
       line->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(line);
@@ -286,6 +300,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Group", 5) || ((objectType.empty()) && !strcmp(suf, "grp")))
     {
       auto * group = new MetaGroup();
+      group->APIVersion(m_APIVersion);
       group->SetEvent(m_Event);
       group->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(group);
@@ -294,6 +309,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "AffineTransform", 15) || ((objectType.empty()) && !strcmp(suf, "trn")))
     {
       auto * group = new MetaGroup();
+      group->APIVersion(m_APIVersion);
       group->SetEvent(m_Event);
       group->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(group);
@@ -301,6 +317,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "Mesh", 4) || ((objectType.empty()) && !strcmp(suf, "msh")))
     {
       auto * mesh = new MetaMesh();
+      mesh->APIVersion(m_APIVersion);
       mesh->SetEvent(m_Event);
       mesh->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(mesh);
@@ -308,6 +325,7 @@ MetaObject::M_Destroy();
     else if (!strncmp(objectType.c_str(), "FEMObject", 9) || ((objectType.empty()) && !strcmp(suf, "fem")))
     {
       auto * femobject = new MetaFEMObject();
+      femobject->APIVersion(m_APIVersion);
       femobject->SetEvent(m_Event);
       femobject->ReadStream(m_NDims, m_ReadStream);
       m_ObjectList.push_back(femobject);
@@ -343,19 +361,10 @@ MetaScene::Write(const char * _headName)
 
   if (!m_WriteStream)
   {
-    m_WriteStream = new std::ofstream;
+    m_WriteStream = new METAIO_STREAM::ofstream;
   }
 
-#ifdef __sgi
-  // Create the file. This is required on some older sgi's
-  {
-    std::ofstream tFile(m_FileName, std::ios::out);
-    tFile.close();
-  }
-  m_WriteStream->open(m_FileName, std::ios::out);
-#else
-  m_WriteStream->open(m_FileName, std::ios::binary | std::ios::out);
-#endif
+  m_WriteStream->open(m_FileName.c_str(), std::ios::binary | std::ios::out);
 
   if (!m_WriteStream->rdbuf()->is_open())
   {
@@ -414,8 +423,7 @@ MetaScene::M_SetupReadFields()
   MET_FieldRecordType * mF;
 
   mF = new MET_FieldRecordType;
-  MET_InitReadField(mF, "NObjects", MET_INT, false);
-  mF->required = true;
+  MET_InitReadField(mF, "NObjects", MET_INT, true);
   mF->terminateRead = true;
   m_Fields.push_back(mF);
 
@@ -430,6 +438,13 @@ MetaScene::M_SetupWriteFields()
 
   MET_FieldRecordType * mF;
 
+  if (m_FileFormatVersion > 0)
+  {
+    mF = new MET_FieldRecordType;
+    MET_InitWriteField(mF, "FileFormatVersion", MET_UINT, m_FileFormatVersion);
+    m_Fields.push_back(mF);
+  }
+
   if (strlen(m_Comment) > 0)
   {
     mF = new MET_FieldRecordType;
@@ -473,7 +488,7 @@ MetaScene::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("NObjects", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NObjects = static_cast<int>(mF->value[0]);
   }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaSurface.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaSurface.cxx
index 1883f9f09af..151c4f5eb6f 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaSurface.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaSurface.cxx
@@ -244,19 +244,19 @@ MetaSurface::M_Read()
   MET_FieldRecordType * mF;
 
   mF = MET_GetFieldRecord("NPoints", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     m_NPoints = static_cast<int>(mF->value[0]);
   }
 
   mF = MET_GetFieldRecord("ElementType", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     MET_StringToType(reinterpret_cast<char *>(mF->value), &m_ElementType);
   }
 
   mF = MET_GetFieldRecord("PointDim", &m_Fields);
-  if (mF->defined)
+  if (mF && mF->defined)
   {
     strcpy(m_PointDim, reinterpret_cast<char *>(mF->value));
   }
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.cxx
index 591fd663a70..abbf7574f73 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.cxx
@@ -590,7 +590,7 @@ MET_ValueToValue(MET_ValueEnumType _fromType,
 // Uncompress a stream given an uncompressedSeekPosition
 METAIO_EXPORT
 std::streamoff
-MET_UncompressStream(std::ifstream *            stream,
+MET_UncompressStream(METAIO_STREAM::ifstream *            stream,
                      std::streamoff             uncompressedSeekPosition,
                      unsigned char *            uncompressedData,
                      std::streamoff             uncompressedDataSize,
@@ -1910,6 +1910,66 @@ MET_SwapByteIfSystemMSB(void * val, MET_ValueEnumType _type)
   }
 }
 
+
+void MET_PrintFieldRecord(std::ostream & _fp, MET_FieldRecordType * _mf)
+{
+  if (_mf == nullptr)
+  {
+    _fp << "NULL Field Record" << '\n';
+    return;
+  }
+  _fp << "Name = " << _mf->name << '\n';
+  _fp << "Type = " << MET_ValueTypeName[_mf->type] << '\n';
+  _fp << "Defined = " << _mf->defined << '\n';
+  _fp << "Length = " << _mf->length << '\n';
+  _fp << "DependsOn = " << _mf->dependsOn << '\n';
+  _fp << "Required = " << _mf->required << '\n';
+  _fp << "TerminateRead = " << _mf->terminateRead << '\n';
+  _fp << "Value = ";
+  if (!_mf->defined)
+  {
+    _fp << "Undefined" << '\n';
+    return;
+  }
+  if (_mf->type == MET_STRING)
+  {
+    _fp << reinterpret_cast<char *>(_mf->value) << '\n';
+  }
+  else if (_mf->type == MET_ASCII_CHAR || _mf->type == MET_CHAR || _mf->type == MET_UCHAR ||
+           _mf->type == MET_SHORT || _mf->type == MET_USHORT || _mf->type == MET_LONG ||
+           _mf->type == MET_ULONG || _mf->type == MET_INT || _mf->type == MET_UINT ||
+           _mf->type == MET_FLOAT || _mf->type == MET_DOUBLE)
+  {
+    _fp << _mf->name << " : " << _mf->value[0] << '\n';
+  }
+  else if (_mf->type == MET_CHAR_ARRAY || _mf->type == MET_UCHAR_ARRAY || _mf->type == MET_SHORT_ARRAY ||
+           _mf->type == MET_USHORT_ARRAY || _mf->type == MET_INT_ARRAY || _mf->type == MET_UINT_ARRAY ||
+           _mf->type == MET_FLOAT_ARRAY || _mf->type == MET_DOUBLE_ARRAY)
+  {
+    _fp << _mf->value[0];
+    for (int i = 1; i < _mf->length; i++)
+    {
+      _fp << ", " << _mf->value[i];
+    }
+    _fp << '\n';
+  }
+  else if (_mf->type == MET_FLOAT_MATRIX)
+  {
+    _fp << '\n';
+    int count = 0;
+    for (int i = 0; i < _mf->length; i++)
+    {
+      _fp << _mf->value[count++];
+      for (int j = 1; j < _mf->length; j++)
+      {
+        _fp << ", " << _mf->value[count++];
+      }
+      _fp << '\n';
+    }
+  }
+}
+
+
 #if (METAIO_USE_NAMESPACE)
 };
 #endif
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.h b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.h
index 0deef82a311..8f85d3a1dbf 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.h
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/metaUtils.h
@@ -349,7 +349,7 @@ MET_PerformUncompression(const unsigned char * sourceCompressed,
 // Uncompress a stream given an uncompressedSeekPosition
 METAIO_EXPORT
 std::streamoff
-MET_UncompressStream(std::ifstream *            stream,
+MET_UncompressStream(METAIO_STREAM::ifstream *            stream,
                      std::streamoff             uncompressedSeekPosition,
                      unsigned char *            uncompressedData,
                      std::streamoff             uncompressedDataSize,
@@ -442,6 +442,10 @@ MET_Read(std::istream &                       fp,
          std::vector<MET_FieldRecordType *> * newFields = nullptr);
 
 
+METAIO_EXPORT
+void
+MET_PrintFieldRecord(std::ostream & _fp, MET_FieldRecordType * _mf);
+
 METAIO_EXPORT
 std::string
 MET_ReadForm(std::istream & _fp);


Test patch:
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta2Object.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta2Object.cxx
index c79c6f15de7..b1385ad061d 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta2Object.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta2Object.cxx
@@ -40,25 +40,31 @@ main(int, char *[])
   float myMatrix[4];
   for (i = 0; i < 4; i++)
   {
-    myMatrix[i] = i;
+    myMatrix[i] = static_cast<float>(i);
   }
   tObj.AddUserField("MyMatrix", MET_FLOAT_MATRIX, 2, myMatrix);
 
+  std::cout << "*** Writing this info..." << std::endl;
   tObj.PrintInfo();
   tObj.Write();
 
   tObj.Clear();
   tObj.ClearUserFields();
 
+  std::cout << "*** Adding user fields..." << std::endl;
   tObj.AddUserField("MyName", MET_STRING);
   tObj.AddUserField("MyArray", MET_INT_ARRAY, 3);
   tObj.AddUserField("MyMatrix", MET_FLOAT_MATRIX, 2);
 
+  std::cout << "*** Pre-reading..." << std::endl;
+  tObj.PrintInfo();
+  std::cout << "*** Reading..." << std::endl;
   tObj.Read();
+  std::cout << "*** Reading results..." << std::endl;
   tObj.PrintInfo();
 
   char * name = static_cast<char *>(tObj.GetUserField("MyName"));
-  if (strcmp(name, "Julien") != 0)
+  if (name == nullptr || strcmp(name, "Julien") != 0)
   {
     std::cout << "MyName: FAIL" << '\n';
     return EXIT_FAILURE;
@@ -69,7 +75,7 @@ main(int, char *[])
   int * array = static_cast<int *>(tObj.GetUserField("MyArray"));
   for (i = 0; i < 3; i++)
   {
-    if (array[i] != i + 1)
+    if (array == nullptr || array[i] != i + 1)
     {
       std::cout << "MyArray: FAIL" << '\n';
       delete[] array;
@@ -82,7 +88,7 @@ main(int, char *[])
   auto * matrix = static_cast<float *>(tObj.GetUserField("MyMatrix"));
   for (i = 0; i < 4; i++)
   {
-    if (matrix[i] != i)
+    if (matrix == nullptr || matrix[i] != i)
     {
       std::cout << "MyMatrix: FAIL" << '\n';
       delete[] matrix;
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta4Tube.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta4Tube.cxx
index 5e41df30224..e5fffcde703 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta4Tube.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta4Tube.cxx
@@ -25,10 +25,11 @@ main(int, char *[])
   for (i = 0; i < 10; i++)
   {
     pnt = new TubePnt(3);
-    pnt->m_X[0] = i;
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
-    pnt->m_R = i;
+    float i_f = static_cast<float>(i);
+    pnt->m_X[0] = i_f;
+    pnt->m_X[1] = i_f;
+    pnt->m_X[2] = i_f;
+    pnt->m_R = i_f;
     tube1->GetPoints().push_back(pnt);
   }
 
@@ -38,10 +39,11 @@ main(int, char *[])
   for (i = 0; i < 5; i++)
   {
     pnt = new TubePnt(3);
-    pnt->m_X[0] = i;
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
-    pnt->m_R = i;
+    float i_f = static_cast<float>(i);
+    pnt->m_X[0] = i_f;
+    pnt->m_X[1] = i_f;
+    pnt->m_X[2] = i_f;
+    pnt->m_R = i_f;
     tube2->GetPoints().push_back(pnt);
   }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta5Blob.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta5Blob.cxx
index 0772304173f..33e3da1b6a0 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta5Blob.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta5Blob.cxx
@@ -20,8 +20,8 @@ main(int, char *[])
   {
     pnt = new BlobPnt(3);
     pnt->m_X[0] = static_cast<float>(0.2);
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
+    pnt->m_X[1] = static_cast<float>(i);
+    pnt->m_X[2] = static_cast<float>(i);
     blob.GetPoints().push_back(pnt);
   }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta6Surface.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta6Surface.cxx
index 116501d31e2..cf4db0eedfa 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta6Surface.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta6Surface.cxx
@@ -15,11 +15,12 @@ main(int, char *[])
   {
     pnt = new SurfacePnt(3);
     pnt->m_X[0] = static_cast<float>(0.2);
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
+    float i_f = static_cast<float>(i);
+    pnt->m_X[1] = i_f;
+    pnt->m_X[2] = i_f;
     pnt->m_V[0] = static_cast<float>(0.8);
-    pnt->m_V[1] = i;
-    pnt->m_V[2] = i;
+    pnt->m_V[1] = i_f;
+    pnt->m_V[2] = i_f;
     surface->GetPoints().push_back(pnt);
   }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta7Line.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta7Line.cxx
index 32ecec0f878..012243c94d5 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta7Line.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta7Line.cxx
@@ -15,14 +15,15 @@ main(int, char *[])
   {
     pnt = new LinePnt(3);
     pnt->m_X[0] = static_cast<float>(0.2);
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
+    float i_f = static_cast<float>(i);
+    pnt->m_X[1] = i_f;
+    pnt->m_X[2] = i_f;
     pnt->m_V[0][0] = static_cast<float>(0.3);
-    pnt->m_V[0][1] = i;
-    pnt->m_V[0][2] = i;
+    pnt->m_V[0][1] = i_f;
+    pnt->m_V[0][2] = i_f;
     pnt->m_V[1][0] = static_cast<float>(0.4);
-    pnt->m_V[1][1] = i + 1;
-    pnt->m_V[1][2] = i + 1;
+    pnt->m_V[1][1] = i_f + 1;
+    pnt->m_V[1][2] = i_f + 1;
     Line->GetPoints().push_back(pnt);
   }
 
diff --git a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta9Landmark.cxx b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta9Landmark.cxx
index d53293ca23c..5912775aaf7 100644
--- a/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta9Landmark.cxx
+++ b/Modules/ThirdParty/MetaIO/src/MetaIO/src/tests/testMeta9Landmark.cxx
@@ -16,8 +16,8 @@ main(int, char *[])
   {
     pnt = new LandmarkPnt(3);
     pnt->m_X[0] = static_cast<float>(0.2);
-    pnt->m_X[1] = i;
-    pnt->m_X[2] = i;
+    pnt->m_X[1] = static_cast<float>(i);
+    pnt->m_X[2] = static_cast<float>(i);
     Landmark.GetPoints().push_back(pnt);
   }