/*========================================================================= * * 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 itkZeroFluxNeumannImageNeighborhoodPixelAccessPolicy_h #define itkZeroFluxNeumannImageNeighborhoodPixelAccessPolicy_h #include "itkIndex.h" #include "itkOffset.h" #include "itkSize.h" namespace itk { /** * \class ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy * ImageNeighborhoodPixelAccessPolicy class for ShapedImageNeighborhoodRange. * Allows getting and setting the value of a pixel, located in a specified * neighborhood location, at a specified offset. Uses "border replication" as * extrapolation method for pixels outside the image border. * * \see ShapedNeighborhoodIterator * \see ZeroFluxNeumannBoundaryCondition * \ingroup ImageIterators * \ingroup ITKCommon */ template class ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy final { private: using NeighborhoodAccessorFunctorType = typename TImage::NeighborhoodAccessorFunctorType; using PixelType = typename TImage::PixelType; using InternalPixelType = typename TImage::InternalPixelType; using ImageDimensionType = typename TImage::ImageDimensionType; static constexpr ImageDimensionType ImageDimension = TImage::ImageDimension; using IndexType = Index; using OffsetType = Offset; using ImageSizeType = Size; using ImageSizeValueType = SizeValueType; // Index value to the image buffer, indexing the current pixel. const IndexValueType m_PixelIndexValue; // A reference to the accessor of the image. const NeighborhoodAccessorFunctorType & m_NeighborhoodAccessor; // Private helper function. Clamps the index value between the interval // [0 .. imageSizeValue>. static IndexValueType GetClampedIndexValue(const IndexValueType indexValue, const ImageSizeValueType imageSizeValue) noexcept { return (indexValue <= 0) ? 0 : (static_cast(indexValue) < imageSizeValue) ? indexValue : static_cast(imageSizeValue - 1); } // Private helper function. Calculates and returns the index value of the // current pixel within the image buffer. static IndexValueType CalculatePixelIndexValue(const ImageSizeType & imageSize, const OffsetType & offsetTable, const IndexType & pixelIndex) noexcept { IndexValueType result = 0; for (ImageDimensionType i = 0; i < ImageDimension; ++i) { result += GetClampedIndexValue(pixelIndex[i], imageSize[i]) * offsetTable[i]; } return result; } public: // Deleted member functions: ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy() = delete; ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy & operator=(const ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy &) = delete; // Explicitly-defaulted functions: ~ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy() = default; ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy( const ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy &) noexcept = default; /** Constructor called directly by the pixel proxy of * ShapedImageNeighborhoodRange. */ ZeroFluxNeumannImageNeighborhoodPixelAccessPolicy(const ImageSizeType & imageSize, const OffsetType & offsetTable, const NeighborhoodAccessorFunctorType & neighborhoodAccessor, const IndexType & pixelIndex) noexcept : m_PixelIndexValue{ CalculatePixelIndexValue(imageSize, offsetTable, pixelIndex) } , m_NeighborhoodAccessor(neighborhoodAccessor) {} /** Retrieves the pixel value from the image buffer, at the current * index value. */ PixelType GetPixelValue(const InternalPixelType * const imageBufferPointer) const noexcept { return m_NeighborhoodAccessor.Get(imageBufferPointer + m_PixelIndexValue); } /** Sets the value of the image buffer at the current index value to the * specified value. */ void SetPixelValue(InternalPixelType * const imageBufferPointer, const PixelType & pixelValue) const noexcept { m_NeighborhoodAccessor.Set(imageBufferPointer + m_PixelIndexValue, pixelValue); } }; } // namespace itk #endif