module CV.ImageOp where
import System.IO.Unsafe (unsafePerformIO)
import CV.Image
import Control.Monad ((>=>))
import Data.Monoid
import Control.Category
import Prelude hiding ((.),id)
newtype ImageOperation c d = ImgOp (Image c d-> IO ())
(#>) :: ImageOperation c d-> ImageOperation c d -> ImageOperation c d
(#>) (ImgOp a) (ImgOp b) = ImgOp (\img -> (a img >> b img))
nonOp = ImgOp (\i -> return ())
img <# op = unsafeOperate op img
fromImageOp (ImgOp f) = IOP $\i -> (f i >> return i)
newtype IOP a b = IOP (a -> IO b)
instance Category IOP where
id = IOP return
(IOP f) . (IOP g) = IOP $ g >=> (f >>= return)
(&#&) :: IOP (Image c d) e -> IOP (Image c d) f -> IOP (Image c d) (Image c d,Image c d)
(IOP f) &#& (IOP g) = IOP $ op
where
op i = withCloneValue i $ \cl -> (f i >> g cl >> return (i,cl))
unsafeOperate op img = unsafePerformIO $ operate op img
runIOP (IOP f) img = withCloneValue img $ \clone -> f clone
img <## [] = img
img <## op = unsafeOperate (foldl1 (#>) op) img
operate ::ImageOperation c d -> Image c d -> IO (Image c d)
operate (ImgOp op) img = withCloneValue img $ \clone ->
op clone >> return clone
operateOn = flip operate
times n op = foldl (#>) nonOp (replicate n op)
directOp i (ImgOp op) = op i
operateInPlace (ImgOp op) img = op img
unsafeOperateOn img op = unsafePerformIO $ operate op img
operateWithROI pos size (ImgOp op) img = withClone img $ \clone ->
withIOROI pos size clone (op clone)