module Graphics.Hexif.PrettyPrintRat where
import Graphics.Hexif.DataExif
import Text.Printf (printf)
import GHC.Float
ppRationalValues :: ExifTag -> [(Int,Int)] -> String
ppRationalValues _ [] = "No values"
ppRationalValues tg (r : []) = ppRationalValue tg r
ppRationalValues TagGPSLatitude rs = ppGPSLongLatt rs
ppRationalValues TagGPSLongitude rs = ppGPSLongLatt rs
ppRationalValues TagGPSDestLatitude rs = ppGPSLongLatt rs
ppRationalValues TagGPSDestLongitude rs = ppGPSLongLatt rs
ppRationalValues TagGPSTimeStamp rs = ppGPSTimeStamp $ map rat2Double rs
ppRationalValues _ rs = concatMap fmtRat' rs
where fmtRat' r = fmtRat r ++ " "
ppRationalValue :: ExifTag -> (Int,Int) -> String
ppRationalValue t r
| t == TagExposureTime = fmtRatWithSlash r ++ " sec."
| t == TagFNumber = "f/" ++ fmtRatFloat r
| t == TagCompressedBitsPerPixel = ' ' : fmtRat r
| t == TagExposureBiasValue = ppExposureBiasValue r
| t == TagFocalLength = ppFocalLength r
| t == TagApertureValue = ppApertureValue f
| t == TagMaxApertureValue = ppApertureValue f
| t == TagShutterSpeedValue = ppShutterSpeedValue f
| t == TagDigitalZoomRatio = printf "%.4f" f
| t == TagBrightnessValue = ppBrightnessValue f
| otherwise = fmtRat r
where f = rat2Float r
rat2Float :: (Int,Int) -> Float
rat2Float (n,d) = (fromIntegral n::Float) / (fromIntegral d::Float)
rat2Double :: (Int,Int) -> Double
rat2Double (n,d) = (fromIntegral n::Double) / (fromIntegral d::Double)
fmtRatWithSlash :: (Int, Int) -> String
fmtRatWithSlash (num,denum) =
show (div num ggt) ++ "/" ++ show (div denum ggt)
where ggt = gcd num denum
fmtRat :: (Int, Int) -> String
fmtRat r@(num, denum) =
if mod num denum == 0 then fmtRatInt r else fmtRatFloat r
fmtRatInt :: (Int, Int) -> String
fmtRatInt (num, denum) = show $ div num denum
fmtRatFloat :: (Int, Int) -> String
fmtRatFloat = show . rat2Float
ppExposureBiasValue :: (Int, Int) -> String
ppExposureBiasValue r = printf "%.2f EV" (rat2Float r)
ppFocalLength :: (Int, Int) -> String
ppFocalLength r = printf "%.1f mm" (rat2Float r)
ppApertureValue :: Float -> String
ppApertureValue f = printf "%.2f EV (f/%.1f)" f pf
where
pf = 2 ** (f / 2)
ppShutterSpeedValue :: Float -> String
ppShutterSpeedValue f = printf "%.02f EV (1/%d sec.)" f (d::Int)
where
d = floor $ fromRational 2 ** f;
ppBrightnessValue :: Float -> String
ppBrightnessValue f = printf "%.2f EV (%.2f cd/m^2)" f pf
where
pf = 1 / (pi * 0.3048 * 0.3048) * 2 ** f
ppGPSLongLatt :: [(Int,Int)] -> String
ppGPSLongLatt rs = fmtLL fs
where
fs = map rat2Double rs
fmtLL (r1:r2:r3:[]) = printf "%2d, %2d, %.4f" d m s
where
(d,m,s) = degNorm r1 r2 r3
fmtLL _ = "verify data format"
degNorm :: Double -> Double -> Double -> (Int, Int, Float)
degNorm dd mm ss = (d, m, s)
where
secs = dd * 3600 + mm * 60 + ss
q1 = secs / 3600
d = floor q1
r1 = (q1 fromIntegral d) * 60
m = floor r1
s = double2Float (r1 fromIntegral m) * 60
ppGPSTimeStamp :: [Double] -> String
ppGPSTimeStamp [h, m, s] = printf "%02.0f:%02.0f:%05.2f" h m s
ppGPSTimeStamp _ = "Invalid date format"