packages feed

minimung-0.1: Data/Image.hs

{-# LANGUAGE ExistentialQuantification #-}

-- |
-- Module     : Data.Image
-- Maintainer : Yakov Zaytsev <yakov@yakov.cc>
-- Stability  : experimental
--
-- Functional image
--
-- To-Do:
--
-- * ???
-- > type ImageT = Image a -> Image b
--

module Data.Image (
                         Image
                       , ColorC
                       , GrayImage
                       , RGB(..)

                       , (.|)
                       , (*|)

                       , (.-)
                       , (.^)

                       , crop

                       , threshold

                       -- * Geometry
                       , intervalAt

                       -- * Misc
                       , square
                       , inW
                       ) where

import Foreign.Ptr
import Foreign.Storable
import qualified Graphics.UI.GLUT as G (Size(..))
import Data.Word

import Data.Geometry

-- |
-- Image with pixels represented as values of type a.
--
-- To-Do
--
-- *
--
-- > instance Num Image a where
--
-- Or make individual operators (-), (+) etc.
--
-- See also 'RGB'.
--
type Image a = Point -> a
-- XXX
-- data Image a = Image (Point -> a)
--              | Image a `Over` Image


-- | Color index.
type ColorC = Word32

type GrayImage = Image ColorC

class RGB c where
    toRGB :: c -> (ColorC, ColorC, ColorC)

-- class Yuv c where
--     getY :: c -> ColorC

intervalAt :: Int -> Int -> [Int]
intervalAt y windowH = [y - windowH `div` 2 .. y + windowH `div` 2]


type Window = Size

inW :: Point -> Window -> Bool
inW (x, y) (w, h) = x >= 0 && x < w && y >= 0 && y < h

square x = x * x

-- |
(*|) :: (Storable a) => Image a -> (Ptr a, G.Size) -> IO ()
f *| (ptr, G.Size w' h') = do
  sequence_ $ map pokeP ps
      where
          w = fromIntegral w'   -- View pattern
          h = fromIntegral h'
          ps = points $ Rectangle (0, 0) (w - 1, h - 1)   -- [(x, y) | y <- [0 .. h - 1], x <- [0 .. w - 1]]
          pokeP p@(x, y) = let idx = (y * w + x) in pokeElemOff ptr idx $ f p

-- -- |
-- -- Example:
-- --
-- -- > let g = toGray frame
-- -- > withArray (g .| frameSize) -> \gg -> displayPixels frameSize (PixelData Luminance UnsignedByte gg) 
-- --
-- (*|) :: Image a -> Size -> [a]
-- f *| (w, h) = f .| ps
--     where
--         ps = [(x, y) | y <- [0 .. h - 1], x <- [0 .. w - 1]]


-- |
-- ???
(.|) :: Image a -> [Point] -> [a]
f .| ps = map f ps


threshold :: (Ord a, Num a) => a -> Image a -> Image a
threshold t f (x, y)
    | ff < t = 0
    | otherwise = ff
    where
        ff = f (x, y)
-- threshold :: ColorC -> GrayImage -> GrayImage
-- threshold t f (x, y)
--     | ff < t = 0
--     | otherwise = ff
--     where
--         ff = f (x, y)

crop' :: a -> Image a -> Region -> Image a
crop' ff f (Rectangle orig window)
            = g
            where
                g p
                    | p `inW` window = f $ translate orig p
                    | otherwise = ff

crop :: forall a . (Num a) => Image a -> Region -> Image a
crop = crop' 0

(.-) :: (Num a) => Image a -> Image a -> Image a
f .- g = h
   where
       h p = f p - g p

(.^) :: (Num a) => Image a -> Int -> Image a
f .^ 2 = g
       where
           g p = (f p) * (f p)  -- ???