Permalink
Browse files

BMP file IO & pixel manipulation

  • Loading branch information...
1 parent 2010ec9 commit 3ebc61f79aa0a610c25cebd6cfcfdf825bcc8333 @tmcdonell committed Jun 7, 2012
Showing with 120 additions and 0 deletions.
  1. +3 −0 Data/Array/Accelerate/IO.hs
  2. +114 −0 Data/Array/Accelerate/IO/BMP.hs
  3. +3 −0 accelerate-io.cabal
@@ -26,13 +26,16 @@
module Data.Array.Accelerate.IO (
module Data.Array.Accelerate.IO.ByteString,
+ module Data.Array.Accelerate.IO.BMP,
module Data.Array.Accelerate.IO.Ptr,
module Data.Array.Accelerate.IO.Repa,
module Data.Array.Accelerate.IO.Vector,
) where
import Data.Array.Accelerate.IO.ByteString
+import Data.Array.Accelerate.IO.BMP
import Data.Array.Accelerate.IO.Ptr
import Data.Array.Accelerate.IO.Repa
import Data.Array.Accelerate.IO.Vector
+
@@ -0,0 +1,114 @@
+-- |
+-- Module : Data.Array.Accelerate.IO.BMP
+-- Copyright : [2012] Trevor L. McDonell
+-- License : BSD3
+--
+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>
+-- Stability : experimental
+-- Portability : non-portable (GHC extensions)
+--
+
+module Data.Array.Accelerate.IO.BMP (
+
+ -- * File IO
+ readImageFromBMP, writeImageToBMP,
+
+ -- * Manipulating pixels
+ RGBA32,
+ unpackRGBA32, packRGBA32, luminanceOfRGBA32, rgba32OfLuminance
+
+) where
+
+import Data.Bits
+import Data.Word
+import Codec.BMP
+
+import Data.Array.Accelerate as A
+import Data.Array.Accelerate.IO.ByteString as A
+
+
+-- File IO ---------------------------------------------------------------------
+
+-- | Read RGBA components from a BMP file
+--
+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
+ --
+ Right `fmap` A.fromByteString (Z :. h :. w) ((), bs)
+
+
+-- | Write the image data to a file.
+--
+writeImageToBMP :: FilePath -> Array DIM2 RGBA32 -> IO ()
+writeImageToBMP file rgba = do
+ let Z :. h :. w = A.arrayShape rgba
+ ((), bs) <- A.toByteString rgba
+ --
+ writeBMP file (packRGBA32ToBMP w h bs)
+
+
+-- Manipulating pixels ---------------------------------------------------------
+--
+-- TLM: this should be moved into something like:
+-- accelerate-algorithms:Data.Array.Accelerate.Algorithms.Pixel
+--
+
+-- | Packed RGBA pixel data
+--
+type RGBA32 = Word32
+
+-- | Unpack a RGBA32 value into a tuple of (Red, Green, Blue, Alpha) values.
+--
+unpackRGBA32 :: Exp RGBA32 -> Exp (Word8, Word8, Word8, Word8)
+unpackRGBA32 rgba =
+ let r = A.fromIntegral $ rgba .&. 0xFF
+ g = A.fromIntegral $ (rgba `div` 0x100) .&. 0xFF
+ b = A.fromIntegral $ (rgba `div` 0x10000) .&. 0xFF
+ a = A.fromIntegral $ (rgba `div` 0x1000000) .&. 0xFF
+ in
+ lift (r, g, b, a)
+
+
+-- | Promote a tuple of (Red, Green, Blue, Alpha) values into a packed RGBA32
+-- value.
+--
+packRGBA32 :: Exp (Word8, Word8, Word8, Word8) -> Exp RGBA32
+packRGBA32 rgba =
+ let (r', g', b', a') = unlift rgba
+ r = A.fromIntegral r'
+ g = (A.fromIntegral g') * 0x100
+ b = (A.fromIntegral b') * 0x10000
+ a = (A.fromIntegral a') * 0x1000000
+ in
+ r + g + b + a
+
+
+-- | Convert an RGBA colour to its luminance value in the range [0..1].
+--
+luminanceOfRGBA32 :: (Elt a, IsFloating a) => Exp RGBA32 -> Exp a
+luminanceOfRGBA32 rgba =
+ let r = 0.3 * A.fromIntegral (rgba .&. 0xFF)
+ g = 0.59 * A.fromIntegral ((rgba `div` 0x100) .&. 0xFF)
+ b = 0.11 * A.fromIntegral ((rgba `div` 0x10000) .&. 0xFF)
+ in
+ r + g + b
+
+
+-- | Convert a value in the range [0..1] to a grey RGB colour.
+--
+rgba32OfLuminance :: (Elt a, IsFloating a) => Exp a -> Exp RGBA32
+rgba32OfLuminance val =
+ let v = A.truncate (255 * val) -- (0 `A.max` val `A.min` 1)
+ r = v
+ g = v * 0x100
+ b = v * 0x10000
+ a = 0xFF000000
+ in
+ r + g + b + a
+
View
@@ -40,13 +40,15 @@ Library
Build-depends: accelerate == 0.13.*,
array >= 0.3,
base == 4.*,
+ bmp >= 1.2,
bytestring >= 0.9,
repa >= 3.2,
vector >= 0.9
Exposed-modules: Data.Array.Accelerate.IO
Other-modules: Data.Array.Accelerate.IO.BlockCopy
Data.Array.Accelerate.IO.ByteString
+ Data.Array.Accelerate.IO.BMP
Data.Array.Accelerate.IO.Ptr
Data.Array.Accelerate.IO.Repa
Data.Array.Accelerate.IO.Vector
@@ -67,3 +69,4 @@ Library
Source-repository head
Type: git
Location: git://github.com/AccelerateHS/accelerate-io.git
+

0 comments on commit 3ebc61f

Please sign in to comment.