{-# LANGUAGE OverloadedStrings #-} module Reanimate.Povray ( povray , povrayQuick , povraySlow ) where import Codec.Picture.Png import qualified Data.ByteString as B import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.IO as T import Graphics.SvgTree (Tree (..)) import Reanimate.Cache import Reanimate.Memo import Reanimate.Misc import Reanimate.Raster import Reanimate.Svg.Constructors import System.FilePath (replaceExtension) import System.IO.Unsafe (unsafePerformIO) povrayRaw :: [String] -> Text -> Tree povrayRaw args script = memo [Key mkPovrayImage, KeyPrim args, KeyPrim script] (unsafePerformIO $ mkPovrayImage args script) povray :: [String] -> Text -> Tree povray args = povrayRaw (["+H180","+W320", "+A"] ++ args) povrayQuick :: [String] -> Text -> Tree povrayQuick args = povrayRaw (["+H180","+W320"] ++ args) povraySlow :: [String] -> Text -> Tree povraySlow args = povrayRaw (["+H1440","+W2560", "+A"] ++ args) mkPovrayImage :: [String] -> Text -> IO Tree mkPovrayImage args script = cacheDiskKey key $ do exec <- requireExecutable "povray" withTempFile "pov" $ \pov_file -> do let out = replaceExtension pov_file "png" T.writeFile pov_file script ret <- runCmd_ exec (args ++ ["-D","+UA", pov_file, "+o"++out]) case ret of Left{} -> error "povray went wrong" Right{} -> do png <- B.readFile out case decodePng png of Left{} -> error "bad image" Right img -> return $ center $ scaleToSize 16 9 $ embedDynamicImage img where key = T.concat (script:map T.pack args)