/*
 * @(#)QuickTimeAtoms.txt  1.8  2011-04-05
 *
 * Copyright (c) 2000-2011 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */

/* This file contains the description of some
 * well known QuickTime data structures as
 * published in
 *   Inside Macintosh: QuickTime
 *   Apple Technical Library, 1993
 *   Addison-Wesley, Reading ...
 *   ISBN 0-201-62201-7
 *
 * @version 1.8 2011-04-05 Adds gmhd Generic Media Info header.
 *  <br>1.7 2011-01-06 Adds MPEG-4 Atoms.
 *  <br>1.6 2010-12-31 Fixes soundSampleDescription atom. Added additional
 *                    copyright atoms.
 * <br>1.5 2010-04-02 Added a union struct to the SampleDescriptionAtom.
 * <br>1.4 2008-06-15 Added support for atoms: tapt, clef, prof, enof.
 * <br>1.3 Added support for the following atoms: ftyp, @des.
 */
magic cprtAtom "cprt";
description cprtAtom "Copyright Atom", "Copyright notice.";

magic ftypAtom "ftyp";
description ftypAtom "File Type Atom", "The file type atom identifies the file type specifications the file is compatible with. When a file is compatible with more than one specification, the file type atom lists all the compatible types and indicates the preferred brand, or best use, among the compatible types";

magic movieAtom "moov";
description movieAtom "Movie Atom", "The movie atom holds the description of the movie.";

magic compressedMovieAtom "cmov";
description compressedMovieAtom "Compressed Movie", "The compressed movie atom holds the compressed description of the movie.";

magic dataCompressionAtom "dcom";
description dataCompressionAtom "Data Compression Atom", "Describes what lossless data compression algorithm was used to compress the movie header atoms.";

magic compressedMovieDataAtom "cmvd";
description compressedMovieDataAtom "Compressed Movie Data", "Holds the compressed movie header atoms. The first 32-bit integer in the compressed movie data atom indicates the uncompressed size of the movie resource and then the compressed movie resource data follows";

magic movieDataAtom "mdat";
description movieDataAtom "Movie Data Atom", "The movie data atom contains the media data of the movie. Usually this data can be interpreted only by using information provided by the movie atom.";

magic freeAtom "free";
description freeAtom "Free Space Atom", "The free space atom marks unused space available in the file.";

magic skipAtom "skip";
description skipAtom "Skip Atom", "The skip atom marks unused space available in the file.";

magic wideAtom "wide";
description wideAtom "Reserved Space", "The wide atom marks reserved space which can be overwritten by an extended size field. The wide atom consists only of a type and size field. This occupies 8 bytes - enough space to add an extended size field to the header of the atom that follows. If an atom grows to exceed 2^32 bytes in size, and it is preceeded by a wide atom, you may create a new atom header, containing an extended size field, by overwriting the wide atom.";

magic previewAtom "pnot";
description previewAtom "Preview Atom", "The preview atom contains information that allows you to find the preview image associated with a QuickTime movie.";

magic referenceMovieAtom "rmra";
description referenceMovieAtom "Reference Movie Atom", "A movie that contains this atom references to alternate movies, i. e. movies having different data rates, allowing an application to choose the best-looking movie based on the configuration of the computer system. The reference movie atom contains one or more reference movie descriptor atoms, each of which describes an alternate movie.";

magic dataReferenceAtom "rdrf";
description dataReferenceAtom "Data Reference Atom", "A data reference atom contains the information necessary to locate a movie, or a stream or file that QuickTime canplay, typically in the form of a URL or a file alias.";

magic dataRateAtom "rmdr";
description dataRateAtom "Data Rate Atom", "A data rate atom specifies the minimum data rate required to play a movie.";
magic cpuSpeedAtom "rmcs";
description cpuSpeedAtom "CPU Speed Atom", "A CPU speed atom specifies the minimum computing power needed to display a movie. This is not a simple measurement of clock speed - it is a measurement of performance for QuickTime-related operations. Speed is expressed as a relative value between 100 and 2^31, in multiples of 100. Typical scores might range from a minimum score of 100, which would describe a computer as slow as, or slower than, a 166 MHz Pentium or 120 MHz Power PC, to a maximum score of 600 for a 500 MHz Pentium III or 400 MHz G4 PowerPC. A Computer with a graphics accelerator and a Gigahertz clock speed might score as high as 1000.";
magic versionCheckAtom "rmvc";
description versionCheckAtom "Version Check Atom", ".";
magic componentDetectAtom "rmcd";
description componentDetectAtom "Component Detect Atom", ".";
magic qualityAtom "rmqu";
description qualityAtom "Quality Atom", ".";

magic referenceMovieDescriptorAtom "rmda";
description referenceMovieDescriptorAtom "Reference Movie Descriptor Atom", "Describes where a particular movie can be found, and optionally what the system requirements are to play that movie, as well as an optonal quality rating for that movie.";

magic trackAtom "trak";
description trackAtom "Track Atom", "Track atoms define a single track of a movie. A movie may consist of one or more tracks. Each track is independent of the other tracks in the movie and carries its own temporal and spatial information.";

magic editAtom "edts";
description editAtom "Edit Atom", "Edit atoms define the portions of the media that are to be used to build up a track for a movie.";

magic mediaAtom "mdia";
description mediaAtom "Media Atom",  "Media atoms define the data for a movie track. It specifies the component that is to interpret the media data, and it also specifies the data references.";

magic mediaInformationAtom "minf";
description mediaInformationAtom "Media Information Atom", "Media information atoms store handler-specific information for the media data that constitutes a track. The media handler uses this information to map from media time to media data. These atoms are formatted differently based on the type of media data stored in the atom. The format and content of media information atoms are dictated by the media handler that is responsible for interpreting the media data stream. Another media handler would not know how to interpret this information.";

magic dataInformationAtom "dinf";
description dataInformationAtom "Data Information Atom", "The handler reference atom (hdlr) contains information specifying the data handler component that provides access to the media data. The handler uses the data information atom to specify where the data is stored.";

magic sampleTableAtom "stbl";
description sampleTableAtom "Sample Table Atom", "The sample table atom contains information for converting from media time to sample number to sample location. This atom also indicates how to interpret the sample (for example, whether to decompress the video sample and, if so, how).";

magic userDefinedDataAtom "udta";
description userDefinedDataAtom "User Defined Data Atom", "This atom holds user-defined data.";

magic clippingAtom "clip";
description clippinAtom "Clipping Atom", "Clipping atoms specify the clipping regions for movies and tracks.";

magic trackMatteAtom "matt";
description trackMatteAtom "Track Matte Atom", "Track matte atoms specify the mattes for tracks. A track matte is a pixel map that defines the blending of visual track data.";

magic movieHeaderAtom "mvhd";
description movieHeaderAtom "Movie Header Atom", "The movie header atom defines the time scale and duration information of the entire movie, as well as its display characteristics.";

magic windowLocationAtom "WLOC";
description windowLocationAtom "Window Location Atom", "Default window location for movie.";

magic trackApertureModeDimensions "tapt";
description trackApertureModeDimensions "Track Aperture Mode Dimensions", "";

magic trackCleanApertureModeDimensions "clef";
description trackCleanApertureModeDimensions "Track Clean Aperture Dimensions", "";

magic trackProductionApertureDimensions "prof";
description trackProductionApertureDimensions "Track Production Aperture Dimensions", "";

magic trackEncodePixelsModeDimensions "enof";
description trackEncodePixelsModeDimensions "Track Encode Pixels Dimensions", "";

magic playSelectionAtom "SelO";
description playSelectionAtom "Play Selection Atom", "";

magic playAllFramesAtom "AllF";
description playAllFramesAtom "Play All Frames Atom", "";

typedef struct {
    int version; // 4 bytes version/flags = byte hex version + 24-bit hex flags
                 // (current = 0)
    short languageCode; //  1/8 byte ISO language padding = 1-bit value set to 0
           //-> 1 7/8 bytes content language = 3 * 5-bits ISO 639-2 language code less 0x60
           //  - example code for english = 0x15C7
    byte unknown;
    cstring copyright;
} cprtAtom;

typedef struct {
    magic brand;
    bcd4 versionYear;
    bcd2 versionMonth;
    bcd2 versionMinor;
    magic[] compatibleBrands;
} ftypAtom;

typedef struct {
    magic compressionMethod;
} dataCompressionAtom;

typedef struct {
    mactimestamp modificationDate;
    short versionNumber;
    magic atomType;
    short atomIndex;
} previewAtom;

// Enumeration for data reference flags
set {
    SelfContained = 0x1 // movie is self contained
} DataReferenceFlags;
typedef struct {
    int set DataReferenceFlags flags;
    magic dataReferenceType;
    int dataReferenceSize;
    string dataReference;
} dataReferenceAtom;

typedef struct {
    byte[4] flags;
    int bitsPerSecond;
} dataRateAtom;

typedef struct {
    byte[4] flags;
    int cpuSpeed;
} cpuSpeedAtom;

typedef struct {
    byte version;
    byte[3] flags;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int timeScale;
    int duration;
    fixed16d16 preferredRate;
    fixed8d8 preferredVolume;
    byte[10] reserved;
    fixed16d16 matrixA;
    fixed16d16 matrixB;
    fixed2d30 matrixU;
    fixed16d16 matrixC;
    fixed16d16 matrixD;
    fixed2d30 matrixV;
    fixed16d16 matrixX;
    fixed16d16 matrixY;
    fixed2d30 matrixW;
    int previewTime;
    int previewDuration;
    int posterTime;
    int selectionTime;
    int selectionDuration;
    int currentTime;
    int nextTrackId;
} movieHeaderAtom;


magic trackHeaderAtom "tkhd";
description trackHeaderAtom "Track Header Atom", "The track header atom describes the characteristics of a single track within a movie, including temporal, spatial, and volume information.";

// Enumeration for track header flags
set {
    TrackEnable = 0x1, // enabled track
    TrackInMovie = 0x2, // track in playback
    TrackInPreview = 0x4, // track in preview
    TrackInPoster = 0x8 // track in poster
} TrackHeaderFlags;


typedef struct {
    byte version;
    byte flag0;
    byte flag1;
    byte set TrackHeaderFlags flag2;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int trackId;
    byte[4] reserved;
    int duration;
    byte[8] reserved;
    short layer;
    short alternateGroup;
    fixed8d8 volume;
    byte[2] reserved;
    fixed16d16 matrixA;
    fixed16d16 matrixB;
    fixed2d30 matrixU;
    fixed16d16 matrixC;
    fixed16d16 matrixD;
    fixed2d30 matrixV;
    fixed16d16 matrixX;
    fixed16d16 matrixY;
    fixed2d30 matrixW;
    fixed16d16 trackWidth;
    fixed16d16 trackHeight;
} trackHeaderAtom;


magic mediaHeaderAtom "mdhd";
description mediaHeaderAtom "Media Header Atom", "The media header atom specifies the characteristics of the media that is used to store data for the movie track defined in its associated track atom.";

typedef struct {
    byte version;
    byte[3] flags;
    mactimestamp creationTime;
    mactimestamp modificationTime;
    int timeScale;
    int duration;
    short language;
    short quality;
} mediaHeaderAtom;


magic handlerReferenceAtom "hdlr";
description handlerReferenceAtom "Handler Reference Atom", "The handler reference atom specifies the component that is to interpret a media's data. This component is called a media handler.";

typedef struct {
    byte version;
    byte[3] flags;
    magic componentType;
    magic componentSubtype;
    magic componentManufacturer;
    int componentFlags;
    int componentFlagsMask;
    pstring componentName;
    ubyte[] extraData;
} handlerReferenceAtom;

magic movieAlbumAtom "©alb";
description movieAlbumAtom "Movie Album Atom", "";
typedef struct {
    pstring album;
} movieAlbumAtom;

magic movieArtistAtom "©ART";
description movieArtistAtom "Movie Artist Atom", "";
typedef struct {
    pstring artist;
} movieArtistAtom;

magic copyrightStatementAtom "©cpy";
typedef struct {
    pstring copyright;
} copyrightStatementAtom;

magic copyrightCommentsAtom "©cmt";
typedef struct {
    pstring comments;
} copyrightCommentsAtom;

magic creationDateAtom "©day";
description creationDateAtom "Movie Creation Date Atom", "";
typedef struct {
    pstring date;
} creationDateAtom;

magic movieDescriptionAtom "©des";
typedef struct {
    pstring description;
} movieDescriptionAtom;

magic movieDirectorAtom "©dir";
typedef struct {
    pstring director;
} movieDirectorAtom;

magic copyrightDisclaimerAtom "©dis";
typedef struct {
    pstring disclaimer;
} copyrightDisclaimerAtom;

magic editComment1Atom "©ed1";
typedef struct {
    pstring edit;
} editComment1Atom;

magic editComment2Atom "©ed2";
typedef struct {
    pstring edit;
} editComment2Atom;

magic editComment3Atom "©ed3";

typedef struct {
    pstring edit;
} editComment3Atom;

magic editComment4Atom "©ed4";

typedef struct {
    pstring edit;
} editComment4Atom;

magic editComment5Atom "©ed5";

typedef struct {
    pstring edit;
} editComment5Atom;

magic editComment6Atom "©ed6";

typedef struct {
    pstring edit;
} editComment7Atom;

magic editComment7Atom "©ed7";

typedef struct {
    pstring edit;
} editComment7Atom;

magic editComment8Atom "©ed8";
typedef struct {
    pstring edit;
} editComment8Atom;

magic editComment9Atom "©ed9";
typedef struct {
    pstring edit;
} editComment9Atom;

magic movieEncodingSoftwareAtom "©enc";
description movieEncodingSoftwareAtom "Movie Encoding Software Atom", "";
typedef struct {
    pstring encodingSoftware;
} movieEncodingSoftwareAtom;

magic formatAtom "©fmt";
typedef struct {
    pstring format;
} formatAtom;

magic movieInfoAtom "©inf";

typedef struct {
    pstring info;
} movieInfoAtom;

magic movieProducerAtom "©prd";
typedef struct {
    pstring producer;
} movieProducerAtom;

magic moviePerformersAtom "©prf";
typedef struct {
    pstring performer;
} moviePerformersAtom;

magic movieRequirementsAtom "©req";
typedef struct {
    pstring requirements;
} movieRequirementsAtom;

magic movieNameAtom "©nam";
description movieNameAtom "Movie Name Atom", "";
typedef struct {
    pstring name;
} movieNameAtom;

magic movieSourceCreditsAtom "©src";
typedef struct {
    pstring source;
} movieSourceCreditsAtom;

magic copyrightSoftwareAtom "©swr";
typedef struct {
    pstring software;
} copyrightSoftwareAtom;

magic movieTrackNumberAtom "©trk";
description movieTrackNumberAtom "Movie Track Number Atom", "";
typedef struct {
    pstring trackNumber;
} movieTrackNumberAtom;

magic movieWriterAtom "©wrt";
typedef struct {
    pstring writer;
} movieWriterAtom;

magic clippingRegionAtom "crgn";

typedef struct {
    short regionSize;
    short[4] regionBoundaryBox;
    byte[] clippingRegionData;
} clippingRegionAtom;

magic compressedMatteAtom "kmat";
description compressedMatteAtom "Compressed Matte Atom", "The compressed matte atom specifies the image description structure associated with a particular matte atom.";

typedef struct {
    byte versions;
    byte[3] flags;
    byte[] matteImageDescriptionStructureAndMatteData;
} compressedMatteAtom;

magic editListAtom "elst";
description editListAtom "Edit List Atom", "Edit list atoms specify how to map from a time in a movie to a time in a media, and ultimatively to media data";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    editListTable editListTable[numberOfEntries];
} editListAtom;

typedef struct {
    int trackDuration;
    int mediaTime;
    fixed16d16 mediaRate;
} editListTable;

magic videoMediaInformationHeaderAtom "vmhd";
description videoMediaInformationHeaderAtom "Video Media Information Header Atom", "Video media information atoms are the highest-level atoms in video media. A number of other atoms define specific characteristics of the video media data.";

set {
    videoFlagNoLeanAhead=1 // I am not shure if this is the correct value for this flag
} vmhdFlags;

enum {
    Copy = 0x0,  
    DitherCopy = 0x40,  
    Blend = 0x20, // uses opcolor  
    Transparent = 0x24, // uses opcolor  
    StraightAlpha = 0x100,  
    PremulWhiteAlpha = 0x101,  
    PremulBlackAlpha = 0x102,  
    StraightAlphaBlend = 0x104, // uses opclor  
    Composition = 0x103  
} GraphicsModes;

typedef struct {
    byte version;
    byte flag1;
    byte flag2;
    byte set vmhdFlags flag3;
    short enum GraphicsModes graphicsMode;
    ushort[3] opcolor;
} videoMediaInformationHeaderAtom;

magic soundMediaInformationHeaderAtom "smhd";
description soundMediaInformationHeaderAtom "Sound Media Information Header Atom", "The sound media information header atom stores the sound media information.";

typedef struct {
    uint size;
    magic type;
    ubyte version;  // A 1-byte specification of the version of this sound media information header atom.
    byte[3] flags; // A 3-byte space for sound media information flags. Set this field to 0.
    short balance;  // A 16-bit integer that specifies the sound balance of this
                    // sound media. Sound balance is the setting that controls
                    // the mix of sound between the two speakers of a computer.
                    // This field is normally set to 0.
                    // Balance values are represented as 16-bit, fixed-point
                    // numbers that range from -1.0 to +1.0. The high-order 8
                    // bits contain the integer portion of the value; the
                    // low-order 8 bits contain the fractional part. Negative
                    // values weight the balance toward the left speaker;
                    // positive values emphasize the right channel. Setting the
                    // balance to 0 corresponds to a neutral setting.
    short reserved; // Reserved for use by Apple. Set this field to 0.
} soundMediaInformationHeaderAtom;

magic genericMediaInformationHeaderAtom "gmhd";
description genericMediaInformationHeaderAtom "Generic Media Information Header Atom", "";

magic genericMediaInformationAtom "gmin";
description genericMediaInformationAtom "Generic Media Information Atom", "";

typedef struct {
    ubyte version;
    ubyte[3] flags;
    short graphicsMode;  //
    ushort opcolor1;  //
    ushort opcolor2;  //
    ushort opcolor3;  //
    ushort balance;  //
    ushort reserved; //
} genericMediaInformationAtom;

magic textMediaInformationAtom "text";
description textMediaInformationAtom "Text Media Information Atom", "";

typedef struct {
    fixed16d16 matrixA;
    fixed16d16 matrixB;
    fixed2d30 matrixU;
    fixed16d16 matrixC;
    fixed16d16 matrixD;
    fixed2d30 matrixV;
    fixed16d16 matrixX;
    fixed16d16 matrixY;
    fixed2d30 matrixW;
} textMediaInformationAtom;


magic trackReferenceAtom "tref";
description trackReferenceAtom "Track Reference Atom", "";


magic dataReferenceAtom "dref";
description dataReferenceAtom "Data Reference Atom", "The data reference atom encompasses the data references.";

typedef struct {
    ubyte version;
    ubyte[3] flags;
    int numberOfEntries;
    dataReferenceEntry dataReference[numberOfEntries];
} dataReferenceAtom;

set {
    dataRefSelfReference=1 // I am not shure if this is the correct value for this flag
} drefEntryFlags;

typedef struct {
    uint size;
    magic type;
    byte version;
    ubyte flag1;
    ubyte flag2;
    ubyte set drefEntryFlags flag3;
    ubyte[size - 12] data;
} dataReferenceEntry;

magic sampleDescriptionAtom "stsd";
description sampleDescriptionAtom  "Sample Description Atom", "The sample description atom stores information for the decoding of samples in the media. In the case of video media, the sample descriptions are image description structures.";

magic videoSampleDescriptionAtom "stsd (vmhd)";
description videoSampleDescriptionAtom  "Video Sample Description Atom",
    "The video sample description contains information that defines how to interpret video media data.";

magic soundSampleDescriptionAtom "stsd (smhd)";
description soundSampleDescriptionAtom  "Sound Sample Description Atom",
    "The sound sample description contains information that defines how to interpret sound media data.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    sampleDescriptionEntry sampleDescriptionTable[numberOfEntries];
} sampleDescriptionAtom;

typedef struct {
    int size;
    magic type;
    byte[6] reserved; // six bytes that must be zero
    short dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms. 
    ubyte[size - 16] data;
} sampleDescriptionEntry;

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    videoSampleDescriptionEntry sampleDescriptionTable[numberOfEntries];
} videoSampleDescriptionAtom;

typedef struct {
    int size;
    magic type;
    byte[6] reserved; // six bytes that must be zero
    short dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms.
    videoSampleDescription data;
} videoSampleDescriptionEntry;

typedef struct {
    ushort version;     // A 16-bit integer indicating the version number of the
                        // compressed data. This is set to 0, unless a
                        // compressor has changed its data format.
    ushort revisionLevel;// A 16-bit integer that must be set to 0.
    magic vendor;       // A 32-bit integer that specifies the developer of the
                        // compressor that generated the compressed data. Often
                        //  this field contains 'appl' to indicate Apple
                        // Computer, Inc.
    uint temporalQuality;// A 32-bit integer containing a value from 0 to 1023
                        // indicating the degree of temporal compression.
    uint spatialQuality;// A 32-bit integer containing a value from 0 to 1024
                        // indicating the degree of spatial compression.
    ushort width;       // A 16-bit integer that specifies the width of the
                        // source image in pixels.
    ushort height;      // A 16-bit integer that specifies the height of the
                        // source image in pixels.
    fixed16d16 horizontalResolution;
                        // A 32-bit fixed-point number containing the horizontal
                        // resolution of the image in pixels per inch.
    fixed16d16 verticalResolution;
                        // A 32-bit fixed-point number containing the vertical
                        // resolution of the image in pixels per inch.
    uint dataSize;      // A 32-bit integer that must be set to 0.
    ushort frameCount;  // A 16-bit integer that indicates how many frames of
                        // compressed data are stored in each sample. Usually
                        // set to 1.
    pstring32 compressorName;// A 32-byte Pascal string containing the name of the
                        // compressor that created the image, such as "jpeg".
    ushort depth;       // A 16-bit integer that indicates the pixel depth of
                        // the compressed image. Values of 1, 2, 4, 8 ,16, 24,
                        // and 32 indicate the depth of color images. The value
                        // 32 should be used only if the image contains an alpha
                        // channel. Values of 34, 36, and 40 indicate 2-, 4-,
                        // and 8-bit grayscale, respectively, for grayscale
                        // images.
    ushort colorTableId; // A 16-bit integer that identifies which color table to
                        // use. If this field is set to –1, the default color
                        // table should be used for the specified depth. For all
                        // depths below 16 bits per pixel, this indicates a
                        // standard Macintosh color table for the specified
                        // depth. Depths of 16, 24, and 32 have no color table.
                        // If the color table ID is set to 0, a color table is
                        // contained within the sample description itself. The
                        // color table immediately follows the color table ID
                        // field in the sample description. See “Color Table
                        // Atoms” (page 41) for a complete description of a color table.

    videoSampleDescriptionExtension[] extendedData;
} videoSampleDescription;

typedef struct {
    uint dataSize;
    magic type;
    ubyte[dataSize - 8] data;
} videoSampleDescriptionExtension;

typedef struct {
    byte version; // A 1-byte specification of the version of this sample description atom.
    byte[3] flags; // A 3-byte space for sample description flags. Set this field to 0.
    int numberOfEntries; // A 32-bit integer containing the number of sample descriptions that follow.
    soundSampleDescriptionEntry sampleDescriptionTable[numberOfEntries];
} soundSampleDescriptionAtom;

typedef struct {
} soundSampleDescriptionAtomV1;



typedef struct {
    int size; // A 32-bit integer indicating the number of bytes in the sample description.
    magic type;         // A 32-bit integer indicating the format of the stored data.
        // This depends on the media type, but is usually either the
        // compression format or the media type.
    byte[6] reserved; // six bytes that must be zero
    short dataReferenceIndex; // A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms.
    soundSampleDescription data;
} soundSampleDescriptionEntry;

enum {
    version0 = 0, // compressionId must be 0 for version 0 sound sample description.
    uncompressedAudio = -1,
    compressedAudio = -2,
} soundSampleCompressionId;


typedef struct {
    ushort version;     // A 16-bit integer that holds the sample description
                        // version (currently 0 or 1).
    ushort revisionLevel;// A 16-bit integer that must be set to 0.
    uint vendor;        // A 32-bit integer that must be set to 0.
    ushort numberOfChannels;
                        // A 16-bit integer that indicates the number of sound
                        // channels used by the sound sample. Set to 1 for
                        // monaural sounds, 2 for stereo sounds.
                        // Higher numbers of channels are not supported.
    ushort sampleSize;  // A 16-bit integer that specifies the number of bits in
                        // each uncompressed sound sample. Allowable values are
                        // 8 or 16. Formats using more than 16 bits per sample
                        // set this field to 16 and use sound description
                        // version 1.
    short enum soundSampleCompressionId compressionId;// A 16-bit integer that must be set to 0 for version 0
                        // sound descriptions. This may be set to –2 for some
                        // version 1 sound descriptions; see “Redefined Sample
                        // Tables” (page 115).
    ushort packetSize;  // A 16-bit integer that must be set to 0.
    fixed16d16 sampleRate;// A 32-bit unsigned fixed-point number (16.16) that
                        // indicates the rate at which the sound samples were
                        // obtained. The integer portion of this number should
                        // match the media’s time scale. Many older version 0
                        // files have values of 22254.5454 or 11127.2727, but
                        // most files have integer values, such as 44100. Sample
                        // rates greater than 2^16 are not supported.
  soundSampleDescriptionV1[version] v1; // Additional fields for version 1
  soundSampleDescriptionExtension[] extendedData;
} soundSampleDescription;

typedef struct {
    uint samplesPerPacket;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The number of uncompressed frames generated by a
                        // compressed frame (an uncompressed frame is one sample
                        // from each channel). This is also the frame duration,
                        // expressed in the media’s timescale, where the
                        // timescale is equal to the sample rate. For
                        // uncompressed formats, this field is always 1.
    uint bytesPerPacket;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // For uncompressed audio, the number of bytes in a
                        // sample for a single channel. This replaces the older
                        // sampleSize field, which is set to 16.
                        // This value is calculated by dividing the frame size
                        // by the number of channels. The same calculation is
                        // performed to calculate the value of this field for
                        // compressed audio, but the result of the calculation
                        // is not generally meaningful for compressed audio.
    uint bytesPerFrame;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The number of bytes in a frame: for uncompressed
                        // audio, an uncompressed frame; for compressed audio, a
                        // compressed frame. This can be calculated by
                        // multiplying the bytes per packet field by the number
                        // of channels.
    uint bytesPerSample;
                        // This field is only present if version == 1.
                        // A 32-bit integer.
                        // The size of an uncompressed sample in bytes. This is
                        // set to 1 for 8-bit audio, 2 for all other cases, even
                        // if the sample size is greater than 2 bytes.
} soundSampleDescriptionV1;

typedef struct {
    uint dataSize;
    magic type;
    ubyte[dataSize - 8] data;
} soundSampleDescriptionExtension;



magic timeToSampleAtom "stts";
description timeToSampleAtom "Time-to-Sample Atom", "Time-to-sample atoms store duration information for the samples in a media, providing a mapping from a time in a media to the corresponding data sample.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    timeToSampleTable timeToSampleTable[numberOfEntries];
} timeToSampleAtom;

typedef struct {
    int sampleCount;
    int sampleDuration;
} timeToSampleTable;

magic syncSampleAtom "stss";
description syncSampleAtom "Sync Sample Atom", "The sync sample atom identifies the key frames in the media. In a media that contains compressed data, key frames define starting points for portions of a temporally compressed sequence. The key frame is self-contained - that is, it is independent of preceding frames. Subsequent frames may depend on the key frame.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    syncSampleTable syncSampleTable[numberOfEntries];
} syncSampleAtom;

typedef struct {
    int number;
} syncSampleTable;

magic sampleToChunkAtom "stsc";
description sampleToChunkAtom "Sample-to-Chunk Atom", "As samples are added to a media, they are collected into chunks that allow optimized data access. A chunk may contain one or more samples. Chunks in a media may have different sizes, and the samples within a chunk may have different sizes.";

typedef struct {
    byte version;
    byte[3] flags;
    int numberOfEntries;
    sampleToChunkTable sampleToChunkTable[numberOfEntries];
} sampleToChunkAtom;

typedef struct {
    int firstChunk;
    int samplesPerChunk;
    int sampleDescription;
} sampleToChunkTable;

magic sampleSizeAtom "stsz";
description sampleSizeAtom "Sample Size Atom", "Sample size atoms identify the size of each sample in the media.";

typedef struct {
    byte version;
    byte[3] flags;
    int sampleSize;
    int numberOfEntries;
    sampleSizeTable sampleSizeTable[numberOfEntries];
} sampleSizeAtom;

typedef struct {
    int size;
} sampleSizeTable;

magic chunkOffsetAtom "stco";
description chunkOffsetAtom "Chunk Offset Atom", "Chunk offset atoms identify the location of each chunk of data in the media's data stream, relative to the beginning of the file.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    chunkOffsetTable chunkOffsetTable[numberOfEntries];
} chunkOffsetAtom;

typedef struct {
    uint offset;
} chunkOffsetTable;

magic chunkOffset64Atom "co64";
description chunkOffset64Atom "Chunk Offset 64-bit Atom", "Chunk offset atoms identify the location of each chunk of data in the media's data stream, relative to the beginning of the file.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    chunkOffset64Table chunkOffsetTable[numberOfEntries];
} chunkOffset64Atom;

typedef struct {
    long offset;
} chunkOffset64Table;

magic shadowSyncAtom "stsh";
description shadowSyncAtom "Shadow Sync Atom", "Shadow sync atoms contain self-contained samples that are alternates for existing frame difference samples. Shadow sync atoms are used to optimiye random access operations on a movie. Scrubbing is an example of such a random access operation. These atoms are used to enhance playback performance.";

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    shadowSyncTable shadowSyncTable[numberOfEntries];
} shadowSyncAtom;

typedef struct {
    int frameDifferenceSampleNumber;
    int syncSampleNumber;
} shadowSyncTable;

typedef struct {
    short x;
    short y;
} windowLocationAtom;

magic loopAtom "LOOP";
description loopAtom "Loop All Frames Atom", "";

typedef struct {
    uint loop;  //
} loopAtom;



// Atoms from MPEG-4: ISO/IEC 14496-12:2008(E)

magic cttsAtom "ctts";
description cttsAtom "Composition Time to Sample Atom",
"This atom provides the offset between decoding time and composition time. "+
"The offsets are expressed as signed numbers such that CT(n) = DT(n) + CTTS(n) "+
"where CTTS(n) is the (uncompressed) table entry for sample n."+
"The composition time to sample table is optional and must only be present if "+
"DT and CT differ for any samples. Hint tracks do not use this box.";

typedef struct {
    uint sampleCount;
    int sampleOffset; // signed!
} cttsEntry;

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    cttsEntry entry[numberOfEntries];
} cttsAtom;


magic sdtpAtom "sdtp";
description sdtpAtom "Independent And Disposable Samples Atom",
"This optional table answers three questions about sample dependency: "+
"<ol>"+
"<li>does this sample depend on others (is it an I-picture)?</li>"+
"<li>do no other samples depend on this one?</li>"+
"<li>does this sample contain multiple (redundant) encodings of the data at "+
"this time-instant (possibly with different dependencies)?</li>"+
"</ol>";
/*
"In the absence of this table: "+
"<ol>"+
"<li>the sync sample table answers the first question; in most video codecs, "+
"I-pictures are also sync points,</li>"+
"<li>the dependency of other samples on this one is unknown.</li>"+
"<li>the existence of redundant coding is unknown.</li>"+
"</ol>";
*/
enum {
    unknown = 0,
    isDependent = 1,
    isIndependent = 2,
    reserved = 3,
} sdtpSampleDependsOn;

enum {
    unknown = 0,
    hasDependents = 1,
    noDependents = 2,
    reserved = 3,
} sdtpSampleIsDependedOn;

enum {
    unknown = 0,
    hasRedundancy = 1,
    noRedundancy = 2,
    reserved = 3,
} sdtpSampleHasRedundancy;

typedef struct {
    uint2 reserved;
    uint2 enum sdtpSampleDependsOn sampleDependsOn;
    uint2 enum sdtpSampleIsDependedOn sampleIsDependedOn;
    uint2 enum sdtpSampleHasRedundancy sampleHasRedundancy;
} sdtpSample;

typedef struct {
    byte version;
    byte[3] flags;
    sdtpSample sample[];
} sdtpAtom;



// Atoms from Apple Atom Inspector

magic cslgAtom "cslg";
description cslgAtom "Composition Shift Info Atom",
"";

typedef struct {
    byte version;
    byte[3] flags;
    int shift;
    int leastDelta;
    int greatestDelta;
    uint displayStartTime;
    uint displayEndTime;
} cslgAtom;


magic stpsAtom "stps";
description stpsAtom "Partial Sync Samples Atom",
"";

typedef struct {
    uint sample;
} stpsEntry;

typedef struct {
    byte version;
    byte[3] flags;
    uint numberOfEntries;
    stpsEntry entry[numberOfEntries];
} stpsAtom;
