flac-picture 0.1.2 → 0.1.3
raw patch · 7 files changed
+152/−134 lines, 7 filesdep ~JuicyPixelsdep ~basedep ~bytestringsetup-changed
Dependency ranges changed: JuicyPixels, base, bytestring, hspec
Files
- CHANGELOG.md +4/−0
- Codec/Audio/FLAC/Metadata/Picture.hs +52/−46
- LICENSE.md +1/−1
- README.md +10/−4
- Setup.hs +0/−6
- flac-picture.cabal +69/−58
- tests/Codec/Audio/FLAC/Metadata/PictureSpec.hs +16/−19
CHANGELOG.md view
@@ -1,3 +1,7 @@+## FLAC Picture 0.1.3++* Maintenance release with newer dependencies.+ ## FLAC Picture 0.1.2 * Test suite is compatible with `flac-0.2.0` and later.
Codec/Audio/FLAC/Metadata/Picture.hs view
@@ -1,73 +1,79 @@+{-# LANGUAGE OverloadedStrings #-}+ -- | -- Module : Codec.Audio.FLAC.Metadata.Picture--- Copyright : © 2017–2019 Mark Karpov+-- Copyright : © 2017–present Mark Karpov -- License : BSD 3 clause -- -- Maintainer : Mark Karpov <markkarpov92@gmail.com> -- Stability : experimental -- Portability : portable ----- Juicy-Pixels-powered helpers to read\/write images to FLAC metadata+-- Juicy-Pixels-powered helpers to read\/write images into FLAC metadata -- blocks. For best player support, use PNG or JPEG (we don't provide--- helpers for other formats at the time anyway).--{-# LANGUAGE OverloadedStrings #-}-+-- helpers for other formats anyway). module Codec.Audio.FLAC.Metadata.Picture- ( retrieveImage- , writeJpegPicture- , writePngPicture )+ ( retrieveImage,+ writeJpegPicture,+ writePngPicture,+ ) where import Codec.Audio.FLAC.Metadata import Codec.Picture+import Data.ByteString.Lazy qualified as BL import Data.Word-import qualified Data.ByteString.Lazy as BL --- | Read specific type of picture from FLAC metadata as a 'DynamicImage'.--retrieveImage- :: PictureType- -> FlacMeta (Either String DynamicImage)+-- | Read a picture of 'PictureType' from FLAC metadata as a '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+-- | Write the given image into FLAC metadata block corresponding to a -- specific 'PictureType'.--writeJpegPicture- :: PictureType -- ^ Type of picture we're writing- -> Word8 -- ^ Quality factor, see 'encodeJpegAtQuality'- -> Image PixelYCbCr8 -- ^ The picture to write- -> FlacMeta ()+writeJpegPicture ::+ -- | Type of picture we're writing+ PictureType ->+ -- | Quality factor, see 'encodeJpegAtQuality'+ Word8 ->+ -- | The picture to write+ Image PixelYCbCr8 ->+ 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)- }+ 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+-- | Write the given image into FLAC metadata block corresponding to a -- specific 'PictureType'.--writePngPicture- :: PictureType -- ^ Type of picture we're writing- -> Image PixelRGB8 -- ^ The picture to write- -> FlacMeta ()+writePngPicture ::+ -- | Type of picture we're writing+ PictureType ->+ -- | The picture to write+ Image PixelRGB8 ->+ 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)- }+ 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
@@ -1,4 +1,4 @@-Copyright © 2017–2018 Mark Karpov+Copyright © 2017–present Mark Karpov All rights reserved.
README.md view
@@ -4,13 +4,19 @@ [](https://hackage.haskell.org/package/flac-picture) [](http://stackage.org/nightly/package/flac-picture) [](http://stackage.org/lts/package/flac-picture)-[](https://travis-ci.org/mrkkrp/flac-picture)+ -I bet you always wanted to write a picture into FLAC metadata blocks. I'll-tell you what, with **Haskell** you can do it.+Support for writing pictures into FLAC metadata blocks with `JuicyPixels`. +## Contribution++Issues, bugs, and questions may be reported in [the GitHub issue tracker for+this project](https://github.com/mrkkrp/flac-picture/issues).++Pull requests are also welcome.+ ## License -Copyright © 2017–2019 Mark Karpov+Copyright © 2017–present Mark Karpov Distributed under BSD 3 clause license.
− Setup.hs
@@ -1,6 +0,0 @@-module Main (main) where--import Distribution.Simple--main :: IO ()-main = defaultMain
flac-picture.cabal view
@@ -1,66 +1,77 @@-name: flac-picture-version: 0.1.2-cabal-version: 1.18-tested-with: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.3-license: BSD3-license-file: LICENSE.md-author: Mark Karpov <markkarpov92@gmail.com>-maintainer: Mark Karpov <markkarpov92@gmail.com>-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+cabal-version: 2.4+name: flac-picture+version: 0.1.3+license: BSD-3-Clause+license-file: LICENSE.md+maintainer: Mark Karpov <markkarpov92@gmail.com>+author: Mark Karpov <markkarpov92@gmail.com>+tested-with: ghc ==9.4.7 ghc ==9.6.3 ghc ==9.8.1+homepage: https://github.com/mrkkrp/flac-picture+bug-reports: https://github.com/mrkkrp/flac-picture/issues+synopsis:+ Support for writing pictures into FLAC metadata blocks with JuicyPixels +description:+ Support for writing pictures into FLAC metadata blocks with JuicyPixels.++category: Codec, Audio, Image+build-type: Simple+data-files:+ audio-samples/*.flac+ picture-samples/*.jpeg+ picture-samples/*.png++extra-doc-files:+ CHANGELOG.md+ README.md+ source-repository head- type: git- location: https://github.com/mrkkrp/flac-picture.git+ type: git+ location: https://github.com/mrkkrp/flac-picture.git flag dev- description: Turn on development settings.- manual: True- default: False+ description: Turn on development settings.+ default: False+ manual: True library- build-depends: JuicyPixels >= 3.2.6.5 && < 4.0- , base >= 4.8 && < 5.0- , bytestring >= 0.2 && < 0.11- , flac >= 0.1 && < 0.3- exposed-modules: Codec.Audio.FLAC.Metadata.Picture- if flag(dev)- ghc-options: -Wall -Werror- else- ghc-options: -O2 -Wall- if flag(dev) && impl(ghc >= 8.0)- ghc-options: -Wcompat- -Wincomplete-record-updates- -Wincomplete-uni-patterns- -Wnoncanonical-monad-instances- -Wnoncanonical-monadfail-instances- default-language: Haskell2010+ exposed-modules: Codec.Audio.FLAC.Metadata.Picture+ default-language: GHC2021+ build-depends:+ JuicyPixels >=3.2.6.5 && <4,+ base >=4.15 && <5,+ bytestring >=0.2 && <0.13,+ flac >=0.1 && <0.3 + if flag(dev)+ ghc-options:+ -Wall -Werror -Wredundant-constraints -Wpartial-fields+ -Wunused-packages++ else+ ghc-options: -O2 -Wall+ 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.8 && < 5.0- , bytestring >= 0.2 && < 0.11- , directory >= 1.2.2 && < 1.4- , flac >= 0.1 && < 0.3- , flac-picture- , hspec >= 2.0 && < 3.0- , temporary >= 1.1 && < 1.4- build-tools: hspec-discover >= 2.0 && < 3.0- if flag(dev)- ghc-options: -Wall -Werror- else- ghc-options: -O2 -Wall- default-language: Haskell2010+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ build-tool-depends: hspec-discover:hspec-discover >=2 && <3+ hs-source-dirs: tests+ other-modules: Codec.Audio.FLAC.Metadata.PictureSpec+ default-language: GHC2021+ build-depends:+ JuicyPixels >=3.2.6.5 && <4,+ base >=4.15 && <5,+ bytestring >=0.2 && <0.13,+ directory >=1.2.2 && <1.4,+ flac >=0.1 && <0.3,+ flac-picture,+ hspec >=2 && <3,+ temporary >=1.1 && <1.4++ if flag(dev)+ ghc-options:+ -Wall -Werror -Wredundant-constraints -Wpartial-fields+ -Wunused-packages++ else+ ghc-options: -O2 -Wall
tests/Codec/Audio/FLAC/Metadata/PictureSpec.hs view
@@ -1,30 +1,29 @@-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE RecordWildCards #-} -module Codec.Audio.FLAC.Metadata.PictureSpec- ( spec )-where+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.ByteString.Lazy qualified as BL 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 ->+ 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)+ Right (ImageYCbCr8 pic'') <-+ (pure . decodeJpeg . BL.toStrict)+ (encodeJpegAtQuality 100 pic) Just PictureData {..} <- runFlacMeta def path (retrieve $ Picture ptype) pictureMimeType `shouldBe` "image/jpeg" pictureDescription `shouldBe` ""@@ -34,7 +33,7 @@ pictureColors `shouldBe` 0 Right (ImageYCbCr8 pic') <- runFlacMeta def path (retrieveImage ptype) pic' `imageShouldBe` pic''- describe "writePngPicture/retrieveImage" . forM_ [minBound..maxBound] $ \ptype ->+ 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)@@ -54,24 +53,22 @@ -- | 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 ::+ (Pixel a, Show (PixelBaseComponent a), Eq (PixelBaseComponent a)) =>+ Image a ->+ Image a ->+ Expectation imageShouldBe img0 img1 = do- (shouldBe `on` imageWidth) img0 img1+ (shouldBe `on` imageWidth) img0 img1 (shouldBe `on` imageHeight) img0 img1- (shouldBe `on` imageData) img0 img1+ (shouldBe `on` imageData) img0 img1 -- | A shortcut for 'defaultMetaSettings'.- def :: MetaSettings def = defaultMetaSettings