2
/////////////////////////////////////////////////////////////////
3
/// getID3() by James Heinrich <info@getid3.org> //
4
// available at http://getid3.sourceforge.net //
5
// or http://www.getid3.org //
6
/////////////////////////////////////////////////////////////////
7
// See readme.txt for more details //
8
/////////////////////////////////////////////////////////////////
10
// module.audio-video.riff.php //
11
// module for analyzing RIFF files //
12
// multiple formats supported by this module: //
13
// Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
14
// dependencies: module.audio.mp3.php //
15
// module.audio.ac3.php //
16
// module.audio.dts.php //
18
/////////////////////////////////////////////////////////////////
21
* @todo Parse AC-3/DTS audio inside WAVE correctly
22
* @todo Rewrite RIFF parser totally
25
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
26
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true);
27
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.dts.php', __FILE__, true);
29
class getid3_riff extends getid3_handler
32
public function Analyze() {
33
$info = &$this->getid3->info;
35
// initialize these values to an empty array, otherwise they default to NULL
36
// and you can't append array values to a NULL value
37
$info['riff'] = array('raw'=>array());
40
$thisfile_riff = &$info['riff'];
41
$thisfile_riff_raw = &$thisfile_riff['raw'];
42
$thisfile_audio = &$info['audio'];
43
$thisfile_video = &$info['video'];
44
$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
45
$thisfile_riff_audio = &$thisfile_riff['audio'];
46
$thisfile_riff_video = &$thisfile_riff['video'];
48
$Original['avdataoffset'] = $info['avdataoffset'];
49
$Original['avdataend'] = $info['avdataend'];
51
$this->fseek($info['avdataoffset']);
52
$RIFFheader = $this->fread(12);
53
$offset = $this->ftell();
54
$RIFFtype = substr($RIFFheader, 0, 4);
55
$RIFFsize = substr($RIFFheader, 4, 4);
56
$RIFFsubtype = substr($RIFFheader, 8, 4);
60
case 'FORM': // AIFF, AIFC
61
$info['fileformat'] = 'aiff';
62
$thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
63
$thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
66
case 'RIFF': // AVI, WAV, etc
67
case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
68
case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
69
$info['fileformat'] = 'riff';
70
$thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
71
if ($RIFFsubtype == 'RMP3') {
72
// RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
73
$RIFFsubtype = 'WAVE';
75
$thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
76
if (($info['avdataend'] - $info['filesize']) == 1) {
77
// LiteWave appears to incorrectly *not* pad actual output file
78
// to nearest WORD boundary so may appear to be short by one
79
// byte, in which case - skip warning
80
$info['avdataend'] = $info['filesize'];
83
$nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
84
while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) {
86
$this->fseek($nextRIFFoffset);
87
} catch (getid3_exception $e) {
88
if ($e->getCode() == 10) {
89
//$this->warning('RIFF parser: '.$e->getMessage());
90
$this->error('AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime may be wrong');
91
$this->warning('[avdataend] value may be incorrect, multiple AVIX chunks may be present');
97
$nextRIFFheader = $this->fread(12);
98
if ($nextRIFFoffset == ($info['avdataend'] - 1)) {
99
if (substr($nextRIFFheader, 0, 1) == "\x00") {
100
// RIFF padded to WORD boundary, we're actually already at the end
104
$nextRIFFheaderID = substr($nextRIFFheader, 0, 4);
105
$nextRIFFsize = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4));
106
$nextRIFFtype = substr($nextRIFFheader, 8, 4);
107
$chunkdata = array();
108
$chunkdata['offset'] = $nextRIFFoffset + 8;
109
$chunkdata['size'] = $nextRIFFsize;
110
$nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size'];
112
switch ($nextRIFFheaderID) {
115
$chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset);
117
if (!isset($thisfile_riff[$nextRIFFtype])) {
118
$thisfile_riff[$nextRIFFtype] = array();
120
$thisfile_riff[$nextRIFFtype][] = $chunkdata;
125
$thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
129
$info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size']));
133
if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) {
134
$DIVXTAG = $nextRIFFheader.$this->fread(128 - 12);
135
if (substr($DIVXTAG, -7) == 'DIVXTAG') {
136
// DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file
137
$this->warning('Found wrongly-structured DIVXTAG at offset '.($this->ftell() - 128).', parsing anyway');
138
$info['divxtag']['comments'] = self::ParseDIVXTAG($DIVXTAG);
142
$this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file');
148
if ($RIFFsubtype == 'WAVE') {
149
$thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
154
$this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead');
155
unset($info['fileformat']);
160
switch ($RIFFsubtype) {
162
if (empty($thisfile_audio['bitrate_mode'])) {
163
$thisfile_audio['bitrate_mode'] = 'cbr';
165
if (empty($thisfile_audio_dataformat)) {
166
$thisfile_audio_dataformat = 'wav';
169
if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
170
$info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
171
$info['avdataend'] = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size'];
173
if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
175
$thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
176
$thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
177
if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
178
$info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
181
$thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
182
unset($thisfile_riff_audio[$streamindex]['raw']);
183
$thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
185
$thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
186
if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
187
$info['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
189
$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
191
if (empty($info['playtime_seconds'])) { // may already be set (e.g. DTS-WAV)
192
$info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
195
$thisfile_audio['lossless'] = false;
196
if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
197
switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
200
$thisfile_audio['lossless'] = true;
204
$thisfile_audio_dataformat = 'ac3';
213
$thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag'];
214
$thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
215
$thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless'];
216
$thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat;
219
if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
222
$rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
223
$thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array());
224
$thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad'];
225
$thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
226
$thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
228
$thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
229
$thisfile_riff_raw_rgad['nRadioRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 4, 2));
230
$thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 6, 2));
232
$nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
233
$nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
234
$thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
235
$thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
236
$thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
237
$thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
238
$thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
239
$thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
240
$thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
241
$thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
243
$thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
244
if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
245
$thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
246
$thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
247
$thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
249
if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
250
$thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
251
$thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
252
$thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
256
if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
257
$thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
259
// This should be a good way of calculating exact playtime,
260
// but some sample files have had incorrect number of samples,
261
// so cannot use this method
263
// if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
264
// $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
267
if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
268
$thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
271
if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
273
$thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
275
$thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256));
276
$thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32));
277
$thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32));
278
$thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10);
279
$thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8);
280
$thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8));
281
$thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1));
282
$thisfile_riff_WAVE_bext_0['reserved'] = substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
283
$thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
284
if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
285
if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
286
list($dummy, $bext_timestamp['year'], $bext_timestamp['month'], $bext_timestamp['day']) = $matches_bext_date;
287
list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
288
$thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
290
$info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
293
$info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
295
$thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
296
$thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
299
if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
301
$thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
303
$thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
304
$thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
305
if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
306
$thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
307
$thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
308
$thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
310
$thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
312
$thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
313
$thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
314
$thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
315
$thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
316
$thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
319
if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
321
$thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
323
$thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4);
324
$thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64));
325
$thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64));
326
$thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
327
$thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
328
$thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
329
$thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
330
$thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
331
$thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
332
$thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8));
333
$thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
334
$thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8));
335
$thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
336
$thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
337
$thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
338
$thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true);
339
for ($i = 0; $i < 8; $i++) {
340
$thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
341
$thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
343
$thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024));
344
$thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
346
$thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
347
$thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title'];
350
if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
351
// SoundMiner metadata
354
$thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE['SNDM'][0];
355
$thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data'];
356
$SNDM_startoffset = 0;
357
$SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0['size'];
359
while ($SNDM_startoffset < $SNDM_endoffset) {
360
$SNDM_thisTagOffset = 0;
361
$SNDM_thisTagSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4));
362
$SNDM_thisTagOffset += 4;
363
$SNDM_thisTagKey = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4);
364
$SNDM_thisTagOffset += 4;
365
$SNDM_thisTagDataSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
366
$SNDM_thisTagOffset += 2;
367
$SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
368
$SNDM_thisTagOffset += 2;
369
$SNDM_thisTagDataText = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize);
370
$SNDM_thisTagOffset += $SNDM_thisTagDataSize;
372
if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
373
$info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
375
} elseif ($SNDM_thisTagSize <= 0) {
376
$info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
379
$SNDM_startoffset += $SNDM_thisTagSize;
381
$thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText;
382
if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) {
383
$thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
385
$info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
390
'tracktitle'=>'title',
391
'category' =>'genre',
393
'tracktitle'=>'title',
395
foreach ($tagmapping as $fromkey => $tokey) {
396
if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
397
$thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
402
if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) {
403
// requires functions simplexml_load_string and get_object_vars
404
if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) {
405
$thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML;
406
if (isset($parsedXML['SPEED']['MASTER_SPEED'])) {
407
@list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']);
408
$thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000);
410
if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) {
411
@list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']);
412
$thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000);
414
if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) {
415
$samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0'));
416
$thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE'];
417
$h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600);
418
$m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60);
419
$s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60));
420
$f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate'];
421
$thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f);
422
$thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f));
430
if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
431
$thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
432
$info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
435
if (!empty($info['wavpack'])) {
436
$thisfile_audio_dataformat = 'wavpack';
437
$thisfile_audio['bitrate_mode'] = 'vbr';
438
$thisfile_audio['encoder'] = 'WavPack v'.$info['wavpack']['version'];
440
// Reset to the way it was - RIFF parsing will have messed this up
441
$info['avdataend'] = $Original['avdataend'];
442
$thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
444
$this->fseek($info['avdataoffset'] - 44);
445
$RIFFdata = $this->fread(44);
446
$OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8;
447
$OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
449
if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
450
$info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
451
$this->fseek($info['avdataend']);
452
$RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
455
// move the data chunk after all other chunks (if any)
456
// so that the RIFF parser doesn't see EOF when trying
457
// to skip over the data chunk
458
$RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
459
$getid3_riff = new getid3_riff($this->getid3);
460
$getid3_riff->ParseRIFFdata($RIFFdata);
464
if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
465
switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
467
if (!empty($info['ac3'])) {
468
// Dolby Digital WAV files masquerade as PCM-WAV, but they're not
469
$thisfile_audio['wformattag'] = 0x2000;
470
$thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']);
471
$thisfile_audio['lossless'] = false;
472
$thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
473
$thisfile_audio['sample_rate'] = $info['ac3']['sample_rate'];
475
if (!empty($info['dts'])) {
476
// Dolby DTS files masquerade as PCM-WAV, but they're not
477
$thisfile_audio['wformattag'] = 0x2001;
478
$thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']);
479
$thisfile_audio['lossless'] = false;
480
$thisfile_audio['bitrate'] = $info['dts']['bitrate'];
481
$thisfile_audio['sample_rate'] = $info['dts']['sample_rate'];
484
case 0x08AE: // ClearJump LiteWave
485
$thisfile_audio['bitrate_mode'] = 'vbr';
486
$thisfile_audio_dataformat = 'litewave';
488
//typedef struct tagSLwFormat {
489
// WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
490
// DWORD m_dwScale; // scale factor for lossy compression
491
// DWORD m_dwBlockSize; // number of samples in encoded blocks
492
// WORD m_wQuality; // alias for the scale factor
493
// WORD m_wMarkDistance; // distance between marks in bytes
496
// //following paramters are ignored if CF_FILESRC is not set
497
// DWORD m_dwOrgSize; // original file size in bytes
498
// WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
499
// DWORD m_dwRiffChunkSize; // riff chunk size in the original file
501
// PCMWAVEFORMAT m_OrgWf; // original wave format
502
// }SLwFormat, *PSLwFormat;
505
$thisfile_riff['litewave']['raw'] = array();
506
$riff_litewave = &$thisfile_riff['litewave'];
507
$riff_litewave_raw = &$riff_litewave['raw'];
510
'compression_method' => 1,
511
'compression_flags' => 1,
513
'm_dwBlockSize' => 4,
515
'm_wMarkDistance' => 2,
518
'm_bFactExists' => 2,
519
'm_dwRiffChunkSize' => 4,
521
$litewave_offset = 18;
522
foreach ($flags as $flag => $length) {
523
$riff_litewave_raw[$flag] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], $litewave_offset, $length));
524
$litewave_offset += $length;
527
//$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20));
528
$riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality'];
530
$riff_litewave['flags']['raw_source'] = ($riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
531
$riff_litewave['flags']['vbr_blocksize'] = ($riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
532
$riff_litewave['flags']['seekpoints'] = (bool) ($riff_litewave_raw['compression_flags'] & 0x04);
534
$thisfile_audio['lossless'] = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false);
535
$thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor'];
542
if ($info['avdataend'] > $info['filesize']) {
543
switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
544
case 'wavpack': // WavPack
546
case 'ofr': // OptimFROG
547
case 'ofs': // OptimFROG DualStream
548
// lossless compressed audio formats that keep original RIFF headers - skip warning
552
if (($info['avdataend'] - $info['filesize']) == 1) {
553
// LiteWave appears to incorrectly *not* pad actual output file
554
// to nearest WORD boundary so may appear to be short by one
555
// byte, in which case - skip warning
557
// Short by more than one byte, throw warning
558
$info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
559
$info['avdataend'] = $info['filesize'];
564
if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) {
565
// output file appears to be incorrectly *not* padded to nearest WORD boundary
566
// Output less severe warning
567
$info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
568
$info['avdataend'] = $info['filesize'];
570
// Short by more than one byte, throw warning
571
$info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
572
$info['avdataend'] = $info['filesize'];
577
if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) {
578
if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
579
$info['avdataend']--;
580
$info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
583
if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
584
unset($thisfile_audio['bits_per_sample']);
585
if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
586
$thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
592
$thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
593
$thisfile_video['dataformat'] = 'avi';
594
$info['mime_type'] = 'video/avi';
596
if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
597
$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
598
if (isset($thisfile_riff['AVIX'])) {
599
$info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
601
$info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
603
if ($info['avdataend'] > $info['filesize']) {
604
$info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)';
605
$info['avdataend'] = $info['filesize'];
609
if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
610
//$bIndexType = array(
611
// 0x00 => 'AVI_INDEX_OF_INDEXES',
612
// 0x01 => 'AVI_INDEX_OF_CHUNKS',
613
// 0x80 => 'AVI_INDEX_IS_DATA',
615
//$bIndexSubtype = array(
617
// 0x01 => 'AVI_INDEX_2FIELD',
620
foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
621
$ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
623
$thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($ahsisd, 0, 2));
624
$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = $this->EitherEndian2Int(substr($ahsisd, 2, 1));
625
$thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = $this->EitherEndian2Int(substr($ahsisd, 3, 1));
626
$thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = $this->EitherEndian2Int(substr($ahsisd, 4, 4));
627
$thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($ahsisd, 8, 4);
628
$thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = $this->EitherEndian2Int(substr($ahsisd, 12, 4));
630
//$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
631
//$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
636
if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
637
$avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
640
$thisfile_riff_raw['avih'] = array();
641
$thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
643
$thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L)
644
if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
645
$info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
650
'dwMaxBytesPerSec', // max. transfer rate
651
'dwPaddingGranularity', // pad to multiples of this size; normally 2K.
652
'dwFlags', // the ever-present flags
653
'dwTotalFrames', // # frames in file
654
'dwInitialFrames', //
656
'dwSuggestedBufferSize', //
665
foreach ($flags as $flag) {
666
$thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4));
671
'hasindex' => 0x00000010,
672
'mustuseindex' => 0x00000020,
673
'interleaved' => 0x00000100,
674
'trustcktype' => 0x00000800,
675
'capturedfile' => 0x00010000,
676
'copyrighted' => 0x00020010,
678
foreach ($flags as $flag => $value) {
679
$thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
683
$thisfile_riff_video[$streamindex] = array();
684
$thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
686
if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
687
$thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
688
$thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width'];
690
if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
691
$thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
692
$thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height'];
694
if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
695
$thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
696
$thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames'];
699
$thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
700
$thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
702
if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
703
if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
704
for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
705
if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
706
$strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
707
$strhfccType = substr($strhData, 0, 4);
709
if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
710
$strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
713
$thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
715
switch ($strhfccType) {
717
$thisfile_audio['bitrate_mode'] = 'cbr';
718
$thisfile_audio_dataformat = 'wav';
719
if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
720
$streamindex = count($thisfile_riff_audio);
723
$thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData);
724
$thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
727
$thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
728
$thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
730
if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
731
unset($thisfile_audio_streams_currentstream['bits_per_sample']);
733
$thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
734
unset($thisfile_audio_streams_currentstream['raw']);
737
$thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
739
unset($thisfile_riff_audio[$streamindex]['raw']);
740
$thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
742
$thisfile_audio['lossless'] = false;
743
switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
745
$thisfile_audio_dataformat = 'wav';
746
$thisfile_audio['lossless'] = true;
749
case 0x0050: // MPEG Layer 2 or Layer 1
750
$thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
753
case 0x0055: // MPEG Layer 3
754
$thisfile_audio_dataformat = 'mp3';
758
$thisfile_audio_dataformat = 'aac';
761
case 0x0161: // Windows Media v7 / v8 / v9
762
case 0x0162: // Windows Media Professional v9
763
case 0x0163: // Windows Media Lossess v9
764
$thisfile_audio_dataformat = 'wma';
768
$thisfile_audio_dataformat = 'ac3';
772
$thisfile_audio_dataformat = 'dts';
776
$thisfile_audio_dataformat = 'wav';
779
$thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat;
780
$thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless'];
781
$thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
788
$thisfile_riff_raw['strh'][$i] = array();
789
$thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i];
791
$thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType;
792
$thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4);
793
$thisfile_riff_raw_strh_current['dwFlags'] = $this->EitherEndian2Int(substr($strhData, 8, 4)); // Contains AVITF_* flags
794
$thisfile_riff_raw_strh_current['wPriority'] = $this->EitherEndian2Int(substr($strhData, 12, 2));
795
$thisfile_riff_raw_strh_current['wLanguage'] = $this->EitherEndian2Int(substr($strhData, 14, 2));
796
$thisfile_riff_raw_strh_current['dwInitialFrames'] = $this->EitherEndian2Int(substr($strhData, 16, 4));
797
$thisfile_riff_raw_strh_current['dwScale'] = $this->EitherEndian2Int(substr($strhData, 20, 4));
798
$thisfile_riff_raw_strh_current['dwRate'] = $this->EitherEndian2Int(substr($strhData, 24, 4));
799
$thisfile_riff_raw_strh_current['dwStart'] = $this->EitherEndian2Int(substr($strhData, 28, 4));
800
$thisfile_riff_raw_strh_current['dwLength'] = $this->EitherEndian2Int(substr($strhData, 32, 4));
801
$thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4));
802
$thisfile_riff_raw_strh_current['dwQuality'] = $this->EitherEndian2Int(substr($strhData, 40, 4));
803
$thisfile_riff_raw_strh_current['dwSampleSize'] = $this->EitherEndian2Int(substr($strhData, 44, 4));
804
$thisfile_riff_raw_strh_current['rcFrame'] = $this->EitherEndian2Int(substr($strhData, 48, 4));
806
$thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
807
$thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler'];
808
if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
809
$thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
810
$thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
812
$thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
813
$thisfile_video['pixel_aspect_ratio'] = (float) 1;
814
switch ($thisfile_riff_raw_strh_current['fccHandler']) {
815
case 'HFYU': // Huffman Lossless Codec
816
case 'IRAW': // Intel YUV Uncompressed
817
case 'YUY2': // Uncompressed YUV 4:2:2
818
$thisfile_video['lossless'] = true;
822
$thisfile_video['lossless'] = false;
826
switch ($strhfccType) {
828
$thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($info['fileformat'] == 'riff'));
829
$thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
831
if ($thisfile_riff_video_current['codec'] == 'DV') {
832
$thisfile_riff_video_current['dv_type'] = 2;
837
$thisfile_riff_video_current['dv_type'] = 1;
843
$info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
850
if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
852
$thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
853
if (self::fourccLookup($thisfile_video['fourcc'])) {
854
$thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']);
855
$thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
858
switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
859
case 'HFYU': // Huffman Lossless Codec
860
case 'IRAW': // Intel YUV Uncompressed
861
case 'YUY2': // Uncompressed YUV 4:2:2
862
$thisfile_video['lossless'] = true;
863
//$thisfile_video['bits_per_sample'] = 24;
867
$thisfile_video['lossless'] = false;
868
//$thisfile_video['bits_per_sample'] = 24;
879
$thisfile_audio['bitrate_mode'] = 'cbr';
880
$thisfile_audio_dataformat = 'cda';
881
$thisfile_audio['lossless'] = true;
882
unset($info['mime_type']);
884
$info['avdataoffset'] = 44;
886
if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
888
$thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
890
$thisfile_riff_CDDA_fmt_0['unknown1'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2));
891
$thisfile_riff_CDDA_fmt_0['track_num'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2));
892
$thisfile_riff_CDDA_fmt_0['disc_id'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4));
893
$thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4));
894
$thisfile_riff_CDDA_fmt_0['playtime_frames'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
895
$thisfile_riff_CDDA_fmt_0['unknown6'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
896
$thisfile_riff_CDDA_fmt_0['unknown7'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
898
$thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
899
$thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
900
$info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
901
$info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
903
// hardcoded data for CD-audio
904
$thisfile_audio['sample_rate'] = 44100;
905
$thisfile_audio['channels'] = 2;
906
$thisfile_audio['bits_per_sample'] = 16;
907
$thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
908
$thisfile_audio['bitrate_mode'] = 'cbr';
915
$thisfile_audio['bitrate_mode'] = 'cbr';
916
$thisfile_audio_dataformat = 'aiff';
917
$thisfile_audio['lossless'] = true;
918
$info['mime_type'] = 'audio/x-aiff';
920
if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
921
$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
922
$info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
923
if ($info['avdataend'] > $info['filesize']) {
924
if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) {
925
// structures rounded to 2-byte boundary, but dumb encoders
926
// forget to pad end of file to make this actually work
928
$info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
930
$info['avdataend'] = $info['filesize'];
934
if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
937
$thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
939
$thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true);
940
$thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false);
941
$thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true);
942
$thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10));
944
if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
945
$thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
946
$CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false);
947
$thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
948
switch ($thisfile_riff_audio['codec_name']) {
950
$thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
951
$thisfile_audio['lossless'] = true;
955
switch ($thisfile_riff_audio['codec_fourcc']) {
956
// http://developer.apple.com/qa/snd/snd07.html
958
$thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
959
$thisfile_audio['lossless'] = true;
963
$thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
964
$thisfile_audio['lossless'] = true;
973
$thisfile_audio['codec'] = $thisfile_riff_audio['codec_name'];
974
$thisfile_audio['lossless'] = false;
979
$thisfile_audio['channels'] = $thisfile_riff_audio['channels'];
980
if ($thisfile_riff_audio['bits_per_sample'] > 0) {
981
$thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
983
$thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
984
if ($thisfile_audio['sample_rate'] == 0) {
985
$info['error'][] = 'Corrupted AIFF file: sample_rate == zero';
988
$info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
991
if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
993
$CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
995
for ($i = 0; $i < $CommentCount; $i++) {
996
$info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
998
$info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
1000
$CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
1002
$info['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
1003
$offset += $CommentLength;
1005
$info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']);
1006
$thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment'];
1010
$CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1011
foreach ($CommentsChunkNames as $key => $value) {
1012
if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1013
$thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1017
if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
1018
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1019
$getid3_temp = new getID3();
1020
$getid3_temp->openfile($this->getid3->filename);
1021
$getid3_id3v2 = new getid3_id3v2($getid3_temp);
1022
$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
1023
if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1024
$info['id3v2'] = $getid3_temp->info['id3v2'];
1026
unset($getid3_temp, $getid3_id3v2);
1032
$thisfile_audio['bitrate_mode'] = 'cbr';
1033
$thisfile_audio_dataformat = '8svx';
1034
$thisfile_audio['bits_per_sample'] = 8;
1035
$thisfile_audio['channels'] = 1; // overridden below, if need be
1036
$info['mime_type'] = 'audio/x-aiff';
1038
if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
1039
$info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
1040
$info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
1041
if ($info['avdataend'] > $info['filesize']) {
1042
$info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
1046
if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
1048
$thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
1050
$thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4));
1051
$thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4));
1052
$thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4));
1053
$thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
1054
$thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
1055
$thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
1056
$thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
1058
$thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
1060
switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
1062
$thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
1063
$thisfile_audio['lossless'] = true;
1064
$ActualBitsPerSample = 8;
1068
$thisfile_audio['codec'] = 'Fibonacci-delta encoding';
1069
$thisfile_audio['lossless'] = false;
1070
$ActualBitsPerSample = 4;
1074
$info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
1079
if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
1080
$ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
1081
switch ($ChannelsIndex) {
1083
$thisfile_audio['channels'] = 2;
1086
case 2: // Left channel only
1087
case 4: // Right channel only
1088
$thisfile_audio['channels'] = 1;
1092
$info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
1098
$CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1099
foreach ($CommentsChunkNames as $key => $value) {
1100
if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1101
$thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1105
$thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
1106
if (!empty($thisfile_audio['bitrate'])) {
1107
$info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8);
1113
$info['mime_type'] = 'video/mpeg';
1114
if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
1115
if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
1116
$getid3_temp = new getID3();
1117
$getid3_temp->openfile($this->getid3->filename);
1118
$getid3_mpeg = new getid3_mpeg($getid3_temp);
1119
$getid3_mpeg->Analyze();
1120
if (empty($getid3_temp->info['error'])) {
1121
$info['audio'] = $getid3_temp->info['audio'];
1122
$info['video'] = $getid3_temp->info['video'];
1123
$info['mpeg'] = $getid3_temp->info['mpeg'];
1124
$info['warning'] = $getid3_temp->info['warning'];
1126
unset($getid3_temp, $getid3_mpeg);
1133
$info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
1134
unset($info['fileformat']);
1138
switch ($RIFFsubtype) {
1142
$ID3v2_key_good = 'id3 ';
1143
$ID3v2_keys_bad = array('ID3 ', 'tag ');
1144
foreach ($ID3v2_keys_bad as $ID3v2_key_bad) {
1145
if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) {
1146
$thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad];
1147
$info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"';
1151
if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
1152
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1153
$getid3_temp = new getID3();
1154
$getid3_temp->openfile($this->getid3->filename);
1155
$getid3_id3v2 = new getid3_id3v2($getid3_temp);
1156
$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
1157
if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1158
$info['id3v2'] = $getid3_temp->info['id3v2'];
1160
unset($getid3_temp, $getid3_id3v2);
1165
if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
1166
$thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
1168
if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
1169
self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
1171
if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
1172
self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
1175
if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) {
1176
$thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version'];
1179
if (!isset($info['playtime_seconds'])) {
1180
$info['playtime_seconds'] = 0;
1182
if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1183
// needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie
1184
$info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1185
} elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1186
$info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1189
if ($info['playtime_seconds'] > 0) {
1190
if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1192
if (!isset($info['bitrate'])) {
1193
$info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1196
} elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
1198
if (!isset($thisfile_audio['bitrate'])) {
1199
$thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1202
} elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1204
if (!isset($thisfile_video['bitrate'])) {
1205
$thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1212
if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) {
1214
$info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1215
$thisfile_audio['bitrate'] = 0;
1216
$thisfile_video['bitrate'] = $info['bitrate'];
1217
foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
1218
$thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
1219
$thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
1221
if ($thisfile_video['bitrate'] <= 0) {
1222
unset($thisfile_video['bitrate']);
1224
if ($thisfile_audio['bitrate'] <= 0) {
1225
unset($thisfile_audio['bitrate']);
1229
if (isset($info['mpeg']['audio'])) {
1230
$thisfile_audio_dataformat = 'mp'.$info['mpeg']['audio']['layer'];
1231
$thisfile_audio['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1232
$thisfile_audio['channels'] = $info['mpeg']['audio']['channels'];
1233
$thisfile_audio['bitrate'] = $info['mpeg']['audio']['bitrate'];
1234
$thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1235
if (!empty($info['mpeg']['audio']['codec'])) {
1236
$thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
1238
if (!empty($thisfile_audio['streams'])) {
1239
foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
1240
if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
1241
$thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate'];
1242
$thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels'];
1243
$thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
1244
$thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
1245
$thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec'];
1249
$getid3_mp3 = new getid3_mp3($this->getid3);
1250
$thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions();
1255
if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
1256
switch ($thisfile_audio_dataformat) {
1258
// ignore bits_per_sample
1262
$thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
1268
if (empty($thisfile_riff_raw)) {
1269
unset($thisfile_riff['raw']);
1271
if (empty($thisfile_riff_audio)) {
1272
unset($thisfile_riff['audio']);
1274
if (empty($thisfile_riff_video)) {
1275
unset($thisfile_riff['video']);
1281
public function ParseRIFF($startoffset, $maxoffset) {
1282
$info = &$this->getid3->info;
1285
$FoundAllChunksWeNeed = false;
1288
$this->fseek($startoffset);
1289
$maxoffset = min($maxoffset, $info['avdataend']);
1290
while ($this->ftell() < $maxoffset) {
1291
$chunknamesize = $this->fread(8);
1292
//$chunkname = substr($chunknamesize, 0, 4);
1293
$chunkname = str_replace("\x00", '_', substr($chunknamesize, 0, 4)); // note: chunk names of 4 null bytes do appear to be legal (has been observed inside INFO and PRMI chunks, for example), but makes traversing array keys more difficult
1294
$chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4));
1295
//if (strlen(trim($chunkname, "\x00")) < 4) {
1296
if (strlen($chunkname) < 4) {
1297
$this->error('Expecting chunk name at offset '.($this->ftell() - 8).' but found nothing. Aborting RIFF parsing.');
1300
if (($chunksize == 0) && ($chunkname != 'JUNK')) {
1301
$this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.');
1304
if (($chunksize % 2) != 0) {
1305
// all structures are packed on word boundaries
1309
switch ($chunkname) {
1311
$listname = $this->fread(4);
1312
if (preg_match('#^(movi|rec )$#i', $listname)) {
1313
$RIFFchunk[$listname]['offset'] = $this->ftell() - 4;
1314
$RIFFchunk[$listname]['size'] = $chunksize;
1316
if (!$FoundAllChunksWeNeed) {
1317
$WhereWeWere = $this->ftell();
1318
$AudioChunkHeader = $this->fread(12);
1319
$AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1320
$AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1321
$AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1323
if ($AudioChunkStreamType == 'wb') {
1324
$FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1325
if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1327
if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1328
$getid3_temp = new getID3();
1329
$getid3_temp->openfile($this->getid3->filename);
1330
$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1331
$getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
1332
$getid3_mp3 = new getid3_mp3($getid3_temp);
1333
$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1334
if (isset($getid3_temp->info['mpeg']['audio'])) {
1335
$info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio'];
1336
$info['audio'] = $getid3_temp->info['audio'];
1337
$info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
1338
$info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1339
$info['audio']['channels'] = $info['mpeg']['audio']['channels'];
1340
$info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
1341
$info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1342
//$info['bitrate'] = $info['audio']['bitrate'];
1344
unset($getid3_temp, $getid3_mp3);
1347
} elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
1350
$getid3_temp = new getID3();
1351
$getid3_temp->openfile($this->getid3->filename);
1352
$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1353
$getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
1354
$getid3_ac3 = new getid3_ac3($getid3_temp);
1355
$getid3_ac3->Analyze();
1356
if (empty($getid3_temp->info['error'])) {
1357
$info['audio'] = $getid3_temp->info['audio'];
1358
$info['ac3'] = $getid3_temp->info['ac3'];
1359
if (!empty($getid3_temp->info['warning'])) {
1360
foreach ($getid3_temp->info['warning'] as $key => $value) {
1361
$info['warning'][] = $value;
1365
unset($getid3_temp, $getid3_ac3);
1368
$FoundAllChunksWeNeed = true;
1369
$this->fseek($WhereWeWere);
1371
$this->fseek($chunksize - 4, SEEK_CUR);
1375
if (!isset($RIFFchunk[$listname])) {
1376
$RIFFchunk[$listname] = array();
1378
$LISTchunkParent = $listname;
1379
$LISTchunkMaxOffset = $this->ftell() - 4 + $chunksize;
1380
if ($parsedChunk = $this->ParseRIFF($this->ftell(), $LISTchunkMaxOffset)) {
1381
$RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1388
if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1389
$this->fseek($chunksize, SEEK_CUR);
1393
if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1394
$thisindex = count($RIFFchunk[$chunkname]);
1396
$RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8;
1397
$RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1398
switch ($chunkname) {
1400
$info['avdataoffset'] = $this->ftell();
1401
$info['avdataend'] = $info['avdataoffset'] + $chunksize;
1403
$testData = $this->fread(36);
1404
if ($testData === '') {
1407
if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
1409
// Probably is MP3 data
1410
if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
1411
$getid3_temp = new getID3();
1412
$getid3_temp->openfile($this->getid3->filename);
1413
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1414
$getid3_temp->info['avdataend'] = $info['avdataend'];
1415
$getid3_mp3 = new getid3_mp3($getid3_temp);
1416
$getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
1417
if (empty($getid3_temp->info['error'])) {
1418
$info['audio'] = $getid3_temp->info['audio'];
1419
$info['mpeg'] = $getid3_temp->info['mpeg'];
1421
unset($getid3_temp, $getid3_mp3);
1424
} elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
1426
// This is probably AC-3 data
1427
$getid3_temp = new getID3();
1428
if ($isRegularAC3) {
1429
$getid3_temp->openfile($this->getid3->filename);
1430
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1431
$getid3_temp->info['avdataend'] = $info['avdataend'];
1433
$getid3_ac3 = new getid3_ac3($getid3_temp);
1434
if ($isRegularAC3) {
1435
$getid3_ac3->Analyze();
1437
// Dolby Digital WAV
1438
// AC-3 content, but not encoded in same format as normal AC-3 file
1439
// For one thing, byte order is swapped
1441
for ($i = 0; $i < 28; $i += 2) {
1442
$ac3_data .= substr($testData, 8 + $i + 1, 1);
1443
$ac3_data .= substr($testData, 8 + $i + 0, 1);
1445
$getid3_ac3->AnalyzeString($ac3_data);
1448
if (empty($getid3_temp->info['error'])) {
1449
$info['audio'] = $getid3_temp->info['audio'];
1450
$info['ac3'] = $getid3_temp->info['ac3'];
1451
if (!empty($getid3_temp->info['warning'])) {
1452
foreach ($getid3_temp->info['warning'] as $newerror) {
1453
$this->warning('getid3_ac3() says: ['.$newerror.']');
1457
unset($getid3_temp, $getid3_ac3);
1459
} elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
1461
// This is probably DTS data
1462
$getid3_temp = new getID3();
1463
$getid3_temp->openfile($this->getid3->filename);
1464
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1465
$getid3_dts = new getid3_dts($getid3_temp);
1466
$getid3_dts->Analyze();
1467
if (empty($getid3_temp->info['error'])) {
1468
$info['audio'] = $getid3_temp->info['audio'];
1469
$info['dts'] = $getid3_temp->info['dts'];
1470
$info['playtime_seconds'] = $getid3_temp->info['playtime_seconds']; // may not match RIFF calculations since DTS-WAV often used 14/16 bit-word packing
1471
if (!empty($getid3_temp->info['warning'])) {
1472
foreach ($getid3_temp->info['warning'] as $newerror) {
1473
$this->warning('getid3_dts() says: ['.$newerror.']');
1478
unset($getid3_temp, $getid3_dts);
1480
} elseif (substr($testData, 0, 4) == 'wvpk') {
1482
// This is WavPack data
1483
$info['wavpack']['offset'] = $info['avdataoffset'];
1484
$info['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($testData, 4, 4));
1485
$this->parseWavPackHeader(substr($testData, 8, 28));
1488
// This is some other kind of data (quite possibly just PCM)
1489
// do nothing special, just skip it
1491
$nextoffset = $info['avdataend'];
1492
$this->fseek($nextoffset);
1504
// always read data in
1506
// should be: never read data in
1507
// but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
1508
if ($chunksize < 1048576) {
1509
if ($chunksize > 0) {
1510
$RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1511
if ($chunkname == 'JUNK') {
1512
if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) {
1513
// only keep text characters [chr(32)-chr(127)]
1514
$info['riff']['comments']['junk'][] = trim($matches[1]);
1516
// but if nothing there, ignore
1517
// remove the key in either case
1518
unset($RIFFchunk[$chunkname][$thisindex]['data']);
1522
$this->warning('Chunk "'.$chunkname.'" at offset '.$this->ftell().' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data');
1523
$this->fseek($chunksize, SEEK_CUR);
1528
// $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
1532
if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1533
$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1534
$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1535
unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1536
unset($RIFFchunk[$chunkname][$thisindex]['size']);
1537
if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1538
unset($RIFFchunk[$chunkname][$thisindex]);
1540
if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1541
unset($RIFFchunk[$chunkname]);
1543
$RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1544
} elseif ($chunksize < 2048) {
1545
// only read data in if smaller than 2kB
1546
$RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1548
$this->fseek($chunksize, SEEK_CUR);
1556
} catch (getid3_exception $e) {
1557
if ($e->getCode() == 10) {
1558
$this->warning('RIFF parser: '.$e->getMessage());
1567
public function ParseRIFFdata(&$RIFFdata) {
1568
$info = &$this->getid3->info;
1570
$tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
1571
$fp_temp = fopen($tempfile, 'wb');
1572
$RIFFdataLength = strlen($RIFFdata);
1573
$NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1574
for ($i = 0; $i < 4; $i++) {
1575
$RIFFdata[($i + 4)] = $NewLengthString[$i];
1577
fwrite($fp_temp, $RIFFdata);
1580
$getid3_temp = new getID3();
1581
$getid3_temp->openfile($tempfile);
1582
$getid3_temp->info['filesize'] = $RIFFdataLength;
1583
$getid3_temp->info['filenamepath'] = $info['filenamepath'];
1584
$getid3_temp->info['tags'] = $info['tags'];
1585
$getid3_temp->info['warning'] = $info['warning'];
1586
$getid3_temp->info['error'] = $info['error'];
1587
$getid3_temp->info['comments'] = $info['comments'];
1588
$getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array());
1589
$getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array());
1590
$getid3_riff = new getid3_riff($getid3_temp);
1591
$getid3_riff->Analyze();
1593
$info['riff'] = $getid3_temp->info['riff'];
1594
$info['warning'] = $getid3_temp->info['warning'];
1595
$info['error'] = $getid3_temp->info['error'];
1596
$info['tags'] = $getid3_temp->info['tags'];
1597
$info['comments'] = $getid3_temp->info['comments'];
1598
unset($getid3_riff, $getid3_temp);
1604
public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) {
1605
$RIFFinfoKeyLookup = array(
1606
'IARL'=>'archivallocation',
1608
'ICDS'=>'costumedesigner',
1609
'ICMS'=>'commissionedby',
1612
'ICOP'=>'copyright',
1613
'ICRD'=>'creationdate',
1614
'IDIM'=>'dimensions',
1615
'IDIT'=>'digitizationdate',
1616
'IDPI'=>'resolution',
1617
'IDST'=>'distributor',
1619
'IENG'=>'engineers',
1620
'IFRM'=>'accountofparts',
1623
'ILGT'=>'lightness',
1625
'IMED'=>'orignalmedium',
1628
'IPDS'=>'productiondesigner',
1636
'ISGN'=>'secondarygenre',
1637
'ISHP'=>'sharpness',
1638
'ISRC'=>'sourcesupplier',
1639
'ISRF'=>'digitizationsource',
1640
'ISTD'=>'productionstudio',
1642
'ITCH'=>'encoded_by',
1647
foreach ($RIFFinfoKeyLookup as $key => $value) {
1648
if (isset($RIFFinfoArray[$key])) {
1649
foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1650
if (trim($commentdata['data']) != '') {
1651
if (isset($CommentsTargetArray[$value])) {
1652
$CommentsTargetArray[$value][] = trim($commentdata['data']);
1654
$CommentsTargetArray[$value] = array(trim($commentdata['data']));
1663
public static function parseWAVEFORMATex($WaveFormatExData) {
1665
$WaveFormatEx['raw'] = array();
1666
$WaveFormatEx_raw = &$WaveFormatEx['raw'];
1668
$WaveFormatEx_raw['wFormatTag'] = substr($WaveFormatExData, 0, 2);
1669
$WaveFormatEx_raw['nChannels'] = substr($WaveFormatExData, 2, 2);
1670
$WaveFormatEx_raw['nSamplesPerSec'] = substr($WaveFormatExData, 4, 4);
1671
$WaveFormatEx_raw['nAvgBytesPerSec'] = substr($WaveFormatExData, 8, 4);
1672
$WaveFormatEx_raw['nBlockAlign'] = substr($WaveFormatExData, 12, 2);
1673
$WaveFormatEx_raw['wBitsPerSample'] = substr($WaveFormatExData, 14, 2);
1674
if (strlen($WaveFormatExData) > 16) {
1675
$WaveFormatEx_raw['cbSize'] = substr($WaveFormatExData, 16, 2);
1677
$WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw);
1679
$WaveFormatEx['codec'] = self::wFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1680
$WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1681
$WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1682
$WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1683
$WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1685
return $WaveFormatEx;
1688
public function parseWavPackHeader($WavPackChunkData) {
1693
// short bits; // added for version 2.00
1694
// short flags, shift; // added for version 3.00
1695
// long total_samples, crc, crc2;
1696
// char extension [4], extra_bc, extras [3];
1700
$info = &$this->getid3->info;
1701
$info['wavpack'] = array();
1702
$thisfile_wavpack = &$info['wavpack'];
1704
$thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1705
if ($thisfile_wavpack['version'] >= 2) {
1706
$thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1708
if ($thisfile_wavpack['version'] >= 3) {
1709
$thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1710
$thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1711
$thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1712
$thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1713
$thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1714
$thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1715
$thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1716
for ($i = 0; $i <= 2; $i++) {
1717
$thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1721
$thisfile_wavpack['flags'] = array();
1722
$thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1724
$thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1725
$thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1726
$thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1727
$thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1728
$thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1729
$thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1730
$thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1731
$thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1732
$thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1733
$thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1734
$thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1735
$thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1736
$thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1737
$thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1738
$thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1739
$thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1740
$thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1741
$thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1742
$thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1743
$thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1749
public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
1751
$parsed['biSize'] = substr($BITMAPINFOHEADER, 0, 4); // number of bytes required by the BITMAPINFOHEADER structure
1752
$parsed['biWidth'] = substr($BITMAPINFOHEADER, 4, 4); // width of the bitmap in pixels
1753
$parsed['biHeight'] = substr($BITMAPINFOHEADER, 8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
1754
$parsed['biPlanes'] = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1
1755
$parsed['biBitCount'] = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels
1756
$parsed['biSizeImage'] = substr($BITMAPINFOHEADER, 20, 4); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1757
$parsed['biXPelsPerMeter'] = substr($BITMAPINFOHEADER, 24, 4); // horizontal resolution, in pixels per metre, of the target device
1758
$parsed['biYPelsPerMeter'] = substr($BITMAPINFOHEADER, 28, 4); // vertical resolution, in pixels per metre, of the target device
1759
$parsed['biClrUsed'] = substr($BITMAPINFOHEADER, 32, 4); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
1760
$parsed['biClrImportant'] = substr($BITMAPINFOHEADER, 36, 4); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
1761
$parsed = array_map('getid3_lib::'.($littleEndian ? 'Little' : 'Big').'Endian2Int', $parsed);
1763
$parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier
1768
public static function ParseDIVXTAG($DIVXTAG, $raw=false) {
1769
// structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1770
// source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1771
// 'Byte Layout: '1111111111111111
1772
// '32 for Movie - 1 '1111111111111111
1773
// '28 for Author - 6 '6666666666666666
1774
// '4 for year - 2 '6666666666662222
1775
// '3 for genre - 3 '7777777777777777
1776
// '48 for Comments - 7 '7777777777777777
1777
// '1 for Rating - 4 '7777777777777777
1778
// '5 for Future Additions - 0 '333400000DIVXTAG
1781
static $DIVXTAGgenre = array(
1783
1 => 'Action/Adventure',
1795
13 => 'Infomercial',
1796
14 => 'Interactive',
1798
16 => 'Music Video',
1805
$DIVXTAGrating = array(
1814
$parsed['title'] = trim(substr($DIVXTAG, 0, 32));
1815
$parsed['artist'] = trim(substr($DIVXTAG, 32, 28));
1816
$parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4)));
1817
$parsed['comment'] = trim(substr($DIVXTAG, 64, 48));
1818
$parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3)));
1819
$parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1));
1820
//$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null
1821
//$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG"
1823
$parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']);
1824
$parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1827
unset($parsed['genre_id'], $parsed['rating_id']);
1828
foreach ($parsed as $key => $value) {
1829
if (!$value === '') {
1830
unset($parsed['key']);
1835
foreach ($parsed as $tag => $value) {
1836
$parsed[$tag] = array($value);
1842
public static function waveSNDMtagLookup($tagshortname) {
1845
/** This is not a comment!
1852
©fin featuredinstrument
1862
return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1865
public static function wFormatTagLookup($wFormatTag) {
1869
/** This is not a comment!
1871
0x0000 Microsoft Unknown Wave Format
1872
0x0001 Pulse Code Modulation (PCM)
1873
0x0002 Microsoft ADPCM
1875
0x0004 Compaq Computer VSELP
1877
0x0006 Microsoft A-Law
1878
0x0007 Microsoft mu-Law
1879
0x0008 Microsoft DTS
1881
0x0011 Intel DVI/IMA ADPCM
1882
0x0012 Videologic MediaSpace ADPCM
1883
0x0013 Sierra Semiconductor ADPCM
1884
0x0014 Antex Electronics G.723 ADPCM
1885
0x0015 DSP Solutions DigiSTD
1886
0x0016 DSP Solutions DigiFIX
1887
0x0017 Dialogic OKI ADPCM
1888
0x0018 MediaVision ADPCM
1889
0x0019 Hewlett-Packard CU
1891
0x0021 Speech Compression Sonarc
1892
0x0022 DSP Group TrueSpeech
1893
0x0023 Echo Speech EchoSC1
1894
0x0024 Audiofile AF36
1895
0x0025 Audio Processing Technology APTX
1896
0x0026 AudioFile AF10
1900
0x0031 Microsoft GSM 6.10
1902
0x0033 Antex Electronics ADPCME
1903
0x0034 Control Resources VQLPC
1904
0x0035 DSP Solutions DigiREAL
1905
0x0036 DSP Solutions DigiADPCM
1906
0x0037 Control Resources CR10
1907
0x0038 Natural MicroSystems VBXADPCM
1908
0x0039 Crystal Semiconductor IMA ADPCM
1910
0x003B Rockwell ADPCM
1911
0x003C Rockwell Digit LK
1913
0x0040 Antex Electronics G.721 ADPCM
1916
0x0050 MPEG Layer-2 or Layer-1
1924
0x0063 Canopus Atrac
1929
0x0069 Voxware Byte Aligned
1934
0x0074 Voxware MetaVoice
1935
0x0075 Voxware MetaSound
1936
0x0076 Voxware RT29HW
1950
0x0092 Dolby AC3 SPDIF
1951
0x0093 MediaSonic G.723
1952
0x0094 Aculab PLC Prosody 8kbps
1954
0x0098 Philips LPCBB
1957
0x0100 Rhetorex ADPCM
1960
0x0103 IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
1963
0x0123 Digital G.723
1964
0x0125 Sanyo LD ADPCM
1965
0x0130 Sipro Lab Telecom ACELP NET
1966
0x0131 Sipro Lab Telecom ACELP 4800
1967
0x0132 Sipro Lab Telecom ACELP 8V3
1968
0x0133 Sipro Lab Telecom G.729
1969
0x0134 Sipro Lab Telecom G.729A
1970
0x0135 Sipro Lab Telecom Kelvin
1971
0x0140 Windows Media Video V8
1972
0x0150 Qualcomm PureVoice
1973
0x0151 Qualcomm HalfRate
1974
0x0155 Ring Zero Systems TUB GSM
1975
0x0160 Microsoft Audio 1
1976
0x0161 Windows Media Audio V7 / V8 / V9
1977
0x0162 Windows Media Audio Professional V9
1978
0x0163 Windows Media Audio Lossless V9
1979
0x0200 Creative Labs ADPCM
1980
0x0202 Creative Labs Fastspeech8
1981
0x0203 Creative Labs Fastspeech10
1982
0x0210 UHER Informatic GmbH ADPCM
1984
0x0230 I-link Worldwide VC
1985
0x0240 Aureal RAW Sport
1986
0x0250 Interactive Products HSX
1987
0x0251 Interactive Products RPELP
1988
0x0260 Consistent Software CS2
1990
0x0300 Fujitsu FM Towns Snd
1992
0x0401 Intel Music Coder
1993
0x0450 QDesign Music
1995
0x0681 AT&T Labs TPC
1996
0x08AE ClearJump LiteWave
1998
0x1001 Olivetti ADPCM
1999
0x1002 Olivetti CELP
2002
0x1100 Lernout & Hauspie Codec (0x1100)
2003
0x1101 Lernout & Hauspie CELP Codec (0x1101)
2004
0x1102 Lernout & Hauspie SBC Codec (0x1102)
2005
0x1103 Lernout & Hauspie SBC Codec (0x1103)
2006
0x1104 Lernout & Hauspie SBC Codec (0x1104)
2008
0x1401 AT&T ISIAudio
2009
0x1500 Soundspace Music Compression
2010
0x181C VoxWare RT24 Speech
2011
0x1FC4 NCT Soft ALF2CD (www.nctsoft.com)
2014
0x2002 WAVE_FORMAT_14_4
2015
0x2003 WAVE_FORMAT_28_8
2016
0x2004 WAVE_FORMAT_COOK
2017
0x2005 WAVE_FORMAT_DNET
2021
0x676F Ogg Vorbis 1+
2022
0x6770 Ogg Vorbis 2+
2023
0x6771 Ogg Vorbis 3+
2024
0x7A21 GSM-AMR (CBR, no SID)
2025
0x7A22 GSM-AMR (VBR, including SID)
2026
0xFFFE WAVE_FORMAT_EXTENSIBLE
2027
0xFFFF WAVE_FORMAT_DEVELOPMENT
2031
return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
2034
public static function fourccLookup($fourcc) {
2038
/** This is not a comment!
2040
swot http://developer.apple.com/qa/snd/snd07.html
2041
____ No Codec (____)
2042
_BIT BI_BITFIELDS (Raw RGB)
2043
_JPG JPEG compressed
2044
_PNG PNG compressed W3C/ISO/IEC (RFC-2083)
2045
_RAW Full Frames (Uncompressed)
2052
AASC Autodesk Animator
2053
ABYR Kensington ?ABYR?
2054
AEMI Array Microsystems VideoONE MPEG1-I Capture
2055
AFLC Autodesk Animator FLC
2056
AFLI Autodesk Animator FLI
2057
AMPG Array Microsystems VideoONE MPEG
2058
ANIM Intel RDX (ANIM)
2059
AP41 AngelPotion Definitive
2062
ASVX Asus Video 2.0 (audio)
2063
AUR2 AuraVision Aura 2 Codec - YUV 4:2:2
2064
AURA AuraVision Aura 1 Codec - YUV 4:1:1
2065
AVDJ Independent JPEG Group\'s codec (AVDJ)
2066
AVRN Independent JPEG Group\'s codec (AVRN)
2067
AYUV 4:4:4 YUV (AYUV)
2068
AZPR Quicktime Apple Video (AZPR)
2070
BLZ0 Blizzard DivX MPEG-4
2071
BTVC Conexant Composite Video
2072
BINK RAD Game Tools Bink Video
2073
BT20 Conexant Prosumer Video
2074
BTCV Conexant Composite Video Codec
2075
BW10 Data Translation Broadway MPEG Capture
2078
CFCC Digital Processing Systems DPS Perception
2079
CGDI Microsoft Office 97 Camcorder Video
2080
CHAM Winnov Caviara Champagne
2081
CJPG Creative WebCam JPEG
2082
CLJR Cirrus Logic YUV 4:1:1
2083
CMYK Common Data Format in Printing (Colorgraph)
2084
CPLA Weitek 4:2:0 YUV Planar
2085
CRAM Microsoft Video 1 (CRAM)
2088
CWLT Microsoft Color WLT DIB
2089
CYUV Creative Labs YUV
2093
DIB Device Independent Bitmap
2094
DIV1 FFmpeg OpenDivX
2095
DIV2 Microsoft MPEG-4 v1/v2
2096
DIV3 DivX ;-) MPEG-4 v3.x Low-Motion
2097
DIV4 DivX ;-) MPEG-4 v3.x Fast-Motion
2098
DIV5 DivX MPEG-4 v5.x
2099
DIV6 DivX ;-) (MS MPEG-4 v3.x)
2100
DIVX DivX MPEG-4 v4 (OpenDivX / Project Mayo)
2102
DMB1 Matrox Rainbow Runner hardware MJPEG
2105
DUCK Duck TrueMotion 1.0
2106
DPS0 DPS/Leitch Reality Motion JPEG
2107
DPSC DPS/Leitch PAR Motion JPEG
2108
DV25 Matrox DVCPRO codec
2109
DV50 Matrox DVCPRO50 codec
2110
DVC IEC 61834 and SMPTE 314M (DVC/DV Video)
2111
DVCP IEC 61834 and SMPTE 314M (DVC/DV Video)
2112
DVHD IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
2113
DVMA Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
2114
DVSL IEC Standard DV compressed in SD (SDL)
2116
DVE2 InSoft DVE-2 Videoconferencing
2117
dvsd IEC 61834 and SMPTE 314M DVC/DV Video
2118
DVSD IEC 61834 and SMPTE 314M DVC/DV Video
2119
DVX1 Lucent DVX1000SP Video Decoder
2120
DVX2 Lucent DVX2000S Video Decoder
2121
DVX3 Lucent DVX3000S Video Decoder
2123
DXT1 Microsoft DirectX Compressed Texture (DXT1)
2124
DXT2 Microsoft DirectX Compressed Texture (DXT2)
2125
DXT3 Microsoft DirectX Compressed Texture (DXT3)
2126
DXT4 Microsoft DirectX Compressed Texture (DXT4)
2127
DXT5 Microsoft DirectX Compressed Texture (DXT5)
2128
DXTC Microsoft DirectX Compressed Texture (DXTC)
2129
DXTn Microsoft DirectX Compressed Texture (DXTn)
2130
EM2V Etymonix MPEG-2 I-frame (www.etymonix.com)
2134
ETV1 eTreppid Video ETV1
2135
ETV2 eTreppid Video ETV2
2136
ETVC eTreppid Video ETVC
2137
FLIC Autodesk FLI/FLC Animation
2139
FLV4 On2 TrueMotion VP6
2140
FRWT Darim Vision Forward Motion JPEG (www.darvision.com)
2141
FRWU Darim Vision Forward Uncompressed (www.darvision.com)
2142
FLJP D-Vision Field Encoded Motion JPEG
2144
FRWA SoftLab-Nsk Forward Motion JPEG w/ alpha channel
2145
FRWD SoftLab-Nsk Forward Motion JPEG
2146
FVF1 Iterated Systems Fractal Video Frame
2147
GLZW Motion LZW (gabest@freemail.hu)
2148
GPEG Motion JPEG (gabest@freemail.hu)
2149
GWLT Microsoft Greyscale WLT DIB
2150
H260 Intel ITU H.260 Videoconferencing
2151
H261 Intel ITU H.261 Videoconferencing
2152
H262 Intel ITU H.262 Videoconferencing
2153
H263 Intel ITU H.263 Videoconferencing
2154
H264 Intel ITU H.264 Videoconferencing
2155
H265 Intel ITU H.265 Videoconferencing
2156
H266 Intel ITU H.266 Videoconferencing
2157
H267 Intel ITU H.267 Videoconferencing
2158
H268 Intel ITU H.268 Videoconferencing
2159
H269 Intel ITU H.269 Videoconferencing
2160
HFYU Huffman Lossless Codec
2161
HMCR Rendition Motion Compensation Format (HMCR)
2162
HMRR Rendition Motion Compensation Format (HMRR)
2163
I263 FFmpeg I263 decoder
2164
IF09 Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
2165
IUYV Interlaced version of UYVY (www.leadtools.com)
2166
IY41 Interlaced version of Y41P (www.leadtools.com)
2167
IYU1 12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard
2168
IYU2 24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec IEEE standard
2169
IYUV Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes)
2170
i263 Intel ITU H.263 Videoconferencing (i263)
2172
IAN Intel Indeo 4 (RDX)
2173
ICLB InSoft CellB Videoconferencing
2175
IJPG Intergraph JPEG
2176
ILVC Intel Layered Video
2178
IPDV I-O Data Device Giga AVI DV Codec
2179
IR21 Intel Indeo 2.1
2180
IRAW Intel YUV Uncompressed
2181
IV30 Intel Indeo 3.0
2182
IV31 Intel Indeo 3.1
2183
IV32 Ligos Indeo 3.2
2184
IV33 Ligos Indeo 3.3
2185
IV34 Ligos Indeo 3.4
2186
IV35 Ligos Indeo 3.5
2187
IV36 Ligos Indeo 3.6
2188
IV37 Ligos Indeo 3.7
2189
IV38 Ligos Indeo 3.8
2190
IV39 Ligos Indeo 3.9
2191
IV40 Ligos Indeo Interactive 4.0
2192
IV41 Ligos Indeo Interactive 4.1
2193
IV42 Ligos Indeo Interactive 4.2
2194
IV43 Ligos Indeo Interactive 4.3
2195
IV44 Ligos Indeo Interactive 4.4
2196
IV45 Ligos Indeo Interactive 4.5
2197
IV46 Ligos Indeo Interactive 4.6
2198
IV47 Ligos Indeo Interactive 4.7
2199
IV48 Ligos Indeo Interactive 4.8
2200
IV49 Ligos Indeo Interactive 4.9
2201
IV50 Ligos Indeo Interactive 5.0
2202
JBYR Kensington ?JBYR?
2203
JPEG Still Image JPEG DIB
2204
JPGL Pegasus Lossless Motion JPEG
2205
KMVC Team17 Software Karl Morton\'s Video Codec
2206
LSVM Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
2207
LEAD LEAD Video Codec
2208
Ljpg LEAD MJPEG Codec
2209
MDVD Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
2210
MJPA Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
2211
MJPB Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
2212
MMES Matrox MPEG-2 I-frame
2213
MP2v Microsoft S-Mpeg 4 version 1 (MP2v)
2214
MP42 Microsoft S-Mpeg 4 version 2 (MP42)
2215
MP43 Microsoft S-Mpeg 4 version 3 (MP43)
2216
MP4S Microsoft S-Mpeg 4 version 3 (MP4S)
2218
MPG1 FFmpeg MPEG 1/2
2219
MPG2 FFmpeg MPEG 1/2
2220
MPG3 FFmpeg DivX ;-) (MS MPEG-4 v3)
2221
MPG4 Microsoft MPEG-4
2222
MPGI Sigma Designs MPEG
2223
MPNG PNG images decoder
2224
MSS1 Microsoft Windows Screen Video
2225
MSZH LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2226
M261 Microsoft H.261
2227
M263 Microsoft H.263
2228
M4S2 Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
2229
m4s2 Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
2230
MC12 ATI Motion Compensation Format (MC12)
2231
MCAM ATI Motion Compensation Format (MCAM)
2232
MJ2C Morgan Multimedia Motion JPEG2000
2233
mJPG IBM Motion JPEG w/ Huffman Tables
2234
MJPG Microsoft Motion JPEG DIB
2235
MP42 Microsoft MPEG-4 (low-motion)
2236
MP43 Microsoft MPEG-4 (fast-motion)
2237
MP4S Microsoft MPEG-4 (MP4S)
2238
mp4s Microsoft MPEG-4 (mp4s)
2239
MPEG Chromatic Research MPEG-1 Video I-Frame
2240
MPG4 Microsoft MPEG-4 Video High Speed Compressor
2241
MPGI Sigma Designs MPEG
2242
MRCA FAST Multimedia Martin Regen Codec
2243
MRLE Microsoft Run Length Encoding
2244
MSVC Microsoft Video 1
2254
MV12 Motion Pixels Codec (old)
2255
MWV1 Aware Motion Wavelets
2256
nAVI SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
2257
NT00 NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
2259
NTN1 Nogatech Video Compression 1
2260
NVS0 nVidia GeForce Texture (NVS0)
2261
NVS1 nVidia GeForce Texture (NVS1)
2262
NVS2 nVidia GeForce Texture (NVS2)
2263
NVS3 nVidia GeForce Texture (NVS3)
2264
NVS4 nVidia GeForce Texture (NVS4)
2265
NVS5 nVidia GeForce Texture (NVS5)
2266
NVT0 nVidia GeForce Texture (NVT0)
2267
NVT1 nVidia GeForce Texture (NVT1)
2268
NVT2 nVidia GeForce Texture (NVT2)
2269
NVT3 nVidia GeForce Texture (NVT3)
2270
NVT4 nVidia GeForce Texture (NVT4)
2271
NVT5 nVidia GeForce Texture (NVT5)
2272
PIXL MiroXL, Pinnacle PCTV
2273
PDVC I-O Data Device Digital Video Capture DV codec
2274
PGVV Radius Video Vision
2275
PHMO IBM Photomotion
2276
PIM1 MPEG Realtime (Pinnacle Cards)
2277
PIM2 Pegasus Imaging ?PIM2?
2278
PIMJ Pegasus Imaging Lossless JPEG
2279
PVEZ Horizons Technology PowerEZ
2280
PVMM PacketVideo Corporation MPEG-4
2281
PVW2 Pegasus Imaging Wavelet Compression
2282
Q1.0 Q-Team\'s QPEG 1.0 (www.q-team.de)
2283
Q1.1 Q-Team\'s QPEG 1.1 (www.q-team.de)
2284
QPEG Q-Team QPEG 1.0
2285
qpeq Q-Team QPEG 1.1
2287
RGBA Raw RGB w/ Alpha
2288
RMP4 REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
2289
ROQV Id RoQ File Video Decoder
2290
RPZA Quicktime Apple Video (RPZA)
2291
RUD0 Rududu video codec (http://rududu.ifrance.com/rududu/)
2292
RV10 RealVideo 1.0 (aka RealVideo 5.0)
2293
RV13 RealVideo 1.0 (RV13)
2297
RGBT Raw RGB w/ Transparency
2298
RLE Microsoft Run Length Encoder
2299
RLE4 Run Length Encoded (4bpp, 16-color)
2300
RLE8 Run Length Encoded (8bpp, 256-color)
2301
RT21 Intel Indeo RealTime Video 2.1
2304
RVX Intel RDX (RVX )
2305
SMC Apple Graphics (SMC )
2306
SP54 Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
2308
SVQ3 Sorenson Video 3 (Apple Quicktime 5)
2309
s422 Tekram VideoCap C210 YUV 4:2:2
2310
SDCC Sun Communication Digital Camera Codec
2311
SFMC CrystalNet Surface Fitting Method
2314
smsv WorldConnect Wavelet Video
2316
SPLC Splash Studios ACM Audio Codec (www.splashstudios.net)
2317
SQZ2 Microsoft VXTreme Video Codec V2
2318
STVA ST Microelectronics CMOS Imager Data (Bayer)
2319
STVB ST Microelectronics CMOS Imager Data (Nudged Bayer)
2320
STVC ST Microelectronics CMOS Imager Data (Bunched)
2321
STVX ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
2322
STVY ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
2323
SV10 Sorenson Video R1
2325
T420 Toshiba YUV 4:2:0
2326
TM2A Duck TrueMotion Archiver 2.0 (www.duck.com)
2327
TVJP Pinnacle/Truevision Targa 2000 board (TVJP)
2328
TVMJ Pinnacle/Truevision Targa 2000 board (TVMJ)
2329
TY0N Tecomac Low-Bit Rate Codec (www.tecomac.com)
2330
TY2C Trident Decompression Driver
2331
TLMS TeraLogic Motion Intraframe Codec (TLMS)
2332
TLST TeraLogic Motion Intraframe Codec (TLST)
2333
TM20 Duck TrueMotion 2.0
2334
TM2X Duck TrueMotion 2X
2335
TMIC TeraLogic Motion Intraframe Codec (TMIC)
2336
TMOT Horizons Technology TrueMotion S
2337
tmot Horizons TrueMotion Video Compression
2338
TR20 Duck TrueMotion RealTime 2.0
2339
TSCC TechSmith Screen Capture Codec
2340
TV10 Tecomac Low-Bit Rate Codec
2342
U263 UB Video H.263/H.263+/H.263++ Decoder
2343
UMP4 UB Video MPEG 4 (www.ubvideo.com)
2344
UYNV Nvidia UYVY packed 4:2:2
2345
UYVP Evans & Sutherland YCbCr 4:2:2 extended precision
2346
UCOD eMajix.com ClearVideo
2348
UYVY UYVY packed 4:2:2
2350
VIFP VFAPI Reader Codec (www.yks.ne.jp/~hori/)
2351
VIV1 FFmpeg H263+ decoder
2353
VQC2 Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
2354
VTLP Alaris VideoGramPiX
2358
V422 Vitec Multimedia 24-bit YUV 4:2:2 Format
2359
V655 Vitec Multimedia 16-bit YUV 4:2:2 Format
2360
VCR1 ATI Video Codec 1
2361
VCR2 ATI Video Codec 2
2369
VDCT Vitec Multimedia Video Maker Pro DIB
2371
VDOW VDOnet VDOLive (H.263)
2372
VDTZ Darim Vison VideoTizer YUV
2373
VGPX Alaris VideoGramPiX
2374
VIDS Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
2375
VIVO Vivo H.263 v2.00
2377
VIXL Miro/Pinnacle Video XL
2378
VLV1 VideoLogic/PURE Digital Videologic Capture
2381
VP6F On2 TrueMotion VP6
2382
VX1K Lucent VX1000S Video Codec
2383
VX2K Lucent VX2000S Video Codec
2384
VXSP Lucent VX1000SP Video Codec
2386
WHAM Microsoft Video 1 (WHAM)
2387
WINX Winnov Software Compression
2388
WJPG AverMedia Winbond JPEG
2389
WMV1 Windows Media Video V7
2390
WMV2 Windows Media Video V8
2391
WMV3 Windows Media Video V9
2392
WNV1 Winnov Hardware Compression
2393
XYZP Extended PAL format XYZ palette (www.riff.org)
2395
XLV0 NetXL Video Decoder
2396
XMPG Xing MPEG (I-Frame only)
2397
XVID XviD MPEG-4 (www.xvid.org)
2399
YU92 Intel YUV (YU92)
2400
YUNV Nvidia Uncompressed YUV 4:2:2
2401
YUVP Extended PAL format YUV palette (www.riff.org)
2402
Y211 YUV 2:1:1 Packed
2403
Y411 YUV 4:1:1 Packed
2404
Y41B Weitek YUV 4:1:1 Planar
2405
Y41P Brooktree PC1 YUV 4:1:1 Packed
2406
Y41T Brooktree PC1 YUV 4:1:1 with transparency
2407
Y42B Weitek YUV 4:2:2 Planar
2408
Y42T Brooktree UYUV 4:2:2 with transparency
2409
Y422 ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
2410
Y800 Simple, single Y plane for monochrome images
2412
YC12 Intel YUV 12 codec
2413
YUV8 Winnov Caviar YUV8
2415
YUY2 Uncompressed YUV 4:2:2
2418
YVU9 Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
2419
YVYU YVYU 4:2:2 Packed
2420
ZLIB Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2421
ZPEG Metheus Video Zipper
2425
return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2428
private function EitherEndian2Int($byteword, $signed=false) {
2429
if ($this->getid3->info['fileformat'] == 'riff') {
2430
return getid3_lib::LittleEndian2Int($byteword, $signed);
2432
return getid3_lib::BigEndian2Int($byteword, false, $signed);