webp 0.1.0.3 → 0.1.1.0
raw patch · 6 files changed
+61/−20 lines, 6 filesdep +binary
Dependencies added: binary
Files
- CHANGELOG.md +5/−0
- src/Codec/Picture/WebP.hs +24/−18
- src/Codec/Picture/WebP/Container.hs +27/−0
- test/Spec.hs +1/−0
- test/data/tumblr_ddca20a372af5d3c6d38436ffc882f72_99c41c0a_1280.webp too large to diff
- webp.cabal +4/−2
CHANGELOG.md view
@@ -1,5 +1,10 @@ # webp +## 0.1.1.0++ * Add `isAnim`+ * Avoid error/potential segfault on trying to read animated WebP+ ## 0.1.0.3 * Fix flipped width/height
src/Codec/Picture/WebP.hs view
@@ -7,26 +7,34 @@ , encodeRgba8Lossless , encodeRgb8 , encodeRgba8+ , isAnim ) where -import Codec.Picture (Image (Image), PixelBaseComponent,- PixelRGB8, PixelRGBA8)-import Control.Applicative (pure, (<*>))-import qualified Data.ByteString as BS-import qualified Data.ByteString.Internal as BS-import qualified Data.ByteString.Unsafe as BS-import Data.Functor ((<$>))-import Data.Vector.Storable (Vector, unsafeFromForeignPtr0,- unsafeWith)-import Data.Word (Word8)-import Foreign.C.Types (CChar, CFloat, CInt, CSize)-import Foreign.ForeignPtr (newForeignPtr)-import Foreign.Ptr (Ptr, castPtr)-import System.IO.Unsafe (unsafePerformIO)+import Codec.Picture (Image (Image),+ PixelBaseComponent, PixelRGB8,+ PixelRGBA8)+import Codec.Picture.WebP.Container+import Control.Applicative (pure, (<*>))+import qualified Data.ByteString as BS+import qualified Data.ByteString.Internal as BS+import qualified Data.ByteString.Lazy as BSL+import qualified Data.ByteString.Unsafe as BS+import Data.Functor ((<$>))+import Data.Vector.Storable (Vector, unsafeFromForeignPtr0,+ unsafeWith)+import Data.Word (Word8)+import Foreign.C.Types (CChar, CFloat, CInt, CSize)+import Foreign.ForeignPtr (newForeignPtr)+import Foreign.Ptr (Ptr, castPtr)+import System.IO.Unsafe (unsafePerformIO) import WebP.Decode import WebP.Encode import WebP.Types +errAnim :: BS.ByteString -> BS.ByteString+errAnim inp | isAnim (BSL.fromStrict inp) = error "Animated WebP not supported (nor sensible for JuicyPixels)."+ | otherwise = inp+ decodeRgb8 :: BS.ByteString -> Image PixelRGB8 decodeRgb8 = decodeJuicyPixels decodeRgb8BS @@ -68,13 +76,11 @@ => (BS.ByteString -> (CInt, CInt, BS.ByteString)) -> BS.ByteString -> Image p-decodeJuicyPixels decoder = (\(w, h, img) -> Image (fromIntegral w) (fromIntegral h) (bytesToVec img)) . decoder+decodeJuicyPixels decoder = (\(w, h, img) -> Image (fromIntegral w) (fromIntegral h) (bytesToVec img)) . decoder . errAnim where bytesToVec = \(BS.PS fp _ l) -> unsafeFromForeignPtr0 fp l -decodeRgb8BS :: BS.ByteString -> (CInt, CInt, BS.ByteString)+decodeRgb8BS, decodeRgba8BS :: BS.ByteString -> (CInt, CInt, BS.ByteString) decodeRgb8BS = decodeAbsBS webPDecodeRGB 3--decodeRgba8BS :: BS.ByteString -> (CInt, CInt, BS.ByteString) decodeRgba8BS = decodeAbsBS webPDecodeRGBA 4 {-# NOINLINE decodeAbsBS #-}
+ src/Codec/Picture/WebP/Container.hs view
@@ -0,0 +1,27 @@+-- https://stackoverflow.com/a/73170213/11296354+-- https://developers.google.com/speed/webp/docs/riff_container++{-# LANGUAGE OverloadedStrings #-}++module Codec.Picture.WebP.Container (isAnim) where++import Control.Monad (unless)+import Data.Binary.Get (Get, getByteString, runGetOrFail, skip)+import qualified Data.ByteString.Lazy as BSL++-- | Sniff out animated WebP+--+-- @since 0.1.1.0+isAnim :: BSL.ByteString -> Bool+isAnim inp = case runGetOrFail getAnim inp of Left (_, _, e) -> error e; Right (_, _, x) -> x++getAnim :: Get Bool+getAnim = do+ signature 4 "RIFF" "Expected first four bytes to be RIFF"+ skip 4+ signature 4 "WEBP" "Expected WEBP"+ skip 4 *> skip 14+ anim <- getByteString 4+ pure (anim=="ANIM")+ where+ signature n bytes err = do {sig <- getByteString n; unless (sig==bytes) (fail err)}
test/Spec.hs view
@@ -11,6 +11,7 @@ testGroup "Converts to PNG without throwing an exception" [ convRgbPng "test/data/6b3001b4ebfc341ed0359c00586e6ce1.webp" , convRgbPng "test/data/d99cc366dfbbf99493f917e2d43c683f.webp"+ -- , convRgbPng "test/data/tumblr_ddca20a372af5d3c6d38436ffc882f72_99c41c0a_1280.webp" , convRgbaPng "test/data/6b3001b4ebfc341ed0359c00586e6ce1.webp" , convRgbaPng "test/data/d99cc366dfbbf99493f917e2d43c683f.webp" , roundtripLosslessRGB "test/data/6b3001b4ebfc341ed0359c00586e6ce1.webp"
+ test/data/tumblr_ddca20a372af5d3c6d38436ffc882f72_99c41c0a_1280.webp view
file too large to diff
webp.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.18 name: webp-version: 0.1.0.3+version: 0.1.1.0 license: GPL-3 license-file: LICENSE copyright: Copyright: (c) 2020 Vanessa McHale@@ -31,6 +31,7 @@ pkgconfig-depends: libwebp >=0.6.1 hs-source-dirs: src other-modules:+ Codec.Picture.WebP.Container WebP.Encode WebP.Decode WebP.Types@@ -42,7 +43,8 @@ base >=4.7 && <5, JuicyPixels >=3.0, bytestring,- vector >=0.9.1+ vector >=0.9.1,+ binary >=0.6.4.0 if !flag(cross) build-tool-depends: c2hs:c2hs