{-# LANGUAGE OverloadedStrings #-}moduleData.Conduit.ImageSize(sinkImageSize,Size(..),sinkImageInfo,FileFormat(..))whereimportqualifiedData.ByteString.LazyasLimportqualifiedData.ConduitasCimportqualifiedData.Conduit.BinaryasCBimportqualifiedData.ByteStringasSimportData.ByteString.Char8()importData.ByteString.Lazy.Char8()importControl.Applicative((<$>),(<*>))dataSize=Size{width::Int,height::Int}deriving(Show,Eq,Ord,Read)dataFileFormat=GIF|PNG|JPGderiving(Show,Eq,Ord,Read,Enum)-- | Specialized version of 'sinkImageInfo' that returns only the-- image size.sinkImageSize::Monadm=>C.SinkS.ByteStringm(MaybeSize)sinkImageSize=fmap(fmapfst)sinkImageInfo-- | 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::Monadm=>C.SinkS.ByteStringm(Maybe(Size,FileFormat))sinkImageInfo=C.NeedInput(pushHeaderid)closewhereclose=returnNothingpushHeaderfrontbs'|S.lengthbs>=11&&S.take5(S.drop6bs)==S.pack[0x4A,0x46,0x49,0x46,0x00]=sinkPushjpg$S.drop4bs|S.lengthbs>=6&&S.take6bs`elem`gifs=sinkPushgif$S.drop6bs|S.lengthbs>=8&&S.take8bs==S.pack[137,80,78,71,13,10,26,10]=sinkPushpng$S.drop8bs|S.lengthbs<11=C.NeedInput(pushHeader$S.appendbs)close|otherwise=C.Done(Justbs)Nothingwherebs=frontbs'gifs=["GIF87a","GIF89a"]gif=dob<-CB.take4letgoxy=fromIntegralx+(fromIntegraly)*256return$caseL.unpackbof[w1,w2,h1,h2]->Just(Size(gow1w2)(goh1h2),GIF)_->Nothingpng=do_<-CB.take4-- FIXME drophdr<-CB.take4ifhdr=="IHDR"thendomw<-getInt40mh<-getInt40return$(\wh->(Sizewh,PNG))<$>mw<*>mhelsereturnNothingsinkPush(C.NeedInputpush_)x=pushxsinkPush__=error"Data.Conduit.ImageSize.sinkPush"jpg=domi<-getInt20casemiofNothing->returnNothingJusti->do_<-CB.take$i-2jpgFramejpgFrame=domx<-CB.headcasemxofJust255->domy<-CB.headcasemyofJust0xC0->do_<-CB.take3mh<-getInt20mw<-getInt20return$(\wh->(Sizewh,JPG))<$>mw<*>mhJust_->jpgNothing->returnNothing_->returnNothinggetInt::(Monadm,Integrali)=>Int->i->C.SinkS.ByteStringm(Maybei)getInt0i=return$JustigetIntleni=domx<-CB.headcasemxofNothing->returnNothingJustx->getInt(len-1)(i*256+fromIntegralx)