{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NegativeLiterals #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} -- | -- Module : Graphics.Color.Space.RGB.ITU.Rec601 -- Copyright : (c) Alexey Kuleshevich 2019-2020 -- License : BSD3 -- Maintainer : Alexey Kuleshevich -- Stability : experimental -- Portability : non-portable -- module Graphics.Color.Space.RGB.ITU.Rec601 ( pattern BT601_525 , BT601_525 , pattern BT601_625 , BT601_625 , D65 , primaries525 , primaries625 , transfer , itransfer , module Graphics.Color.Space ) where import Data.Coerce import Data.Typeable import Foreign.Storable import Graphics.Color.Illuminant.ITU.Rec601 import Graphics.Color.Model.Internal import qualified Graphics.Color.Model.RGB as CM import Graphics.Color.Space import Graphics.Color.Space.RGB.ITU.Rec470 (primaries625) import Graphics.Color.Space.RGB.Luma ------------------------------------ -- ITU-R BT.601 (525) -------------- ------------------------------------ -- | [ITU-R BT.601](https://en.wikipedia.org/wiki/Rec._601) (525) color space data BT601_525 (l :: Linearity) newtype instance Color (BT601_525 l) e = BT601_525 (Color CM.RGB e) -- | ITU-R BT.601 (525) color space deriving instance Eq e => Eq (Color (BT601_525 l) e) -- | ITU-R BT.601 (525) color space deriving instance Ord e => Ord (Color (BT601_525 l) e) -- | ITU-R BT.601 (525) color space deriving instance Functor (Color (BT601_525 l)) -- | ITU-R BT.601 (525) color space deriving instance Applicative (Color (BT601_525 l)) -- | ITU-R BT.601 (525) color space deriving instance Foldable (Color (BT601_525 l)) -- | ITU-R BT.601 (525) color space deriving instance Traversable (Color (BT601_525 l)) -- | ITU-R BT.601 (525) color space deriving instance Storable e => Storable (Color (BT601_525 l) e) -- | ITU-R BT.601 (525) color space instance (Typeable l, Elevator e) => Show (Color (BT601_525 l) e) where showsPrec _ = showsColorModel -- | ITU-R BT.601 (525) color space instance (Typeable l, Elevator e) => ColorModel (BT601_525 l) e where type Components (BT601_525 l) e = (e, e, e) toComponents = toComponents . unColorRGB {-# INLINE toComponents #-} fromComponents = mkColorRGB . fromComponents {-# INLINE fromComponents #-} -- | ITU-R BT.601 (525) linear color space instance Elevator e => ColorSpace (BT601_525 'Linear) D65 e where type BaseModel (BT601_525 'Linear) = CM.RGB toBaseSpace = id {-# INLINE toBaseSpace #-} fromBaseSpace = id {-# INLINE fromBaseSpace #-} luminance = rgbLinearLuminance . fmap toRealFloat {-# INLINE luminance #-} toColorXYZ = rgbLinear2xyz . fmap toRealFloat {-# INLINE toColorXYZ #-} fromColorXYZ = fmap fromRealFloat . xyz2rgbLinear {-# INLINE fromColorXYZ #-} -- | ITU-R BT.601 (525) linear color space instance Elevator e => ColorSpace (BT601_525 'NonLinear) D65 e where type BaseModel (BT601_525 'NonLinear) = CM.RGB toBaseSpace = id {-# INLINE toBaseSpace #-} fromBaseSpace = id {-# INLINE fromBaseSpace #-} luminance = rgbLuminance . fmap toRealFloat {-# INLINE luminance #-} toColorXYZ = rgb2xyz . fmap toRealFloat {-# INLINE toColorXYZ #-} fromColorXYZ = fmap fromRealFloat . xyz2rgb {-# INLINE fromColorXYZ #-} -- | ITU-R BT.601 (525) color space instance RedGreenBlue BT601_525 D65 where gamut = primaries525 ecctf = BT601_525 . fmap transfer . coerce {-# INLINE ecctf #-} dcctf = BT601_525 . fmap itransfer . coerce {-# INLINE dcctf #-} ------------------------------------ -- ITU-R BT.601 (625) -------------- ------------------------------------ -- | [ITU-R BT.601](https://en.wikipedia.org/wiki/Rec._601) (625) color space data BT601_625 (l :: Linearity) newtype instance Color (BT601_625 l) e = BT601_625 (Color CM.RGB e) -- | ITU-R BT.601 (625) color space deriving instance Eq e => Eq (Color (BT601_625 l) e) -- | ITU-R BT.601 (625) color space deriving instance Ord e => Ord (Color (BT601_625 l) e) -- | ITU-R BT.601 (625) color space deriving instance Functor (Color (BT601_625 l)) -- | ITU-R BT.601 (625) color space deriving instance Applicative (Color (BT601_625 l)) -- | ITU-R BT.601 (625) color space deriving instance Foldable (Color (BT601_625 l)) -- | ITU-R BT.601 (625) color space deriving instance Traversable (Color (BT601_625 l)) -- | ITU-R BT.601 (625) color space deriving instance Storable e => Storable (Color (BT601_625 l) e) -- | ITU-R BT.601 (625) color space instance (Typeable l, Elevator e) => Show (Color (BT601_625 l) e) where showsPrec _ = showsColorModel -- | ITU-R BT.601 (625) color space instance (Typeable l, Elevator e) => ColorModel (BT601_625 l) e where type Components (BT601_625 l) e = (e, e, e) toComponents = toComponents . unColorRGB {-# INLINE toComponents #-} fromComponents = mkColorRGB . fromComponents {-# INLINE fromComponents #-} -- | ITU-R BT.601 (625) linear color space instance Elevator e => ColorSpace (BT601_625 'Linear) D65 e where type BaseModel (BT601_625 'Linear) = CM.RGB toBaseSpace = id {-# INLINE toBaseSpace #-} fromBaseSpace = id {-# INLINE fromBaseSpace #-} luminance = rgbLinearLuminance . fmap toRealFloat {-# INLINE luminance #-} toColorXYZ = rgbLinear2xyz . fmap toRealFloat {-# INLINE toColorXYZ #-} fromColorXYZ = fmap fromRealFloat . xyz2rgbLinear {-# INLINE fromColorXYZ #-} -- | ITU-R BT.601 (625) color space instance Elevator e => ColorSpace (BT601_625 'NonLinear) D65 e where type BaseModel (BT601_625 'NonLinear) = CM.RGB toBaseSpace = id {-# INLINE toBaseSpace #-} fromBaseSpace = id {-# INLINE fromBaseSpace #-} luminance = rgbLuminance . fmap toRealFloat {-# INLINE luminance #-} toColorXYZ = rgb2xyz . fmap toRealFloat {-# INLINE toColorXYZ #-} fromColorXYZ = fmap fromRealFloat . xyz2rgb {-# INLINE fromColorXYZ #-} -- | ITU-R BT.601 (625) color space instance RedGreenBlue BT601_625 D65 where gamut = primaries625 ecctf = BT601_625 . fmap transfer . coerce {-# INLINE ecctf #-} dcctf = BT601_625 . fmap itransfer . coerce {-# INLINE dcctf #-} instance Luma BT601_525 where rWeight = 0.299 gWeight = 0.587 bWeight = 0.114 instance Luma BT601_625 where rWeight = 0.299 gWeight = 0.587 bWeight = 0.114 -- | Rec.601 transfer function "gamma". This is a helper function, therefore `ecctf` should be used -- instead. -- -- \[ -- \gamma(L) = \begin{cases} -- 4.500 L & L \le 0.018 \\ -- 1.099 L^{0.45} - 0.099 & \text{otherwise} -- \end{cases} -- \] -- -- @since 0.1.0 transfer :: (Ord a, Floating a) => a -> a transfer l | l < 0.018 = 4.5 * l | otherwise = 1.099 * (l ** 0.45 {- ~ 1 / 2.2 -}) - 0.099 {-# INLINE transfer #-} -- | Rec.601 inverse transfer function "gamma". This is a helper function, therefore `dcctf` should -- be used instead. -- -- \[ -- \gamma^{-1}(E) = \begin{cases} -- E / 4.5 & E \leq gamma(0.018) \\ -- \left(\tfrac{E + 0.099}{1.099}\right)^{\frac{1}{0.45}} & \text{otherwise} -- \end{cases} -- \] -- -- @since 0.1.0 itransfer :: (Ord a, Floating a) => a -> a itransfer e | e < inv0018 = e / 4.5 | otherwise = ((e + 0.099) / 1.099) ** (1 / 0.45) where !inv0018 = transfer 0.018 -- ~ 0.081 {-# INLINE itransfer #-} -- | Primaries for ITU-R BT.601 (525). -- -- @since 0.1.0 primaries525 :: RealFloat e => Gamut rgb i e primaries525 = Gamut (Primary 0.630 0.340) (Primary 0.310 0.595) (Primary 0.155 0.070)