hsexif-0.5.0.3: Graphics/PrettyPrinters.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Graphics.PrettyPrinters where
import Graphics.Types (ExifValue(..))
import Data.List (foldl')
import Text.Printf (printf)
import qualified Data.Map as Map
import Data.Char (chr)
import qualified Data.ByteString as BS
import Control.Arrow (first)
ppResolutionUnit :: ExifValue -> String
ppResolutionUnit = fromNumberMap [(1, "No absolute unit"),
(2, "Inch"),
(3, "Centimeter")]
ppYCbCrPositioning :: ExifValue -> String
ppYCbCrPositioning = fromNumberMap [(1, "Centered"), (2, "Co-sited")]
ppExposureProgram :: ExifValue -> String
ppExposureProgram = fromNumberMap [(0, "Not defined"),
(1, "Manual"),
(2, "Normal program"),
(3, "Aperture priority"),
(4, "Shutter priority"),
(5, "Creative program (biased toward depth of field)"),
(6, "Action program (biased toward fast shutter speed)"),
(7, "Portrait mode (for closeup photos with the background out of focus)"),
(8, "Landscape mode (for landscape photos with the background in focus)")]
ppMeteringMode :: ExifValue -> String
ppMeteringMode = fromNumberMap [(0, "Unknown"),
(1, "Average"),
(2, "Center-weighted average"),
(3, "Spot"),
(4, "MultiSpot"),
(5, "Pattern"),
(6, "Partial"),
(255, "other")]
ppLightSource :: ExifValue -> String
ppLightSource = fromNumberMap [(0, "Unknown"),
(1, "Daylight"),
(2, "Fluorescent"),
(3, "Tungsten (incandescent light)"),
(4, "Flash"),
(9, "Fine weather"),
(10, "Cloudy weather"),
(11, "Shade"),
(12, "Daylight fluorescent (D 5700 - 7100K)"),
(13, "Day white fluorescent (N 4600 - 5400K)"),
(14, "Cool white fluorescent (W 3900 - 4500K)"),
(15, "White fluorescent (WW 3200 - 3700K)"),
(17, "Standard light A"),
(18, "Standard light B"),
(19, "Standard light C"),
(20, "D55"),
(21, "D65"),
(22, "D75"),
(23, "D50"),
(24, "ISO studio tungsten"),
(255, "Other light source")]
ppFlash :: ExifValue -> String
ppFlash = fromNumberMap [(0, "Flash did not fire"),
(1, "Flash fired"),
(5, "Strobe return light not detected"),
(7, "Strobe return light detected"),
(9, "Flash fired, compulsory flash mode"),
(0x0D, "Flash fired, compulsory flash mode, return light not detected"),
(0x0F, "Flash fired, compulsory flash mode, return light detected"),
(0x10, "Flash did not fire, compulsory flash mode"),
(0x18, "Flash did not fire, auto mode"),
(0x19, "Flash fired, auto mode"),
(0x1D, "Flash fired, auto mode, return light not detected"),
(0x1F, "Flash fired, auto mode, return light detected"),
(0x20, "No flash function"),
(0x41, "Flash fired, red-eye reduction mode"),
(0x45, "Flash fired, red-eye reduction mode, return light not detected"),
(0x47, "Flash fired, red-eye reduction mode, return light detected"),
(0x49, "Flash fired, compulsory flash mode, red-eye reduction mode"),
(0x4D, "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"),
(0x4F, "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"),
(0x59, "Flash fired, auto mode, red-eye reduction mode"),
(0x5D, "Flash fired, auto mode, return light not detected, red-eye reduction mode"),
(0x5F, "Flash fired, auto mode, return light detected, red-eye reduction mode")]
ppColorSpace :: ExifValue -> String
ppColorSpace = fromNumberMap [(1, "sRGB"), (65535, "Uncalibrated")]
ppCustomRendered :: ExifValue -> String
ppCustomRendered = fromNumberMap [(0, "Normal process"), (1, "Custom process")]
ppExposureMode :: ExifValue -> String
ppExposureMode = fromNumberMap [(0, "Auto exposure"),
(1, "Manual exposure"),
(2, "Auto bracket")]
ppWhiteBalance :: ExifValue -> String
ppWhiteBalance = fromNumberMap [(0, "Auto white balance"),
(1, "Manual white balance")]
ppSceneCaptureType :: ExifValue -> String
ppSceneCaptureType = fromNumberMap [(0, "Standard"),
(1, "Landscape"),
(2, "Portrait"),
(3, "Night scene")]
ppGainControl :: ExifValue -> String
ppGainControl = fromNumberMap [(0, "Normal"),
(1, "Low gain up"),
(2, "High gain up"),
(3, "Low gain down"),
(4, "High gain down")]
ppContrastSharpness :: ExifValue -> String
ppContrastSharpness = fromNumberMap [(0, "Normal"), (1, "Soft"), (2, "Hard")]
ppSaturation :: ExifValue -> String
ppSaturation = fromNumberMap [(0, "Normal"),
(1, "Low saturation"),
(2, "High saturation")]
ppSensingMethod :: ExifValue -> String
ppSensingMethod = fromNumberMap [(1, "Not defined"),
(2, "One-chip color area sensor"),
(3, "Two-chip color area sensor"),
(4, "Three-chip color area sensor"),
(5, "Color sequential area sensor"),
(7, "Trilinear sensor"),
(8, "Color sequential linear sensor")]
ppSubjectDistanceRange :: ExifValue -> String
ppSubjectDistanceRange = fromNumberMap [(0, "Unknown"),
(1, "Macro"),
(2, "Close view"),
(3, "Distance view")]
ppFocalPlaneResolutionUnit :: ExifValue -> String
ppFocalPlaneResolutionUnit = fromNumberMap [(1, "No absolute unit of measurement"),
(2, "Inch"),
(3, "Centimeter")]
ppOrientation :: ExifValue -> String
ppOrientation = fromNumberMap [(1, "Top-left"),
(2, "Top-right"),
(3, "Bottom-right"),
(4, "Bottom-left"),
(5, "Left-top"),
(6, "Right-top"),
(7, "Right-bottom"),
(8, "Left-bottom")]
ppSceneType :: ExifValue -> String
ppSceneType = fromNumberMap [(1, "Directly photographed")]
ppGpsAltitudeRef :: ExifValue -> String
ppGpsAltitudeRef = fromNumberMap [(0, "Sea level"),
(1, "Below sea level")]
ppComponentConfiguration :: ExifValue -> String
ppComponentConfiguration (ExifUndefined bs) = foldl' addComponent [] numbers
where
numbers :: [Int] = fmap fromIntegral $ BS.unpack bs
addComponent soFar c = soFar ++ formatComponent c
formatComponent c = case c of
0 -> "-"
1 -> "Y"
2 -> "Cb"
3 -> "Cr"
4 -> "R"
5 -> "G"
6 -> "B"
_ -> "?"
ppComponentConfiguration v@_ = unknown v
ppFlashPixVersion :: ExifValue -> String
ppFlashPixVersion = formatVersion "FlashPix version %.1f"
ppExifVersion :: ExifValue -> String
ppExifVersion = formatVersion "Exif version %.2f"
formatVersion :: String -> ExifValue -> String
formatVersion fmt (ExifUndefined s) = printf fmt num
where
num :: Float = read asStr / 10.0
asStr = fmap (chr . fromIntegral) $ BS.unpack s
formatVersion _ v@_ = unknown v
fromNumberMap :: [(Int, String)] -> ExifValue -> String
fromNumberMap m = fromMap convertedMap
where convertedMap = fmap (first ExifNumber) m
fromMap :: [(ExifValue, String)] -> ExifValue -> String
fromMap m v = Map.findWithDefault (unknown v) v $ Map.fromList m
unknown :: Show a => a -> String
unknown v = "Unknown value: " ++ show v