JuicyPixels-1.2.1: Codec/Picture/Jpg/Types.hs
module Codec.Picture.Jpg.Types( MutableMacroBlock
, createEmptyMutableMacroBlock
, mutate
, printMacroBlock
, (!!!), (.!!!.), (.<-.)
) where
import Control.Monad.ST( ST )
import Foreign.Storable ( Storable )
import Control.Monad.Primitive ( PrimState, PrimMonad )
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as M
-- import Data.Vector.Storable( (!) )
import Text.Printf
{-# INLINE (!!!) #-}
(!!!) :: (Storable e) => V.Vector e -> Int -> e
(!!!) = -- (!)
V.unsafeIndex
{-# INLINE (.!!!.) #-}
(.!!!.) :: (PrimMonad m, Storable a)
=> M.STVector (PrimState m) a -> Int -> m a
(.!!!.) = -- M.read
M.unsafeRead
{-# INLINE (.<-.) #-}
(.<-.) :: (PrimMonad m, Storable a)
=> M.STVector (PrimState m) a -> Int -> a -> m ()
(.<-.) = -- M.write
M.unsafeWrite
-- | Macroblock that can be transformed.
type MutableMacroBlock s a = M.STVector s a
{-# INLINE createEmptyMutableMacroBlock #-}
-- | Create a new macroblock with the good array size
createEmptyMutableMacroBlock :: (Storable a, Num a) => ST s (MutableMacroBlock s a)
createEmptyMutableMacroBlock = M.replicate 64 0
{-# INLINE mutate #-}
-- | Return the transformed block
mutate :: Storable a
=> (Int -> a -> a) -- ^ The updating function
-> MutableMacroBlock s a -> ST s (MutableMacroBlock s a)
mutate f block = update 0 >> return block
where updateVal i = (block .!!!. i) >>= (block .<-. i) . f i
update 63 = updateVal 63
update n = updateVal n >> update (n + 1)
printMacroBlock :: (Storable a, PrintfArg a)
=> MutableMacroBlock s a -> ST s String
printMacroBlock block = pLn 0
where pLn 64 = return "===============================\n"
pLn i = do
v <- block .!!!. i
vn <- pLn (i+1)
return $ printf (if i `mod` 8 == 0 then "\n%5d " else "%5d ") v ++ vn