{-# LANGUAGE BangPatterns , CPP , RecordWildCards , TypeFamilies , TypeOperators #-} module Vision.Image.HSV.Type ( HSV, HSVPixel (..), HSVDelayed ) where #if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<*>)) #endif import Data.Word import Foreign.Storable (Storable (..)) import Foreign.Ptr (castPtr, plusPtr) import Vision.Image.Class (Pixel (..)) import Vision.Image.Interpolate (Interpolable (..)) import Vision.Image.Type (Manifest, Delayed) data HSVPixel = HSVPixel { hsvHue :: {-# UNPACK #-} !Word8, hsvSat :: {-# UNPACK #-} !Word8 , hsvValue :: {-# UNPACK #-} !Word8 } deriving (Eq, Show) -- | 24 bits (3 * 8 bits) HSV image. -- -- The Hue value is in [0..179], Saturation in [0..255] and Value in [0..255]. -- -- This image type is more respectful to human eye perception of colors and can -- be converted (using 'convert') from 'RGB' images. -- -- Uses equations to convert from and -- to RGB. type HSV = Manifest HSVPixel type HSVDelayed = Delayed HSVPixel instance Storable HSVPixel where sizeOf _ = 3 * sizeOf (undefined :: Word8) {-# INLINE sizeOf #-} alignment _ = alignment (undefined :: Word8) {-# INLINE alignment #-} peek !ptr = let !ptr' = castPtr ptr in HSVPixel <$> peek ptr' <*> peek (ptr' `plusPtr` 1) <*> peek (ptr' `plusPtr` 2) {-# INLINE peek #-} poke !ptr HSVPixel { .. } = let !ptr' = castPtr ptr in poke ptr' hsvHue >> poke (ptr' `plusPtr` 1) hsvSat >> poke (ptr' `plusPtr` 2) hsvValue {-# INLINE poke #-} instance Pixel HSVPixel where type PixelChannel HSVPixel = Word8 pixNChannels _ = 3 {-# INLINE pixNChannels #-} pixIndex !(HSVPixel h _ _) 0 = h pixIndex !(HSVPixel _ s _) 1 = s pixIndex !(HSVPixel _ _ v) _ = v {-# INLINE pixIndex #-} instance Interpolable HSVPixel where interpol f a b = let HSVPixel aHue aSat aVal = a HSVPixel bHue bSat bVal = b in HSVPixel { hsvHue = f aHue bHue, hsvSat = f aSat bSat , hsvValue = f aVal bVal } {-# INLINE interpol #-}