module Graphics.Exif (Exif,
fromFile, fromData,
getTag, allTags) where
import Graphics.Exif.Internals
import Control.Monad
import Foreign
newtype Exif = Exif (ForeignPtr ExifData)
fromFile :: FilePath -> IO Exif
fromFile f = dataFromFile f >>= mkExif
fromData :: Ptr () -> Int -> IO Exif
fromData p c = dataFromData p c >>= mkExif
getTag :: Exif -> String -> IO (Maybe String)
getTag x s = withExif x f
where f d = do t <- tagFromName s
es <- dataGetEntries d
e <- firstFilterM (entryHasTag t) es
maybe (return Nothing) (fmap Just . entryGetValue) e
allTags :: Exif -> IO [(String,String)]
allTags x = withExif x f
where f d = dataGetEntries d >>= mapM g
g e = do t <- entryGetTag e
n <- tagName t
v <- entryGetValue e
return (n,v)
mkExif :: Ptr ExifData -> IO Exif
mkExif p | p == nullPtr = fail "mkExif: NULL"
| otherwise = liftM Exif $ newForeignPtr dataFree p
withExif :: Exif -> (Ptr ExifData -> IO a) -> IO a
withExif (Exif e) f = withForeignPtr e f
dataGetEntries :: Ptr ExifData -> IO [Ptr ExifEntry]
dataGetEntries d = dataGetContents d >>= liftM concat . mapM contentGetEntries
entryHasTag :: ExifTag -> Ptr ExifEntry -> IO Bool
entryHasTag t e = liftM (==t) $ entryGetTag e
firstFilterM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
firstFilterM _ [] = return Nothing
firstFilterM f (x:xs) =
f x >>= \b -> if b then return (Just x) else firstFilterM f xs