module Data.Colour.SRGB
(Colour, RGB(..)
,sRGB24, sRGBBounded, sRGB
,toSRGB24, toSRGBBounded, toSRGB
,sRGB24shows, sRGB24show
,sRGB24reads, sRGB24read
,sRGBSpace
)
where
import Data.Word
import Numeric
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 :: 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 (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 :: 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 (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 :: 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 :: Colour b -> RGB b
toSRGB Colour b
c = (b -> b) -> RGB b -> 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 :: Colour b -> RGB a
toSRGBBounded Colour b
c = (b -> a) -> RGB b -> RGB a
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 :: 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 :: Colour b -> ShowS
sRGB24shows Colour b
c =
([Char]
"#"[Char] -> 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, Show 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, Show 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, Show 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 = ([Char]
"0"[Char] -> 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, Show a) => a -> ShowS
showHex a
x
| Bool
otherwise = a -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex a
x
sRGB24show :: (RealFrac b, Floating b) => Colour b -> String
sRGB24show :: Colour b -> [Char]
sRGB24show Colour b
x = Colour b -> ShowS
forall b. (RealFrac b, Floating b) => Colour b -> ShowS
sRGB24shows Colour b
x [Char]
""
sRGB24reads :: (Ord b, Floating b) => ReadS (Colour b)
sRGB24reads :: ReadS (Colour b)
sRGB24reads [Char]
"" = []
sRGB24reads [Char]
x =
[(Word8 -> Word8 -> Word8 -> Colour b
forall b.
(Ord b, Floating b) =>
Word8 -> Word8 -> Word8 -> Colour b
sRGB24 Word8
a Word8
b Word8
c, [Char]
c0)
|(Word8
a,[Char]
a0) <- [Char] -> [(Word8, [Char])]
forall a. (Eq a, Num a) => [Char] -> [(a, [Char])]
readPair [Char]
x', (Word8
b,[Char]
b0) <- [Char] -> [(Word8, [Char])]
forall a. (Eq a, Num a) => [Char] -> [(a, [Char])]
readPair [Char]
a0, (Word8
c,[Char]
c0) <- [Char] -> [(Word8, [Char])]
forall a. (Eq a, Num a) => [Char] -> [(a, [Char])]
readPair [Char]
b0]
where
x' :: [Char]
x' | [Char] -> Char
forall a. [a] -> a
head [Char]
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'#' = ShowS
forall a. [a] -> [a]
tail [Char]
x
| Bool
otherwise = [Char]
x
readPair :: [Char] -> [(a, [Char])]
readPair [] = []
readPair [Char
_] = []
readPair [Char]
a = [(a
x,[Char]
a1)|(a
x,[Char]
"") <- [Char] -> [(a, [Char])]
forall a. (Eq a, Num a) => [Char] -> [(a, [Char])]
readHex [Char]
a0]
where
([Char]
a0,[Char]
a1) = Int -> [Char] -> ([Char], [Char])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
2 [Char]
a
sRGB24read :: (Ord b, Floating b) => String -> (Colour b)
sRGB24read :: [Char] -> Colour b
sRGB24read [Char]
x | [(Colour b, [Char])] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Colour b, [Char])]
rx Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
1 Bool -> Bool -> Bool
|| Bool -> Bool
not ([Char] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ((Colour b, [Char]) -> [Char]
forall a b. (a, b) -> b
snd ([(Colour b, [Char])] -> (Colour b, [Char])
forall a. [a] -> a
head [(Colour b, [Char])]
rx))) =
[Char] -> Colour b
forall a. HasCallStack => [Char] -> a
error [Char]
"Data.Colour.SRGB.sRGB24read: no parse"
| Bool
otherwise = (Colour b, [Char]) -> Colour b
forall a b. (a, b) -> a
fst ([(Colour b, [Char])] -> (Colour b, [Char])
forall a. [a] -> a
head [(Colour b, [Char])]
rx)
where
rx :: [(Colour b, [Char])]
rx = ReadS (Colour b)
forall b. (Ord b, Floating b) => ReadS (Colour b)
sRGB24reads [Char]
x
sRGBSpace :: (Ord a, Floating a) => RGBSpace a
sRGBSpace :: 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)