# -*- coding: UTF-8 -*-

"""
RIFF parser, able to parse:
   * AVI video container
   * WAV audio container
   * CDA file

Documents:
- libavformat source code from ffmpeg library
  http://ffmpeg.mplayerhq.hu/
- Video for Windows Programmer's Guide
  http://www.opennet.ru/docs/formats/avi.txt
- What is an animated cursor?
  http://www.gdgsoft.com/anituner/help/aniformat.htm

Authors:
   * Aurélien Jacobs
   * Mickaël KENIKSSI
   * Victor Stinner
Changelog:
   * 2007-03-30: support ACON (animated icons)
   * 2006-08-08: merge AVI, WAV and CDA parsers into RIFF parser
   * 2006-08-03: creation of CDA parser by Mickaël KENIKSSI
   * 2005-06-21: creation of WAV parser by Victor Stinner
   * 2005-06-08: creation of AVI parser by Victor Stinner and Aurélien Jacobs
Thanks to:
   * Wojtek Kaniewski (wojtekka AT logonet.com.pl) for its CDA file
     format information
"""

from lib.hachoir_parser import Parser
from lib.hachoir_core.field import (FieldSet, ParserError,
    UInt8, UInt16, UInt32, Enum,
    Bit, NullBits, NullBytes,
    RawBytes, String, PaddingBytes,
    SubFile)
from lib.hachoir_core.tools import alignValue, humanDuration
from lib.hachoir_core.endian import LITTLE_ENDIAN
from lib.hachoir_core.text_handler import filesizeHandler, textHandler
from lib.hachoir_parser.video.fourcc import audio_codec_name, video_fourcc_name
from lib.hachoir_parser.image.ico import IcoFile
from datetime import timedelta

def parseText(self):
    yield String(self, "text", self["size"].value,
        strip=" \0", truncate="\0",
        charset="ISO-8859-1")

def parseRawFormat(self, size):
    yield RawBytes(self, "raw_format", size)

def parseVideoFormat(self, size):
    yield UInt32(self, "video_size", "Video format: Size")
    yield UInt32(self, "width", "Video format: Width")
    yield UInt32(self, "height", "Video format: Height")
    yield UInt16(self, "panes", "Video format: Panes")
    yield UInt16(self, "depth", "Video format: Depth")
    yield UInt32(self, "tag1", "Video format: Tag1")
    yield UInt32(self, "img_size", "Video format: Image size")
    yield UInt32(self, "xpels_meter", "Video format: XPelsPerMeter")
    yield UInt32(self, "ypels_meter", "Video format: YPelsPerMeter")
    yield UInt32(self, "clr_used", "Video format: ClrUsed")
    yield UInt32(self, "clr_important", "Video format: ClrImportant")

def parseAudioFormat(self, size):
    yield Enum(UInt16(self, "codec", "Audio format: Codec id"), audio_codec_name)
    yield UInt16(self, "channel", "Audio format: Channels")
    yield UInt32(self, "sample_rate", "Audio format: Sample rate")
    yield UInt32(self, "bit_rate", "Audio format: Bit rate")
    yield UInt16(self, "block_align", "Audio format: Block align")
    if size >= 16:
        yield UInt16(self, "bits_per_sample", "Audio format: Bits per sample")
    if size >= 18:
        yield UInt16(self, "ext_size", "Audio format: Size of extra information")
    if size >= 28: # and self["a_channel"].value > 2
        yield UInt16(self, "reserved", "Audio format: ")
        yield UInt32(self, "channel_mask", "Audio format: channels placement bitmask")
        yield UInt32(self, "subformat", "Audio format: Subformat id")

def parseAVIStreamFormat(self):
    size = self["size"].value
    strtype = self["../stream_hdr/stream_type"].value
    TYPE_HANDLER = {
        "vids": (parseVideoFormat, 40),
        "auds": (parseAudioFormat, 16)
    }
    handler = parseRawFormat
    if strtype in TYPE_HANDLER:
        info = TYPE_HANDLER[strtype]
        if info[1] <= size:
            handler = info[0]
    for field in handler(self, size):
        yield field

def parseAVIStreamHeader(self):
    if self["size"].value != 56:
        raise ParserError("Invalid stream header size")
    yield String(self, "stream_type", 4, "Stream type four character code", charset="ASCII")
    field = String(self, "fourcc", 4, "Stream four character code", strip=" \0", charset="ASCII")
    if self["stream_type"].value == "vids":
        yield Enum(field, video_fourcc_name, lambda text: text.upper())
    else:
        yield field
    yield UInt32(self, "flags", "Stream flags")
    yield UInt16(self, "priority", "Stream priority")
    yield String(self, "language", 2, "Stream language", charset="ASCII", strip="\0")
    yield UInt32(self, "init_frames", "InitialFrames")
    yield UInt32(self, "scale", "Time scale")
    yield UInt32(self, "rate", "Divide by scale to give frame rate")
    yield UInt32(self, "start", "Stream start time (unit: rate/scale)")
    yield UInt32(self, "length", "Stream length (unit: rate/scale)")
    yield UInt32(self, "buf_size", "Suggested buffer size")
    yield UInt32(self, "quality", "Stream quality")
    yield UInt32(self, "sample_size", "Size of samples")
    yield UInt16(self, "left", "Destination rectangle (left)")
    yield UInt16(self, "top", "Destination rectangle (top)")
    yield UInt16(self, "right", "Destination rectangle (right)")
    yield UInt16(self, "bottom", "Destination rectangle (bottom)")

class RedBook(FieldSet):
    """
    RedBook offset parser, used in CD audio (.cda) file
    """
    def createFields(self):
        yield UInt8(self, "frame")
        yield UInt8(self, "second")
        yield UInt8(self, "minute")
        yield PaddingBytes(self, "notused", 1)

def formatSerialNumber(field):
    """
    Format an disc serial number.
    Eg. 0x00085C48 => "0008-5C48"
    """
    sn = field.value
    return "%04X-%04X" % (sn >> 16, sn & 0xFFFF)

def parseCDDA(self):
    """
    HSG address format: number of 1/75 second

    HSG offset = (minute*60 + second)*75 + frame + 150 (from RB offset)
    HSG length = (minute*60 + second)*75 + frame (from RB length)
    """
    yield UInt16(self, "cda_version", "CD file version (currently 1)")
    yield UInt16(self, "track_no", "Number of track")
    yield textHandler(UInt32(self, "disc_serial", "Disc serial number"),
        formatSerialNumber)
    yield UInt32(self, "hsg_offset", "Track offset (HSG format)")
    yield UInt32(self, "hsg_length", "Track length (HSG format)")
    yield RedBook(self, "rb_offset", "Track offset (Red-book format)")
    yield RedBook(self, "rb_length", "Track length (Red-book format)")

def parseWAVFormat(self):
    size = self["size"].value
    if size not in (16, 18):
        self.warning("Format with size of %s bytes is not supported!" % size)
    yield Enum(UInt16(self, "codec", "Audio codec"), audio_codec_name)
    yield UInt16(self, "nb_channel", "Number of audio channel")
    yield UInt32(self, "sample_per_sec", "Sample per second")
    yield UInt32(self, "byte_per_sec", "Average byte per second")
    yield UInt16(self, "block_align", "Block align")
    yield UInt16(self, "bit_per_sample", "Bits per sample")

def parseWAVFact(self):
    yield UInt32(self, "nb_sample", "Number of samples in audio stream")

def parseAviHeader(self):
    yield UInt32(self, "microsec_per_frame", "Microsecond per frame")
    yield UInt32(self, "max_byte_per_sec", "Maximum byte per second")
    yield NullBytes(self, "reserved", 4)

    # Flags
    yield NullBits(self, "reserved[]", 4)
    yield Bit(self, "has_index")
    yield Bit(self, "must_use_index")
    yield NullBits(self, "reserved[]", 2)
    yield Bit(self, "is_interleaved")
    yield NullBits(self, "reserved[]", 2)
    yield Bit(self, "trust_cktype")
    yield NullBits(self, "reserved[]", 4)
    yield Bit(self, "was_capture_file")
    yield Bit(self, "is_copyrighted")
    yield NullBits(self, "reserved[]", 14)

    yield UInt32(self, "total_frame", "Total number of frames in the video")
    yield UInt32(self, "init_frame", "Initial frame (used in interleaved video)")
    yield UInt32(self, "nb_stream", "Number of streams")
    yield UInt32(self, "sug_buf_size", "Suggested buffer size")
    yield UInt32(self, "width", "Width in pixel")
    yield UInt32(self, "height", "Height in pixel")
    yield UInt32(self, "scale")
    yield UInt32(self, "rate")
    yield UInt32(self, "start")
    yield UInt32(self, "length")

def parseODML(self):
    yield UInt32(self, "total_frame", "Real number of frame of OpenDML video")
    padding = self["size"].value - 4
    if 0 < padding:
        yield NullBytes(self, "padding[]", padding)

class AVIIndexEntry(FieldSet):
    size = 16*8
    def createFields(self):
        yield String(self, "tag", 4, "Tag", charset="ASCII")
        yield UInt32(self, "flags")
        yield UInt32(self, "start", "Offset from start of movie data")
        yield UInt32(self, "length")

def parseIndex(self):
    while not self.eof:
        yield AVIIndexEntry(self, "index[]")

class Chunk(FieldSet):
    TAG_INFO = {
        # This dictionnary is edited by RiffFile.validate()

        "LIST": ("list[]", None, "Sub-field list"),
        "JUNK": ("junk[]", None, "Junk (padding)"),

        # Metadata
        "INAM": ("title", parseText, "Document title"),
        "IART": ("artist", parseText, "Artist"),
        "ICMT": ("comment", parseText, "Comment"),
        "ICOP": ("copyright", parseText, "Copyright"),
        "IENG": ("author", parseText, "Author"),
        "ICRD": ("creation_date", parseText, "Creation date"),
        "ISFT": ("producer", parseText, "Producer"),
        "IDIT": ("datetime", parseText, "Date time"),

        # TODO: Todo: see below
        # "strn": Stream description
        # TWOCC code, movie/field[]/tag.value[2:4]:
        #   "db": "Uncompressed video frame",
        #   "dc": "Compressed video frame",
        #   "wb": "Audio data",
        #   "pc": "Palette change"
    }

    subtag_info = {
        "INFO": ("info", "File informations"),
        "hdrl": ("headers", "Headers"),
        "strl": ("stream[]", "Stream header list"),
        "movi": ("movie", "Movie stream"),
        "odml": ("odml", "ODML"),
    }

    def __init__(self, *args, **kw):
        FieldSet.__init__(self, *args, **kw)
        self._size = (8 + alignValue(self["size"].value, 2)) * 8
        tag = self["tag"].value
        if tag in self.TAG_INFO:
            self.tag_info = self.TAG_INFO[tag]
            if tag == "LIST":
                subtag = self["subtag"].value
                if subtag in self.subtag_info:
                    info = self.subtag_info[subtag]
                    self.tag_info = (info[0], None, info[1])
            self._name = self.tag_info[0]
            self._description = self.tag_info[2]
        else:
            self.tag_info = ("field[]", None, None)

    def createFields(self):
        yield String(self, "tag", 4, "Tag", charset="ASCII")
        yield filesizeHandler(UInt32(self, "size", "Size"))
        if not self["size"].value:
            return
        if self["tag"].value == "LIST":
            yield String(self, "subtag", 4, "Sub-tag", charset="ASCII")
            handler = self.tag_info[1]
            while 8 < (self.size - self.current_size)/8:
                field = self.__class__(self, "field[]")
                yield field
                if (field.size/8) % 2 != 0:
                    yield UInt8(self, "padding[]", "Padding")
        else:
            handler = self.tag_info[1]
            if handler:
                for field in handler(self):
                    yield field
            else:
                yield RawBytes(self, "raw_content", self["size"].value)
            padding = self.seekBit(self._size)
            if padding:
                yield padding

    def createDescription(self):
        tag = self["tag"].display
        return u"Chunk (tag %s)" % tag

class ChunkAVI(Chunk):
    TAG_INFO = Chunk.TAG_INFO.copy()
    TAG_INFO.update({
        "strh": ("stream_hdr", parseAVIStreamHeader, "Stream header"),
        "strf": ("stream_fmt", parseAVIStreamFormat, "Stream format"),
        "avih": ("avi_hdr", parseAviHeader, "AVI header"),
        "idx1": ("index", parseIndex, "Stream index"),
        "dmlh": ("odml_hdr", parseODML, "ODML header"),
    })

class ChunkCDDA(Chunk):
    TAG_INFO = Chunk.TAG_INFO.copy()
    TAG_INFO.update({
        'fmt ': ("cdda", parseCDDA, "CD audio informations"),
    })

class ChunkWAVE(Chunk):
    TAG_INFO = Chunk.TAG_INFO.copy()
    TAG_INFO.update({
        'fmt ': ("format", parseWAVFormat, "Audio format"),
        'fact': ("nb_sample", parseWAVFact, "Number of samples"),
        'data': ("audio_data", None, "Audio stream data"),
    })

def parseAnimationHeader(self):
    yield UInt32(self, "hdr_size", "Size of header (36 bytes)")
    if self["hdr_size"].value != 36:
        self.warning("Animation header with unknown size (%s)" % self["size"].value)
    yield UInt32(self, "nb_frame", "Number of unique Icons in this cursor")
    yield UInt32(self, "nb_step", "Number of Blits before the animation cycles")
    yield UInt32(self, "cx")
    yield UInt32(self, "cy")
    yield UInt32(self, "bit_count")
    yield UInt32(self, "planes")
    yield UInt32(self, "jiffie_rate", "Default Jiffies (1/60th of a second) if rate chunk not present")
    yield Bit(self, "is_icon")
    yield NullBits(self, "padding", 31)

def parseAnimationSequence(self):
    while not self.eof:
        yield UInt32(self, "icon[]")

def formatJiffie(field):
    sec = float(field.value) / 60
    return humanDuration(timedelta(seconds=sec))

def parseAnimationRate(self):
    while not self.eof:
        yield textHandler(UInt32(self, "rate[]"), formatJiffie)

def parseIcon(self):
    yield SubFile(self, "icon_file", self["size"].value, parser_class=IcoFile)

class ChunkACON(Chunk):
    TAG_INFO = Chunk.TAG_INFO.copy()
    TAG_INFO.update({
        'anih': ("anim_hdr", parseAnimationHeader, "Animation header"),
        'seq ': ("anim_seq", parseAnimationSequence, "Animation sequence"),
        'rate': ("anim_rate", parseAnimationRate, "Animation sequence"),
        'icon': ("icon[]", parseIcon, "Icon"),
    })

class RiffFile(Parser):
    PARSER_TAGS = {
        "id": "riff",
        "category": "container",
        "file_ext": ("avi", "cda", "wav", "ani"),
        "min_size": 16*8,
        "mime": (u"video/x-msvideo", u"audio/x-wav", u"audio/x-cda"),
        # FIXME: Use regex "RIFF.{4}(WAVE|CDDA|AVI )"
        "magic": (
            ("AVI LIST", 8*8),
            ("WAVEfmt ", 8*8),
            ("CDDAfmt ", 8*8),
            ("ACONanih", 8*8),
        ),
        "description": "Microsoft RIFF container"
    }
    VALID_TYPES = {
        "WAVE": (ChunkWAVE, u"audio/x-wav",     u"Microsoft WAVE audio", ".wav"),
        "CDDA": (ChunkCDDA, u"audio/x-cda",     u"Microsoft Windows audio CD file (cda)", ".cda"),
        "AVI ": (ChunkAVI,  u"video/x-msvideo", u"Microsoft AVI video", ".avi"),
        "ACON": (ChunkACON, u"image/x-ani",     u"Microsoft Windows animated cursor", ".ani"),
    }
    endian = LITTLE_ENDIAN

    def validate(self):
        if self.stream.readBytes(0, 4) != "RIFF":
            return "Wrong signature"
        if self["type"].value not in self.VALID_TYPES:
            return "Unknown RIFF content type"
        return True

    def createFields(self):
        yield String(self, "signature", 4, "AVI header (RIFF)", charset="ASCII")
        yield filesizeHandler(UInt32(self, "filesize", "File size"))
        yield String(self, "type", 4, "Content type (\"AVI \", \"WAVE\", ...)", charset="ASCII")

        # Choose chunk type depending on file type
        try:
            chunk_cls = self.VALID_TYPES[self["type"].value][0]
        except KeyError:
            chunk_cls = Chunk

        # Parse all chunks up to filesize
        while self.current_size < self["filesize"].value*8+8:
            yield chunk_cls(self, "chunk[]")
        if not self.eof:
            yield RawBytes(self, "padding[]", (self.size-self.current_size)/8)

    def createMimeType(self):
        try:
            return self.VALID_TYPES[self["type"].value][1]
        except KeyError:
            return None

    def createDescription(self):
        tag = self["type"].value
        if tag == "AVI ":
            desc = u"Microsoft AVI video"
            if "headers/avi_hdr" in self:
                header = self["headers/avi_hdr"]
                desc += ": %ux%u pixels" % (header["width"].value, header["height"].value)
                microsec = header["microsec_per_frame"].value
                if microsec:
                    desc += ", %.1f fps" % (1000000.0 / microsec)
                    if "total_frame" in header and header["total_frame"].value:
                        delta = timedelta(seconds=float(header["total_frame"].value) * microsec)
                        desc += ", " + humanDuration(delta)
            return desc
        else:
            try:
                return self.VALID_TYPES[tag][2]
            except KeyError:
                return u"Microsoft RIFF container"

    def createContentSize(self):
        size = (self["filesize"].value + 8) * 8
        return min(size, self.stream.size)

    def createFilenameSuffix(self):
        try:
            return self.VALID_TYPES[self["type"].value][3]
        except KeyError:
            return ".riff"


[((100, 12, 100, 97), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((46, 10, 48, 29), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((51, 10, 51, 44), 'lib.hachoir_core.field.RawBytes', 'RawBytes', ({(51, 19, 51, 23): 'self', (51, 25, 51, 37): '"""raw_format"""', (51, 39, 51, 43): 'size'}, {}), "(self, 'raw_format', size)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((54, 10, 54, 58), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(54, 17, 54, 21): 'self', (54, 23, 54, 35): '"""video_size"""', (54, 37, 54, 57): '"""Video format: Size"""'}, {}), "(self, 'video_size', 'Video format: Size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((55, 10, 55, 54), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(55, 17, 55, 21): 'self', (55, 23, 55, 30): '"""width"""', (55, 32, 55, 53): '"""Video format: Width"""'}, {}), "(self, 'width', 'Video format: Width')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((56, 10, 56, 56), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(56, 17, 56, 21): 'self', (56, 23, 56, 31): '"""height"""', (56, 33, 56, 55): '"""Video format: Height"""'}, {}), "(self, 'height', 'Video format: Height')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((57, 10, 57, 54), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(57, 17, 57, 21): 'self', (57, 23, 57, 30): '"""panes"""', (57, 32, 57, 53): '"""Video format: Panes"""'}, {}), "(self, 'panes', 'Video format: Panes')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((58, 10, 58, 54), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(58, 17, 58, 21): 'self', (58, 23, 58, 30): '"""depth"""', (58, 32, 58, 53): '"""Video format: Depth"""'}, {}), "(self, 'depth', 'Video format: Depth')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((59, 10, 59, 52), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(59, 17, 59, 21): 'self', (59, 23, 59, 29): '"""tag1"""', (59, 31, 59, 51): '"""Video format: Tag1"""'}, {}), "(self, 'tag1', 'Video format: Tag1')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((60, 10, 60, 62), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(60, 17, 60, 21): 'self', (60, 23, 60, 33): '"""img_size"""', (60, 35, 60, 61): '"""Video format: Image size"""'}, {}), "(self, 'img_size', 'Video format: Image size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((61, 10, 61, 68), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(61, 17, 61, 21): 'self', (61, 23, 61, 36): '"""xpels_meter"""', (61, 38, 61, 67): '"""Video format: XPelsPerMeter"""'}, {}), "(self, 'xpels_meter', 'Video format: XPelsPerMeter')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((62, 10, 62, 68), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(62, 17, 62, 21): 'self', (62, 23, 62, 36): '"""ypels_meter"""', (62, 38, 62, 67): '"""Video format: YPelsPerMeter"""'}, {}), "(self, 'ypels_meter', 'Video format: YPelsPerMeter')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((63, 10, 63, 59), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(63, 17, 63, 21): 'self', (63, 23, 63, 33): '"""clr_used"""', (63, 35, 63, 58): '"""Video format: ClrUsed"""'}, {}), "(self, 'clr_used', 'Video format: ClrUsed')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((64, 10, 64, 69), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(64, 17, 64, 21): 'self', (64, 23, 64, 38): '"""clr_important"""', (64, 40, 64, 68): '"""Video format: ClrImportant"""'}, {}), "(self, 'clr_important', 'Video format: ClrImportant')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((68, 10, 68, 59), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(68, 17, 68, 21): 'self', (68, 23, 68, 32): '"""channel"""', (68, 34, 68, 58): '"""Audio format: Channels"""'}, {}), "(self, 'channel', 'Audio format: Channels')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((69, 10, 69, 66), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(69, 17, 69, 21): 'self', (69, 23, 69, 36): '"""sample_rate"""', (69, 38, 69, 65): '"""Audio format: Sample rate"""'}, {}), "(self, 'sample_rate', 'Audio format: Sample rate')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((70, 10, 70, 60), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(70, 17, 70, 21): 'self', (70, 23, 70, 33): '"""bit_rate"""', (70, 35, 70, 59): '"""Audio format: Bit rate"""'}, {}), "(self, 'bit_rate', 'Audio format: Bit rate')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((71, 10, 71, 66), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(71, 17, 71, 21): 'self', (71, 23, 71, 36): '"""block_align"""', (71, 38, 71, 65): '"""Audio format: Block align"""'}, {}), "(self, 'block_align', 'Audio format: Block align')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((98, 14, 98, 55), 'lib.hachoir_core.field.ParserError', 'ParserError', ({(98, 26, 98, 54): '"""Invalid stream header size"""'}, {}), "('Invalid stream header size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((99, 10, 99, 92), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((105, 10, 105, 47), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(105, 17, 105, 21): 'self', (105, 23, 105, 30): '"""flags"""', (105, 32, 105, 46): '"""Stream flags"""'}, {}), "(self, 'flags', 'Stream flags')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((106, 10, 106, 53), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(106, 17, 106, 21): 'self', (106, 23, 106, 33): '"""priority"""', (106, 35, 106, 52): '"""Stream priority"""'}, {}), "(self, 'priority', 'Stream priority')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((107, 10, 107, 85), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((108, 10, 108, 54), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(108, 17, 108, 21): 'self', (108, 23, 108, 36): '"""init_frames"""', (108, 38, 108, 53): '"""InitialFrames"""'}, {}), "(self, 'init_frames', 'InitialFrames')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((109, 10, 109, 45), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(109, 17, 109, 21): 'self', (109, 23, 109, 30): '"""scale"""', (109, 32, 109, 44): '"""Time scale"""'}, {}), "(self, 'scale', 'Time scale')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((110, 10, 110, 68), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(110, 17, 110, 21): 'self', (110, 23, 110, 29): '"""rate"""', (110, 31, 110, 67): '"""Divide by scale to give frame rate"""'}, {}), "(self, 'rate', 'Divide by scale to give frame rate')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((111, 10, 111, 71), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(111, 17, 111, 21): 'self', (111, 23, 111, 30): '"""start"""', (111, 32, 111, 70): '"""Stream start time (unit: rate/scale)"""'}, {}), "(self, 'start', 'Stream start time (unit: rate/scale)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((112, 10, 112, 68), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(112, 17, 112, 21): 'self', (112, 23, 112, 31): '"""length"""', (112, 33, 112, 67): '"""Stream length (unit: rate/scale)"""'}, {}), "(self, 'length', 'Stream length (unit: rate/scale)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((113, 10, 113, 59), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(113, 17, 113, 21): 'self', (113, 23, 113, 33): '"""buf_size"""', (113, 35, 113, 58): '"""Suggested buffer size"""'}, {}), "(self, 'buf_size', 'Suggested buffer size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((114, 10, 114, 51), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(114, 17, 114, 21): 'self', (114, 23, 114, 32): '"""quality"""', (114, 34, 114, 50): '"""Stream quality"""'}, {}), "(self, 'quality', 'Stream quality')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((115, 10, 115, 56), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(115, 17, 115, 21): 'self', (115, 23, 115, 36): '"""sample_size"""', (115, 38, 115, 55): '"""Size of samples"""'}, {}), "(self, 'sample_size', 'Size of samples')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((116, 10, 116, 62), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(116, 17, 116, 21): 'self', (116, 23, 116, 29): '"""left"""', (116, 31, 116, 61): '"""Destination rectangle (left)"""'}, {}), "(self, 'left', 'Destination rectangle (left)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((117, 10, 117, 60), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(117, 17, 117, 21): 'self', (117, 23, 117, 28): '"""top"""', (117, 30, 117, 59): '"""Destination rectangle (top)"""'}, {}), "(self, 'top', 'Destination rectangle (top)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((118, 10, 118, 64), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(118, 17, 118, 21): 'self', (118, 23, 118, 30): '"""right"""', (118, 32, 118, 63): '"""Destination rectangle (right)"""'}, {}), "(self, 'right', 'Destination rectangle (right)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((119, 10, 119, 66), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(119, 17, 119, 21): 'self', (119, 23, 119, 31): '"""bottom"""', (119, 33, 119, 65): '"""Destination rectangle (bottom)"""'}, {}), "(self, 'bottom', 'Destination rectangle (bottom)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((146, 10, 146, 70), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(146, 17, 146, 21): 'self', (146, 23, 146, 36): '"""cda_version"""', (146, 38, 146, 69): '"""CD file version (currently 1)"""'}, {}), "(self, 'cda_version', 'CD file version (currently 1)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((147, 10, 147, 53), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(147, 17, 147, 21): 'self', (147, 23, 147, 33): '"""track_no"""', (147, 35, 147, 52): '"""Number of track"""'}, {}), "(self, 'track_no', 'Number of track')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((150, 10, 150, 65), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(150, 17, 150, 21): 'self', (150, 23, 150, 35): '"""hsg_offset"""', (150, 37, 150, 64): '"""Track offset (HSG format)"""'}, {}), "(self, 'hsg_offset', 'Track offset (HSG format)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((151, 10, 151, 65), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(151, 17, 151, 21): 'self', (151, 23, 151, 35): '"""hsg_length"""', (151, 37, 151, 64): '"""Track length (HSG format)"""'}, {}), "(self, 'hsg_length', 'Track length (HSG format)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((160, 10, 160, 63), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(160, 17, 160, 21): 'self', (160, 23, 160, 35): '"""nb_channel"""', (160, 37, 160, 62): '"""Number of audio channel"""'}, {}), "(self, 'nb_channel', 'Number of audio channel')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((161, 10, 161, 61), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(161, 17, 161, 21): 'self', (161, 23, 161, 39): '"""sample_per_sec"""', (161, 41, 161, 60): '"""Sample per second"""'}, {}), "(self, 'sample_per_sec', 'Sample per second')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((162, 10, 162, 65), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(162, 17, 162, 21): 'self', (162, 23, 162, 37): '"""byte_per_sec"""', (162, 39, 162, 64): '"""Average byte per second"""'}, {}), "(self, 'byte_per_sec', 'Average byte per second')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((163, 10, 163, 52), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(163, 17, 163, 21): 'self', (163, 23, 163, 36): '"""block_align"""', (163, 38, 163, 51): '"""Block align"""'}, {}), "(self, 'block_align', 'Block align')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((164, 10, 164, 59), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(164, 17, 164, 21): 'self', (164, 23, 164, 39): '"""bit_per_sample"""', (164, 41, 164, 58): '"""Bits per sample"""'}, {}), "(self, 'bit_per_sample', 'Bits per sample')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((167, 10, 167, 72), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(167, 17, 167, 21): 'self', (167, 23, 167, 34): '"""nb_sample"""', (167, 36, 167, 71): '"""Number of samples in audio stream"""'}, {}), "(self, 'nb_sample', 'Number of samples in audio stream')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((170, 10, 170, 69), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(170, 17, 170, 21): 'self', (170, 23, 170, 43): '"""microsec_per_frame"""', (170, 45, 170, 68): '"""Microsecond per frame"""'}, {}), "(self, 'microsec_per_frame', 'Microsecond per frame')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((171, 10, 171, 69), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(171, 17, 171, 21): 'self', (171, 23, 171, 41): '"""max_byte_per_sec"""', (171, 43, 171, 68): '"""Maximum byte per second"""'}, {}), "(self, 'max_byte_per_sec', 'Maximum byte per second')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((172, 10, 172, 40), 'lib.hachoir_core.field.NullBytes', 'NullBytes', ({(172, 20, 172, 24): 'self', (172, 26, 172, 36): '"""reserved"""', (172, 38, 172, 39): '(4)'}, {}), "(self, 'reserved', 4)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((175, 10, 175, 41), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(175, 19, 175, 23): 'self', (175, 25, 175, 37): '"""reserved[]"""', (175, 39, 175, 40): '(4)'}, {}), "(self, 'reserved[]', 4)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((176, 10, 176, 32), 'lib.hachoir_core.field.Bit', 'Bit', ({(176, 14, 176, 18): 'self', (176, 20, 176, 31): '"""has_index"""'}, {}), "(self, 'has_index')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((177, 10, 177, 37), 'lib.hachoir_core.field.Bit', 'Bit', ({(177, 14, 177, 18): 'self', (177, 20, 177, 36): '"""must_use_index"""'}, {}), "(self, 'must_use_index')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((178, 10, 178, 41), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(178, 19, 178, 23): 'self', (178, 25, 178, 37): '"""reserved[]"""', (178, 39, 178, 40): '(2)'}, {}), "(self, 'reserved[]', 2)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((179, 10, 179, 37), 'lib.hachoir_core.field.Bit', 'Bit', ({(179, 14, 179, 18): 'self', (179, 20, 179, 36): '"""is_interleaved"""'}, {}), "(self, 'is_interleaved')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((180, 10, 180, 41), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(180, 19, 180, 23): 'self', (180, 25, 180, 37): '"""reserved[]"""', (180, 39, 180, 40): '(2)'}, {}), "(self, 'reserved[]', 2)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((181, 10, 181, 35), 'lib.hachoir_core.field.Bit', 'Bit', ({(181, 14, 181, 18): 'self', (181, 20, 181, 34): '"""trust_cktype"""'}, {}), "(self, 'trust_cktype')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((182, 10, 182, 41), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(182, 19, 182, 23): 'self', (182, 25, 182, 37): '"""reserved[]"""', (182, 39, 182, 40): '(4)'}, {}), "(self, 'reserved[]', 4)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((183, 10, 183, 39), 'lib.hachoir_core.field.Bit', 'Bit', ({(183, 14, 183, 18): 'self', (183, 20, 183, 38): '"""was_capture_file"""'}, {}), "(self, 'was_capture_file')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((184, 10, 184, 37), 'lib.hachoir_core.field.Bit', 'Bit', ({(184, 14, 184, 18): 'self', (184, 20, 184, 36): '"""is_copyrighted"""'}, {}), "(self, 'is_copyrighted')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((185, 10, 185, 42), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(185, 19, 185, 23): 'self', (185, 25, 185, 37): '"""reserved[]"""', (185, 39, 185, 41): '(14)'}, {}), "(self, 'reserved[]', 14)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((187, 10, 187, 76), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(187, 17, 187, 21): 'self', (187, 23, 187, 36): '"""total_frame"""', (187, 38, 187, 75): '"""Total number of frames in the video"""'}, {}), "(self, 'total_frame', 'Total number of frames in the video')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((188, 10, 188, 81), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(188, 17, 188, 21): 'self', (188, 23, 188, 35): '"""init_frame"""', (188, 37, 188, 80): '"""Initial frame (used in interleaved video)"""'}, {}), "(self, 'init_frame', 'Initial frame (used in interleaved video)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((189, 10, 189, 56), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(189, 17, 189, 21): 'self', (189, 23, 189, 34): '"""nb_stream"""', (189, 36, 189, 55): '"""Number of streams"""'}, {}), "(self, 'nb_stream', 'Number of streams')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((190, 10, 190, 63), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(190, 17, 190, 21): 'self', (190, 23, 190, 37): '"""sug_buf_size"""', (190, 39, 190, 62): '"""Suggested buffer size"""'}, {}), "(self, 'sug_buf_size', 'Suggested buffer size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((191, 10, 191, 49), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(191, 17, 191, 21): 'self', (191, 23, 191, 30): '"""width"""', (191, 32, 191, 48): '"""Width in pixel"""'}, {}), "(self, 'width', 'Width in pixel')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((192, 10, 192, 51), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(192, 17, 192, 21): 'self', (192, 23, 192, 31): '"""height"""', (192, 33, 192, 50): '"""Height in pixel"""'}, {}), "(self, 'height', 'Height in pixel')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((193, 10, 193, 31), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(193, 17, 193, 21): 'self', (193, 23, 193, 30): '"""scale"""'}, {}), "(self, 'scale')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((194, 10, 194, 30), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(194, 17, 194, 21): 'self', (194, 23, 194, 29): '"""rate"""'}, {}), "(self, 'rate')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((195, 10, 195, 31), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(195, 17, 195, 21): 'self', (195, 23, 195, 30): '"""start"""'}, {}), "(self, 'start')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((196, 10, 196, 32), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(196, 17, 196, 21): 'self', (196, 23, 196, 31): '"""length"""'}, {}), "(self, 'length')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((199, 10, 199, 78), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(199, 17, 199, 21): 'self', (199, 23, 199, 36): '"""total_frame"""', (199, 38, 199, 77): '"""Real number of frame of OpenDML video"""'}, {}), "(self, 'total_frame', 'Real number of frame of OpenDML video')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((251, 8, 251, 44), 'lib.hachoir_core.field.FieldSet.__init__', 'FieldSet.__init__', ({(251, 26, 251, 30): 'self', (251, 32, 251, 37): '*args'}, {}), '(self, *args, **kw)', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((319, 10, 319, 63), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(319, 17, 319, 21): 'self', (319, 23, 319, 33): '"""hdr_size"""', (319, 35, 319, 62): '"""Size of header (36 bytes)"""'}, {}), "(self, 'hdr_size', 'Size of header (36 bytes)')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((322, 10, 322, 75), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(322, 17, 322, 21): 'self', (322, 23, 322, 33): '"""nb_frame"""', (322, 35, 322, 74): '"""Number of unique Icons in this cursor"""'}, {}), "(self, 'nb_frame', 'Number of unique Icons in this cursor')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((323, 10, 323, 80), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(323, 17, 323, 21): 'self', (323, 23, 323, 32): '"""nb_step"""', (323, 34, 323, 79): '"""Number of Blits before the animation cycles"""'}, {}), "(self, 'nb_step', 'Number of Blits before the animation cycles')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((324, 10, 324, 28), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(324, 17, 324, 21): 'self', (324, 23, 324, 27): '"""cx"""'}, {}), "(self, 'cx')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((325, 10, 325, 28), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(325, 17, 325, 21): 'self', (325, 23, 325, 27): '"""cy"""'}, {}), "(self, 'cy')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((326, 10, 326, 35), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(326, 17, 326, 21): 'self', (326, 23, 326, 34): '"""bit_count"""'}, {}), "(self, 'bit_count')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((327, 10, 327, 32), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(327, 17, 327, 21): 'self', (327, 23, 327, 31): '"""planes"""'}, {}), "(self, 'planes')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((328, 10, 328, 103), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(328, 17, 328, 21): 'self', (328, 23, 328, 36): '"""jiffie_rate"""', (328, 38, 328, 102): '"""Default Jiffies (1/60th of a second) if rate chunk not present"""'}, {}), "(self, 'jiffie_rate',\n    'Default Jiffies (1/60th of a second) if rate chunk not present')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((329, 10, 329, 30), 'lib.hachoir_core.field.Bit', 'Bit', ({(329, 14, 329, 18): 'self', (329, 20, 329, 29): '"""is_icon"""'}, {}), "(self, 'is_icon')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((330, 10, 330, 39), 'lib.hachoir_core.field.NullBits', 'NullBits', ({(330, 19, 330, 23): 'self', (330, 25, 330, 34): '"""padding"""', (330, 36, 330, 38): '(31)'}, {}), "(self, 'padding', 31)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((338, 25, 338, 47), 'datetime.timedelta', 'timedelta', (), '', False, 'from datetime import timedelta\n'), ((345, 10, 345, 78), 'lib.hachoir_core.field.SubFile', 'SubFile', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((67, 15, 67, 62), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(67, 22, 67, 26): 'self', (67, 28, 67, 35): '"""codec"""', (67, 37, 67, 61): '"""Audio format: Codec id"""'}, {}), "(self, 'codec', 'Audio format: Codec id')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((73, 14, 73, 78), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(73, 21, 73, 25): 'self', (73, 27, 73, 44): '"""bits_per_sample"""', (73, 46, 73, 77): '"""Audio format: Bits per sample"""'}, {}), "(self, 'bits_per_sample', 'Audio format: Bits per sample')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((75, 14, 75, 81), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(75, 21, 75, 25): 'self', (75, 27, 75, 37): '"""ext_size"""', (75, 39, 75, 80): '"""Audio format: Size of extra information"""'}, {}), "(self, 'ext_size', 'Audio format: Size of extra information')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((77, 14, 77, 56), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(77, 21, 77, 25): 'self', (77, 27, 77, 37): '"""reserved"""', (77, 39, 77, 55): '"""Audio format: """'}, {}), "(self, 'reserved', 'Audio format: ')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((78, 14, 78, 86), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(78, 21, 78, 25): 'self', (78, 27, 78, 41): '"""channel_mask"""', (78, 43, 78, 85): '"""Audio format: channels placement bitmask"""'}, {}), "(self, 'channel_mask', 'Audio format: channels placement bitmask')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((79, 14, 79, 69), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(79, 21, 79, 25): 'self', (79, 27, 79, 38): '"""subformat"""', (79, 40, 79, 68): '"""Audio format: Subformat id"""'}, {}), "(self, 'subformat', 'Audio format: Subformat id')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((126, 14, 126, 34), 'lib.hachoir_core.field.UInt8', 'UInt8', ({(126, 20, 126, 24): 'self', (126, 26, 126, 33): '"""frame"""'}, {}), "(self, 'frame')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((127, 14, 127, 35), 'lib.hachoir_core.field.UInt8', 'UInt8', ({(127, 20, 127, 24): 'self', (127, 26, 127, 34): '"""second"""'}, {}), "(self, 'second')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((128, 14, 128, 35), 'lib.hachoir_core.field.UInt8', 'UInt8', ({(128, 20, 128, 24): 'self', (128, 26, 128, 34): '"""minute"""'}, {}), "(self, 'minute')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((129, 14, 129, 46), 'lib.hachoir_core.field.PaddingBytes', 'PaddingBytes', ({(129, 27, 129, 31): 'self', (129, 33, 129, 42): '"""notused"""', (129, 44, 129, 45): '(1)'}, {}), "(self, 'notused', 1)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((148, 22, 148, 71), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(148, 29, 148, 33): 'self', (148, 35, 148, 48): '"""disc_serial"""', (148, 50, 148, 70): '"""Disc serial number"""'}, {}), "(self, 'disc_serial', 'Disc serial number')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((159, 15, 159, 51), 'lib.hachoir_core.field.UInt16', 'UInt16', ({(159, 22, 159, 26): 'self', (159, 28, 159, 35): '"""codec"""', (159, 37, 159, 50): '"""Audio codec"""'}, {}), "(self, 'codec', 'Audio codec')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((202, 14, 202, 51), 'lib.hachoir_core.field.NullBytes', 'NullBytes', ({(202, 24, 202, 28): 'self', (202, 30, 202, 41): '"""padding[]"""', (202, 43, 202, 50): 'padding'}, {}), "(self, 'padding[]', padding)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((207, 14, 207, 60), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((208, 14, 208, 35), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(208, 21, 208, 25): 'self', (208, 27, 208, 34): '"""flags"""'}, {}), "(self, 'flags')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((209, 14, 209, 70), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(209, 21, 209, 25): 'self', (209, 27, 209, 34): '"""start"""', (209, 36, 209, 69): '"""Offset from start of movie data"""'}, {}), "(self, 'start', 'Offset from start of movie data')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((210, 14, 210, 36), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(210, 21, 210, 25): 'self', (210, 27, 210, 35): '"""length"""'}, {}), "(self, 'length')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((267, 14, 267, 60), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((334, 14, 334, 36), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(334, 21, 334, 25): 'self', (334, 27, 334, 35): '"""icon[]"""'}, {}), "(self, 'icon[]')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((388, 14, 388, 80), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((390, 14, 390, 96), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((252, 26, 252, 59), 'lib.hachoir_core.tools.alignValue', 'alignValue', ({(252, 37, 252, 55): "self['size'].value", (252, 57, 252, 58): '(2)'}, {}), "(self['size'].value, 2)", False, 'from lib.hachoir_core.tools import alignValue, humanDuration\n'), ((268, 30, 268, 58), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(268, 37, 268, 41): 'self', (268, 43, 268, 49): '"""size"""', (268, 51, 268, 57): '"""Size"""'}, {}), "(self, 'size', 'Size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((272, 18, 272, 71), 'lib.hachoir_core.field.String', 'String', (), '', False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((342, 26, 342, 48), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(342, 33, 342, 37): 'self', (342, 39, 342, 47): '"""rate[]"""'}, {}), "(self, 'rate[]')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((389, 30, 389, 67), 'lib.hachoir_core.field.UInt32', 'UInt32', ({(389, 37, 389, 41): 'self', (389, 43, 389, 53): '"""filesize"""', (389, 55, 389, 66): '"""File size"""'}, {}), "(self, 'filesize', 'File size')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((402, 18, 402, 78), 'lib.hachoir_core.field.RawBytes', 'RawBytes', ({(402, 27, 402, 31): 'self', (402, 33, 402, 44): '"""padding[]"""', (402, 46, 402, 77): '((self.size - self.current_size) / 8)'}, {}), "(self, 'padding[]', (self.size - self.current_size) / 8)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((285, 22, 285, 71), 'lib.hachoir_core.field.RawBytes', 'RawBytes', ({(285, 31, 285, 35): 'self', (285, 37, 285, 50): '"""raw_content"""', (285, 52, 285, 70): "self['size'].value"}, {}), "(self, 'raw_content', self['size'].value)", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((278, 26, 278, 61), 'lib.hachoir_core.field.UInt8', 'UInt8', ({(278, 32, 278, 36): 'self', (278, 38, 278, 49): '"""padding[]"""', (278, 51, 278, 60): '"""Padding"""'}, {}), "(self, 'padding[]', 'Padding')", False, 'from lib.hachoir_core.field import FieldSet, ParserError, UInt8, UInt16, UInt32, Enum, Bit, NullBits, NullBytes, RawBytes, String, PaddingBytes, SubFile\n'), ((422, 39, 422, 59), 'lib.hachoir_core.tools.humanDuration', 'humanDuration', ({(422, 53, 422, 58): 'delta'}, {}), '(delta)', False, 'from lib.hachoir_core.tools import alignValue, humanDuration\n')]