{-# LINE 1 "CV/Bindings/ImgProc.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}
{-# LINE 2 "CV/Bindings/ImgProc.hsc" #-}
module CV.Bindings.ImgProc where

import Foreign.C.Types
import Foreign.Ptr
import Foreign.Marshal.Utils
import Foreign.Marshal.Array
import Foreign.ForeignPtr hiding (newForeignPtr)
import Foreign.Concurrent
import CV.Bindings.Types
import CV.Bindings.Core
import CV.Image
import System.IO.Unsafe

import CV.Bindings.Matrix
import Foreign.Ptr (Ptr,FunPtr,plusPtr)
import Foreign.Ptr (wordPtrToPtr,castPtrToFunPtr)
import Foreign.Storable
import Foreign.C.Types
import Foreign.C.String (CString,CStringLen,CWString,CWStringLen)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Array (peekArray,pokeArray)
import Data.Int
import Data.Word

{-# LINE 17 "CV/Bindings/ImgProc.hsc" #-}


{-# LINE 19 "CV/Bindings/ImgProc.hsc" #-}

{-# LINE 20 "CV/Bindings/ImgProc.hsc" #-}

{-# LINE 21 "CV/Bindings/ImgProc.hsc" #-}

{-# LINE 22 "CV/Bindings/ImgProc.hsc" #-}

-- CVAPI(void) cvCopyMakeBorder(
--   const CvArr* src,
--   CvArr* dst,
--   CvPoint offset,
--   int bordertype,
--   CvScalar value CV_DEFAULT(cvScalarAll(0))
-- );

-- Copies source 2D array inside of the larger destination array and
-- makes a border of the specified type (IPL_BORDER_*) around the copied area.

foreign import ccall "wrapCopyMakeBorder" c'wrapCopyMakeBorder
  :: Ptr C'CvArr -> CInt -> CInt -> CInt -> CInt -> CInt -> CFloat -> IO (Ptr BareImage)
foreign import ccall "&wrapCopyMakeBorder" p'wrapCopyMakeBorder
  :: FunPtr (Ptr C'CvArr -> CInt -> CInt -> CInt -> CInt -> CInt -> CFloat -> IO (Ptr BareImage))

{-# LINE 35 "CV/Bindings/ImgProc.hsc" #-}

data BorderType = BorderConstant | BorderReplicate | BorderReflect | BorderWrap

cBorderType t = case t of
  BorderConstant -> c'IPL_BORDER_CONSTANT
  BorderReplicate -> c'IPL_BORDER_REPLICATE
  BorderReflect -> c'IPL_BORDER_REFLECT
  BorderWrap -> c'IPL_BORDER_WRAP

copyMakeBorder :: Image d c -> Int -> Int -> Int -> Int -> BorderType -> Float -> IO (Image d c)
copyMakeBorder i t b l r border value =
  withGenImage i $ \iptr ->
      creatingImage $
        c'wrapCopyMakeBorder iptr
            (fromIntegral t)
            (fromIntegral b)
            (fromIntegral l)
            (fromIntegral r)
            (cBorderType border)
            (realToFrac value)
-- moments

-- | Calculates all spatial and central moments up to the 3rd order
--   @
--   CVAPI(void) cvMoments(
--     const CvArr* arr,
--     CvMoments* moments,
--     int binary CV_DEFAULT(0));@

foreign import ccall "cvMoments" c'cvMoments
  :: Ptr C'CvArr -> Ptr C'CvMoments -> CInt -> IO ()
foreign import ccall "&cvMoments" p'cvMoments
  :: FunPtr (Ptr C'CvArr -> Ptr C'CvMoments -> CInt -> IO ())

{-# LINE 65 "CV/Bindings/ImgProc.hsc" #-}

-- | Retrieve particular spatial moment (m_xy)
--   @
--   CVAPI(double) cvGetSpatialMoment(
--     CvMoments* moments,
--     int x_order,
--     int y_order );@

foreign import ccall "cvGetSpatialMoment" c'cvGetSpatialMoment
  :: Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble)
foreign import ccall "&cvGetSpatialMoment" p'cvGetSpatialMoment
  :: FunPtr (Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble))

{-# LINE 74 "CV/Bindings/ImgProc.hsc" #-}

-- | Retrieve particular central moment (mu_xy)
--   @
--   CVAPI(double) cvGetCentralMoment(
--     CvMoments* moments,
--     int x_order,
--     int y_order );@

foreign import ccall "cvGetCentralMoment" c'cvGetCentralMoment
  :: Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble)
foreign import ccall "&cvGetCentralMoment" p'cvGetCentralMoment
  :: FunPtr (Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble))

{-# LINE 83 "CV/Bindings/ImgProc.hsc" #-}

-- | Retrieve particular normalized central moment (eta_xy)
--   @
--   CVAPI(double) cvGetNormalizedCentralMoment(
--     CvMoments* moments,
--     int x_order,
--     int y_order );@

foreign import ccall "cvGetNormalizedCentralMoment" c'cvGetNormalizedCentralMoment
  :: Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble)
foreign import ccall "&cvGetNormalizedCentralMoment" p'cvGetNormalizedCentralMoment
  :: FunPtr (Ptr C'CvMoments -> CInt -> CInt -> IO (CDouble))

{-# LINE 92 "CV/Bindings/ImgProc.hsc" #-}

-- | Calculates 7 Hu's invariants from precalculated spatial and central moments
--   @
--   CVAPI(void) cvGetHuMoments(
--     CvMoments* moments,
--     CvHuMoments* hu_moments );@

foreign import ccall "cvGetHuMoments" c'cvGetHuMoments
  :: Ptr C'CvMoments -> Ptr C'CvHuMoments -> IO ()
foreign import ccall "&cvGetHuMoments" p'cvGetHuMoments
  :: FunPtr (Ptr C'CvMoments -> Ptr C'CvHuMoments -> IO ())

{-# LINE 100 "CV/Bindings/ImgProc.hsc" #-}

-- CVAPI(void) cvCornerHarris(
--   const CvArr* image,
--   CvArr* harris_responce,
--   int block_size,
--   int aperture_size CV_DEFAULT(3),
--   double k CV_DEFAULT(0.04)
-- );

foreign import ccall "cvCornerHarris" c'cvCornerHarris
  :: Ptr C'CvArr -> Ptr C'CvArr -> Int -> Int -> Double -> IO ()
foreign import ccall "&cvCornerHarris" p'cvCornerHarris
  :: FunPtr (Ptr C'CvArr -> Ptr C'CvArr -> Int -> Int -> Double -> IO ())

{-# LINE 110 "CV/Bindings/ImgProc.hsc" #-}

-- CVAPI(CvSeq*) cvHoughLines2(
--   CvArr* image,
--   void* line_storage,
--   int method,
--   double rho,
--   double theta,
--   int threshold,
--   double param1 CV_DEFAULT(0),
--   double param2 CV_DEFAULT(0)
-- );
--
-- CvSeq* cvHoughCircles(
--   CvArr* image,
--   void* circle_storage,
--   int method,
--   double dp,
--   double min_dist,
--   double param1=100,
--   double param2=100,
--   int min_radius=0,
--   int max_radius=0
-- );

c'CV_HOUGH_STANDARD = 0
c'CV_HOUGH_STANDARD :: (Num a) => a

{-# LINE 135 "CV/Bindings/ImgProc.hsc" #-}
c'CV_HOUGH_PROBABILISTIC = 1
c'CV_HOUGH_PROBABILISTIC :: (Num a) => a

{-# LINE 136 "CV/Bindings/ImgProc.hsc" #-}
c'CV_HOUGH_MULTI_SCALE = 2
c'CV_HOUGH_MULTI_SCALE :: (Num a) => a

{-# LINE 137 "CV/Bindings/ImgProc.hsc" #-}
c'CV_HOUGH_GRADIENT = 3
c'CV_HOUGH_GRADIENT :: (Num a) => a

{-# LINE 138 "CV/Bindings/ImgProc.hsc" #-}

foreign import ccall "cvHoughLines2" c'cvHoughLines2
  :: Ptr C'CvArr -> Ptr () -> Int -> Double -> Double -> Int -> Double -> Double -> IO ()
foreign import ccall "&cvHoughLines2" p'cvHoughLines2
  :: FunPtr (Ptr C'CvArr -> Ptr () -> Int -> Double -> Double -> Int -> Double -> Double -> IO ())

{-# LINE 140 "CV/Bindings/ImgProc.hsc" #-}
foreign import ccall "cvHoughCircles" c'cvHoughCircles
  :: Ptr C'CvArr -> Ptr () -> Int -> Double -> Double -> Double -> Double -> Int -> Int -> IO ()
foreign import ccall "&cvHoughCircles" p'cvHoughCircles
  :: FunPtr (Ptr C'CvArr -> Ptr () -> Int -> Double -> Double -> Double -> Double -> Int -> Int -> IO ())

{-# LINE 141 "CV/Bindings/ImgProc.hsc" #-}

foreign import ccall "wrapFilter2" c'wrapFilter2
  :: Ptr C'CvArr -> Ptr C'CvArr -> Ptr C'CvMat -> Ptr C'CvPoint -> IO ()
foreign import ccall "&wrapFilter2" p'wrapFilter2
  :: FunPtr (Ptr C'CvArr -> Ptr C'CvArr -> Ptr C'CvMat -> Ptr C'CvPoint -> IO ())

{-# LINE 143 "CV/Bindings/ImgProc.hsc" #-}

foreign import ccall "cvCalcArrBackProject" c'cvCalcArrBackProject
  :: Ptr (Ptr C'IplImage) -> Ptr C'CvArr -> Ptr C'CvHistogram -> IO ()
foreign import ccall "&cvCalcArrBackProject" p'cvCalcArrBackProject
  :: FunPtr (Ptr (Ptr C'IplImage) -> Ptr C'CvArr -> Ptr C'CvHistogram -> IO ())

{-# LINE 145 "CV/Bindings/ImgProc.hsc" #-}

c'CV_HIST_ARRAY = 0
c'CV_HIST_ARRAY :: (Num a) => a

{-# LINE 147 "CV/Bindings/ImgProc.hsc" #-}

foreign import ccall "cvCreateHist" c'cvCreateHist
  :: Int -> Ptr Int -> Int -> Ptr (Ptr Float) -> Int -> IO (Ptr C'CvHistogram)
foreign import ccall "&cvCreateHist" p'cvCreateHist
  :: FunPtr (Int -> Ptr Int -> Int -> Ptr (Ptr Float) -> Int -> IO (Ptr C'CvHistogram))

{-# LINE 149 "CV/Bindings/ImgProc.hsc" #-}
foreign import ccall "cvReleaseHist" c'cvReleaseHist
  :: Ptr (Ptr C'CvHistogram) -> IO ()
foreign import ccall "&cvReleaseHist" p'cvReleaseHist
  :: FunPtr (Ptr (Ptr C'CvHistogram) -> IO ())

{-# LINE 150 "CV/Bindings/ImgProc.hsc" #-}
foreign import ccall "cvCalcArrHist" c'cvCalcArrHist
  :: Ptr (Ptr C'IplImage) -> Ptr C'CvHistogram -> Int -> Ptr C'CvArr -> IO ()
foreign import ccall "&cvCalcArrHist" p'cvCalcArrHist
  :: FunPtr (Ptr (Ptr C'IplImage) -> Ptr C'CvHistogram -> Int -> Ptr C'CvArr -> IO ())

{-# LINE 151 "CV/Bindings/ImgProc.hsc" #-}

newtype Histogram = Histogram (ForeignPtr C'CvHistogram)
creatingHistogram fun = do
    iptr :: Ptr C'CvHistogram <- fun
    fptr :: ForeignPtr C'CvHistogram <- newForeignPtr iptr (with iptr c'cvReleaseHist)
    return . Histogram $ fptr


emptyUniformHistogramND dims =
    withArray dims $ \c_sizes ->
    c'cvCreateHist 1 c_sizes c'CV_HIST_ARRAY nullPtr 1

-- #ccall cvFindContours, Ptr <CvArr> -> Ptr <CvMemStorage> -> Ptr (Ptr <CvSeq>) -> Cint -> CInt -> CInt-> Ptr <CvPoint>
-- thresholding types

-- | value = value > threshold ? max_value : 0 
c'CV_THRESH_BINARY = 0
c'CV_THRESH_BINARY :: (Num a) => a

{-# LINE 168 "CV/Bindings/ImgProc.hsc" #-}
-- | value = value > threshold ? 0 : max_value
c'CV_THRESH_BINARY_INV = 1
c'CV_THRESH_BINARY_INV :: (Num a) => a

{-# LINE 170 "CV/Bindings/ImgProc.hsc" #-}
-- | value = value > threshold ? threshold : value
c'CV_THRESH_TRUNC = 2
c'CV_THRESH_TRUNC :: (Num a) => a

{-# LINE 172 "CV/Bindings/ImgProc.hsc" #-}
-- | value = value > threshold ? value : 0
c'CV_THRESH_TOZERO = 3
c'CV_THRESH_TOZERO :: (Num a) => a

{-# LINE 174 "CV/Bindings/ImgProc.hsc" #-}
-- | value = value > threshold ? 0 : value
c'CV_THRESH_TOZERO_INV = 4
c'CV_THRESH_TOZERO_INV :: (Num a) => a

{-# LINE 176 "CV/Bindings/ImgProc.hsc" #-}
c'CV_THRESH_MASK = 7
c'CV_THRESH_MASK :: (Num a) => a

{-# LINE 177 "CV/Bindings/ImgProc.hsc" #-}
-- | Use Otsu algorithm to choose the optimal threshold value;
--   combine the flag with one of the above CV_THRESH_* values.
--   Note: when using this, the threshold value is ignored.
c'CV_THRESH_OTSU = 8
c'CV_THRESH_OTSU :: (Num a) => a

{-# LINE 181 "CV/Bindings/ImgProc.hsc" #-}

-- | CV_THRESH_OTSU | CV_THRESH_BINARY
c'CV_THRESH_OTSU_BINARY = 8
c'CV_THRESH_OTSU_BINARY :: (Num a) => a

{-# LINE 184 "CV/Bindings/ImgProc.hsc" #-}
-- | CV_THRESH_OTSU | CV_THRESH_BINARY_INV
c'CV_THRESH_OTSU_BINARY_INV = 9
c'CV_THRESH_OTSU_BINARY_INV :: (Num a) => a

{-# LINE 186 "CV/Bindings/ImgProc.hsc" #-}
-- | CV_THRESH_OTSU | CV_THRESH_TRUNC
c'CV_THRESH_OTSU_TRUNC = 10
c'CV_THRESH_OTSU_TRUNC :: (Num a) => a

{-# LINE 188 "CV/Bindings/ImgProc.hsc" #-}
-- | CV_THRESH_OTSU | CV_THRESH_TOZERO
c'CV_THRESH_OTSU_TOZERO = 11
c'CV_THRESH_OTSU_TOZERO :: (Num a) => a

{-# LINE 190 "CV/Bindings/ImgProc.hsc" #-}
-- | CV_THRESH_OTSU | CV_THRESH_TOZERO
c'CV_THRESH_OTSU_TOZERO_INV = 12
c'CV_THRESH_OTSU_TOZERO_INV :: (Num a) => a

{-# LINE 192 "CV/Bindings/ImgProc.hsc" #-}

-- | Applies fixed-level threshold to grayscale image.
--   This is a basic operation applied before retrieving contours.
--   @
--   CVAPI(double) cvThreshold(
--   const CvArr* src, 
--   CvArr* dst,
--   double threshold,
--   double  max_value,
--   int threshold_type);@

foreign import ccall "cvThreshold" c'cvThreshold
  :: Ptr C'CvArr -> Ptr C'CvArr -> CDouble -> CDouble -> CInt -> IO (CDouble)
foreign import ccall "&cvThreshold" p'cvThreshold
  :: FunPtr (Ptr C'CvArr -> Ptr C'CvArr -> CDouble -> CDouble -> CInt -> IO (CDouble))

{-# LINE 204 "CV/Bindings/ImgProc.hsc" #-}

-- | Threshold for each pixel is the mean calculated from /block_size/
--   neighborhood, minus /param1/.
c'CV_ADAPTIVE_THRESH_MEAN_C = 0
c'CV_ADAPTIVE_THRESH_MEAN_C :: (Num a) => a

{-# LINE 208 "CV/Bindings/ImgProc.hsc" #-}
-- | Threshold for each pixel is the gaussian mean calculated from /block_size/
--   neighborhood, minus /param1/
c'CV_ADAPTIVE_THRESH_GAUSSIAN_C = 1
c'CV_ADAPTIVE_THRESH_GAUSSIAN_C :: (Num a) => a

{-# LINE 211 "CV/Bindings/ImgProc.hsc" #-}

-- | Applies adaptive threshold to grayscale image.
--   The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
--   CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
--   neighborhood size (3, 5, 7 etc.),
--   and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
--   @
--   CVAPI(void) cvAdaptiveThreshold(
--   const CvArr* src,
--   CvArr* dst,
--   double max_value,
--   int adaptive_method CV_DEFAULT(CV_ADAPTIVE_THRESH_MEAN_C),
--   int threshold_type CV_DEFAULT(CV_THRESH_BINARY),
--   int block_size CV_DEFAULT(3),
--   double param1 CV_DEFAULT(5));@

foreign import ccall "cvAdaptiveThreshold" c'cvAdaptiveThreshold
  :: Ptr C'CvArr -> Ptr C'CvArr -> CDouble -> CInt -> CInt -> CInt -> CDouble -> IO ()
foreign import ccall "&cvAdaptiveThreshold" p'cvAdaptiveThreshold
  :: FunPtr (Ptr C'CvArr -> Ptr C'CvArr -> CDouble -> CInt -> CInt -> CInt -> CDouble -> IO ())

{-# LINE 228 "CV/Bindings/ImgProc.hsc" #-}

-- | Fills the connected component until the color difference gets large enough
--   @
--   CVAPI(void) cvFloodFill(
--   CvArr* image,
--   CvPoint seed_point,
--   CvScalar new_val,
--   CvScalar lo_diff CV_DEFAULT(cvScalarAll(0)),
--   CvScalar up_diff CV_DEFAULT(cvScalarAll(0)),
--   CvConnectedComp* comp CV_DEFAULT(NULL),
--   int flags CV_DEFAULT(4),
--   CvArr* mask CV_DEFAULT(NULL));@

-- | Labels connected components by flood filling each with a different value.
--   @
--   void fillConnectedComponents(const IplImage* img, int *count)@

foreign import ccall "fillConnectedComponents" c'fillConnectedComponents
  :: Ptr C'IplImage -> Ptr CInt -> IO ()
foreign import ccall "&fillConnectedComponents" p'fillConnectedComponents
  :: FunPtr (Ptr C'IplImage -> Ptr CInt -> IO ())

{-# LINE 246 "CV/Bindings/ImgProc.hsc" #-}

-- | Masks a connected component by filling it with white, and filling all
--   other pixels with black.
--   @
--   void maskConnectedComponent(const IplImage *src, IplImage *mask, int id)@

foreign import ccall "maskConnectedComponent" c'maskConnectedComponent
  :: Ptr C'IplImage -> Ptr C'IplImage -> CInt -> IO ()
foreign import ccall "&maskConnectedComponent" p'maskConnectedComponent
  :: FunPtr (Ptr C'IplImage -> Ptr C'IplImage -> CInt -> IO ())

{-# LINE 253 "CV/Bindings/ImgProc.hsc" #-}