diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## Juicy Pixels Extra 0.5.2
+
+* Replacing CPP preprocessing rules with expicit SPECIALIZE pragmas. [See PR
+  26](https://github.com/mrkkrp/JuicyPixels-extra/pull/26).
+
 ## Juicy Pixels Extra 0.5.1
 
 * `scaleBilinear` no longer hangs when the target width or height is 0.
diff --git a/Codec/Picture/Extra.hs b/Codec/Picture/Extra.hs
--- a/Codec/Picture/Extra.hs
+++ b/Codec/Picture/Extra.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
@@ -81,23 +80,19 @@
                 `addp` mulp (pixelAt' (x + 1) (y + 1)) (δx * δy)
             go (x' + 1) y'
     go 0 0
-
-#define scaleBilinear_spec(pixel) \
-{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image pixel -> Image pixel #-}
-
-scaleBilinear_spec (M.PixelRGBA16)
-scaleBilinear_spec (M.PixelRGBA8)
-scaleBilinear_spec (M.PixelCMYK16)
-scaleBilinear_spec (M.PixelCMYK8)
-scaleBilinear_spec (M.PixelYCbCr8)
-scaleBilinear_spec (M.PixelRGB16)
-scaleBilinear_spec (M.PixelYCbCrK8)
-scaleBilinear_spec (M.PixelRGB8)
-scaleBilinear_spec (M.PixelYA16)
-scaleBilinear_spec (M.PixelYA8)
-scaleBilinear_spec (M.Pixel32)
-scaleBilinear_spec (M.Pixel16)
-scaleBilinear_spec (M.Pixel8)
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelRGBA16 -> Image M.PixelRGBA16 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelRGBA8 -> Image M.PixelRGBA8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelCMYK16 -> Image M.PixelCMYK16 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelCMYK8 -> Image M.PixelCMYK8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelYCbCr8 -> Image M.PixelYCbCr8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelRGB16 -> Image M.PixelRGB16 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelYCbCrK8 -> Image M.PixelYCbCrK8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelRGB8 -> Image M.PixelRGB8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelYA16 -> Image M.PixelYA16 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.PixelYA8 -> Image M.PixelYA8 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.Pixel32 -> Image M.Pixel32 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.Pixel16 -> Image M.Pixel16 #-}
+{-# SPECIALIZE scaleBilinear :: Int -> Int -> Image M.Pixel8 -> Image M.Pixel8 #-}
 
 mulp :: (Pixel a, Integral (PixelBaseComponent a)) => a -> Float -> a
 mulp pixel x = colorMap (floor . (* x) . fromIntegral) pixel
diff --git a/JuicyPixels-extra.cabal b/JuicyPixels-extra.cabal
--- a/JuicyPixels-extra.cabal
+++ b/JuicyPixels-extra.cabal
@@ -1,11 +1,11 @@
 cabal-version:   1.18
 name:            JuicyPixels-extra
-version:         0.5.1
+version:         0.5.2
 license:         BSD3
 license-file:    LICENSE.md
 maintainer:      Mark Karpov <markkarpov92@gmail.com>
 author:          Mark Karpov <markkarpov92@gmail.com>
-tested-with:     ghc ==8.8.4 ghc ==8.10.4 ghc ==9.0.1
+tested-with:     ghc ==8.8.4 ghc ==8.10.5 ghc ==9.0.1
 homepage:        https://github.com/mrkkrp/JuicyPixels-extra
 bug-reports:     https://github.com/mrkkrp/JuicyPixels-extra/issues
 synopsis:        Efficiently scale, crop, flip images with JuicyPixels
