module Data.Colour.SRGB
(Colour, RGB(..)
,sRGB24, sRGBBounded, sRGB
,toSRGB24, toSRGBBounded, toSRGB
,sRGB24shows, sRGB24show
,sRGB24reads, sRGB24read
,sRGBSpace
)
where
import Data.Word (Word8)
import Numeric (readHex, showHex)
import Data.Colour.Internal (quantize)
import Data.Colour.SRGB.Linear
import Data.Colour.RGBSpace hiding (transferFunction)
transferFunction :: a -> a
transferFunction a
lin | a
lin a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
1 = a
1
| a
lin a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0.0031308 = a
12.92a -> a -> a
forall a. Num a => a -> a -> a
*a
lin
| Bool
otherwise = (a
1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
a)a -> a -> a
forall a. Num a => a -> a -> a
*a
lina -> a -> a
forall a. Floating a => a -> a -> a
**(a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
2.4) a -> a -> a
forall a. Num a => a -> a -> a
- a
a
where
a :: a
a = a
0.055
invTransferFunction :: a -> a
invTransferFunction a
nonLin | a
nonLin a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
1 = a
1
| a
nonLin a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0.04045 = a
nonLina -> a -> a
forall a. Fractional a => a -> a -> a
/a
12.92
| Bool
otherwise =
((a
nonLin a -> a -> a
forall a. Num a => a -> a -> a
+ a
a)a -> a -> a
forall a. Fractional a => a -> a -> a
/(a
1 a -> a -> a
forall a. Num a => a -> a -> a
+ a
a))a -> a -> a
forall a. Floating a => a -> a -> a
**a
2.4
where
a :: a
a = a
0.055
sRGB :: (Ord b, Floating b) => b -> b -> b -> Colour b
sRGB :: forall b. (Ord b, Floating b) => b -> b -> b -> Colour b
sRGB = (RGB b -> Colour b) -> b -> b -> b -> Colour b
forall a b. (RGB a -> b) -> a -> a -> a -> b
curryRGB ((b -> b -> b -> Colour b) -> RGB b -> Colour b
forall a b. (a -> a -> a -> b) -> RGB a -> b
uncurryRGB b -> b -> b -> Colour b
forall a. Fractional a => a -> a -> a -> Colour a
rgb (RGB b -> Colour b) -> (RGB b -> RGB b) -> RGB b -> Colour b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> b) -> RGB b -> RGB b
forall a b. (a -> b) -> RGB a -> RGB b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall {a}. (Ord a, Floating a) => a -> a
invTransferFunction)
sRGBBounded :: (Ord b, Floating b, Integral a, Bounded a) =>
a -> a -> a -> Colour b
sRGBBounded :: forall b a.
(Ord b, Floating b, Integral a, Bounded a) =>
a -> a -> a -> Colour b
sRGBBounded a
r' a
g' a
b' = (b -> b -> b -> Colour b) -> RGB b -> Colour b
forall a b. (a -> a -> a -> b) -> RGB a -> b
uncurryRGB b -> b -> b -> Colour b
forall b. (Ord b, Floating b) => b -> b -> b -> Colour b
sRGB ((a -> b) -> RGB a -> RGB b
forall a b. (a -> b) -> RGB a -> RGB b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
forall {a}. Integral a => a -> b
f (a -> a -> a -> RGB a
forall a. a -> a -> a -> RGB a
RGB a
r' a
g' a
b'))
where
f :: a -> b
f a
x' = (a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x'b -> b -> b
forall a. Fractional a => a -> a -> a
/b
m)
m :: b
m = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a
forall a. Bounded a => a
maxBound a -> a -> a
forall a. a -> a -> a
`asTypeOf` a
r'
sRGB24 :: (Ord b, Floating b) => Word8 -> Word8 -> Word8 -> Colour b
sRGB24 :: forall b.
(Ord b, Floating b) =>
Word8 -> Word8 -> Word8 -> Colour b
sRGB24 = Word8 -> Word8 -> Word8 -> Colour b
forall b a.
(Ord b, Floating b, Integral a, Bounded a) =>
a -> a -> a -> Colour b
sRGBBounded
toSRGB :: (Ord b, Floating b) => Colour b -> RGB b
toSRGB :: forall b. (Ord b, Floating b) => Colour b -> RGB b
toSRGB Colour b
c = (b -> b) -> RGB b -> RGB b
forall a b. (a -> b) -> RGB a -> RGB b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall {a}. (Ord a, Floating a) => a -> a
transferFunction (Colour b -> RGB b
forall a. Fractional a => Colour a -> RGB a
toRGB Colour b
c)
toSRGBBounded :: (RealFrac b, Floating b, Integral a, Bounded a) =>
Colour b -> RGB a
toSRGBBounded :: forall b a.
(RealFrac b, Floating b, Integral a, Bounded a) =>
Colour b -> RGB a
toSRGBBounded Colour b
c = (b -> a) -> RGB b -> RGB a
forall a b. (a -> b) -> RGB a -> RGB b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> a
f (Colour b -> RGB b
forall b. (Ord b, Floating b) => Colour b -> RGB b
toSRGB Colour b
c)
where
f :: b -> a
f b
x' = b -> a
forall a1 a. (RealFrac a1, Integral a, Bounded a) => a1 -> a
quantize (b
mb -> b -> b
forall a. Num a => a -> a -> a
*b
x')
m :: b
m = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ a
forall a. Bounded a => a
maxBound a -> a -> a
forall a. a -> a -> a
`asTypeOf` (b -> a
f b
forall a. HasCallStack => a
undefined)
toSRGB24 :: (RealFrac b, Floating b) => Colour b -> RGB Word8
toSRGB24 :: forall b. (RealFrac b, Floating b) => Colour b -> RGB Word8
toSRGB24 = Colour b -> RGB Word8
forall b a.
(RealFrac b, Floating b, Integral a, Bounded a) =>
Colour b -> RGB a
toSRGBBounded
sRGB24shows :: (RealFrac b, Floating b) => Colour b -> ShowS
sRGB24shows :: forall b. (RealFrac b, Floating b) => Colour b -> ShowS
sRGB24shows Colour b
c =
(String
"#"String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall {a}. Integral a => a -> ShowS
showHex2 Word8
r' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall {a}. Integral a => a -> ShowS
showHex2 Word8
g' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> ShowS
forall {a}. Integral a => a -> ShowS
showHex2 Word8
b'
where
RGB Word8
r' Word8
g' Word8
b' = Colour b -> RGB Word8
forall b. (RealFrac b, Floating b) => Colour b -> RGB Word8
toSRGB24 Colour b
c
showHex2 :: a -> ShowS
showHex2 a
x | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0xf = (String
"0"String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ShowS
forall {a}. Integral a => a -> ShowS
showHex a
x
| Bool
otherwise = a -> ShowS
forall {a}. Integral a => a -> ShowS
showHex a
x
sRGB24show :: (RealFrac b, Floating b) => Colour b -> String
sRGB24show :: forall b. (RealFrac b, Floating b) => Colour b -> String
sRGB24show Colour b
x = Colour b -> ShowS
forall b. (RealFrac b, Floating b) => Colour b -> ShowS
sRGB24shows Colour b
x String
""
sRGB24reads :: (Ord b, Floating b) => ReadS (Colour b)
sRGB24reads :: forall b. (Ord b, Floating b) => ReadS (Colour b)
sRGB24reads String
"" = []
sRGB24reads String
x =
[(Word8 -> Word8 -> Word8 -> Colour b
forall b.
(Ord b, Floating b) =>
Word8 -> Word8 -> Word8 -> Colour b
sRGB24 Word8
a Word8
b Word8
c, String
c0)
|(Word8
a,String
a0) <- String -> [(Word8, String)]
forall {a}. (Eq a, Num a) => String -> [(a, String)]
readPair String
x', (Word8
b,String
b0) <- String -> [(Word8, String)]
forall {a}. (Eq a, Num a) => String -> [(a, String)]
readPair String
a0, (Word8
c,String
c0) <- String -> [(Word8, String)]
forall {a}. (Eq a, Num a) => String -> [(a, String)]
readPair String
b0]
where
x' :: String
x' | String -> Char
forall a. HasCallStack => [a] -> a
head String
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'#' = ShowS
forall a. HasCallStack => [a] -> [a]
tail String
x
| Bool
otherwise = String
x
readPair :: String -> [(a, String)]
readPair [] = []
readPair [Char
_] = []
readPair String
a = [(a
x,String
a1)|(a
x,String
"") <- String -> [(a, String)]
forall {a}. (Eq a, Num a) => String -> [(a, String)]
readHex String
a0]
where
(String
a0,String
a1) = Int -> String -> (String, String)
forall a. Int -> [a] -> ([a], [a])
splitAt Int
2 String
a
sRGB24read :: (Ord b, Floating b) => String -> (Colour b)
sRGB24read :: forall b. (Ord b, Floating b) => String -> Colour b
sRGB24read String
x | [(Colour b, String)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Colour b, String)]
rx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
1 Bool -> Bool -> Bool
|| Bool -> Bool
not (String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ((Colour b, String) -> String
forall a b. (a, b) -> b
snd ([(Colour b, String)] -> (Colour b, String)
forall a. HasCallStack => [a] -> a
head [(Colour b, String)]
rx))) =
String -> Colour b
forall a. HasCallStack => String -> a
error String
"Data.Colour.SRGB.sRGB24read: no parse"
| Bool
otherwise = (Colour b, String) -> Colour b
forall a b. (a, b) -> a
fst ([(Colour b, String)] -> (Colour b, String)
forall a. HasCallStack => [a] -> a
head [(Colour b, String)]
rx)
where
rx :: [(Colour b, String)]
rx = ReadS (Colour b)
forall b. (Ord b, Floating b) => ReadS (Colour b)
sRGB24reads String
x
sRGBSpace :: (Ord a, Floating a) => RGBSpace a
sRGBSpace :: forall a. (Ord a, Floating a) => RGBSpace a
sRGBSpace = RGBGamut -> TransferFunction a -> RGBSpace a
forall a. RGBGamut -> TransferFunction a -> RGBSpace a
mkRGBSpace RGBGamut
sRGBGamut TransferFunction a
transfer
where
transfer :: TransferFunction a
transfer = (a -> a) -> (a -> a) -> a -> TransferFunction a
forall a. (a -> a) -> (a -> a) -> a -> TransferFunction a
TransferFunction a -> a
forall {a}. (Ord a, Floating a) => a -> a
transferFunction a -> a
forall {a}. (Ord a, Floating a) => a -> a
invTransferFunction (a -> a
forall a. Fractional a => a -> a
recip a
2.2)