{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module      : Graphics.Color.Space.RGB.Derived.AdobeRGB
-- Copyright   : (c) Alexey Kuleshevich 2019-2020
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability   : experimental
-- Portability : non-portable
--
module Graphics.Color.Space.RGB.Derived.AdobeRGB
  ( AdobeRGB
  ) where

import Data.Typeable
import Foreign.Storable
import Graphics.Color.Model.Internal
import qualified Graphics.Color.Model.RGB as CM
import Graphics.Color.Space.Internal
import Graphics.Color.Space.RGB.Internal
import qualified Graphics.Color.Space.RGB.AdobeRGB as AdobeRGB


-- | The most common @AdobeRGB@ color space with an arbitrary illuminant
data AdobeRGB (i :: k) (l :: Linearity)

-- | `AdobeRGB` color space (derived)
newtype instance Color (AdobeRGB i l) e = AdobeRGB (Color CM.RGB e)

-- | `AdobeRGB` color space (derived)
deriving instance Eq e => Eq (Color (AdobeRGB i l) e)
-- | `AdobeRGB` color space (derived)
deriving instance Ord e => Ord (Color (AdobeRGB i l) e)
-- | `AdobeRGB` color space (derived)
deriving instance Functor (Color (AdobeRGB i l))
-- | `AdobeRGB` color space (derived)
deriving instance Applicative (Color (AdobeRGB i l))
-- | `AdobeRGB` color space (derived)
deriving instance Foldable (Color (AdobeRGB i l))
-- | `AdobeRGB` color space (derived)
deriving instance Traversable (Color (AdobeRGB i l))
-- | `AdobeRGB` color space (derived)
deriving instance Storable e => Storable (Color (AdobeRGB i l) e)

-- | `AdobeRGB` color space (derived)
instance (Typeable l, Illuminant i, Elevator e) => Show (Color (AdobeRGB (i :: k) l) e) where
  showsPrec :: Int -> Color (AdobeRGB i l) e -> ShowS
showsPrec Int
_ = Color (AdobeRGB i l) e -> ShowS
forall cs e. ColorModel cs e => Color cs e -> ShowS
showsColorModel

-- | `AdobeRGB` color space (derived)
instance (Typeable l, Illuminant i, Elevator e) => ColorModel (AdobeRGB (i :: k) l) e where
  type Components (AdobeRGB i l) e = (e, e, e)
  toComponents :: Color (AdobeRGB i l) e -> Components (AdobeRGB i l) e
toComponents = Color RGB e -> (e, e, e)
forall cs e. ColorModel cs e => Color cs e -> Components cs e
toComponents (Color RGB e -> (e, e, e))
-> (Color (AdobeRGB i l) e -> Color RGB e)
-> Color (AdobeRGB i l) e
-> (e, e, e)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Color (AdobeRGB i l) e -> Color RGB e
forall k (cs :: Linearity -> *) (i :: k) (l :: Linearity) e.
RedGreenBlue cs i =>
Color (cs l) e -> Color RGB e
unColorRGB
  {-# INLINE toComponents #-}
  fromComponents :: Components (AdobeRGB i l) e -> Color (AdobeRGB i l) e
fromComponents = Color RGB e -> Color (AdobeRGB i l) e
forall k (cs :: Linearity -> *) (i :: k) e (l :: Linearity).
RedGreenBlue cs i =>
Color RGB e -> Color (cs l) e
mkColorRGB (Color RGB e -> Color (AdobeRGB i l) e)
-> ((e, e, e) -> Color RGB e)
-> (e, e, e)
-> Color (AdobeRGB i l) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e, e, e) -> Color RGB e
forall cs e. ColorModel cs e => Components cs e -> Color cs e
fromComponents
  {-# INLINE fromComponents #-}

-- | `AdobeRGB` linear color space (derived)
instance (Illuminant i, Elevator e) => ColorSpace (AdobeRGB i 'Linear) i e where
  type BaseModel (AdobeRGB i 'Linear) = CM.RGB
  toBaseSpace :: Color (AdobeRGB i 'Linear) e
-> Color (BaseSpace (AdobeRGB i 'Linear)) e
toBaseSpace = Color (AdobeRGB i 'Linear) e
-> Color (BaseSpace (AdobeRGB i 'Linear)) e
forall a. a -> a
id
  {-# INLINE toBaseSpace #-}
  fromBaseSpace :: Color (BaseSpace (AdobeRGB i 'Linear)) e
-> Color (AdobeRGB i 'Linear) e
fromBaseSpace = Color (BaseSpace (AdobeRGB i 'Linear)) e
-> Color (AdobeRGB i 'Linear) e
forall a. a -> a
id
  {-# INLINE fromBaseSpace #-}
  luminance :: Color (AdobeRGB i 'Linear) e -> Color (Y i) a
luminance = Color (AdobeRGB i 'Linear) a -> Color (Y i) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (cs 'Linear) e -> Color (Y i) e
rgbLinearLuminance (Color (AdobeRGB i 'Linear) a -> Color (Y i) a)
-> (Color (AdobeRGB i 'Linear) e -> Color (AdobeRGB i 'Linear) a)
-> Color (AdobeRGB i 'Linear) e
-> Color (Y i) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> a)
-> Color (AdobeRGB i 'Linear) e -> Color (AdobeRGB i 'Linear) a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> a
forall e a. (Elevator e, Elevator a, RealFloat a) => e -> a
toRealFloat
  {-# INLINE luminance #-}
  toColorXYZ :: Color (AdobeRGB i 'Linear) e -> Color (XYZ i) a
toColorXYZ = Color (AdobeRGB i 'Linear) a -> Color (XYZ i) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'NonLinear) i e,
 ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (cs 'Linear) e -> Color (XYZ i) e
rgbLinear2xyz (Color (AdobeRGB i 'Linear) a -> Color (XYZ i) a)
-> (Color (AdobeRGB i 'Linear) e -> Color (AdobeRGB i 'Linear) a)
-> Color (AdobeRGB i 'Linear) e
-> Color (XYZ i) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> a)
-> Color (AdobeRGB i 'Linear) e -> Color (AdobeRGB i 'Linear) a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> a
forall e a. (Elevator e, Elevator a, RealFloat a) => e -> a
toRealFloat
  {-# INLINE toColorXYZ #-}
  fromColorXYZ :: Color (XYZ i) a -> Color (AdobeRGB i 'Linear) e
fromColorXYZ = (a -> e)
-> Color (AdobeRGB i 'Linear) a -> Color (AdobeRGB i 'Linear) e
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> e
forall e a. (Elevator e, Elevator a, RealFloat a) => a -> e
fromRealFloat (Color (AdobeRGB i 'Linear) a -> Color (AdobeRGB i 'Linear) e)
-> (Color (XYZ i) a -> Color (AdobeRGB i 'Linear) a)
-> Color (XYZ i) a
-> Color (AdobeRGB i 'Linear) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Color (XYZ i) a -> Color (AdobeRGB i 'Linear) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'NonLinear) i e,
 ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (XYZ i) e -> Color (cs 'Linear) e
xyz2rgbLinear
  {-# INLINE fromColorXYZ #-}

-- | `AdobeRGB` color space (derived)
instance (Illuminant i, Elevator e) => ColorSpace (AdobeRGB i 'NonLinear) i e where
  type BaseModel (AdobeRGB i 'NonLinear) = CM.RGB
  toBaseSpace :: Color (AdobeRGB i 'NonLinear) e
-> Color (BaseSpace (AdobeRGB i 'NonLinear)) e
toBaseSpace = Color (AdobeRGB i 'NonLinear) e
-> Color (BaseSpace (AdobeRGB i 'NonLinear)) e
forall a. a -> a
id
  {-# INLINE toBaseSpace #-}
  fromBaseSpace :: Color (BaseSpace (AdobeRGB i 'NonLinear)) e
-> Color (AdobeRGB i 'NonLinear) e
fromBaseSpace = Color (BaseSpace (AdobeRGB i 'NonLinear)) e
-> Color (AdobeRGB i 'NonLinear) e
forall a. a -> a
id
  {-# INLINE fromBaseSpace #-}
  luminance :: Color (AdobeRGB i 'NonLinear) e -> Color (Y i) a
luminance = Color (AdobeRGB i 'NonLinear) a -> Color (Y i) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (cs 'NonLinear) e -> Color (Y i) e
rgbLuminance (Color (AdobeRGB i 'NonLinear) a -> Color (Y i) a)
-> (Color (AdobeRGB i 'NonLinear) e
    -> Color (AdobeRGB i 'NonLinear) a)
-> Color (AdobeRGB i 'NonLinear) e
-> Color (Y i) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> a)
-> Color (AdobeRGB i 'NonLinear) e
-> Color (AdobeRGB i 'NonLinear) a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> a
forall e a. (Elevator e, Elevator a, RealFloat a) => e -> a
toRealFloat
  {-# INLINE luminance #-}
  toColorXYZ :: Color (AdobeRGB i 'NonLinear) e -> Color (XYZ i) a
toColorXYZ = Color (AdobeRGB i 'NonLinear) a -> Color (XYZ i) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'NonLinear) i e,
 ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (cs 'NonLinear) e -> Color (XYZ i) e
rgb2xyz (Color (AdobeRGB i 'NonLinear) a -> Color (XYZ i) a)
-> (Color (AdobeRGB i 'NonLinear) e
    -> Color (AdobeRGB i 'NonLinear) a)
-> Color (AdobeRGB i 'NonLinear) e
-> Color (XYZ i) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e -> a)
-> Color (AdobeRGB i 'NonLinear) e
-> Color (AdobeRGB i 'NonLinear) a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> a
forall e a. (Elevator e, Elevator a, RealFloat a) => e -> a
toRealFloat
  {-# INLINE toColorXYZ #-}
  fromColorXYZ :: Color (XYZ i) a -> Color (AdobeRGB i 'NonLinear) e
fromColorXYZ = (a -> e)
-> Color (AdobeRGB i 'NonLinear) a
-> Color (AdobeRGB i 'NonLinear) e
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> e
forall e a. (Elevator e, Elevator a, RealFloat a) => a -> e
fromRealFloat (Color (AdobeRGB i 'NonLinear) a
 -> Color (AdobeRGB i 'NonLinear) e)
-> (Color (XYZ i) a -> Color (AdobeRGB i 'NonLinear) a)
-> Color (XYZ i) a
-> Color (AdobeRGB i 'NonLinear) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Color (XYZ i) a -> Color (AdobeRGB i 'NonLinear) a
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, ColorSpace (cs 'NonLinear) i e,
 ColorSpace (cs 'Linear) i e, RealFloat e) =>
Color (XYZ i) e -> Color (cs 'NonLinear) e
xyz2rgb
  {-# INLINE fromColorXYZ #-}

-- | `AdobeRGB` color space (derived)
instance Illuminant i => RedGreenBlue (AdobeRGB i) i where
  gamut :: Gamut (AdobeRGB i) i e
gamut = Gamut AdobeRGB D65 e -> Gamut (AdobeRGB i) i e
forall k1 k2 (cs' :: Linearity -> *) (i' :: k1) e
       (cs :: Linearity -> *) (i :: k2).
Gamut cs' i' e -> Gamut cs i e
coerceGamut (forall i e.
(RedGreenBlue AdobeRGB i, RealFloat e) =>
Gamut AdobeRGB i e
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, RealFloat e) =>
Gamut cs i e
gamut @_ @AdobeRGB.AdobeRGB)
  transfer :: e -> e
transfer = forall i e. (RedGreenBlue AdobeRGB i, RealFloat e) => e -> e
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, RealFloat e) =>
e -> e
transfer @_ @AdobeRGB.AdobeRGB
  {-# INLINE transfer #-}
  itransfer :: e -> e
itransfer = forall i e. (RedGreenBlue AdobeRGB i, RealFloat e) => e -> e
forall k (cs :: Linearity -> *) (i :: k) e.
(RedGreenBlue cs i, RealFloat e) =>
e -> e
itransfer @_ @AdobeRGB.AdobeRGB
  {-# INLINE itransfer #-}