/*========================================================================= * * Copyright NumFOCUS * * 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 * * https://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 itkMetaArrayReader_h #define itkMetaArrayReader_h #include "ITKIOMetaExport.h" #include "itkLightProcessObject.h" #include "itkArray.h" #include "itkCovariantVector.h" #include "itkVariableLengthVector.h" #include "metaArray.h" namespace itk { class ITKIOMeta_EXPORT MetaArrayReader : public LightProcessObject { public: /** SmartPointer type alias support */ using Self = MetaArrayReader; using Superclass = LightProcessObject; using Pointer = SmartPointer; using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkNewMacro(Self); /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(MetaArrayReader); /** Set the filename. */ itkSetStringMacro(FileName); /** Get the filename. */ itkGetStringMacro(FileName); /** Get a pointer to the MetaArray so that its options, such as adding * comments and user-defined fields, can be changed. */ MetaArray * GetMetaArrayPointer(); /** Specify the buffer (already allocated) into which data should be read. */ void SetBuffer(void * _buffer); /** Read the Array in MetaIO format. */ void Update(); /** Return the MetaIO type that corresponds to the element type. */ MET_ValueEnumType GetDataType() const { return m_MetaArray.ElementType(); } /** Size is used by itkArray and VariableLengthVector. */ int Size() const { return m_MetaArray.Length(); } /** GetNumberOfElements is used by itkArray and VariableLengthVector. */ int GetNumberOfElements() const { return m_MetaArray.Length(); } /** GetVectorDimension is used by itkVector. */ int GetVectorDimension() const { return m_MetaArray.Length(); } /** GetNumberOfComponents is used by itkVector and itkCovariantVector. */ int GetNumberOfComponents() const { return m_MetaArray.Length(); } /** GetCovariantVectorDimension is used by itkVector. */ int GetCovariantVectorDimension() const { return m_MetaArray.Length(); } /** GetElement is used by itkArray, itkFixedArray, and VariableLengthVector. */ template inline void GetElement(TValue & value, unsigned int i, unsigned int channel = 0) const { value = static_cast(m_MetaArray.ElementData(i * m_MetaArray.ElementNumberOfChannels() + channel)); } /** Get an itkArray. * Specify the MetaType of the elements of the Array and provide a * pointer to the Array. The buffer of the Array is replaced by the * buffer into which the data was directly read (a copy does not occur). * If _letVectorManageData is true, the buffer persists even after this * MetaArrayReader is destroyed. Otherwise, the buffer (and therefore * the validity of the data in the Array) is destroyed when the * MetaArrayReader is destroyed. */ template void GetOutput(MET_ValueEnumType _metaElementType, Array * _array, bool _letArrayManageData = true) { if (m_MetaArray.ElementType() != _metaElementType) { m_MetaArray.ConvertElementDataTo(_metaElementType); } _array->SetData((TValue *)(m_MetaArray.ElementData()), m_MetaArray.Length(), _letArrayManageData); if (_letArrayManageData) { m_MetaArray.AutoFreeElementData(false); } } /** Get an itkFixedArray. */ template bool GetOutput(MET_ValueEnumType itkNotUsed(_metaElementType), FixedArray * _array) { if (static_cast(VLength) <= m_MetaArray.Length()) { unsigned int i; for (i = 0; i < VLength; ++i) { this->GetElement((*_array)[i], i); } return true; } return false; } /** Get an itkVector. * Specify the MetaType of the elements of the itkVector and provide * a pointer to the itkVector into which the data should be copied. */ template bool GetOutput(MET_ValueEnumType itkNotUsed(_metaElementType), Vector * _vector) { if (static_cast(VLength) <= m_MetaArray.Length()) { unsigned int i; for (i = 0; i < VLength; ++i) { this->GetElement((*_vector)[i], i); } return true; } return false; } /** Get an itkCovariantVector. * Specify the MetaType of the elements of the itkCovariantVector and * provide a pointer to the itkCovariantVector into which the data * should be copied. */ template bool GetOutput(MET_ValueEnumType itkNotUsed(_metaElementType), CovariantVector * _vector) { if (static_cast(VLength) <= m_MetaArray.Length()) { unsigned int i; for (i = 0; i < VLength; ++i) { this->GetElement((*_vector)[i], i); } return true; } return false; } /** Get it VariableLengthVector. * Specify the MetaType of the elements of the VariableLengthVector and * provide a pointer to the VariableLengthVector. The buffer of the * VariableLengthVector is replaced by the buffer into which the data * was directly read (a copy does not occur). * If _letVectorManageData is true, the buffer persists even after this * MetaArrayReader is destroyed. Otherwise, the buffer (and therefore * the validity of the data in the VariableLengthVector) is destroyed * when the MetaArrayReader is destroyed. */ template void GetOutput(MET_ValueEnumType _metaElementType, VariableLengthVector * _vector, bool _letVectorManageData = true) { if (m_MetaArray.ElementType() != _metaElementType) { m_MetaArray.ConvertElementDataTo(_metaElementType); } _vector->SetData((TValue *)(m_MetaArray.ElementData()), m_MetaArray.Length(), _letVectorManageData); if (_letVectorManageData) { m_MetaArray.AutoFreeElementData(false); } } /** Get an itkArray of Arrays, itk::Array< itk::Array >. * Assumes all sub-arrays have the same length. * Specify the MetaType of the elements of the Array< Array< * > > and * provide a pointer to the Array of arrays. Elements are copied * into the array of arrays. */ template void GetMultiChannelOutput(MET_ValueEnumType _metaElementType, Array * _array) { if (m_MetaArray.ElementType() != _metaElementType) { m_MetaArray.ConvertElementDataTo(_metaElementType); } int rows = m_MetaArray.Length(); int cols = m_MetaArray.ElementNumberOfChannels(); _array->SetSize(rows); for (int i = 0; i < rows; ++i) { (*_array)[i].SetSize(cols); for (int j = 0; j < cols; ++j) { (*_array)[i][j] = static_cast(m_MetaArray.ElementData(i * cols + j)); } } } protected: MetaArrayReader(); ~MetaArrayReader() override; void PrintSelf(std::ostream & os, Indent indent) const override; private: MetaArray m_MetaArray{}; std::string m_FileName{}; void * m_Buffer{ nullptr }; }; } // namespace itk #endif // itkMetaArrayReader_h