module Vision.Image.Grey.Conversion () where
import Data.Convertible (Convertible (..))
import qualified Data.Vector.Storable as V
import Data.Word
import Vision.Image.Grey.Type (GreyPixel (..))
import Vision.Image.RGBA.Type (RGBAPixel (..))
import Vision.Image.RGB.Type (RGBPixel (..))
instance Convertible GreyPixel GreyPixel where
safeConvert = Right
instance Convertible RGBAPixel GreyPixel where
safeConvert !(RGBAPixel r g b a) =
Right $ GreyPixel $ word8 $ int (rgbToGrey r g b) * int a `quot` 255
instance Convertible RGBPixel GreyPixel where
safeConvert !(RGBPixel r g b) =
Right $ GreyPixel $ rgbToGrey r g b
rgbToGrey :: Word8 -> Word8 -> Word8 -> Word8
rgbToGrey !r !g !b = (redLookupTable V.! int r)
+ (greenLookupTable V.! int g)
+ (blueLookupTable V.! int b)
redLookupTable, greenLookupTable, blueLookupTable :: V.Vector Word8
redLookupTable = V.generate 256 (\val -> round $ double val * 0.299)
greenLookupTable = V.generate 256 (\val -> round $ double val * 0.587)
blueLookupTable = V.generate 256 (\val -> round $ double val * 0.114)
double :: Integral a => a -> Double
double = fromIntegral
int :: Integral a => a -> Int
int = fromIntegral
word8 :: Integral a => a -> Word8
word8 = fromIntegral