~canonical-sysadmins/wordpress/3.9.x

« back to all changes in this revision

Viewing changes to wp-includes/ID3/module.audio-video.riff.php

  • Committer: Jacek Nykis
  • Date: 2013-08-22 11:13:48 UTC
  • Revision ID: jacek.nykis@canonical.com-20130822111348-c4rttn5cynk5tl3o
Import wordpress 3.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
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
/////////////////////////////////////////////////////////////////
 
9
//                                                             //
 
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                          //
 
17
//                                                            ///
 
18
/////////////////////////////////////////////////////////////////
 
19
 
 
20
/**
 
21
* @todo Parse AC-3/DTS audio inside WAVE correctly
 
22
* @todo Rewrite RIFF parser totally
 
23
*/
 
24
 
 
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);
 
28
 
 
29
class getid3_riff extends getid3_handler
 
30
{
 
31
 
 
32
        public function Analyze() {
 
33
                $info = &$this->getid3->info;
 
34
 
 
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());
 
38
 
 
39
                // Shortcuts
 
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'];
 
47
 
 
48
                $Original['avdataoffset'] = $info['avdataoffset'];
 
49
                $Original['avdataend']    = $info['avdataend'];
 
50
 
 
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);
 
57
 
 
58
                switch ($RIFFtype) {
 
59
 
 
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));
 
64
                                break;
 
65
 
 
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';
 
74
                                }
 
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'];
 
81
                                }
 
82
 
 
83
                                $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
 
84
                                while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) {
 
85
                                        try {
 
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');
 
92
                                                        break;
 
93
                                                } else {
 
94
                                                        throw $e;
 
95
                                                }
 
96
                                        }
 
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
 
101
                                                        break;
 
102
                                                }
 
103
                                        }
 
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'];
 
111
 
 
112
                                        switch ($nextRIFFheaderID) {
 
113
 
 
114
                                                case 'RIFF':
 
115
                                                        $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset);
 
116
 
 
117
                                                        if (!isset($thisfile_riff[$nextRIFFtype])) {
 
118
                                                                $thisfile_riff[$nextRIFFtype] = array();
 
119
                                                        }
 
120
                                                        $thisfile_riff[$nextRIFFtype][] = $chunkdata;
 
121
                                                        break;
 
122
 
 
123
                                                case 'JUNK':
 
124
                                                        // ignore
 
125
                                                        $thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
 
126
                                                        break;
 
127
 
 
128
                                                case 'IDVX':
 
129
                                                        $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size']));
 
130
                                                        break;
 
131
 
 
132
                                                default:
 
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);
 
139
                                                                        break 2;
 
140
                                                                }
 
141
                                                        }
 
142
                                                        $this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file');
 
143
                                                        break 2;
 
144
 
 
145
                                        }
 
146
 
 
147
                                }
 
148
                                if ($RIFFsubtype == 'WAVE') {
 
149
                                        $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
 
150
                                }
 
151
                                break;
 
152
 
 
153
                        default:
 
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']);
 
156
                                return false;
 
157
                }
 
158
 
 
159
                $streamindex = 0;
 
160
                switch ($RIFFsubtype) {
 
161
                        case 'WAVE':
 
162
                                if (empty($thisfile_audio['bitrate_mode'])) {
 
163
                                        $thisfile_audio['bitrate_mode'] = 'cbr';
 
164
                                }
 
165
                                if (empty($thisfile_audio_dataformat)) {
 
166
                                        $thisfile_audio_dataformat = 'wav';
 
167
                                }
 
168
 
 
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'];
 
172
                                }
 
173
                                if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
 
174
 
 
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';
 
179
                                                return false;
 
180
                                        }
 
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];
 
184
 
 
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'];
 
188
                                        }
 
189
                                        $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
 
190
 
 
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']);
 
193
                                        }
 
194
 
 
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']) {
 
198
 
 
199
                                                        case 0x0001:  // PCM
 
200
                                                                $thisfile_audio['lossless'] = true;
 
201
                                                                break;
 
202
 
 
203
                                                        case 0x2000:  // AC-3
 
204
                                                                $thisfile_audio_dataformat = 'ac3';
 
205
                                                                break;
 
206
 
 
207
                                                        default:
 
208
                                                                // do nothing
 
209
                                                                break;
 
210
 
 
211
                                                }
 
212
                                        }
 
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;
 
217
                                }
 
218
 
 
219
                                if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
 
220
 
 
221
                                        // shortcuts
 
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'];
 
227
 
 
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));
 
231
 
 
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));
 
242
 
 
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']);
 
248
                                        }
 
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']);
 
253
                                        }
 
254
                                }
 
255
 
 
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));
 
258
 
 
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
 
262
 
 
263
                                        // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
 
264
                                        //     $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
 
265
                                        // }
 
266
                                }
 
267
                                if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
 
268
                                        $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
 
269
                                }
 
270
 
 
271
                                if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
 
272
                                        // shortcut
 
273
                                        $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
 
274
 
 
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']);
 
289
                                                } else {
 
290
                                                        $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
 
291
                                                }
 
292
                                        } else {
 
293
                                                $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
 
294
                                        }
 
295
                                        $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
 
296
                                        $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_bext_0['title'];
 
297
                                }
 
298
 
 
299
                                if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
 
300
                                        // shortcut
 
301
                                        $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
 
302
 
 
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);
 
309
 
 
310
                                                $thisfile_riff_WAVE_MEXT_0['nominal_frame_size']        = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
 
311
                                        }
 
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);
 
317
                                }
 
318
 
 
319
                                if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
 
320
                                        // shortcut
 
321
                                        $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
 
322
 
 
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));
 
342
                                        }
 
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)));
 
345
 
 
346
                                        $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
 
347
                                        $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_cart_0['title'];
 
348
                                }
 
349
 
 
350
                                if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
 
351
                                        // SoundMiner metadata
 
352
 
 
353
                                        // shortcuts
 
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'];
 
358
 
 
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;
 
371
 
 
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).')';
 
374
                                                        break;
 
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).')';
 
377
                                                        break;
 
378
                                                }
 
379
                                                $SNDM_startoffset += $SNDM_thisTagSize;
 
380
 
 
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;
 
384
                                                } else {
 
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).')';
 
386
                                                }
 
387
                                        }
 
388
 
 
389
                                        $tagmapping = array(
 
390
                                                'tracktitle'=>'title',
 
391
                                                'category'  =>'genre',
 
392
                                                'cdtitle'   =>'album',
 
393
                                                'tracktitle'=>'title',
 
394
                                        );
 
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];
 
398
                                                }
 
399
                                        }
 
400
                                }
 
401
 
 
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);
 
409
                                                }
 
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);
 
413
                                                }
 
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));
 
423
                                                }
 
424
                                                unset($parsedXML);
 
425
                                        }
 
426
                                }
 
427
 
 
428
 
 
429
 
 
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']);
 
433
                                }
 
434
 
 
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'];
 
439
 
 
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'];
 
443
 
 
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;
 
448
 
 
449
                                        if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
 
450
                                                $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
 
451
                                                $this->fseek($info['avdataend']);
 
452
                                                $RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
 
453
                                        }
 
454
 
 
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);
 
461
                                        unset($getid3_riff);
 
462
                                }
 
463
 
 
464
                                if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
 
465
                                        switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
 
466
                                                case 0x0001: // PCM
 
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'];
 
474
                                                        }
 
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'];
 
482
                                                        }
 
483
                                                        break;
 
484
                                                case 0x08AE: // ClearJump LiteWave
 
485
                                                        $thisfile_audio['bitrate_mode'] = 'vbr';
 
486
                                                        $thisfile_audio_dataformat   = 'litewave';
 
487
 
 
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
 
494
                                                        //  WORD    m_wReserved;
 
495
                                                        //
 
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
 
500
                                                        //
 
501
                                                        //  PCMWAVEFORMAT m_OrgWf;     // original wave format
 
502
                                                        // }SLwFormat, *PSLwFormat;
 
503
 
 
504
                                                        // shortcut
 
505
                                                        $thisfile_riff['litewave']['raw'] = array();
 
506
                                                        $riff_litewave     = &$thisfile_riff['litewave'];
 
507
                                                        $riff_litewave_raw = &$riff_litewave['raw'];
 
508
 
 
509
                                                        $flags = array(
 
510
                                                                'compression_method' => 1,
 
511
                                                                'compression_flags'  => 1,
 
512
                                                                'm_dwScale'          => 4,
 
513
                                                                'm_dwBlockSize'      => 4,
 
514
                                                                'm_wQuality'         => 2,
 
515
                                                                'm_wMarkDistance'    => 2,
 
516
                                                                'm_wReserved'        => 2,
 
517
                                                                'm_dwOrgSize'        => 4,
 
518
                                                                'm_bFactExists'      => 2,
 
519
                                                                'm_dwRiffChunkSize'  => 4,
 
520
                                                        );
 
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;
 
525
                                                        }
 
526
 
 
527
                                                        //$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20));
 
528
                                                        $riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality'];
 
529
 
 
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);
 
533
 
 
534
                                                        $thisfile_audio['lossless']        = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false);
 
535
                                                        $thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor'];
 
536
                                                        break;
 
537
 
 
538
                                                default:
 
539
                                                        break;
 
540
                                        }
 
541
                                }
 
542
                                if ($info['avdataend'] > $info['filesize']) {
 
543
                                        switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
 
544
                                                case 'wavpack': // WavPack
 
545
                                                case 'lpac':    // LPAC
 
546
                                                case 'ofr':     // OptimFROG
 
547
                                                case 'ofs':     // OptimFROG DualStream
 
548
                                                        // lossless compressed audio formats that keep original RIFF headers - skip warning
 
549
                                                        break;
 
550
 
 
551
                                                case 'litewave':
 
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
 
556
                                                        } else {
 
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'];
 
560
                                                        }
 
561
                                                        break;
 
562
 
 
563
                                                default:
 
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'];
 
569
                                                        } else {
 
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'];
 
573
                                                        }
 
574
                                                        break;
 
575
                                        }
 
576
                                }
 
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';
 
581
                                        }
 
582
                                }
 
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'];
 
587
                                        }
 
588
                                }
 
589
                                break;
 
590
 
 
591
                        case 'AVI ':
 
592
                                $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
 
593
                                $thisfile_video['dataformat']   = 'avi';
 
594
                                $info['mime_type']      = 'video/avi';
 
595
 
 
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'];
 
600
                                        } else {
 
601
                                                $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
 
602
                                        }
 
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'];
 
606
                                        }
 
607
                                }
 
608
 
 
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',
 
614
                                        //);
 
615
                                        //$bIndexSubtype = array(
 
616
                                        //      0x01 => array(
 
617
                                        //              0x01 => 'AVI_INDEX_2FIELD',
 
618
                                        //      ),
 
619
                                        //);
 
620
                                        foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
 
621
                                                $ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
 
622
 
 
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));
 
629
 
 
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']];
 
632
 
 
633
                                                unset($ahsisd);
 
634
                                        }
 
635
                                }
 
636
                                if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
 
637
                                        $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
 
638
 
 
639
                                        // shortcut
 
640
                                        $thisfile_riff_raw['avih'] = array();
 
641
                                        $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
 
642
 
 
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';
 
646
                                                return false;
 
647
                                        }
 
648
 
 
649
                                        $flags = array(
 
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',        //
 
655
                                                'dwStreams',              //
 
656
                                                'dwSuggestedBufferSize',  //
 
657
                                                'dwWidth',                //
 
658
                                                'dwHeight',               //
 
659
                                                'dwScale',                //
 
660
                                                'dwRate',                 //
 
661
                                                'dwStart',                //
 
662
                                                'dwLength',               //
 
663
                                        );
 
664
                                        $avih_offset = 4;
 
665
                                        foreach ($flags as $flag) {
 
666
                                                $thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4));
 
667
                                                $avih_offset += 4;
 
668
                                        }
 
669
 
 
670
                                        $flags = array(
 
671
                                                'hasindex'     => 0x00000010,
 
672
                                                'mustuseindex' => 0x00000020,
 
673
                                                'interleaved'  => 0x00000100,
 
674
                                                'trustcktype'  => 0x00000800,
 
675
                                                'capturedfile' => 0x00010000,
 
676
                                                'copyrighted'  => 0x00020010,
 
677
                                        );
 
678
                    foreach ($flags as $flag => $value) {
 
679
                                                $thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
 
680
                                        }
 
681
 
 
682
                                        // shortcut
 
683
                                        $thisfile_riff_video[$streamindex] = array();
 
684
                                        $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
 
685
 
 
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'];
 
689
                                        }
 
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'];
 
693
                                        }
 
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'];
 
697
                                        }
 
698
 
 
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'];
 
701
                                }
 
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);
 
708
 
 
709
                                                                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
 
710
                                                                        $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
 
711
 
 
712
                                                                        // shortcut
 
713
                                                                        $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
 
714
 
 
715
                                                                        switch ($strhfccType) {
 
716
                                                                                case 'auds':
 
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);
 
721
                                                                                        }
 
722
 
 
723
                                                                                        $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData);
 
724
                                                                                        $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
 
725
 
 
726
                                                                                        // shortcut
 
727
                                                                                        $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
 
728
                                                                                        $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
 
729
 
 
730
                                                                                        if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
 
731
                                                                                                unset($thisfile_audio_streams_currentstream['bits_per_sample']);
 
732
                                                                                        }
 
733
                                                                                        $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
 
734
                                                                                        unset($thisfile_audio_streams_currentstream['raw']);
 
735
 
 
736
                                                                                        // shortcut
 
737
                                                                                        $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
 
738
 
 
739
                                                                                        unset($thisfile_riff_audio[$streamindex]['raw']);
 
740
                                                                                        $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
 
741
 
 
742
                                                                                        $thisfile_audio['lossless'] = false;
 
743
                                                                                        switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
 
744
                                                                                                case 0x0001:  // PCM
 
745
                                                                                                        $thisfile_audio_dataformat  = 'wav';
 
746
                                                                                                        $thisfile_audio['lossless'] = true;
 
747
                                                                                                        break;
 
748
 
 
749
                                                                                                case 0x0050: // MPEG Layer 2 or Layer 1
 
750
                                                                                                        $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
 
751
                                                                                                        break;
 
752
 
 
753
                                                                                                case 0x0055: // MPEG Layer 3
 
754
                                                                                                        $thisfile_audio_dataformat = 'mp3';
 
755
                                                                                                        break;
 
756
 
 
757
                                                                                                case 0x00FF: // AAC
 
758
                                                                                                        $thisfile_audio_dataformat = 'aac';
 
759
                                                                                                        break;
 
760
 
 
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';
 
765
                                                                                                        break;
 
766
 
 
767
                                                                                                case 0x2000: // AC-3
 
768
                                                                                                        $thisfile_audio_dataformat = 'ac3';
 
769
                                                                                                        break;
 
770
 
 
771
                                                                                                case 0x2001: // DTS
 
772
                                                                                                        $thisfile_audio_dataformat = 'dts';
 
773
                                                                                                        break;
 
774
 
 
775
                                                                                                default:
 
776
                                                                                                        $thisfile_audio_dataformat = 'wav';
 
777
                                                                                                        break;
 
778
                                                                                        }
 
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'];
 
782
                                                                                        break;
 
783
 
 
784
 
 
785
                                                                                case 'iavs':
 
786
                                                                                case 'vids':
 
787
                                                                                        // shortcut
 
788
                                                                                        $thisfile_riff_raw['strh'][$i]                  = array();
 
789
                                                                                        $thisfile_riff_raw_strh_current                 = &$thisfile_riff_raw['strh'][$i];
 
790
 
 
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));
 
805
 
 
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'];
 
811
                                                                                        }
 
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;
 
819
                                                                                                        break;
 
820
 
 
821
                                                                                                default:
 
822
                                                                                                        $thisfile_video['lossless'] = false;
 
823
                                                                                                        break;
 
824
                                                                                        }
 
825
 
 
826
                                                                                        switch ($strhfccType) {
 
827
                                                                                                case 'vids':
 
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'];
 
830
 
 
831
                                                                                                        if ($thisfile_riff_video_current['codec'] == 'DV') {
 
832
                                                                                                                $thisfile_riff_video_current['dv_type'] = 2;
 
833
                                                                                                        }
 
834
                                                                                                        break;
 
835
 
 
836
                                                                                                case 'iavs':
 
837
                                                                                                        $thisfile_riff_video_current['dv_type'] = 1;
 
838
                                                                                                        break;
 
839
                                                                                        }
 
840
                                                                                        break;
 
841
 
 
842
                                                                                default:
 
843
                                                                                        $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
 
844
                                                                                        break;
 
845
 
 
846
                                                                        }
 
847
                                                                }
 
848
                                                        }
 
849
 
 
850
                                                        if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
 
851
 
 
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'];
 
856
                                                                }
 
857
 
 
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;
 
864
                                                                                break;
 
865
 
 
866
                                                                        default:
 
867
                                                                                $thisfile_video['lossless']        = false;
 
868
                                                                                //$thisfile_video['bits_per_sample'] = 24;
 
869
                                                                                break;
 
870
                                                                }
 
871
 
 
872
                                                        }
 
873
                                                }
 
874
                                        }
 
875
                                }
 
876
                                break;
 
877
 
 
878
                        case 'CDDA':
 
879
                                $thisfile_audio['bitrate_mode'] = 'cbr';
 
880
                                $thisfile_audio_dataformat      = 'cda';
 
881
                                $thisfile_audio['lossless']     = true;
 
882
                                unset($info['mime_type']);
 
883
 
 
884
                                $info['avdataoffset'] = 44;
 
885
 
 
886
                                if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
 
887
                                        // shortcut
 
888
                                        $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
 
889
 
 
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));
 
897
 
 
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'];
 
902
 
 
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';
 
909
                                }
 
910
                                break;
 
911
 
 
912
 
 
913
                        case 'AIFF':
 
914
                        case 'AIFC':
 
915
                                $thisfile_audio['bitrate_mode'] = 'cbr';
 
916
                                $thisfile_audio_dataformat      = 'aiff';
 
917
                                $thisfile_audio['lossless']     = true;
 
918
                                $info['mime_type']      = 'audio/x-aiff';
 
919
 
 
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
 
927
                                                } else {
 
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';
 
929
                                                }
 
930
                                                $info['avdataend'] = $info['filesize'];
 
931
                                        }
 
932
                                }
 
933
 
 
934
                                if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
 
935
 
 
936
                                        // shortcut
 
937
                                        $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
 
938
 
 
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));
 
943
 
 
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']) {
 
949
                                                        case 'NONE':
 
950
                                                                $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
 
951
                                                                $thisfile_audio['lossless'] = true;
 
952
                                                                break;
 
953
 
 
954
                                                        case '':
 
955
                                                                switch ($thisfile_riff_audio['codec_fourcc']) {
 
956
                                                                        // http://developer.apple.com/qa/snd/snd07.html
 
957
                                                                        case 'sowt':
 
958
                                                                                $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
 
959
                                                                                $thisfile_audio['lossless'] = true;
 
960
                                                                                break;
 
961
 
 
962
                                                                        case 'twos':
 
963
                                                                                $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
 
964
                                                                                $thisfile_audio['lossless'] = true;
 
965
                                                                                break;
 
966
 
 
967
                                                                        default:
 
968
                                                                                break;
 
969
                                                                }
 
970
                                                                break;
 
971
 
 
972
                                                        default:
 
973
                                                                $thisfile_audio['codec']    = $thisfile_riff_audio['codec_name'];
 
974
                                                                $thisfile_audio['lossless'] = false;
 
975
                                                                break;
 
976
                                                }
 
977
                                        }
 
978
 
 
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'];
 
982
                                        }
 
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';
 
986
                                                return false;
 
987
                                        }
 
988
                                        $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
 
989
                                }
 
990
 
 
991
                                if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
 
992
                                        $offset = 0;
 
993
                                        $CommentCount                                   = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
 
994
                                        $offset += 2;
 
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);
 
997
                                                $offset += 4;
 
998
                                                $info['comments_raw'][$i]['marker_id']      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
 
999
                                                $offset += 2;
 
1000
                                                $CommentLength                              = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
 
1001
                                                $offset += 2;
 
1002
                                                $info['comments_raw'][$i]['comment']        =                           substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
 
1003
                                                $offset += $CommentLength;
 
1004
 
 
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'];
 
1007
                                        }
 
1008
                                }
 
1009
 
 
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'];
 
1014
                                        }
 
1015
                                }
 
1016
/*
 
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'];
 
1025
                                        }
 
1026
                                        unset($getid3_temp, $getid3_id3v2);
 
1027
                                }
 
1028
*/
 
1029
                                break;
 
1030
 
 
1031
                        case '8SVX':
 
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';
 
1037
 
 
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';
 
1043
                                        }
 
1044
                                }
 
1045
 
 
1046
                                if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
 
1047
                                        // shortcut
 
1048
                                        $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
 
1049
 
 
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));
 
1057
 
 
1058
                                        $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
 
1059
 
 
1060
                                        switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
 
1061
                                                case 0:
 
1062
                                                        $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
 
1063
                                                        $thisfile_audio['lossless'] = true;
 
1064
                                                        $ActualBitsPerSample        = 8;
 
1065
                                                        break;
 
1066
 
 
1067
                                                case 1:
 
1068
                                                        $thisfile_audio['codec']    = 'Fibonacci-delta encoding';
 
1069
                                                        $thisfile_audio['lossless'] = false;
 
1070
                                                        $ActualBitsPerSample        = 4;
 
1071
                                                        break;
 
1072
 
 
1073
                                                default:
 
1074
                                                        $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
 
1075
                                                        break;
 
1076
                                        }
 
1077
                                }
 
1078
 
 
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) {
 
1082
                                                case 6: // Stereo
 
1083
                                                        $thisfile_audio['channels'] = 2;
 
1084
                                                        break;
 
1085
 
 
1086
                                                case 2: // Left channel only
 
1087
                                                case 4: // Right channel only
 
1088
                                                        $thisfile_audio['channels'] = 1;
 
1089
                                                        break;
 
1090
 
 
1091
                                                default:
 
1092
                                                        $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
 
1093
                                                        break;
 
1094
                                        }
 
1095
 
 
1096
                                }
 
1097
 
 
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'];
 
1102
                                        }
 
1103
                                }
 
1104
 
 
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);
 
1108
                                }
 
1109
                                break;
 
1110
 
 
1111
 
 
1112
                        case 'CDXA':
 
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'];
 
1125
                                                }
 
1126
                                                unset($getid3_temp, $getid3_mpeg);
 
1127
                                        }
 
1128
                                }
 
1129
                                break;
 
1130
 
 
1131
 
 
1132
                        default:
 
1133
                                $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
 
1134
                                unset($info['fileformat']);
 
1135
                                break;
 
1136
                }
 
1137
 
 
1138
                switch ($RIFFsubtype) {
 
1139
                        case 'WAVE':
 
1140
                        case 'AIFF':
 
1141
                        case 'AIFC':
 
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.'"';
 
1148
                                        }
 
1149
                                }
 
1150
 
 
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'];
 
1159
                                        }
 
1160
                                        unset($getid3_temp, $getid3_id3v2);
 
1161
                                }
 
1162
                                break;
 
1163
                }
 
1164
 
 
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));
 
1167
                }
 
1168
                if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
 
1169
                        self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
 
1170
                }
 
1171
                if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
 
1172
                        self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
 
1173
                }
 
1174
 
 
1175
                if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) {
 
1176
                        $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version'];
 
1177
                }
 
1178
 
 
1179
                if (!isset($info['playtime_seconds'])) {
 
1180
                        $info['playtime_seconds'] = 0;
 
1181
                }
 
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);
 
1187
                }
 
1188
 
 
1189
                if ($info['playtime_seconds'] > 0) {
 
1190
                        if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
 
1191
 
 
1192
                                if (!isset($info['bitrate'])) {
 
1193
                                        $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
 
1194
                                }
 
1195
 
 
1196
                        } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
 
1197
 
 
1198
                                if (!isset($thisfile_audio['bitrate'])) {
 
1199
                                        $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
 
1200
                                }
 
1201
 
 
1202
                        } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
 
1203
 
 
1204
                                if (!isset($thisfile_video['bitrate'])) {
 
1205
                                        $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
 
1206
                                }
 
1207
 
 
1208
                        }
 
1209
                }
 
1210
 
 
1211
 
 
1212
                if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) {
 
1213
 
 
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'];
 
1220
                        }
 
1221
                        if ($thisfile_video['bitrate'] <= 0) {
 
1222
                                unset($thisfile_video['bitrate']);
 
1223
                        }
 
1224
                        if ($thisfile_audio['bitrate'] <= 0) {
 
1225
                                unset($thisfile_audio['bitrate']);
 
1226
                        }
 
1227
                }
 
1228
 
 
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'];
 
1237
                        }
 
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'];
 
1246
                                        }
 
1247
                                }
 
1248
                        }
 
1249
                        $getid3_mp3 = new getid3_mp3($this->getid3);
 
1250
                        $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions();
 
1251
                        unset($getid3_mp3);
 
1252
                }
 
1253
 
 
1254
 
 
1255
                if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
 
1256
                        switch ($thisfile_audio_dataformat) {
 
1257
                                case 'ac3':
 
1258
                                        // ignore bits_per_sample
 
1259
                                        break;
 
1260
 
 
1261
                                default:
 
1262
                                        $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
 
1263
                                        break;
 
1264
                        }
 
1265
                }
 
1266
 
 
1267
 
 
1268
                if (empty($thisfile_riff_raw)) {
 
1269
                        unset($thisfile_riff['raw']);
 
1270
                }
 
1271
                if (empty($thisfile_riff_audio)) {
 
1272
                        unset($thisfile_riff['audio']);
 
1273
                }
 
1274
                if (empty($thisfile_riff_video)) {
 
1275
                        unset($thisfile_riff['video']);
 
1276
                }
 
1277
 
 
1278
                return true;
 
1279
        }
 
1280
 
 
1281
        public function ParseRIFF($startoffset, $maxoffset) {
 
1282
                $info = &$this->getid3->info;
 
1283
 
 
1284
                $RIFFchunk = false;
 
1285
                $FoundAllChunksWeNeed = false;
 
1286
 
 
1287
                try {
 
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.');
 
1298
                                        break;
 
1299
                                }
 
1300
                                if (($chunksize == 0) && ($chunkname != 'JUNK')) {
 
1301
                                        $this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.');
 
1302
                                        break;
 
1303
                                }
 
1304
                                if (($chunksize % 2) != 0) {
 
1305
                                        // all structures are packed on word boundaries
 
1306
                                        $chunksize++;
 
1307
                                }
 
1308
 
 
1309
                                switch ($chunkname) {
 
1310
                                        case 'LIST':
 
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;
 
1315
 
 
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));
 
1322
 
 
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)) {
 
1326
                                                                                // MP3
 
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'];
 
1343
                                                                                        }
 
1344
                                                                                        unset($getid3_temp, $getid3_mp3);
 
1345
                                                                                }
 
1346
 
 
1347
                                                                        } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
 
1348
 
 
1349
                                                                                // AC3
 
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;
 
1362
                                                                                                }
 
1363
                                                                                        }
 
1364
                                                                                }
 
1365
                                                                                unset($getid3_temp, $getid3_ac3);
 
1366
                                                                        }
 
1367
                                                                }
 
1368
                                                                $FoundAllChunksWeNeed = true;
 
1369
                                                                $this->fseek($WhereWeWere);
 
1370
                                                        }
 
1371
                                                        $this->fseek($chunksize - 4, SEEK_CUR);
 
1372
 
 
1373
                                                } else {
 
1374
 
 
1375
                                                        if (!isset($RIFFchunk[$listname])) {
 
1376
                                                                $RIFFchunk[$listname] = array();
 
1377
                                                        }
 
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);
 
1382
                                                        }
 
1383
 
 
1384
                                                }
 
1385
                                                break;
 
1386
 
 
1387
                                        default:
 
1388
                                                if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
 
1389
                                                        $this->fseek($chunksize, SEEK_CUR);
 
1390
                                                        break;
 
1391
                                                }
 
1392
                                                $thisindex = 0;
 
1393
                                                if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
 
1394
                                                        $thisindex = count($RIFFchunk[$chunkname]);
 
1395
                                                }
 
1396
                                                $RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8;
 
1397
                                                $RIFFchunk[$chunkname][$thisindex]['size']   = $chunksize;
 
1398
                                                switch ($chunkname) {
 
1399
                                                        case 'data':
 
1400
                                                                $info['avdataoffset'] = $this->ftell();
 
1401
                                                                $info['avdataend']    = $info['avdataoffset'] + $chunksize;
 
1402
 
 
1403
                                                                $testData = $this->fread(36);
 
1404
                                                                if ($testData === '') {
 
1405
                                                                        break;
 
1406
                                                                }
 
1407
                                                                if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
 
1408
 
 
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'];
 
1420
                                                                                }
 
1421
                                                                                unset($getid3_temp, $getid3_mp3);
 
1422
                                                                        }
 
1423
 
 
1424
                                                                } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
 
1425
 
 
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'];
 
1432
                                                                        }
 
1433
                                                                        $getid3_ac3 = new getid3_ac3($getid3_temp);
 
1434
                                                                        if ($isRegularAC3) {
 
1435
                                                                                $getid3_ac3->Analyze();
 
1436
                                                                        } else {
 
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
 
1440
                                                                                $ac3_data = '';
 
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);
 
1444
                                                                                }
 
1445
                                                                                $getid3_ac3->AnalyzeString($ac3_data);
 
1446
                                                                        }
 
1447
 
 
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.']');
 
1454
                                                                                        }
 
1455
                                                                                }
 
1456
                                                                        }
 
1457
                                                                        unset($getid3_temp, $getid3_ac3);
 
1458
 
 
1459
                                                                } elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
 
1460
 
 
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.']');
 
1474
                                                                                        }
 
1475
                                                                                }
 
1476
                                                                        }
 
1477
 
 
1478
                                                                        unset($getid3_temp, $getid3_dts);
 
1479
 
 
1480
                                                                } elseif (substr($testData, 0, 4) == 'wvpk') {
 
1481
 
 
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));
 
1486
 
 
1487
                                                                } else {
 
1488
                                                                        // This is some other kind of data (quite possibly just PCM)
 
1489
                                                                        // do nothing special, just skip it
 
1490
                                                                }
 
1491
                                                                $nextoffset = $info['avdataend'];
 
1492
                                                                $this->fseek($nextoffset);
 
1493
                                                                break;
 
1494
 
 
1495
                                                        case 'iXML':
 
1496
                                                        case 'bext':
 
1497
                                                        case 'cart':
 
1498
                                                        case 'fmt ':
 
1499
                                                        case 'strh':
 
1500
                                                        case 'strf':
 
1501
                                                        case 'indx':
 
1502
                                                        case 'MEXT':
 
1503
                                                        case 'DISP':
 
1504
                                                                // always read data in
 
1505
                                                        case 'JUNK':
 
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]);
 
1515
                                                                                        }
 
1516
                                                                                        // but if nothing there, ignore
 
1517
                                                                                        // remove the key in either case
 
1518
                                                                                        unset($RIFFchunk[$chunkname][$thisindex]['data']);
 
1519
                                                                                }
 
1520
                                                                        }
 
1521
                                                                } else {
 
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);
 
1524
                                                                }
 
1525
                                                                break;
 
1526
 
 
1527
                                                        //case 'IDVX':
 
1528
                                                        //      $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
 
1529
                                                        //      break;
 
1530
 
 
1531
                                                        default:
 
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]);
 
1539
                                                                        }
 
1540
                                                                        if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
 
1541
                                                                                unset($RIFFchunk[$chunkname]);
 
1542
                                                                        }
 
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);
 
1547
                                                                } else {
 
1548
                                                                        $this->fseek($chunksize, SEEK_CUR);
 
1549
                                                                }
 
1550
                                                                break;
 
1551
                                                }
 
1552
                                                break;
 
1553
                                }
 
1554
                        }
 
1555
 
 
1556
                } catch (getid3_exception $e) {
 
1557
                        if ($e->getCode() == 10) {
 
1558
                                $this->warning('RIFF parser: '.$e->getMessage());
 
1559
                        } else {
 
1560
                                throw $e;
 
1561
                        }
 
1562
                }
 
1563
 
 
1564
                return $RIFFchunk;
 
1565
        }
 
1566
 
 
1567
        public function ParseRIFFdata(&$RIFFdata) {
 
1568
                $info = &$this->getid3->info;
 
1569
                if ($RIFFdata) {
 
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];
 
1576
                        }
 
1577
                        fwrite($fp_temp, $RIFFdata);
 
1578
                        fclose($fp_temp);
 
1579
 
 
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();
 
1592
 
 
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);
 
1599
                        unlink($tempfile);
 
1600
                }
 
1601
                return false;
 
1602
        }
 
1603
 
 
1604
        public static function parseComments(&$RIFFinfoArray, &$CommentsTargetArray) {
 
1605
                $RIFFinfoKeyLookup = array(
 
1606
                        'IARL'=>'archivallocation',
 
1607
                        'IART'=>'artist',
 
1608
                        'ICDS'=>'costumedesigner',
 
1609
                        'ICMS'=>'commissionedby',
 
1610
                        'ICMT'=>'comment',
 
1611
                        'ICNT'=>'country',
 
1612
                        'ICOP'=>'copyright',
 
1613
                        'ICRD'=>'creationdate',
 
1614
                        'IDIM'=>'dimensions',
 
1615
                        'IDIT'=>'digitizationdate',
 
1616
                        'IDPI'=>'resolution',
 
1617
                        'IDST'=>'distributor',
 
1618
                        'IEDT'=>'editor',
 
1619
                        'IENG'=>'engineers',
 
1620
                        'IFRM'=>'accountofparts',
 
1621
                        'IGNR'=>'genre',
 
1622
                        'IKEY'=>'keywords',
 
1623
                        'ILGT'=>'lightness',
 
1624
                        'ILNG'=>'language',
 
1625
                        'IMED'=>'orignalmedium',
 
1626
                        'IMUS'=>'composer',
 
1627
                        'INAM'=>'title',
 
1628
                        'IPDS'=>'productiondesigner',
 
1629
                        'IPLT'=>'palette',
 
1630
                        'IPRD'=>'product',
 
1631
                        'IPRO'=>'producer',
 
1632
                        'IPRT'=>'part',
 
1633
                        'IRTD'=>'rating',
 
1634
                        'ISBJ'=>'subject',
 
1635
                        'ISFT'=>'software',
 
1636
                        'ISGN'=>'secondarygenre',
 
1637
                        'ISHP'=>'sharpness',
 
1638
                        'ISRC'=>'sourcesupplier',
 
1639
                        'ISRF'=>'digitizationsource',
 
1640
                        'ISTD'=>'productionstudio',
 
1641
                        'ISTR'=>'starring',
 
1642
                        'ITCH'=>'encoded_by',
 
1643
                        'IWEB'=>'url',
 
1644
                        'IWRI'=>'writer',
 
1645
                        '____'=>'comment',
 
1646
                );
 
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']);
 
1653
                                                } else {
 
1654
                                                        $CommentsTargetArray[$value] = array(trim($commentdata['data']));
 
1655
                                                }
 
1656
                                        }
 
1657
                                }
 
1658
                        }
 
1659
                }
 
1660
                return true;
 
1661
        }
 
1662
 
 
1663
        public static function parseWAVEFORMATex($WaveFormatExData) {
 
1664
                // shortcut
 
1665
                $WaveFormatEx['raw'] = array();
 
1666
                $WaveFormatEx_raw    = &$WaveFormatEx['raw'];
 
1667
 
 
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);
 
1676
                }
 
1677
                $WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw);
 
1678
 
 
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'];
 
1684
 
 
1685
                return $WaveFormatEx;
 
1686
        }
 
1687
 
 
1688
        public function parseWavPackHeader($WavPackChunkData) {
 
1689
                // typedef struct {
 
1690
                //     char ckID [4];
 
1691
                //     long ckSize;
 
1692
                //     short version;
 
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];
 
1697
                // } WavpackHeader;
 
1698
 
 
1699
                // shortcut
 
1700
                $info = &$this->getid3->info;
 
1701
                $info['wavpack']  = array();
 
1702
                $thisfile_wavpack = &$info['wavpack'];
 
1703
 
 
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));
 
1707
                }
 
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));
 
1718
                        }
 
1719
 
 
1720
                        // shortcut
 
1721
                        $thisfile_wavpack['flags'] = array();
 
1722
                        $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
 
1723
 
 
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);
 
1744
                }
 
1745
 
 
1746
                return true;
 
1747
        }
 
1748
 
 
1749
        public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
 
1750
 
 
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);
 
1762
 
 
1763
                $parsed['fourcc']          = substr($BITMAPINFOHEADER, 16, 4);  // compression identifier
 
1764
 
 
1765
                return $parsed;
 
1766
        }
 
1767
 
 
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
 
1779
                // '128 bytes total
 
1780
 
 
1781
                static $DIVXTAGgenre  = array(
 
1782
                         0 => 'Action',
 
1783
                         1 => 'Action/Adventure',
 
1784
                         2 => 'Adventure',
 
1785
                         3 => 'Adult',
 
1786
                         4 => 'Anime',
 
1787
                         5 => 'Cartoon',
 
1788
                         6 => 'Claymation',
 
1789
                         7 => 'Comedy',
 
1790
                         8 => 'Commercial',
 
1791
                         9 => 'Documentary',
 
1792
                        10 => 'Drama',
 
1793
                        11 => 'Home Video',
 
1794
                        12 => 'Horror',
 
1795
                        13 => 'Infomercial',
 
1796
                        14 => 'Interactive',
 
1797
                        15 => 'Mystery',
 
1798
                        16 => 'Music Video',
 
1799
                        17 => 'Other',
 
1800
                        18 => 'Religion',
 
1801
                        19 => 'Sci Fi',
 
1802
                        20 => 'Thriller',
 
1803
                        21 => 'Western',
 
1804
                ),
 
1805
                $DIVXTAGrating = array(
 
1806
                         0 => 'Unrated',
 
1807
                         1 => 'G',
 
1808
                         2 => 'PG',
 
1809
                         3 => 'PG-13',
 
1810
                         4 => 'R',
 
1811
                         5 => 'NC-17',
 
1812
                );
 
1813
 
 
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"
 
1822
 
 
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']);
 
1825
 
 
1826
                if (!$raw) {
 
1827
                        unset($parsed['genre_id'], $parsed['rating_id']);
 
1828
                        foreach ($parsed as $key => $value) {
 
1829
                                if (!$value === '') {
 
1830
                                        unset($parsed['key']);
 
1831
                                }
 
1832
                        }
 
1833
                }
 
1834
 
 
1835
                foreach ($parsed as $tag => $value) {
 
1836
                        $parsed[$tag] = array($value);
 
1837
                }
 
1838
 
 
1839
                return $parsed;
 
1840
        }
 
1841
 
 
1842
        public static function waveSNDMtagLookup($tagshortname) {
 
1843
                $begin = __LINE__;
 
1844
 
 
1845
                /** This is not a comment!
 
1846
 
 
1847
                        ©kwd    keywords
 
1848
                        ©BPM    bpm
 
1849
                        ©trt    tracktitle
 
1850
                        ©des    description
 
1851
                        ©gen    category
 
1852
                        ©fin    featuredinstrument
 
1853
                        ©LID    longid
 
1854
                        ©bex    bwdescription
 
1855
                        ©pub    publisher
 
1856
                        ©cdt    cdtitle
 
1857
                        ©alb    library
 
1858
                        ©com    composer
 
1859
 
 
1860
                */
 
1861
 
 
1862
                return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
 
1863
        }
 
1864
 
 
1865
        public static function wFormatTagLookup($wFormatTag) {
 
1866
 
 
1867
                $begin = __LINE__;
 
1868
 
 
1869
                /** This is not a comment!
 
1870
 
 
1871
                        0x0000  Microsoft Unknown Wave Format
 
1872
                        0x0001  Pulse Code Modulation (PCM)
 
1873
                        0x0002  Microsoft ADPCM
 
1874
                        0x0003  IEEE Float
 
1875
                        0x0004  Compaq Computer VSELP
 
1876
                        0x0005  IBM CVSD
 
1877
                        0x0006  Microsoft A-Law
 
1878
                        0x0007  Microsoft mu-Law
 
1879
                        0x0008  Microsoft DTS
 
1880
                        0x0010  OKI ADPCM
 
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
 
1890
                        0x0020  Yamaha ADPCM
 
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
 
1897
                        0x0027  Prosody 1612
 
1898
                        0x0028  LRC
 
1899
                        0x0030  Dolby AC2
 
1900
                        0x0031  Microsoft GSM 6.10
 
1901
                        0x0032  MSNAudio
 
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
 
1909
                        0x003A  EchoSC3
 
1910
                        0x003B  Rockwell ADPCM
 
1911
                        0x003C  Rockwell Digit LK
 
1912
                        0x003D  Xebec
 
1913
                        0x0040  Antex Electronics G.721 ADPCM
 
1914
                        0x0041  G.728 CELP
 
1915
                        0x0042  MSG723
 
1916
                        0x0050  MPEG Layer-2 or Layer-1
 
1917
                        0x0052  RT24
 
1918
                        0x0053  PAC
 
1919
                        0x0055  MPEG Layer-3
 
1920
                        0x0059  Lucent G.723
 
1921
                        0x0060  Cirrus
 
1922
                        0x0061  ESPCM
 
1923
                        0x0062  Voxware
 
1924
                        0x0063  Canopus Atrac
 
1925
                        0x0064  G.726 ADPCM
 
1926
                        0x0065  G.722 ADPCM
 
1927
                        0x0066  DSAT
 
1928
                        0x0067  DSAT Display
 
1929
                        0x0069  Voxware Byte Aligned
 
1930
                        0x0070  Voxware AC8
 
1931
                        0x0071  Voxware AC10
 
1932
                        0x0072  Voxware AC16
 
1933
                        0x0073  Voxware AC20
 
1934
                        0x0074  Voxware MetaVoice
 
1935
                        0x0075  Voxware MetaSound
 
1936
                        0x0076  Voxware RT29HW
 
1937
                        0x0077  Voxware VR12
 
1938
                        0x0078  Voxware VR18
 
1939
                        0x0079  Voxware TQ40
 
1940
                        0x0080  Softsound
 
1941
                        0x0081  Voxware TQ60
 
1942
                        0x0082  MSRT24
 
1943
                        0x0083  G.729A
 
1944
                        0x0084  MVI MV12
 
1945
                        0x0085  DF G.726
 
1946
                        0x0086  DF GSM610
 
1947
                        0x0088  ISIAudio
 
1948
                        0x0089  Onlive
 
1949
                        0x0091  SBC24
 
1950
                        0x0092  Dolby AC3 SPDIF
 
1951
                        0x0093  MediaSonic G.723
 
1952
                        0x0094  Aculab PLC    Prosody 8kbps
 
1953
                        0x0097  ZyXEL ADPCM
 
1954
                        0x0098  Philips LPCBB
 
1955
                        0x0099  Packed
 
1956
                        0x00FF  AAC
 
1957
                        0x0100  Rhetorex ADPCM
 
1958
                        0x0101  IBM mu-law
 
1959
                        0x0102  IBM A-law
 
1960
                        0x0103  IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
 
1961
                        0x0111  Vivo G.723
 
1962
                        0x0112  Vivo Siren
 
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
 
1983
                        0x0220  Quarterdeck
 
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
 
1989
                        0x0270  Sony SCX
 
1990
                        0x0300  Fujitsu FM Towns Snd
 
1991
                        0x0400  BTV Digital
 
1992
                        0x0401  Intel Music Coder
 
1993
                        0x0450  QDesign Music
 
1994
                        0x0680  VME VMPCM
 
1995
                        0x0681  AT&T Labs TPC
 
1996
                        0x08AE  ClearJump LiteWave
 
1997
                        0x1000  Olivetti GSM
 
1998
                        0x1001  Olivetti ADPCM
 
1999
                        0x1002  Olivetti CELP
 
2000
                        0x1003  Olivetti SBC
 
2001
                        0x1004  Olivetti OPR
 
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)
 
2007
                        0x1400  Norris
 
2008
                        0x1401  AT&T ISIAudio
 
2009
                        0x1500  Soundspace Music Compression
 
2010
                        0x181C  VoxWare RT24 Speech
 
2011
                        0x1FC4  NCT Soft ALF2CD (www.nctsoft.com)
 
2012
                        0x2000  Dolby AC3
 
2013
                        0x2001  Dolby DTS
 
2014
                        0x2002  WAVE_FORMAT_14_4
 
2015
                        0x2003  WAVE_FORMAT_28_8
 
2016
                        0x2004  WAVE_FORMAT_COOK
 
2017
                        0x2005  WAVE_FORMAT_DNET
 
2018
                        0x674F  Ogg Vorbis 1
 
2019
                        0x6750  Ogg Vorbis 2
 
2020
                        0x6751  Ogg Vorbis 3
 
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
 
2028
 
 
2029
                */
 
2030
 
 
2031
                return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
 
2032
        }
 
2033
 
 
2034
        public static function fourccLookup($fourcc) {
 
2035
 
 
2036
                $begin = __LINE__;
 
2037
 
 
2038
                /** This is not a comment!
 
2039
 
 
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)
 
2046
                        _RGB    Raw RGB Bitmap
 
2047
                        _RL4    RLE 4bpp RGB
 
2048
                        _RL8    RLE 8bpp RGB
 
2049
                        3IV1    3ivx MPEG-4 v1
 
2050
                        3IV2    3ivx MPEG-4 v2
 
2051
                        3IVX    3ivx MPEG-4
 
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
 
2060
                        ASV1    Asus Video v1
 
2061
                        ASV2    Asus Video v2
 
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)
 
2069
                        BGR     Raw RGB32
 
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
 
2076
                        CC12    Intel YUV12
 
2077
                        CDVC    Canopus DV
 
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)
 
2086
                        cvid    Radius Cinepak
 
2087
                        CVID    Radius Cinepak
 
2088
                        CWLT    Microsoft Color WLT DIB
 
2089
                        CYUV    Creative Labs YUV
 
2090
                        CYUY    ATI YUV
 
2091
                        D261    H.261
 
2092
                        D263    H.263
 
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)
 
2101
                        divx    DivX MPEG-4
 
2102
                        DMB1    Matrox Rainbow Runner hardware MJPEG
 
2103
                        DMB2    Paradigm MJPEG
 
2104
                        DSVD    ?DSVD?
 
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)
 
2115
                        DVAN    ?DVAN?
 
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
 
2122
                        DX50    DivX v5
 
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)
 
2131
                        EKQ0    Elsa ?EKQ0?
 
2132
                        ELK0    Elsa ?ELK0?
 
2133
                        ESCP    Eidos Escape
 
2134
                        ETV1    eTreppid Video ETV1
 
2135
                        ETV2    eTreppid Video ETV2
 
2136
                        ETVC    eTreppid Video ETVC
 
2137
                        FLIC    Autodesk FLI/FLC Animation
 
2138
                        FLV1    Sorenson Spark
 
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
 
2143
                        FPS1    FRAPS v1
 
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)
 
2171
                        I420    Intel Indeo 4
 
2172
                        IAN     Intel Indeo 4 (RDX)
 
2173
                        ICLB    InSoft CellB Videoconferencing
 
2174
                        IGOR    Power DVD
 
2175
                        IJPG    Intergraph JPEG
 
2176
                        ILVC    Intel Layered Video
 
2177
                        ILVR    ITU-T H.263+
 
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)
 
2217
                        MP4V    FFmpeg MPEG-4
 
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
 
2245
                        MTX1    Matrox ?MTX1?
 
2246
                        MTX2    Matrox ?MTX2?
 
2247
                        MTX3    Matrox ?MTX3?
 
2248
                        MTX4    Matrox ?MTX4?
 
2249
                        MTX5    Matrox ?MTX5?
 
2250
                        MTX6    Matrox ?MTX6?
 
2251
                        MTX7    Matrox ?MTX7?
 
2252
                        MTX8    Matrox ?MTX8?
 
2253
                        MTX9    Matrox ?MTX9?
 
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)
 
2258
                        NUV1    NuppelVideo
 
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
 
2286
                        RGB     Raw BGR32
 
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)
 
2294
                        RV20    RealVideo G2
 
2295
                        RV30    RealVideo 8
 
2296
                        RV40    RealVideo 9
 
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
 
2302
                        rv20    RealVideo G2
 
2303
                        rv30    RealVideo 8
 
2304
                        RVX     Intel RDX (RVX )
 
2305
                        SMC     Apple Graphics (SMC )
 
2306
                        SP54    Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
 
2307
                        SPIG    Radius Spigot
 
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
 
2312
                        SMSC    Radius SMSC
 
2313
                        SMSD    Radius SMSD
 
2314
                        smsv    WorldConnect Wavelet Video
 
2315
                        SPIG    Radius Spigot
 
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
 
2324
                        SVQ1    Sorenson Video
 
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
 
2341
                        TY2N    Trident ?TY2N?
 
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
 
2347
                        ULTI    IBM Ultimotion
 
2348
                        UYVY    UYVY packed 4:2:2
 
2349
                        V261    Lucent VX2000S
 
2350
                        VIFP    VFAPI Reader Codec (www.yks.ne.jp/~hori/)
 
2351
                        VIV1    FFmpeg H263+ decoder
 
2352
                        VIV2    Vivo H.263
 
2353
                        VQC2    Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
 
2354
                        VTLP    Alaris VideoGramPiX
 
2355
                        VYU9    ATI YUV (VYU9)
 
2356
                        VYUY    ATI YUV (VYUY)
 
2357
                        V261    Lucent VX2000S
 
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
 
2362
                        VCR3    ATI VCR 3.0
 
2363
                        VCR4    ATI VCR 4.0
 
2364
                        VCR5    ATI VCR 5.0
 
2365
                        VCR6    ATI VCR 6.0
 
2366
                        VCR7    ATI VCR 7.0
 
2367
                        VCR8    ATI VCR 8.0
 
2368
                        VCR9    ATI VCR 9.0
 
2369
                        VDCT    Vitec Multimedia Video Maker Pro DIB
 
2370
                        VDOM    VDOnet VDOWave
 
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
 
2376
                        vivo    Vivo H.263
 
2377
                        VIXL    Miro/Pinnacle Video XL
 
2378
                        VLV1    VideoLogic/PURE Digital Videologic Capture
 
2379
                        VP30    On2 VP3.0
 
2380
                        VP31    On2 VP3.1
 
2381
                        VP6F    On2 TrueMotion VP6
 
2382
                        VX1K    Lucent VX1000S Video Codec
 
2383
                        VX2K    Lucent VX2000S Video Codec
 
2384
                        VXSP    Lucent VX1000SP Video Codec
 
2385
                        WBVC    Winbond W9960
 
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)
 
2394
                        x263    Xirlink H.263
 
2395
                        XLV0    NetXL Video Decoder
 
2396
                        XMPG    Xing MPEG (I-Frame only)
 
2397
                        XVID    XviD MPEG-4 (www.xvid.org)
 
2398
                        XXAN    ?XXAN?
 
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
 
2411
                        Y8      Grayscale video
 
2412
                        YC12    Intel YUV 12 codec
 
2413
                        YUV8    Winnov Caviar YUV8
 
2414
                        YUV9    Intel YUV9
 
2415
                        YUY2    Uncompressed YUV 4:2:2
 
2416
                        YUYV    Canopus YUV
 
2417
                        YV12    YVU12 Planar
 
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
 
2422
 
 
2423
                */
 
2424
 
 
2425
                return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
 
2426
        }
 
2427
 
 
2428
        private function EitherEndian2Int($byteword, $signed=false) {
 
2429
                if ($this->getid3->info['fileformat'] == 'riff') {
 
2430
                        return getid3_lib::LittleEndian2Int($byteword, $signed);
 
2431
                }
 
2432
                return getid3_lib::BigEndian2Int($byteword, false, $signed);
 
2433
        }
 
2434
 
 
2435
}