diff --git a/Graphics/Gloss/Data/Picture.hs b/Graphics/Gloss/Data/Picture.hs
--- a/Graphics/Gloss/Data/Picture.hs
+++ b/Graphics/Gloss/Data/Picture.hs
@@ -11,8 +11,10 @@
 	, color, translate, rotate, scale
 	, pictures
 
-	-- * Line loops
+	-- * Miscellaneous
+	, loadBMP
  	, lineLoop
+ 	, circleSolid
 	
 	-- * Rectangles
 	, rectanglePath, 	rectangleWire, 		rectangleSolid
@@ -21,10 +23,13 @@
 import Graphics.Gloss.Data.Color
 import Graphics.Gloss.Data.Point
 import Graphics.Gloss.Data.Vector
+import Control.Monad
 import Data.Monoid
-import Data.ByteString
 
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
 
+
 -- | A path through the x-y plane.
 type Path	= [Point]				
 
@@ -119,6 +124,33 @@
 pictures = Pictures
 
 
+-- BMP file loader ------------------------------------------------------------
+-- | An IO action that loads a BMP format file from the given path, and
+--   produces a picture.
+--   TODO: Use Codec.BMP library instead.
+loadBMP :: FilePath -> IO Picture
+loadBMP fname = do
+    bs <- B.readFile fname
+    when (not (isBmp bs)) $ error (fname ++ ": not a bmp file"                      )
+    when (bpp  bs < 32)   $ error (fname ++ ": must be saved in 32-bit RGBA format" )
+    when (comp bs /= 0)   $ error (fname ++ ": must be saved in uncompressed format")
+    return (Bitmap (width bs) (height bs) (dat bs))
+  where range s n bs    = B.unpack (B.take n (B.drop s bs))
+        littleEndian ds = sum [ fromIntegral b * 256^k | (b,k) <- zip ds [(0 :: Int) ..] ]
+        isBmp bs        = littleEndian (range  0 2 bs) == (19778 :: Int)
+        pxOff bs        = littleEndian (range 10 4 bs) :: Int
+        width bs        = littleEndian (range 18 4 bs) :: Int
+        height bs       = littleEndian (range 22 4 bs) :: Int
+        bpp bs          = littleEndian (range 28 2 bs) :: Int
+        comp bs         = littleEndian (range 30 4 bs) :: Int
+        dat bs          = swapRB (B.take (4 * width bs * height bs)
+                                         (B.drop (pxOff bs) bs))
+        swapRB bs
+          | B.null bs   = B.empty
+          | otherwise   = let [b,g,r,a] = B.unpack (B.take 4 bs)
+                          in  B.pack [r,g,b,a] `B.append` swapRB (B.drop 4 bs)
+
+
 -- Shapes ----------------------------------------------------------------------------------------
 -- | A closed loop along this path.
 lineLoop :: Path -> Picture
@@ -164,8 +196,13 @@
 	= Polygon $ rectanglePath sizeX sizeY
 
 
--- | A sold rectangle in the y > 0 half of the x-y plane,
+-- | A solid rectangle in the y > 0 half of the x-y plane,
 --	with the given width and height.
 rectangleUpperSolid :: Float -> Float -> Picture
 rectangleUpperSolid sizeX sizeY
 	= Polygon  $ rectangleUpperPath sizeX sizeY
+
+-- | A solid circle with the given radius.
+circleSolid :: Float -> Picture
+circleSolid r = thickCircle (r/2) r
+
diff --git a/Graphics/Gloss/Data/Point.hs b/Graphics/Gloss/Data/Point.hs
--- a/Graphics/Gloss/Data/Point.hs
+++ b/Graphics/Gloss/Data/Point.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS -fno-warn-missing-methods #-}
+{-# OPTIONS -fno-warn-missing-methods -fno-warn-orphans #-}
 {-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
 module Graphics.Gloss.Data.Point
 	( Point
diff --git a/gloss.cabal b/gloss.cabal
--- a/gloss.cabal
+++ b/gloss.cabal
@@ -1,5 +1,5 @@
 Name:                gloss
-Version:             1.3.3.1
+Version:             1.3.4.1
 License:             MIT
 License-file:        LICENSE
 Author:              Ben Lippmeier
