/*========================================================================= * * 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 itkNthElementPixelAccessor_h #define itkNthElementPixelAccessor_h #include "itkMacro.h" #include "itkDefaultConvertPixelTraits.h" #include "itkVariableLengthVector.h" #include "itkDefaultVectorPixelAccessor.h" namespace itk { /** * \class NthElementPixelAccessor * \brief Give access to the N-th of a Container type * * This class is intended to be used as parameter of * an ImageAdaptor to make a Container appears as being * of scalar type T, showing only the N-th component. * * This class is templated over the container type. * Any container type that provides a method: * operator[]( unsigned int ) can be used here, * for example: itkPoint, itkVector, itkVectorContainer, * and std::vector. * * For performance, no bound checking is performed during * access to the n-th element. * * \sa ImageAdaptor * \sa PixelAccessor * * \ingroup ImageAdaptors * \ingroup ITKImageAdaptors */ template class NthElementPixelAccessor { public: /** Standard class type aliases. */ using Self = NthElementPixelAccessor; /** that this class will exhibit */ using ExternalType = T; /** Internal type alias. It defines the internal real * representation of data */ using InternalType = TContainer; /** Write access to the NthElement component */ inline void Set(InternalType & output, const ExternalType & input) const { DefaultConvertPixelTraits::SetNthComponent(m_ElementNumber, output, input); } /** Read access to the NthElement component */ inline ExternalType Get(const InternalType & input) const { return static_cast(DefaultConvertPixelTraits::GetNthComponent(m_ElementNumber, input)); } /** Get the element number to access in the container */ unsigned int GetElementNumber() const { return m_ElementNumber; } /** Set the element number to access in the container */ void SetElementNumber(unsigned int nth) { m_ElementNumber = nth; } /** This is needed to convert a pixel accessor to a functor. * \sa AdaptImageFilter */ bool operator==(const Self & accessor) const { return m_ElementNumber == accessor.m_ElementNumber; } ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(Self); /** Assignment operator */ NthElementPixelAccessor & operator=(const NthElementPixelAccessor & accessor) { m_ElementNumber = accessor.m_ElementNumber; return *this; } /** Constructor */ NthElementPixelAccessor() { m_ElementNumber = 0; } private: // Identifier of the N-th element to be accessed unsigned int m_ElementNumber; }; template class NthElementPixelAccessor> : private DefaultVectorPixelAccessor { public: /** Standard class type aliases. */ using Self = NthElementPixelAccessor; using VectorLengthType = unsigned int; /** External type alias. It defines the external aspect * that this class will exhibit. */ using ExternalType = TOutputPixelType; /** Internal type alias used by the ImageAdaptor for the buffer pointer */ using InternalType = TPixelType; using ActualPixelType = VariableLengthVector; inline void Set(ActualPixelType & output, const ExternalType & input) const { output[m_ElementNumber] = input; } inline void Set(InternalType & output, const ExternalType & input, const unsigned long offset) const { // note: v is a reference to the internal buffer, this method of // access relies on return value optimization to work ActualPixelType v = Superclass::Get(output, offset); return Set(v, input); } inline ExternalType Get(const ActualPixelType & input) const { ExternalType output; output = static_cast(input[m_ElementNumber]); return output; } inline ExternalType Get(const InternalType & input, const SizeValueType offset) const { return Get(Superclass::Get(input, offset)); } /** Get the element number to access in the container */ unsigned int GetElementNumber() const { return m_ElementNumber; } /** Set the element number to access in the container */ void SetElementNumber(unsigned int nth) { m_ElementNumber = nth; } /** Set the length of each vector in the VectorImage */ void SetVectorLength(VectorLengthType l) { Superclass::SetVectorLength(l); } /** Get Vector lengths */ VectorLengthType GetVectorLength() const { return Superclass::GetVectorLength(); } NthElementPixelAccessor(unsigned int length = 1) { Superclass::SetVectorLength(length); } /** This is needed to convert a pixel accessor to a functor. * \sa AdaptImageFilter */ bool operator==(const Self & accessor) const { return m_ElementNumber == accessor.m_ElementNumber; } ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(Self); /** Assignment operator */ NthElementPixelAccessor & operator=(const NthElementPixelAccessor & accessor) { m_ElementNumber = accessor.m_ElementNumber; this->SetVectorLength(accessor.GetVectorLength()); return *this; } protected: using Superclass = DefaultVectorPixelAccessor; private: VectorLengthType m_ElementNumber{ 0 }; }; } // end namespace itk #endif