/*=========================================================================
*
*  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 sitkSpeckleNoiseImageFilter_h
#define sitkSpeckleNoiseImageFilter_h

/*
 * WARNING: DO NOT EDIT THIS FILE!
 * THIS FILE IS AUTOMATICALLY GENERATED BY THE SIMPLEITK BUILD PROCESS.
 * Please look at sitkImageFilterTemplate.h.in to make changes.
 */

#include <memory>

#include "sitkBasicFilters.h"
#include "sitkImageFilter.h"

namespace itk::simple {

    /**\class SpeckleNoiseImageFilter
\brief Alter an image with speckle (multiplicative) noise.

The speckle noise follows a gamma distribution of mean 1 and standard deviation provided by the user. The noise is proportional to the pixel intensity.

It can be modeled as:

\par 
\f$ I = I_0 \ast G \f$ 


\par 
where \f$ G \f$ is a is a gamma distributed random variable of mean 1 and variance proportional to the noise level:


\par 
\f$ G \sim \Gamma(\frac{1}{\sigma^2}, \sigma^2) \f$ 


\author Gaetan Lehmann


This code was contributed in the Insight Journal paper "Noise
Simulation". https://doi.org/10.54294/vh6vbw
\sa itk::simple::SpeckleNoise for the procedural interface
\sa itk::SpeckleNoiseImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT SpeckleNoiseImageFilter : public ImageFilter {
    public:
      using Self = SpeckleNoiseImageFilter;

      /** Destructor */
      virtual ~SpeckleNoiseImageFilter();

      /** Default Constructor that takes no arguments and initializes
       * default parameters */
      SpeckleNoiseImageFilter();

      /** Define the pixels types supported by this filter */
      using PixelIDTypeList = BasicPixelIDTypeList;
\

      /**
       * Set/Get the standard deviation of the gamma distribution. Defaults to 1.0.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetStandardDeviation ( double StandardDeviation ) { this->m_StandardDeviation = StandardDeviation; return *this; }

      /**
       * Set/Get the standard deviation of the gamma distribution. Defaults to 1.0.
       */
      double GetStandardDeviation() const { return this->m_StandardDeviation; }\

      /**
       */
      SITK_RETURN_SELF_TYPE_HEADER SetSeed ( uint32_t Seed ) { this->m_Seed = Seed; return *this; }

      /**
       */
      uint32_t GetSeed() const { return this->m_Seed; }

      /** Name of this class */
      std::string GetName() const { return std::string ("SpeckleNoiseImageFilter"); }

      /** Print ourselves out */
      std::string ToString() const;


      /** Execute the filter on the input image */
#ifndef SWIG
      Image Execute ( Image&& image1 );
#endif
      Image Execute ( const Image& image1 );

    private:

      /** Setup for member function dispatching */

      using MemberFunctionType = Image (Self::*)( const Image& image1 );
      template <class TImageType> Image ExecuteInternal ( const Image& image1 );
      /** Dispatched methods which calls ExecuteInternal on each component */
      template <class TImageType> Image ExecuteInternalVectorImage ( const Image& image );

      friend struct detail::MemberFunctionAddressor<MemberFunctionType>;
      friend struct detail::ExecuteInternalVectorImageAddressor<MemberFunctionType>;
      std::unique_ptr<detail::MemberFunctionFactory<MemberFunctionType> > m_MemberFactory;


      double  m_StandardDeviation{1.0};

      uint32_t  m_Seed{(uint32_t) itk::simple::sitkWallClock};


      bool m_InPlace{false};
    };

    /**\
     * \brief Alter an image with speckle (multiplicative) noise.
     *
     * This function directly calls the execute method of SpeckleNoiseImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::SpeckleNoiseImageFilter for the object oriented interface
     * @{
     */
#ifndef SWIG
     SITKBasicFilters_EXPORT Image SpeckleNoise ( Image&& image1, double standardDeviation = 1.0, uint32_t seed = (uint32_t) itk::simple::sitkWallClock );
#endif
     SITKBasicFilters_EXPORT Image SpeckleNoise ( const Image& image1, double standardDeviation = 1.0, uint32_t seed = (uint32_t) itk::simple::sitkWallClock );

     /** @} */
}
#endif
