mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 18:28:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			97 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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.
 | 
