{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}
-- |
-- Module      : Graphics.Pixel.ColorSpace
-- Copyright   : (c) Alexey Kuleshevich 2019-2020
-- License     : BSD3
-- Maintainer  : Alexey Kuleshevich <lehins@yandex.ru>
-- Stability   : experimental
-- Portability : non-portable
--
module Graphics.Pixel.ColorSpace
  ( Pixel(Pixel, PixelY, PixelXYZ, PixelLAB, PixelRGB, PixelHSI, PixelHSL, PixelHSV,
      PixelCMYK, PixelY'CbCr, PixelY', PixelYA, PixelXYZA, PixelLABA, PixelRGBA, PixelHSIA, PixelHSLA,
      PixelHSVA, PixelCMYKA, PixelY'CbCrA, PixelY'A)
  , liftPixel
  , pixelColor
  -- * Conversion
  -- ** Color space
  , convertPixel
  , toPixelY
  , toPixelXYZ
  , fromPixelXYZ
  , toPixelBaseSpace
  , fromPixelBaseSpace
  -- ** Color model
  , toPixelBaseModel
  , fromPixelBaseModel
  -- ** Precision
  , toPixel8
  , toPixel16
  , toPixel32
  , toPixel64
  , toPixelF
  , toPixelD
  -- * RGB
  , toPixelLinearRGB
  , fromPixelLinearRGB
  -- ** sRGB color space
  , pattern PixelSRGB
  , pattern PixelSRGBA
  -- ** Luma
  , rgbPixelLuma
  -- * Re-export of color space
  , module Graphics.Color.Space
  , module Graphics.Color.Algebra.Binary
  ) where

import Data.Coerce
import Graphics.Color.Adaptation.VonKries
import Graphics.Color.Algebra.Binary
import qualified Graphics.Color.Model.RGB as CM
import Graphics.Color.Space
import Graphics.Pixel.Internal

-- | Convert a pixel from one color space to any other.
--
-- >>> :set -XDataKinds
-- >>> :set -XTypeApplications
-- >>> px = PixelSRGB @Float 0.0 0.5 1.0
-- >>> px
-- <SRGB 'NonLinear:( 0.00000000, 0.50000000, 1.00000000)>
-- >>> convertPixel @(AdobeRGB 'NonLinear) @_ @Word8 px
-- <AdobeRGB 'NonLinear:( 71,127,251)>
--
-- @since 0.1.0
convertPixel ::
     forall cs i e cs' i' e' . (ColorSpace cs' i' e', ColorSpace cs i e)
  => Pixel cs' e'
  -> Pixel cs e
convertPixel :: Pixel cs' e' -> Pixel cs e
convertPixel = (Color cs' e' -> Color cs e) -> Pixel cs' e' -> Pixel cs e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color cs' e' -> Color cs e
forall k1 k2 cs' (i' :: k1) e' cs (i :: k2) e.
(ColorSpace cs' i' e', ColorSpace cs i e) =>
Color cs' e' -> Color cs e
convert
{-# INLINE convertPixel #-}

-- | Constructor for a pixel in @sRGB@ color space
--
-- @since 0.1.0
pattern PixelSRGB :: e -> e -> e -> Pixel (SRGB 'NonLinear) e
pattern $bPixelSRGB :: e -> e -> e -> Pixel (SRGB 'NonLinear) e
$mPixelSRGB :: forall r e.
Pixel (SRGB 'NonLinear) e
-> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelSRGB r g b = Pixel (SRGB (CM.ColorRGB r g b))
{-# COMPLETE PixelSRGB #-}

-- | Constructor for a pixel in @sRGB@ color space with Alpha channel
--
-- @since 0.1.0
pattern PixelSRGBA :: e -> e -> e -> e -> Pixel (Alpha (SRGB 'NonLinear)) e
pattern $bPixelSRGBA :: e -> e -> e -> e -> Pixel (Alpha (SRGB 'NonLinear)) e
$mPixelSRGBA :: forall r e.
Pixel (Alpha (SRGB 'NonLinear)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelSRGBA r g b a = Pixel (Alpha (SRGB (CM.ColorRGB r g b)) a)
{-# COMPLETE PixelSRGBA #-}

-- | Constructor for a pixel with Luminance
--
-- @since 0.1.0
pattern PixelY :: e -> Pixel (Y i) e
pattern $bPixelY :: e -> Pixel (Y i) e
$mPixelY :: forall r k e (i :: k).
Pixel (Y i) e -> (e -> r) -> (Void# -> r) -> r
PixelY y = Pixel (Y y)
{-# COMPLETE PixelY #-}

-- | Constructor for a pixel with Luminance and Alpha channel
--
-- @since 0.1.0
pattern PixelYA :: e -> e -> Pixel (Alpha (Y i)) e
pattern $bPixelYA :: e -> e -> Pixel (Alpha (Y i)) e
$mPixelYA :: forall r k e (i :: k).
Pixel (Alpha (Y i)) e -> (e -> e -> r) -> (Void# -> r) -> r
PixelYA y a = Pixel (Alpha (Y y) a)
{-# COMPLETE PixelYA #-}

-- | Constructor for a pixel in @CIE1931 XYZ@ color space
--
-- @since 0.1.0
pattern PixelXYZ :: e -> e -> e -> Pixel (XYZ i) e
pattern $bPixelXYZ :: e -> e -> e -> Pixel (XYZ i) e
$mPixelXYZ :: forall r k e (i :: k).
Pixel (XYZ i) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelXYZ x y z = Pixel (XYZ (V3 x y z))
{-# COMPLETE PixelXYZ #-}


-- | Constructor for a pixel in @CIE1931 XYZ@ color space with Alpha channel
--
-- @since 0.1.0
pattern PixelXYZA :: e -> e -> e -> e -> Pixel (Alpha (XYZ i)) e
pattern $bPixelXYZA :: e -> e -> e -> e -> Pixel (Alpha (XYZ i)) e
$mPixelXYZA :: forall r k e (i :: k).
Pixel (Alpha (XYZ i)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelXYZA x y z a = Pixel (Alpha (XYZ (V3 x y z)) a)
{-# COMPLETE PixelXYZA #-}


-- | Constructor for a pixel in @CIE1976 LAB@ color space
--
-- @since 0.3.0
pattern PixelLAB :: e -> e -> e -> Pixel (LAB i) e
pattern $bPixelLAB :: e -> e -> e -> Pixel (LAB i) e
$mPixelLAB :: forall r k e (i :: k).
Pixel (LAB i) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelLAB l' a' b' = Pixel (LAB (V3 l' a' b'))
{-# COMPLETE PixelLAB #-}

-- | Constructor for a pixel in @CIE1976 LAB@ color space with Alpha channel
--
-- @since 0.3.0
pattern PixelLABA :: e -> e -> e -> e -> Pixel (Alpha (LAB i)) e
pattern $bPixelLABA :: e -> e -> e -> e -> Pixel (Alpha (LAB i)) e
$mPixelLABA :: forall r k e (i :: k).
Pixel (Alpha (LAB i)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelLABA l' a' b' a = Pixel (Alpha (LAB (V3 l' a' b')) a)
{-# COMPLETE PixelLABA #-}

-- | Constructor for a pixel in RGB color space.
--
-- @since 0.1.0
pattern PixelRGB :: RedGreenBlue cs (i :: k) => e -> e -> e -> Pixel (cs l) e
pattern $bPixelRGB :: e -> e -> e -> Pixel (cs l) e
$mPixelRGB :: forall r k2 (cs :: Linearity -> *) k2 (i :: k2) e (l :: Linearity).
RedGreenBlue cs i =>
Pixel (cs l) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelRGB r g b <- (coerce . unColorRGB . coerce -> V3 r g b) where
        PixelRGB e
r e
g e
b = Color (cs l) e -> Pixel (cs l) e
coerce (Color RGB e -> Color (cs l) e
forall k (cs :: Linearity -> *) (i :: k) e (l :: Linearity).
RedGreenBlue cs i =>
Color RGB e -> Color (cs l) e
mkColorRGB (V3 e -> Color RGB e
coerce (e -> e -> e -> V3 e
forall a. a -> a -> a -> V3 a
V3 e
r e
g e
b)))
{-# COMPLETE PixelRGB #-}

-- | Constructor for a pixel in @HSI@.
--
-- @since 0.1.0
pattern PixelHSI :: e -> e -> e -> Pixel (HSI cs) e
pattern $bPixelHSI :: e -> e -> e -> Pixel (HSI cs) e
$mPixelHSI :: forall r k e (cs :: k).
Pixel (HSI cs) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSI h s i = Pixel (ColorHSI h s i)
{-# COMPLETE PixelHSI #-}


-- | Constructor for a pixel in @HSL@.
--
-- @since 0.1.0
pattern PixelHSL :: e -> e -> e -> Pixel (HSL cs) e
pattern $bPixelHSL :: e -> e -> e -> Pixel (HSL cs) e
$mPixelHSL :: forall r k e (cs :: k).
Pixel (HSL cs) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSL h s l = Pixel (ColorHSL h s l)
{-# COMPLETE PixelHSL #-}


-- | Constructor for a pixel in @HSV@.
--
-- @since 0.1.0
pattern PixelHSV :: e -> e -> e -> Pixel (HSV cs) e
pattern $bPixelHSV :: e -> e -> e -> Pixel (HSV cs) e
$mPixelHSV :: forall r k e (cs :: k).
Pixel (HSV cs) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSV h s v = Pixel (ColorHSV h s v)
{-# COMPLETE PixelHSV #-}

-- | Constructor for a pixel in @CMYK@.
--
-- @since 0.1.0
pattern PixelCMYK :: e -> e -> e -> e -> Pixel (CMYK cs) e
pattern $bPixelCMYK :: e -> e -> e -> e -> Pixel (CMYK cs) e
$mPixelCMYK :: forall r k e (cs :: k).
Pixel (CMYK cs) e -> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelCMYK c m y k = Pixel (ColorCMYK c m y k)
{-# COMPLETE PixelCMYK #-}


-- | Constructor for a pixel in @Y'CbCr@.
--
-- @since 0.1.0
pattern PixelY'CbCr :: e -> e -> e -> Pixel (Y'CbCr cs) e
pattern $bPixelY'CbCr :: e -> e -> e -> Pixel (Y'CbCr cs) e
$mPixelY'CbCr :: forall r e (cs :: Linearity -> *).
Pixel (Y'CbCr cs) e -> (e -> e -> e -> r) -> (Void# -> r) -> r
PixelY'CbCr y cb cr = Pixel (ColorY'CbCr y cb cr)
{-# COMPLETE PixelY'CbCr #-}

-- | Constructor for a pixel with Luma (not to be confused with luminance `Y`)
--
-- @since 0.1.4
pattern PixelY' :: e -> Pixel (Y' cs) e
pattern $bPixelY' :: e -> Pixel (Y' cs) e
$mPixelY' :: forall r e (cs :: Linearity -> *).
Pixel (Y' cs) e -> (e -> r) -> (Void# -> r) -> r
PixelY' y = Pixel (Y' y)
{-# COMPLETE PixelY' #-}

-- | Constructor for a pixel with Luma and Alpha channel (not to be confused with luminance `Y`)
--
-- @since 0.1.4
pattern PixelY'A :: e -> e -> Pixel (Alpha (Y' cs)) e
pattern $bPixelY'A :: e -> e -> Pixel (Alpha (Y' cs)) e
$mPixelY'A :: forall r e (cs :: Linearity -> *).
Pixel (Alpha (Y' cs)) e -> (e -> e -> r) -> (Void# -> r) -> r
PixelY'A y a = Pixel (Alpha (Y' y) a)
{-# COMPLETE PixelY'A #-}


-- | Constructor for a pixel in RGB color space with Alpha channel
--
-- @since 0.1.0
pattern PixelRGBA :: RedGreenBlue cs i => e -> e -> e -> e -> Pixel (Alpha (cs l)) e
pattern $bPixelRGBA :: e -> e -> e -> e -> Pixel (Alpha (cs l)) e
$mPixelRGBA :: forall r k (cs :: Linearity -> *) (i :: k) e (l :: Linearity).
RedGreenBlue cs i =>
Pixel (Alpha (cs l)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelRGBA r g b a <- (pixelColor -> Alpha (unColorRGB -> CM.ColorRGB r g b) a) where
        PixelRGBA e
r e
g e
b e
a = Color (Alpha (cs l)) e -> Pixel (Alpha (cs l)) e
forall cs e. Color cs e -> Pixel cs e
Pixel (Color (cs l) e -> e -> Color (Alpha (cs l)) e
forall cs e. Color cs e -> e -> Color (Alpha cs) e
Alpha (Color RGB e -> Color (cs l) e
forall k (cs :: Linearity -> *) (i :: k) e (l :: Linearity).
RedGreenBlue cs i =>
Color RGB e -> Color (cs l) e
mkColorRGB (e -> e -> e -> Color RGB e
forall e. e -> e -> e -> Color RGB e
CM.ColorRGB e
r e
g e
b)) e
a)
{-# COMPLETE PixelRGBA #-}


-- | Constructor for a pixel in @HSI@ with alpha channel.
--
-- @since 0.1.0
pattern PixelHSIA :: e -> e -> e -> e -> Pixel (Alpha (HSI cs)) e
pattern $bPixelHSIA :: e -> e -> e -> e -> Pixel (Alpha (HSI cs)) e
$mPixelHSIA :: forall r k e (cs :: k).
Pixel (Alpha (HSI cs)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSIA h s i a = Pixel (ColorHSIA h s i a)
{-# COMPLETE PixelHSIA #-}

-- | Constructor for a pixel in @HSL@ with alpha channel.
--
-- @since 0.1.0
pattern PixelHSLA :: e -> e -> e -> e -> Pixel (Alpha (HSL cs)) e
pattern $bPixelHSLA :: e -> e -> e -> e -> Pixel (Alpha (HSL cs)) e
$mPixelHSLA :: forall r k e (cs :: k).
Pixel (Alpha (HSL cs)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSLA h s l a = Pixel (ColorHSLA h s l a)
{-# COMPLETE PixelHSLA #-}


-- | Constructor for a pixel in @HSV@ with alpha channel.
--
-- @since 0.1.0
pattern PixelHSVA :: e -> e -> e -> e -> Pixel (Alpha (HSV cs)) e
pattern $bPixelHSVA :: e -> e -> e -> e -> Pixel (Alpha (HSV cs)) e
$mPixelHSVA :: forall r k e (cs :: k).
Pixel (Alpha (HSV cs)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelHSVA h s v a = Pixel (ColorHSVA h s v a)
{-# COMPLETE PixelHSVA #-}


-- | Constructor for a pixel in @CMYK@ with alpha channel.
--
-- @since 0.1.0
pattern PixelCMYKA :: e -> e -> e -> e -> e -> Pixel (Alpha (CMYK cs)) e
pattern $bPixelCMYKA :: e -> e -> e -> e -> e -> Pixel (Alpha (CMYK cs)) e
$mPixelCMYKA :: forall r k e (cs :: k).
Pixel (Alpha (CMYK cs)) e
-> (e -> e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelCMYKA c m y k a = Pixel (ColorCMYKA c m y k a)
{-# COMPLETE PixelCMYKA #-}


-- | Constructor for a pixel in @Y'CbCr@ with alpha channel.
--
-- @since 0.1.0
pattern PixelY'CbCrA :: e -> e -> e -> e -> Pixel (Alpha (Y'CbCr cs)) e
pattern $bPixelY'CbCrA :: e -> e -> e -> e -> Pixel (Alpha (Y'CbCr cs)) e
$mPixelY'CbCrA :: forall r e (cs :: Linearity -> *).
Pixel (Alpha (Y'CbCr cs)) e
-> (e -> e -> e -> e -> r) -> (Void# -> r) -> r
PixelY'CbCrA y cb cr a = Pixel (ColorY'CbCrA y cb cr a)
{-# COMPLETE PixelY'CbCrA #-}

-- | Convert non-linear RGB color space into linear one
--
-- @since 0.2.0
toPixelLinearRGB ::
     (RedGreenBlue cs i, RealFloat e) => Pixel (cs 'NonLinear) e -> Pixel (cs 'Linear) e
toPixelLinearRGB :: Pixel (cs 'NonLinear) e -> Pixel (cs 'Linear) e
toPixelLinearRGB = (Color (cs 'NonLinear) e -> Color (cs 'Linear) e)
-> Pixel (cs 'NonLinear) e -> Pixel (cs 'Linear) e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color (cs 'NonLinear) e -> Color (cs 'Linear) e
forall k (cs :: Linearity -> *) e (i :: k).
(RedGreenBlue cs i, RealFloat e) =>
Color (cs 'NonLinear) e -> Color (cs 'Linear) e
dcctf
{-# INLINE toPixelLinearRGB #-}

-- | Convert linear RGB color space into a non-linear one
--
-- @since 0.2.0
fromPixelLinearRGB ::
     (RedGreenBlue cs i, RealFloat e) => Pixel (cs 'Linear) e -> Pixel (cs 'NonLinear) e
fromPixelLinearRGB :: Pixel (cs 'Linear) e -> Pixel (cs 'NonLinear) e
fromPixelLinearRGB = (Color (cs 'Linear) e -> Color (cs 'NonLinear) e)
-> Pixel (cs 'Linear) e -> Pixel (cs 'NonLinear) e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color (cs 'Linear) e -> Color (cs 'NonLinear) e
forall k (cs :: Linearity -> *) e (i :: k).
(RedGreenBlue cs i, RealFloat e) =>
Color (cs 'Linear) e -> Color (cs 'NonLinear) e
ecctf
{-# INLINE fromPixelLinearRGB #-}

-- | Convert an RGB pixel to `Y'` if it has the weights specified with `Luma`.
--
-- @since 0.1.4
rgbPixelLuma ::
     forall cs i e' e. (Luma cs, RedGreenBlue cs i, Elevator e', Elevator e, RealFloat e)
  => Pixel (cs 'NonLinear) e'
  -> Pixel (Y' cs) e
rgbPixelLuma :: Pixel (cs 'NonLinear) e' -> Pixel (Y' cs) e
rgbPixelLuma = (Color (cs 'NonLinear) e' -> Color (Y' cs) e)
-> Pixel (cs 'NonLinear) e' -> Pixel (Y' cs) e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color (cs 'NonLinear) e' -> Color (Y' cs) e
forall k (cs :: Linearity -> *) (i :: k) e' e.
(Luma cs, RedGreenBlue cs i, Elevator e', Elevator e,
 RealFloat e) =>
Color (cs 'NonLinear) e' -> Color (Y' cs) e
rgbLuma

-- | Compute luminance of a pixel color
--
-- @since 0.1.0
toPixelY :: ColorSpace cs i e => Pixel cs e -> Pixel (Y i) e
toPixelY :: Pixel cs e -> Pixel (Y i) e
toPixelY = (Color cs e -> Color (Y i) e) -> Pixel cs e -> Pixel (Y i) e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel ((Double -> e) -> Color (Y i) Double -> Color (Y i) e
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Double -> e
forall e. Elevator e => Double -> e
fromDouble (Color (Y i) Double -> Color (Y i) e)
-> (Color cs e -> Color (Y i) Double)
-> Color cs e
-> Color (Y i) e
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Color cs e -> Color (Y i) Double
forall k cs (i :: k) e a.
(ColorSpace cs i e, Elevator a, RealFloat a) =>
Color cs e -> Color (Y i) a
luminance)
{-# INLINE toPixelY #-}

-- | Convert to CIE1931 XYZ color space, with the same illuminant as the original.
--
-- @since 0.1.0
toPixelXYZ :: (ColorSpace cs i e, Elevator a, RealFloat a) => Pixel cs e -> Pixel (XYZ i) a
toPixelXYZ :: Pixel cs e -> Pixel (XYZ i) a
toPixelXYZ = (Color cs e -> Color (XYZ i) a) -> Pixel cs e -> Pixel (XYZ i) a
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color cs e -> Color (XYZ i) a
forall k cs (i :: k) e a.
(ColorSpace cs i e, Elevator a, RealFloat a) =>
Color cs e -> Color (XYZ i) a
toColorXYZ
{-# INLINE toPixelXYZ #-}


-- | Convert from CIE1931 XYZ color space, with the same illuminant as the target color
-- space.
--
-- @since 0.1.0
fromPixelXYZ :: (ColorSpace cs i e, Elevator a, RealFloat a) => Pixel (XYZ i) a -> Pixel cs e
fromPixelXYZ :: Pixel (XYZ i) a -> Pixel cs e
fromPixelXYZ = (Color (XYZ i) a -> Color cs e) -> Pixel (XYZ i) a -> Pixel cs e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color (XYZ i) a -> Color cs e
forall k cs (i :: k) e a.
(ColorSpace cs i e, Elevator a, RealFloat a) =>
Color (XYZ i) a -> Color cs e
fromColorXYZ
{-# INLINE fromPixelXYZ #-}



-- Color Space conversions

-- | Drop all color space information and only keep the values encoded in the fitting
-- color model, which the color space is backed by.
--
-- @since 0.1.0
toPixelBaseModel :: ColorSpace cs i e => Pixel cs e -> Pixel (BaseModel cs) e
toPixelBaseModel :: Pixel cs e -> Pixel (BaseModel cs) e
toPixelBaseModel = (Color cs e -> Color (BaseModel cs) e)
-> Pixel cs e -> Pixel (BaseModel cs) e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color cs e -> Color (BaseModel cs) e
forall k cs (i :: k) e.
ColorSpace cs i e =>
Color cs e -> Color (BaseModel cs) e
toBaseModel
{-# INLINE toPixelBaseModel #-}

-- | Promote a pixel without color space information to a color space that is backed by
-- the fitting color model
--
-- @since 0.1.0
fromPixelBaseModel :: ColorSpace cs i e => Pixel (BaseModel cs) e -> Pixel cs e
fromPixelBaseModel :: Pixel (BaseModel cs) e -> Pixel cs e
fromPixelBaseModel = (Color (BaseModel cs) e -> Color cs e)
-> Pixel (BaseModel cs) e -> Pixel cs e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color (BaseModel cs) e -> Color cs e
forall k cs (i :: k) e.
ColorSpace cs i e =>
Color (BaseModel cs) e -> Color cs e
fromBaseModel
{-# INLINE fromPixelBaseModel #-}

-- | Convert pixel in an alternative representation of color space, to its base color
-- space. Example from CMYK to SRGB
--
-- @since 0.1.0
toPixelBaseSpace ::
     (ColorSpace cs i e, bcs ~ BaseSpace cs, ColorSpace bcs i e) => Pixel cs e -> Pixel bcs e
toPixelBaseSpace :: Pixel cs e -> Pixel bcs e
toPixelBaseSpace = (Color cs e -> Color bcs e) -> Pixel cs e -> Pixel bcs e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color cs e -> Color bcs e
forall k cs (i :: k) e.
(ColorSpace cs i e, ColorSpace (BaseSpace cs) i e) =>
Color cs e -> Color (BaseSpace cs) e
toBaseSpace
{-# INLINE toPixelBaseSpace #-}

-- | Covert a color space of a pixel into it's alternative representation. Example AdobeRGB to HSI.
--
-- @since 0.1.0
fromPixelBaseSpace ::
     (ColorSpace cs i e, bcs ~ BaseSpace cs, ColorSpace bcs i e) => Pixel bcs e -> Pixel cs e
fromPixelBaseSpace :: Pixel bcs e -> Pixel cs e
fromPixelBaseSpace = (Color bcs e -> Color cs e) -> Pixel bcs e -> Pixel cs e
forall cs e cs' e'.
(Color cs e -> Color cs' e') -> Pixel cs e -> Pixel cs' e'
liftPixel Color bcs e -> Color cs e
forall k cs (i :: k) e.
(ColorSpace cs i e, ColorSpace (BaseSpace cs) i e) =>
Color (BaseSpace cs) e -> Color cs e
fromBaseSpace
{-# INLINE fromPixelBaseSpace #-}


-- -- | Constructor for a pixel in @sRGB@ color space with 8-bits per channel
-- pattern PixelRGB8 :: Word8 -> Word8 -> Word8 -> Pixel SRGB Word8
-- pattern PixelRGB8 r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGB8 #-}

-- -- | Constructor for a pixel in @sRGB@ color space with 16-bits per channel
-- pattern PixelRGB16 :: Word16 -> Word16 -> Word16 -> Pixel SRGB Word16
-- pattern PixelRGB16 r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGB16 #-}

-- -- | Constructor for a pixel in @sRGB@ color space with 32-bits per channel
-- pattern PixelRGB32 :: Word32 -> Word32 -> Word32 -> Pixel SRGB Word32
-- pattern PixelRGB32 r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGB32 #-}

-- -- | Constructor for a pixel in @sRGB@ color space with 64-bits per channel
-- pattern PixelRGB64 :: Word64 -> Word64 -> Word64 -> Pixel SRGB Word64
-- pattern PixelRGB64 r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGB64 #-}

-- -- | Constructor for a pixel in @sRGB@ color space with 32-bit floating point value per channel
-- pattern PixelRGBF :: Float -> Float -> Float -> Pixel SRGB Float
-- pattern PixelRGBF r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGBF #-}

-- -- | Constructor for a pixel in @sRGB@ color space with 32-bit floating point value per channel
-- pattern PixelRGBD :: Double -> Double -> Double -> Pixel SRGB Double
-- pattern PixelRGBD r g b = Pixel (SRGB (CM.ColorRGB r g b))
-- {-# COMPLETE PixelRGBD #-}