AC-Colour 1.1.3 → 1.1.4
raw patch · 6 files changed
+132/−34 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Colour.Nonlinear: Colour8_sRGB :: Colour8 -> Colour8_sRGB
+ Data.Colour.Nonlinear: Colour_sRGB :: Colour -> Colour_sRGB
+ Data.Colour.Nonlinear: cdemote_sRGB :: Colour_sRGB -> Colour8_sRGB
+ Data.Colour.Nonlinear: colour_from_sRGB :: Colour_sRGB -> Colour
+ Data.Colour.Nonlinear: colour_to_sRGB :: Colour -> Colour_sRGB
+ Data.Colour.Nonlinear: cpromote_sRGB :: Colour8_sRGB -> Colour_sRGB
+ Data.Colour.Nonlinear: instance Eq Colour8_sRGB
+ Data.Colour.Nonlinear: instance Eq Colour_sRGB
+ Data.Colour.Nonlinear: instance Ord Colour8_sRGB
+ Data.Colour.Nonlinear: instance Ord Colour_sRGB
+ Data.Colour.Nonlinear: instance Show Colour8_sRGB
+ Data.Colour.Nonlinear: instance Show Colour_sRGB
+ Data.Colour.Nonlinear: newtype Colour8_sRGB
+ Data.Colour.Nonlinear: newtype Colour_sRGB
Files
- AC-Colour.cabal +14/−8
- Data/Colour.hs +5/−0
- Data/Colour/Double.hs +16/−9
- Data/Colour/Map.hs +10/−2
- Data/Colour/Nonlinear.hs +62/−0
- Data/Colour/Word8.hs +25/−15
AC-Colour.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.6 Name: AC-Colour -Version: 1.1.3 +Version: 1.1.4 Stability: Experimental Synopsis: Efficient RGB colour types. @@ -10,12 +10,12 @@ both @Double@ and @Word8@ channel types. It implements efficient conversions between the two (GHC-specific), and general arithmetic over colours. - + . Changes: - - * Added (linear) colour map support. - - * Added pack/unpack functions. + . + * Added sRGB support. + . + * Minor documentation improvements. Category: Data, Math, Numerical, Graphics License: BSD3 @@ -23,9 +23,15 @@ Author: Andrew Coppin Maintainer: MathematicalOrchid@hotmail.com Build-Type: Simple -Tested-With: GHC == 6.10.3 +Tested-With: GHC == 7.0.2 Library - Exposed-modules: Data.Colour.Double, Data.Colour.Map, Data.Colour.Word8, Data.Colour.FastFloor, Data.Colour + Exposed-modules: + Data.Colour.Double + Data.Colour.Map + Data.Colour.Word8 + Data.Colour.Nonlinear + Data.Colour.FastFloor + Data.Colour Build-Depends: base >= 4 && < 5, ghc-prim >= 0.1.0.0 && < 0.3 HS-Source-Dirs: .
Data/Colour.hs view
@@ -8,6 +8,11 @@ However, full arithmetic on 'Colour8' is supported anyway, in case anybody wants to work that way. It is slightly less efficient and flexible, however. + + Note that most colour values from external sources are typically + colour values in the non-linear sRGB colour space, rather than the + linear RGB values handled here. See "Data.Colour.Nonlinear" for + conversion functions. -} module Data.Colour
Data/Colour/Double.hs view
@@ -1,19 +1,24 @@ {- | - This module provides 'Colour', which stores RGB (red, green, blue) - colour values where each channel is a @Double@. It also provides - arithmetic over such colours, and a few predefined colours. + This module provides 'Colour', which stores linear RGB + (red, green, blue) colour values where each channel is a 'Double'. + It also provides arithmetic over such colours, and a few predefined + colours. -} module Data.Colour.Double where {- | - The @Colour@ type. Stores a red, a green and a blue component as - strict, unboxed @Double@ values. (So it should be quite efficient - in time and space.) Also provides various class instances for - arithmetic, etc. It is generally assumed that each channel will - have a value somewhere between 0 and 1 at all times. + The main colour type. It stores three channels (red, green and + blue) as linear 'Double' values normally ranging from 0 to 1. + (0 represents minimum intensity, 1 represents maximum. Black is + therefore @Colour 0 0 0@ and white is @Colour 1 1 1@.) - Note that @(*)@ acts channel-wise. This is usually what is wanted. + The channel values are stored as strict, unboxed fields, so + operating on @Colour@s should be quite efficient in time and space. + + The 'Num' and 'Fractional' instances provide arithmetic for + @Colour@s. Note that @(*)@ acts channel-wise; this is usually what + is wanted. -} data Colour = Colour {red, green, blue :: {-# UNPACK #-} !Double} deriving (Eq, Ord, Show) @@ -74,9 +79,11 @@ clip :: Colour -> Colour clip = cmap (min 1 . max 0) +-- | Convert a 'Colour' into a tuple. unpack :: Colour -> (Double, Double, Double) unpack (Colour r g b) = (r, g, b) +-- | Convert a tuple into a 'Colour'. pack :: (Double, Double, Double) -> Colour pack (r, g, b) = Colour r g b
Data/Colour/Map.hs view
@@ -5,8 +5,13 @@ module Data.Colour.Map ( + -- * Utility range_cycle, + + -- * Simple colour range ColourMap, colour_map, + + -- * Repeating colour range FullColourMap (..), full_colour_map ) where @@ -71,8 +76,11 @@ in (1-k) `cscale` c0 + k `cscale` c1 {- | - This is a colour map with has optional repeating behaviour - using 'range_cycle' above. + This is a colour map with has optional repeating behaviour using + 'range_cycle' above. + + Notice that the parameter range that gets repeated need not cover + the entire range of the underlying 'ColourMap'. -} data FullColourMap = SimpleMap ColourMap | -- ^ Colour map which does not repeat.
+ Data/Colour/Nonlinear.hs view
@@ -0,0 +1,62 @@+{- | + Support for the \"sRGB\" colour space. + + This colour space is the /de facto/ standard colour space for + computer data, unless some more specific colour space is explicitly + specified. Unless you know differently, any image data received + from the outside world is probably sRGB, and and data output is + probably expected to be sRGB. + + Unfortunately, sRGB is a non-linear colour space, so it is not + feasible to perform arithmetic in it directly. (The sRGB colour + space basically standardises the defective non-linear behaviour of + obsolete CRT display technology.) +-} + +module Data.Colour.Nonlinear where + +import Data.Word (Word8) -- For Haddock. + +import Data.Colour + +-- * Types + +{- | + Type for holding sRGB colour values (with 'Double' components). + + The standard 'Colour' type is for /linear/ RGB values. This type + is for sRGB colours, which are non-linear. +-} +newtype Colour_sRGB = Colour_sRGB Colour deriving (Eq, Ord, Show) + +{- | + Type for holding sRGB colour values (with 'Word8' components). + + The standard 'Colour8' type is for /linear/ RGB values. This type + is for sRGB colours, which are non-linear. +-} +newtype Colour8_sRGB = Colour8_sRGB Colour8 deriving (Eq, Ord, Show) + +-- * Conversions + +-- | Convert a linear RGB value into a non-linear sRGB value. +colour_to_sRGB :: Colour -> Colour_sRGB +colour_to_sRGB (Colour r g b) = Colour_sRGB (Colour (f r) (f g) (f b)) + where + f :: Double -> Double + f x = if x <= 0.0031308 then 12.92 * x else 1.055 * (x ** (1 / 2.4)) - 0.055 + +-- | Convert from 'Double' components to 'Word8' components. +cdemote_sRGB :: Colour_sRGB -> Colour8_sRGB +cdemote_sRGB (Colour_sRGB c) = Colour8_sRGB (cdemote c) + +-- | Convert from 'Word8' components to 'Double' components. +cpromote_sRGB :: Colour8_sRGB -> Colour_sRGB +cpromote_sRGB (Colour8_sRGB c) = Colour_sRGB (cpromote c) + +-- | Convert a non-linear sRGB value into a linear RGB value. +colour_from_sRGB :: Colour_sRGB -> Colour +colour_from_sRGB (Colour_sRGB (Colour r g b)) = Colour (f r) (f g) (f b) + where + f :: Double -> Double + f x = if x <= 0.04045 then x / 12.92 else ((x + 0.055)/1.055) ** 2.4
Data/Colour/Word8.hs view
@@ -1,13 +1,18 @@ {- | - This module provides 'Colour8', which stores RGB (red, green, blue) - colour values where each channel is a @Word8@. It also provides - arithmetic over such colours, and a few predefined colours. + This module provides 'Colour8', which stores linear RGB (red, + green, blue) colour values where each channel is a @Word8@. It also + provides arithmetic over such colours, and a few predefined + colours. It is the general intention that \"most\" work will be done with - "Data.Colour.Double", with values converted to @Colour8@ only - as a final step. However, full arithmetic is supported anyway, - in case anybody wants to work that way. It is slightly less - efficient and flexible, however. + "Data.Colour.Double", with values converted to @Colour8@ only as a + final step. However, full arithmetic is supported anyway, in case + anybody wants to work that way. It is slightly less efficient and + flexible, however. + + Beware that \"most\" RGB data found in external sources is in the + (non-linear) sRGB colour space, not the /linear/ RGB colour space + used here. See "Data.Colour.Nonlinear" for conversion functions. -} module Data.Colour.Word8 where @@ -15,15 +20,18 @@ import Data.Word {- | - The @Colour@ type. Stores a red, a green and a blue component as - strict, unboxed @Word8@ values. (So it should be quite efficient - in time and space.) Also provides various class instances for - arithmetic, etc. + The integral colour. It stores three channels (red, green and + blue) as linear 'Word8' values ranging from 0 to 255. (0 represents + minimum intensity, 255 represents maximum. Black is therefore + @Colour8 0 0 0@ and white is @Colour8 255 255 255@.) - Note that 0x00 is assumed to mean zero, and 0xFF to mean one. - That means that @(*)@ is slightly slower than you might expect - due to the extra steps required for renormalisation; @(+)@ and - @(-)@ are still efficient, however. + The channel values are stored as strict, unboxed fields, so + operating on @Colour8@s should be quite efficient in time and + space. + + The 'Num' and 'Fractional' instances provide arithmetic for + @Colour8@s. Note that @(*)@ acts channel-wise; this is usually what + is wanted. -} data Colour8 = Colour8 {red8, green8, blue8 :: {-# UNPACK #-} !Word8} deriving (Eq, Ord, Show) @@ -72,9 +80,11 @@ signum = c8map signum fromInteger = grey8 . fromInteger +-- | Convert a 'Colour8' to a tuple. unpack8 :: Colour8 -> (Word8, Word8, Word8) unpack8 (Colour8 r g b) = (r,g,b) +-- | Convert a tuple to a 'Colour8'. pack8 :: (Word8, Word8, Word8) -> Colour8 pack8 (r,g,b) = Colour8 r g b