module Vision.Image.Mutable (
MutableImage (..), create
, MutableManifest (..)
) where
import Control.Monad.Primitive (PrimMonad (..))
import Control.Monad.ST (ST, runST)
import Data.Vector.Storable (MVector)
import Foreign.Storable (Storable)
import Prelude hiding (read)
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as MV
import Vision.Image.Class (Image, ImagePixel)
import Vision.Image.Type (Manifest (..))
import Vision.Primitive (
Point, Size, fromLinearIndex, toLinearIndex, shapeLength
)
class Image (Freezed i) => MutableImage i where
type Freezed i
mShape :: i s -> Size
new :: PrimMonad m => Size -> m (i (PrimState m))
new' :: PrimMonad m => Size -> ImagePixel (Freezed i) -> m (i (PrimState m))
read :: PrimMonad m => i (PrimState m) -> Point
-> m (ImagePixel (Freezed i))
read !img !ix = img `linearRead` toLinearIndex (mShape img) ix
linearRead :: PrimMonad m
=> i (PrimState m) -> Int -> m (ImagePixel (Freezed i))
linearRead !img !ix = img `read` fromLinearIndex (mShape img) ix
write :: PrimMonad m => i (PrimState m) -> Point -> ImagePixel (Freezed i)
-> m ()
write !img !ix !val = linearWrite img (toLinearIndex (mShape img) ix) val
linearWrite :: PrimMonad m => i (PrimState m) -> Int
-> ImagePixel (Freezed i) -> m ()
linearWrite !img !ix !val = write img (fromLinearIndex (mShape img) ix) val
freeze :: PrimMonad m => i (PrimState m) -> m (Freezed i)
unsafeFreeze :: PrimMonad m => i (PrimState m) -> m (Freezed i)
unsafeFreeze = freeze
thaw :: PrimMonad m => Freezed i -> m (i (PrimState m))
create :: (MutableImage i) => (forall s. ST s (i s)) -> Freezed i
create action =
runST $ do
img <- action
unsafeFreeze img
data MutableManifest p s = MutableManifest {
mmSize :: !Size
, mmVector :: !(MVector s p)
}
instance Storable p => MutableImage (MutableManifest p) where
type Freezed (MutableManifest p) = Manifest p
mShape = mmSize
new !size = do
mvec <- MV.new (shapeLength size)
return $! MutableManifest size mvec
new' !size !val = do
mvec <- MV.replicate (shapeLength size) val
return $! MutableManifest size mvec
linearRead !img = MV.read (mmVector img)
linearWrite !img = MV.write (mmVector img)
freeze !(MutableManifest size mvec) = do
vec <- V.freeze mvec
return $! Manifest size vec
unsafeFreeze !(MutableManifest size mvec) = do
vec <- V.unsafeFreeze mvec
return $! Manifest size vec
thaw !(Manifest size vec) = do
mvec <- V.thaw vec
return $! MutableManifest size mvec