packages feed

hip 1.0.1 → 1.0.1.1

raw patch · 10 files changed

+131/−53 lines, 10 filesbinary-addedPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Graphics.Image.Interface.Repa: fromRepaArray :: (ColorSpace cs, Unbox (PixelElt cs e)) => Array D DIM2 (Pixel cs e) -> Image RD cs e
+ Graphics.Image.Interface.Repa: toRepaArray :: (ColorSpace cs, Unbox (PixelElt cs e)) => Image RD cs e -> Array D DIM2 (Pixel cs e)
+ Graphics.Image.Processing: rotate :: (Array arr cs e, Elevator e, Interpolation method) => method (Pixel cs e) -> Double -> Image arr cs e -> Image arr cs e

Files

hip.cabal view
@@ -1,5 +1,5 @@ Name:              hip-Version:           1.0.1+Version:           1.0.1.1 License:           BSD3 License-File:      LICENSE Author:            Alexey Kuleshevich
+ images/frog_rotate330.png view

binary file changed (absent → 446222 bytes)

src/Graphics/Image.hs view
@@ -10,11 +10,11 @@ -- -- Haskell Image Processing (HIP) library is a wrapper around any array like -- data structure and is fully agnostic to the underlying representation. All of--- the functionality in this library relies on few type classes that+-- the functionality in this library relies upon a few type classes, which -- corresponding representation types are instances of: ----- * @__`Graphics.Image.Types.Array` arr cs e__@ - this is a base class for every--- __@`Graphics.Image.Types.Image`@ @arr@ @cs@ @e@__, where @__arr__@ stands for an underlying array+-- * @__`Array` arr cs e__@ - this is a base class for every+-- __@`Image`@ @arr@ @cs@ @e@__, where @__arr__@ stands for an underlying array -- representation, @__cs__@ is the `ColorSpace` of an image and @__e__@ is the -- type denoting precision of an image. --@@ -116,7 +116,7 @@  import Graphics.Image.Processing import Graphics.Image.Processing.Complex---import Graphics.Image.Processing.Binary+import Graphics.Image.Processing.Geometric import Graphics.Image.IO.Histogram  
src/Graphics/Image/IO.hs view
@@ -199,61 +199,61 @@    * 'BMP': -    * __in__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')-    * __out__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')+    * __read__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')+    * __write__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')  * 'GIF': -    * __in__: ('RGB'  'Word8'), ('RGBA'  'Word8')-    * __out__: ('RGB'  'Word8')+    * __read__: ('RGB'  'Word8'), ('RGBA'  'Word8')+    * __write__: ('RGB'  'Word8')     * Also supports reading and writing animated images, when used as @['GIF']@  * 'HDR': -    * __in__: ('RGB'  'Float')-    * __out__: ('RGB'  'Float')+    * __read__: ('RGB'  'Float')+    * __write__: ('RGB'  'Float')  * 'JPG': -    * __in__: ('Y' 'Word8'), ('YA' 'Word8'), ('RGB'  'Word8'), ('CMYK'  'Word8'),+    * __read__: ('Y' 'Word8'), ('YA' 'Word8'), ('RGB'  'Word8'), ('CMYK'  'Word8'),     ('YCbCr', 'Word8')-    * __out__: ('Y' 'Word8'), ('YA', 'Word8'), ('RGB'  'Word8'), ('CMYK'  'Word8'),+    * __write__: ('Y' 'Word8'), ('YA', 'Word8'), ('RGB'  'Word8'), ('CMYK'  'Word8'),     ('YCbCr', 'Word8')  * 'PNG': -    * __in__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),+    * __read__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),     ('RGB'  'Word8'), ('RGB'  'Word16'), ('RGBA'  'Word8'), ('RGBA'  'Word16')-    * __out__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),+    * __write__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),     ('RGB'  'Word8'), ('RGB'  'Word16'), ('RGBA'  'Word8'), ('RGBA'  'Word16')  * 'TGA': -    * __in__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')-    * __out__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')+    * __read__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')+    * __write__: ('Y' 'Word8'), ('RGB'  'Word8'), ('RGBA'  'Word8')  * 'TIF': -    * __in__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),+    * __read__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),     ('RGB'  'Word8'), ('RGB'  'Word16'), ('RGBA'  'Word8'), ('RGBA'  'Word16'),     ('CMYK'  'Word8'), ('CMYK'  'Word16')-    * __out__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),+    * __write__: ('Y' 'Word8'), ('Y' 'Word16'), ('YA' 'Word8'), ('YA' 'Word16'),     ('RGB'  'Word8'), ('RGB'  'Word16'), ('RGBA'  'Word8'), ('RGBA'  'Word16')     ('CMYK'  'Word8'), ('CMYK'  'Word16'), ('YCbCr'  'Word8')  * 'PBM': -    * __in__: ('Binary' 'Bit')+    * __read__: ('Binary' 'Bit')     * Also supports sequence of images in one file, when read as @['PBM']@  * 'PGM': -    * __in__: ('Y' 'Word8'), ('Y' 'Word16')+    * __read__: ('Y' 'Word8'), ('Y' 'Word16')     * Also supports sequence of images in one file, when read as @['PGM']@  * 'PPM': -    * __in__: ('RGB'  'Word8'), ('RGB'  'Word16')+    * __read__: ('RGB'  'Word8'), ('RGB'  'Word16')     * Also supports sequence of images in one file, when read as @['PPM']@  -}
src/Graphics/Image/IO/External/JuicyPixels.hs view
@@ -506,7 +506,7 @@ -- PNG Format Reading  instance (Array arr Y Word8, Array arr Binary Bit) => Readable (Image arr Binary Bit) PNG where-  decode _ = either Left (Right . toImageBinary) . jpImageY8ToImage . JP.decodePng+  decode _ = fmap toImageBinary . jpImageY8ToImage . JP.decodePng  instance Array arr Y Word8 => Readable (Image arr Y Word8) PNG where   decode _ = jpImageY8ToImage . JP.decodePng@@ -548,7 +548,7 @@ -- TGA Format Reading  instance (Array arr Y Word8, Array arr Binary Bit) => Readable (Image arr Binary Bit) TGA where-  decode _ = either Left (Right . toImageBinary) . jpImageY8ToImage . JP.decodeTga+  decode _ = fmap toImageBinary . jpImageY8ToImage . JP.decodeTga  instance Array arr Y Word8 => Readable (Image arr Y Word8) TGA where   decode _ = jpImageY8ToImage . JP.decodeTga@@ -575,7 +575,7 @@ -- TIF Format Reading  instance (Array arr Y Word8, Array arr Binary Bit) => Readable (Image arr Binary Bit) TIF where-  decode _ = either Left (Right . toImageBinary) . jpImageY8ToImage . JP.decodeTiff+  decode _ = fmap toImageBinary . jpImageY8ToImage . JP.decodeTiff  instance Array arr Y Word8 => Readable (Image arr Y Word8) TIF where   decode _ = jpImageY8ToImage . JP.decodeTiff@@ -926,13 +926,10 @@   encode _ opts = encodeJPG opts ((convert :: Pixel RGB Word8 -> JP.PixelRGB8)                                   . toWord8)  -instance ManifestArray arr CMYK Double => Writable (Image arr CMYK Double) JPG where-  encode _ opts = encodeJPG opts ((convert :: Pixel CMYK Word8 -> JP.PixelCMYK8)-                                  . toWord8) +instance ManifestArray arr RGBA Double => Writable (Image arr RGBA Double) JPG where+  encode _ opts = encodeJPG opts ((convert :: Pixel RGB Word8 -> JP.PixelRGB8)+                                  . toWord8 . dropAlpha)  -instance ManifestArray arr YCbCr Double => Writable (Image arr YCbCr Double) JPG where-  encode _ opts = encodeJPG opts ((convert :: Pixel YCbCr Word8 -> JP.PixelYCbCr8)-                                  . toWord8)   -- Writable PNG 
src/Graphics/Image/Interface/Repa.hs view
@@ -16,6 +16,8 @@   computeS, computeP, delay,   -- * Representation   RD(..), RS(..), RP(..),+  -- * Conversion+  fromRepaArray, toRepaArray   ) where  import Graphics.Image.IO
src/Graphics/Image/Interface/Repa/Internal.hs view
@@ -11,7 +11,8 @@ -- Portability : non-portable -- module Graphics.Image.Interface.Repa.Internal (-  RD(..), RP(..), RS(..), computeP, computeS, delay+  RD(..), RP(..), RS(..), computeP, computeS, delay,+  fromRepaArray, toRepaArray   ) where  #if MIN_VERSION_base(4,8,0)@@ -223,12 +224,12 @@    index (RSImage (RUImage arr)) (i, j) = R.index arr (Z :. i :. j)   index (RSImage (RScalar px))  (_, _) = px-  index _ _ = _error_compute+  index _ _ = _errorCompute   {-# INLINE index #-}    deepSeqImage (RSImage (RUImage arr)) = deepSeqArray arr   deepSeqImage (RSImage (RScalar px))  = seq px-  deepSeqImage _ = _error_compute+  deepSeqImage _ = _errorCompute   {-# INLINE deepSeqImage #-}    (|*|) i1@(RSImage img1) i2@(RSImage img2) =@@ -237,11 +238,11 @@    fold !f !px0 (RSImage (RUImage arr)) = R.foldAllS f px0 $ arr   fold !f !px0 (RSImage (RScalar px))  = f px0 px-  fold _  _  _ = _error_compute+  fold _  _  _ = _errorCompute   {-# INLINE fold #-}    eq (RSImage (RUImage arr1)) (RSImage (RUImage arr2)) = R.equalsS arr1 arr2-  eq _ _ = _error_compute+  eq _ _ = _errorCompute   {-# INLINE eq #-}  @@ -250,12 +251,12 @@   index (RPImage (RUImage arr)) (i, j) = R.index arr (Z :. i :. j)   index (RPImage (RScalar px))  (0, 0) = px   index (RPImage (RScalar _))   (_, _) = error "Scalar Image can only be indexed at (0,0)."-  index _ _ = _error_compute+  index _ _ = _errorCompute   {-# INLINE index #-}    deepSeqImage (RPImage (RUImage arr)) = deepSeqArray arr   deepSeqImage (RPImage (RScalar px))  = seq px-  deepSeqImage _ = _error_compute+  deepSeqImage _ = _errorCompute   {-# INLINE deepSeqImage #-}    (|*|) i1@(RPImage img1) i2@(RPImage img2) =@@ -264,11 +265,11 @@    fold !f !px0 (RPImage (RUImage arr)) = head . R.foldAllP f px0 $ arr   fold !f !px0 (RPImage (RScalar px))  = f px0 px-  fold _  _  _ = _error_compute+  fold _  _  _ = _errorCompute   {-# INLINE fold #-}    eq (RPImage (RUImage arr1)) (RPImage (RUImage arr2)) = head $ R.equalsP arr1 arr2-  eq _ _ = _error_compute+  eq _ _ = _errorCompute   {-# INLINE eq #-}    @@ -379,7 +380,7 @@ instance Exchangable RS VU where   exchange _ img@(RSImage (RUImage arr)) = fromUnboxedVector (dims img) (R.toUnboxed arr)   exchange _ (RSImage (RScalar px)) = singleton px-  exchange _ _                     = _error_compute+  exchange _ _                     = _errorCompute   {-# INLINE exchange #-}  @@ -387,7 +388,7 @@ instance Exchangable RP VU where   exchange _ img@(RPImage (RUImage arr)) = fromUnboxedVector (dims img) (R.toUnboxed arr)   exchange _ (RPImage (RScalar px)) = singleton px-  exchange _ _                     = _error_compute+  exchange _ _                     = _errorCompute   {-# INLINE exchange #-}  -- | Computes an image in parallel and ensures that all elements are evaluated.@@ -424,7 +425,7 @@     getPx (Z :. i :. j) =       sumAllS (slice arr1 (Any :. (i :: Int) :. All) *^ slice arr2 (Any :. (j :: Int)))     {-# INLINE getPx #-}-mult _ _ = _error_compute+mult _ _ = _errorCompute {-# INLINE mult #-}  @@ -450,13 +451,25 @@ getDelayed _             = error "Scalar image is not an array." {-# INLINE getDelayed #-} ++-- | Create an image from a 2D Repa delayed array.+fromRepaArray :: (ColorSpace cs, Unbox (PixelElt cs e)) =>+                 R.Array D DIM2 (Pixel cs e) -> Image RD cs e+fromRepaArray = RDImage+++-- | Retrieve an underlying Repa array from `RD` image type.+toRepaArray :: (ColorSpace cs, Unbox (PixelElt cs e)) =>+               Image RD cs e -> R.Array D DIM2 (Pixel cs e)+toRepaArray (RUImage arr) = R.delay arr+toRepaArray (RDImage arr) = arr+toRepaArray (RScalar px) = R.fromFunction (Z :. 1 :. 1) $ const px   -_error_compute :: t-_error_compute = error "Image should be computed at ths point. Please report this error"+_errorCompute :: t+_errorCompute = error "Image should be computed at ths point. Please report this error"                          -_error_scalar_op :: t-_error_scalar_op =-  error "This operation is not allowed on scalar images."+_errorScalarOp :: t+_errorScalarOp = error "This operation is not allowed on scalar images."   instance R.Elt Bit where
src/Graphics/Image/Processing/Binary.hs view
@@ -35,7 +35,12 @@  -- | 'Thresholding' contains a convenient set of functions for binary image -- construction, which is done by comparing either a single pixel with every--- pixel in an image or two same size images pointwise.+-- pixel in an image or two same size images pointwise. For example:+--+-- >>> frog <- readImageY "images/frog.jpg"+-- >>> frog .==. PixelY 0    -- (or: PixelY 0 .==. frog)+-- >>> frog .<. flipH frog   -- (or: flipH frog .>. frog)+-- class Array arr Binary Bit => Thresholding a b arr | a b -> arr where   (.==.) :: (Eq (Pixel cs e), Array arr cs e)  => a cs e -> b cs e -> Image arr Binary Bit   (./=.) :: (Eq (Pixel cs e), Array arr cs e)  => a cs e -> b cs e -> Image arr Binary Bit@@ -119,7 +124,7 @@ {-# INLINE (.||.) #-}  --- | Complement each pixel in the image+-- | Complement each pixel in a binary image invert :: Array arr Binary Bit => Image arr Binary Bit -> Image arr Binary Bit invert = map complement {-# INLINE invert #-}
src/Graphics/Image/Processing/Geometric.hs view
@@ -18,7 +18,7 @@   -- ** Flipping   flipV, flipH,   -- ** Rotation-  rotate90, rotate180, rotate270,+  rotate90, rotate180, rotate270, rotate,   -- ** Scaling   resize, scale                                             ) where@@ -115,6 +115,7 @@   {-# INLINE newPx #-} {-# INLINE topToBottom #-} + -- | Crop an image, i.e. retrieves a sub-image image with @m@ rows and @n@ -- columns. Make sure @(m + i, n + j)@ is not greater than dimensions of a -- source image.@@ -193,6 +194,39 @@ {-# INLINE rotate270 #-}  ++-- | Rotate an image clockwise by an angle Θ in radians.+--+-- >>> frog <- readImageRGBA "images/frog.jpg"+-- >>> writeImage "images/frog_rotate330.png" $ rotate (Bilinear (Fill 0)) (11*pi/6) frog+--+-- <<images/frog.jpg>> <<images/frog_rotate330.png>>+--+rotate :: (Array arr cs e, Elevator e, Interpolation method) =>+          method (Pixel cs e) -- ^ Interpolation method to be used+       -> Double -- ^ Angle in radians+       -> Image arr cs e -- ^ Source image+       -> Image arr cs e -- ^ Rotated image+rotate !method !theta' !img = traverse img getNewDims getNewPx where+  !theta = angle0to2pi (-theta') -- invert angle direction and put it into [0, 2*pi) range+  !sz@(m, n) = dims img+  !(mD, nD) = (fromIntegral m, fromIntegral n)+  !(sinTheta, cosTheta) = (sin' theta, cos' theta)+  !(sinThetaAbs, cosThetaAbs) = (abs sinTheta, abs cosTheta)+  !(mD', nD') = (mD * cosThetaAbs + nD * sinThetaAbs, nD * cosThetaAbs + mD * sinThetaAbs)+  !(iDelta, jDelta) =+    case (sinTheta >= 0, cosTheta >= 0) of+         (True         , True         ) -> (nD * sinTheta, 0)    -- I quadrant+         (True         , False        ) -> (mD', -nD * cosTheta) -- II quadrant+         (False        , False        ) -> (-mD * cosTheta, nD') -- III quadrant+         (False        , True         ) -> (0, -mD * sinTheta)   -- IV quadrant+  getNewDims _ = (ceiling mD', ceiling nD')+  getNewPx getPx (i, j) = interpolate method sz getPx (i', j') where+    (iD, jD) = (fromIntegral i - iDelta + 0.5, fromIntegral j - jDelta + 0.5)+    i' = iD * cosTheta + jD * sinTheta - 0.5+    j' = jD * cosTheta - iD * sinTheta - 0.5++ -- | Resize an image using an interpolation method. -- -- >>> frog <- readImageRGB "images/frog.jpg"@@ -204,7 +238,7 @@           method (Pixel cs e) -- ^ Interpolation method to be used during scaling.        -> (Int, Int)     -- ^ Dimensions of a result image.        -> Image arr cs e -- ^ Source image.-       -> Image arr cs e -- ^ Reuslt image.+       -> Image arr cs e -- ^ Result image. resize !method !sz'@(m', n') !img = traverse img (const sz') getNewPx where   !sz@(m, n) = dims img   !(fM, fN) = (fromIntegral m' / fromIntegral m, fromIntegral n' / fromIntegral n)@@ -229,3 +263,28 @@   then error "scale: scaling factor must be greater than 0."   else resize method (round (fM * fromIntegral m), round (fN * fromIntegral n)) img {-# INLINE scale #-}++++-- | Put an angle into @[0, 2*pi)@ range.+angle0to2pi :: Double -> Double+angle0to2pi !f = f - 2 * pi * floor' (f / (2 * pi))+ where  floor' :: Double -> Double+        floor' !x = fromIntegral (floor x :: Int)+        {-# INLINE floor' #-}+{-# INLINE angle0to2pi #-}+++-- | Make sure @sin' pi == 0@ instead of @sin pi == 1.2246467991473532e-16@+sin' :: Double -> Double+sin' a = if abs sinA <= _0 then 0 else sinA+  where !_0   = 10 * sin pi+        !sinA = sin a+{-# INLINE sin' #-}+++-- | Make sure @cos' (pi/2) == 0@ instead of @cos (pi/2) == 6.123233995736766e-17@+-- and @cos' (3*pi/2) == 0@ instead of @cos (3*pi/2) == -1.8369701987210297e-16@+cos' :: Double -> Double+cos' a = sin' (a + pi/2)+{-# INLINE cos' #-}
src/Graphics/Image/Types.hs view
@@ -8,9 +8,10 @@ -- module Graphics.Image.Types (   module Graphics.Image.ColorSpace,+  module Graphics.Image.IO.External,   Array, Image, ManifestArray, SequentialArray, MutableArray, MImage,   Exchangable, Border(..),-  VU(..), RD(..), RS(..), RP(..), +  VU(..), RD(..), RS(..), RP(..),   ) where  @@ -18,3 +19,4 @@ import Graphics.Image.Interface import Graphics.Image.Interface.Vector (VU(..)) import Graphics.Image.Interface.Repa (RD(..), RS(..), RP(..))+import Graphics.Image.IO.External