{-# LANGUAGE FlexibleContexts #-}
module Main where
import Codec.Picture (DynamicImage)
import qualified Codec.Picture.Png as Juicy
import Codec.Picture.Png.Streaming
import Codec.Picture.Png.Streaming.Juicy
import Control.Monad (void)
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Trans.Resource (MonadResource, runResourceT)
import qualified Data.ByteString as B
import Criterion.Main
import qualified Data.ByteString.Streaming as Q
import Streaming.Prelude (Of (..))
readPNG :: (MonadResource m) => FilePath -> m DynamicImage
readPNG readPath =
do decoded <- decodePNGFile readPath
res :> _ <- imageFromStream decoded
return res
decodeBS :: B.ByteString -> IO DynamicImage
decodeBS bs =
do decoded <- decodePNG $ Q.fromStrict bs
res :> _ <- imageFromStream decoded
return res
copyPNG :: (MonadResource m) => FilePath -> FilePath -> m ()
copyPNG readPath writePath =
do image <- readPNG readPath
liftIO . void $ Juicy.writeDynamicPng writePath image
fstOf :: Of a b -> a
fstOf (x :> _) = x
benchImage :: (String, B.ByteString) -> [Benchmark]
benchImage (path, image) =
-- [ bench ("read " ++ path ++ " with JuicyPixels") . nf Juicy.decodePng $ image
[ bench ("read " ++ path ++ " with streaming") . nfIO $ decodeBS image
]
benchmarkMain :: IO ()
benchmarkMain =
do hugeFile <- B.readFile "huge.png"
largeFile <- B.readFile "large.png"
mediumFile <- B.readFile "medium.png"
smallFile <- B.readFile "small.png"
defaultMain $ benchImage =<< [("huge.png", hugeFile)]
-- [ ("small.png", smallFile)
-- , ("medium.png", mediumFile)
-- , ("large.png", largeFile)
-- , ("huge.png", hugeFile)
-- ]
main :: IO ()
-- main = runResourceT $ copyPNG "huge.png" "result.png"
main = benchmarkMain