    -- | This module provide a totally partial and incomplete maping

    -- of Exif values. Used for Tiff parsing and reused for Exif extraction.

    module Codec.Picture.Metadata.Exif ( ExifTag( .. )
                                       , ExifData( .. )

                                       , tagOfWord16
                                       , word16OfTag

                                       , isInIFD0
                                       ) where

    import Control.DeepSeq( NFData( .. ) )
    import Data.Int( Int32 )
    import Data.Word( Word16, Word32 )
    import qualified Data.Vector as V
    import qualified Data.ByteString as B

    -- | Tag values used for exif fields. Completly incomplete

    data ExifTag
      = TagPhotometricInterpretation
      | TagCompression -- ^ Short type

      | TagImageWidth  -- ^ Short or long type

      | TagImageLength -- ^ Short or long type

      | TagXResolution -- ^ Rational type

      | TagYResolution -- ^ Rational type

      | TagResolutionUnit --  ^ Short type

      | TagRowPerStrip -- ^ Short or long type

      | TagStripByteCounts -- ^ Short or long

      | TagStripOffsets -- ^ Short or long

      | TagBitsPerSample --  ^ Short

      | TagColorMap -- ^ Short

      | TagTileWidth
      | TagTileLength
      | TagTileOffset
      | TagTileByteCount
      | TagSamplesPerPixel -- ^ Short

      | TagArtist
      | TagDocumentName
      | TagSoftware
      | TagPlanarConfiguration -- ^ Short

      | TagOrientation
      | TagSampleFormat -- ^ Short

      | TagInkSet
      | TagSubfileType
      | TagFillOrder
      | TagYCbCrCoeff
      | TagYCbCrSubsampling
      | TagYCbCrPositioning
      | TagReferenceBlackWhite
      | TagXPosition
      | TagYPosition
      | TagExtraSample
      | TagImageDescription
      | TagPredictor
      | TagCopyright
      | TagMake
      | TagModel
      | TagDateTime
      | TagGPSInfo
      | TagLightSource -- ^ Short

      | TagFlash -- ^ Short

      | TagJpegProc
      | TagJPEGInterchangeFormat
      | TagJPEGInterchangeFormatLength
      | TagJPEGRestartInterval
      | TagJPEGLosslessPredictors
      | TagJPEGPointTransforms
      | TagJPEGQTables
      | TagJPEGDCTables
      | TagJPEGACTables

      | TagExifOffset
      | TagUnknown !Word16
      deriving (ExifTag -> ExifTag -> Bool
    (ExifTag -> ExifTag -> Bool)
    -> (ExifTag -> ExifTag -> Bool) -> Eq ExifTag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: ExifTag -> ExifTag -> Bool
    $c/= :: ExifTag -> ExifTag -> Bool
    == :: ExifTag -> ExifTag -> Bool
    $c== :: ExifTag -> ExifTag -> Bool
    Eq, Eq ExifTag
    Eq ExifTag =>
    (ExifTag -> ExifTag -> Ordering)
    -> (ExifTag -> ExifTag -> Bool)
    -> (ExifTag -> ExifTag -> Bool)
    -> (ExifTag -> ExifTag -> Bool)
    -> (ExifTag -> ExifTag -> Bool)
    -> (ExifTag -> ExifTag -> ExifTag)
    -> (ExifTag -> ExifTag -> ExifTag)
    -> Ord ExifTag
    ExifTag -> ExifTag -> Bool
    ExifTag -> ExifTag -> Ordering
    ExifTag -> ExifTag -> ExifTag
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    min :: ExifTag -> ExifTag -> ExifTag
    $cmin :: ExifTag -> ExifTag -> ExifTag
    max :: ExifTag -> ExifTag -> ExifTag
    $cmax :: ExifTag -> ExifTag -> ExifTag
    >= :: ExifTag -> ExifTag -> Bool
    $c>= :: ExifTag -> ExifTag -> Bool
    > :: ExifTag -> ExifTag -> Bool
    $c> :: ExifTag -> ExifTag -> Bool
    <= :: ExifTag -> ExifTag -> Bool
    $c<= :: ExifTag -> ExifTag -> Bool
    < :: ExifTag -> ExifTag -> Bool
    $c< :: ExifTag -> ExifTag -> Bool
    compare :: ExifTag -> ExifTag -> Ordering
    $ccompare :: ExifTag -> ExifTag -> Ordering
    $cp1Ord :: Eq ExifTag
    Ord, Int -> ExifTag -> ShowS
    [ExifTag] -> ShowS
    ExifTag -> String
    (Int -> ExifTag -> ShowS)
    -> (ExifTag -> String) -> ([ExifTag] -> ShowS) -> Show ExifTag
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [ExifTag] -> ShowS
    $cshowList :: [ExifTag] -> ShowS
    show :: ExifTag -> String
    $cshow :: ExifTag -> String
    showsPrec :: Int -> ExifTag -> ShowS
    $cshowsPrec :: Int -> ExifTag -> ShowS
    Show)

    -- | Convert a value to it's corresponding Exif tag.

    -- Will often be written as 'TagUnknown'

    tagOfWord16 :: Word16 -> ExifTag
    tagOfWord16 :: Word16 -> ExifTag
    tagOfWord16 v :: Word16
    v = case Word16
    v of
      255 -> ExifTag
    TagSubfileType
      256 -> ExifTag
    TagImageWidth
      257 -> ExifTag
    TagImageLength
      258 -> ExifTag
    TagBitsPerSample
      259 -> ExifTag
    TagCompression
      262 -> ExifTag
    TagPhotometricInterpretation
      266 -> ExifTag
    TagFillOrder
      269 -> ExifTag
    TagDocumentName
      270 -> ExifTag
    TagImageDescription
      271 -> ExifTag
    TagMake
      272 -> ExifTag
    TagModel
      273 -> ExifTag
    TagStripOffsets
      274 -> ExifTag
    TagOrientation
      277 -> ExifTag
    TagSamplesPerPixel
      278 -> ExifTag
    TagRowPerStrip
      279 -> ExifTag
    TagStripByteCounts
      282 -> ExifTag
    TagXResolution
      283 -> ExifTag
    TagYResolution
      284 -> ExifTag
    TagPlanarConfiguration
      286 -> ExifTag
    TagXPosition
      287 -> ExifTag
    TagYPosition
      296 -> ExifTag
    TagResolutionUnit
      305 -> ExifTag
    TagSoftware
      306 -> ExifTag
    TagDateTime
      315 -> ExifTag
    TagArtist
      317 -> ExifTag
    TagPredictor
      320 -> ExifTag
    TagColorMap
      322 -> ExifTag
    TagTileWidth
      323 -> ExifTag
    TagTileLength
      324 -> ExifTag
    TagTileOffset
      325 -> ExifTag
    TagTileByteCount
      332 -> ExifTag
    TagInkSet
      338 -> ExifTag
    TagExtraSample
      339 -> ExifTag
    TagSampleFormat
      529 -> ExifTag
    TagYCbCrCoeff
      512 -> ExifTag
    TagJpegProc
      513 -> ExifTag
    TagJPEGInterchangeFormat
      514 -> ExifTag
    TagJPEGInterchangeFormatLength
      515 -> ExifTag
    TagJPEGRestartInterval
      517 -> ExifTag
    TagJPEGLosslessPredictors
      518 -> ExifTag
    TagJPEGPointTransforms
      519 -> ExifTag
    TagJPEGQTables
      520 -> ExifTag
    TagJPEGDCTables
      521 -> ExifTag
    TagJPEGACTables
      530 -> ExifTag
    TagYCbCrSubsampling
      531 -> ExifTag
    TagYCbCrPositioning
      532 -> ExifTag
    TagReferenceBlackWhite
      33432 -> ExifTag
    TagCopyright
      34665 -> ExifTag
    TagExifOffset
      34853 -> ExifTag
    TagGPSInfo
      37384 -> ExifTag
    TagLightSource
      37385 -> ExifTag
    TagFlash
      vv :: Word16
    vv -> Word16 -> ExifTag
    TagUnknown Word16
    vv

    -- | Convert a tag to it's corresponding value.

    word16OfTag :: ExifTag -> Word16
    word16OfTag :: ExifTag -> Word16
    word16OfTag t :: ExifTag
    t = case ExifTag
    t of
      TagSubfileType -> 255
      TagImageWidth -> 256
      TagImageLength -> 257
      TagBitsPerSample -> 258
      TagCompression -> 259
      TagPhotometricInterpretation -> 262
      TagFillOrder -> 266
      TagDocumentName -> 269
      TagImageDescription -> 270
      TagMake -> 271
      TagModel -> 272
      TagStripOffsets -> 273
      TagOrientation -> 274
      TagSamplesPerPixel -> 277
      TagRowPerStrip -> 278
      TagStripByteCounts -> 279
      TagXResolution -> 282
      TagYResolution -> 283
      TagPlanarConfiguration -> 284
      TagXPosition -> 286
      TagYPosition -> 287
      TagResolutionUnit -> 296
      TagSoftware -> 305
      TagDateTime -> 306
      TagArtist -> 315
      TagPredictor -> 317
      TagColorMap -> 320
      TagTileWidth -> 322
      TagTileLength -> 323
      TagTileOffset -> 324
      TagTileByteCount -> 325
      TagInkSet -> 332
      TagExtraSample -> 338
      TagSampleFormat -> 339
      TagYCbCrCoeff -> 529
      TagJpegProc -> 512
      TagJPEGInterchangeFormat -> 513
      TagJPEGInterchangeFormatLength -> 514
      TagJPEGRestartInterval -> 515
      TagJPEGLosslessPredictors -> 517
      TagJPEGPointTransforms -> 518
      TagJPEGQTables -> 519
      TagJPEGDCTables -> 520
      TagJPEGACTables -> 521
      TagYCbCrSubsampling -> 530
      TagYCbCrPositioning -> 531
      TagReferenceBlackWhite -> 532
      TagCopyright -> 33432
      TagExifOffset -> 34665
      TagGPSInfo -> 34853
      TagLightSource -> 37384
      TagFlash -> 37385
      (TagUnknown v :: Word16
    v) -> Word16
    v

    isInIFD0 :: ExifTag -> Bool
    isInIFD0 :: ExifTag -> Bool
    isInIFD0 t :: ExifTag
    t = ExifTag -> Word16
    word16OfTag ExifTag
    t Word16 -> Word16 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word16
    lastTag Bool -> Bool -> Bool
    || Bool
    isRedirectTag where
      lastTag :: Word16
    lastTag = ExifTag -> Word16
    word16OfTag ExifTag
    TagCopyright
      isRedirectTag :: Bool
    isRedirectTag = ExifTag
    t ExifTag -> [ExifTag] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [ExifTag
    TagExifOffset, ExifTag
    TagGPSInfo]

    -- | Possible data held by an Exif tag

    data ExifData
      = ExifNone
      | ExifLong      !Word32
      | ExifShort     !Word16
      | ExifString    !B.ByteString
      | ExifUndefined !B.ByteString
      | ExifShorts    !(V.Vector Word16)
      | ExifLongs     !(V.Vector Word32)
      | ExifRational  !Word32 !Word32
      | ExifSignedRational  !Int32 !Int32
      | ExifIFD       ![(ExifTag, ExifData)]
      deriving Int -> ExifData -> ShowS
    [ExifData] -> ShowS
    ExifData -> String
    (Int -> ExifData -> ShowS)
    -> (ExifData -> String) -> ([ExifData] -> ShowS) -> Show ExifData
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [ExifData] -> ShowS
    $cshowList :: [ExifData] -> ShowS
    show :: ExifData -> String
    $cshow :: ExifData -> String
    showsPrec :: Int -> ExifData -> ShowS
    $cshowsPrec :: Int -> ExifData -> ShowS
    Show

    instance NFData ExifTag where
      rnf :: ExifTag -> ()
    rnf a :: ExifTag
    a = ExifTag
    a ExifTag -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

    instance NFData ExifData where
      rnf :: ExifData -> ()
    rnf (ExifIFD ifds :: [(ExifTag, ExifData)]
    ifds) = [(ExifTag, ExifData)] -> ()
    forall a. NFData a => a -> ()
    rnf [(ExifTag, ExifData)]
    ifds () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()
      rnf (ExifLongs l :: Vector Word32
    l) = Vector Word32 -> ()
    forall a. NFData a => a -> ()
    rnf Vector Word32
    l () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()
      rnf (ExifShorts l :: Vector Word16
    l) = Vector Word16 -> ()
    forall a. NFData a => a -> ()
    rnf Vector Word16
    l () -> () -> ()
    forall a b. a -> b -> b
    `seq` ()
      rnf a :: ExifData
    a = ExifData
    a ExifData -> () -> ()
    forall a b. a -> b -> b
    `seq` ()