    -- | 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
    $c== :: ExifTag -> ExifTag -> Bool
    == :: ExifTag -> ExifTag -> Bool
    $c/= :: ExifTag -> ExifTag -> Bool
    /= :: 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
    $ccompare :: ExifTag -> ExifTag -> Ordering
    compare :: ExifTag -> ExifTag -> Ordering
    $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
    >= :: ExifTag -> ExifTag -> Bool
    $cmax :: ExifTag -> ExifTag -> ExifTag
    max :: ExifTag -> ExifTag -> ExifTag
    $cmin :: ExifTag -> ExifTag -> ExifTag
    min :: ExifTag -> ExifTag -> 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
    $cshowsPrec :: Int -> ExifTag -> ShowS
    showsPrec :: Int -> ExifTag -> ShowS
    $cshow :: ExifTag -> String
    show :: ExifTag -> String
    $cshowList :: [ExifTag] -> ShowS
    showList :: [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 Word16
    v = case Word16
    v of
      Word16
    255 -> ExifTag
    TagSubfileType
      Word16
    256 -> ExifTag
    TagImageWidth
      Word16
    257 -> ExifTag
    TagImageLength
      Word16
    258 -> ExifTag
    TagBitsPerSample
      Word16
    259 -> ExifTag
    TagCompression
      Word16
    262 -> ExifTag
    TagPhotometricInterpretation
      Word16
    266 -> ExifTag
    TagFillOrder
      Word16
    269 -> ExifTag
    TagDocumentName
      Word16
    270 -> ExifTag
    TagImageDescription
      Word16
    271 -> ExifTag
    TagMake
      Word16
    272 -> ExifTag
    TagModel
      Word16
    273 -> ExifTag
    TagStripOffsets
      Word16
    274 -> ExifTag
    TagOrientation
      Word16
    277 -> ExifTag
    TagSamplesPerPixel
      Word16
    278 -> ExifTag
    TagRowPerStrip
      Word16
    279 -> ExifTag
    TagStripByteCounts
      Word16
    282 -> ExifTag
    TagXResolution
      Word16
    283 -> ExifTag
    TagYResolution
      Word16
    284 -> ExifTag
    TagPlanarConfiguration
      Word16
    286 -> ExifTag
    TagXPosition
      Word16
    287 -> ExifTag
    TagYPosition
      Word16
    296 -> ExifTag
    TagResolutionUnit
      Word16
    305 -> ExifTag
    TagSoftware
      Word16
    306 -> ExifTag
    TagDateTime
      Word16
    315 -> ExifTag
    TagArtist
      Word16
    317 -> ExifTag
    TagPredictor
      Word16
    320 -> ExifTag
    TagColorMap
      Word16
    322 -> ExifTag
    TagTileWidth
      Word16
    323 -> ExifTag
    TagTileLength
      Word16
    324 -> ExifTag
    TagTileOffset
      Word16
    325 -> ExifTag
    TagTileByteCount
      Word16
    332 -> ExifTag
    TagInkSet
      Word16
    338 -> ExifTag
    TagExtraSample
      Word16
    339 -> ExifTag
    TagSampleFormat
      Word16
    529 -> ExifTag
    TagYCbCrCoeff
      Word16
    512 -> ExifTag
    TagJpegProc
      Word16
    513 -> ExifTag
    TagJPEGInterchangeFormat
      Word16
    514 -> ExifTag
    TagJPEGInterchangeFormatLength
      Word16
    515 -> ExifTag
    TagJPEGRestartInterval
      Word16
    517 -> ExifTag
    TagJPEGLosslessPredictors
      Word16
    518 -> ExifTag
    TagJPEGPointTransforms
      Word16
    519 -> ExifTag
    TagJPEGQTables
      Word16
    520 -> ExifTag
    TagJPEGDCTables
      Word16
    521 -> ExifTag
    TagJPEGACTables
      Word16
    530 -> ExifTag
    TagYCbCrSubsampling
      Word16
    531 -> ExifTag
    TagYCbCrPositioning
      Word16
    532 -> ExifTag
    TagReferenceBlackWhite
      Word16
    33432 -> ExifTag
    TagCopyright
      Word16
    34665 -> ExifTag
    TagExifOffset
      Word16
    34853 -> ExifTag
    TagGPSInfo
      Word16
    37384 -> ExifTag
    TagLightSource
      Word16
    37385 -> ExifTag
    TagFlash
      Word16
    vv -> Word16 -> ExifTag
    TagUnknown Word16
    vv

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

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

    isInIFD0 :: ExifTag -> Bool
    isInIFD0 :: ExifTag -> Bool
    isInIFD0 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 a. Eq a => a -> [a] -> 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
    $cshowsPrec :: Int -> ExifData -> ShowS
    showsPrec :: Int -> ExifData -> ShowS
    $cshow :: ExifData -> String
    show :: ExifData -> String
    $cshowList :: [ExifData] -> ShowS
    showList :: [ExifData] -> ShowS
    Show

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

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