module Data.Colour.RGBSpace
(Colour
,RGB(..)
,uncurryRGB, curryRGB
,RGBGamut
,mkRGBGamut, primaries, whitePoint
,inGamut
,TransferFunction(..)
,linearTransferFunction, powerTransferFunction
,inverseTransferFunction
,RGBSpace()
,mkRGBSpace ,gamut, transferFunction
,linearRGBSpace
,rgbUsingSpace
,toRGBUsingSpace
)
where
import Data.Colour.CIE.Chromaticity
import Data.Colour.Matrix
import Data.Colour.RGB
import Data.Colour.SRGB.Linear
inGamut :: (Ord a, Fractional a) => RGBGamut -> Colour a -> Bool
inGamut :: forall a. (Ord a, Fractional a) => RGBGamut -> Colour a -> Bool
inGamut RGBGamut
gamut Colour a
c = Bool
r Bool -> Bool -> Bool
&& Bool
g Bool -> Bool -> Bool
&& Bool
b
where
test :: a -> Bool
test a
x = a
0 forall a. Ord a => a -> a -> Bool
<= a
x Bool -> Bool -> Bool
&& a
x forall a. Ord a => a -> a -> Bool
<= a
1
RGB Bool
r Bool
g Bool
b = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {a}. (Ord a, Num a) => a -> Bool
test (forall a. Fractional a => RGBGamut -> Colour a -> RGB a
toRGBUsingGamut RGBGamut
gamut Colour a
c)
rtf :: (Fractional b, Real a) => [[a]] -> [[b]]
rtf :: forall b a. (Fractional b, Real a) => [[a]] -> [[b]]
rtf = forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> [a] -> [b]
map forall a b. (Real a, Fractional b) => a -> b
realToFrac)
rgbUsingGamut :: (Fractional a) => RGBGamut -> a -> a -> a -> Colour a
rgbUsingGamut :: forall a. Fractional a => RGBGamut -> a -> a -> a -> Colour a
rgbUsingGamut RGBGamut
gamut a
r a
g a
b = forall a. Fractional a => a -> a -> a -> Colour a
rgb a
r0 a
g0 a
b0
where
matrix :: [[a]]
matrix = forall b a. (Fractional b, Real a) => [[a]] -> [[b]]
rtf forall a b. (a -> b) -> a -> b
$ forall {a}. Num a => [[a]] -> [[a]] -> [[a]]
matrixMult (RGBGamut -> [[Rational]]
xyz2rgb RGBGamut
sRGBGamut) (RGBGamut -> [[Rational]]
rgb2xyz RGBGamut
gamut)
[a
r0,a
g0,a
b0] = forall {b}. Num b => [[b]] -> [b] -> [b]
mult [[a]]
matrix [a
r,a
g,a
b]
toRGBUsingGamut :: (Fractional a) => RGBGamut -> Colour a -> RGB a
toRGBUsingGamut :: forall a. Fractional a => RGBGamut -> Colour a -> RGB a
toRGBUsingGamut RGBGamut
gamut Colour a
c = forall a. a -> a -> a -> RGB a
RGB a
r a
g a
b
where
RGB a
r0 a
g0 a
b0 = forall a. Fractional a => Colour a -> RGB a
toRGB Colour a
c
matrix :: [[a]]
matrix = forall b a. (Fractional b, Real a) => [[a]] -> [[b]]
rtf forall a b. (a -> b) -> a -> b
$ forall {a}. Num a => [[a]] -> [[a]] -> [[a]]
matrixMult (RGBGamut -> [[Rational]]
xyz2rgb RGBGamut
gamut) (RGBGamut -> [[Rational]]
rgb2xyz RGBGamut
sRGBGamut)
[a
r,a
g,a
b] = forall {b}. Num b => [[b]] -> [b] -> [b]
mult [[a]]
matrix [a
r0,a
g0,a
b0]
data TransferFunction a = TransferFunction
{ forall a. TransferFunction a -> a -> a
transfer :: a -> a
, forall a. TransferFunction a -> a -> a
transferInverse :: a -> a
, forall a. TransferFunction a -> a
transferGamma :: a }
linearTransferFunction :: (Num a) => TransferFunction a
linearTransferFunction :: forall a. Num a => TransferFunction a
linearTransferFunction = forall a. (a -> a) -> (a -> a) -> a -> TransferFunction a
TransferFunction forall a. a -> a
id forall a. a -> a
id a
1
powerTransferFunction :: (Floating a) => a -> TransferFunction a
powerTransferFunction :: forall a. Floating a => a -> TransferFunction a
powerTransferFunction a
gamma =
forall a. (a -> a) -> (a -> a) -> a -> TransferFunction a
TransferFunction (forall a. Floating a => a -> a -> a
**a
gamma) (forall a. Floating a => a -> a -> a
**(forall a. Fractional a => a -> a
recip a
gamma)) a
gamma
inverseTransferFunction :: (Fractional a) => TransferFunction a -> TransferFunction a
inverseTransferFunction :: forall a. Fractional a => TransferFunction a -> TransferFunction a
inverseTransferFunction (TransferFunction a -> a
for a -> a
rev a
g) =
forall a. (a -> a) -> (a -> a) -> a -> TransferFunction a
TransferFunction a -> a
rev a -> a
for (forall a. Fractional a => a -> a
recip a
g)
instance (Num a) => Semigroup (TransferFunction a) where
(TransferFunction a -> a
f0 a -> a
f1 a
f) <> :: TransferFunction a -> TransferFunction a -> TransferFunction a
<> (TransferFunction a -> a
g0 a -> a
g1 a
g) =
(forall a. (a -> a) -> (a -> a) -> a -> TransferFunction a
TransferFunction (a -> a
f0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
g0) (a -> a
g1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f1) (a
fforall a. Num a => a -> a -> a
*a
g))
instance (Num a) => Monoid (TransferFunction a) where
mempty :: TransferFunction a
mempty = forall a. Num a => TransferFunction a
linearTransferFunction
data RGBSpace a = RGBSpace { forall a. RGBSpace a -> RGBGamut
gamut :: RGBGamut,
forall a. RGBSpace a -> TransferFunction a
transferFunction :: TransferFunction a }
mkRGBSpace :: RGBGamut
-> TransferFunction a
-> RGBSpace a
mkRGBSpace :: forall a. RGBGamut -> TransferFunction a -> RGBSpace a
mkRGBSpace = forall a. RGBGamut -> TransferFunction a -> RGBSpace a
RGBSpace
linearRGBSpace :: (Num a) => RGBGamut -> RGBSpace a
linearRGBSpace :: forall a. Num a => RGBGamut -> RGBSpace a
linearRGBSpace RGBGamut
gamut = forall a. RGBGamut -> TransferFunction a -> RGBSpace a
RGBSpace RGBGamut
gamut forall a. Monoid a => a
mempty
rgbUsingSpace :: (Fractional a) => RGBSpace a -> a -> a -> a -> Colour a
rgbUsingSpace :: forall a. Fractional a => RGBSpace a -> a -> a -> a -> Colour a
rgbUsingSpace RGBSpace a
space =
forall a b. (RGB a -> b) -> a -> a -> a -> b
curryRGB (forall a b. (a -> a -> a -> b) -> RGB a -> b
uncurryRGB (forall a. Fractional a => RGBGamut -> a -> a -> a -> Colour a
rgbUsingGamut (forall a. RGBSpace a -> RGBGamut
gamut RGBSpace a
space)) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
tinv)
where
tinv :: a -> a
tinv = forall a. TransferFunction a -> a -> a
transferInverse (forall a. RGBSpace a -> TransferFunction a
transferFunction RGBSpace a
space)
toRGBUsingSpace :: (Fractional a) => RGBSpace a -> Colour a -> RGB a
toRGBUsingSpace :: forall a. Fractional a => RGBSpace a -> Colour a -> RGB a
toRGBUsingSpace RGBSpace a
space Colour a
c = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
t (forall a. Fractional a => RGBGamut -> Colour a -> RGB a
toRGBUsingGamut (forall a. RGBSpace a -> RGBGamut
gamut RGBSpace a
space) Colour a
c)
where
t :: a -> a
t = forall a. TransferFunction a -> a -> a
transfer (forall a. RGBSpace a -> TransferFunction a
transferFunction RGBSpace a
space)