    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE TupleSections #-}
    {-# LANGUAGE CPP #-}
    -- | Module implementing function to read and write

    -- Targa (*.tga) files.

    module Codec.Picture.Tga( decodeTga
                            , decodeTgaWithMetadata
                            , decodeTgaWithPaletteAndMetadata
                            , TgaSaveable
                            , encodeTga
                            , writeTga
                            )  where

    #if !MIN_VERSION_base(4,8,0)
    import Data.Monoid( mempty )
    import Control.Applicative( (<*>), pure, (<$>) )
    #endif

    import Control.Arrow( first )
    import Control.Monad.ST( ST, runST )
    import Data.Bits( (.&.)
                    , (.|.)
                    , bit
                    , testBit
                    , setBit
                    , unsafeShiftL
                    , unsafeShiftR )
    import Data.Word( Word8, Word16 )
    import Data.Binary( Binary( .. ), encode )
    import Data.Binary.Get( Get
                          , getByteString
                          , getWord8
                          , getWord16le
                          )
    import Data.Binary.Put( putWord8
                          , putWord16le
                          , putByteString
                          )

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Lazy as Lb
    import qualified Data.ByteString.Unsafe as U
    import qualified Data.Vector.Storable.Mutable as M

    import Codec.Picture.Types
    import Codec.Picture.InternalHelper
    import Codec.Picture.Metadata( Metadatas
                                 , SourceFormat( SourceTGA )
                                 , basicMetadata )
    import Codec.Picture.VectorByteConversion

    data TgaColorMapType
      = ColorMapWithoutTable
      | ColorMapWithTable
      | ColorMapUnknown Word8

    instance Binary TgaColorMapType where
      get :: Get TgaColorMapType
    get = do
        v <- Get Word8
    getWord8
        return $ case v of
          Word8
    0 -> TgaColorMapType
    ColorMapWithoutTable
          Word8
    1 -> TgaColorMapType
    ColorMapWithTable
          Word8
    n -> Word8 -> TgaColorMapType
    ColorMapUnknown Word8
    n

      put :: TgaColorMapType -> Put
    put TgaColorMapType
    v = case TgaColorMapType
    v of
        TgaColorMapType
    ColorMapWithoutTable -> Word8 -> Put
    putWord8 Word8
    0
        TgaColorMapType
    ColorMapWithTable -> Word8 -> Put
    putWord8 Word8
    1
        (ColorMapUnknown Word8
    vv) -> Word8 -> Put
    putWord8 Word8
    vv

    data TgaImageType
      = ImageTypeNoData Bool
      | ImageTypeColorMapped Bool
      | ImageTypeTrueColor Bool
      | ImageTypeMonochrome Bool

    isRleEncoded :: TgaImageType -> Bool
    isRleEncoded :: TgaImageType -> Bool
    isRleEncoded TgaImageType
    v = case TgaImageType
    v of
      ImageTypeNoData      Bool
    yn -> Bool
    yn
      ImageTypeColorMapped Bool
    yn -> Bool
    yn
      ImageTypeTrueColor   Bool
    yn -> Bool
    yn
      ImageTypeMonochrome  Bool
    yn -> Bool
    yn

    imageTypeOfCode :: Word8 -> Get TgaImageType
    imageTypeOfCode :: Word8 -> Get TgaImageType
    imageTypeOfCode Word8
    v = case Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    3 of
        Word8
    0 -> TgaImageType -> Get TgaImageType
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TgaImageType -> Get TgaImageType)
    -> TgaImageType -> Get TgaImageType
    forall a b. (a -> b) -> a -> b
    $ Bool -> TgaImageType
    ImageTypeNoData Bool
    isEncoded
        Word8
    1 -> TgaImageType -> Get TgaImageType
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TgaImageType -> Get TgaImageType)
    -> TgaImageType -> Get TgaImageType
    forall a b. (a -> b) -> a -> b
    $ Bool -> TgaImageType
    ImageTypeColorMapped Bool
    isEncoded
        Word8
    2 -> TgaImageType -> Get TgaImageType
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TgaImageType -> Get TgaImageType)
    -> TgaImageType -> Get TgaImageType
    forall a b. (a -> b) -> a -> b
    $ Bool -> TgaImageType
    ImageTypeTrueColor Bool
    isEncoded
        Word8
    3 -> TgaImageType -> Get TgaImageType
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TgaImageType -> Get TgaImageType)
    -> TgaImageType -> Get TgaImageType
    forall a b. (a -> b) -> a -> b
    $ Bool -> TgaImageType
    ImageTypeMonochrome Bool
    isEncoded
        Word8
    _ -> String -> Get TgaImageType
    forall a. String -> Get a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail (String -> Get TgaImageType) -> String -> Get TgaImageType
    forall a b. (a -> b) -> a -> b
    $ String
    "Unknown TGA image type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    v
      where
        isEncoded :: Bool
    isEncoded = Word8 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word8
    v Int
    3

    codeOfImageType :: TgaImageType -> Word8
    codeOfImageType :: TgaImageType -> Word8
    codeOfImageType TgaImageType
    v = case TgaImageType
    v of
        ImageTypeNoData Bool
    encoded -> Word8 -> Bool -> Word8
    forall {a}. Bits a => a -> Bool -> a
    setVal Word8
    0 Bool
    encoded
        ImageTypeColorMapped Bool
    encoded -> Word8 -> Bool -> Word8
    forall {a}. Bits a => a -> Bool -> a
    setVal Word8
    1 Bool
    encoded
        ImageTypeTrueColor Bool
    encoded -> Word8 -> Bool -> Word8
    forall {a}. Bits a => a -> Bool -> a
    setVal Word8
    2 Bool
    encoded
        ImageTypeMonochrome Bool
    encoded -> Word8 -> Bool -> Word8
    forall {a}. Bits a => a -> Bool -> a
    setVal Word8
    3 Bool
    encoded
        where
          setVal :: a -> Bool -> a
    setVal a
    vv Bool
    True = a -> Int -> a
    forall a. Bits a => a -> Int -> a
    setBit a
    vv Int
    3
          setVal a
    vv Bool
    False = a
    vv

    instance Binary TgaImageType where
      get :: Get TgaImageType
    get = Get Word8
    getWord8 Get Word8 -> (Word8 -> Get TgaImageType) -> Get TgaImageType
    forall a b. Get a -> (a -> Get b) -> Get b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Word8 -> Get TgaImageType
    imageTypeOfCode
      put :: TgaImageType -> Put
    put = Word8 -> Put
    putWord8 (Word8 -> Put) -> (TgaImageType -> Word8) -> TgaImageType -> Put
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TgaImageType -> Word8
    codeOfImageType

    data TgaImageDescription = TgaImageDescription
      { TgaImageDescription -> Bool
    _tgaIdXOrigin       :: Bool
      , TgaImageDescription -> Bool
    _tgaIdYOrigin       :: Bool
      , TgaImageDescription -> Word8
    _tgaIdAttributeBits :: Word8
      }

    instance Binary TgaImageDescription where
      put :: TgaImageDescription -> Put
    put TgaImageDescription
    desc = Word8 -> Put
    putWord8 (Word8 -> Put) -> Word8 -> Put
    forall a b. (a -> b) -> a -> b
    $ Word8
    xOrig Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word8
    yOrig Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. Word8
    attr
        where
          xOrig :: Word8
    xOrig | TgaImageDescription -> Bool
    _tgaIdXOrigin TgaImageDescription
    desc = Int -> Word8
    forall a. Bits a => Int -> a
    bit Int
    4
                | Bool
    otherwise = Word8
    0

          yOrig :: Word8
    yOrig | Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ TgaImageDescription -> Bool
    _tgaIdYOrigin TgaImageDescription
    desc = Int -> Word8
    forall a. Bits a => Int -> a
    bit Int
    5
                | Bool
    otherwise = Word8
    0

          attr :: Word8
    attr = TgaImageDescription -> Word8
    _tgaIdAttributeBits TgaImageDescription
    desc Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0xF

      get :: Get TgaImageDescription
    get = Word8 -> TgaImageDescription
    toDescr (Word8 -> TgaImageDescription)
    -> Get Word8 -> Get TgaImageDescription
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Word8
    getWord8 where
        toDescr :: Word8 -> TgaImageDescription
    toDescr Word8
    v = TgaImageDescription
          { _tgaIdXOrigin :: Bool
    _tgaIdXOrigin       = Word8 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word8
    v Int
    4
          , _tgaIdYOrigin :: Bool
    _tgaIdYOrigin       = Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word8
    v Int
    5
          , _tgaIdAttributeBits :: Word8
    _tgaIdAttributeBits = Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0xF
          }

    data TgaHeader = TgaHeader
      { TgaHeader -> Word8
    _tgaHdrIdLength         :: {-# UNPACK #-} !Word8
      , TgaHeader -> TgaColorMapType
    _tgaHdrColorMapType     :: !TgaColorMapType
      , TgaHeader -> TgaImageType
    _tgaHdrImageType        :: !TgaImageType
      , TgaHeader -> Word16
    _tgaHdrMapStart         :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word16
    _tgaHdrMapLength        :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word8
    _tgaHdrMapDepth         :: {-# UNPACK #-} !Word8
      , TgaHeader -> Word16
    _tgaHdrXOffset          :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word16
    _tgaHdrYOffset          :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word16
    _tgaHdrWidth            :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word16
    _tgaHdrHeight           :: {-# UNPACK #-} !Word16
      , TgaHeader -> Word8
    _tgaHdrPixelDepth       :: {-# UNPACK #-} !Word8
      , TgaHeader -> TgaImageDescription
    _tgaHdrImageDescription :: {-# UNPACK #-} !TgaImageDescription
      }

    instance Binary TgaHeader where
      get :: Get TgaHeader
    get = Word8
    -> TgaColorMapType
    -> TgaImageType
    -> Word16
    -> Word16
    -> Word8
    -> Word16
    -> Word16
    -> Word16
    -> Word16
    -> Word8
    -> TgaImageDescription
    -> TgaHeader
    TgaHeader
         (Word8
     -> TgaColorMapType
     -> TgaImageType
     -> Word16
     -> Word16
     -> Word8
     -> Word16
     -> Word16
     -> Word16
     -> Word16
     -> Word8
     -> TgaImageDescription
     -> TgaHeader)
    -> Get Word8
    -> Get
         (TgaColorMapType
          -> TgaImageType
          -> Word16
          -> Word16
          -> Word8
          -> Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Get Word8
    g8 Get
      (TgaColorMapType
       -> TgaImageType
       -> Word16
       -> Word16
       -> Word8
       -> Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get TgaColorMapType
    -> Get
         (TgaImageType
          -> Word16
          -> Word16
          -> Word8
          -> Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get TgaColorMapType
    forall t. Binary t => Get t
    get Get
      (TgaImageType
       -> Word16
       -> Word16
       -> Word8
       -> Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get TgaImageType
    -> Get
         (Word16
          -> Word16
          -> Word8
          -> Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get TgaImageType
    forall t. Binary t => Get t
    get Get
      (Word16
       -> Word16
       -> Word8
       -> Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get Word16
    -> Get
         (Word16
          -> Word8
          -> Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get
      (Word16
       -> Word8
       -> Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get Word16
    -> Get
         (Word8
          -> Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get
      (Word8
       -> Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get Word8
    -> Get
         (Word16
          -> Word16
          -> Word16
          -> Word16
          -> Word8
          -> TgaImageDescription
          -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word8
    g8
         Get
      (Word16
       -> Word16
       -> Word16
       -> Word16
       -> Word8
       -> TgaImageDescription
       -> TgaHeader)
    -> Get Word16
    -> Get
         (Word16
          -> Word16 -> Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get
      (Word16
       -> Word16 -> Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    -> Get Word16
    -> Get
         (Word16 -> Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get (Word16 -> Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    -> Get Word16
    -> Get (Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get (Word16 -> Word8 -> TgaImageDescription -> TgaHeader)
    -> Get Word16 -> Get (Word8 -> TgaImageDescription -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word16
    g16 Get (Word8 -> TgaImageDescription -> TgaHeader)
    -> Get Word8 -> Get (TgaImageDescription -> TgaHeader)
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get Word8
    g8 Get (TgaImageDescription -> TgaHeader)
    -> Get TgaImageDescription -> Get TgaHeader
    forall a b. Get (a -> b) -> Get a -> Get b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Get TgaImageDescription
    forall t. Binary t => Get t
    get
       where g16 :: Get Word16
    g16 = Get Word16
    getWord16le
             g8 :: Get Word8
    g8 = Get Word8
    getWord8

      put :: TgaHeader -> Put
    put TgaHeader
    v = do
        let p8 :: Word8 -> Put
    p8 = Word8 -> Put
    putWord8
            p16 :: Word16 -> Put
    p16 = Word16 -> Put
    putWord16le
        Word8 -> Put
    p8  (Word8 -> Put) -> Word8 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word8
    _tgaHdrIdLength TgaHeader
    v
        TgaColorMapType -> Put
    forall t. Binary t => t -> Put
    put (TgaColorMapType -> Put) -> TgaColorMapType -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> TgaColorMapType
    _tgaHdrColorMapType TgaHeader
    v
        TgaImageType -> Put
    forall t. Binary t => t -> Put
    put (TgaImageType -> Put) -> TgaImageType -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> TgaImageType
    _tgaHdrImageType TgaHeader
    v

        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrMapStart TgaHeader
    v
        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrMapLength TgaHeader
    v
        Word8 -> Put
    p8  (Word8 -> Put) -> Word8 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word8
    _tgaHdrMapDepth TgaHeader
    v
        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrXOffset TgaHeader
    v
        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrYOffset TgaHeader
    v
        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrWidth TgaHeader
    v
        Word16 -> Put
    p16 (Word16 -> Put) -> Word16 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrHeight TgaHeader
    v
        Word8 -> Put
    p8  (Word8 -> Put) -> Word8 -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word8
    _tgaHdrPixelDepth TgaHeader
    v
        TgaImageDescription -> Put
    forall t. Binary t => t -> Put
    put (TgaImageDescription -> Put) -> TgaImageDescription -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> TgaImageDescription
    _tgaHdrImageDescription TgaHeader
    v

    data TgaFile = TgaFile
      { TgaFile -> TgaHeader
    _tgaFileHeader :: !TgaHeader
      , TgaFile -> ByteString
    _tgaFileId     :: !B.ByteString
      , TgaFile -> ByteString
    _tgaPalette    :: !B.ByteString
      , TgaFile -> ByteString
    _tgaFileRest   :: !B.ByteString
      }

    getPalette :: TgaHeader -> Get B.ByteString
    getPalette :: TgaHeader -> Get ByteString
    getPalette TgaHeader
    hdr | TgaHeader -> Word16
    _tgaHdrMapLength TgaHeader
    hdr Word16 -> Word16 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word16
    0 = ByteString -> Get ByteString
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ByteString
    forall a. Monoid a => a
    mempty
    getPalette TgaHeader
    hdr = Int -> Get ByteString
    getByteString (Int -> Get ByteString) -> Int -> Get ByteString
    forall a b. (a -> b) -> a -> b
    $ Int
    bytePerPixel Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    pixelCount
      where
        bytePerPixel :: Int
    bytePerPixel = Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8 -> Int) -> Word8 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word8
    _tgaHdrMapDepth TgaHeader
    hdr Word8 -> Word8 -> Word8
    forall a. Integral a => a -> a -> a
    `div` Word8
    8
        pixelCount :: Int
    pixelCount = Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Int) -> Word16 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrMapLength TgaHeader
    hdr

    instance Binary TgaFile where
      get :: Get TgaFile
    get = do
        hdr <- Get TgaHeader
    forall t. Binary t => Get t
    get
        validateTga hdr
        fileId <- getByteString . fromIntegral $ _tgaHdrIdLength hdr
        palette <- getPalette hdr
        rest <- getRemainingBytes

        return TgaFile {
            _tgaFileHeader = hdr
          , _tgaFileId = fileId
          , _tgaPalette = palette
          , _tgaFileRest = rest
          }

      put :: TgaFile -> Put
    put TgaFile
    file = do
        TgaHeader -> Put
    forall t. Binary t => t -> Put
    put (TgaHeader -> Put) -> TgaHeader -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaFile -> TgaHeader
    _tgaFileHeader TgaFile
    file
        ByteString -> Put
    putByteString (ByteString -> Put) -> ByteString -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaFile -> ByteString
    _tgaFileId TgaFile
    file
        ByteString -> Put
    putByteString (ByteString -> Put) -> ByteString -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaFile -> ByteString
    _tgaPalette TgaFile
    file
        ByteString -> Put
    putByteString (ByteString -> Put) -> ByteString -> Put
    forall a b. (a -> b) -> a -> b
    $ TgaFile -> ByteString
    _tgaFileRest TgaFile
    file

    data Depth8 = Depth8
    data Depth15 = Depth15
    data Depth24 = Depth24
    data Depth32 = Depth32

    class (Pixel (Unpacked a)) => TGAPixel a where
       type Unpacked a
       packedByteSize :: a -> Int
       tgaUnpack      :: a -> B.ByteString -> Int -> Unpacked a

    instance TGAPixel Depth8 where
       type Unpacked Depth8 = Pixel8
       packedByteSize :: Depth8 -> Int
    packedByteSize Depth8
    _ = Int
    1
       tgaUnpack :: Depth8 -> ByteString -> Int -> Unpacked Depth8
    tgaUnpack Depth8
    _ = ByteString -> Int -> Word8
    ByteString -> Int -> Unpacked Depth8
    U.unsafeIndex

    instance TGAPixel Depth15 where
       type Unpacked Depth15 = PixelRGBA8
       packedByteSize :: Depth15 -> Int
    packedByteSize Depth15
    _ = Int
    2
       tgaUnpack :: Depth15 -> ByteString -> Int -> Unpacked Depth15
    tgaUnpack Depth15
    _ ByteString
    str Int
    ix = Word8 -> Word8 -> Word8 -> Word8 -> PixelRGBA8
    PixelRGBA8 Word8
    r Word8
    g Word8
    b Word8
    a
          where
            v0 :: Word8
    v0 = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str Int
    ix
            v1 :: Word8
    v1 = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int -> Word8) -> Int -> Word8
    forall a b. (a -> b) -> a -> b
    $ Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1
            r :: Word8
    r = (Word8
    v1 Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x7c) Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    1;
            g :: Word8
    g = ((Word8
    v1 Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x03) Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    6) Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .|. ((Word8
    v0 Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0xe0) Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftR` Int
    2);
            b :: Word8
    b = (Word8
    v0 Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x1f) Word8 -> Int -> Word8
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` Int
    3
            a :: Word8
    a = Word8
    255 -- v1 .&. 0x80

    instance TGAPixel Depth24 where
       type Unpacked Depth24 = PixelRGB8
       packedByteSize :: Depth24 -> Int
    packedByteSize Depth24
    _ = Int
    3
       tgaUnpack :: Depth24 -> ByteString -> Int -> Unpacked Depth24
    tgaUnpack Depth24
    _ ByteString
    str Int
    ix = Word8 -> Word8 -> Word8 -> PixelRGB8
    PixelRGB8 Word8
    r Word8
    g Word8
    b
         where
           b :: Word8
    b = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str Int
    ix
           g :: Word8
    g = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)
           r :: Word8
    r = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2)

    instance TGAPixel Depth32 where
       type Unpacked Depth32 = PixelRGBA8
       packedByteSize :: Depth32 -> Int
    packedByteSize Depth32
    _ = Int
    4
       tgaUnpack :: Depth32 -> ByteString -> Int -> Unpacked Depth32
    tgaUnpack Depth32
    _ ByteString
    str Int
    ix = Word8 -> Word8 -> Word8 -> Word8 -> PixelRGBA8
    PixelRGBA8 Word8
    r Word8
    g Word8
    b Word8
    a
         where
           b :: Word8
    b = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str Int
    ix
           g :: Word8
    g = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)
           r :: Word8
    r = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    2)
           a :: Word8
    a = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    str (Int
    ix Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    3)

    prepareUnpacker :: TgaFile
                    -> (forall tgapx. (TGAPixel tgapx) => tgapx -> TgaFile -> Image (Unpacked tgapx))
                    -> Either String DynamicImage
    prepareUnpacker :: TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    f =
      let hdr :: TgaHeader
    hdr = TgaFile -> TgaHeader
    _tgaFileHeader TgaFile
    file
          flipper :: (Pixel px) => Image px -> Image px
          flipper :: forall px. Pixel px => Image px -> Image px
    flipper = TgaImageDescription -> Image px -> Image px
    forall px. Pixel px => TgaImageDescription -> Image px -> Image px
    flipImage (TgaImageDescription -> Image px -> Image px)
    -> TgaImageDescription -> Image px -> Image px
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> TgaImageDescription
    _tgaHdrImageDescription TgaHeader
    hdr
      in
      case TgaHeader -> Word8
    _tgaHdrPixelDepth TgaHeader
    hdr of
        Word8
    8  -> DynamicImage -> Either String DynamicImage
    forall a. a -> Either String a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (DynamicImage -> Either String DynamicImage)
    -> (Image Word8 -> DynamicImage)
    -> Image Word8
    -> Either String DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image Word8 -> DynamicImage
    ImageY8 (Image Word8 -> DynamicImage)
    -> (Image Word8 -> Image Word8) -> Image Word8 -> DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image Word8 -> Image Word8
    forall px. Pixel px => Image px -> Image px
    flipper (Image Word8 -> Either String DynamicImage)
    -> Image Word8 -> Either String DynamicImage
    forall a b. (a -> b) -> a -> b
    $ Depth8 -> TgaFile -> Image (Unpacked Depth8)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    f Depth8
    Depth8 TgaFile
    file
        Word8
    16 -> DynamicImage -> Either String DynamicImage
    forall a. a -> Either String a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (DynamicImage -> Either String DynamicImage)
    -> (Image PixelRGBA8 -> DynamicImage)
    -> Image PixelRGBA8
    -> Either String DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGBA8 -> DynamicImage
    ImageRGBA8 (Image PixelRGBA8 -> DynamicImage)
    -> (Image PixelRGBA8 -> Image PixelRGBA8)
    -> Image PixelRGBA8
    -> DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGBA8 -> Image PixelRGBA8
    forall px. Pixel px => Image px -> Image px
    flipper (Image PixelRGBA8 -> Either String DynamicImage)
    -> Image PixelRGBA8 -> Either String DynamicImage
    forall a b. (a -> b) -> a -> b
    $ Depth15 -> TgaFile -> Image (Unpacked Depth15)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    f Depth15
    Depth15 TgaFile
    file
        Word8
    24 -> DynamicImage -> Either String DynamicImage
    forall a. a -> Either String a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (DynamicImage -> Either String DynamicImage)
    -> (Image PixelRGB8 -> DynamicImage)
    -> Image PixelRGB8
    -> Either String DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGB8 -> DynamicImage
    ImageRGB8 (Image PixelRGB8 -> DynamicImage)
    -> (Image PixelRGB8 -> Image PixelRGB8)
    -> Image PixelRGB8
    -> DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGB8 -> Image PixelRGB8
    forall px. Pixel px => Image px -> Image px
    flipper (Image PixelRGB8 -> Either String DynamicImage)
    -> Image PixelRGB8 -> Either String DynamicImage
    forall a b. (a -> b) -> a -> b
    $ Depth24 -> TgaFile -> Image (Unpacked Depth24)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    f Depth24
    Depth24 TgaFile
    file
        Word8
    32 -> DynamicImage -> Either String DynamicImage
    forall a. a -> Either String a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (DynamicImage -> Either String DynamicImage)
    -> (Image PixelRGBA8 -> DynamicImage)
    -> Image PixelRGBA8
    -> Either String DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGBA8 -> DynamicImage
    ImageRGBA8 (Image PixelRGBA8 -> DynamicImage)
    -> (Image PixelRGBA8 -> Image PixelRGBA8)
    -> Image PixelRGBA8
    -> DynamicImage
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGBA8 -> Image PixelRGBA8
    forall px. Pixel px => Image px -> Image px
    flipper (Image PixelRGBA8 -> Either String DynamicImage)
    -> Image PixelRGBA8 -> Either String DynamicImage
    forall a b. (a -> b) -> a -> b
    $ Depth32 -> TgaFile -> Image (Unpacked Depth32)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    f Depth32
    Depth32 TgaFile
    file
        Word8
    n  -> String -> Either String DynamicImage
    forall a b. a -> Either a b
    Left (String -> Either String DynamicImage)
    -> String -> Either String DynamicImage
    forall a b. (a -> b) -> a -> b
    $ String
    "Invalid bit depth (" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Word8 -> String
    forall a. Show a => a -> String
    show Word8
    n String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    ")"

    toPaletted :: (Pixel px)
               => (Image Pixel8 -> Palette' px -> PalettedImage) -> Image px
               -> DynamicImage
               -> Either String PalettedImage
    toPaletted :: forall px.
    Pixel px =>
    (Image Word8 -> Palette' px -> PalettedImage)
    -> Image px -> DynamicImage -> Either String PalettedImage
    toPaletted Image Word8 -> Palette' px -> PalettedImage
    f Image px
    palette (ImageY8 Image Word8
    img) = PalettedImage -> Either String PalettedImage
    forall a. a -> Either String a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (PalettedImage -> Either String PalettedImage)
    -> PalettedImage -> Either String PalettedImage
    forall a b. (a -> b) -> a -> b
    $ Image Word8 -> Palette' px -> PalettedImage
    f Image Word8
    img Palette' px
    pal where
      pal :: Palette' px
    pal = Palette'
        { _paletteSize :: Int
    _paletteSize = Image px -> Int
    forall a. Image a -> Int
    imageWidth Image px
    palette
        , _paletteData :: Vector (PixelBaseComponent px)
    _paletteData = Image px -> Vector (PixelBaseComponent px)
    forall a. Image a -> Vector (PixelBaseComponent a)
    imageData Image px
    palette
        }
    toPaletted Image Word8 -> Palette' px -> PalettedImage
    _ Image px
    _ DynamicImage
    _ = String -> Either String PalettedImage
    forall a b. a -> Either a b
    Left String
    "Bad colorspace for image"

    unparse :: TgaFile -> Either String (PalettedImage, Metadatas)
    unparse :: TgaFile -> Either String (PalettedImage, Metadatas)
    unparse TgaFile
    file =
      let hdr :: TgaHeader
    hdr = TgaFile -> TgaHeader
    _tgaFileHeader TgaFile
    file
          imageType :: TgaImageType
    imageType = TgaHeader -> TgaImageType
    _tgaHdrImageType TgaHeader
    hdr

          unpacker :: forall tgapx. (TGAPixel tgapx)
                   => tgapx -> TgaFile -> Image (Unpacked tgapx)
          unpacker :: forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker | TgaImageType -> Bool
    isRleEncoded TgaImageType
    imageType = tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpackRLETga
                   | Bool
    otherwise = tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpackUncompressedTga

          metas :: Metadatas
    metas = SourceFormat -> Word16 -> Word16 -> Metadatas
    forall nSize.
    Integral nSize =>
    SourceFormat -> nSize -> nSize -> Metadatas
    basicMetadata SourceFormat
    SourceTGA (TgaHeader -> Word16
    _tgaHdrWidth TgaHeader
    hdr) (TgaHeader -> Word16
    _tgaHdrHeight TgaHeader
    hdr)
          decodedPalette :: Either String (PalettedImage, Metadatas)
    decodedPalette = TgaFile -> Either String (PalettedImage, Metadatas)
    unparse TgaFile
    file
            { _tgaFileHeader = hdr
                { _tgaHdrHeight = 1
                , _tgaHdrWidth = _tgaHdrMapLength hdr
                , _tgaHdrPixelDepth = _tgaHdrMapDepth hdr
                , _tgaHdrImageType = ImageTypeTrueColor False
                }
            , _tgaFileRest = _tgaPalette file
            }
      in
      case TgaImageType
    imageType of
        ImageTypeNoData Bool
    _ -> String -> Either String (PalettedImage, Metadatas)
    forall a b. a -> Either a b
    Left String
    "No data detected in TGA file"
        ImageTypeTrueColor Bool
    _ ->
          (DynamicImage -> (PalettedImage, Metadatas))
    -> Either String DynamicImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((, Metadatas
    metas) (PalettedImage -> (PalettedImage, Metadatas))
    -> (DynamicImage -> PalettedImage)
    -> DynamicImage
    -> (PalettedImage, Metadatas)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DynamicImage -> PalettedImage
    TrueColorImage) (Either String DynamicImage
     -> Either String (PalettedImage, Metadatas))
    -> Either String DynamicImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> a -> b
    $ TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker
        ImageTypeMonochrome Bool
    _ ->
          (DynamicImage -> (PalettedImage, Metadatas))
    -> Either String DynamicImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((, Metadatas
    metas) (PalettedImage -> (PalettedImage, Metadatas))
    -> (DynamicImage -> PalettedImage)
    -> DynamicImage
    -> (PalettedImage, Metadatas)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DynamicImage -> PalettedImage
    TrueColorImage) (Either String DynamicImage
     -> Either String (PalettedImage, Metadatas))
    -> Either String DynamicImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> a -> b
    $ TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker
        ImageTypeColorMapped Bool
    _ ->
          case Either String (PalettedImage, Metadatas)
    decodedPalette of
            Left String
    str -> String -> Either String (PalettedImage, Metadatas)
    forall a b. a -> Either a b
    Left String
    str
            Right (TrueColorImage (ImageY8 Image Word8
    img), Metadatas
    _) ->
              (PalettedImage -> (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (, Metadatas
    metas) (Either String PalettedImage
     -> Either String (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> a -> b
    $ TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker Either String DynamicImage
    -> (DynamicImage -> Either String PalettedImage)
    -> Either String PalettedImage
    forall a b.
    Either String a -> (a -> Either String b) -> Either String b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Image Word8 -> Palette' Word8 -> PalettedImage)
    -> Image Word8 -> DynamicImage -> Either String PalettedImage
    forall px.
    Pixel px =>
    (Image Word8 -> Palette' px -> PalettedImage)
    -> Image px -> DynamicImage -> Either String PalettedImage
    toPaletted Image Word8 -> Palette' Word8 -> PalettedImage
    PalettedY8 Image Word8
    img
            Right (TrueColorImage (ImageRGB8 Image PixelRGB8
    img), Metadatas
    _) ->
              (PalettedImage -> (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (, Metadatas
    metas) (Either String PalettedImage
     -> Either String (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> a -> b
    $ TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker Either String DynamicImage
    -> (DynamicImage -> Either String PalettedImage)
    -> Either String PalettedImage
    forall a b.
    Either String a -> (a -> Either String b) -> Either String b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Image Word8 -> Palette' PixelRGB8 -> PalettedImage)
    -> Image PixelRGB8 -> DynamicImage -> Either String PalettedImage
    forall px.
    Pixel px =>
    (Image Word8 -> Palette' px -> PalettedImage)
    -> Image px -> DynamicImage -> Either String PalettedImage
    toPaletted Image Word8 -> Palette' PixelRGB8 -> PalettedImage
    PalettedRGB8 Image PixelRGB8
    img
            Right (TrueColorImage (ImageRGBA8 Image PixelRGBA8
    img), Metadatas
    _) ->
              (PalettedImage -> (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> Either String a -> Either String b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (, Metadatas
    metas) (Either String PalettedImage
     -> Either String (PalettedImage, Metadatas))
    -> Either String PalettedImage
    -> Either String (PalettedImage, Metadatas)
    forall a b. (a -> b) -> a -> b
    $ TgaFile
    -> (forall tgapx.
        TGAPixel tgapx =>
        tgapx -> TgaFile -> Image (Unpacked tgapx))
    -> Either String DynamicImage
    prepareUnpacker TgaFile
    file tgapx -> TgaFile -> Image (Unpacked tgapx)
    forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpacker Either String DynamicImage
    -> (DynamicImage -> Either String PalettedImage)
    -> Either String PalettedImage
    forall a b.
    Either String a -> (a -> Either String b) -> Either String b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Image Word8 -> Palette' PixelRGBA8 -> PalettedImage)
    -> Image PixelRGBA8 -> DynamicImage -> Either String PalettedImage
    forall px.
    Pixel px =>
    (Image Word8 -> Palette' px -> PalettedImage)
    -> Image px -> DynamicImage -> Either String PalettedImage
    toPaletted Image Word8 -> Palette' PixelRGBA8 -> PalettedImage
    PalettedRGBA8 Image PixelRGBA8
    img
            Right (PalettedImage, Metadatas)
    _ -> String -> Either String (PalettedImage, Metadatas)
    forall a b. a -> Either a b
    Left String
    "Unknown pixel type"

    writeRun :: (Pixel px)
             => M.STVector s (PixelBaseComponent px) -> Int -> px -> Int
             -> ST s Int
    writeRun :: forall px s.
    Pixel px =>
    STVector s (PixelBaseComponent px) -> Int -> px -> Int -> ST s Int
    writeRun STVector s (PixelBaseComponent px)
    imgData Int
    localMaxi px
    px = Int -> ST s Int
    run
      where
        writeDelta :: Int
    writeDelta = px -> Int
    forall a. Pixel a => a -> Int
    componentCount px
    px
        run :: Int -> ST s Int
    run Int
    writeIndex
          | Int
    writeIndex Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    localMaxi = Int -> ST s Int
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Int
    writeIndex
        run Int
    writeIndex = do
          STVector (PrimState (ST s)) (PixelBaseComponent px)
    -> Int -> px -> ST s ()
    forall a (m :: * -> *).
    (Pixel a, PrimMonad m) =>
    STVector (PrimState m) (PixelBaseComponent a) -> Int -> a -> m ()
    forall (m :: * -> *).
    PrimMonad m =>
    STVector (PrimState m) (PixelBaseComponent px) -> Int -> px -> m ()
    unsafeWritePixel STVector s (PixelBaseComponent px)
    STVector (PrimState (ST s)) (PixelBaseComponent px)
    imgData Int
    writeIndex px
    px
          Int -> ST s Int
    run (Int -> ST s Int) -> Int -> ST s Int
    forall a b. (a -> b) -> a -> b
    $ Int
    writeIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    writeDelta

    copyData :: forall tgapx s
              . (TGAPixel tgapx)
             => tgapx
             -> M.STVector s (PixelBaseComponent (Unpacked tgapx))
             -> B.ByteString
             -> Int -> Int
             -> Int -> Int
             -> ST s (Int, Int)
    copyData :: forall tgapx s.
    TGAPixel tgapx =>
    tgapx
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    -> ByteString
    -> Int
    -> Int
    -> Int
    -> Int
    -> ST s (Int, Int)
    copyData tgapx
    tgapx STVector s (PixelBaseComponent (Unpacked tgapx))
    imgData ByteString
    readData Int
    maxi Int
    maxRead = Int -> Int -> ST s (Int, Int)
    go
      where
        readDelta :: Int
    readDelta = tgapx -> Int
    forall a. TGAPixel a => a -> Int
    packedByteSize tgapx
    tgapx
        writeDelta :: Int
    writeDelta = Unpacked tgapx -> Int
    forall a. Pixel a => a -> Int
    componentCount (Unpacked tgapx
    forall a. HasCallStack => a
    undefined :: Unpacked tgapx)

        go :: Int -> Int -> ST s (Int, Int)
    go Int
    writeIndex Int
    readIndex
          | Int
    writeIndex Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    maxi Bool -> Bool -> Bool
    ||
            Int
    readIndex Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    maxRead = (Int, Int) -> ST s (Int, Int)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int
    writeIndex, Int
    readIndex)
        go Int
    writeIndex Int
    readIndex = do
          let px :: Unpacked tgapx
    px = tgapx -> ByteString -> Int -> Unpacked tgapx
    forall a. TGAPixel a => a -> ByteString -> Int -> Unpacked a
    tgaUnpack tgapx
    tgapx ByteString
    readData Int
    readIndex :: Unpacked tgapx
          STVector (PrimState (ST s)) (PixelBaseComponent (Unpacked tgapx))
    -> Int -> Unpacked tgapx -> ST s ()
    forall a (m :: * -> *).
    (Pixel a, PrimMonad m) =>
    STVector (PrimState m) (PixelBaseComponent a) -> Int -> a -> m ()
    forall (m :: * -> *).
    PrimMonad m =>
    STVector (PrimState m) (PixelBaseComponent (Unpacked tgapx))
    -> Int -> Unpacked tgapx -> m ()
    unsafeWritePixel STVector s (PixelBaseComponent (Unpacked tgapx))
    STVector (PrimState (ST s)) (PixelBaseComponent (Unpacked tgapx))
    imgData Int
    writeIndex Unpacked tgapx
    px
          Int -> Int -> ST s (Int, Int)
    go (Int
    writeIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    writeDelta) (Int
    readIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    readDelta)

    unpackUncompressedTga :: forall tgapx
                           . (TGAPixel tgapx)
                          => tgapx -- ^ Type witness

                          -> TgaFile
                          -> Image (Unpacked tgapx)
    unpackUncompressedTga :: forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpackUncompressedTga tgapx
    tga TgaFile
    file = (forall s. ST s (Image (Unpacked tgapx))) -> Image (Unpacked tgapx)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (Image (Unpacked tgapx)))
     -> Image (Unpacked tgapx))
    -> (forall s. ST s (Image (Unpacked tgapx)))
    -> Image (Unpacked tgapx)
    forall a b. (a -> b) -> a -> b
    $ do
        img <- Int
    -> Int
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    -> MutableImage s (Unpacked tgapx)
    forall s a.
    Int -> Int -> STVector s (PixelBaseComponent a) -> MutableImage s a
    MutableImage Int
    width Int
    height (STVector s (PixelBaseComponent (Unpacked tgapx))
     -> MutableImage s (Unpacked tgapx))
    -> ST s (STVector s (PixelBaseComponent (Unpacked tgapx)))
    -> ST s (MutableImage s (Unpacked tgapx))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int
    -> ST
         s
         (MVector (PrimState (ST s)) (PixelBaseComponent (Unpacked tgapx)))
    forall (m :: * -> *) a.
    (PrimMonad m, Storable a) =>
    Int -> m (MVector (PrimState m) a)
    M.new Int
    maxi
        let imgData = MutableImage s (Unpacked tgapx)
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    forall s a. MutableImage s a -> STVector s (PixelBaseComponent a)
    mutableImageData MutableImage s (Unpacked tgapx)
    img
        _ <- copyData tga imgData readData maxi maxRead 0 0
        unsafeFreezeImage img

      where
        hdr :: TgaHeader
    hdr = TgaFile -> TgaHeader
    _tgaFileHeader TgaFile
    file
        width :: Int
    width = Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Int) -> Word16 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrWidth TgaHeader
    hdr
        height :: Int
    height = Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Int) -> Word16 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrHeight TgaHeader
    hdr
        readData :: ByteString
    readData = TgaFile -> ByteString
    _tgaFileRest TgaFile
    file
        compCount :: Int
    compCount = Unpacked tgapx -> Int
    forall a. Pixel a => a -> Int
    componentCount (Unpacked tgapx
    forall a. HasCallStack => a
    undefined :: Unpacked tgapx)
        maxi :: Int
    maxi = Int
    width Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    height Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    compCount
        maxRead :: Int
    maxRead = ByteString -> Int
    B.length ByteString
    readData

    isRleChunk :: Word8 -> Bool
    isRleChunk :: Word8 -> Bool
    isRleChunk Word8
    v = Word8 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Word8
    v Int
    7

    runLength :: Word8 -> Int
    runLength :: Word8 -> Int
    runLength Word8
    v = Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word8
    v Word8 -> Word8 -> Word8
    forall a. Bits a => a -> a -> a
    .&. Word8
    0x7F) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1

    unpackRLETga :: forall tgapx
                  . (TGAPixel tgapx)
                 => tgapx -- ^ Type witness

                 -> TgaFile
                 -> Image (Unpacked tgapx)
    unpackRLETga :: forall tgapx.
    TGAPixel tgapx =>
    tgapx -> TgaFile -> Image (Unpacked tgapx)
    unpackRLETga tgapx
    tga TgaFile
    file = (forall s. ST s (Image (Unpacked tgapx))) -> Image (Unpacked tgapx)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (Image (Unpacked tgapx)))
     -> Image (Unpacked tgapx))
    -> (forall s. ST s (Image (Unpacked tgapx)))
    -> Image (Unpacked tgapx)
    forall a b. (a -> b) -> a -> b
    $ do
        img <- Int
    -> Int
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    -> MutableImage s (Unpacked tgapx)
    forall s a.
    Int -> Int -> STVector s (PixelBaseComponent a) -> MutableImage s a
    MutableImage Int
    width Int
    height (STVector s (PixelBaseComponent (Unpacked tgapx))
     -> MutableImage s (Unpacked tgapx))
    -> ST s (STVector s (PixelBaseComponent (Unpacked tgapx)))
    -> ST s (MutableImage s (Unpacked tgapx))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int
    -> ST
         s
         (MVector (PrimState (ST s)) (PixelBaseComponent (Unpacked tgapx)))
    forall (m :: * -> *) a.
    (PrimMonad m, Storable a) =>
    Int -> m (MVector (PrimState m) a)
    M.new Int
    maxi
        let imgData = MutableImage s (Unpacked tgapx)
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    forall s a. MutableImage s a -> STVector s (PixelBaseComponent a)
    mutableImageData MutableImage s (Unpacked tgapx)
    img

            go Int
    writeIndex Int
    readIndex
                | Int
    writeIndex Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    maxi = () -> ST s ()
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
                | Int
    readIndex Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    maxRead = () -> ST s ()
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            go Int
    writeIndex Int
    readIndex = do
              let code :: Word8
    code = ByteString -> Int -> Word8
    U.unsafeIndex ByteString
    readData Int
    readIndex
                  copyMax :: Int
    copyMax = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    min Int
    maxi (Int -> Int) -> Int -> Int
    forall a b. (a -> b) -> a -> b
    $ Int
    writeIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Word8 -> Int
    runLength Word8
    code Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    compCount

              if Word8 -> Bool
    isRleChunk Word8
    code then do
                let px :: Unpacked tgapx
    px = tgapx -> ByteString -> Int -> Unpacked tgapx
    forall a. TGAPixel a => a -> ByteString -> Int -> Unpacked a
    tgaUnpack tgapx
    tga ByteString
    readData (Int
    readIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) :: Unpacked tgapx
                lastWriteIndex <- STVector s (PixelBaseComponent (Unpacked tgapx))
    -> Int -> Unpacked tgapx -> Int -> ST s Int
    forall px s.
    Pixel px =>
    STVector s (PixelBaseComponent px) -> Int -> px -> Int -> ST s Int
    writeRun STVector s (PixelBaseComponent (Unpacked tgapx))
    imgData Int
    copyMax Unpacked tgapx
    px Int
    writeIndex
                go lastWriteIndex $ readIndex + 1 + readDelta

              else do
                (newWrite, newRead) <-
                    tgapx
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    -> ByteString
    -> Int
    -> Int
    -> Int
    -> Int
    -> ST s (Int, Int)
    forall tgapx s.
    TGAPixel tgapx =>
    tgapx
    -> STVector s (PixelBaseComponent (Unpacked tgapx))
    -> ByteString
    -> Int
    -> Int
    -> Int
    -> Int
    -> ST s (Int, Int)
    copyData tgapx
    tga STVector s (PixelBaseComponent (Unpacked tgapx))
    imgData ByteString
    readData Int
    copyMax Int
    maxRead
                        Int
    writeIndex (Int
    readIndex Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1)
                go newWrite newRead

        go 0 0
        unsafeFreezeImage img

      where
        hdr :: TgaHeader
    hdr = TgaFile -> TgaHeader
    _tgaFileHeader TgaFile
    file
        width :: Int
    width = Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Int) -> Word16 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrWidth TgaHeader
    hdr
        height :: Int
    height = Word16 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word16 -> Int) -> Word16 -> Int
    forall a b. (a -> b) -> a -> b
    $ TgaHeader -> Word16
    _tgaHdrHeight TgaHeader
    hdr
        readData :: ByteString
    readData = TgaFile -> ByteString
    _tgaFileRest TgaFile
    file
        compCount :: Int
    compCount = Unpacked tgapx -> Int
    forall a. Pixel a => a -> Int
    componentCount (Unpacked tgapx
    forall a. HasCallStack => a
    undefined :: Unpacked tgapx)
        maxi :: Int
    maxi = Int
    width Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    height Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    compCount
        maxRead :: Int
    maxRead = ByteString -> Int
    B.length ByteString
    readData
        readDelta :: Int
    readDelta = tgapx -> Int
    forall a. TGAPixel a => a -> Int
    packedByteSize tgapx
    tga

    flipImage :: (Pixel px)
              => TgaImageDescription -> Image px -> Image px
    flipImage :: forall px. Pixel px => TgaImageDescription -> Image px -> Image px
    flipImage TgaImageDescription
    desc Image px
    img
        | Bool
    xFlip Bool -> Bool -> Bool
    && Bool
    yFlip =
            (Int -> Int -> px) -> Int -> Int -> Image px
    forall px. Pixel px => (Int -> Int -> px) -> Int -> Int -> Image px
    generateImage (\Int
    x Int
    y -> Image px -> Int -> Int -> px
    forall a. Pixel a => Image a -> Int -> Int -> a
    pixelAt Image px
    img (Int
    wMax Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    x) (Int
    hMax Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    y)) Int
    w Int
    h
        | Bool
    xFlip =
            (Int -> Int -> px) -> Int -> Int -> Image px
    forall px. Pixel px => (Int -> Int -> px) -> Int -> Int -> Image px
    generateImage (\Int
    x Int
    y -> Image px -> Int -> Int -> px
    forall a. Pixel a => Image a -> Int -> Int -> a
    pixelAt Image px
    img (Int
    wMax Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    x) Int
    y) Int
    w Int
    h
        | Bool
    yFlip =
            (Int -> Int -> px) -> Int -> Int -> Image px
    forall px. Pixel px => (Int -> Int -> px) -> Int -> Int -> Image px
    generateImage (\Int
    x Int
    y -> Image px -> Int -> Int -> px
    forall a. Pixel a => Image a -> Int -> Int -> a
    pixelAt Image px
    img Int
    x (Int
    hMax Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    y)) Int
    w Int
    h
        | Bool
    otherwise = Image px
    img
      where
        xFlip :: Bool
    xFlip = TgaImageDescription -> Bool
    _tgaIdXOrigin TgaImageDescription
    desc
        yFlip :: Bool
    yFlip = TgaImageDescription -> Bool
    _tgaIdYOrigin TgaImageDescription
    desc
        w :: Int
    w = Image px -> Int
    forall a. Image a -> Int
    imageWidth Image px
    img
        h :: Int
    h = Image px -> Int
    forall a. Image a -> Int
    imageHeight Image px
    img

        !wMax :: Int
    wMax = Int
    w Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1
        !hMax :: Int
    hMax = Int
    h Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1

    validateTga :: TgaHeader -> Get ()
    validateTga :: TgaHeader -> Get ()
    validateTga TgaHeader
    hdr
        | TgaHeader -> Word16
    _tgaHdrWidth TgaHeader
    hdr Word16 -> Word16 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word16
    0 = String -> Get ()
    forall a. String -> Get a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Width is null or negative"
        | TgaHeader -> Word16
    _tgaHdrHeight TgaHeader
    hdr Word16 -> Word16 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word16
    0 = String -> Get ()
    forall a. String -> Get a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Height is null or negative"
    validateTga TgaHeader
    _ = () -> Get ()
    forall a. a -> Get a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()

    -- | Transform a raw tga image to an image, without modifying

    -- the underlying pixel type.

    --

    -- This function can output the following images:

    --

    --  * 'ImageY8'

    --

    --  * 'ImageRGB8'

    --

    --  * 'ImageRGBA8'

    --

    decodeTga :: B.ByteString -> Either String DynamicImage
    decodeTga :: ByteString -> Either String DynamicImage
    decodeTga ByteString
    byte = (DynamicImage, Metadatas) -> DynamicImage
    forall a b. (a, b) -> a
    fst ((DynamicImage, Metadatas) -> DynamicImage)
    -> Either String (DynamicImage, Metadatas)
    -> Either String DynamicImage
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> Either String (DynamicImage, Metadatas)
    decodeTgaWithMetadata ByteString
    byte

    -- | Equivalent to decodeTga but also provide metadata

    decodeTgaWithMetadata :: B.ByteString -> Either String (DynamicImage, Metadatas)
    decodeTgaWithMetadata :: ByteString -> Either String (DynamicImage, Metadatas)
    decodeTgaWithMetadata ByteString
    byte = (PalettedImage -> DynamicImage)
    -> (PalettedImage, Metadatas) -> (DynamicImage, Metadatas)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first PalettedImage -> DynamicImage
    palettedToTrueColor ((PalettedImage, Metadatas) -> (DynamicImage, Metadatas))
    -> Either String (PalettedImage, Metadatas)
    -> Either String (DynamicImage, Metadatas)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> Either String (PalettedImage, Metadatas)
    decodeTgaWithPaletteAndMetadata ByteString
    byte

    -- | Equivalent to decodeTga but with metdata and palette if any

    decodeTgaWithPaletteAndMetadata :: B.ByteString -> Either String (PalettedImage, Metadatas)
    decodeTgaWithPaletteAndMetadata :: ByteString -> Either String (PalettedImage, Metadatas)
    decodeTgaWithPaletteAndMetadata ByteString
    byte = Get TgaFile -> ByteString -> Either String TgaFile
    forall a. Get a -> ByteString -> Either String a
    runGetStrict Get TgaFile
    forall t. Binary t => Get t
    get ByteString
    byte Either String TgaFile
    -> (TgaFile -> Either String (PalettedImage, Metadatas))
    -> Either String (PalettedImage, Metadatas)
    forall a b.
    Either String a -> (a -> Either String b) -> Either String b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= TgaFile -> Either String (PalettedImage, Metadatas)
    unparse

    -- | This typeclass determine if a pixel can be saved in the

    -- TGA format.

    class TgaSaveable a where
        tgaDataOfImage :: Image a -> B.ByteString
        tgaPixelDepthOfImage :: Image a -> Word8
        tgaTypeOfImage :: Image a -> TgaImageType

    instance TgaSaveable Pixel8 where
        tgaDataOfImage :: Image Word8 -> ByteString
    tgaDataOfImage = Vector Word8 -> ByteString
    forall a. Storable a => Vector a -> ByteString
    toByteString (Vector Word8 -> ByteString)
    -> (Image Word8 -> Vector Word8) -> Image Word8 -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image Word8 -> Vector Word8
    Image Word8 -> Vector (PixelBaseComponent Word8)
    forall a. Image a -> Vector (PixelBaseComponent a)
    imageData
        tgaPixelDepthOfImage :: Image Word8 -> Word8
    tgaPixelDepthOfImage Image Word8
    _ = Word8
    8
        tgaTypeOfImage :: Image Word8 -> TgaImageType
    tgaTypeOfImage Image Word8
    _ = Bool -> TgaImageType
    ImageTypeMonochrome Bool
    False

    instance TgaSaveable PixelRGB8 where
        tgaPixelDepthOfImage :: Image PixelRGB8 -> Word8
    tgaPixelDepthOfImage Image PixelRGB8
    _ = Word8
    24
        tgaTypeOfImage :: Image PixelRGB8 -> TgaImageType
    tgaTypeOfImage Image PixelRGB8
    _ = Bool -> TgaImageType
    ImageTypeTrueColor Bool
    False
        tgaDataOfImage :: Image PixelRGB8 -> ByteString
    tgaDataOfImage = Vector Word8 -> ByteString
    forall a. Storable a => Vector a -> ByteString
    toByteString (Vector Word8 -> ByteString)
    -> (Image PixelRGB8 -> Vector Word8)
    -> Image PixelRGB8
    -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGB8 -> Vector Word8
    Image PixelRGB8 -> Vector (PixelBaseComponent PixelRGB8)
    forall a. Image a -> Vector (PixelBaseComponent a)
    imageData (Image PixelRGB8 -> Vector Word8)
    -> (Image PixelRGB8 -> Image PixelRGB8)
    -> Image PixelRGB8
    -> Vector Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PixelRGB8 -> PixelRGB8) -> Image PixelRGB8 -> Image PixelRGB8
    forall a b. (Pixel a, Pixel b) => (a -> b) -> Image a -> Image b
    pixelMap PixelRGB8 -> PixelRGB8
    flipRgb
          where
            flipRgb :: PixelRGB8 -> PixelRGB8
    flipRgb (PixelRGB8 Word8
    r Word8
    g Word8
    b) = Word8 -> Word8 -> Word8 -> PixelRGB8
    PixelRGB8 Word8
    b Word8
    g Word8
    r

    instance TgaSaveable PixelRGBA8 where
        tgaPixelDepthOfImage :: Image PixelRGBA8 -> Word8
    tgaPixelDepthOfImage Image PixelRGBA8
    _ = Word8
    32
        tgaTypeOfImage :: Image PixelRGBA8 -> TgaImageType
    tgaTypeOfImage Image PixelRGBA8
    _ = Bool -> TgaImageType
    ImageTypeTrueColor Bool
    False
        tgaDataOfImage :: Image PixelRGBA8 -> ByteString
    tgaDataOfImage = Vector Word8 -> ByteString
    forall a. Storable a => Vector a -> ByteString
    toByteString (Vector Word8 -> ByteString)
    -> (Image PixelRGBA8 -> Vector Word8)
    -> Image PixelRGBA8
    -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Image PixelRGBA8 -> Vector Word8
    Image PixelRGBA8 -> Vector (PixelBaseComponent PixelRGBA8)
    forall a. Image a -> Vector (PixelBaseComponent a)
    imageData (Image PixelRGBA8 -> Vector Word8)
    -> (Image PixelRGBA8 -> Image PixelRGBA8)
    -> Image PixelRGBA8
    -> Vector Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PixelRGBA8 -> PixelRGBA8) -> Image PixelRGBA8 -> Image PixelRGBA8
    forall a b. (Pixel a, Pixel b) => (a -> b) -> Image a -> Image b
    pixelMap PixelRGBA8 -> PixelRGBA8
    flipRgba
          where
            flipRgba :: PixelRGBA8 -> PixelRGBA8
    flipRgba (PixelRGBA8 Word8
    r Word8
    g Word8
    b Word8
    a) = Word8 -> Word8 -> Word8 -> Word8 -> PixelRGBA8
    PixelRGBA8 Word8
    b Word8
    g Word8
    r Word8
    a

    -- | Helper function to directly write an image a tga on disk.

    writeTga :: (TgaSaveable pixel) => FilePath -> Image pixel -> IO ()
    writeTga :: forall pixel. TgaSaveable pixel => String -> Image pixel -> IO ()
    writeTga String
    path Image pixel
    img = String -> ByteString -> IO ()
    Lb.writeFile String
    path (ByteString -> IO ()) -> ByteString -> IO ()
    forall a b. (a -> b) -> a -> b
    $ Image pixel -> ByteString
    forall px. TgaSaveable px => Image px -> ByteString
    encodeTga Image pixel
    img

    -- | Transform a compatible image to a raw bytestring

    -- representing a Targa file.

    encodeTga :: (TgaSaveable px) => Image px -> Lb.ByteString
    encodeTga :: forall px. TgaSaveable px => Image px -> ByteString
    encodeTga Image px
    img = TgaFile -> ByteString
    forall a. Binary a => a -> ByteString
    encode TgaFile
    file
      where
        file :: TgaFile
    file = TgaFile
          { _tgaFileHeader :: TgaHeader
    _tgaFileHeader = TgaHeader
                { _tgaHdrIdLength :: Word8
    _tgaHdrIdLength         = Word8
    0
                , _tgaHdrColorMapType :: TgaColorMapType
    _tgaHdrColorMapType     = TgaColorMapType
    ColorMapWithoutTable
                , _tgaHdrImageType :: TgaImageType
    _tgaHdrImageType        = Image px -> TgaImageType
    forall a. TgaSaveable a => Image a -> TgaImageType
    tgaTypeOfImage Image px
    img
                , _tgaHdrMapStart :: Word16
    _tgaHdrMapStart         = Word16
    0
                , _tgaHdrMapLength :: Word16
    _tgaHdrMapLength        = Word16
    0
                , _tgaHdrMapDepth :: Word8
    _tgaHdrMapDepth         = Word8
    0
                , _tgaHdrXOffset :: Word16
    _tgaHdrXOffset          = Word16
    0
                , _tgaHdrYOffset :: Word16
    _tgaHdrYOffset          = Word16
    0
                , _tgaHdrWidth :: Word16
    _tgaHdrWidth            = Int -> Word16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word16) -> Int -> Word16
    forall a b. (a -> b) -> a -> b
    $ Image px -> Int
    forall a. Image a -> Int
    imageWidth Image px
    img
                , _tgaHdrHeight :: Word16
    _tgaHdrHeight           = Int -> Word16
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word16) -> Int -> Word16
    forall a b. (a -> b) -> a -> b
    $ Image px -> Int
    forall a. Image a -> Int
    imageHeight Image px
    img
                , _tgaHdrPixelDepth :: Word8
    _tgaHdrPixelDepth       = Image px -> Word8
    forall a. TgaSaveable a => Image a -> Word8
    tgaPixelDepthOfImage Image px
    img
                , _tgaHdrImageDescription :: TgaImageDescription
    _tgaHdrImageDescription = TgaImageDescription
                        { _tgaIdXOrigin :: Bool
    _tgaIdXOrigin       = Bool
    False
                        , _tgaIdYOrigin :: Bool
    _tgaIdYOrigin       = Bool
    False
                        , _tgaIdAttributeBits :: Word8
    _tgaIdAttributeBits = Word8
    0
                        }
                }
          , _tgaFileId :: ByteString
    _tgaFileId     = ByteString
    forall a. Monoid a => a
    mempty
          , _tgaPalette :: ByteString
    _tgaPalette    = ByteString
    forall a. Monoid a => a
    mempty
          , _tgaFileRest :: ByteString
    _tgaFileRest   = Image px -> ByteString
    forall a. TgaSaveable a => Image a -> ByteString
    tgaDataOfImage Image px
    img
          }

    {-# ANN module "HLint: ignore Reduce duplication" #-}