avif 0.1.2.1 → 1.0.0.0
raw patch · 4 files changed
+34/−14 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Codec.Avif.FFI: AvifPixelFormatCount :: AvifPixelFormat
- Codec.Avif.FFI: AvifPixelFormatNone :: AvifPixelFormat
- Codec.Avif.FFI: AvifPixelFormatYuv400 :: AvifPixelFormat
- Codec.Avif.FFI: AvifPixelFormatYuv420 :: AvifPixelFormat
- Codec.Avif.FFI: AvifPixelFormatYuv422 :: AvifPixelFormat
- Codec.Avif.FFI: AvifPixelFormatYuv444 :: AvifPixelFormat
- Codec.Avif.FFI: AvifResultBmffParseFailed :: AvifResult
- Codec.Avif.FFI: AvifResultCannotChangeSetting :: AvifResult
- Codec.Avif.FFI: AvifResultColorAlphaSizeMismatch :: AvifResult
- Codec.Avif.FFI: AvifResultDecodeAlphaFailed :: AvifResult
- Codec.Avif.FFI: AvifResultDecodeColorFailed :: AvifResult
- Codec.Avif.FFI: AvifResultEncodeAlphaFailed :: AvifResult
- Codec.Avif.FFI: AvifResultEncodeColorFailed :: AvifResult
- Codec.Avif.FFI: AvifResultIncompatibleImage :: AvifResult
- Codec.Avif.FFI: AvifResultInvalidArgument :: AvifResult
- Codec.Avif.FFI: AvifResultInvalidCodecSpecificOption :: AvifResult
- Codec.Avif.FFI: AvifResultInvalidExifPayload :: AvifResult
- Codec.Avif.FFI: AvifResultInvalidFtyp :: AvifResult
- Codec.Avif.FFI: AvifResultInvalidImageGrid :: AvifResult
- Codec.Avif.FFI: AvifResultIoError :: AvifResult
- Codec.Avif.FFI: AvifResultIoNotSet :: AvifResult
- Codec.Avif.FFI: AvifResultIspeSizeMismatch :: AvifResult
- Codec.Avif.FFI: AvifResultNoAv1ItemsFound :: AvifResult
- Codec.Avif.FFI: AvifResultNoCodecAvailable :: AvifResult
- Codec.Avif.FFI: AvifResultNoContent :: AvifResult
- Codec.Avif.FFI: AvifResultNoImagesRemaining :: AvifResult
- Codec.Avif.FFI: AvifResultNoYuvFormatSelected :: AvifResult
- Codec.Avif.FFI: AvifResultNotImplemented :: AvifResult
- Codec.Avif.FFI: AvifResultOk :: AvifResult
- Codec.Avif.FFI: AvifResultOutOfMemory :: AvifResult
- Codec.Avif.FFI: AvifResultReformatFailed :: AvifResult
- Codec.Avif.FFI: AvifResultTruncatedData :: AvifResult
- Codec.Avif.FFI: AvifResultUnknownError :: AvifResult
- Codec.Avif.FFI: AvifResultUnsupportedDepth :: AvifResult
- Codec.Avif.FFI: AvifResultWaitingOnIo :: AvifResult
- Codec.Avif.FFI: avifDecoderCreate :: IO (Ptr AvifDecoder)
- Codec.Avif.FFI: avifDecoderDestroy :: FinalizerPtr ()
- Codec.Avif.FFI: avifDecoderReadMemory :: AvifDecoderPtr -> AvifImagePtr -> Ptr UInt8 -> CSize -> IO AvifResult
- Codec.Avif.FFI: avifEncoderCreate :: IO (Ptr AvifEncoder)
- Codec.Avif.FFI: avifEncoderDestroy :: FinalizerPtr ()
- Codec.Avif.FFI: avifEncoderWrite :: AvifEncoderPtr -> AvifImagePtr -> Ptr AvifRwData -> IO AvifResult
- Codec.Avif.FFI: avifImageCreate :: CInt -> CInt -> CInt -> AvifPixelFormat -> IO (Ptr AvifImage)
- Codec.Avif.FFI: avifImageCreateEmpty :: IO (Ptr AvifImage)
- Codec.Avif.FFI: avifImageDestroy :: FinalizerPtr ()
- Codec.Avif.FFI: avifImageRGBToYUV :: AvifImagePtr -> Ptr AvifRGBImage -> IO AvifResult
- Codec.Avif.FFI: avifImageYUVToRGB :: AvifImagePtr -> Ptr AvifRGBImage -> IO AvifResult
- Codec.Avif.FFI: avifRGBImageAllocatePixels :: Ptr AvifRGBImage -> IO ()
- Codec.Avif.FFI: avifRGBImageFreePixels :: Ptr AvifRGBImage -> IO ()
- Codec.Avif.FFI: avifRGBImagePixelSize :: Ptr AvifRGBImage -> IO UInt32
- Codec.Avif.FFI: avifRGBImageSetDefaults :: Ptr AvifRGBImage -> AvifImagePtr -> IO ()
- Codec.Avif.FFI: data AvifPixelFormat
- Codec.Avif.FFI: data AvifResult
- Codec.Avif.FFI: instance GHC.Classes.Eq Codec.Avif.FFI.AvifResult
- Codec.Avif.FFI: instance GHC.Enum.Enum Codec.Avif.FFI.AvifPixelFormat
- Codec.Avif.FFI: instance GHC.Enum.Enum Codec.Avif.FFI.AvifResult
- Codec.Avif.FFI: instance GHC.Exception.Type.Exception Codec.Avif.FFI.AvifResult
- Codec.Avif.FFI: instance GHC.Show.Show Codec.Avif.FFI.AvifResult
+ Codec.Avif: AvifResultDecodeGainMapFailed :: AvifResult
+ Codec.Avif: AvifResultEncodeGainMapFailed :: AvifResult
+ Codec.Avif: AvifResultInternalError :: AvifResult
+ Codec.Avif: AvifResultInvalidToneMappedImage :: AvifResult
+ Codec.Avif: AvifResultMissingImageItem :: AvifResult
+ Codec.Avif: ImageRGBA16 :: Image PixelRGBA16 -> RgbImage
+ Codec.Avif: ImageRGBA8 :: Image PixelRGBA8 -> RgbImage
+ Codec.Avif: data RgbImage
- Codec.Avif: decode :: ByteString -> Image PixelRGBA8
+ Codec.Avif: decode :: ByteString -> RgbImage
- Codec.Avif: decodeE :: ByteString -> Either AvifResult (Image PixelRGBA8)
+ Codec.Avif: decodeE :: ByteString -> Either AvifResult RgbImage
Files
- CHANGELOG.md +2/−2
- avif.cabal +1/−1
- src/Codec/Avif.chs +17/−8
- test/Spec.hs +14/−3
CHANGELOG.md view
@@ -1,8 +1,8 @@ # avif -# 0.1.2.1+# 1.0.0.0 - * Remove deprecated function under the hood+ * Change signature of `decode` and `decodeE` to handle 16-bit images. # 0.1.2.0
avif.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: avif-version: 0.1.2.1+version: 1.0.0.0 license: AGPL-3 license-file: LICENSE copyright: Copyright: (c) 2021 Vanessa McHale
src/Codec/Avif.chs view
@@ -2,16 +2,18 @@ , decode , decodeE , AvifResult (..)+ , RgbImage (..) ) where import Codec.Avif.FFI-import Codec.Picture (Image (Image), PixelRGBA8)+import Codec.Picture (Image (Image), PixelRGBA8, PixelRGBA16) import Control.Exception (throw, throwIO) import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BS import Foreign.Ptr (castPtr) import Foreign.ForeignPtr (castForeignPtr, newForeignPtr, mallocForeignPtrBytes, withForeignPtr)-import Foreign.Marshal (allocaBytes, copyBytes)+import Foreign.Marshal (allocaBytes)+import Foreign.Marshal.Utils (copyBytes) import qualified Data.Vector.Storable as VS import System.IO.Unsafe (unsafePerformIO) @@ -54,12 +56,17 @@ where (Image w h bytes) = img (imgPtr, _) = VS.unsafeToForeignPtr0 bytes -decode :: BS.ByteString -> Image PixelRGBA8+-- | Cf. 'Codec.Picture.DynamicImage'+--+-- @since 1.0.0.0+data RgbImage = ImageRGBA8 (Image PixelRGBA8) | ImageRGBA16 (Image PixelRGBA16)++decode :: BS.ByteString -> RgbImage decode = either throw id.decodeE {-# NOINLINE decodeE #-} -- | @since 0.1.2.0-decodeE :: BS.ByteString -> Either AvifResult (Image PixelRGBA8)+decodeE :: BS.ByteString -> Either AvifResult RgbImage decodeE bs = unsafePerformIO $ BS.unsafeUseAsCStringLen bs $ \(p, sz) -> do preDec <- avifDecoderCreate dec <- castForeignPtr <$> newForeignPtr avifDecoderDestroy (castPtr preDec)@@ -84,10 +91,12 @@ pxPtr <- {# get avifRGBImage->pixels #} rgbImagePtr - let sz' = w*h*pxSz+ let sz' = fromIntegral (w*h*pxSz) :: Int - outBytes <- mallocForeignPtrBytes (fromIntegral sz')+ outBytes <- mallocForeignPtrBytes sz' withForeignPtr outBytes $ \outPtr -> do- copyBytes outPtr (castPtr pxPtr) (fromIntegral sz')- Right (Image (fromIntegral w) (fromIntegral h) (VS.unsafeFromForeignPtr0 outBytes (fromIntegral sz'))) <$ (avifRGBImageFreePixels rgbImagePtr)+ copyBytes (castPtr outPtr) (castPtr pxPtr) sz'+ let img | pxSz==8 = ImageRGBA16 (Image (fromIntegral w) (fromIntegral h) (VS.unsafeFromForeignPtr0 (castForeignPtr outBytes) sz'))+ | pxSz==4 = ImageRGBA8 (Image (fromIntegral w) (fromIntegral h) (VS.unsafeFromForeignPtr0 outBytes sz'))+ Right img <$ avifRGBImageFreePixels rgbImagePtr
test/Spec.hs view
@@ -14,6 +14,7 @@ testGroup "Roundtrip" [ decodeNoThrow "test/data/original.avif" , decEncNoThrow "test/data/original.avif"+ -- , decodeRGB16 "test/data/woman.avif" , decodeFail ] @@ -22,13 +23,23 @@ let res = decodeE "aaaaa" in assertBool "fails on bad input" $ isLeft res +decodeRGB16 :: FilePath -> TestTree+decodeRGB16 fp = testCase fp $ do+ res <- decodeE <$> BS.readFile fp+ case res of+ Right ImageRGBA16{} -> assertBool "decodes 16-bit" True+ Right _ -> assertFailure "expected 16-bit color."+ Left err -> assertFailure (show err)+ decodeNoThrow :: FilePath -> TestTree decodeNoThrow fp = testCase fp $ do- res <- decode <$> BS.readFile fp- assertBool "Doesn't throw exception" (res `deepseq` True)+ res <- decodeE <$> BS.readFile fp+ case res of+ Left err -> assertFailure (show err)+ Right{} -> assertBool "Doesn't error" True decEncNoThrow :: FilePath -> TestTree decEncNoThrow fp = testCase fp $ do bytes <- BS.readFile fp- let res = encode (decode bytes)+ let res = encode ((\(ImageRGBA8 img) -> img) $ decode bytes) assertBool "Doesn't throw exception" (res `deepseq` True)