{-# LANGUAGE ViewPatterns #-} module Vision.Image.JuicyPixels where import Vision.Image import Vision.Primitive import Codec.Picture as JP import Foreign.ForeignPtr import Data.Vector.Storable as V fcast :: Vector (PixelBaseComponent Pixel8) -> Vector GreyPixel fcast v = unsafeFromForeignPtr (castForeignPtr fp) o l where (fp,o,l) = unsafeToForeignPtr v jcast :: Vector GreyPixel -> Vector (PixelBaseComponent Pixel8) jcast v = unsafeFromForeignPtr (castForeignPtr fp) o l where (fp,o,l) = unsafeToForeignPtr v -- XXX friday is 4 bytes per elem (1/4 the elem) while JP is 1 byte per -- elem for 4x the length! We can make fcast total at -- the cost of an O(n) copy. Do so and document. jcastRGBA :: Vector RGBAPixel -> Vector (PixelBaseComponent PixelRGBA8) jcastRGBA v = unsafeFromForeignPtr (castForeignPtr fp) (4*o) (4*l) where (fp,o,l) = unsafeToForeignPtr v fcastRGBA :: Vector (PixelBaseComponent PixelRGBA8) -> Vector RGBAPixel fcastRGBA v | o `rem` 4 /= 0 = error "Can not cast a JuicyPixel image constructed via a vector with non zero offset (mod 4)." | otherwise = unsafeFromForeignPtr (castForeignPtr fp) (o`div`4) (l`div`4) where (fp,o,l) = unsafeToForeignPtr v jcastRGB :: Vector RGBPixel -> Vector (PixelBaseComponent PixelRGB8) jcastRGB v = unsafeFromForeignPtr (castForeignPtr fp) (3*o) (3*l) where (fp,o,l) = unsafeToForeignPtr v fcastRGB :: Vector (PixelBaseComponent PixelRGB8) -> Vector RGBPixel fcastRGB v | o `rem` 3 /= 0 = error "Can not cast a JuicyPixel image constructed via a vector with non zero offset (mod 3)." | otherwise = unsafeFromForeignPtr (castForeignPtr fp) (o`div`3) (l`div`3) where (fp,o,l) = unsafeToForeignPtr v toFridayGrey :: JP.Image Pixel8 -> Grey toFridayGrey (JP.Image w h vec) = Manifest (Z :. h :. w) (fcast vec) toJuicyGrey :: Grey -> JP.Image Pixel8 toJuicyGrey (compute -> Manifest (Z :. h :. w) vec) = JP.Image w h (jcast vec) toFridayRGB :: JP.Image PixelRGB8 -> RGB toFridayRGB (JP.Image w h vec) = Manifest (Z :. h :. w) (fcastRGB vec) toJuicyRGB :: RGB -> JP.Image PixelRGB8 toJuicyRGB (compute -> Manifest (Z :. h :. w) vec) = JP.Image w h (jcastRGB vec) toFridayRGBA :: JP.Image PixelRGBA8 -> RGBA toFridayRGBA (JP.Image w h vec) = Manifest (Z :. h :. w) (fcastRGBA vec) toJuicyRGBA :: RGBA -> JP.Image PixelRGBA8 toJuicyRGBA (compute -> Manifest (Z :. h :. w) vec) = JP.Image w h (jcastRGBA vec)