libheif-hs-0.1.0.0: test/Main.hs
{-# LANGUAGE CPP #-}
module Main (main) where
import Codec.HEIF
import Control.Monad
import Data.ByteString qualified as BS
import Data.ByteString.Lazy qualified as BSL
import Data.Map qualified as M
import SampleImage
import System.Directory (doesFileExist)
import System.IO.Temp (withSystemTempFile)
import Test.Hspec
main :: IO ()
main = hspec spec
inWasm :: Bool
#if defined(__wasm32__) || defined(__wasm__) || defined(wasm32_HOST_ARCH)
inWasm = True
#else
inWasm = False
#endif
isHEIFException :: HeifError -> HeifSubError -> HeifException -> Bool
isHEIFException expectedCode expectedSubcode (LibraryException (Library {..})) =
code == expectedCode && subcode == expectedSubcode
isHEIFException _ _ _ = False
-- wasm has a virtual file system, some test steps are not executed there
itOnNative :: String -> Expectation -> Spec
itOnNative label test = it label $ do
when inWasm $ pendingWith "Test not supported on WASM target"
test
spec :: Spec
spec = describe "libheif-hs tests" $ do
describe "HEIF library inclusion" $ do
it "The linked library version is 1.23.1" $ do
x <- heifVersion
x `shouldBe` "1.23.1"
describe "Image RGB decoding" $ do
it "Fails with an empty image" $ do
decodeThrow defaultDecodeOptions mempty
`shouldThrow` isHEIFException HeifErrorInvalidInput HeifSubErrorUnspecified
itOnNative "Can decode a HEIC file to raw RGB pixels and metadata" $ do
let testFile = "./samples/heic-100x100.heic"
exists <- doesFileExist testFile
exists `shouldBe` True
Decoded {..} <- decodeFromFileThrow defaultDecodeOptions testFile
let Image {..} = decodedImage
expectedWidth = 100
expectedHeight = 100
imageWidth `shouldBe` expectedWidth
imageHeight `shouldBe` expectedHeight
it "Can decode HEIC file ByteString to raw RGB pixels and metadata" $ do
Decoded {..} <- decodeThrow defaultDecodeOptions sampleHEICFile
let Image {..} = decodedImage
expectedWidth = 100
expectedHeight = 100
imageWidth `shouldBe` expectedWidth
imageHeight `shouldBe` expectedHeight
BS.length imagePixelsRGB `shouldBe` fromIntegral (expectedWidth * expectedHeight * 3)
BS.unpack (BS.take 10 imagePixelsRGB)
`shouldBe` [59, 130, 246, 59, 130, 246, 59, 130, 246, 59]
let Metadata {..} = decodedMetadata
length metadataBlocks `shouldBe` 1
case M.toList metadataBlocks of
[(_, MetadataBlock {..})] -> do
metadataBlockType `shouldBe` Exif
BS.take 4 metadataBlockData `shouldBe` "Exif"
_ -> pure ()
it "Can decode encoded HEIC file" $ do
decoded <- decodeThrow defaultDecodeOptions sampleHEICFile
encoded <- encodeThrow defaultEncodeOptions decoded
decoded' <- decodeThrow defaultDecodeOptions $ BSL.toStrict encoded
decodedMetadata decoded `shouldBe` decodedMetadata decoded'
let image = decodedImage decoded
image' = decodedImage decoded'
compareNumberOfBytes = 10
imageWidth image `shouldBe` imageWidth image'
imageHeight image `shouldBe` imageHeight image'
-- The sample image contains solid colors in the beginning so we can compare only the first
-- part of the image, otherwise because of compression/decompression differences the RGB
-- data is not be byte-to-byte identical
BS.take compareNumberOfBytes (imagePixelsRGB image)
`shouldBe` BS.take compareNumberOfBytes (imagePixelsRGB image')
itOnNative "Can encode HEIC to file" $ do
withSystemTempFile "test.heic" $ \testFile _ -> do
decoded <- decodeThrow defaultDecodeOptions sampleHEICFile
encodeToFileThrow defaultEncodeOptions testFile decoded
doesFileExist testFile >>= (`shouldBe` True)