Skip to content

Commit

Permalink
Adding format in metadatas
Browse files Browse the repository at this point in the history
  • Loading branch information
Twinside committed Jun 3, 2015
1 parent 0b56958 commit 02ca4de
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 15 deletions.
1 change: 1 addition & 0 deletions changelog
Expand Up @@ -6,6 +6,7 @@ V3.2.5.2 June 2015

* Adding: Width & Height metdata to help querying image information
without decompressing the whole.
* Adding: Source format metadata.

v3.2.5.1 May 2015
---------------
Expand Down
5 changes: 2 additions & 3 deletions src/Codec/Picture/Bitmap.hs
Expand Up @@ -26,7 +26,6 @@ import Control.Applicative( (<$>) )
import Control.Monad( when, forM_ )
import Control.Monad.ST ( ST, runST )
import Data.Maybe( fromMaybe )
import Data.Monoid( (<>) )
import qualified Data.Vector as V
import qualified Data.Vector.Storable as VS
import qualified Data.Vector.Storable.Mutable as M
Expand Down Expand Up @@ -313,9 +312,9 @@ pixelGet = do
return $ PixelRGB8 r g b

metadataOfHeader :: BmpInfoHeader -> Metadatas
metadataOfHeader hdr = Met.mkSizeMetadata (width hdr) (height hdr) <> dpiMeta
metadataOfHeader hdr =
Met.simpleMetadata Met.SourceBitmap (width hdr) (height hdr) dpiX dpiY
where
dpiMeta = Met.insert Met.DpiY dpiY $ Met.singleton Met.DpiX dpiX
dpiX = Met.dotsPerMeterToDotPerInch . fromIntegral $ xResolution hdr
dpiY = Met.dotsPerMeterToDotPerInch . fromIntegral $ yResolution hdr

Expand Down
6 changes: 4 additions & 2 deletions src/Codec/Picture/Gif.hs
Expand Up @@ -59,7 +59,9 @@ import Data.Binary.Put( Put

import Codec.Picture.InternalHelper
import Codec.Picture.Types
import Codec.Picture.Metadata( Metadatas, mkSizeMetadata )
import Codec.Picture.Metadata( Metadatas
, SourceFormat( SourceGif )
, basicMetadata )
import Codec.Picture.Gif.LZW
import Codec.Picture.Gif.LZWEncoding
import Codec.Picture.BitWriter
Expand Down Expand Up @@ -665,7 +667,7 @@ decodeFirstGifImage :: GifFile -> Either String (DynamicImage, Metadatas)
decodeFirstGifImage img@GifFile { gifImages = (firstImage:_) } =
case decodeAllGifImages img { gifImages = [firstImage] } of
[] -> Left "No image after decoding"
(i:_) -> Right (i, mkSizeMetadata (screenWidth hdr) (screenHeight hdr))
(i:_) -> Right (i, basicMetadata SourceGif (screenWidth hdr) (screenHeight hdr))
where hdr = gifScreenDescriptor $ gifHeader img
decodeFirstGifImage _ = Left "No image in gif file"

Expand Down
6 changes: 4 additions & 2 deletions src/Codec/Picture/HDR.hs
Expand Up @@ -37,7 +37,9 @@ import Control.Monad.Primitive ( PrimState, PrimMonad )
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.Mutable as M

import Codec.Picture.Metadata( Metadatas, mkSizeMetadata )
import Codec.Picture.Metadata( Metadatas
, SourceFormat( SourceHDR )
, basicMetadata )
import Codec.Picture.InternalHelper
import Codec.Picture.Types
import Codec.Picture.VectorByteConversion
Expand Down Expand Up @@ -180,7 +182,7 @@ decodeHDRWithMetadata str = runST $ runExceptT $
case runGet decodeHeader $ L.fromChunks [str] of
Left err -> throwE err
Right rez ->
let meta = mkSizeMetadata (abs $ radianceWidth rez) (abs $ radianceHeight rez) in
let meta = basicMetadata SourceHDR (abs $ radianceWidth rez) (abs $ radianceHeight rez) in
(, meta) . ImageRGBF <$> (decodeRadiancePicture rez >>= lift . unsafeFreezeImage)

getChar8 :: Get Char
Expand Down
6 changes: 4 additions & 2 deletions src/Codec/Picture/Jpg.hs
Expand Up @@ -47,7 +47,9 @@ import qualified Data.ByteString.Lazy as L
import Codec.Picture.InternalHelper
import Codec.Picture.BitWriter
import Codec.Picture.Types
import Codec.Picture.Metadata( Metadatas, mkSizeMetadata )
import Codec.Picture.Metadata( Metadatas
, SourceFormat( SourceJpeg )
, basicMetadata )
import Codec.Picture.Tiff.Types
import Codec.Picture.Tiff.Metadata
import Codec.Picture.Jpg.Types
Expand Down Expand Up @@ -588,7 +590,7 @@ decodeJpegWithMetadata file = case runGetStrict get file of
imgWidth = fromIntegral $ jpgWidth scanInfo
imgHeight = fromIntegral $ jpgHeight scanInfo

sizeMeta = mkSizeMetadata imgWidth imgHeight
sizeMeta = basicMetadata SourceJpeg imgWidth imgHeight

imageSize = imgWidth * imgHeight * compCount

Expand Down
44 changes: 42 additions & 2 deletions src/Codec/Picture/Metadata.hs
Expand Up @@ -16,6 +16,7 @@ module Codec.Picture.Metadata( -- * Types
, Keys( .. )
, Value( .. )
, Elem( .. )
, SourceFormat( .. )

-- * Functions
, Codec.Picture.Metadata.lookup
Expand All @@ -31,6 +32,8 @@ module Codec.Picture.Metadata( -- * Types
-- * Helper functions
, mkDpiMetadata
, mkSizeMetadata
, basicMetadata
, simpleMetadata

-- * Conversion functions
, dotsPerMeterToDotPerInch
Expand All @@ -57,6 +60,20 @@ data Equiv a b where
Refl :: Equiv a a
#endif

-- | Type describing the original file format of the ilfe.
data SourceFormat
= SourceJpeg
| SourceGif
| SourceBitmap
| SourceTiff
| SourcePng
| SourceHDR
| SourceTGA
deriving (Eq, Show)

instance NFData SourceFormat where
rnf a = a `seq` ()

-- | Store various additional information about an image. If
-- something is not recognized, it can be stored in an unknown tag.
--
Expand All @@ -78,6 +95,7 @@ data Equiv a b where
--
data Keys a where
Gamma :: Keys Double
Format :: Keys SourceFormat
DpiX :: Keys Word
DpiY :: Keys Word
Width :: Keys Word
Expand Down Expand Up @@ -134,6 +152,7 @@ keyEq a b = case (a, b) of
(Disclaimer, Disclaimer) -> Just Refl
(Source, Source) -> Just Refl
(Warning, Warning) -> Just Refl
(Format, Format) -> Just Refl
(Unknown v1, Unknown v2) | v1 == v2 -> Just Refl
(Exif t1, Exif t2) | t1 == t2 -> Just Refl
_ -> Nothing
Expand Down Expand Up @@ -211,9 +230,30 @@ dotsPerCentiMeterToDotPerInch z = z * 254 `div` 100

-- | Create metadatas indicating the resolution, with DpiX == DpiY
mkDpiMetadata :: Word -> Metadatas
mkDpiMetadata w = insert DpiY w $ singleton DpiX w
mkDpiMetadata w =
Metadatas [DpiY :=> w, DpiX :=> w]

-- | Create metadatas holding width and height information.
mkSizeMetadata :: Integral n => n -> n -> Metadatas
mkSizeMetadata w h = insert Width (fromIntegral w) . singleton Height $ fromIntegral h
mkSizeMetadata w h =
Metadatas [ Width :=> fromIntegral w, Height :=> fromIntegral h ]

-- | Create simple metadatas with Format, Width & Height
basicMetadata :: Integral nSize => SourceFormat -> nSize -> nSize -> Metadatas
basicMetadata f w h =
Metadatas [ Format :=> f
, Width :=> fromIntegral w
, Height :=> fromIntegral h
]

-- | Create simple metadatas with Format, Width, Height, DpiX & DpiY
simpleMetadata :: (Integral nSize, Integral nDpi)
=> SourceFormat -> nSize -> nSize -> nDpi -> nDpi -> Metadatas
simpleMetadata f w h dpiX dpiY =
Metadatas [ Format :=> f
, Width :=> fromIntegral w
, Height :=> fromIntegral h
, DpiX :=> fromIntegral dpiX
, DpiY :=> fromIntegral dpiY
]

3 changes: 2 additions & 1 deletion src/Codec/Picture/Png.hs
Expand Up @@ -508,7 +508,8 @@ decodePngWithMetadata :: B.ByteString -> Either String (DynamicImage, Metadatas)
decodePngWithMetadata byte = do
rawImg <- runGetStrict get byte
let ihdr = header rawImg
metadatas = mkSizeMetadata (width ihdr) (height ihdr) <> extractMetadatas rawImg
metadatas =
basicMetadata SourcePng (width ihdr) (height ihdr) <> extractMetadatas rawImg
compressedImageData =
Lb.concat [chunkData chunk | chunk <- chunks rawImg
, chunkType chunk == iDATSignature]
Expand Down
1 change: 1 addition & 0 deletions src/Codec/Picture/Png/Metadata.hs
Expand Up @@ -113,6 +113,7 @@ encodeSingleMetadata = Met.foldMap go where
Met.DpiY :=> _ -> mempty
Met.Width :=> _ -> mempty
Met.Height :=> _ -> mempty
Met.Format :=> _ -> mempty
Met.Gamma :=> g ->
pure $ mkRawChunk gammaSignature . encode $ PngGamma g
Met.Title :=> tx -> txt "Title" (L.pack tx)
Expand Down
6 changes: 4 additions & 2 deletions src/Codec/Picture/Tga.hs
Expand Up @@ -47,7 +47,9 @@ import qualified Data.Vector.Storable.Mutable as M

import Codec.Picture.Types
import Codec.Picture.InternalHelper
import Codec.Picture.Metadata( Metadatas, mkSizeMetadata )
import Codec.Picture.Metadata( Metadatas
, SourceFormat( SourceTGA )
, basicMetadata )
import Codec.Picture.VectorByteConversion

data TgaColorMapType
Expand Down Expand Up @@ -284,7 +286,7 @@ unparse file =
unpacker | isRleEncoded imageType = unpackRLETga
| otherwise = unpackUncompressedTga

metas = mkSizeMetadata (_tgaHdrWidth hdr) (_tgaHdrHeight hdr)
metas = basicMetadata SourceTGA (_tgaHdrWidth hdr) (_tgaHdrHeight hdr)
decodedPalette = unparse file
{ _tgaFileHeader = hdr
{ _tgaHdrHeight = 1
Expand Down
2 changes: 1 addition & 1 deletion src/Codec/Picture/Tiff/Metadata.hs
Expand Up @@ -17,7 +17,7 @@ import Codec.Picture.Tiff.Types
import Codec.Picture.Metadata.Exif

extractTiffStringMetadata :: [ImageFileDirectory] -> Metadatas
extractTiffStringMetadata = foldMap go where
extractTiffStringMetadata = Met.insert Met.Format Met.SourceTiff . foldMap go where
strMeta k = Met.singleton k . B.unpack
exif ifd =
Met.singleton (Met.Exif $ ifdIdentifier ifd) $ ifdExtended ifd
Expand Down

0 comments on commit 02ca4de

Please sign in to comment.