{-# LANGUAGE MultiParamTypeClasses #-} module RSAGL.Color.RGB (RGB(..), rgb, rgb256, grayscale, greyscale, grayscale256, greyscale256, mapRGB, zipRGB, zipRGB3) where import RSAGL.Math.Types import RSAGL.Color.ColorSpace import RSAGL.Color.Auxiliary import RSAGL.Math.Vector import RSAGL.Math.AbstractVector import Control.DeepSeq import Control.Parallel.Strategies -- | A color in the red-green-blue color space. data RGB = RGB { rgb_red :: {-# UNPACK #-} !RSdouble, rgb_green :: {-# UNPACK #-} !RSdouble, rgb_blue :: {-# UNPACK #-} !RSdouble } deriving (Eq,Ord,Read,Show) instance NFData RGB where instance Xyz RGB where toXYZ c = (rgb_red c,rgb_green c,rgb_blue c) fromXYZ (r,g,b) = RGB r g b instance ColorSpace RGB where affineColorSpaceOf _ = color_space_rgb instance ExportColorCoordinates RGB where exportColorCoordinates (RGB r g b) = transformColorFromTo color_space_rgb $ Point3D r g b instance ImportColorCoordinates RGB where importColorCoordinates f = RGB r g b where Point3D r g b = f color_space_rgb -- | Construct a color from an RGB triple in the range \[0.0..1.0\]. rgb :: (ImportColorCoordinates c) => RSdouble -> RSdouble -> RSdouble -> c rgb r g b = transformColor $ RGB r g b {-# SPECIALIZE rgb :: RSdouble -> RSdouble -> RSdouble -> RGB #-} -- | Construct a color from an RGB triple in the range \[0..255\]. rgb256 :: (ImportColorCoordinates c,Integral i) => i -> i -> i -> c rgb256 r g b = rgb (i2f256 r) (i2f256 g) (i2f256 b) {-# SPECIALIZE rgb256 :: (Integral i) => i -> i -> i -> RGB #-} -- | Construct a gray color from a value in the range -- \[0.0..1.0\]. grayscale :: (ImportColorCoordinates c) => RSdouble -> c grayscale = greyscale {-# SPECIALIZE grayscale :: RSdouble -> RGB #-} greyscale :: (ImportColorCoordinates c) => RSdouble -> c greyscale x = transformColor $ RGB x x x {-# SPECIALIZE greyscale :: RSdouble -> RGB #-} -- | Construct a gray color from a value in the range -- \[0..255\]. grayscale256 :: (Integral i,ImportColorCoordinates c) => i -> c grayscale256 = greyscale256 {-# SPECIALIZE grayscale256 :: (Integral i) => i -> RGB #-} greyscale256 :: (Integral i,ImportColorCoordinates c) => i -> c greyscale256 x = transformColor (rgb256 x x x :: RGB) {-# SPECIALIZE greyscale256 :: (Integral i) => i -> RGB #-} instance AbstractZero RGB where zero = RGB 0 0 0 instance AbstractAdd RGB RGB where add = zipRGB (+) instance AbstractSubtract RGB RGB where sub = zipRGB (-) instance AbstractScale RGB where scalarMultiply d = mapRGB (*d) instance AbstractVector RGB mapRGB :: (RSdouble -> RSdouble) -> RGB -> RGB mapRGB f (RGB r g b) = RGB (f r) (f g) (f b) zipRGB :: (RSdouble -> RSdouble -> RSdouble) -> RGB -> RGB -> RGB zipRGB f (RGB r1 g1 b1) (RGB r2 g2 b2) = RGB (f r1 r2) (f g1 g2) (f b1 b2) -- | A combining function on three RGB values. zipRGB3 :: (RSdouble -> RSdouble -> RSdouble -> RSdouble) -> RGB -> RGB -> RGB -> RGB zipRGB3 f (RGB r1 g1 b1) (RGB r2 g2 b2) (RGB r3 g3 b3) = RGB (f r1 r2 r3) (f g1 g2 g3) (f b1 b2 b3)