{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
module Data.Array.Accelerate.IO.Codec.BMP (
RGBA32,
readImageFromBMP, writeImageToBMP,
) where
import Data.Word
import Codec.BMP
import Data.Array.Accelerate.IO.Data.ByteString
import Data.Array.Accelerate.Sugar.Array
import Data.Array.Accelerate.Sugar.Shape
type RGBA32 = Word32
readImageFromBMP :: FilePath -> IO (Either Error (Array DIM2 RGBA32))
readImageFromBMP file = do
ebmp <- readBMP file
case ebmp of
Left err -> return $ Left err
Right bmp -> do
let (w,h) = bmpDimensions bmp
bs = unpackBMPToRGBA32 bmp'
arr = fromByteStrings (Z :. h :. w) bs
bmp' = bmp { bmpBitmapInfo = info' }
info' = case bmpBitmapInfo bmp of
InfoV3 i -> InfoV3 (info3 i)
InfoV4 i -> InfoV4 (info4 i)
InfoV5 i -> InfoV5 (info5 i)
info3 BitmapInfoV3{..} = BitmapInfoV3 { dib3HeightFlipped = not dib3HeightFlipped, .. }
info4 BitmapInfoV4{..} = BitmapInfoV4 { dib4InfoV3 = info3 dib4InfoV3, .. }
info5 BitmapInfoV5{..} = BitmapInfoV5 { dib5InfoV4 = info4 dib5InfoV4, .. }
return $ Right arr
writeImageToBMP :: FilePath -> Array DIM2 RGBA32 -> IO ()
writeImageToBMP file rgba = writeBMP file bmp'
where
Z :. h :. w = shape rgba
bs = toByteStrings rgba
bmp = packRGBA32ToBMP w h bs
bmp' = bmp { bmpBitmapInfo = info' }
info' = case bmpBitmapInfo bmp of
InfoV3 i -> InfoV3 (info3 i)
InfoV4 i -> InfoV4 (info4 i)
InfoV5 i -> InfoV5 (info5 i)
info3 BitmapInfoV3{..} = BitmapInfoV3 { dib3Height = -dib3Height, dib3HeightFlipped = True, .. }
info4 BitmapInfoV4{..} = BitmapInfoV4 { dib4InfoV3 = info3 dib4InfoV3, .. }
info5 BitmapInfoV5{..} = BitmapInfoV5 { dib5InfoV4 = info4 dib5InfoV4, .. }