packages feed

hsexif 0.4.0.1 → 0.5.0.0

raw patch · 3 files changed

+41/−37 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Graphics.HsExif: readGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)
+ Graphics.HsExif: getGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)

Files

Graphics/HsExif.hs view
@@ -13,7 +13,7 @@ 	getOrientation, 	ImageOrientation(..), 	RotationDirection(..),-	readGpsLatitudeLongitude,+	getGpsLatitudeLongitude,  	-- * The ExifValue type 	ExifValue(..),@@ -142,7 +142,7 @@ import Data.Binary.Put import qualified Data.ByteString.Lazy as B import qualified Data.ByteString as BS-import Control.Monad (liftM, unless)+import Control.Monad (liftM, unless, replicateM) import qualified Data.ByteString.Char8 as Char8 import Data.Word import Data.Char (isDigit, ord, chr)@@ -239,7 +239,7 @@ getWord32 Intel = getWord32le getWord32 Motorola = getWord32be -putWord32 :: ByteAlign -> (Word32 -> Put)+putWord32 :: ByteAlign -> Word32 -> Put putWord32 Intel = putWord32le putWord32 Motorola = putWord32be @@ -514,16 +514,16 @@ 		readMany :: ByteAlign -> Int -> Get ExifValue 	} -readNumberList decoder = \byteAlign components -> liftM (ExifNumberList . fmap fromIntegral)-			$ readManyInternal byteAlign components-			where readManyInternal byteAlign components = count components (decoder byteAlign)+readNumberList :: Integral a => (ByteAlign -> Get a) -> ByteAlign -> Int -> Get ExifValue+readNumberList decoder byteAlign components = liftM (ExifNumberList . fmap fromIntegral)+			$ count components (decoder byteAlign)  unsignedByteValueHandler = ValueHandler 	{ 		dataTypeId = 1, 		dataLength = 1, 		readSingle = \_ -> liftM (ExifNumber . fromIntegral) getWord8,-		readMany = readNumberList (\_ -> getWord8)+		readMany = readNumberList $ const getWord8 	}  asciiStringValueHandler = ValueHandler@@ -538,7 +538,7 @@ 	{ 		dataTypeId = 3, 		dataLength = 2,-		readSingle = \byteAlign -> liftM (ExifNumber . fromIntegral) $ getWord16 byteAlign,+		readSingle = liftM (ExifNumber . fromIntegral) . getWord16, 		readMany = readNumberList getWord16 	} @@ -546,7 +546,7 @@ 	{ 		dataTypeId = 4, 		dataLength = 4,-		readSingle = \byteAlign -> liftM (ExifNumber . fromIntegral) $ getWord32 byteAlign,+		readSingle = liftM (ExifNumber . fromIntegral) . getWord32, 		readMany = readNumberList getWord32 	} @@ -561,8 +561,7 @@ 		dataTypeId = 5, 		dataLength = 8, 		readSingle = readRationalContents ExifRational,-		readMany = let readManyInternal byteAlign components = count components (readRationalContents (,) byteAlign) in-			\byteAlign components -> liftM ExifRationalList $ readManyInternal byteAlign components+		readMany = \byteAlign components -> liftM ExifRationalList $ count components (readRationalContents (,) byteAlign) 	}  signedByteValueHandler = ValueHandler@@ -570,7 +569,7 @@ 		dataTypeId = 6, 		dataLength = 1, 		readSingle = \_ -> liftM (ExifNumber . signedInt8ToInt) getWord8,-		readMany = readNumberList (\_ -> liftM signedInt8ToInt getWord8)+		readMany = readNumberList (liftM signedInt8ToInt . const getWord8) 	}  undefinedValueHandler = ValueHandler@@ -585,16 +584,16 @@ 	{ 		dataTypeId = 8, 		dataLength = 2,-		readSingle = \byteAlign -> liftM (ExifNumber . signedInt16ToInt) $ getWord16 byteAlign,-		readMany = readNumberList (\b -> liftM signedInt16ToInt $ getWord16 b)+		readSingle = liftM (ExifNumber . signedInt16ToInt) . getWord16,+		readMany = readNumberList (liftM signedInt16ToInt . getWord16) 	}  signedLongValueHandler = ValueHandler 	{ 		dataTypeId = 9, 		dataLength = 4,-		readSingle = \byteAlign -> liftM (ExifNumber . signedInt32ToInt) $ getWord32 byteAlign,-		readMany = readNumberList (\b -> liftM signedInt32ToInt $ getWord32 b)+		readSingle = liftM (ExifNumber . signedInt32ToInt) . getWord32,+		readMany = readNumberList (liftM signedInt32ToInt . getWord32) 	}  readSignedRationalContents :: (Int -> Int -> a) -> ByteAlign -> Get a@@ -608,8 +607,7 @@ 		dataTypeId = 10, 		dataLength = 8, 		readSingle = readSignedRationalContents ExifRational,-		readMany = let readManyInternal byteAlign components = count components (readSignedRationalContents (,) byteAlign) in-			\byteAlign components -> liftM ExifRationalList $ readManyInternal byteAlign components+		readMany = \byteAlign components -> liftM ExifRationalList $ count components (readSignedRationalContents (,) byteAlign) 	}  valueHandlers :: [ValueHandler]@@ -643,12 +641,12 @@ getHandler typeId = find ((==typeId) . dataTypeId) valueHandlers  decodeEntryWithHandler :: ByteAlign -> Int -> ValueHandler -> IfEntry -> Get ExifValue-decodeEntryWithHandler byteAlign tiffHeaderStart handler entry = do-	if dataLength handler * (entryNoComponents entry) <= 4-		then return $ parseInline byteAlign handler entry inlineBs+decodeEntryWithHandler byteAlign tiffHeaderStart handler entry =+	if dataLength handler * entryNoComponents entry <= 4+		then do+			let inlineBs = runPut $ putWord32 byteAlign $ entryContents entry+			return $ parseInline byteAlign handler entry inlineBs 		else parseOffset byteAlign tiffHeaderStart handler entry-	where-		inlineBs = runPut $ putWord32 byteAlign $ entryContents entry  parseInline :: ByteAlign -> ValueHandler -> IfEntry -> B.ByteString -> ExifValue parseInline byteAlign handler entry bytestring =@@ -702,7 +700,7 @@  count :: Int -> Get a -> Get [a] count n p | n <= 0 = return []-        | otherwise = sequence (replicate n p)+        | otherwise = replicateM n p 	  -- | Extract the date and time when the picture was taken@@ -752,26 +750,27 @@  -- | Extract the GPS latitude and longitude where the picture was taken -- (if it is present in the EXIF)-readGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)-readGpsLatitudeLongitude exifData = do+getGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)+getGpsLatitudeLongitude exifData = do 	(ExifText latRef) <- Map.lookup gpsLatitudeRef exifData-	latDec <- liftM gpsDecodeToDecimalDegrees $ Map.lookup gpsLatitude exifData+	latDec <- Map.lookup gpsLatitude exifData >>= gpsDecodeToDecimalDegrees  	let signedLatDec = case latRef of 		"S" -> -latDec 		_ -> latDec 	(ExifText longRef) <- Map.lookup gpsLongitudeRef exifData-	longDec <- liftM gpsDecodeToDecimalDegrees $ Map.lookup gpsLongitude exifData+	longDec <- Map.lookup gpsLongitude exifData >>= gpsDecodeToDecimalDegrees  	let signedLongDec = case longRef of 		"W" -> -longDec 		_ -> longDec 	return (signedLatDec, signedLongDec) -gpsDecodeToDecimalDegrees :: ExifValue -> Double-gpsDecodeToDecimalDegrees (ExifRationalList intPairs) = floatings !! 0 + floatings !! 1 / 60 + floatings !! 2 / 3600+gpsDecodeToDecimalDegrees :: ExifValue -> Maybe Double+gpsDecodeToDecimalDegrees (ExifRationalList intPairs) = case fmap (uncurry intsToFloating) intPairs of+			(degrees:minutes:seconds:[]) -> Just $ degrees + minutes / 60 + seconds / 3600+			_ -> Nothing 	where-		floatings = fmap (uncurry intsToFloating) intPairs-		intsToFloating n d = (fromIntegral n) / (fromIntegral d)-gpsDecodeToDecimalDegrees _ = error "gpsDecodeToDecimalDegrees not called on a rational list!?" -- no way to prevent this at compile time???+		intsToFloating n d = fromIntegral n / fromIntegral d+gpsDecodeToDecimalDegrees _ = Nothing  -- $intro --
hsexif.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                hsexif-version:             0.4.0.1+version:             0.5.0.0 synopsis:            EXIF handling library in pure Haskell description:         The hsexif library provides functions for working with EXIF data                      contained in JPEG files. Currently it only supports reading the data.
tests/Tests.hs view
@@ -26,8 +26,9 @@ 		describe "basic parsing" $ testBasic imageContents 		describe "extract picture date" $ testDate exifData 		describe "image orientation" $ testOrientation exifData-		describe "read exif date time" $ testReadExifDateTime+		describe "read exif date time" testReadExifDateTime 		describe "read GPS lat long" $ testReadGpsLatLong gpsExifData+		describe "read GPS lat long -- no data" $ testReadGpsLatLongNoData exifData  testNotAJpeg :: B.ByteString -> Spec testNotAJpeg imageContents = it "returns empty list if not a JPEG" $@@ -94,7 +95,7 @@ 	where 		-- the makerNote is HUGE. so test it separately. 		parsed = (\(Right x) -> x) $ parseExif imageContents-		cleanedParsed = Map.fromList $ filter (\(a,_) -> not (a==makerNote)) $ Map.toList parsed+		cleanedParsed = Map.fromList $ filter (\(a,_) -> (a/=makerNote)) $ Map.toList parsed 		makerNoteV = (\(Just (ExifUndefined x)) -> x) $ Map.lookup makerNote parsed  testDate :: Map ExifTag ExifValue -> Spec@@ -113,9 +114,13 @@  testReadGpsLatLong :: Map ExifTag ExifValue -> Spec testReadGpsLatLong exifData = it "reads gps latitude longitude" $ do-	let (Just (lat,long)) = readGpsLatitudeLongitude exifData+	let (Just (lat,long)) = getGpsLatitudeLongitude exifData 	assertBool' $ 50.2179 < lat && 50.2180 > lat 	assertBool' $ -5.031 > long && -5.032 < long ++testReadGpsLatLongNoData :: Map ExifTag ExifValue -> Spec+testReadGpsLatLongNoData exifData = it "reads gps latitude longitude" $+	assertEqual' Nothing $ getGpsLatitudeLongitude exifData  assertEqual' :: (Show a, Eq a) => a -> a -> Assertion assertEqual' = assertEqual "doesn't match"