diff --git a/Graphics/PDF/Documentation.hs b/Graphics/PDF/Documentation.hs
--- a/Graphics/PDF/Documentation.hs
+++ b/Graphics/PDF/Documentation.hs
@@ -302,6 +302,12 @@
 Right jpg <- 'readJpegFile' \"logo.jpg\"  
 @
 
+Alternatively, jpegs can be compiled into your code. After converting a jpeg to a data URL, a 'JpegFile' can be created with:
+
+@
+let Right jpg = readJpegDataURL "data:image/jpeg;base64,........."
+@
+
 The haskell code is just extracting the size of the image from the file. The image is not decoded.
 
 -}
diff --git a/Graphics/PDF/Draw.hs b/Graphics/PDF/Draw.hs
--- a/Graphics/PDF/Draw.hs
+++ b/Graphics/PDF/Draw.hs
@@ -104,6 +104,9 @@
 import Graphics.PDF.LowLevel.Serializer
 import Graphics.PDF.Resources
 import Graphics.PDF.Data.PDFTree(PDFTree)
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative
+#endif
 
 data AnnotationStyle = AnnotationStyle !(Maybe Color)
 
diff --git a/Graphics/PDF/Image.hs b/Graphics/PDF/Image.hs
--- a/Graphics/PDF/Image.hs
+++ b/Graphics/PDF/Image.hs
@@ -26,6 +26,7 @@
    , readJpegFile
    , jpegBounds
    , createPDFRawImage
+   , readJpegDataURL
  ) where
      
 import Graphics.PDF.LowLevel.Types
@@ -42,12 +43,21 @@
 #endif
 import Data.Char(ord)
 import Data.Bits
+#if __GLASGOW_HASKELL__ >= 710
 import qualified Control.Monad.Except as EXC
+#else
+import qualified Control.Monad.Error as EXC
+#endif
 import Graphics.PDF.Coordinates
-import Data.Binary.Builder(Builder,fromLazyByteString)
+import Data.Binary.Builder(Builder,fromLazyByteString,fromByteString)
 import Control.Exception as E
 import qualified Data.Vector.Unboxed as U
 import Data.Word
+import qualified Data.ByteString.Char8 as C8 (ByteString, pack, index, length)
+import Data.ByteString.Base64(decode)
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative
+#endif
 
 m_sof0 :: Int
 m_sof0 = 0xc0 
@@ -160,7 +170,11 @@
 io = FA . liftIO
 
 -- | File analyzer monad
+#if __GLASGOW_HASKELL__ >= 710
 newtype FA a = FA { unFA :: EXC.ExceptT String IO a}
+#else
+newtype FA a = FA { unFA :: EXC.ErrorT String IO a}
+#endif
 #ifndef __HADDOCK__
   deriving(Monad,Applicative,EXC.MonadError String,Functor)
 #else
@@ -171,7 +185,11 @@
 #endif
     
 runFA :: FA a -> IO (Either String a)
+#if __GLASGOW_HASKELL__ >= 710
 runFA = EXC.runExceptT . unFA
+#else
+runFA = EXC.runErrorT . unFA
+#endif
 
 readWord16 :: Handle -> FA Int
 readWord16 h = io $ do
@@ -335,7 +353,91 @@
                                                    , (PDFName "Interpolate", AnyPdfObject interpolate)
                                                    ]
                                              }
-                tell . fromLazyByteString . B.pack . addPixel . U.toList $ stream       
+                tell . fromLazyByteString . B.pack . addPixel . U.toList $ stream  
+
+-- Read Jpeg from ByteString
+-- These two functions bother me.  They could throw an exception if the incoming data is invalid...
+
+sIndex :: C8.ByteString -> Int -> Maybe Char
+sIndex bs idx = 
+  if (idx < 0) || (idx > C8.length bs)
+  then Nothing
+  else Just $ bs `C8.index` idx
+
+sReadWord8 :: C8.ByteString -> Int -> Maybe Int
+sReadWord8 bs idx = 
+  case mlo of
+    Nothing -> Nothing
+    Just lo -> Just (fromEnum . ord $ lo)
+  where mlo = bs `sIndex` idx
+
+sReadWord16 :: C8.ByteString -> Int -> Maybe Int
+sReadWord16 bs idx = 
+  case (sequence [mhi,mlo]) of
+    Nothing -> Nothing
+    Just [hi,lo] -> Just $ ((fromEnum hi) `shiftL` 8) .|. (fromEnum . ord $ lo)
+    Just _ -> Nothing
+  where mhi = bs `sIndex` idx
+        mlo = bs `sIndex` (idx + 1)
+
+parseJpegDetailData :: C8.ByteString -> Int -> Maybe (Int,Int,Int,Int)
+parseJpegDetailData bs offset = 
+  let m_bits_per_component = sReadWord8 bs (offset + 4)
+      m_height = sReadWord16 bs (offset + 5)
+      m_width = sReadWord16 bs (offset + 7)
+      m_color_space = sReadWord8 bs (offset + 9)
+  in case (sequence [m_bits_per_component, m_height, m_width, m_color_space]) of
+    Nothing -> Nothing
+    Just [bits_per_component, height, width, color_space] -> Just (bits_per_component, height, width, color_space)
+    Just _ -> Nothing
+
+parseJpegContentData :: C8.ByteString -> Int -> Either String (Int,Int,Int,Int)
+parseJpegContentData bs offset = 
+  let msof = sReadWord8 bs (offset + 1)
+      ml = sReadWord16 bs (offset + 2)
+  in case (sequence [msof, ml]) of
+    Nothing -> Left "Corrupt JPEG data URL"
+    Just [sof, l] -> case sof of
+                       a | a `elem` [m_sof5,m_sof6,m_sof7,m_sof9,m_sof10,m_sof11,m_sof13,m_sof14,m_sof15] -> Left "Unuspported compression mode"
+                         | a `elem` [m_sof0,m_sof1,m_sof3] -> case (parseJpegDetailData bs offset) of
+                                                                Nothing -> Left "Corrupt JPEG data URL"
+                                                                Just d -> Right d
+                         | a `elem` [m_soi,m_eoi,m_tem,m_rst0,m_rst1,m_rst2,m_rst3,m_rst4,m_rst5,m_rst6,m_rst7] -> parseJpegContentData bs (offset + 2)
+                         | otherwise -> parseJpegContentData bs (offset + l + 2)
+    Just _ -> Left "Corrupt JPEG data URL"
+
+analyzeJpegData :: C8.ByteString -> Either String (Int,PDFFloat,PDFFloat,Int)
+analyzeJpegData bs =
+  let mheader = sReadWord16 bs 0
+  in case mheader of
+    Nothing -> Left "Not a JPEG data URL"
+    Just header -> if (header /= 0x0FFD8) 
+                   then Left "Not a JPEG data URL"
+                   else let jpegData = parseJpegContentData bs 0
+                        in case jpegData of
+                          Right (bits_per_component,height,width,color_space) -> if (color_space `elem` [1,3,4])
+                                                                                 then Right (bits_per_component,(fromIntegral height),(fromIntegral width),color_space)
+                                                                                 else Left "Color space not supported"
+                          Left err -> Left err
+
+readJpegData :: String -> Either String JpegFile
+readJpegData dataString = 
+  case (decode $ C8.pack dataString) of
+    Left err -> Left err
+    Right bs -> 
+      let jpegData = analyzeJpegData bs
+      in case jpegData of
+           Left err -> Left err
+           Right (bits_per_component,height,width,color_space) -> Right $ JpegFile bits_per_component width height color_space (fromByteString bs) 
+
+-- | Reads a data URL string, and returns a JpegFile.
+-- The incoming string must be a correctly formatted data URL for a JPEG.
+-- You can convert jpeg files to data URLs at the following web site:
+-- http://dataurl.net/#dataurlmaker
+readJpegDataURL :: String -> Either String JpegFile
+readJpegDataURL dataurl = if (take 23 dataurl /= "data:image/jpeg;base64,")
+                          then Left "Data URL does not start with a valid JPEG header"
+                          else readJpegData $ drop 23 dataurl   
 
 -- | A Jpeg file   
 data JpegFile = JpegFile !Int !PDFFloat !PDFFloat !Int !Builder
diff --git a/Graphics/PDF/Text.hs b/Graphics/PDF/Text.hs
--- a/Graphics/PDF/Text.hs
+++ b/Graphics/PDF/Text.hs
@@ -62,6 +62,9 @@
 #else
 import Data.ByteString.Base(w2c,c2w)
 #endif
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative
+#endif
 
 foreign import ccall "ctext.h c_getLeading" cgetLeading :: Int -> Int
 foreign import ccall "ctext.h c_getAdvance" cgetAdvance :: Int -> Int -> Int
diff --git a/Graphics/PDF/Typesetting.hs b/Graphics/PDF/Typesetting.hs
--- a/Graphics/PDF/Typesetting.hs
+++ b/Graphics/PDF/Typesetting.hs
@@ -109,6 +109,9 @@
 import Graphics.PDF.Hyphenate
 import Data.List(unfoldr,intersperse)
 import Data.Char(isSpace,isAlpha)
+#if __GLASGOW_HASKELL__ < 710
+import Control.Applicative
+#endif
 
 -- | Display a formatted text in a given bounding rectangle with a given default paragraph style, a given default text style. No clipping
 -- is taking place. Drawing stop when the last line is crossing the bounding rectangle in vertical direction
diff --git a/HPDF.cabal b/HPDF.cabal
--- a/HPDF.cabal
+++ b/HPDF.cabal
@@ -1,14 +1,14 @@
 Name: HPDF
-Version: 1.4.7
+Version: 1.4.8
 cabal-version: >=1.6
 License: BSD3
 License-file:LICENSE
-Copyright: Copyright (c) 2007-2013, alpheccar.org
+Copyright: Copyright (c) 2007-2015, alpheccar.org
 category: Graphics
 synopsis: Generation of PDF documents
 maintainer: misc@NOSPAMalpheccar.org
 build-type: Simple
-tested-with: GHC==7.6.1
+tested-with: GHC==7.8.4,GHC==7.10.2
 homepage: http://www.alpheccar.org
 description: A PDF library with support for several pages, page transitions, outlines, annotations, compression, colors, shapes, patterns, jpegs, fonts, typesetting ... Have a look at the "Graphics.PDF.Documentation" module to see how to use it. Or, download the package and look at the test.hs file in the Test folder. That file is giving an example of each feature.
 extra-source-files:
@@ -23,7 +23,12 @@
   README.txt
   NEWS.txt
   TODO.txt
+  changelog.md
 
+source-repository head
+  type:     git
+  location: https://github.com/alpheccar/HPDF.git
+  
 library
   build-depends: 
       base >= 4 && < 5, 
@@ -34,7 +39,8 @@
       zlib >= 0.5, 
       binary >= 0.4, 
       mtl,
-      vector >=0.10
+      vector >=0.10,
+      base64-bytestring >= 0.1
   
   ghc-options: -Wall -fno-warn-tabs -funbox-strict-fields  -O2
 
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,4 @@
+HPDF 1.4.8 (released 2015-09-04)
+	* Building on GHC 7.10 and GHC 7.8.4 
+    * Parsing of JPEG data URLs by Scott Sedgwick
+    
