{-# LANGUAGE CPP #-}

-- |
-- Module      :  Codec.Audio.FLAC.Metadata.Internal.Types
-- Copyright   :  © 2016–present Mark Karpov
-- License     :  BSD 3 clause
--
-- Maintainer  :  Mark Karpov <markkarpov92@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- Mostly non-public metadata-specific helper types.
module Codec.Audio.FLAC.Metadata.Internal.Types
  ( MetaChain (..),
    MetaIterator (..),
    Metadata (..),
    MetadataType (..),
    MetaChainStatus (..),
    MetaException (..),
    ApplicationId,
    mkApplicationId,
    unApplicationId,
    SeekPoint (..),
    CueSheetData (..),
    CueTrack (..),
    PictureType (..),
    PictureData (..),
  )
where

import Control.Exception (Exception)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as B8
import Data.List.NonEmpty (NonEmpty (..))
import Data.String (IsString (..))
import Data.Text (Text)
import Data.Void
import Foreign

#if !MIN_VERSION_base(4,13,0)
import Data.Semigroup ((<>))
#endif

-- | An opaque newtype wrapper around @'Ptr' 'Void'@, serves to represent a
-- pointer to a metadata chain.
newtype MetaChain = MetaChain (Ptr Void)

-- | The same as 'MetaChain', this one is for pointers to metadata iterator.
newtype MetaIterator = MetaIterator (Ptr Void)

-- | The same as 'MetaChain', this one for pointers to metadata structure
-- itself.
newtype Metadata = Metadata (Ptr Void)

-- | Enumeration of all known metadata blocks.
data MetadataType
  = -- | Stream info block (general data like sample rate)
    StreamInfoBlock
  | -- | Padding block
    PaddingBlock
  | -- | Application block
    ApplicationBlock
  | -- | Seek table block
    SeekTableBlock
  | -- | Vorbis comment block, a.k.a. FLAC tags
    VorbisCommentBlock
  | -- | Cue sheet block
    CueSheetBlock
  | -- | Picture block
    PictureBlock
  | -- | Undefined block
    UndefinedBlock
  deriving (Int -> MetadataType -> ShowS
[MetadataType] -> ShowS
MetadataType -> String
(Int -> MetadataType -> ShowS)
-> (MetadataType -> String)
-> ([MetadataType] -> ShowS)
-> Show MetadataType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MetadataType] -> ShowS
$cshowList :: [MetadataType] -> ShowS
show :: MetadataType -> String
$cshow :: MetadataType -> String
showsPrec :: Int -> MetadataType -> ShowS
$cshowsPrec :: Int -> MetadataType -> ShowS
Show, ReadPrec [MetadataType]
ReadPrec MetadataType
Int -> ReadS MetadataType
ReadS [MetadataType]
(Int -> ReadS MetadataType)
-> ReadS [MetadataType]
-> ReadPrec MetadataType
-> ReadPrec [MetadataType]
-> Read MetadataType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MetadataType]
$creadListPrec :: ReadPrec [MetadataType]
readPrec :: ReadPrec MetadataType
$creadPrec :: ReadPrec MetadataType
readList :: ReadS [MetadataType]
$creadList :: ReadS [MetadataType]
readsPrec :: Int -> ReadS MetadataType
$creadsPrec :: Int -> ReadS MetadataType
Read, MetadataType -> MetadataType -> Bool
(MetadataType -> MetadataType -> Bool)
-> (MetadataType -> MetadataType -> Bool) -> Eq MetadataType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetadataType -> MetadataType -> Bool
$c/= :: MetadataType -> MetadataType -> Bool
== :: MetadataType -> MetadataType -> Bool
$c== :: MetadataType -> MetadataType -> Bool
Eq, Eq MetadataType
Eq MetadataType =>
(MetadataType -> MetadataType -> Ordering)
-> (MetadataType -> MetadataType -> Bool)
-> (MetadataType -> MetadataType -> Bool)
-> (MetadataType -> MetadataType -> Bool)
-> (MetadataType -> MetadataType -> Bool)
-> (MetadataType -> MetadataType -> MetadataType)
-> (MetadataType -> MetadataType -> MetadataType)
-> Ord MetadataType
MetadataType -> MetadataType -> Bool
MetadataType -> MetadataType -> Ordering
MetadataType -> MetadataType -> MetadataType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MetadataType -> MetadataType -> MetadataType
$cmin :: MetadataType -> MetadataType -> MetadataType
max :: MetadataType -> MetadataType -> MetadataType
$cmax :: MetadataType -> MetadataType -> MetadataType
>= :: MetadataType -> MetadataType -> Bool
$c>= :: MetadataType -> MetadataType -> Bool
> :: MetadataType -> MetadataType -> Bool
$c> :: MetadataType -> MetadataType -> Bool
<= :: MetadataType -> MetadataType -> Bool
$c<= :: MetadataType -> MetadataType -> Bool
< :: MetadataType -> MetadataType -> Bool
$c< :: MetadataType -> MetadataType -> Bool
compare :: MetadataType -> MetadataType -> Ordering
$ccompare :: MetadataType -> MetadataType -> Ordering
$cp1Ord :: Eq MetadataType
Ord, MetadataType
MetadataType -> MetadataType -> Bounded MetadataType
forall a. a -> a -> Bounded a
maxBound :: MetadataType
$cmaxBound :: MetadataType
minBound :: MetadataType
$cminBound :: MetadataType
Bounded, Int -> MetadataType
MetadataType -> Int
MetadataType -> [MetadataType]
MetadataType -> MetadataType
MetadataType -> MetadataType -> [MetadataType]
MetadataType -> MetadataType -> MetadataType -> [MetadataType]
(MetadataType -> MetadataType)
-> (MetadataType -> MetadataType)
-> (Int -> MetadataType)
-> (MetadataType -> Int)
-> (MetadataType -> [MetadataType])
-> (MetadataType -> MetadataType -> [MetadataType])
-> (MetadataType -> MetadataType -> [MetadataType])
-> (MetadataType -> MetadataType -> MetadataType -> [MetadataType])
-> Enum MetadataType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: MetadataType -> MetadataType -> MetadataType -> [MetadataType]
$cenumFromThenTo :: MetadataType -> MetadataType -> MetadataType -> [MetadataType]
enumFromTo :: MetadataType -> MetadataType -> [MetadataType]
$cenumFromTo :: MetadataType -> MetadataType -> [MetadataType]
enumFromThen :: MetadataType -> MetadataType -> [MetadataType]
$cenumFromThen :: MetadataType -> MetadataType -> [MetadataType]
enumFrom :: MetadataType -> [MetadataType]
$cenumFrom :: MetadataType -> [MetadataType]
fromEnum :: MetadataType -> Int
$cfromEnum :: MetadataType -> Int
toEnum :: Int -> MetadataType
$ctoEnum :: Int -> MetadataType
pred :: MetadataType -> MetadataType
$cpred :: MetadataType -> MetadataType
succ :: MetadataType -> MetadataType
$csucc :: MetadataType -> MetadataType
Enum)

-- | Enumeration of meta chain statuses.
data MetaChainStatus
  = -- | The chain is in the normal OK state.
    MetaChainStatusOK
  | -- | The data passed into a function violated the function's usage
    -- criteria.
    MetaChainStatusIllegalInput
  | -- | The chain could not open the target file.
    MetaChainStatusErrorOpeningFile
  | -- | The chain could not find the FLAC signature at the start of the
    -- file.
    MetaChainStatusNotFlacFile
  | -- | The chain tried to write to a file that was not writable.
    MetaChainStatusNotWritable
  | -- | The chain encountered input that does not conform to the FLAC
    -- metadata specification.
    MetaChainStatusBadMetadata
  | -- | The chain encountered an error while reading the FLAC file.
    MetaChainStatusReadError
  | -- | The chain encountered an error while seeking in the FLAC file.
    MetaChainStatusSeekError
  | -- | The chain encountered an error while writing the FLAC file.
    MetaChainStatusWriteError
  | -- | The chain encountered an error renaming the FLAC file.
    MetaChainStatusRenameError
  | -- | The chain encountered an error removing the temporary file.
    MetaChainStatusUnlinkError
  | -- | Memory allocation failed.
    MetaChainStatusMemoryAllocationError
  | -- | The caller violated an assertion or an unexpected error occurred.
    MetaChainStatusInternalError
  | -- | One or more of the required callbacks was NULL.
    MetaChainStatusInvalidCallbacks
  | -- | This error occurs when read and write methods do not match (i.e.
    -- when if you read with callbacks, you should also use function that
    -- writes with callbacks).
    MetaChainStatusReadWriteMismatch
  | -- | Should not ever happen when you use this binding.
    MetaChainStatusWrongWriteCall
  deriving (Int -> MetaChainStatus -> ShowS
[MetaChainStatus] -> ShowS
MetaChainStatus -> String
(Int -> MetaChainStatus -> ShowS)
-> (MetaChainStatus -> String)
-> ([MetaChainStatus] -> ShowS)
-> Show MetaChainStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MetaChainStatus] -> ShowS
$cshowList :: [MetaChainStatus] -> ShowS
show :: MetaChainStatus -> String
$cshow :: MetaChainStatus -> String
showsPrec :: Int -> MetaChainStatus -> ShowS
$cshowsPrec :: Int -> MetaChainStatus -> ShowS
Show, ReadPrec [MetaChainStatus]
ReadPrec MetaChainStatus
Int -> ReadS MetaChainStatus
ReadS [MetaChainStatus]
(Int -> ReadS MetaChainStatus)
-> ReadS [MetaChainStatus]
-> ReadPrec MetaChainStatus
-> ReadPrec [MetaChainStatus]
-> Read MetaChainStatus
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MetaChainStatus]
$creadListPrec :: ReadPrec [MetaChainStatus]
readPrec :: ReadPrec MetaChainStatus
$creadPrec :: ReadPrec MetaChainStatus
readList :: ReadS [MetaChainStatus]
$creadList :: ReadS [MetaChainStatus]
readsPrec :: Int -> ReadS MetaChainStatus
$creadsPrec :: Int -> ReadS MetaChainStatus
Read, MetaChainStatus -> MetaChainStatus -> Bool
(MetaChainStatus -> MetaChainStatus -> Bool)
-> (MetaChainStatus -> MetaChainStatus -> Bool)
-> Eq MetaChainStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetaChainStatus -> MetaChainStatus -> Bool
$c/= :: MetaChainStatus -> MetaChainStatus -> Bool
== :: MetaChainStatus -> MetaChainStatus -> Bool
$c== :: MetaChainStatus -> MetaChainStatus -> Bool
Eq, Eq MetaChainStatus
Eq MetaChainStatus =>
(MetaChainStatus -> MetaChainStatus -> Ordering)
-> (MetaChainStatus -> MetaChainStatus -> Bool)
-> (MetaChainStatus -> MetaChainStatus -> Bool)
-> (MetaChainStatus -> MetaChainStatus -> Bool)
-> (MetaChainStatus -> MetaChainStatus -> Bool)
-> (MetaChainStatus -> MetaChainStatus -> MetaChainStatus)
-> (MetaChainStatus -> MetaChainStatus -> MetaChainStatus)
-> Ord MetaChainStatus
MetaChainStatus -> MetaChainStatus -> Bool
MetaChainStatus -> MetaChainStatus -> Ordering
MetaChainStatus -> MetaChainStatus -> MetaChainStatus
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MetaChainStatus -> MetaChainStatus -> MetaChainStatus
$cmin :: MetaChainStatus -> MetaChainStatus -> MetaChainStatus
max :: MetaChainStatus -> MetaChainStatus -> MetaChainStatus
$cmax :: MetaChainStatus -> MetaChainStatus -> MetaChainStatus
>= :: MetaChainStatus -> MetaChainStatus -> Bool
$c>= :: MetaChainStatus -> MetaChainStatus -> Bool
> :: MetaChainStatus -> MetaChainStatus -> Bool
$c> :: MetaChainStatus -> MetaChainStatus -> Bool
<= :: MetaChainStatus -> MetaChainStatus -> Bool
$c<= :: MetaChainStatus -> MetaChainStatus -> Bool
< :: MetaChainStatus -> MetaChainStatus -> Bool
$c< :: MetaChainStatus -> MetaChainStatus -> Bool
compare :: MetaChainStatus -> MetaChainStatus -> Ordering
$ccompare :: MetaChainStatus -> MetaChainStatus -> Ordering
$cp1Ord :: Eq MetaChainStatus
Ord, MetaChainStatus
MetaChainStatus -> MetaChainStatus -> Bounded MetaChainStatus
forall a. a -> a -> Bounded a
maxBound :: MetaChainStatus
$cmaxBound :: MetaChainStatus
minBound :: MetaChainStatus
$cminBound :: MetaChainStatus
Bounded, Int -> MetaChainStatus
MetaChainStatus -> Int
MetaChainStatus -> [MetaChainStatus]
MetaChainStatus -> MetaChainStatus
MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
MetaChainStatus
-> MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
(MetaChainStatus -> MetaChainStatus)
-> (MetaChainStatus -> MetaChainStatus)
-> (Int -> MetaChainStatus)
-> (MetaChainStatus -> Int)
-> (MetaChainStatus -> [MetaChainStatus])
-> (MetaChainStatus -> MetaChainStatus -> [MetaChainStatus])
-> (MetaChainStatus -> MetaChainStatus -> [MetaChainStatus])
-> (MetaChainStatus
    -> MetaChainStatus -> MetaChainStatus -> [MetaChainStatus])
-> Enum MetaChainStatus
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: MetaChainStatus
-> MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
$cenumFromThenTo :: MetaChainStatus
-> MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
enumFromTo :: MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
$cenumFromTo :: MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
enumFromThen :: MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
$cenumFromThen :: MetaChainStatus -> MetaChainStatus -> [MetaChainStatus]
enumFrom :: MetaChainStatus -> [MetaChainStatus]
$cenumFrom :: MetaChainStatus -> [MetaChainStatus]
fromEnum :: MetaChainStatus -> Int
$cfromEnum :: MetaChainStatus -> Int
toEnum :: Int -> MetaChainStatus
$ctoEnum :: Int -> MetaChainStatus
pred :: MetaChainStatus -> MetaChainStatus
$cpred :: MetaChainStatus -> MetaChainStatus
succ :: MetaChainStatus -> MetaChainStatus
$csucc :: MetaChainStatus -> MetaChainStatus
Enum)

-- | The exception that is thrown when manipulation of FLAC metadata fails
-- for some reason.
data MetaException
  = -- | General failure, see the attached 'MetaChainStatus'.
    MetaGeneralProblem MetaChainStatus
  | -- | Invalid seek table was passed to be written.
    MetaInvalidSeekTable
  | -- | Invalid CUE sheet was passed to be written. The reason why the data
    -- was invalid is attached.
    MetaInvalidCueSheet Text
  | -- | Invalid picture data was passed to be written. The reason why the
    -- data was invalid is attached.
    MetaInvalidPicture Text
  deriving (MetaException -> MetaException -> Bool
(MetaException -> MetaException -> Bool)
-> (MetaException -> MetaException -> Bool) -> Eq MetaException
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetaException -> MetaException -> Bool
$c/= :: MetaException -> MetaException -> Bool
== :: MetaException -> MetaException -> Bool
$c== :: MetaException -> MetaException -> Bool
Eq, Int -> MetaException -> ShowS
[MetaException] -> ShowS
MetaException -> String
(Int -> MetaException -> ShowS)
-> (MetaException -> String)
-> ([MetaException] -> ShowS)
-> Show MetaException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MetaException] -> ShowS
$cshowList :: [MetaException] -> ShowS
show :: MetaException -> String
$cshow :: MetaException -> String
showsPrec :: Int -> MetaException -> ShowS
$cshowsPrec :: Int -> MetaException -> ShowS
Show, ReadPrec [MetaException]
ReadPrec MetaException
Int -> ReadS MetaException
ReadS [MetaException]
(Int -> ReadS MetaException)
-> ReadS [MetaException]
-> ReadPrec MetaException
-> ReadPrec [MetaException]
-> Read MetaException
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [MetaException]
$creadListPrec :: ReadPrec [MetaException]
readPrec :: ReadPrec MetaException
$creadPrec :: ReadPrec MetaException
readList :: ReadS [MetaException]
$creadList :: ReadS [MetaException]
readsPrec :: Int -> ReadS MetaException
$creadsPrec :: Int -> ReadS MetaException
Read)

instance Exception MetaException

-- | A normalizing wrapper around 'ByteString' that makes sure that the
-- 'ByteString' inside is a valid FLAC application name. You can create
-- values of this type using Haskell string literals with
-- @OverloadedStrings@ or with the 'mkApplicationId' smart constructor.
-- Extract the inner 'ByteString' with 'unApplicationId'.
newtype ApplicationId = ApplicationId ByteString
  deriving (ApplicationId -> ApplicationId -> Bool
(ApplicationId -> ApplicationId -> Bool)
-> (ApplicationId -> ApplicationId -> Bool) -> Eq ApplicationId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ApplicationId -> ApplicationId -> Bool
$c/= :: ApplicationId -> ApplicationId -> Bool
== :: ApplicationId -> ApplicationId -> Bool
$c== :: ApplicationId -> ApplicationId -> Bool
Eq, Eq ApplicationId
Eq ApplicationId =>
(ApplicationId -> ApplicationId -> Ordering)
-> (ApplicationId -> ApplicationId -> Bool)
-> (ApplicationId -> ApplicationId -> Bool)
-> (ApplicationId -> ApplicationId -> Bool)
-> (ApplicationId -> ApplicationId -> Bool)
-> (ApplicationId -> ApplicationId -> ApplicationId)
-> (ApplicationId -> ApplicationId -> ApplicationId)
-> Ord ApplicationId
ApplicationId -> ApplicationId -> Bool
ApplicationId -> ApplicationId -> Ordering
ApplicationId -> ApplicationId -> ApplicationId
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ApplicationId -> ApplicationId -> ApplicationId
$cmin :: ApplicationId -> ApplicationId -> ApplicationId
max :: ApplicationId -> ApplicationId -> ApplicationId
$cmax :: ApplicationId -> ApplicationId -> ApplicationId
>= :: ApplicationId -> ApplicationId -> Bool
$c>= :: ApplicationId -> ApplicationId -> Bool
> :: ApplicationId -> ApplicationId -> Bool
$c> :: ApplicationId -> ApplicationId -> Bool
<= :: ApplicationId -> ApplicationId -> Bool
$c<= :: ApplicationId -> ApplicationId -> Bool
< :: ApplicationId -> ApplicationId -> Bool
$c< :: ApplicationId -> ApplicationId -> Bool
compare :: ApplicationId -> ApplicationId -> Ordering
$ccompare :: ApplicationId -> ApplicationId -> Ordering
$cp1Ord :: Eq ApplicationId
Ord)

instance Show ApplicationId where
  show :: ApplicationId -> String
show (ApplicationId appId :: ByteString
appId) = ByteString -> String
forall a. Show a => a -> String
show ByteString
appId

instance IsString ApplicationId where
  fromString :: String -> ApplicationId
fromString = ByteString -> ApplicationId
mkApplicationId (ByteString -> ApplicationId)
-> (String -> ByteString) -> String -> ApplicationId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
B8.pack

-- | Application id must be four bytes long. If it's too short, null bytes
-- will be appended to it to make it four bytes long. If it's too long, it
-- will be truncated.
mkApplicationId :: ByteString -> ApplicationId
mkApplicationId :: ByteString -> ApplicationId
mkApplicationId appId :: ByteString
appId =
  ByteString -> ApplicationId
ApplicationId (ByteString -> ApplicationId) -> ByteString -> ApplicationId
forall a b. (a -> b) -> a -> b
$
    Int -> ByteString -> ByteString
B.take 4 (ByteString
appId ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> Int -> Word8 -> ByteString
B.replicate 4 0x00)

-- | Get 'ByteString' from 'ApplicationId'.
unApplicationId :: ApplicationId -> ByteString
unApplicationId :: ApplicationId -> ByteString
unApplicationId (ApplicationId appId :: ByteString
appId) = ByteString
appId

-- | Single point in a seek table metadata block.
data SeekPoint = SeekPoint
  { -- | The sample number of the target frame
    SeekPoint -> Word64
seekPointSampleNumber :: !Word64,
    -- | The offset in bytes of the target frame with respect to beginning
    -- of the first frame
    SeekPoint -> Word64
seekPointStreamOffset :: !Word64,
    -- | The number of samples in the target frame
    SeekPoint -> Word32
seekPointFrameSamples :: !Word32
  }
  deriving (SeekPoint -> SeekPoint -> Bool
(SeekPoint -> SeekPoint -> Bool)
-> (SeekPoint -> SeekPoint -> Bool) -> Eq SeekPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SeekPoint -> SeekPoint -> Bool
$c/= :: SeekPoint -> SeekPoint -> Bool
== :: SeekPoint -> SeekPoint -> Bool
$c== :: SeekPoint -> SeekPoint -> Bool
Eq, Eq SeekPoint
Eq SeekPoint =>
(SeekPoint -> SeekPoint -> Ordering)
-> (SeekPoint -> SeekPoint -> Bool)
-> (SeekPoint -> SeekPoint -> Bool)
-> (SeekPoint -> SeekPoint -> Bool)
-> (SeekPoint -> SeekPoint -> Bool)
-> (SeekPoint -> SeekPoint -> SeekPoint)
-> (SeekPoint -> SeekPoint -> SeekPoint)
-> Ord SeekPoint
SeekPoint -> SeekPoint -> Bool
SeekPoint -> SeekPoint -> Ordering
SeekPoint -> SeekPoint -> SeekPoint
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SeekPoint -> SeekPoint -> SeekPoint
$cmin :: SeekPoint -> SeekPoint -> SeekPoint
max :: SeekPoint -> SeekPoint -> SeekPoint
$cmax :: SeekPoint -> SeekPoint -> SeekPoint
>= :: SeekPoint -> SeekPoint -> Bool
$c>= :: SeekPoint -> SeekPoint -> Bool
> :: SeekPoint -> SeekPoint -> Bool
$c> :: SeekPoint -> SeekPoint -> Bool
<= :: SeekPoint -> SeekPoint -> Bool
$c<= :: SeekPoint -> SeekPoint -> Bool
< :: SeekPoint -> SeekPoint -> Bool
$c< :: SeekPoint -> SeekPoint -> Bool
compare :: SeekPoint -> SeekPoint -> Ordering
$ccompare :: SeekPoint -> SeekPoint -> Ordering
$cp1Ord :: Eq SeekPoint
Ord, Int -> SeekPoint -> ShowS
[SeekPoint] -> ShowS
SeekPoint -> String
(Int -> SeekPoint -> ShowS)
-> (SeekPoint -> String)
-> ([SeekPoint] -> ShowS)
-> Show SeekPoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SeekPoint] -> ShowS
$cshowList :: [SeekPoint] -> ShowS
show :: SeekPoint -> String
$cshow :: SeekPoint -> String
showsPrec :: Int -> SeekPoint -> ShowS
$cshowsPrec :: Int -> SeekPoint -> ShowS
Show, ReadPrec [SeekPoint]
ReadPrec SeekPoint
Int -> ReadS SeekPoint
ReadS [SeekPoint]
(Int -> ReadS SeekPoint)
-> ReadS [SeekPoint]
-> ReadPrec SeekPoint
-> ReadPrec [SeekPoint]
-> Read SeekPoint
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SeekPoint]
$creadListPrec :: ReadPrec [SeekPoint]
readPrec :: ReadPrec SeekPoint
$creadPrec :: ReadPrec SeekPoint
readList :: ReadS [SeekPoint]
$creadList :: ReadS [SeekPoint]
readsPrec :: Int -> ReadS SeekPoint
$creadsPrec :: Int -> ReadS SeekPoint
Read)

-- | CUE sheet as stored in FLAC metadata. This differs from traditional CUE
-- sheets stored in “.cue” files (see
-- <https://hackage.haskell.org/package/cue-sheet> to work with those).
data CueSheetData = CueSheetData
  { -- | Media catalog number, in ASCII printable characters 0x20-0x7e. In
    -- general, the media catalog number may be 0 to 128 bytes long; any
    -- unused characters will be right-padded with NUL characters. For
    -- CD-DA, this is a thirteen digit number.
    CueSheetData -> ByteString
cueCatalog :: !ByteString,
    -- | The number of lead-in samples. This field has meaning only for
    -- CD-DA CUE sheets; for other uses it should be 0. For CD-DA, the
    -- lead-in is the TRACK 00 area where the table of contents is stored;
    -- more precisely, it is the number of samples from the first sample of
    -- the media to the first sample of the first index point of the first
    -- track. According to the Red Book, the lead-in must be silence and CD
    -- grabbing software does not usually store it; additionally, the
    -- lead-in must be at least two seconds but may be longer. For these
    -- reasons the lead-in length is stored here so that the absolute
    -- position of the first track can be computed. Note that the lead-in
    -- stored here is the number of samples up to the first index point of
    -- the first track, not necessarily to INDEX 01 of the first track; even
    -- the first track may have INDEX 00 data.
    CueSheetData -> Word64
cueLeadIn :: !Word64,
    -- | 'True' if CUE sheet corresponds to a Compact Disc, else 'False'.
    CueSheetData -> Bool
cueIsCd :: !Bool,
    -- | Collection of actual tracks in the CUE sheet, see 'CueTrack'.
    CueSheetData -> [CueTrack]
cueTracks :: ![CueTrack],
    -- | The obligatory lead-out track, will be written with the index 170.
    CueSheetData -> CueTrack
cueLeadOutTrack :: !CueTrack
  }
  deriving (CueSheetData -> CueSheetData -> Bool
(CueSheetData -> CueSheetData -> Bool)
-> (CueSheetData -> CueSheetData -> Bool) -> Eq CueSheetData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CueSheetData -> CueSheetData -> Bool
$c/= :: CueSheetData -> CueSheetData -> Bool
== :: CueSheetData -> CueSheetData -> Bool
$c== :: CueSheetData -> CueSheetData -> Bool
Eq, Eq CueSheetData
Eq CueSheetData =>
(CueSheetData -> CueSheetData -> Ordering)
-> (CueSheetData -> CueSheetData -> Bool)
-> (CueSheetData -> CueSheetData -> Bool)
-> (CueSheetData -> CueSheetData -> Bool)
-> (CueSheetData -> CueSheetData -> Bool)
-> (CueSheetData -> CueSheetData -> CueSheetData)
-> (CueSheetData -> CueSheetData -> CueSheetData)
-> Ord CueSheetData
CueSheetData -> CueSheetData -> Bool
CueSheetData -> CueSheetData -> Ordering
CueSheetData -> CueSheetData -> CueSheetData
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CueSheetData -> CueSheetData -> CueSheetData
$cmin :: CueSheetData -> CueSheetData -> CueSheetData
max :: CueSheetData -> CueSheetData -> CueSheetData
$cmax :: CueSheetData -> CueSheetData -> CueSheetData
>= :: CueSheetData -> CueSheetData -> Bool
$c>= :: CueSheetData -> CueSheetData -> Bool
> :: CueSheetData -> CueSheetData -> Bool
$c> :: CueSheetData -> CueSheetData -> Bool
<= :: CueSheetData -> CueSheetData -> Bool
$c<= :: CueSheetData -> CueSheetData -> Bool
< :: CueSheetData -> CueSheetData -> Bool
$c< :: CueSheetData -> CueSheetData -> Bool
compare :: CueSheetData -> CueSheetData -> Ordering
$ccompare :: CueSheetData -> CueSheetData -> Ordering
$cp1Ord :: Eq CueSheetData
Ord, Int -> CueSheetData -> ShowS
[CueSheetData] -> ShowS
CueSheetData -> String
(Int -> CueSheetData -> ShowS)
-> (CueSheetData -> String)
-> ([CueSheetData] -> ShowS)
-> Show CueSheetData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CueSheetData] -> ShowS
$cshowList :: [CueSheetData] -> ShowS
show :: CueSheetData -> String
$cshow :: CueSheetData -> String
showsPrec :: Int -> CueSheetData -> ShowS
$cshowsPrec :: Int -> CueSheetData -> ShowS
Show, ReadPrec [CueSheetData]
ReadPrec CueSheetData
Int -> ReadS CueSheetData
ReadS [CueSheetData]
(Int -> ReadS CueSheetData)
-> ReadS [CueSheetData]
-> ReadPrec CueSheetData
-> ReadPrec [CueSheetData]
-> Read CueSheetData
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CueSheetData]
$creadListPrec :: ReadPrec [CueSheetData]
readPrec :: ReadPrec CueSheetData
$creadPrec :: ReadPrec CueSheetData
readList :: ReadS [CueSheetData]
$creadList :: ReadS [CueSheetData]
readsPrec :: Int -> ReadS CueSheetData
$creadsPrec :: Int -> ReadS CueSheetData
Read)

-- | Single track in a CUE sheet.
data CueTrack = CueTrack
  { -- | Track offset in samples, relative to the beginning of the FLAC
    -- audio stream. It is the offset to the first index point of the track.
    -- (Note how this differs from CD-DA, where the track's offset in the
    -- TOC is that of the track's INDEX 01 even if there is an INDEX 00.)
    -- For CD-DA, the offset must be evenly divisible by 588 samples (588
    -- samples = 44100 samples\/sec * 1\/75th of a sec).
    CueTrack -> Word64
cueTrackOffset :: !Word64,
    -- | Track ISRC, empty if not present. This is a 12-digit alphanumeric
    -- code, the @cue-sheet@ package has corresponding type with smart
    -- constructor and validation, but for now we don't want to depend on
    -- that package.
    CueTrack -> ByteString
cueTrackIsrc :: !ByteString,
    -- | 'True' for audio tracks, 'False' for non-audio tracks.
    CueTrack -> Bool
cueTrackAudio :: !Bool,
    -- | 'False' for no pre-emphasis, 'True' for pre-emphasis.
    CueTrack -> Bool
cueTrackPreEmphasis :: !Bool,
    -- | INDEX 00 (pregap) offset, see 'cueTrackIndices' for more info about
    -- indices.
    CueTrack -> Maybe Word64
cueTrackPregapIndex :: !(Maybe Word64),
    -- | Track's index points. Offset in samples, relative to the track
    -- offset, of the index point. For CD-DA, the offset must be evenly
    -- divisible by 588 samples (588 samples = 44100 samples\/sec * 1\/75th
    -- of a sec). Note that the offset is from the beginning of the track,
    -- not the beginning of the audio data.
    CueTrack -> NonEmpty Word64
cueTrackIndices :: !(NonEmpty Word64)
  }
  deriving (CueTrack -> CueTrack -> Bool
(CueTrack -> CueTrack -> Bool)
-> (CueTrack -> CueTrack -> Bool) -> Eq CueTrack
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CueTrack -> CueTrack -> Bool
$c/= :: CueTrack -> CueTrack -> Bool
== :: CueTrack -> CueTrack -> Bool
$c== :: CueTrack -> CueTrack -> Bool
Eq, Eq CueTrack
Eq CueTrack =>
(CueTrack -> CueTrack -> Ordering)
-> (CueTrack -> CueTrack -> Bool)
-> (CueTrack -> CueTrack -> Bool)
-> (CueTrack -> CueTrack -> Bool)
-> (CueTrack -> CueTrack -> Bool)
-> (CueTrack -> CueTrack -> CueTrack)
-> (CueTrack -> CueTrack -> CueTrack)
-> Ord CueTrack
CueTrack -> CueTrack -> Bool
CueTrack -> CueTrack -> Ordering
CueTrack -> CueTrack -> CueTrack
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CueTrack -> CueTrack -> CueTrack
$cmin :: CueTrack -> CueTrack -> CueTrack
max :: CueTrack -> CueTrack -> CueTrack
$cmax :: CueTrack -> CueTrack -> CueTrack
>= :: CueTrack -> CueTrack -> Bool
$c>= :: CueTrack -> CueTrack -> Bool
> :: CueTrack -> CueTrack -> Bool
$c> :: CueTrack -> CueTrack -> Bool
<= :: CueTrack -> CueTrack -> Bool
$c<= :: CueTrack -> CueTrack -> Bool
< :: CueTrack -> CueTrack -> Bool
$c< :: CueTrack -> CueTrack -> Bool
compare :: CueTrack -> CueTrack -> Ordering
$ccompare :: CueTrack -> CueTrack -> Ordering
$cp1Ord :: Eq CueTrack
Ord, Int -> CueTrack -> ShowS
[CueTrack] -> ShowS
CueTrack -> String
(Int -> CueTrack -> ShowS)
-> (CueTrack -> String) -> ([CueTrack] -> ShowS) -> Show CueTrack
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CueTrack] -> ShowS
$cshowList :: [CueTrack] -> ShowS
show :: CueTrack -> String
$cshow :: CueTrack -> String
showsPrec :: Int -> CueTrack -> ShowS
$cshowsPrec :: Int -> CueTrack -> ShowS
Show, ReadPrec [CueTrack]
ReadPrec CueTrack
Int -> ReadS CueTrack
ReadS [CueTrack]
(Int -> ReadS CueTrack)
-> ReadS [CueTrack]
-> ReadPrec CueTrack
-> ReadPrec [CueTrack]
-> Read CueTrack
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [CueTrack]
$creadListPrec :: ReadPrec [CueTrack]
readPrec :: ReadPrec CueTrack
$creadPrec :: ReadPrec CueTrack
readList :: ReadS [CueTrack]
$creadList :: ReadS [CueTrack]
readsPrec :: Int -> ReadS CueTrack
$creadsPrec :: Int -> ReadS CueTrack
Read)

-- | Type of picture FLAC metadata can contain. There may be several
-- metadata blocks containing pictures of different types.
data PictureType
  = -- | Other
    PictureOther
  | -- | 32×32 pixels file icon (PNG only)
    PictureFileIconStandard
  | -- | Other file icon
    PictureFileIcon
  | -- | Cover (front)
    PictureFrontCover
  | -- | Cover (back)
    PictureBackCover
  | -- | Leaflet page
    PictureLeafletPage
  | -- | Media (e.g. label side of CD)
    PictureMedia
  | -- | Lead artist\/lead performer\/soloist
    PictureLeadArtist
  | -- | Artist\/performer
    PictureArtist
  | -- | Conductor
    PictureConductor
  | -- | Band\/orchestra
    PictureBand
  | -- | Composer
    PictureComposer
  | -- | Lyricist\/text writer
    PictureLyricist
  | -- | Recording location
    PictureRecordingLocation
  | -- | During recording
    PictureDuringRecording
  | -- | During performance
    PictureDuringPerformance
  | -- | Movie\/video screen capture
    PictureVideoScreenCapture
  | -- | A bright coloured fish
    PictureFish
  | -- | Illustration
    PictureIllustration
  | -- | Band\/artist logotype
    PictureBandLogotype
  | -- | Publisher\/studio logotype
    PicturePublisherLogotype
  deriving (Int -> PictureType -> ShowS
[PictureType] -> ShowS
PictureType -> String
(Int -> PictureType -> ShowS)
-> (PictureType -> String)
-> ([PictureType] -> ShowS)
-> Show PictureType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PictureType] -> ShowS
$cshowList :: [PictureType] -> ShowS
show :: PictureType -> String
$cshow :: PictureType -> String
showsPrec :: Int -> PictureType -> ShowS
$cshowsPrec :: Int -> PictureType -> ShowS
Show, ReadPrec [PictureType]
ReadPrec PictureType
Int -> ReadS PictureType
ReadS [PictureType]
(Int -> ReadS PictureType)
-> ReadS [PictureType]
-> ReadPrec PictureType
-> ReadPrec [PictureType]
-> Read PictureType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PictureType]
$creadListPrec :: ReadPrec [PictureType]
readPrec :: ReadPrec PictureType
$creadPrec :: ReadPrec PictureType
readList :: ReadS [PictureType]
$creadList :: ReadS [PictureType]
readsPrec :: Int -> ReadS PictureType
$creadsPrec :: Int -> ReadS PictureType
Read, PictureType -> PictureType -> Bool
(PictureType -> PictureType -> Bool)
-> (PictureType -> PictureType -> Bool) -> Eq PictureType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PictureType -> PictureType -> Bool
$c/= :: PictureType -> PictureType -> Bool
== :: PictureType -> PictureType -> Bool
$c== :: PictureType -> PictureType -> Bool
Eq, Eq PictureType
Eq PictureType =>
(PictureType -> PictureType -> Ordering)
-> (PictureType -> PictureType -> Bool)
-> (PictureType -> PictureType -> Bool)
-> (PictureType -> PictureType -> Bool)
-> (PictureType -> PictureType -> Bool)
-> (PictureType -> PictureType -> PictureType)
-> (PictureType -> PictureType -> PictureType)
-> Ord PictureType
PictureType -> PictureType -> Bool
PictureType -> PictureType -> Ordering
PictureType -> PictureType -> PictureType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PictureType -> PictureType -> PictureType
$cmin :: PictureType -> PictureType -> PictureType
max :: PictureType -> PictureType -> PictureType
$cmax :: PictureType -> PictureType -> PictureType
>= :: PictureType -> PictureType -> Bool
$c>= :: PictureType -> PictureType -> Bool
> :: PictureType -> PictureType -> Bool
$c> :: PictureType -> PictureType -> Bool
<= :: PictureType -> PictureType -> Bool
$c<= :: PictureType -> PictureType -> Bool
< :: PictureType -> PictureType -> Bool
$c< :: PictureType -> PictureType -> Bool
compare :: PictureType -> PictureType -> Ordering
$ccompare :: PictureType -> PictureType -> Ordering
$cp1Ord :: Eq PictureType
Ord, PictureType
PictureType -> PictureType -> Bounded PictureType
forall a. a -> a -> Bounded a
maxBound :: PictureType
$cmaxBound :: PictureType
minBound :: PictureType
$cminBound :: PictureType
Bounded, Int -> PictureType
PictureType -> Int
PictureType -> [PictureType]
PictureType -> PictureType
PictureType -> PictureType -> [PictureType]
PictureType -> PictureType -> PictureType -> [PictureType]
(PictureType -> PictureType)
-> (PictureType -> PictureType)
-> (Int -> PictureType)
-> (PictureType -> Int)
-> (PictureType -> [PictureType])
-> (PictureType -> PictureType -> [PictureType])
-> (PictureType -> PictureType -> [PictureType])
-> (PictureType -> PictureType -> PictureType -> [PictureType])
-> Enum PictureType
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PictureType -> PictureType -> PictureType -> [PictureType]
$cenumFromThenTo :: PictureType -> PictureType -> PictureType -> [PictureType]
enumFromTo :: PictureType -> PictureType -> [PictureType]
$cenumFromTo :: PictureType -> PictureType -> [PictureType]
enumFromThen :: PictureType -> PictureType -> [PictureType]
$cenumFromThen :: PictureType -> PictureType -> [PictureType]
enumFrom :: PictureType -> [PictureType]
$cenumFrom :: PictureType -> [PictureType]
fromEnum :: PictureType -> Int
$cfromEnum :: PictureType -> Int
toEnum :: Int -> PictureType
$ctoEnum :: Int -> PictureType
pred :: PictureType -> PictureType
$cpred :: PictureType -> PictureType
succ :: PictureType -> PictureType
$csucc :: PictureType -> PictureType
Enum)

-- | Representation of picture contained in a FLAC metadata block.
data PictureData = PictureData
  { -- | The picture's MIME data. For best compatibility with players, use
    -- picture data of MIME type @image\/jpeg@ or @image\/png@.
    PictureData -> Text
pictureMimeType :: !Text,
    -- | Picture's description.
    PictureData -> Text
pictureDescription :: !Text,
    -- | Picture's width in pixels.
    PictureData -> Word32
pictureWidth :: !Word32,
    -- | Picture's height in pixels.
    PictureData -> Word32
pictureHeight :: !Word32,
    -- | Picture's color depth in bits-per-pixel.
    PictureData -> Word32
pictureDepth :: !Word32,
    -- | For indexed palettes (like GIF), picture's number of colors (the
    -- number of palette entries), or 0 for non-indexed (i.e. 2 ^ depth).
    PictureData -> Word32
pictureColors :: !Word32,
    -- | Binary picture data.
    PictureData -> ByteString
pictureData :: !ByteString
  }
  deriving (PictureData -> PictureData -> Bool
(PictureData -> PictureData -> Bool)
-> (PictureData -> PictureData -> Bool) -> Eq PictureData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PictureData -> PictureData -> Bool
$c/= :: PictureData -> PictureData -> Bool
== :: PictureData -> PictureData -> Bool
$c== :: PictureData -> PictureData -> Bool
Eq, Eq PictureData
Eq PictureData =>
(PictureData -> PictureData -> Ordering)
-> (PictureData -> PictureData -> Bool)
-> (PictureData -> PictureData -> Bool)
-> (PictureData -> PictureData -> Bool)
-> (PictureData -> PictureData -> Bool)
-> (PictureData -> PictureData -> PictureData)
-> (PictureData -> PictureData -> PictureData)
-> Ord PictureData
PictureData -> PictureData -> Bool
PictureData -> PictureData -> Ordering
PictureData -> PictureData -> PictureData
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PictureData -> PictureData -> PictureData
$cmin :: PictureData -> PictureData -> PictureData
max :: PictureData -> PictureData -> PictureData
$cmax :: PictureData -> PictureData -> PictureData
>= :: PictureData -> PictureData -> Bool
$c>= :: PictureData -> PictureData -> Bool
> :: PictureData -> PictureData -> Bool
$c> :: PictureData -> PictureData -> Bool
<= :: PictureData -> PictureData -> Bool
$c<= :: PictureData -> PictureData -> Bool
< :: PictureData -> PictureData -> Bool
$c< :: PictureData -> PictureData -> Bool
compare :: PictureData -> PictureData -> Ordering
$ccompare :: PictureData -> PictureData -> Ordering
$cp1Ord :: Eq PictureData
Ord, Int -> PictureData -> ShowS
[PictureData] -> ShowS
PictureData -> String
(Int -> PictureData -> ShowS)
-> (PictureData -> String)
-> ([PictureData] -> ShowS)
-> Show PictureData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PictureData] -> ShowS
$cshowList :: [PictureData] -> ShowS
show :: PictureData -> String
$cshow :: PictureData -> String
showsPrec :: Int -> PictureData -> ShowS
$cshowsPrec :: Int -> PictureData -> ShowS
Show, ReadPrec [PictureData]
ReadPrec PictureData
Int -> ReadS PictureData
ReadS [PictureData]
(Int -> ReadS PictureData)
-> ReadS [PictureData]
-> ReadPrec PictureData
-> ReadPrec [PictureData]
-> Read PictureData
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PictureData]
$creadListPrec :: ReadPrec [PictureData]
readPrec :: ReadPrec PictureData
$creadPrec :: ReadPrec PictureData
readList :: ReadS [PictureData]
$creadList :: ReadS [PictureData]
readsPrec :: Int -> ReadS PictureData
$creadsPrec :: Int -> ReadS PictureData
Read)