packages feed

hip 1.5.5.0 → 1.5.6.0

raw patch · 4 files changed

+116/−17 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Graphics.Image.Processing: Bicubic :: Double -> Bicubic
+ Graphics.Image.Processing: newtype Bicubic

Files

CHANGELOG.md view
@@ -1,3 +1,8 @@+1.5.6.0+=======++* Addition of Bicubic interpolation (Thanks to @kirisaki)+ 1.5.5.0 ======= 
hip.cabal view
@@ -1,5 +1,5 @@ Name:              hip-Version:           1.5.5.0+Version:           1.5.6.0 License:           BSD3 License-File:      LICENSE Author:            Alexey Kuleshevich
src/Graphics/Image/Processing/Interpolation.hs view
@@ -10,7 +10,7 @@ -- Portability : non-portable -- module Graphics.Image.Processing.Interpolation (-  Interpolation(..), Nearest(..), Bilinear(..)+  Interpolation(..), Nearest(..), Bilinear(..), Bicubic(..)   ) where  import Graphics.Image.Interface@@ -38,16 +38,21 @@ data Bilinear = Bilinear deriving Show  +-- | Bicubic interpolation method.+--   The parameter is usually set from -0.5 to -1.0.+newtype Bicubic = Bicubic Double deriving Show++ instance Interpolation Nearest where -  interpolate Nearest border !sz getPx !(i, j) =+  interpolate Nearest border !sz getPx (i, j) =     handleBorderIndex border sz getPx (round i, round j)   {-# INLINE interpolate #-}   instance Interpolation Bilinear where -  interpolate Bilinear border !sz getPx !(i, j) = fi0 + jPx*(fi1-fi0) where+  interpolate Bilinear border !sz getPx (i, j) = fi0 + jPx*(fi1-fi0) where     getPx' = handleBorderIndex border sz getPx     {-# INLINE getPx' #-}     !(i0, j0) = (floor i, floor j)@@ -60,4 +65,86 @@     !f11 = getPx' (i1, j1)     !fi0 = f00 + iPx*(f10-f00)     !fi1 = f01 + iPx*(f11-f01)+  {-# INLINE interpolate #-}+++instance Interpolation Bicubic where++  interpolate (Bicubic a) border !sz getPx (i, j) =+      ( f00 + f10 + f20 + f30+      + f01 + f11 + f21 + f31+      + f02 + f12 + f22 + f32+      + f03 + f13 + f23 + f33 ) * promote (fromDouble (1 / w))+    where+      getPx' = handleBorderIndex border sz getPx+      {-# INLINE getPx' #-}+      distX x = fromIntegral x - i+      {-# INLINE distX #-}+      distY y = fromIntegral y - j+      {-# INLINE distY #-}+      weight x+          | x' <= 1 = ((a + 2) * x' - (a + 3)) * x2' + 1+          | x' <  2 = a * ((x2' - 5 * x' + 8) * x' - 4)+          | otherwise = 0+          where x' = abs x+                x2' = x' * x'+      {-# INLINE weight #-}+      !(i0, j0) = (i1 - 1, j1 - 1)+      !(i1, j1) = (floor i, floor j)+      !(i2, j2) = (i1 + 1, j1 + 1)+      !(i3, j3) = (i1 + 2, j1 + 2)++      !weightX0 = weight (distX i0)+      !weightX1 = weight (distX i1)+      !weightX2 = weight (distX i2)+      !weightX3 = weight (distX i3)+      !weightY0 = weight (distY j0)+      !weightY1 = weight (distY j1)+      !weightY2 = weight (distY j2)+      !weightY3 = weight (distY j3)++      !weightX0Y0 = weightX0 * weightY0+      !weightX1Y0 = weightX1 * weightY0+      !weightX2Y0 = weightX2 * weightY0+      !weightX3Y0 = weightX3 * weightY0++      !weightX0Y1 = weightX0 * weightY1+      !weightX1Y1 = weightX1 * weightY1+      !weightX2Y1 = weightX2 * weightY1+      !weightX3Y1 = weightX3 * weightY1++      !weightX0Y2 = weightX0 * weightY2+      !weightX1Y2 = weightX1 * weightY2+      !weightX2Y2 = weightX2 * weightY2+      !weightX3Y2 = weightX3 * weightY2++      !weightX0Y3 = weightX0 * weightY3+      !weightX1Y3 = weightX1 * weightY3+      !weightX2Y3 = weightX2 * weightY3+      !weightX3Y3 = weightX3 * weightY3++      !f00 = getPx' (i0, j0) * promote (fromDouble weightX0Y0)+      !f10 = getPx' (i1, j0) * promote (fromDouble weightX1Y0)+      !f20 = getPx' (i2, j0) * promote (fromDouble weightX2Y0)+      !f30 = getPx' (i3, j0) * promote (fromDouble weightX3Y0)++      !f01 = getPx' (i0, j1) * promote (fromDouble weightX0Y1)+      !f11 = getPx' (i1, j1) * promote (fromDouble weightX1Y1)+      !f21 = getPx' (i2, j1) * promote (fromDouble weightX2Y1)+      !f31 = getPx' (i3, j1) * promote (fromDouble weightX3Y1)++      !f02 = getPx' (i0, j2) * promote (fromDouble weightX0Y2)+      !f12 = getPx' (i1, j2) * promote (fromDouble weightX1Y2)+      !f22 = getPx' (i2, j2) * promote (fromDouble weightX2Y2)+      !f32 = getPx' (i3, j2) * promote (fromDouble weightX3Y2)++      !f03 = getPx' (i0, j3) * promote (fromDouble weightX0Y3)+      !f13 = getPx' (i1, j3) * promote (fromDouble weightX1Y3)+      !f23 = getPx' (i2, j3) * promote (fromDouble weightX2Y3)+      !f33 = getPx' (i3, j3) * promote (fromDouble weightX3Y3)++      !w = weightX0Y0 + weightX1Y0 + weightX2Y0 + weightX3Y0+         + weightX0Y1 + weightX1Y1 + weightX2Y1 + weightX3Y1+         + weightX0Y2 + weightX1Y2 + weightX2Y2 + weightX3Y2+         + weightX0Y3 + weightX1Y3 + weightX2Y3 + weightX3Y3   {-# INLINE interpolate #-}
tests/Graphics/Image/ProcessingSpec.hs view
@@ -13,17 +13,20 @@ data Interpol   = I1 Nearest   | I2 Bilinear+  | I3 Bicubic  instance Show Interpol where   show (I1 i) = "I1 " ++ show i   show (I2 i) = "I2 " ++ show i+  show (I3 i) = "I3 " ++ show i  instance Arbitrary Interpol where   arbitrary = do     ix <- arbitrary-    case ix `mod` (2 :: Int) of+    case ix `mod` (3 :: Int) of       0 -> return $ I1 Nearest       1 -> return $ I2 Bilinear+      2 -> I3 . Bicubic <$> pure (-1) -- choose (-1, -0.5)       _ -> error $ "Unknown interpolation: " ++ show ix  @@ -71,21 +74,25 @@   rotate90 (leftToRight img $ rotate180 img)  -prop_rotate90 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Bool-prop_rotate90 (I1 i) border img = rotate90 img == rotate i border (pi/2) img-prop_rotate90 (I2 i) border img = rotate90 img == rotate i border (pi/2) img+prop_rotate90 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Property+prop_rotate90 (I1 i) border img = rotate90 img === rotate i border (pi/2) img+prop_rotate90 (I2 i) border img = rotate90 img === rotate i border (pi/2) img+prop_rotate90 (I3 i) border img = rotate90 img === rotate i border (pi/2) img -prop_rotate180 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Bool-prop_rotate180 (I1 i) border img = rotate180 img == rotate i border pi img-prop_rotate180 (I2 i) border img = rotate180 img == rotate i border pi img+prop_rotate180 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Property+prop_rotate180 (I1 i) border img = rotate180 img === rotate i border pi img+prop_rotate180 (I2 i) border img = rotate180 img === rotate i border pi img+prop_rotate180 (I3 i) border img = rotate180 img === rotate i border pi img -prop_rotate270 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Bool-prop_rotate270 (I1 i) border img = rotate270 img == rotate i border (3*pi/2) img-prop_rotate270 (I2 i) border img = rotate270 img == rotate i border (3*pi/2) img+prop_rotate270 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Property+prop_rotate270 (I1 i) border img = rotate270 img === rotate i border (3*pi/2) img+prop_rotate270 (I2 i) border img = rotate270 img === rotate i border (3*pi/2) img+prop_rotate270 (I3 i) border img = rotate270 img === rotate i border (3*pi/2) img -prop_rotate360 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Bool-prop_rotate360 (I1 i) border img = (rotate270 . rotate90) img == rotate i border (2*pi) img-prop_rotate360 (I2 i) border img = (rotate270 . rotate90) img == rotate i border (2*pi) img+prop_rotate360 :: Interpol -> Border (Pixel RGB Double) -> Image VU RGB Double -> Property+prop_rotate360 (I1 i) border img = (rotate270 . rotate90) img === rotate i border (2*pi) img+prop_rotate360 (I2 i) border img = (rotate270 . rotate90) img === rotate i border (2*pi) img+prop_rotate360 (I3 i) border img = (rotate270 . rotate90) img === rotate i border (2*pi) img   struct :: Image VS X Bit