Ticket #19: bmp-loader.dpatch

File bmp-loader.dpatch, 3.0 KB (added by Chris Smith, 13 years ago)

BMP file loader

Line 
11 patch for repository /home/cdsmith/gloss-head-tmp:
2
3Sun Aug  7 21:45:09 MDT 2011  Chris Smith <cdsmith@gmail.com>
4  * Add BMP file loader
5
6New patches:
7
8[Add BMP file loader
9Chris Smith <cdsmith@gmail.com>**20110808034509
10 Ignore-this: dbe9f2941ebccf3844cd0b768c35c5df
11] hunk ./library/Graphics/Gloss/Data/Picture.hs 15
12        , pictures
13 
14        -- * Miscellaneous
15+       , loadBMPFile
16        , lineLoop
17        , circleSolid
18       
19hunk ./library/Graphics/Gloss/Data/Picture.hs 26
20 import Graphics.Gloss.Data.Color
21 import Graphics.Gloss.Data.Point
22 import Graphics.Gloss.Data.Vector
23+import Control.Monad
24 import Data.Monoid
25hunk ./library/Graphics/Gloss/Data/Picture.hs 28
26-import Data.ByteString
27+
28+import Data.ByteString (ByteString)
29+import qualified Data.ByteString as B
30 
31 
32 -- | A path through the x-y plane.
33hunk ./library/Graphics/Gloss/Data/Picture.hs 127
34 pictures = Pictures
35 
36 
37+-- BMP file loader ------------------------------------------------------------
38+-- | An IO action that loads a BMP format file from the given path, and
39+-- produces a picture.
40+loadBMPFile :: FilePath -> IO Picture
41+loadBMPFile fname = do
42+    bs <- B.readFile fname
43+    when (not (isBmp bs)) $ error (fname ++ ": not a bmp file"                      )
44+    when (bpp  bs < 32)   $ error (fname ++ ": must be saved in 32-bit RGBA format" )
45+    when (comp bs /= 0)   $ error (fname ++ ": must be saved in uncompressed format")
46+    return (Bitmap (width bs) (height bs) (dat bs))
47+  where range s n bs    = B.unpack (B.take n (B.drop s bs))
48+        littleEndian ds = sum [ fromIntegral b * 256^k | (b,k) <- zip ds [(0 :: Int) ..] ]
49+        isBmp bs        = littleEndian (range  0 2 bs) == (19778 :: Int)
50+        pxOff bs        = littleEndian (range 10 4 bs) :: Int
51+        width bs        = littleEndian (range 18 4 bs) :: Int
52+        height bs       = littleEndian (range 22 4 bs) :: Int
53+        bpp bs          = littleEndian (range 28 2 bs) :: Int
54+        comp bs         = littleEndian (range 30 4 bs) :: Int
55+        dat bs          = swapRB (B.take (4 * width bs * height bs)
56+                                         (B.drop (pxOff bs) bs))
57+        swapRB bs
58+          | B.null bs   = B.empty
59+          | otherwise   = let [b,g,r,a] = B.unpack (B.take 4 bs)
60+                          in  B.pack [r,g,b,a] `B.append` swapRB (B.drop 4 bs)
61+
62+
63 -- Shapes ----------------------------------------------------------------------------------------
64 -- | A closed loop along this path.
65 lineLoop :: Path -> Picture
66
67Context:
68
69[fix typo in docs
70Chris Smith <cdsmith@gmail.com>**20110805043827
71 Ignore-this: 5eaa3e5393395f8d976fb104aec34715
72]
73[add circleSolid to export list
74Chris Smith <cdsmith@gmail.com>**20110808024148
75 Ignore-this: 62b8f994bd9f7a85fee0eb0524e84cb8
76]
77[Add circleSolid
78Chris Smith <cdsmith@gmail.com>**20110805044049
79 Ignore-this: 1d64f38f77e704a85eabdf21afcac0cb
80]
81[TAG Release 1.3.3.1
82Ben Lippmeier <benl@ouroborus.net>**20110803064127
83 Ignore-this: 66231bcec657fe6c21bb62dfe0dad8bf
84]
85Patch bundle hash:
865871429b1e30cb8988b490c99dc8e6e945d2d8d1