isobmff-builder-0.1.0.1: A (bytestring-) builder for the ISO base media file format ISO-14496-12

Safe HaskellNone
LanguageHaskell2010

Data.ByteString.IsoBaseFileFormat.Boxes.Box

Contents

Description

Definition of the most basic element in an ISOBMFF file: a box. See Chapter 4 in the standard document. A box is a container with a type, a size, possible some data and some nested boxes. The standard defines - among other characteristics - what boxes exist, what data they contain and how they are nested into each other. This library tries to capture some of these characteristics using modern Haskell type system features to provide compile checks for (partial) standard compliance.

Synopsis

Basic Types and classes

class BoxRules t Source #

A class that describes (on the type level) how a box can be nested into other boxes (see Boxes).

Associated Types

type RestrictedTo t :: Maybe [k] Source #

List of boxes that this box can be nested into.

type IsTopLevelBox t :: Bool Source #

If the box is also allowed 'top-level' i.e. in the file directly, not nested in an other box.

type RequiredNestedBoxes t :: [k] Source #

Describes which nested boxes MUST be present in a box using boxes.

type GetCardinality t (c :: k) :: Cardinality Source #

Describes how many times a box should be present in a container (-box).

data Cardinality Source #

Describes how many times a box should be present in a container.

class BoxRules t => IsBoxType t where Source #

Convert type level box types to values

Minimal complete definition

toBoxType

Methods

toBoxType :: proxy t -> BoxType Source #

Instances

class IsBoxContent a where Source #

Types that go into a box. A box content is a piece of data that can be reused in different instances of IsBox. It has no BoxType and hence defines no box.

Minimal complete definition

boxSize, boxBuilder

Instances

IsBoxContent () Source #

An empty box content can by represented by () (i.e. unit).

Methods

boxSize :: () -> BoxSize Source #

boxBuilder :: () -> Builder Source #

IsBoxContent FullBoxHeader Source # 
IsBoxContent BoxTypeExtension Source # 
IsBoxContent FourCc Source # 
IsBoxContent BoxType Source # 
IsBoxContent BoxSizeExtension Source # 
IsBoxContent BoxSize Source # 
IsBoxContent FileType Source # 
IsBoxContent MediaData Source # 
IsBoxContent ProgressiveDownloadInformation Source # 
IsBoxContent Skip Source # 
KnownNat bits => IsBoxContent (BoxFlags Nat bits) Source #

Get the number of bytes required to store a number of bits.

IsBoxContent (Box t t1) Source # 

Methods

boxSize :: Box t t1 -> BoxSize Source #

boxBuilder :: Box t t1 -> Builder Source #

(IsBoxContent p, IsBoxContent c) => IsBoxContent (Extend p c) Source # 
IsBoxContent (UnverifiedBoxes x t bs) Source # 
(IsBoxType x t, ValidBoxes x t bs) => IsBoxContent (Boxes x t bs) Source #

To be nested into a box, Boxes must be an instance of IsBoxContent. This instance concatenates all nested boxes.

Methods

boxSize :: Boxes x t bs -> BoxSize Source #

boxBuilder :: Boxes x t bs -> Builder Source #

data Extend a b Source #

Box content composed of box contents a and b.

Constructors

Extend a b 

Boxes

box :: forall t c. (IsBoxType t, IsBoxContent c) => c -> Box t Source #

Create a Box with a StdType FourCc type.

emptyBox :: forall t. IsBoxType t => Box t Source #

An empty box. This is for boxes without fields. All these boxes contain is their obligatory BoxHeader possibly nested boxes.

data Box b where Source #

A type that wraps the contents of a box and the box type.

Constructors

Box :: (IsBoxType t, IsBoxContent c) => BoxType -> c -> Box t 

Instances

IsBoxContent (Box t t1) Source # 

Methods

boxSize :: Box t t1 -> BoxSize Source #

boxBuilder :: Box t t1 -> Builder Source #

Box Size and Type

data BoxSize Source #

The size of the box. If the size is limited to a (fixed) value, it can be provided as a Word64 which will be represented as either a 32bit compact size or as 64 bit largesize. If UnlimitedSize is used, the box extends to the end of the file.

data BoxSizeExtension Source #

The BoxSize can be > 2^32 in which case an BoxSizeExtension must be added after the type field.

data BoxType Source #

A box has a type, this is the value level representation for the box type.

Constructors

StdType FourCc

FourCc can be used as boxType in Box, standard four letter character code, e.g. ftyp

CustomBoxType String

CustomBoxType defines custom boxTypes in Boxes.

newtype FourCc Source #

A type containin a printable four letter character code.

Constructors

FourCc (Char, Char, Char, Char) 

data BoxTypeExtension Source #

When using custom types extra data must be written after the extra size information. Since the box type and the optional custom box type are not guaranteed to be consequtive, this type handles the second part seperately.

Type-safe box composition

boxes :: forall ts t. (IsBoxType t, ValidBoxes t ts) => Boxes t ts -> Box t Source #

A box that may contain nested boxes. The nested boxes are type checked to be valid in the container box. This results in a container-box with only valid and all required child boxes. This is checked by the type system.

data Boxes cont boxTypes where Source #

A container-box with child boxes.

Constructors

Parent :: IsBoxType t => Box t -> Boxes t '[] 
(:-) :: IsBoxType t => Boxes c ts -> Box t -> Boxes c (t ': ts) infixl 2 

Instances

(IsBoxType x t, ValidBoxes x t bs) => IsBoxContent (Boxes x t bs) Source #

To be nested into a box, Boxes must be an instance of IsBoxContent. This instance concatenates all nested boxes.

Methods

boxSize :: Boxes x t bs -> BoxSize Source #

boxBuilder :: Boxes x t bs -> Builder Source #

type Container parent = Boxes parent '[] Source #

A container box that contains only the parent, and no children (yet).

(^-) :: (IsBoxType t, IsBoxType u) => Box t -> Box u -> Boxes t '[u] infixl 2 Source #

An operator for Parent parent :- firstChild

newtype UnverifiedBoxes t ts Source #

An internal wrapper type around Boxes for the IsBoxContent instance. Since the IsBoxContent instance recursivly deconstructs a Boxes the constraints for the validity ValidBoxes cannot be asserted. To circumvent this the IsBoxContent instance for Boxes delegates to the instance of UnverifiedBoxes, which has no ValidBoxes constraint in the instance head.

Constructors

UnverifiedBoxes (Boxes t ts) 

Type level consistency checks

type ValidBoxes t ts = (AllAllowedIn t ts ~ True, HasAllRequiredBoxes t (RequiredNestedBoxes t) ts ~ True, CheckTopLevelOk t ~ True) Source #

A type-level check that uses BoxRules to check that the contained boxes are standard conform.

type family AllAllowedIn (container :: k) (boxes :: [k]) :: Bool where ... Source #

A type function to check that all nested boxes are allowed in the container.

Equations

AllAllowedIn c '[] = True 
AllAllowedIn c (t ': ts) = If (CheckAllowedIn c t (RestrictedTo t)) (AllAllowedIn c ts) (TypeError (NotAllowedMsg c t)) 

type family CheckAllowedIn (c :: k) (t :: k) (a :: Maybe [k]) :: Bool where ... Source #

Equations

CheckAllowedIn c t Nothing = True 
CheckAllowedIn c t (Just rs) = Find c rs 

type NotAllowedMsg c t = (((((Text "Boxes of type: " :<>: ShowType c) :<>: Text " may not contain boxes of type ") :<>: ShowType t) :$$: ((Text "Valid containers for " :<>: ShowType t) :<>: Text " boxes are: ")) :$$: ShowType (RestrictedTo t)) :$$: (ShowType t :<>: If (IsTopLevelBox c) (Text " boxes may appear top-level in a file.") (Text " boxes must be nested.")) Source #

The custom (type-) error message for AllAllowedIn.

type family HasAllRequiredBoxes (c :: k) (req :: [k]) (nested :: [k]) :: Bool where ... Source #

Check that all required boxes have been nested.

Equations

HasAllRequiredBoxes c '[] nested = True 
HasAllRequiredBoxes c (r ': restReq) nested = If (Find r nested) (HasAllRequiredBoxes c restReq nested) (TypeError (MissingRequired c r nested)) 

type IsSubSet base sub = Intersection base sub == sub Source #

type MissingRequired c r nested = ((((Text "Boxes of type: " :<>: ShowType c) :<>: Text " require these nested boxes: ") :<>: ShowType (RequiredNestedBoxes c)) :$$: (Text "but only these box types were nested: " :<>: ShowType nested)) :$$: (Text "e.g. this type is missing: " :<>: ShowType r) Source #

The custom (type-) error message for HasAllRequiredBoxes.

type family CheckTopLevelOk (t :: k) :: Bool where ... Source #

Check that the box may appear top-level.

type NotTopLevenError c = ((Text "Boxes of type " :<>: ShowType c) :<>: Text " MUST be nested inside boxes of these types: ") :$$: ShowType (RestrictedTo c) Source #

The custom (type-) error message indicating that a box may not appear top-level.

Full Boxes

type FullBox t = Extend FullBoxHeader t Source #

A Box with version and branding information

fullBox :: (IsBoxType t, IsBoxContent c) => BoxVersion -> BoxFlags 24 -> c -> Box t Source #

Create a FullBox from a FourCc StdType and the nested box content.

data FullBoxHeader Source #

The additional header with version and branding information

Constructors

FullBoxHeader BoxVersion (BoxFlags 24) 

newtype BoxVersion Source #

The box version (in a FullBox) is a single byte

Constructors

BoxVersion Word8 

newtype BoxFlags bits Source #

In addition to a BoxVersion there can be 24 bits for custom flags etc in a FullBox.

Constructors

BoxFlags Integer 

Instances

Eq (BoxFlags k bits) Source # 

Methods

(==) :: BoxFlags k bits -> BoxFlags k bits -> Bool #

(/=) :: BoxFlags k bits -> BoxFlags k bits -> Bool #

Num (BoxFlags k bits) Source # 

Methods

(+) :: BoxFlags k bits -> BoxFlags k bits -> BoxFlags k bits #

(-) :: BoxFlags k bits -> BoxFlags k bits -> BoxFlags k bits #

(*) :: BoxFlags k bits -> BoxFlags k bits -> BoxFlags k bits #

negate :: BoxFlags k bits -> BoxFlags k bits #

abs :: BoxFlags k bits -> BoxFlags k bits #

signum :: BoxFlags k bits -> BoxFlags k bits #

fromInteger :: Integer -> BoxFlags k bits #

Show (BoxFlags k bits) Source # 

Methods

showsPrec :: Int -> BoxFlags k bits -> ShowS #

show :: BoxFlags k bits -> String #

showList :: [BoxFlags k bits] -> ShowS #

KnownNat bits => Bits (BoxFlags Nat bits) Source # 

Methods

(.&.) :: BoxFlags Nat bits -> BoxFlags Nat bits -> BoxFlags Nat bits #

(.|.) :: BoxFlags Nat bits -> BoxFlags Nat bits -> BoxFlags Nat bits #

xor :: BoxFlags Nat bits -> BoxFlags Nat bits -> BoxFlags Nat bits #

complement :: BoxFlags Nat bits -> BoxFlags Nat bits #

shift :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

rotate :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

zeroBits :: BoxFlags Nat bits #

bit :: Int -> BoxFlags Nat bits #

setBit :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

clearBit :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

complementBit :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

testBit :: BoxFlags Nat bits -> Int -> Bool #

bitSizeMaybe :: BoxFlags Nat bits -> Maybe Int #

bitSize :: BoxFlags Nat bits -> Int #

isSigned :: BoxFlags Nat bits -> Bool #

shiftL :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

unsafeShiftL :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

shiftR :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

unsafeShiftR :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

rotateL :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

rotateR :: BoxFlags Nat bits -> Int -> BoxFlags Nat bits #

popCount :: BoxFlags Nat bits -> Int #

KnownNat bits => IsBoxContent (BoxFlags Nat bits) Source #

Get the number of bytes required to store a number of bits.

boxFlagBitMask :: KnownNat bits => BoxFlags bits -> Integer Source #

Internal function that creates a bit mask with all bits in a BoxFlags set to 1.

cropBits :: KnownNat bits => BoxFlags bits -> BoxFlags bits Source #

Internal function that masks-out all bits higher than bits.