thumbnail-plus 1.0.3 → 1.0.4
raw patch · 3 files changed
+17/−118 lines, 3 filesdep +imagesize-conduitdep ~conduit-extra
Dependencies added: imagesize-conduit
Dependency ranges changed: conduit-extra
Files
- src/Graphics/ThumbnailPlus/ImageSize.hs +1/−104
- tests/Main.hs +1/−1
- thumbnail-plus.cabal +15/−13
src/Graphics/ThumbnailPlus/ImageSize.hs view
@@ -1,110 +1,7 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE DeriveDataTypeable #-}--- | Detect the image size without opening the image itself.------ Amazingly, reimplementing this wheel is the recommended way of--- not processing huge images according to gd's FAQ. We hope to--- be at least as restrictive as gd itself is, otherwise some--- malicious image could get past this code and blow on gd's--- hand.------ This code has been ressurected by the now-deprecated--- @imagesize-conduit@ library by Michael Snoyman. module Graphics.ThumbnailPlus.ImageSize ( Size (..) , FileFormat (..) , sinkImageInfo ) where -import qualified Data.ByteString.Lazy as L-import Data.Conduit-import qualified Data.Conduit.Binary as CB-import qualified Data.ByteString as S-import Data.ByteString.Char8 ()-import Data.ByteString.Lazy.Char8 ()-import qualified Data.Typeable as T-import Control.Applicative ((<$>), (<*>))---data Size = Size { width :: Int, height :: Int }- deriving (Show, Eq, Ord, Read, T.Typeable)---data FileFormat = GIF | PNG | JPG- deriving (Show, Eq, Ord, Read, Enum, T.Typeable)----- | Find out the size of an image. Also returns the file format--- that parsed correctly. Note that this function does not--- verify that the file is indeed in the format that it returns,--- since it looks only at a small part of the header.-sinkImageInfo :: Monad m => Consumer S.ByteString m (Maybe (Size, FileFormat))-sinkImageInfo = start id- where- start front = await >>= maybe (return Nothing) (pushHeader front)-- pushHeader front bs'- | S.length bs >= 11 && S.take 5 (S.drop 6 bs) ==- S.pack [0x4A, 0x46, 0x49, 0x46, 0x00] =- leftover (S.drop 4 bs) >> jpg- | S.length bs >= 6 && S.take 6 bs `elem` gifs =- leftover (S.drop 6 bs) >> gif- | S.length bs >= 8 && S.take 8 bs == S.pack [137, 80, 78, 71, 13, 10, 26, 10] =- leftover (S.drop 8 bs) >> png- | S.length bs < 11 = start $ S.append bs- | otherwise = leftover bs >> return Nothing- where- bs = front bs'-- gifs = ["GIF87a", "GIF89a"]- gif = do- b <- CB.take 4- let go x y = fromIntegral x + (fromIntegral y) * 256- return $ case L.unpack b of- [w1, w2, h1, h2] -> Just (Size (go w1 w2) (go h1 h2), GIF)- _ -> Nothing-- png = do- CB.drop 4- hdr <- CB.take 4- if hdr == "IHDR"- then do- mw <- getInt 4 0- mh <- getInt 4 0- return $ (\w h -> (Size w h, PNG)) <$> mw <*> mh- else return Nothing-- jpg = do- mi <- getInt 2 0- case mi of- Nothing -> return Nothing- Just i -> do- CB.drop $ i - 2- jpgFrame-- jpgFrame = do- mx <- CB.head- case mx of- Just 255 -> do- my <- CB.head- case my of- Just 0xC0 -> do- _ <- CB.take 3- mh <- getInt 2 0- mw <- getInt 2 0- return $ (\w h -> (Size w h, JPG)) <$> mw <*> mh- Just _ -> jpg- Nothing -> return Nothing- _ -> return Nothing--getInt :: (Monad m, Integral i)- => Int- -> i- -> Consumer S.ByteString m (Maybe i)-getInt 0 i = return $ Just i-getInt len i = do- mx <- CB.head- case mx of- Nothing -> return Nothing- Just x -> getInt (len - 1) (i * 256 + fromIntegral x)+import Data.Conduit.ImageSize
tests/Main.hs view
@@ -54,7 +54,7 @@ check :: Maybe (TP.Size, TP.FileFormat) -> FilePath -> Expectation check ex fp = do- size <- C.runResourceT $ CB.sourceFile fp C.$$ TPIS.sinkImageInfo+ size <- R.runResourceT $ CB.sourceFile fp C.$$ TPIS.sinkImageInfo size `shouldBe` ex checkThumbnail :: TP.Thumbnail -> Expectation
thumbnail-plus.cabal view
@@ -1,5 +1,5 @@ name: thumbnail-plus-version: 1.0.3+version: 1.0.4 synopsis: Generate thumbnails easily and safely. homepage: https://github.com/prowdsponsor/thumbnail-plus license: MIT@@ -23,8 +23,8 @@ * File sizes are constrained and checked. . * Image sizes are constrained and checked before the images- are loaded into memory. Uses code from the deprecated- @imagesize-conduit@ by Michael Snoyman.+ are loaded into memory. Uses @imagesize-conduit@ by Michael+ Snoyman. . * Optionally, the original image is reencoded before being saved.@@ -45,21 +45,22 @@ Graphics.ThumbnailPlus Graphics.ThumbnailPlus.ImageSize build-depends:- base >= 4.6 && < 5,- bytestring >= 0.10,- data-default >= 0.5,+ base >= 4.6 && < 5,+ bytestring >= 0.10,+ data-default >= 0.5, - transformers >= 0.3,- either >= 4.1,+ transformers >= 0.3,+ either >= 4.1, - conduit >= 1.1,- conduit-extra >= 1.1,- resourcet >= 0.4,+ conduit >= 1.1,+ conduit-extra >= 1.1,+ resourcet >= 0.4,+ imagesize-conduit >= 1.0.0.3, directory,- temporary >= 1.2,+ temporary >= 1.2, - gd >= 3000.7.3+ gd >= 3000.7.3 hs-source-dirs: src default-language: Haskell2010 ghc-options: -Wall@@ -71,6 +72,7 @@ data-default, transformers, conduit,+ conduit-extra, resourcet, directory,