text: /*=========================================================================
   *
   *  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
   *
   *         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 itkComplexBSplineInterpolateImageFunction_h
  #define itkComplexBSplineInterpolateImageFunction_h
  
  #include "itkBSplineInterpolateImageFunction.h"
  #include "itkComplexToRealImageFilter.h"
  #include "itkComplexToImaginaryImageFilter.h"
  
  namespace itk
  {
  /**
   * \class ComplexBSplineInterpolateImageFunction.
   * \brief Complex wrapper around BSplineInterpolateImageFunction.
   *
   * A complex wrapper class that splits complex input image in two real-type
   * subimages containing real and imaginary parts, that are interpolated using
   * the standard itkBSplineInterpolateImageFunction. The same requirements apply
   * for this class: Set spline order before setting the input image!
   * Derivative support is currently not implemented
   *
   * This implementation was taken from the Insight Journal paper:
   * https://hdl.handle.net/1926/585
   *
   * \ingroup ImageInterpolators
   * \ingroup ITKReview
   */
  template <typename TImageType, typename TCoordRep = double, typename TCoefficientType = double>
  class ITK_TEMPLATE_EXPORT ComplexBSplineInterpolateImageFunction
    : public InterpolateImageFunction<TImageType, TCoordRep>
  {
  public:
    ITK_DISALLOW_COPY_AND_ASSIGN(ComplexBSplineInterpolateImageFunction);
  
    /** Standard class type alias. */
    using Self = ComplexBSplineInterpolateImageFunction;
    /** Standard class type alias. */
    using Superclass = InterpolateImageFunction<TImageType, TCoordRep>;
    /** Standard class type alias. */
    using Pointer = SmartPointer<Self>;
    /** Standard class type alias. */
    using ConstPointer = SmartPointer<const Self>;
  
    /** Run-time type information (and related methods). */
    itkTypeMacro(ComplexBSplineInterpolateImageFunction, InterpolateImageFunction);
  
    /** New macro for creation of through a Smart Pointer */
    itkNewMacro(Self);
  
    /** Dimension underlying input image. */
    static constexpr unsigned int ImageDimension = Superclass::ImageDimension;
  
    /** OutputType type alias support */
    using OutputType = typename Superclass::OutputType;
  
    /** InputImageType type alias support */
    using InputImageType = typename Superclass::InputImageType;
  
    /** Index type alias support */
    using IndexType = typename Superclass::IndexType;
  
    /** Size type alias support */
    using SizeType = typename Superclass::SizeType;
  
    /** ContinuousIndex type alias support */
    using ContinuousIndexType = typename Superclass::ContinuousIndexType;
  
    /** PointType type alias support */
    using PointType = typename Superclass::PointType;
  
    /** Internal Real and imaginary image type */
    using InternalImageType = Image<double, Self::ImageDimension>;
  
    /** Complex to Real filter type */
    using RealFilterType = ComplexToRealImageFilter<InputImageType, InternalImageType>;
    using ImaginaryFilterType = ComplexToImaginaryImageFilter<InputImageType, InternalImageType>;
  
    /** Underlying real BSpline interpolator */
    using InterpolatorType = BSplineInterpolateImageFunction<InternalImageType, TCoordRep, TCoefficientType>;
  
    /** Evaluate the function at a ContinuousIndex position.
     *
     * Returns the B-Spline interpolated image intensity at a
     * specified point position. No bounds checking is done.
     * The point is assumed to lie within the image buffer.
     *
     * ImageFunction::IsInsideBuffer() can be used to check bounds before
     * calling the method. */
    OutputType
    EvaluateAtContinuousIndex(const ContinuousIndexType & index) const override;
  
    /** Derivative type alias support */
    /*  using CovariantVectorType = CovariantVector< OutputType, Self::ImageDimension  >;
  
      CovariantVectorType EvaluateDerivative( const PointType & point ) const
      {
       ContinuousIndexType index;
       this->GetInputImage()->TransformPhysicalPointToContinuousIndex( point, index );
       return ( this->EvaluateDerivativeAtContinuousIndex( index ) );
      }
  
      CovariantVectorType EvaluateDerivativeAtContinuousIndex( const ContinuousIndexType & x ) const;
    */
  
    /** Get/Sets the Spline Order, supports 0th - 5th order splines. The default
     *  is a 3rd order spline. */
    void
    SetSplineOrder(unsigned int SplineOrder);
  
    itkGetConstMacro(SplineOrder, int);
  
    /** Set the input image.  This must be set by the user, after setting the
      spline order! */
    void
    SetInputImage(const TImageType * inputData) override;
  
    SizeType
    GetRadius() const override
    {
      return SizeType::Filled(m_SplineOrder + 1);
    }
  
  protected:
    ComplexBSplineInterpolateImageFunction();
    ~ComplexBSplineInterpolateImageFunction() override = default;
  
    void
    PrintSelf(std::ostream & os, Indent indent) const override;
  
  private:
    unsigned int m_SplineOrder;
  
    typename InterpolatorType::Pointer m_RealInterpolator;
    typename InterpolatorType::Pointer m_ImaginaryInterpolator;
  
    typename RealFilterType::Pointer m_RealFilter;
  
    typename ImaginaryFilterType::Pointer m_ImaginaryFilter;
  }; // class
  } // namespace itk
  
  #ifndef ITK_MANUAL_INSTANTIATION
  #  include "itkComplexBSplineInterpolateImageFunction.hxx"
  #endif
  
  #endif
  