{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
module Graphics.ExifTags where
import Data.Word
import Text.Printf (printf)
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Time.Calendar
import Data.Time.LocalTime
import Data.Binary.Get
import Data.Maybe (fromMaybe)
import Graphics.Types
import Graphics.PrettyPrinters
import Graphics.Helpers
exifSubIfdTag :: String -> Word16 -> (ExifValue -> Text)-> ExifTag
exifSubIfdTag :: String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
d = TagLocation
-> Maybe String -> Word16 -> (ExifValue -> Text) -> ExifTag
ExifTag TagLocation
ExifSubIFD (forall a. a -> Maybe a
Just String
d)
exifIfd0Tag :: String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag :: String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
d = TagLocation
-> Maybe String -> Word16 -> (ExifValue -> Text) -> ExifTag
ExifTag TagLocation
IFD0 (forall a. a -> Maybe a
Just String
d)
exifGpsTag :: String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag :: String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
d = TagLocation
-> Maybe String -> Word16 -> (ExifValue -> Text) -> ExifTag
ExifTag TagLocation
GpsSubIFD (forall a. a -> Maybe a
Just String
d)
withFormat :: String -> ExifValue -> Text
withFormat :: String -> ExifValue -> Text
withFormat String
fmt = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. PrintfType r => String -> r
printf String
fmt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
asFpWithFormat :: String -> ExifValue -> Text
asFpWithFormat :: String -> ExifValue -> Text
asFpWithFormat String
fmt = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r. PrintfType r => String -> r
printf String
fmt forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ExifValue -> String
formatAsFloatingPoint Int
2
showT :: Show a => a -> Text
showT :: forall a. Show a => a -> Text
showT = String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show
exposureTime :: ExifTag
exposureTime = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exposureTime" Word16
0x829a ExifValue -> Text
ppExposureTime
fnumber :: ExifTag
fnumber = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"fnumber" Word16
0x829d ExifValue -> Text
ppAperture
exposureProgram :: ExifTag
exposureProgram = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exposureProgram" Word16
0x8822 ExifValue -> Text
ppExposureProgram
spectralSensitivity :: ExifTag
spectralSensitivity = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"spectralSensitivity" Word16
0x8824 forall a. Show a => a -> Text
showT
isoSpeedRatings :: ExifTag
isoSpeedRatings = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"isoSpeedRatings" Word16
0x8827 forall a. Show a => a -> Text
showT
oecf :: ExifTag
oecf = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"OECF" Word16
0x8828 forall a. Show a => a -> Text
showT
exifVersion :: ExifTag
exifVersion = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exifVersion" Word16
0x9000 ExifValue -> Text
ppExifVersion
dateTimeOriginal :: ExifTag
dateTimeOriginal = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"dateTimeOriginal" Word16
0x9003 forall a. Show a => a -> Text
showT
dateTimeDigitized :: ExifTag
dateTimeDigitized = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"dateTimeDigitized" Word16
0x9004 forall a. Show a => a -> Text
showT
componentConfiguration :: ExifTag
componentConfiguration = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"componentConfiguration" Word16
0x9101 ExifValue -> Text
ppComponentConfiguration
compressedBitsPerPixel :: ExifTag
compressedBitsPerPixel = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"compressedBitsPerPixel" Word16
0x9102 (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ExifValue -> String
formatAsFloatingPoint Int
2)
shutterSpeedValue :: ExifTag
shutterSpeedValue = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"shutterSpeedValue" Word16
0x9201 ExifValue -> Text
ppExposureTime
apertureValue :: ExifTag
apertureValue = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"apertureValue" Word16
0x9202 ExifValue -> Text
ppApexAperture
brightnessValue :: ExifTag
brightnessValue = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"brightnessValue" Word16
0x9203 forall a b. (a -> b) -> a -> b
$ String -> ExifValue -> Text
asFpWithFormat String
"%s EV"
exposureBiasValue :: ExifTag
exposureBiasValue = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exposureBiasValue" Word16
0x9204 forall a b. (a -> b) -> a -> b
$ String -> ExifValue -> Text
asFpWithFormat String
"%s EV"
maxApertureValue :: ExifTag
maxApertureValue = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"maxApertureValue" Word16
0x9205 ExifValue -> Text
ppApexAperture
subjectDistance :: ExifTag
subjectDistance = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subjectDistance" Word16
0x9206 forall a. Show a => a -> Text
showT
meteringMode :: ExifTag
meteringMode = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"meteringMode" Word16
0x9207 ExifValue -> Text
ppMeteringMode
lightSource :: ExifTag
lightSource = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"lightSource" Word16
0x9208 ExifValue -> Text
ppLightSource
flash :: ExifTag
flash = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"flash" Word16
0x9209 ExifValue -> Text
ppFlash
focalLength :: ExifTag
focalLength = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"focalLength" Word16
0x920a forall a b. (a -> b) -> a -> b
$ String -> ExifValue -> Text
asFpWithFormat String
"%s mm"
subjectArea :: ExifTag
subjectArea = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subjectArea" Word16
0x9214 forall a. Show a => a -> Text
showT
makerNote :: ExifTag
makerNote = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"makerNote" Word16
0x927c ExifValue -> Text
ppUndef
= String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"userComment" Word16
0x9286 ExifValue -> Text
ppUserComment
subSecTime :: ExifTag
subSecTime = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subSecTime" Word16
0x9290 forall a. Show a => a -> Text
showT
subSecTimeOriginal :: ExifTag
subSecTimeOriginal = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subSecTimeOriginal" Word16
0x9291 forall a. Show a => a -> Text
showT
subSecTimeDigitized :: ExifTag
subSecTimeDigitized = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subSecTimeDigitized" Word16
0x9292 forall a. Show a => a -> Text
showT
flashPixVersion :: ExifTag
flashPixVersion = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"flashPixVersion" Word16
0xa000 ExifValue -> Text
ppFlashPixVersion
colorSpace :: ExifTag
colorSpace = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"colorSpace" Word16
0xa001 ExifValue -> Text
ppColorSpace
exifImageWidth :: ExifTag
exifImageWidth = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exifImageWidth" Word16
0xa002 forall a. Show a => a -> Text
showT
exifImageHeight :: ExifTag
exifImageHeight = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exifImageHeight" Word16
0xa003 forall a. Show a => a -> Text
showT
relatedSoundFile :: ExifTag
relatedSoundFile = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"relatedSoundFile" Word16
0xa004 forall a. Show a => a -> Text
showT
flashEnergy :: ExifTag
flashEnergy = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"flashEnergy" Word16
0xa20b forall a. Show a => a -> Text
showT
spatialFrequencyResponse :: ExifTag
spatialFrequencyResponse= String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"spatialFrequencyResponse" Word16
0xa20c forall a. Show a => a -> Text
showT
focalPlaneXResolution :: ExifTag
focalPlaneXResolution = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"focalPlaneXResolution" Word16
0xa20e forall a. Show a => a -> Text
showT
focalPlaneYResolution :: ExifTag
focalPlaneYResolution = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"focalPlaneYResolution" Word16
0xa20f forall a. Show a => a -> Text
showT
focalPlaneResolutionUnit :: ExifTag
focalPlaneResolutionUnit= String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"focalPlaneResolutionUnit" Word16
0xa210 ExifValue -> Text
ppFocalPlaneResolutionUnit
subjectLocation :: ExifTag
subjectLocation = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subjectLocation" Word16
0xa214 forall a. Show a => a -> Text
showT
exposureIndex :: ExifTag
exposureIndex = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exposureIndex" Word16
0xa215 forall a. Show a => a -> Text
showT
sensingMethod :: ExifTag
sensingMethod = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"sensingMethod" Word16
0xa217 ExifValue -> Text
ppSensingMethod
fileSource :: ExifTag
fileSource = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"fileSource" Word16
0xa300 ExifValue -> Text
ppFileSource
sceneType :: ExifTag
sceneType = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"sceneType" Word16
0xa301 ExifValue -> Text
ppSceneType
cfaPattern :: ExifTag
cfaPattern = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"cfaPattern" Word16
0xa302 forall a. Show a => a -> Text
showT
customRendered :: ExifTag
customRendered = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"customRendered" Word16
0xa401 ExifValue -> Text
ppCustomRendered
exposureMode :: ExifTag
exposureMode = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exposureMode" Word16
0xa402 ExifValue -> Text
ppExposureMode
whiteBalance :: ExifTag
whiteBalance = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"whiteBalance" Word16
0xa403 ExifValue -> Text
ppWhiteBalance
digitalZoomRatio :: ExifTag
digitalZoomRatio = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"digitalZoomRatio" Word16
0xa404 forall a. Show a => a -> Text
showT
focalLengthIn35mmFilm :: ExifTag
focalLengthIn35mmFilm = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"focalLengthIn35mmFilm" Word16
0xa405 forall a b. (a -> b) -> a -> b
$ String -> ExifValue -> Text
asFpWithFormat String
"%s mm"
sceneCaptureType :: ExifTag
sceneCaptureType = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"sceneCaptureType" Word16
0xa406 ExifValue -> Text
ppSceneCaptureType
gainControl :: ExifTag
gainControl = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"gainControl" Word16
0xa407 ExifValue -> Text
ppGainControl
contrast :: ExifTag
contrast = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"contrast" Word16
0xa408 ExifValue -> Text
ppContrastSharpness
saturation :: ExifTag
saturation = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"saturation" Word16
0xa409 ExifValue -> Text
ppSaturation
sharpness :: ExifTag
sharpness = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"sharpness" Word16
0xa40a ExifValue -> Text
ppContrastSharpness
deviceSettingDescription :: ExifTag
deviceSettingDescription= String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"deviceSettingDescription" Word16
0xa40b forall a. Show a => a -> Text
showT
subjectDistanceRange :: ExifTag
subjectDistanceRange = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"subjectDistanceRange" Word16
0xa40c ExifValue -> Text
ppSubjectDistanceRange
imageUniqueId :: ExifTag
imageUniqueId = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"imageUniqueId" Word16
0xa420 forall a. Show a => a -> Text
showT
exifInteroperabilityOffset :: ExifTag
exifInteroperabilityOffset=String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"exifInteroperabilityOffset" Word16
0xa005 forall a. Show a => a -> Text
showT
offsetTime :: ExifTag
offsetTime = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"offsetTime" Word16
0x9010 forall a. Show a => a -> Text
showT
offsetTimeDigitized :: ExifTag
offsetTimeDigitized = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"Offset Time Digitized" Word16
0x9012 forall a. Show a => a -> Text
showT
offsetTimeOriginal :: ExifTag
offsetTimeOriginal = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"Offset Time Original" Word16
0x9011 forall a. Show a => a -> Text
showT
lensSpecification :: ExifTag
lensSpecification = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"lensSpecification" Word16
0xa432 forall a. Show a => a -> Text
showT
lensMake :: ExifTag
lensMake = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"lensMake" Word16
0xa433 forall a. Show a => a -> Text
showT
lensModel :: ExifTag
lensModel = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"lensModel" Word16
0xa434 forall a. Show a => a -> Text
showT
compositeImage :: ExifTag
compositeImage = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"compositeImage" Word16
0xa460 forall a. Show a => a -> Text
showT
compositeImageCount :: ExifTag
compositeImageCount = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"compositeImageCount" Word16
0xa461 forall a. Show a => a -> Text
showT
compositeImageExposureTimes :: ExifTag
compositeImageExposureTimes = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifSubIfdTag String
"compositeImageExposureTimes" Word16
0xa462 forall a. Show a => a -> Text
showT
imageDescription :: ExifTag
imageDescription = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"imageDescription" Word16
0x010e forall a. Show a => a -> Text
showT
make :: ExifTag
make = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"make" Word16
0x010f forall a. Show a => a -> Text
showT
model :: ExifTag
model = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"model" Word16
0x0110 forall a. Show a => a -> Text
showT
orientation :: ExifTag
orientation = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"orientation" Word16
0x0112 ExifValue -> Text
ppOrientation
xResolution :: ExifTag
xResolution = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"xResolution" Word16
0x011a forall a. Show a => a -> Text
showT
yResolution :: ExifTag
yResolution = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"xResolution" Word16
0x011b forall a. Show a => a -> Text
showT
resolutionUnit :: ExifTag
resolutionUnit = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"resolutionUnit" Word16
0x0128 ExifValue -> Text
ppResolutionUnit
software :: ExifTag
software = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"software" Word16
0x0131 forall a. Show a => a -> Text
showT
dateTime :: ExifTag
dateTime = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"dateTime" Word16
0x0132 forall a. Show a => a -> Text
showT
artist :: ExifTag
artist = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"artist" Word16
0x013b forall a. Show a => a -> Text
showT
whitePoint :: ExifTag
whitePoint = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"whitePoint" Word16
0x013e forall a. Show a => a -> Text
showT
primaryChromaticities :: ExifTag
primaryChromaticities = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"primaryChromaticities" Word16
0x013f forall a. Show a => a -> Text
showT
yCbCrCoefficients :: ExifTag
yCbCrCoefficients = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"yCbCrCoefficients" Word16
0x0211 forall a. Show a => a -> Text
showT
yCbCrPositioning :: ExifTag
yCbCrPositioning = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"yCbCrPositioning" Word16
0x0213 ExifValue -> Text
ppYCbCrPositioning
referenceBlackWhite :: ExifTag
referenceBlackWhite = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"referenceBlackWhite" Word16
0x0214 forall a. Show a => a -> Text
showT
copyright :: ExifTag
copyright = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"copyright" Word16
0x8298 forall a. Show a => a -> Text
showT
printImageMatching :: ExifTag
printImageMatching = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"printImageMatching" Word16
0xc4a5 ExifValue -> Text
ppUndef
hostComputer :: ExifTag
hostComputer = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifIfd0Tag String
"hostComputer" Word16
0x13c forall a. Show a => a -> Text
showT
gpsVersionID :: ExifTag
gpsVersionID = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsVersionID" Word16
0x0000 forall a. Show a => a -> Text
showT
gpsLatitudeRef :: ExifTag
gpsLatitudeRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsLatitudeRef" Word16
0x0001 ExifValue -> Text
ppGpsLatitudeRef
gpsLatitude :: ExifTag
gpsLatitude = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsLatitude" Word16
0x0002 ExifValue -> Text
ppGpsLongLat
gpsLongitudeRef :: ExifTag
gpsLongitudeRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsLongitudeRef" Word16
0x0003 ExifValue -> Text
ppGpsLongitudeRef
gpsLongitude :: ExifTag
gpsLongitude = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsLongitude" Word16
0x0004 ExifValue -> Text
ppGpsLongLat
gpsAltitudeRef :: ExifTag
gpsAltitudeRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsAltitudeRef" Word16
0x0005 ExifValue -> Text
ppGpsAltitudeRef
gpsAltitude :: ExifTag
gpsAltitude = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsAltitude" Word16
0x0006 (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ExifValue -> String
formatAsFloatingPoint Int
4)
gpsTimeStamp :: ExifTag
gpsTimeStamp = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsTimeStamp" Word16
0x0007 ExifValue -> Text
ppGpsTimeStamp
gpsSatellites :: ExifTag
gpsSatellites = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsSatellites" Word16
0x0008 forall a. Show a => a -> Text
showT
gpsStatus :: ExifTag
gpsStatus = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsStatus" Word16
0x0009 forall a. Show a => a -> Text
showT
gpsMeasureMode :: ExifTag
gpsMeasureMode = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsMeasureMode" Word16
0x000a forall a. Show a => a -> Text
showT
gpsDop :: ExifTag
gpsDop = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDop" Word16
0x000b forall a. Show a => a -> Text
showT
gpsSpeedRef :: ExifTag
gpsSpeedRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsSpeedRef" Word16
0x000c forall a. Show a => a -> Text
showT
gpsSpeed :: ExifTag
gpsSpeed = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsSpeed" Word16
0x000d forall a. Show a => a -> Text
showT
gpsTrackRef :: ExifTag
gpsTrackRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsTrackRef" Word16
0x000e forall a. Show a => a -> Text
showT
gpsTrack :: ExifTag
gpsTrack = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsTrack" Word16
0x000f forall a. Show a => a -> Text
showT
gpsImgDirectionRef :: ExifTag
gpsImgDirectionRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsImgDirectionRef" Word16
0x0010 forall a. Show a => a -> Text
showT
gpsImgDirection :: ExifTag
gpsImgDirection = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsImgDirection" Word16
0x0011 forall a. Show a => a -> Text
showT
gpsMapDatum :: ExifTag
gpsMapDatum = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsMapDatum" Word16
0x0012 forall a. Show a => a -> Text
showT
gpsDestLatitudeRef :: ExifTag
gpsDestLatitudeRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestLatitudeRef" Word16
0x0013 forall a. Show a => a -> Text
showT
gpsDestLatitude :: ExifTag
gpsDestLatitude = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestLatitude" Word16
0x0014 forall a. Show a => a -> Text
showT
gpsDestLongitudeRef :: ExifTag
gpsDestLongitudeRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestLongitudeRef" Word16
0x0015 forall a. Show a => a -> Text
showT
gpsDestLongitude :: ExifTag
gpsDestLongitude = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestLongitude" Word16
0x0016 forall a. Show a => a -> Text
showT
gpsDestBearingRef :: ExifTag
gpsDestBearingRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestBearingRef" Word16
0x0017 forall a. Show a => a -> Text
showT
gpsDestBearing :: ExifTag
gpsDestBearing = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestBearing" Word16
0x0018 forall a. Show a => a -> Text
showT
gpsDestDistanceRef :: ExifTag
gpsDestDistanceRef = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestDistanceRef" Word16
0x0019 forall a. Show a => a -> Text
showT
gpsDestDistance :: ExifTag
gpsDestDistance = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDestDistance" Word16
0x001a forall a. Show a => a -> Text
showT
gpsProcessingMethod :: ExifTag
gpsProcessingMethod = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsProcessingMethod" Word16
0x001b forall a. Show a => a -> Text
showT
gpsAreaInformation :: ExifTag
gpsAreaInformation = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsAreaInformation" Word16
0x001c forall a. Show a => a -> Text
showT
gpsDateStamp :: ExifTag
gpsDateStamp = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDateStamp" Word16
0x001d ExifValue -> Text
ppGpsDateStamp
gpsDifferential :: ExifTag
gpsDifferential = String -> Word16 -> (ExifValue -> Text) -> ExifTag
exifGpsTag String
"gpsDifferential" Word16
0x001e forall a. Show a => a -> Text
showT
allExifTags :: [ExifTag]
allExifTags :: [ExifTag]
allExifTags = [ExifTag
exposureTime, ExifTag
fnumber, ExifTag
exposureProgram, ExifTag
isoSpeedRatings,
ExifTag
exifVersion, ExifTag
dateTimeOriginal, ExifTag
dateTimeDigitized, ExifTag
componentConfiguration,
ExifTag
compressedBitsPerPixel, ExifTag
shutterSpeedValue, ExifTag
apertureValue, ExifTag
brightnessValue,
ExifTag
exposureBiasValue, ExifTag
maxApertureValue, ExifTag
subjectDistance, ExifTag
meteringMode,
ExifTag
lightSource, ExifTag
flash, ExifTag
focalLength, ExifTag
makerNote, ExifTag
userComment,
ExifTag
exifImageWidth, ExifTag
exifImageHeight, ExifTag
relatedSoundFile, ExifTag
focalPlaneXResolution,
ExifTag
focalPlaneYResolution, ExifTag
focalPlaneResolutionUnit, ExifTag
sensingMethod, ExifTag
fileSource,
ExifTag
sceneType, ExifTag
orientation, ExifTag
make, ExifTag
model, ExifTag
software, ExifTag
copyright,
ExifTag
spectralSensitivity, ExifTag
oecf, ExifTag
subjectArea, ExifTag
subSecTime, ExifTag
subSecTimeOriginal,
ExifTag
subSecTimeDigitized, ExifTag
flashPixVersion, ExifTag
colorSpace, ExifTag
flashEnergy,
ExifTag
spatialFrequencyResponse, ExifTag
subjectLocation, ExifTag
exposureIndex, ExifTag
cfaPattern,
ExifTag
customRendered, ExifTag
exposureMode, ExifTag
whiteBalance, ExifTag
digitalZoomRatio,
ExifTag
focalLengthIn35mmFilm, ExifTag
sceneCaptureType, ExifTag
gainControl, ExifTag
contrast,
ExifTag
saturation, ExifTag
sharpness, ExifTag
deviceSettingDescription, ExifTag
subjectDistanceRange,
ExifTag
imageUniqueId, ExifTag
exifInteroperabilityOffset, ExifTag
imageDescription,
ExifTag
xResolution, ExifTag
yResolution, ExifTag
resolutionUnit, ExifTag
dateTime, ExifTag
whitePoint,
ExifTag
primaryChromaticities, ExifTag
yCbCrPositioning, ExifTag
yCbCrCoefficients, ExifTag
referenceBlackWhite,
ExifTag
printImageMatching, ExifTag
artist,
ExifTag
gpsVersionID, ExifTag
gpsLatitudeRef, ExifTag
gpsLatitude, ExifTag
gpsLongitudeRef, ExifTag
gpsLongitude,
ExifTag
gpsAltitudeRef, ExifTag
gpsAltitude, ExifTag
gpsTimeStamp, ExifTag
gpsSatellites, ExifTag
gpsStatus,
ExifTag
gpsMeasureMode, ExifTag
gpsDop, ExifTag
gpsSpeedRef, ExifTag
gpsSpeed, ExifTag
gpsTrackRef, ExifTag
gpsTrack,
ExifTag
gpsImgDirectionRef, ExifTag
gpsImgDirection, ExifTag
gpsMapDatum, ExifTag
gpsDestLatitudeRef,
ExifTag
gpsDestLatitude, ExifTag
gpsDestLongitudeRef, ExifTag
gpsDestLongitude, ExifTag
gpsDestBearingRef,
ExifTag
gpsDestBearing, ExifTag
gpsDestDistanceRef, ExifTag
gpsDestDistance, ExifTag
gpsProcessingMethod,
ExifTag
gpsAreaInformation, ExifTag
gpsDateStamp, ExifTag
gpsDifferential,
ExifTag
offsetTime, ExifTag
offsetTimeDigitized, ExifTag
offsetTimeOriginal, ExifTag
lensSpecification,
ExifTag
lensMake, ExifTag
lensModel, ExifTag
compositeImage, ExifTag
compositeImageCount, ExifTag
compositeImageExposureTimes,
ExifTag
hostComputer]
getGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)
getGpsLatitudeLongitude :: Map ExifTag ExifValue -> Maybe (Double, Double)
getGpsLatitudeLongitude Map ExifTag ExifValue
exifData = do
(ExifText String
latRef) <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsLatitudeRef Map ExifTag ExifValue
exifData
Double
latDec <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsLatitude Map ExifTag ExifValue
exifData forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExifValue -> Maybe Double
gpsDecodeToDecimalDegrees
let signedLatDec :: Double
signedLatDec = if String
latRef forall a. Eq a => a -> a -> Bool
== String
"S" then -Double
latDec else Double
latDec
(ExifText String
longRef) <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsLongitudeRef Map ExifTag ExifValue
exifData
Double
longDec <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsLongitude Map ExifTag ExifValue
exifData forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExifValue -> Maybe Double
gpsDecodeToDecimalDegrees
let signedLongDec :: Double
signedLongDec = if String
longRef forall a. Eq a => a -> a -> Bool
== String
"W" then -Double
longDec else Double
longDec
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
signedLatDec, Double
signedLongDec)
gpsLongLatToCoords :: ExifValue -> Maybe (Double, Double, Double)
gpsLongLatToCoords :: ExifValue -> Maybe (Double, Double, Double)
gpsLongLatToCoords (ExifRationalList [(Int, Int)]
intPairs) = case forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a} {a} {a}.
(Fractional a, Integral a, Integral a) =>
(a, a) -> a
intPairToFloating [(Int, Int)]
intPairs of
[Double
degrees, Double
minutes, Double
seconds] -> forall a. a -> Maybe a
Just (Double
degrees, Double
minutes, Double
seconds)
[Double]
_ -> forall a. Maybe a
Nothing
where
intPairToFloating :: (a, a) -> a
intPairToFloating (a
n, a
d) = forall a b. (Integral a, Num b) => a -> b
fromIntegral a
n forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral a
d
gpsLongLatToCoords ExifValue
_ = forall a. Maybe a
Nothing
gpsDecodeToDecimalDegrees :: ExifValue -> Maybe Double
gpsDecodeToDecimalDegrees :: ExifValue -> Maybe Double
gpsDecodeToDecimalDegrees ExifValue
v = do
(Double
degrees, Double
minutes, Double
seconds) <- ExifValue -> Maybe (Double, Double, Double)
gpsLongLatToCoords ExifValue
v
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Double
degrees forall a. Num a => a -> a -> a
+ Double
minutes forall a. Fractional a => a -> a -> a
/ Double
60 forall a. Num a => a -> a -> a
+ Double
seconds forall a. Fractional a => a -> a -> a
/ Double
3600
ppGpsLongLat :: ExifValue -> Text
ppGpsLongLat :: ExifValue -> Text
ppGpsLongLat ExifValue
x = forall a. a -> Maybe a -> a
fromMaybe Text
"Invalid GPS data" forall a b. (a -> b) -> a -> b
$ ExifValue -> Maybe Text
_ppGpsLongLat ExifValue
x
_ppGpsLongLat :: ExifValue -> Maybe Text
_ppGpsLongLat :: ExifValue -> Maybe Text
_ppGpsLongLat ExifValue
v = do
(Double
degrees, Double
minutes, Double
seconds) <- ExifValue -> Maybe (Double, Double, Double)
gpsLongLatToCoords ExifValue
v
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack forall a b. (a -> b) -> a -> b
$ forall r. PrintfType r => String -> r
printf String
"%.0f° %.0f' %.2f\"" Double
degrees Double
minutes Double
seconds
getGpsDateTime :: Map ExifTag ExifValue -> Maybe LocalTime
getGpsDateTime :: Map ExifTag ExifValue -> Maybe LocalTime
getGpsDateTime Map ExifTag ExifValue
exifData = do
Day
gpsDate <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsDateStamp Map ExifTag ExifValue
exifData forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExifValue -> Maybe Day
parseGpsDate
TimeOfDay
gpsTime <- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ExifTag
gpsTimeStamp Map ExifTag ExifValue
exifData forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ExifValue -> Maybe TimeOfDay
parseGpsTime
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Day -> TimeOfDay -> LocalTime
LocalTime Day
gpsDate TimeOfDay
gpsTime
parseGpsDate :: ExifValue -> Maybe Day
parseGpsDate :: ExifValue -> Maybe Day
parseGpsDate (ExifText String
dateStr) = forall a. Get a -> ByteString -> Maybe a
runMaybeGet Get Day
getExifDate forall a b. (a -> b) -> a -> b
$ String -> ByteString
stringToByteString String
dateStr
parseGpsDate ExifValue
_ = forall a. Maybe a
Nothing
getExifDate :: Get Day
getExifDate :: Get Day
getExifDate = do
Year
year <- forall a. Read a => Int -> Get a
readDigit Int
4
Int
month <- Char -> Get Char
getCharValue Char
':' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Read a => Int -> Get a
readDigit Int
2
Int
day <- Char -> Get Char
getCharValue Char
':' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Read a => Int -> Get a
readDigit Int
2
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Year -> Int -> Int -> Day
fromGregorian Year
year Int
month Int
day
parseGpsTime :: ExifValue -> Maybe TimeOfDay
parseGpsTime :: ExifValue -> Maybe TimeOfDay
parseGpsTime (ExifRationalList [(Int
hr_n, Int
hr_d), (Int
min_n, Int
min_d), (Int
sec_n, Int
sec_d)]) =
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Int -> Int -> Pico -> TimeOfDay
TimeOfDay (Int
hr_n forall a. Integral a => a -> a -> a
`div` Int
hr_d) (Int
min_n forall a. Integral a => a -> a -> a
`div` Int
min_d) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sec_n forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sec_d)
parseGpsTime ExifValue
_ = forall a. Maybe a
Nothing
ppGpsTimeStamp :: ExifValue -> Text
ppGpsTimeStamp :: ExifValue -> Text
ppGpsTimeStamp ExifValue
exifV = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"invalid" (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {t}. PrintfType t => TimeOfDay -> t
formatTod) forall a b. (a -> b) -> a -> b
$ ExifValue -> Maybe TimeOfDay
parseGpsTime ExifValue
exifV
where formatTod :: TimeOfDay -> t
formatTod (TimeOfDay Int
h Int
m Pico
s) = forall r. PrintfType r => String -> r
printf String
"%02d:%02d:%02.2f" Int
h Int
m (forall a b. (Real a, Fractional b) => a -> b
realToFrac Pico
s :: Float)
ppGpsDateStamp :: ExifValue -> Text
ppGpsDateStamp :: ExifValue -> Text
ppGpsDateStamp ExifValue
exifV = forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"invalid" (String -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {t} {t} {t} {t}.
(PrintfArg t, PrintfArg t, PrintfArg t, PrintfType t) =>
(t, t, t) -> t
formatDay forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> (Year, Int, Int)
toGregorian) forall a b. (a -> b) -> a -> b
$ ExifValue -> Maybe Day
parseGpsDate ExifValue
exifV
where formatDay :: (t, t, t) -> t
formatDay (t
year, t
month, t
day) = forall r. PrintfType r => String -> r
printf String
"%d-%02d-%02d" t
year t
month t
day
ppGpsLatitudeRef :: ExifValue -> Text
ppGpsLatitudeRef :: ExifValue -> Text
ppGpsLatitudeRef (ExifText String
"N") = Text
"North"
ppGpsLatitudeRef (ExifText String
"S") = Text
"South"
ppGpsLatitudeRef ExifValue
v = String -> Text
T.pack forall a b. (a -> b) -> a -> b
$ String
"Invalid latitude: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ExifValue
v
ppGpsLongitudeRef :: ExifValue -> Text
ppGpsLongitudeRef :: ExifValue -> Text
ppGpsLongitudeRef (ExifText String
"E") = Text
"East"
ppGpsLongitudeRef (ExifText String
"W") = Text
"West"
ppGpsLongitudeRef ExifValue
v = String -> Text
T.pack forall a b. (a -> b) -> a -> b
$ String
"Invalid longitude: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show ExifValue
v