text: /*=========================================================================
   *
   *  Copyright Insight Software Consortium
   *
   *  Licensed under the Apache License, Version 2.0 (the "License");
   *  you may not use this file except in compliance with the License.
   *  You may obtain a copy of the License at
   *
   *         http://www.apache.org/licenses/LICENSE-2.0.txt
   *
   *  Unless required by applicable law or agreed to in writing, software
   *  distributed under the License is distributed on an "AS IS" BASIS,
   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   *  See the License for the specific language governing permissions and
   *  limitations under the License.
   *
   *=========================================================================*/
  #ifndef itkMetaArrayWriter_h
  #define itkMetaArrayWriter_h
  #include "ITKIOMetaExport.h"
  
  #include "itkLightProcessObject.h"
  #include "itkArray.h"
  #include "itkCovariantVector.h"
  #include "itkVariableLengthVector.h"
  #include "metaArray.h"
  
  namespace itk
  {
  class ITKIOMeta_EXPORT MetaArrayWriter : public LightProcessObject
  {
  public:
    /** SmartPointer type alias support */
    using Self = MetaArrayWriter;
    using Superclass = LightProcessObject;
  
    using Pointer = SmartPointer<Self>;
    using ConstPointer = SmartPointer<const Self>;
  
    /** Method for creation through the object factory. */
    itkNewMacro(Self);
  
    /** Run-time type information (and related methods). */
    itkTypeMacro(MetaArrayWriter, LightProcessObject);
  
    /** Set/Get the filename. */
    itkSetStringMacro(FileName);
    itkGetStringMacro(FileName);
  
    /** Set/Get the filename to which the data is written.
     *  Optional: use if header and data should be in separate files. */
    itkSetStringMacro(DataFileName);
    itkGetStringMacro(DataFileName);
  
    /** Boolean to set binary mode.
     *  If set to On, data will be stored in the file in binary format; if set
     *  to Off, data will be stored in ascci format.
     *  Default is Off. */
    itkBooleanMacro(Binary);
    itkSetMacro(Binary, bool);
    itkGetConstMacro(Binary, bool);
  
    /** Set the input itk Array to write. */
    template <typename TValue>
    void
    SetInput(MET_ValueEnumType _metaElementType, const Array<TValue> * _array)
    {
      m_Buffer = (const void *)(_array->data_block());
      m_MetaArray.InitializeEssential(_array->Size(), _metaElementType);
    }
  
    /** Set the input itk FixedArray to write. */
    template <typename TValue, unsigned int VLength>
    void
    SetInput(MET_ValueEnumType _metaElementType, const FixedArray<TValue, VLength> * _array)
    {
      m_Buffer = (const void *)(_array->GetDataPointer());
      m_MetaArray.InitializeEssential(VLength, _metaElementType);
    }
  
    /** Set the input itk Vector to write. */
    template <typename TValue, unsigned int VLength>
    void
    SetInput(MET_ValueEnumType _metaElementType, const Vector<TValue, VLength> * _vector)
    {
      m_Buffer = (const void *)(_vector->GetDataPointer());
      m_MetaArray.InitializeEssential(VLength, _metaElementType);
    }
  
    /** Set the input itk CovariantVector to write. */
    template <typename TValue, unsigned int VLength>
    void
    SetInput(MET_ValueEnumType _metaElementType, const CovariantVector<TValue, VLength> * _vector)
    {
      m_Buffer = (const void *)(_vector->GetDataPointer());
      m_MetaArray.InitializeEssential(VLength, _metaElementType);
    }
  
    /** Set the input itk VariableLengthVector to write. */
    template <typename TValue>
    void
    SetInput(MET_ValueEnumType _metaElementType, const VariableLengthVector<TValue> * _vector)
    {
      m_Buffer = (const void *)(_vector->GetDataPointer());
      m_MetaArray.InitializeEssential(_vector->Size(), _metaElementType);
    }
  
    /** Copies the elements from an array of arrays into the output
     *  buffer. Requires all sub-arrays to have the same length.
     *  length of the major array is the "length" of the array, while
     *  the length of the sub-arrays is the "number of channels" at each
     *  array position. Expected form itk::Array< itk::Array< * > >.
     *  May work for othesub-array-types that define the [] operator and the
     *  GetSize() function. */
    template <typename TValue>
    void
    SetMultiChannelInput(MET_ValueEnumType _metaElementType, int, const Array<TValue> * _array)
    {
      int rows = _array->GetSize();
      int cols = (*_array)[0].GetSize();
  
      m_MetaArray.InitializeEssential(rows, _metaElementType, cols, nullptr, true, true);
      m_Buffer = m_MetaArray.ElementData();
      for (int i = 0; i < rows; i++)
      {
        for (int j = 0; j < cols; j++)
        {
          m_MetaArray.ElementData(i * cols + j, (double)((*_array)[i][j]));
        }
      }
    }
  
    /** Set/Get the precision of the writing. */
    itkSetMacro(Precision, unsigned int);
    itkGetConstMacro(Precision, unsigned int);
  
    /** Set the data type written to the file. */
    void
    ConvertTo(MET_ValueEnumType _metaElementType);
  
    /** Write out the array. */
    void
    Update();
  
  protected:
    MetaArrayWriter();
    ~MetaArrayWriter() override;
    void
    PrintSelf(std::ostream & os, Indent indent) const override;
  
  private:
    bool m_Binary{ false };
  
    unsigned int m_Precision{ 6 };
  
    std::string m_FileName;
    std::string m_DataFileName;
  
    MetaArray m_MetaArray;
  
    const void * m_Buffer{ nullptr };
  };
  } // namespace itk
  
  #endif // itkMetaArrayWriter_h
  