summaryrefslogtreecommitdiffstats
path: root/Lib/plat-mac/Carbon/MediaDescr.py
blob: 4a40062623a6bf9deebe20aefb4f459dd1926c18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# Parsers/generators for QuickTime media descriptions
import struct

Error = 'MediaDescr.Error'

class _MediaDescriptionCodec:
    def __init__(self, trunc, size, names, fmt):
        self.trunc = trunc
        self.size = size
        self.names = names
        self.fmt = fmt

    def decode(self, data):
        if self.trunc:
            data = data[:self.size]
        values = struct.unpack(self.fmt, data)
        if len(values) != len(self.names):
            raise Error('Format length does not match number of names', descr)
        rv = {}
        for i in range(len(values)):
            name = self.names[i]
            value = values[i]
            if type(name) == type(()):
                name, cod, dec = name
                value = dec(value)
            rv[name] = value
        return rv

    def encode(dict):
        list = [self.fmt]
        for name in self.names:
            if type(name) == type(()):
                name, cod, dec = name
            else:
                cod = dec = None
            value = dict[name]
            if cod:
                value = cod(value)
            list.append(value)
        rv = struct.pack(*list)
        return rv

# Helper functions
def _tofixed(float):
    hi = int(float)
    lo = int(float*0x10000) & 0xffff
    return (hi<<16)|lo

def _fromfixed(fixed):
    hi = (fixed >> 16) & 0xffff
    lo = (fixed & 0xffff)
    return hi + (lo / float(0x10000))

def _tostr31(str):
    return chr(len(str)) + str + '\0'*(31-len(str))

def _fromstr31(str31):
    return str31[1:1+ord(str31[0])]

SampleDescription = _MediaDescriptionCodec(
        1,      # May be longer, truncate
        16,     # size
        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex'), # Attributes
        "l4slhh"        # Format
)

SoundDescription = _MediaDescriptionCodec(
        1,
        36,
        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
        'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
        'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed)),
        "l4slhhhh4shhhhl"       # Format
)

SoundDescriptionV1 = _MediaDescriptionCodec(
        1,
        52,
        ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
        'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
        'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed), 'samplesPerPacket',
        'bytesPerPacket', 'bytesPerFrame', 'bytesPerSample'),
        "l4slhhhh4shhhhlllll"   # Format
)

ImageDescription = _MediaDescriptionCodec(
        1,      # May be longer, truncate
        86,     # size
        ('idSize', 'cType', 'resvd1', 'resvd2', 'dataRefIndex', 'version',
         'revisionLevel', 'vendor', 'temporalQuality', 'spatialQuality',
         'width', 'height', ('hRes', _tofixed, _fromfixed), ('vRes', _tofixed, _fromfixed),
        'dataSize', 'frameCount', ('name', _tostr31, _fromstr31),
         'depth', 'clutID'),
        'l4slhhhh4sllhhlllh32shh',
)

# XXXX Others, like TextDescription and such, remain to be done.