module Data.Colour.RGB where
import Data.List (elemIndex, transpose)
import Data.Colour.Matrix
import Data.Colour.CIE.Chromaticity
data RGB a = RGB {forall a. RGB a -> a
channelRed :: !a
,forall a. RGB a -> a
channelGreen :: !a
,forall a. RGB a -> a
channelBlue :: !a
} deriving (RGB a -> RGB a -> Bool
forall a. Eq a => RGB a -> RGB a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RGB a -> RGB a -> Bool
$c/= :: forall a. Eq a => RGB a -> RGB a -> Bool
== :: RGB a -> RGB a -> Bool
$c== :: forall a. Eq a => RGB a -> RGB a -> Bool
Eq, Int -> RGB a -> ShowS
forall a. Show a => Int -> RGB a -> ShowS
forall a. Show a => [RGB a] -> ShowS
forall a. Show a => RGB a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RGB a] -> ShowS
$cshowList :: forall a. Show a => [RGB a] -> ShowS
show :: RGB a -> String
$cshow :: forall a. Show a => RGB a -> String
showsPrec :: Int -> RGB a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> RGB a -> ShowS
Show, ReadPrec [RGB a]
ReadPrec (RGB a)
ReadS [RGB a]
forall a. Read a => ReadPrec [RGB a]
forall a. Read a => ReadPrec (RGB a)
forall a. Read a => Int -> ReadS (RGB a)
forall a. Read a => ReadS [RGB a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RGB a]
$creadListPrec :: forall a. Read a => ReadPrec [RGB a]
readPrec :: ReadPrec (RGB a)
$creadPrec :: forall a. Read a => ReadPrec (RGB a)
readList :: ReadS [RGB a]
$creadList :: forall a. Read a => ReadS [RGB a]
readsPrec :: Int -> ReadS (RGB a)
$creadsPrec :: forall a. Read a => Int -> ReadS (RGB a)
Read)
instance Functor RGB where
fmap :: forall a b. (a -> b) -> RGB a -> RGB b
fmap a -> b
f (RGB a
r a
g a
b) = forall a. a -> a -> a -> RGB a
RGB (a -> b
f a
r) (a -> b
f a
g) (a -> b
f a
b)
instance Applicative RGB where
pure :: forall a. a -> RGB a
pure a
c = forall a. a -> a -> a -> RGB a
RGB a
c a
c a
c
(RGB a -> b
fr a -> b
fg a -> b
fb) <*> :: forall a b. RGB (a -> b) -> RGB a -> RGB b
<*> (RGB a
r a
g a
b) = forall a. a -> a -> a -> RGB a
RGB (a -> b
fr a
r) (a -> b
fg a
g) (a -> b
fb a
b)
uncurryRGB :: (a -> a -> a -> b) -> RGB a -> b
uncurryRGB :: forall a b. (a -> a -> a -> b) -> RGB a -> b
uncurryRGB a -> a -> a -> b
f (RGB a
r a
g a
b) = a -> a -> a -> b
f a
r a
g a
b
curryRGB :: (RGB a -> b) -> a -> a -> a -> b
curryRGB :: forall a b. (RGB a -> b) -> a -> a -> a -> b
curryRGB RGB a -> b
f a
r a
g a
b = RGB a -> b
f (forall a. a -> a -> a -> RGB a
RGB a
r a
g a
b)
data RGBGamut = RGBGamut {RGBGamut -> RGB (Chromaticity Rational)
primaries :: !(RGB (Chromaticity Rational))
,RGBGamut -> Chromaticity Rational
whitePoint :: !(Chromaticity Rational)
} deriving (RGBGamut -> RGBGamut -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RGBGamut -> RGBGamut -> Bool
$c/= :: RGBGamut -> RGBGamut -> Bool
== :: RGBGamut -> RGBGamut -> Bool
$c== :: RGBGamut -> RGBGamut -> Bool
Eq)
instance Show RGBGamut where
showsPrec :: Int -> RGBGamut -> ShowS
showsPrec Int
d RGBGamut
gamut = Bool -> ShowS -> ShowS
showParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
app_prec) ShowS
showStr
where
showStr :: ShowS
showStr = String -> ShowS
showString String
"mkRGBGamut"
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Show a => Int -> a -> ShowS
showsPrec (Int
app_precforall a. Num a => a -> a -> a
+Int
1) (RGBGamut -> RGB (Chromaticity Rational)
primaries RGBGamut
gamut))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
" " forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Show a => Int -> a -> ShowS
showsPrec (Int
app_precforall a. Num a => a -> a -> a
+Int
1) (RGBGamut -> Chromaticity Rational
whitePoint RGBGamut
gamut))
instance Read RGBGamut where
readsPrec :: Int -> ReadS RGBGamut
readsPrec Int
d String
r = forall a. Bool -> ReadS a -> ReadS a
readParen (Int
d forall a. Ord a => a -> a -> Bool
> Int
app_prec)
(\String
r -> [(RGB (Chromaticity Rational) -> Chromaticity Rational -> RGBGamut
mkRGBGamut RGB (Chromaticity Rational)
p Chromaticity Rational
w,String
t)
|(String
"mkRGBGamut",String
s) <- ReadS String
lex String
r
,(RGB (Chromaticity Rational)
p,String
s0) <- forall a. Read a => Int -> ReadS a
readsPrec (Int
app_precforall a. Num a => a -> a -> a
+Int
1) String
s
,(Chromaticity Rational
w,String
t) <- forall a. Read a => Int -> ReadS a
readsPrec (Int
app_precforall a. Num a => a -> a -> a
+Int
1) String
s0]) String
r
mkRGBGamut :: RGB (Chromaticity Rational)
-> Chromaticity Rational
-> RGBGamut
mkRGBGamut :: RGB (Chromaticity Rational) -> Chromaticity Rational -> RGBGamut
mkRGBGamut = RGB (Chromaticity Rational) -> Chromaticity Rational -> RGBGamut
RGBGamut
primaryMatrix :: (Fractional a) => (RGB (Chromaticity a)) -> [[a]]
primaryMatrix :: forall a. Fractional a => RGB (Chromaticity a) -> [[a]]
primaryMatrix RGB (Chromaticity a)
p =
[[a
xr, a
xg, a
xb]
,[a
yr, a
yg, a
yb]
,[a
zr, a
zg, a
zb]]
where
RGB (a
xr, a
yr, a
zr)
(a
xg, a
yg, a
zg)
(a
xb, a
yb, a
zb) = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Fractional a => Chromaticity a -> (a, a, a)
chromaCoords RGB (Chromaticity a)
p
rgb2xyz :: RGBGamut -> [[Rational]]
rgb2xyz :: RGBGamut -> [[Rational]]
rgb2xyz RGBGamut
space =
forall a. [[a]] -> [[a]]
transpose (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (forall a b. (a -> b) -> [a] -> [b]
map forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Num a => a -> a -> a
(*)) [Rational]
as (forall a. [[a]] -> [[a]]
transpose [[Rational]]
matrix))
where
(Rational
xn, Rational
yn, Rational
zn) = forall a. Fractional a => Chromaticity a -> (a, a, a)
chromaCoords (RGBGamut -> Chromaticity Rational
whitePoint RGBGamut
space)
matrix :: [[Rational]]
matrix = forall a. Fractional a => RGB (Chromaticity a) -> [[a]]
primaryMatrix (RGBGamut -> RGB (Chromaticity Rational)
primaries RGBGamut
space)
as :: [Rational]
as = forall {b}. Num b => [[b]] -> [b] -> [b]
mult (forall {a}. Fractional a => [[a]] -> [[a]]
inverse [[Rational]]
matrix) [Rational
xnforall a. Fractional a => a -> a -> a
/Rational
yn, Rational
1, Rational
znforall a. Fractional a => a -> a -> a
/Rational
yn]
xyz2rgb :: RGBGamut -> [[Rational]]
xyz2rgb :: RGBGamut -> [[Rational]]
xyz2rgb = forall {a}. Fractional a => [[a]] -> [[a]]
inverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. RGBGamut -> [[Rational]]
rgb2xyz
hslsv :: (Fractional a, Ord a) => RGB a -> (a,a,a,a,a)
hslsv :: forall a. (Fractional a, Ord a) => RGB a -> (a, a, a, a, a)
hslsv (RGB a
r a
g a
b) | a
mx forall a. Eq a => a -> a -> Bool
== a
mn = (a
0,a
0,a
mx,a
0 ,a
mx)
| Bool
otherwise = (a
h,a
s,a
l ,a
s0,a
mx)
where
mx :: a
mx = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [a
r,a
g,a
b]
mn :: a
mn = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [a
r,a
g,a
b]
l :: a
l = (a
mxforall a. Num a => a -> a -> a
+a
mn)forall a. Fractional a => a -> a -> a
/a
2
s :: a
s | a
l forall a. Ord a => a -> a -> Bool
<= a
0.5 = (a
mxforall a. Num a => a -> a -> a
-a
mn)forall a. Fractional a => a -> a -> a
/(a
mxforall a. Num a => a -> a -> a
+a
mn)
| Bool
otherwise = (a
mxforall a. Num a => a -> a -> a
-a
mn)forall a. Fractional a => a -> a -> a
/(a
2forall a. Num a => a -> a -> a
-(a
mxforall a. Num a => a -> a -> a
+a
mn))
s0 :: a
s0 = (a
mxforall a. Num a => a -> a -> a
-a
mn)forall a. Fractional a => a -> a -> a
/a
mx
[a
x,a
y,a
z] = forall a. Int -> [a] -> [a]
take Int
3 forall a b. (a -> b) -> a -> b
$ forall a. (a -> Bool) -> [a] -> [a]
dropWhile (forall a. Eq a => a -> a -> Bool
/=a
mx) [a
r,a
g,a
b,a
r,a
g]
Just Int
o = forall a. Eq a => a -> [a] -> Maybe Int
elemIndex a
mx [a
r,a
g,a
b]
h0 :: a
h0 = a
60forall a. Num a => a -> a -> a
*(a
yforall a. Num a => a -> a -> a
-a
z)forall a. Fractional a => a -> a -> a
/(a
mxforall a. Num a => a -> a -> a
-a
mn) forall a. Num a => a -> a -> a
+ a
120forall a. Num a => a -> a -> a
*(forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
o)
h :: a
h | a
h0 forall a. Ord a => a -> a -> Bool
< a
0 = a
h0 forall a. Num a => a -> a -> a
+ a
360
| Bool
otherwise = a
h0
hue :: (Fractional a, Ord a) => RGB a -> a
hue :: forall a. (Fractional a, Ord a) => RGB a -> a
hue RGB a
rgb = a
h
where
(a
h,a
_,a
_,a
_,a
_) = forall a. (Fractional a, Ord a) => RGB a -> (a, a, a, a, a)
hslsv RGB a
rgb
mod1 :: a -> a
mod1 a
x | a
pf forall a. Ord a => a -> a -> Bool
< a
0 = a
pfforall a. Num a => a -> a -> a
+a
1
| Bool
otherwise = a
pf
where
(Integer
_,a
pf) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction a
x