module Graphics.Hexif.Jpeg
( Jpeg
, readJpegFromFile
, extractExif
) where
import Data.Binary
import Data.Binary.Get
import qualified Data.ByteString.Lazy as BL
data Jpeg = Jpeg
{ segments :: [JpegSegment]
}
deriving Eq
data JpegSegment = JpegSegment
{ segMarker :: Int
, segData :: BL.ByteString
}
deriving (Eq)
readJpegFromFile :: String -> IO Jpeg
readJpegFromFile fn = do
bsJpeg <- BL.readFile fn
return $ readJpeg bsJpeg
extractExif :: Jpeg -> BL.ByteString
extractExif jpeg = segData $ head (filter (\seg -> segMarker seg == 0xFFE1) (segments jpeg))
readJpeg :: BL.ByteString -> Jpeg
readJpeg = runGet getJpeg
where
getJpeg :: Get Jpeg
getJpeg = do
_ <- getWord16be
segs <- getSegments
return $ Jpeg segs
getSegments :: Get [JpegSegment]
getSegments = do
seg <- getSegment
if segMarker seg == 0xFFDA
then return [seg]
else do
segs <- getSegments
return $ seg : segs
getSegment :: Get JpegSegment
getSegment = do
marker <- getWord16be
_ <- bytesRead
len <- getWord16be
sgData <- getLazyByteString (fromIntegral len 2)
return $ JpegSegment (fromIntegral marker) sgData