packages feed

JuicyPixels-repa 0.6.2 → 0.7

raw patch · 2 files changed

+51/−19 lines, 2 files

Files

Codec/Picture/Repa.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, MultiParamTypeClasses #-}+{-# LANGUAGE EmptyDataDecls, FlexibleInstances, TypeSynonymInstances, MultiParamTypeClasses, ViewPatterns #-} module Codec.Picture.Repa        ( -- * Primitive types and operations          Img, imgData-       , convertImage+       , convertImage, imgToImage        -- * Generic interface        , readImage, decodeImage        -- * Monomorphic image decoding functions@@ -16,6 +16,8 @@        , reverseColorChannel        , flipHorizontally, flipVertically        , vConcat, hConcat+       -- * Saving Images+       , module Codec.Picture.Saving        -- * Internal Functionallity (exported for advanced uses)        , ToRGBAChannels(..)        ) where@@ -27,6 +29,7 @@ import qualified Codec.Picture as P import Codec.Picture hiding (readImage, decodeImage) import Codec.Picture.Types hiding (convertImage)+import Codec.Picture.Saving import qualified Data.Vector.Storable as S import Foreign.ForeignPtr import Data.Word@@ -64,7 +67,7 @@ -- |@toByteString arr@ converts images to bytestrings, which is often useful -- for Gloss. toByteString :: Img a -> B.ByteString-toByteString (Img arr) =+toByteString ((onImg flipVertically . reverseColorChannel) -> Img arr) =   let fp = RF.toForeignPtr arr       (Z :. row :. col :. chan) = extent arr   in BI.fromForeignPtr fp 0 (col * row * chan)@@ -200,7 +203,7 @@  instance ToRGBAChannels PixelYA8 where   toRGBAChannels = promotePixel-  + instance ToRGBAChannels Pixel8 where   toRGBAChannels = promotePixel @@ -228,28 +231,28 @@   convertImage (ImageRGB8 i) = convertImage i   convertImage (ImageRGBA8 i) = convertImage i -- zeroCopyConvert 4 i   convertImage (ImageYCbCr8 i) = convertImage i-  + instance ConvertImage DynamicImage RGB where   convertImage (ImageY8 i) = convertImage i   convertImage (ImageYA8 i) = convertImage i   convertImage (ImageRGB8 i) = convertImage i -- zeroCopyConvert 3 i   convertImage (ImageRGBA8 i) = convertImage i   convertImage (ImageYCbCr8 i) = convertImage i-  + instance ConvertImage DynamicImage R where   convertImage (ImageY8 i) = convertImage i   convertImage (ImageYA8 i) = convertImage i   convertImage (ImageRGB8 i) = convertImage i   convertImage (ImageRGBA8 i) = convertImage i   convertImage (ImageYCbCr8 i) = convertImage i-  + instance ConvertImage DynamicImage G where   convertImage (ImageY8 i) = convertImage i   convertImage (ImageYA8 i) = convertImage i   convertImage (ImageRGB8 i) = convertImage i   convertImage (ImageRGBA8 i) = convertImage i   convertImage (ImageYCbCr8 i) = convertImage i-  + instance ConvertImage DynamicImage B where   convertImage (ImageY8 i) = convertImage i   convertImage (ImageYA8 i) = convertImage i@@ -260,39 +263,54 @@ instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGBA where   convertImage p@(Image w h dat) =     let z = 4-    in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z) -                                    (\(Z :. y :. x :. z') -> getPixel x y (z - z' - 1) p)-  +    in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)+                                    (\(Z :. y :. x :. z') -> getPixel x y z' p)+ instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) RGB where   convertImage p@(Image w h dat) =     let z = 3     in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)-                            (\(Z :. y :. x :. z') -> getPixel x y (z' - z -1) p)+                            (\(Z :. y :. x :. z') -> getPixel x y z' p)  instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) R where   convertImage p@(Image w h dat) =     let z = 1     in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)                             (\(Z :. y :. x :. z) -> getPixel x y 0 p)-       + instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) G where   convertImage p@(Image w h dat) =     let z = 1     in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)                             (\(Z :. y :. x :. z) -> getPixel x y 1 p)-       + instance (ToRGBAChannels a, Pixel a) => ConvertImage (Image a) B where   convertImage p@(Image w h dat) =     let z = 1     in Img $ R.computeS $ R.fromFunction (Z :. h :. w :. z)                             (\(Z :. y :. x :. z) -> getPixel x y 2 p) +-- Convert a repa-based 'Img' to a JuicyPixels Vector-based 'DynaimcImage'.+imgToImage :: Img a -> DynamicImage+imgToImage (Img arr) =+        let e@(Z :. row :. col :. z)  = extent arr+            f co ro =+               let r = R.unsafeIndex arr (Z:.ro:.co:.(max 0 0))+                   g = R.unsafeIndex arr (Z:.ro:.co:.(max 0 1))+                   b = R.unsafeIndex arr (Z:.ro:.co:.(max 0 2))+                   a = if z == 4 then R.unsafeIndex arr (Z:.ro:.co:.3)+                                 else 255+               in PixelRGBA8 r g b a+        in ImageRGBA8 (generateImage f col row)++-- |Flip an image vertically flipVertically :: Array F DIM3 Word8 -> Array F DIM3 Word8 flipVertically rp = (R.computeS $ backpermute e order rp)  where  e@(Z :. row :. col :. z) = extent rp  order (Z :. oldRow :. oldCol :. oldChan) = Z :. row - oldRow - 1 :. oldCol :. oldChan +-- |Flip an image horizontally flipHorizontally :: Array F DIM3 Word8 -> Array F DIM3 Word8 flipHorizontally rp = (R.computeS $ backpermute e order rp)  where@@ -311,13 +329,17 @@         | h < hb    = fb (Z :. h :. w :. d)         | otherwise = fa (Z :. h - hb :. w :. d) -vConcat :: [Array F DIM3 Word8] -> Array F DIM3 Word8+-- |Combines a list of images such that the first image is on top, then+-- the second, and so on.+vConcat :: [Img a] -> Img a vConcat [] = error "vConcat: Can not concat an empty list into a Repa array"-vConcat xs = R.computeS $ Prelude.foldl1 vStack (Prelude.map R.delay xs)+vConcat xs = Img $ R.computeS $ Prelude.foldl1 vStack (Prelude.map (R.delay . imgData) xs) -hConcat :: [Array F DIM3 Word8] -> Array F DIM3 Word8+-- |Combines a list of images such that the first image is on the left, then+-- the second, and so on.+hConcat :: [Img a] -> Img a hConcat [] = error "hConcat: Can not concat an empty list into a Repa array"-hConcat xs = R.computeS $ Prelude.foldl1 hStack (Prelude.map R.delay xs)+hConcat xs = Img $ R.computeS $ Prelude.foldl1 hStack (Prelude.map (R.delay . imgData) xs)  -- |Stack the images horozontally, placing the first image on the left of the second. hStack :: Array R.D DIM3 Word8 -> Array R.D DIM3 Word8 -> Array R.D DIM3 Word8@@ -330,8 +352,12 @@         | c < ca    = fa (Z :. r :. c :. d)         | otherwise = fb (Z :. r :. c - ca :. d) +-- | A histogram is a one dimensional array where each element+-- indicates how many pixels held the value represented by the element's+-- index. type Histogram = R.Array R.D R.DIM1 Word8 +-- | Compute the RGBA historgrams of the image. histograms :: Img a -> (Histogram, Histogram, Histogram, Histogram) histograms (Img arr) =     let (Z:.nrRow:.nrCol:._) = R.extent arr@@ -345,3 +371,9 @@              in (incElem r hR, incElem g hG, incElem b hB, incElem a hA))           (zero,zero,zero,zero)           [ (row,col) | row <- [0..nrRow-1], col <- [0..nrCol-1] ]++-- | Threshold takes an image and a color channel and a level, returning an+-- image with each pixel of that color channel zeroed or saturated+-- depending on if it was @<=@ the bound or not (@>@).+-- threshhold :: Img a -> Int -> Word8 -> Img a+-- threshhold (Img arr) chan level = do
JuicyPixels-repa.cabal view
@@ -1,5 +1,5 @@ Name:                JuicyPixels-repa-Version:             0.6.2+Version:             0.7 Synopsis:            Convenience functions to obtain array representations of images. Description:         This wraps the Juicy.Pixels library to convert into 'Repa' and                       'Data.Vector.Storable' formats.