text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkImageSincInterpolator.h
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /**
   * @class   vtkImageSincInterpolator
   * @brief   perform sinc interpolation on images
   *
   * vtkImageSincInterpolator provides various windowed sinc interpolation
   * methods for image data.  The default is a five-lobed Lanczos interpolant,
   * with a kernel size of 6.  The interpolator can also bandlimit the image,
   * which can be used for antialiasing.  The interpolation kernels are
   * evaluated via a lookup table for efficiency.
   * @par Thanks:
   * Thanks to David Gobbi at the Seaman Family MR Centre and Dept. of Clinical
   * Neurosciences, Foothills Medical Centre, Calgary, for providing this class.
   * @sa
   * vtkImageReslice
   */
  
  #ifndef vtkImageSincInterpolator_h
  #define vtkImageSincInterpolator_h
  
  #include "vtkAbstractImageInterpolator.h"
  #include "vtkImagingCoreModule.h" // For export macro
  
  #define VTK_LANCZOS_WINDOW 0
  #define VTK_KAISER_WINDOW 1
  #define VTK_COSINE_WINDOW 2
  #define VTK_HANN_WINDOW 3
  #define VTK_HAMMING_WINDOW 4
  #define VTK_BLACKMAN_WINDOW 5
  #define VTK_BLACKMAN_HARRIS3 6
  #define VTK_BLACKMAN_HARRIS4 7
  #define VTK_NUTTALL_WINDOW 8
  #define VTK_BLACKMAN_NUTTALL3 9
  #define VTK_BLACKMAN_NUTTALL4 10
  #define VTK_SINC_KERNEL_SIZE_MAX 32
  
  class vtkImageData;
  struct vtkInterpolationInfo;
  
  class VTKIMAGINGCORE_EXPORT vtkImageSincInterpolator : public vtkAbstractImageInterpolator
  {
  public:
    static vtkImageSincInterpolator* New();
    vtkTypeMacro(vtkImageSincInterpolator, vtkAbstractImageInterpolator);
    void PrintSelf(ostream& os, vtkIndent indent) override;
  
    //@{
    /**
     * The window function to use.  The default is Lanczos, which is very
     * popular and performs well with a kernel width of 6.  The Cosine
     * window is included for historical reasons.  All other windows are
     * described in AH Nuttall, "Some windows with very good sidelobe
     * behavior," IEEE Transactions on Acoustics, Speech, and Signal
     * Processing 29:84-91, 1981.
     */
    virtual void SetWindowFunction(int mode);
    void SetWindowFunctionToLanczos() { this->SetWindowFunction(VTK_LANCZOS_WINDOW); }
    void SetWindowFunctionToKaiser() { this->SetWindowFunction(VTK_KAISER_WINDOW); }
    void SetWindowFunctionToCosine() { this->SetWindowFunction(VTK_COSINE_WINDOW); }
    void SetWindowFunctionToHann() { this->SetWindowFunction(VTK_HANN_WINDOW); }
    void SetWindowFunctionToHamming() { this->SetWindowFunction(VTK_HAMMING_WINDOW); }
    void SetWindowFunctionToBlackman() { this->SetWindowFunction(VTK_BLACKMAN_WINDOW); }
    void SetWindowFunctionToBlackmanHarris3() { this->SetWindowFunction(VTK_BLACKMAN_HARRIS3); }
    void SetWindowFunctionToBlackmanHarris4() { this->SetWindowFunction(VTK_BLACKMAN_HARRIS4); }
    void SetWindowFunctionToNuttall() { this->SetWindowFunction(VTK_NUTTALL_WINDOW); }
    void SetWindowFunctionToBlackmanNuttall3() { this->SetWindowFunction(VTK_BLACKMAN_NUTTALL3); }
    void SetWindowFunctionToBlackmanNuttall4() { this->SetWindowFunction(VTK_BLACKMAN_NUTTALL4); }
    int GetWindowFunction() { return this->WindowFunction; }
    virtual const char* GetWindowFunctionAsString();
    //@}
  
    /**
     * Set the window half-width, this must be an integer between 1 and 16,
     * with a default value of 3.  The kernel size will be twice this value
     * if no blur factors are applied. The total number of sinc lobes will
     * be one less than twice the half-width, so if the half-width is 3 then
     * the kernel size will be 6 and there will be 5 sinc lobes.
     */
    void SetWindowHalfWidth(int n);
    int GetWindowHalfWidth() { return this->WindowHalfWidth; }
  
    /**
     * Turn this on in order to use SetWindowParameter.  If it is off,
     * then the default parameter will be used for the window.
     */
    void SetUseWindowParameter(int val);
    void UseWindowParameterOn() { this->SetUseWindowParameter(1); }
    void UseWindowParameterOff() { this->SetUseWindowParameter(0); }
    int GetUseWindowParameter() { return this->UseWindowParameter; }
  
    /**
     * Set the alpha parameter for the Kaiser window function.
     * This parameter will be ignored unless UseWindowParameter is On.
     * If UseWindowParameter is Off, then alpha is set to be the same as n
     * where n is the window half-width.  Using an alpha less than n
     * increases the sharpness and ringing, while using an alpha greater
     * than n increases the blurring.
     */
    void SetWindowParameter(double parm);
    double GetWindowParameter() { return this->WindowParameter; }
  
    /**
     * Get the support size for use in computing update extents.  If the data
     * will be sampled on a regular grid, then pass a matrix describing the
     * structured coordinate transformation between the output and the input.
     * Otherwise, pass nullptr as the matrix to retrieve the full kernel size.
     */
    void ComputeSupportSize(const double matrix[16], int support[3]) override;
  
    //@{
    /**
     * Blur the image by widening the windowed sinc kernel by the specified
     * factors for the x, y, and z directions.  This reduces the bandwidth
     * by these same factors.  If you turn Antialiasing on, then the blur
     * factors will be computed automatically from the output sampling rate.
     * Blurring increases the computation time because the kernel size
     * increases by the blur factor.
     */
    void SetBlurFactors(double x, double y, double z);
    void SetBlurFactors(const double f[3]) { this->SetBlurFactors(f[0], f[1], f[2]); }
    void GetBlurFactors(double f[3])
    {
      f[0] = this->BlurFactors[0];
      f[1] = this->BlurFactors[1];
      f[2] = this->BlurFactors[2];
    }
    double* GetBlurFactors() VTK_SIZEHINT(3) { return this->BlurFactors; }
    //@}
  
    /**
     * Turn on antialiasing.  If antialiasing is on, then the BlurFactors
     * will be computed automatically from the output sampling rate such that
     * that the image will be bandlimited to the Nyquist frequency.  This
     * is only applicable when the interpolator is being used by a resampling
     * filter like vtkImageReslice.  Such a filter will indicate the output
     * sampling by calling the interpolator's ComputeSupportSize() method,
     * which will compute the blur factors at the same time that it computes
     * the support size.
     */
    void SetAntialiasing(int antialiasing);
    void AntialiasingOn() { this->SetAntialiasing(1); }
    void AntialiasingOff() { this->SetAntialiasing(0); }
    int GetAntialiasing() { return this->Antialiasing; }
  
    /**
     * Turn off renormalization.  Most of the sinc windows provide kernels
     * for which the weights do not sum to one, and for which the sum depends
     * on the offset.  This results in small ripple artifacts in the output.
     * By default, the vtkImageSincInterpolator will renormalize these kernels.
     * This method allows the renormalization to be turned off.
     */
    void SetRenormalization(int renormalization);
    void RenormalizationOn() { this->SetRenormalization(1); }
    void RenormalizationOff() { this->SetRenormalization(0); }
    int GetRenormalization() { return this->Renormalization; }
  
    /**
     * Returns true if the interpolator supports weight precomputation.
     * This will always return true for this interpolator.
     */
    bool IsSeparable() override;
  
    //@{
    /**
     * If the data is going to be sampled on a regular grid, then the
     * interpolation weights can be precomputed.  A matrix must be
     * supplied that provides a transformation between the provided
     * extent and the structured coordinates of the input.  This
     * matrix must perform only permutations, scales, and translation,
     * i.e. each of the three columns must have only one non-zero value.
     * A new extent is provided for out-of-bounds checks.
     * THIS METHOD IS THREAD SAFE.
     */
    void PrecomputeWeightsForExtent(const double matrix[16], const int extent[6], int newExtent[6],
      vtkInterpolationWeights*& weights) override;
    void PrecomputeWeightsForExtent(const float matrix[16], const int extent[6], int newExtent[6],
      vtkInterpolationWeights*& weights) override;
    //@}
  
    /**
     * Free the precomputed weights.  THIS METHOD IS THREAD SAFE.
     */
    void FreePrecomputedWeights(vtkInterpolationWeights*& weights) override;
  
  protected:
    vtkImageSincInterpolator();
    ~vtkImageSincInterpolator() override;
  
    /**
     * Update the interpolator.
     */
    void InternalUpdate() override;
  
    /**
     * Copy the interpolator.
     */
    void InternalDeepCopy(vtkAbstractImageInterpolator* obj) override;
  
    //@{
    /**
     * Get the interpolation functions.
     */
    void GetInterpolationFunc(
      void (**doublefunc)(vtkInterpolationInfo*, const double[3], double*)) override;
    void GetInterpolationFunc(
      void (**floatfunc)(vtkInterpolationInfo*, const float[3], float*)) override;
    //@}
  
    //@{
    /**
     * Get the row interpolation functions.
     */
    void GetRowInterpolationFunc(
      void (**doublefunc)(vtkInterpolationWeights*, int, int, int, double*, int)) override;
    void GetRowInterpolationFunc(
      void (**floatfunc)(vtkInterpolationWeights*, int, int, int, float*, int)) override;
    //@}
  
    /**
     * Build the lookup tables used for the interpolation.
     */
    virtual void BuildKernelLookupTable();
  
    /**
     * Free the kernel lookup tables.
     */
    virtual void FreeKernelLookupTable();
  
    int WindowFunction;
    int WindowHalfWidth;
    float* KernelLookupTable[3];
    int KernelSize[3];
    int Antialiasing;
    int Renormalization;
    double BlurFactors[3];
    double LastBlurFactors[3];
    double WindowParameter;
    int UseWindowParameter;
  
  private:
    vtkImageSincInterpolator(const vtkImageSincInterpolator&) = delete;
    void operator=(const vtkImageSincInterpolator&) = delete;
  };
  
  #endif
  