packages feed

flac-picture (empty) → 0.1.0

raw patch · 11 files changed

+324/−0 lines, 11 filesdep +JuicyPixelsdep +basedep +bytestringsetup-changedbinary-added

Dependencies added: JuicyPixels, base, bytestring, data-default-class, directory, flac, flac-picture, hspec, temporary

Files

+ CHANGELOG.md view
@@ -0,0 +1,3 @@+## FLAC Picture 0.1.0++* Initial release.
+ Codec/Audio/FLAC/Metadata/Picture.hs view
@@ -0,0 +1,73 @@+-- |+-- Module      :  Codec.Audio.FLAC.Metadata.Picture+-- Copyright   :  © 2017 Mark Karpov+-- License     :  BSD 3 clause+--+-- Maintainer  :  Mark Karpov <markkarpov@openmailbox.org>+-- Stability   :  experimental+-- Portability :  portable+--+-- Juicy-Pixels-powered helpers to read\/write images to FLAC metadata+-- blocks. For maximal player support, use PNG or JPEG (we don't provide+-- helpers for other formats at the time anyway).++{-# LANGUAGE OverloadedStrings #-}++module Codec.Audio.FLAC.Metadata.Picture+  ( retrieveImage+  , writeJpegPicture+  , writePngPicture )+where++import Codec.Audio.FLAC.Metadata+import Codec.Picture+import Data.Word+import qualified Data.ByteString.Lazy as BL++-- | Read specific picture from FLAC metadata as 'DynamicImage'.++retrieveImage+  :: PictureType+  -> FlacMeta (Either String DynamicImage)+retrieveImage pictureType = do+  mpicture <- retrieve (Picture pictureType)+  case mpicture of+    Nothing -> return (Left "Picture not found")+    Just picture -> (return . decodeImage . pictureData) picture++-- | Write the given image into FLAC metadata block corresponding to+-- specific 'PictureType'.++writeJpegPicture+  :: PictureType       -- ^ Type of picture we're writing+  -> Word8             -- ^ Quality factor, see 'encodeJpegAtQuality'+  -> Image PixelYCbCr8 -- ^ The picture to write+  -> FlacMeta ()+writeJpegPicture pictureType q image =+  Picture pictureType =-> Just PictureData+    { pictureMimeType    = "image/jpeg"+    , pictureDescription = ""+    , pictureWidth       = fromIntegral (imageWidth image)+    , pictureHeight      = fromIntegral (imageHeight image)+    , pictureDepth       = 24+    , pictureColors      = 0 -- non-indexed+    , pictureData        = BL.toStrict (encodeJpegAtQuality q image)+    }++-- | Write the given image into FLAC metadata block corresponding to+-- specific 'PictureType'.++writePngPicture+  :: PictureType       -- ^ Type of picture we're writing+  -> Image PixelRGB8   -- ^ The picture to write+  -> FlacMeta ()+writePngPicture pictureType image =+  Picture pictureType =-> Just PictureData+    { pictureMimeType    = "image/png"+    , pictureDescription = ""+    , pictureWidth       = fromIntegral (imageWidth image)+    , pictureHeight      = fromIntegral (imageHeight image)+    , pictureDepth       = 24+    , pictureColors      = 0 -- non-indexed+    , pictureData        = BL.toStrict (encodePng image)+    }
+ LICENSE.md view
@@ -0,0 +1,28 @@+Copyright © 2017 Mark Karpov++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright+  notice, this list of conditions and the following disclaimer in the+  documentation and/or other materials provided with the distribution.++* Neither the name Mark Karpov nor the names of contributors may be used to+  endorse or promote products derived from this software without specific+  prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS “AS IS” AND ANY EXPRESS+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN+NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,17 @@+# FLAC Picture++[![License BSD3](https://img.shields.io/badge/license-BSD3-brightgreen.svg)](http://opensource.org/licenses/BSD-3-Clause)+[![Hackage](https://img.shields.io/hackage/v/flac-picture.svg?style=flat)](https://hackage.haskell.org/package/flac-picture)+[![Stackage Nightly](http://stackage.org/package/flac-picture/badge/nightly)](http://stackage.org/nightly/package/flac-picture)+[![Stackage LTS](http://stackage.org/package/flac-picture/badge/lts)](http://stackage.org/lts/package/flac-picture)+[![Build Status](https://travis-ci.org/mrkkrp/flac-picture.svg?branch=master)](https://travis-ci.org/mrkkrp/flac-picture)+[![Coverage Status](https://coveralls.io/repos/mrkkrp/flac-picture/badge.svg?branch=master&service=github)](https://coveralls.io/github/mrkkrp/flac-picture?branch=master)++I bet you always wanted to write a picture into FLAC metadata blocks. I'll+tell you what, with **Haskell** you can do it.++## License++Copyright © 2017 Mark Karpov++Distributed under BSD 3 clause license.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
+ audio-samples/sample.flac view

binary file changed (absent → 11459 bytes)

+ flac-picture.cabal view
@@ -0,0 +1,91 @@+--+-- Cabal configuration for ‘flac-picture’ package.+--+-- Copyright © 2017 Mark Karpov <markkarpov@openmailbox.org>+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are+-- met:+--+-- * Redistributions of source code must retain the above copyright notice,+--   this list of conditions and the following disclaimer.+--+-- * Redistributions in binary form must reproduce the above copyright+--   notice, this list of conditions and the following disclaimer in the+--   documentation and/or other materials provided with the distribution.+--+-- * Neither the name Mark Karpov nor the names of contributors may be used+--   to endorse or promote products derived from this software without+--   specific prior written permission.+--+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS “AS IS” AND ANY+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY+-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+-- POSSIBILITY OF SUCH DAMAGE.++name:                 flac-picture+version:              0.1.0+cabal-version:        >= 1.10+license:              BSD3+license-file:         LICENSE.md+author:               Mark Karpov <markkarpov@openmailbox.org>+maintainer:           Mark Karpov <markkarpov@openmailbox.org>+homepage:             https://github.com/mrkkrp/flac-picture+bug-reports:          https://github.com/mrkkrp/flac-picture/issues+category:             Codec, Audio, Image+synopsis:             Support for writing picture to FLAC metadata blocks with JuicyPixels+build-type:           Simple+description:          Support for writing picture to FLAC metadata blocks with JuicyPixels.+extra-doc-files:      CHANGELOG.md+                    , README.md+data-files:           audio-samples/*.flac+                    , picture-samples/*.jpeg+                    , picture-samples/*.png++source-repository head+  type:               git+  location:           https://github.com/mrkkrp/flac-picture.git++flag dev+  description:        Turn on development settings.+  manual:             True+  default:            False++library+  build-depends:      JuicyPixels      >= 3.2.6.5 && < 4.0+                    , base             >= 4.7 && < 5.0+                    , bytestring       >= 0.2 && < 0.11+                    , flac             >= 0.1 && < 0.2+  exposed-modules:    Codec.Audio.FLAC.Metadata.Picture+  if flag(dev)+    ghc-options:      -Wall -Werror+  else+    ghc-options:      -O2 -Wall+  default-language:   Haskell2010++test-suite tests+  main-is:            Spec.hs+  other-modules:      Codec.Audio.FLAC.Metadata.PictureSpec+  hs-source-dirs:     tests+  type:               exitcode-stdio-1.0+  build-depends:      JuicyPixels      >= 3.2.6.5 && < 4.0+                    , base             >= 4.7 && < 5.0+                    , bytestring       >= 0.2 && < 0.11+                    , data-default-class+                    , directory        >= 1.2.2 && < 1.3+                    , flac             >= 0.1 && < 0.2+                    , flac-picture     >= 0.1.0+                    , hspec            >= 2.0 && < 3.0+                    , temporary        >= 1.1 && < 1.3+  if flag(dev)+    ghc-options:      -Wall -Werror+  else+    ghc-options:      -O2 -Wall+  default-language:   Haskell2010
+ picture-samples/lenna.jpeg view

binary file changed (absent → 7614 bytes)

+ picture-samples/lenna.png view

binary file changed (absent → 7514 bytes)

+ tests/Codec/Audio/FLAC/Metadata/PictureSpec.hs view
@@ -0,0 +1,105 @@+--+-- Tests for the ‘flac-picture’ package.+--+-- Copyright © 2017 Mark Karpov <markkarpov@openmailbox.org>+--+-- Redistribution and use in source and binary forms, with or without+-- modification, are permitted provided that the following conditions are+-- met:+--+-- * Redistributions of source code must retain the above copyright notice,+--   this list of conditions and the following disclaimer.+--+-- * Redistributions in binary form must reproduce the above copyright+--   notice, this list of conditions and the following disclaimer in the+--   documentation and/or other materials provided with the distribution.+--+-- * Neither the name Mark Karpov nor the names of contributors may be used+--   to endorse or promote products derived from this software without+--   specific prior written permission.+--+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS “AS IS” AND ANY+-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY+-- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,+-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+-- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+-- POSSIBILITY OF SUCH DAMAGE.++{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards   #-}++module Codec.Audio.FLAC.Metadata.PictureSpec+  ( spec )+where++import Codec.Audio.FLAC.Metadata+import Codec.Audio.FLAC.Metadata.Picture+import Codec.Picture+import Control.Monad+import Data.Default.Class+import Data.Function (on)+import System.Directory+import System.IO+import System.IO.Temp (withSystemTempFile)+import Test.Hspec+import qualified Data.ByteString.Lazy as BL++spec :: Spec+spec = around withSandbox $ do+  describe "writeJpegPicture/retrieveImage" . forM_ [minBound..maxBound] $ \ptype ->+    it ("writes JPEG picture and reads it back: " ++ show ptype) $ \path -> do+      Right (ImageYCbCr8 pic) <- readJpeg "picture-samples/lenna.jpeg"+      runFlacMeta def path (writeJpegPicture ptype 127 pic)+      let Right (ImageYCbCr8 pic'') = (decodeJpeg . BL.toStrict)+            (encodeJpegAtQuality 100 pic)+      Just PictureData {..} <- runFlacMeta def path (retrieve $ Picture ptype)+      pictureMimeType `shouldBe` "image/jpeg"+      pictureDescription `shouldBe` ""+      pictureWidth `shouldBe` fromIntegral (imageWidth pic)+      pictureHeight `shouldBe` fromIntegral (imageHeight pic)+      pictureDepth `shouldBe` 24+      pictureColors `shouldBe` 0+      Right (ImageYCbCr8 pic') <- runFlacMeta def path (retrieveImage ptype)+      pic' `imageShouldBe` pic''+  describe "writePngPicture/retrieveImage" . forM_ [minBound..maxBound] $ \ptype ->+    it ("writes PNG picture and reads it back: " ++ show ptype) $ \path -> do+      Right (ImageRGB8 pic) <- readPng "picture-samples/lenna.png"+      runFlacMeta def path (writePngPicture ptype pic)+      Just PictureData {..} <- runFlacMeta def path (retrieve $ Picture ptype)+      pictureMimeType `shouldBe` "image/png"+      pictureDescription `shouldBe` ""+      pictureWidth `shouldBe` fromIntegral (imageWidth pic)+      pictureHeight `shouldBe` fromIntegral (imageHeight pic)+      pictureDepth `shouldBe` 24+      pictureColors `shouldBe` 0+      Right (ImageRGB8 pic') <- runFlacMeta def path (retrieveImage ptype)+      pic' `imageShouldBe` pic++----------------------------------------------------------------------------+-- Helpers++-- | Make a temporary copy of @audio-samples/sample.flac@ file and provide+-- the path to the file. Automatically remove the file when the test+-- finishes.++withSandbox :: ActionWith FilePath -> IO ()+withSandbox action = withSystemTempFile "sample.flac" $ \path h -> do+  hClose h+  copyFile "audio-samples/sample.flac" path+  action path++imageShouldBe+  :: (Pixel a, Show (PixelBaseComponent a), Eq (PixelBaseComponent a))+  => Image a+  -> Image a+  -> Expectation+imageShouldBe img0 img1 = do+  (shouldBe `on` imageWidth)  img0 img1+  (shouldBe `on` imageHeight) img0 img1+  (shouldBe `on` imageData)   img0 img1
+ tests/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}