content: {-# language CPP #-}
  {-# language QuasiQuotes #-}
  {-# language TemplateHaskell #-}
  
  #if __GLASGOW_HASKELL__ >= 800
  {-# options_ghc -Wno-redundant-constraints #-}
  #endif
  
  module OpenCV.Extra.XPhoto
    ( dctDenoising
    ) where
  
  import "base" Data.Int ( Int32 )
  import "base" Data.Word ( Word8 )
  import "base" Data.Maybe ( fromMaybe )
  import qualified "inline-c" Language.C.Inline as C
  import qualified "inline-c-cpp" Language.C.Inline.Cpp as C
  import "mtl" Control.Monad.Error.Class ( MonadError )
  import "opencv" OpenCV.Internal.C.Inline ( openCvCtx )
  import "opencv" OpenCV.Internal.C.Types ( withPtr )
  import "opencv" OpenCV.Internal.Exception
  import "opencv" OpenCV.Internal.Core.Types.Mat
  import "opencv" OpenCV.TypeLevel
  
  --------------------------------------------------------------------------------
  
  C.context openCvCtx
  
  C.include "opencv2/core.hpp"
  C.include "opencv2/xphoto.hpp"
  C.using "namespace cv"
  
  {-| Perform dctDenoising function for colored images.
  
  Example:
  
  @
  dctDenoisingImg
      :: forall h w w2 c d
       . ( Mat (ShapeT [h, w]) ('S c) ('S d) ~ Lenna_512x512
         , w2 ~ ((*) w 2)
         )
      => Mat ('S ['S h, 'S w2]) ('S c) ('S d)
  dctDenoisingImg = exceptError $ do
      denoised <- dctDenoising 10 Nothing lenna_512x512
      withMatM
        (Proxy :: Proxy [h, w2])
        (Proxy :: Proxy c)
        (Proxy :: Proxy d)
        black $ \\imgM -> do
          matCopyToM imgM (V2 0 0) lenna_512x512 Nothing
          matCopyToM imgM (V2 w 0) denoised Nothing
    where
      w = fromInteger $ natVal (Proxy :: Proxy w)
  @
  
  <<doc/generated/examples/dctDenoisingImg.png dctDenoisingImg>>
  -}
  
  dctDenoising
     :: (MonadError CvException m)
     => Double -- ^ expected noise standard deviation
     -> Maybe Int32  -- ^ size of block side where dct is computed use default 16
     -> Mat ('S [h, w]) ('S 3) ('S Word8) -- ^ Input image 8-bit 3-channel image.
     -> m (Mat ('S [h, w]) ('S 3) ('S Word8))
               -- ^ Output image same size and type as input.
  dctDenoising sigma mPSize src =
    unsafeWrapException $ do
      dst <- newEmptyMat
      handleCvException (pure $ unsafeCoerceMat dst) $
        withPtr src         $ \srcPtr         ->
        withPtr dst         $ \dstPtr         ->
        [cvExcept|
          cv::xphoto::dctDenoising( *$(Mat * srcPtr)
                                  , *$(Mat * dstPtr)
                                  , $(double c'sigma)
                                  , $(int32_t c'pSize)
                                  );
        |]
    where
      c'sigma = realToFrac sigma
      c'pSize = fromMaybe 16 mPSize
  