never executed always true always false
1 module HelVM.HelMA.Automata.Piet.Parser
2 ( processImage
3 , processImageWithLog
4 ) where
5
6 import HelVM.HelMA.Automata.Piet.Types.Color
7 import HelVM.HelMA.Automata.Piet.Types.Image
8
9 import qualified Codec.Picture as Picture
10
11 import Control.Monad.Logger
12
13 import Data.MonoTraversable
14
15 processImageWithLog ∷ MonadLogger m ⇒ Maybe Natural → Picture.DynamicImage → m (Image Color)
16 processImageWithLog codelInfo dynamicImage = imageFromJuicy actualCodelLength img <$ logDebugN ("Actual codel length: " <> show actualCodelLength) where
17 actualCodelLength = calculateActualCodelLength codelInfo img
18 img = Picture.convertRGBA8 dynamicImage
19
20 processImage ∷ Maybe Natural → Picture.DynamicImage → Image Color
21 processImage codelInfo dynamicImage = imageFromJuicy actualCodelLength img where
22 actualCodelLength = calculateActualCodelLength codelInfo img
23 img = Picture.convertRGBA8 dynamicImage
24
25 calculateActualCodelLength ∷ Maybe Natural → Picture.Image Picture.PixelRGBA8 → Int
26 calculateActualCodelLength codelInfo img = max 1 $ maybe defaultCodelInfo fromIntegral codelInfo where
27 defaultCodelInfo = imageGuessCodelLength img
28
29 imageFromJuicy ∷ Int → Picture.Image Picture.PixelRGBA8 → Image Color
30 imageFromJuicy codelLength img = newImage (width, height) pixels where
31 width = Picture.imageWidth img `div` codelLength
32 height = Picture.imageHeight img `div` codelLength
33
34 pixels = [ ((x, y), extractColor x y) | x <- [0 .. width-1], y <- [0 .. height-1] ]
35
36 extractColor x y = checkAlpha (Picture.pixelAt img (x * codelLength) (y * codelLength))
37 checkAlpha (Picture.PixelRGBA8 r g b _) = rgb2Color r g b
38
39 imageGuessCodelLength ∷ Picture.Image Picture.PixelRGBA8 → Int
40 imageGuessCodelLength img = lastUntil isOne $ scanl gcd (gcd width height) $ fmap olength (group rows) <> fmap olength (group cols) where
41 width = Picture.imageWidth img
42 height = Picture.imageHeight img
43 isOne = (== 1)
44
45 rows = [ [ Picture.pixelAt img x y | x <- [0 .. width-1] ] | y <- [0 .. height-1] ]
46 cols = [ [ Picture.pixelAt img x y | y <- [0 .. height-1] ] | x <- [0 .. width-1] ]
47
48 lastUntil _ [x] = x
49 lastUntil p (x:xs) = guardPred (p x) p x xs
50 lastUntil _ _ = error "empty list in lastUntil helper (imageGuessCodelLength)"
51
52 guardPred True _ x _ = x
53 guardPred False p' _ xs = lastUntil p' xs