diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # phash
 
+## 0.1.4.1
+
+  * Add support for [webp](https://developers.google.com/speed/webp) images.
+
+## 0.1.4.0
+
+  * Add `hammingDistance` function in `PerceptualHash` module
+
 ## 0.1.3.5
 
   * Allows files to be passed via the command-line
diff --git a/app/Parallel.hs b/app/Parallel.hs
--- a/app/Parallel.hs
+++ b/app/Parallel.hs
@@ -32,9 +32,9 @@
     case hash of
         Right x ->
             pure $ \hashes ->
-                case M.lookup x hashes of
-                    Just others -> M.insert x (fp <| others) hashes
-                    Nothing     -> M.insert x (fp :| []) hashes
+                let go (Just others) = Just (fp <| others)
+                    go Nothing       = Just (fp :| [])
+                    in M.alter go x hashes
         Left err -> putStrLn ("WARNING: skipping " ++ fp ++ "\n" ++ err) $> id
 
 stepMap :: TVar (M.Map Word64 (NonEmpty FilePath)) -> FilePath -> IO ()
diff --git a/bench/Bench.cpphs b/bench/Bench.cpphs
--- a/bench/Bench.cpphs
+++ b/bench/Bench.cpphs
@@ -9,12 +9,14 @@
 import           System.FilePath (takeFileName)
 
 mkBGroup :: NFData a => String -> (FilePath -> IO a) -> Benchmark
-mkBGroup str f = bgroup str (toBench <$> [catPath, frogJpeg, frogPng])
+mkBGroup str f = bgroup str (toBench <$> [catPath, frogJpeg, frogPng, lizTaylorWebp, lizTaylorPng])
 
     where toBench fp = bench (takeFileName fp) $ nfIO (f fp)
           catPath = "demo-data/cat.png"
           frogJpeg = "demo-data/frog.jpeg"
           frogPng = "demo-data/frog.png"
+          lizTaylorWebp = "demo-data/liz-taylor.webp"
+          lizTaylorPng = "demo-data/liz-taylor.png"
 
 main :: IO ()
 main =
diff --git a/demo-data/liz-taylor.png b/demo-data/liz-taylor.png
new file mode 100644
Binary files /dev/null and b/demo-data/liz-taylor.png differ
diff --git a/demo-data/liz-taylor.webp b/demo-data/liz-taylor.webp
new file mode 100644
Binary files /dev/null and b/demo-data/liz-taylor.webp differ
diff --git a/perceptual-hash.cabal b/perceptual-hash.cabal
--- a/perceptual-hash.cabal
+++ b/perceptual-hash.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.0
 name:               perceptual-hash
-version:            0.1.3.5
+version:            0.1.4.1
 license:            BSD3
 license-file:       LICENSE
 copyright:          Copyright: (c) 2019-2020 Vanessa McHale
@@ -16,6 +16,8 @@
     demo-data/frog.png
     demo-data/meme.png
     demo-data/meme-watermark.jpg
+    demo-data/liz-taylor.webp
+    demo-data/liz-taylor.png
 
 extra-source-files: include/hs_phash.h
 extra-doc-files:
@@ -45,16 +47,19 @@
     ghc-options:      -Wall -O2
     build-depends:
         base >=4.8 && <5,
-        hip -any,
-        vector-algorithms -any,
-        vector -any,
-        primitive -any
+        hip,
+        vector-algorithms,
+        vector,
+        primitive,
+        webp,
+        bytestring,
+        JuicyPixels
 
     if flag(llvm)
         ghc-options: -fllvm
 
     if flag(with-phash)
-        pkgconfig-depends: pHash -any
+        pkgconfig-depends: pHash
 
     if flag(with-phash)
         exposed-modules: ForeignHash
@@ -79,8 +84,8 @@
     install-includes: hs_phash.h
     ghc-options:      -Wall
     build-depends:
-        base -any,
-        perceptual-hash -any
+        base,
+        perceptual-hash
 
     lib-version-info: 1:0:0
 
@@ -112,9 +117,9 @@
     ghc-options:      -Wall -threaded -rtsopts "-with-rtsopts=-N -qg"
     build-depends:
         base >=4.9 && <5,
-        perceptual-hash -any,
-        containers -any,
-        filepath -any,
+        perceptual-hash,
+        containers,
+        filepath,
         optparse-applicative >=0.13.0.0,
         par-traverse >=0.2.1.0,
         stm >=2.3
@@ -140,9 +145,9 @@
     default-language: Haskell2010
     ghc-options:      -Wall -threaded -rtsopts "-with-rtsopts=-N -K1K"
     build-depends:
-        base -any,
-        perceptual-hash -any,
-        hspec -any
+        base,
+        perceptual-hash,
+        hspec
 
     if impl(ghc >=8.0)
         ghc-options:
@@ -158,7 +163,7 @@
 benchmark phash-bench
     type:               exitcode-stdio-1.0
     main-is:            Bench.hs
-    build-tool-depends: cpphs:cpphs -any
+    build-tool-depends: cpphs:cpphs
     hs-source-dirs:     bench
     default-language:   Haskell2010
     ghc-options:
@@ -167,11 +172,11 @@
         -Wredundant-constraints
 
     build-depends:
-        base -any,
-        perceptual-hash -any,
-        criterion -any,
-        filepath -any,
-        deepseq -any
+        base,
+        perceptual-hash,
+        criterion,
+        filepath,
+        deepseq
 
     if flag(llvm)
         ghc-options: -fllvm
diff --git a/src/PerceptualHash.hs b/src/PerceptualHash.hs
--- a/src/PerceptualHash.hs
+++ b/src/PerceptualHash.hs
@@ -3,19 +3,35 @@
 
 module PerceptualHash ( imgHash
                       , fileHash
+                      , hammingDistance
                       ) where
 
-import           Control.Monad.ST         (runST)
-import           Data.Bits                (shiftL, (.|.))
-import qualified Data.Vector.Generic      as V
-import           Data.Word                (Word64)
-import           Graphics.Image           (Array, Bilinear (..), Border (Edge, Reflect), Image,
-                                           Pixel (PixelX, PixelY), RSU (..), X, Y, convolve, crop,
-                                           makeImage, readImage, resize, transpose, (|*|))
-import           Graphics.Image.Interface (toVector)
-import qualified Graphics.Image.Interface as Hip
-import           Median                   (median)
+import qualified Codec.Picture                 as JuicyPixels
+import           Codec.Picture.WebP            (decodeRgb8)
+import           Control.Monad.ST              (runST)
+import           Data.Bits                     (Bits, popCount, shiftL, xor, (.|.))
+import qualified Data.ByteString               as BS
+import           Data.List                     (isSuffixOf)
+import qualified Data.Vector.Generic           as V
+import qualified Data.Vector.Storable          as VS
+import           Data.Word                     (Word64, Word8)
+import           Graphics.Image                (Array, Bilinear (..), Border (Edge, Reflect), Image,
+                                                Pixel (PixelX, PixelY), RGB, RSU (..), VS, X, Y,
+                                                convert, convolve, crop, makeImage, readImage,
+                                                resize, transpose, (|*|))
+import           Graphics.Image.Interface      (fromVector, toVector)
+import qualified Graphics.Image.Interface      as Hip
+import           Graphics.Image.Interface.Repa (fromRepaArrayS, toRepaArray)
+import           Median                        (median)
 
+-- | See
+-- [wiki](https://en.wikipedia.org/wiki/Hamming_distance#Algorithm_example).
+--
+-- @since 0.1.4.0
+{-# SPECIALIZE hammingDistance :: Word64 -> Word64 -> Int #-}
+hammingDistance :: Bits a => a -> a -> Int
+hammingDistance x y = popCount (x `xor` y)
+
 dct32 :: (Floating e, Array arr Y e) => Image arr Y e
 dct32 = makeImage (32,32) gen
     where gen (i,j) = PixelY $ sqrt(2/n) * cos((fromIntegral ((2*i) * (j-1)) * pi)/(2*n))
@@ -61,5 +77,24 @@
     let med = medianImmut v
     in V.map (<med) v
 
+fileWebp :: FilePath -> IO (Image VS RGB Word8)
+fileWebp fp = do
+    contents <- BS.readFile fp
+    let (JuicyPixels.Image m n pixels) = decodeRgb8 contents
+    pure $ fromVector (m, n) $ VS.unsafeCast pixels
+
+readWebp :: FilePath -> IO (Image VS Y Double)
+readWebp = fmap convert . fileWebp
+
+-- | @since 0.1.5.0
+fileHashWebp :: FilePath -> IO Word64
+fileHashWebp = fmap (imgHash . convRepa) . readWebp
+    -- faster
+    where convRepa = fromRepaArrayS . toRepaArray
+
 fileHash :: FilePath -> IO (Either String Word64)
-fileHash = fmap (fmap (imgHash :: Image RSU Y Double -> Word64)) . readImage
+fileHash fp | ".webp" `isSuffixOf` fp = pure <$> fileHashWebp fp
+            | otherwise = fileHashHip fp
+
+fileHashHip :: FilePath -> IO (Either String Word64)
+fileHashHip = fmap (fmap (imgHash :: Image RSU Y Double -> Word64)) . readImage
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,5 +1,3 @@
--- vim: syntax=hspec
-
 import           PerceptualHash (fileHash)
 import           Test.Hspec
 
@@ -21,3 +19,8 @@
             actual <- fileHash "demo-data/cat.png"
             expected <- fileHash "demo-data/frog.png"
             actual `shouldSatisfy` (/= expected)
+
+        parallel $ it "should match when same" $ do
+            actual <- fileHash "demo-data/liz-taylor.webp"
+            expected <- fileHash "demo-data/liz-taylor.png"
+            actual `shouldBe` expected
