source: branches/MootoolsFileManager-Update/plugins/MootoolsFileManager/mootools-filemanager/Assets/Connector/Assets/getid3/module.audio-video.riff.php @ 1300

Last change on this file since 1300 was 1300, checked in by gogo, 9 years ago

Update the MootoolsFileManager? to the latest cpojer with some modifications.
Add a demo for the MFM examples/mootools-file-manager.php
Change the default config for ImageManager? and ExtendedFileManager? for added security.

File size: 111.6 KB
Line 
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 (optional)               //
16//               module.audio.dts.php (optional)               //
17//                                                            ///
18/////////////////////////////////////////////////////////////////
19
20getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
21
22class getid3_riff
23{
24
25        function getid3_riff(&$fd, &$ThisFileInfo) {
26
27                // initialize these values to an empty array, otherwise they default to NULL
28                // and you can't append array values to a NULL value
29                $ThisFileInfo['riff'] = array('raw'=>array());
30
31                // Shortcuts
32                $thisfile_riff             = &$ThisFileInfo['riff'];
33                $thisfile_riff_raw         = &$thisfile_riff['raw'];
34                $thisfile_audio            = &$ThisFileInfo['audio'];
35                $thisfile_video            = &$ThisFileInfo['video'];
36                $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
37                $thisfile_riff_audio       = &$thisfile_riff['audio'];
38                $thisfile_riff_video       = &$thisfile_riff['video'];
39
40
41                $Original['avdataoffset'] = $ThisFileInfo['avdataoffset'];
42                $Original['avdataend']    = $ThisFileInfo['avdataend'];
43
44                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
45                $RIFFheader = fread($fd, 12);
46                $RIFFsubtype = substr($RIFFheader, 8, 4);
47                switch (substr($RIFFheader, 0, 4)) {
48                        case 'FORM':
49                                $ThisFileInfo['fileformat']   = 'aiff';
50                                $thisfile_riff['header_size'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
51                                $thisfile_riff[$RIFFsubtype]  = getid3_riff::ParseRIFF($fd, $ThisFileInfo['avdataoffset'] + 12, $ThisFileInfo['avdataoffset'] + $thisfile_riff['header_size'], $ThisFileInfo);
52                                break;
53
54                        case 'RIFF':  // AVI, WAV, etc
55                        case 'SDSS':  // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
56                        case 'RMP3':  // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
57                                $ThisFileInfo['fileformat']   = 'riff';
58                                $thisfile_riff['header_size'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
59                                if ($RIFFsubtype == 'RMP3') {
60                                        // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
61                                        $RIFFsubtype = 'WAVE';
62                                }
63                                $thisfile_riff[$RIFFsubtype]  = getid3_riff::ParseRIFF($fd, $ThisFileInfo['avdataoffset'] + 12, $ThisFileInfo['avdataoffset'] + $thisfile_riff['header_size'], $ThisFileInfo);
64
65                                $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
66                                while ($nextRIFFoffset < $ThisFileInfo['filesize']) {
67                                        if (!getid3_lib::intValueSupported($nextRIFFoffset + 1024)) {
68                                                $ThisFileInfo['error'][]   = 'AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
69                                                $ThisFileInfo['warning'][] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
70                                                break;
71                                        } else {
72                                                fseek($fd, $nextRIFFoffset, SEEK_SET);
73                                                $nextRIFFheader = fread($fd, 12);
74                                                $nextRIFFheaderID =                                              substr($nextRIFFheader, 0, 4);
75                                                $nextRIFFsize     = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($nextRIFFheader, 4, 4));
76                                                $nextRIFFtype     =                                              substr($nextRIFFheader, 8, 4);
77                                                $chunkdata = array();
78                                                $chunkdata['offset'] = $nextRIFFoffset + 8;
79                                                $chunkdata['size']   = $nextRIFFsize;
80                                                $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size'];
81                                                switch ($nextRIFFheaderID) {
82                                                        case 'RIFF':
83                                                                $ThisFileInfo['avdataend'] = $nextRIFFoffset;
84                                                                if (!getid3_lib::intValueSupported($ThisFileInfo['avdataend'])) {
85                                                                        $ThisFileInfo['error'][]   = 'AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime is probably wrong';
86                                                                        $ThisFileInfo['warning'][] = '[avdataend] value may be incorrect, multiple AVIX chunks may be present';
87                                                                }
88                                                                $chunkdata['chunks'] = getid3_riff::ParseRIFF($fd, $chunkdata['offset'] + 4, $chunkdata['offset'] + $chunkdata['size'], $ThisFileInfo);
89
90                                                                if (!isset($thisfile_riff[$nextRIFFtype])) {
91                                                                        $thisfile_riff[$nextRIFFtype] = array();
92                                                                }
93                                                                $thisfile_riff[$nextRIFFtype][] = $chunkdata;
94                                                                break;
95                                                        case 'JUNK':
96                                                                // ignore
97                                                                $thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
98                                                                break;
99                                                        default:
100                                                                if ($ThisFileInfo['filesize'] == ($chunkdata['offset'] - 8 + 128)) {
101                                                                        $DIVXTAG = $nextRIFFheader.fread($fd, 128 - 12);
102                                                                        if (substr($DIVXTAG, -7) == 'DIVXTAG') {
103                                                                                // 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
104                                                                                $thisfile_riff['DIVXTAG'] = $this->ParseDIVXTAG($DIVXTAG);
105                                                                                foreach ($thisfile_riff['DIVXTAG'] as $key => $value) {
106                                                                                        if ($value && !preg_match('#_id$#', $key)) {
107                                                                                                $thisfile_riff['comments'][$key][] = $value;
108                                                                                        }
109                                                                                }
110                                                                                break 2;
111                                                                        }
112                                                                }
113                                                                $ThisFileInfo['warning'][] = 'expecting "RIFF" or "JUNK" at '.$nextRIFFoffset.', found '.substr($nextRIFFheader, 0, 4).' - skipping rest of file';
114                                                                break 2;
115                                                }
116                                        }
117                                }
118                                if ($RIFFsubtype == 'WAVE') {
119                                        $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
120                                }
121                                break;
122
123                        default:
124                                $ThisFileInfo['error'][] = 'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead';
125                                unset($ThisFileInfo['fileformat']);
126                                return false;
127                                break;
128                }
129
130                $streamindex = 0;
131                switch ($RIFFsubtype) {
132                        case 'WAVE':
133                                if (empty($thisfile_audio['bitrate_mode'])) {
134                                        $thisfile_audio['bitrate_mode'] = 'cbr';
135                                }
136                                if (empty($thisfile_audio_dataformat)) {
137                                        $thisfile_audio_dataformat = 'wav';
138                                }
139
140                                if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
141                                        $ThisFileInfo['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
142                                        $ThisFileInfo['avdataend']    = $ThisFileInfo['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size'];
143                                }
144                                if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
145
146                                        $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
147                                        $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
148                                        if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
149                                                $ThisFileInfo['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
150                                                return false;
151                                        }
152                                        $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
153                                        unset($thisfile_riff_audio[$streamindex]['raw']);
154                                        $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
155
156                                        $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
157                                        if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
158                                                $ThisFileInfo['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
159                                        }
160                                        $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
161
162                                        $ThisFileInfo['playtime_seconds'] = (float) ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
163
164                                        $thisfile_audio['lossless'] = false;
165                                        if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
166                                                switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
167
168                                                        case 0x0001:  // PCM
169                                                                $thisfile_audio['lossless'] = true;
170                                                                break;
171
172                                                        case 0x2000:  // AC-3
173                                                                $thisfile_audio_dataformat = 'ac3';
174                                                                break;
175
176                                                        default:
177                                                                // do nothing
178                                                                break;
179
180                                                }
181                                        }
182                                        $thisfile_audio['streams'][$streamindex]['wformattag']   = $thisfile_audio['wformattag'];
183                                        $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
184                                        $thisfile_audio['streams'][$streamindex]['lossless']     = $thisfile_audio['lossless'];
185                                        $thisfile_audio['streams'][$streamindex]['dataformat']   = $thisfile_audio_dataformat;
186                                }
187
188                                if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
189
190                                        // shortcuts
191                                        $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
192                                        $thisfile_riff_raw['rgad']    = array('track'=>array(), 'album'=>array());
193                                        $thisfile_riff_raw_rgad       = &$thisfile_riff_raw['rgad'];
194                                        $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
195                                        $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
196
197                                        $thisfile_riff_raw_rgad['fPeakAmplitude']      =               getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
198                                        $thisfile_riff_raw_rgad['nRadioRgAdjust']      = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 4, 2));
199                                        $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 6, 2));
200
201                                        $nRadioRgAdjustBitstring      = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
202                                        $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
203                                        $thisfile_riff_raw_rgad_track['name']       = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
204                                        $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
205                                        $thisfile_riff_raw_rgad_track['signbit']    = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
206                                        $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
207                                        $thisfile_riff_raw_rgad_album['name']       = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
208                                        $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
209                                        $thisfile_riff_raw_rgad_album['signbit']    = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
210                                        $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
211
212                                        $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
213                                        if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
214                                                $thisfile_riff['rgad']['track']['name']            = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
215                                                $thisfile_riff['rgad']['track']['originator']      = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
216                                                $thisfile_riff['rgad']['track']['adjustment']      = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
217                                        }
218                                        if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
219                                                $thisfile_riff['rgad']['album']['name']       = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
220                                                $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
221                                                $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
222                                        }
223                                }
224
225                                if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
226                                        $thisfile_riff_raw['fact']['NumberOfSamples'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
227
228                                        // This should be a good way of calculating exact playtime,
229                                        // but some sample files have had incorrect number of samples,
230                                        // so cannot use this method
231
232                                        // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
233                                        //     $ThisFileInfo['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
234                                        // }
235                                }
236                                if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
237                                        $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
238                                }
239
240                                if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
241                                        // shortcut
242                                        $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
243
244                                        $thisfile_riff_WAVE_bext_0['title']          =                         trim(substr($thisfile_riff_WAVE_bext_0['data'],   0, 256));
245                                        $thisfile_riff_WAVE_bext_0['author']         =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 256,  32));
246                                        $thisfile_riff_WAVE_bext_0['reference']      =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 288,  32));
247                                        $thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
248                                        $thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
249                                        $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338,   8));
250                                        $thisfile_riff_WAVE_bext_0['bwf_version']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346,   1));
251                                        $thisfile_riff_WAVE_bext_0['reserved']       = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 347, 254));
252                                        $thisfile_riff_WAVE_bext_0['coding_history'] =         explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
253                                        if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
254                                                if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
255                                                        list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
256                                                        list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
257                                                        $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']);
258                                                } else {
259                                                        $ThisFileInfo['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
260                                                }
261                                        } else {
262                                                $ThisFileInfo['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
263                                        }
264                                        $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
265                                        $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_bext_0['title'];
266                                }
267
268                                if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
269                                        // shortcut
270                                        $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
271
272                                        $thisfile_riff_WAVE_MEXT_0['raw']['sound_information']      = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
273                                        $thisfile_riff_WAVE_MEXT_0['flags']['homogenous']           = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
274                                        if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
275                                                $thisfile_riff_WAVE_MEXT_0['flags']['padding']          = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
276                                                $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44']         =        (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
277                                                $thisfile_riff_WAVE_MEXT_0['flags']['free_format']      =        (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
278
279                                                $thisfile_riff_WAVE_MEXT_0['nominal_frame_size']        = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
280                                        }
281                                        $thisfile_riff_WAVE_MEXT_0['anciliary_data_length']         = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
282                                        $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def']     = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
283                                        $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left']  = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
284                                        $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free']  = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
285                                        $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
286                                }
287
288                                if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
289                                        // shortcut
290                                        $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
291
292                                        $thisfile_riff_WAVE_cart_0['version']              =                  substr($thisfile_riff_WAVE_cart_0['data'],    0,    4);
293                                        $thisfile_riff_WAVE_cart_0['title']                =             trim(substr($thisfile_riff_WAVE_cart_0['data'],    4,   64));
294                                        $thisfile_riff_WAVE_cart_0['artist']               =             trim(substr($thisfile_riff_WAVE_cart_0['data'],   68,   64));
295                                        $thisfile_riff_WAVE_cart_0['cut_id']               =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  132,   64));
296                                        $thisfile_riff_WAVE_cart_0['client_id']            =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  196,   64));
297                                        $thisfile_riff_WAVE_cart_0['category']             =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  260,   64));
298                                        $thisfile_riff_WAVE_cart_0['classification']       =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  324,   64));
299                                        $thisfile_riff_WAVE_cart_0['out_cue']              =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  388,   64));
300                                        $thisfile_riff_WAVE_cart_0['start_date']           =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  452,   10));
301                                        $thisfile_riff_WAVE_cart_0['start_time']           =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  462,    8));
302                                        $thisfile_riff_WAVE_cart_0['end_date']             =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  470,   10));
303                                        $thisfile_riff_WAVE_cart_0['end_time']             =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  480,    8));
304                                        $thisfile_riff_WAVE_cart_0['producer_app_id']      =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  488,   64));
305                                        $thisfile_riff_WAVE_cart_0['producer_app_version'] =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  552,   64));
306                                        $thisfile_riff_WAVE_cart_0['user_defined_text']    =             trim(substr($thisfile_riff_WAVE_cart_0['data'],  616,   64));
307                                        $thisfile_riff_WAVE_cart_0['zero_db_reference']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'],  680,    4), true);
308                                        for ($i = 0; $i < 8; $i++) {
309                                                $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] =                  substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
310                                                $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));
311                                        }
312                                        $thisfile_riff_WAVE_cart_0['url']              =                 trim(substr($thisfile_riff_WAVE_cart_0['data'],  748, 1024));
313                                        $thisfile_riff_WAVE_cart_0['tag_text']         = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
314
315                                        $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
316                                        $thisfile_riff['comments']['title'][]  = $thisfile_riff_WAVE_cart_0['title'];
317                                }
318
319                                if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
320                                        // SoundMiner metadata
321
322                                        // shortcuts
323                                        $thisfile_riff_WAVE_SNDM_0      = &$thisfile_riff_WAVE['SNDM'][0];
324                                        $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data'];
325                                        $SNDM_startoffset = 0;
326                                        $SNDM_endoffset   = $thisfile_riff_WAVE_SNDM_0['size'];
327
328                                        while ($SNDM_startoffset < $SNDM_endoffset) {
329                                                $SNDM_thisTagOffset = 0;
330                                                $SNDM_thisTagSize      = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4));
331                                                $SNDM_thisTagOffset += 4;
332                                                $SNDM_thisTagKey       =                           substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4);
333                                                $SNDM_thisTagOffset += 4;
334                                                $SNDM_thisTagDataSize  = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
335                                                $SNDM_thisTagOffset += 2;
336                                                $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
337                                                $SNDM_thisTagOffset += 2;
338                                                $SNDM_thisTagDataText =                            substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize);
339                                                $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
340
341                                                if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
342                                                        $ThisFileInfo['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).')';
343                                                        break;
344                                                } elseif ($SNDM_thisTagSize <= 0) {
345                                                        $ThisFileInfo['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
346                                                        break;
347                                                }
348                                                $SNDM_startoffset += $SNDM_thisTagSize;
349
350                                                $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText;
351                                                if ($parsedkey = $this->RIFFwaveSNDMtagLookup($SNDM_thisTagKey)) {
352                                                        $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
353                                                } else {
354                                                        $ThisFileInfo['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
355                                                }
356                                        }
357
358                                        $tagmapping = array(
359                                                'tracktitle'=>'title',
360                                                'category'  =>'genre',
361                                                'cdtitle'   =>'album',
362                                                'tracktitle'=>'title',
363                                        );
364                                        foreach ($tagmapping as $fromkey => $tokey) {
365                                                if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
366                                                        $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
367                                                }
368                                        }
369                                }
370
371                                if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
372                                        $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
373                                        $ThisFileInfo['playtime_seconds'] = (float) ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
374                                }
375
376                                if (!empty($ThisFileInfo['wavpack'])) {
377                                        $thisfile_audio_dataformat = 'wavpack';
378                                        $thisfile_audio['bitrate_mode'] = 'vbr';
379                                        $thisfile_audio['encoder']      = 'WavPack v'.$ThisFileInfo['wavpack']['version'];
380
381                                        // Reset to the way it was - RIFF parsing will have messed this up
382                                        $ThisFileInfo['avdataend']        = $Original['avdataend'];
383                                        $thisfile_audio['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
384
385                                        fseek($fd, $ThisFileInfo['avdataoffset'] - 44, SEEK_SET);
386                                        $RIFFdata = fread($fd, 44);
387                                        $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata,  4, 4)) +  8;
388                                        $OrignalRIFFdataSize   = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
389
390                                        if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
391                                                $ThisFileInfo['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
392                                                fseek($fd, $ThisFileInfo['avdataend'], SEEK_SET);
393                                                $RIFFdata .= fread($fd, $OrignalRIFFheaderSize - $OrignalRIFFdataSize);
394                                        }
395
396                                        // move the data chunk after all other chunks (if any)
397                                        // so that the RIFF parser doesn't see EOF when trying
398                                        // to skip over the data chunk
399                                        $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
400                                        getid3_riff::ParseRIFFdata($RIFFdata, $ThisFileInfo);
401                                }
402
403                                if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
404                                        switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
405                                                case 0x08AE: // ClearJump LiteWave
406                                                        $thisfile_audio['bitrate_mode'] = 'vbr';
407                                                        $thisfile_audio_dataformat   = 'litewave';
408
409                                                        //typedef struct tagSLwFormat {
410                                                        //  WORD    m_wCompFormat;     // low byte defines compression method, high byte is compression flags
411                                                        //  DWORD   m_dwScale;         // scale factor for lossy compression
412                                                        //  DWORD   m_dwBlockSize;     // number of samples in encoded blocks
413                                                        //  WORD    m_wQuality;        // alias for the scale factor
414                                                        //  WORD    m_wMarkDistance;   // distance between marks in bytes
415                                                        //  WORD    m_wReserved;
416                                                        //
417                                                        //  //following paramters are ignored if CF_FILESRC is not set
418                                                        //  DWORD   m_dwOrgSize;       // original file size in bytes
419                                                        //  WORD    m_bFactExists;     // indicates if 'fact' chunk exists in the original file
420                                                        //  DWORD   m_dwRiffChunkSize; // riff chunk size in the original file
421                                                        //
422                                                        //  PCMWAVEFORMAT m_OrgWf;     // original wave format
423                                                        // }SLwFormat, *PSLwFormat;
424
425                                                        // shortcut
426                                                        $thisfile_riff['litewave']['raw'] = array();
427                                                        $thisfile_riff_litewave     = &$thisfile_riff['litewave'];
428                                                        $thisfile_riff_litewave_raw = &$thisfile_riff_litewave['raw'];
429
430                                                        $thisfile_riff_litewave_raw['compression_method'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 18, 1));
431                                                        $thisfile_riff_litewave_raw['compression_flags']  = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 19, 1));
432                                                        $thisfile_riff_litewave_raw['m_dwScale']          = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 20, 4));
433                                                        $thisfile_riff_litewave_raw['m_dwBlockSize']      = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 24, 4));
434                                                        $thisfile_riff_litewave_raw['m_wQuality']         = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 28, 2));
435                                                        $thisfile_riff_litewave_raw['m_wMarkDistance']    = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 30, 2));
436                                                        $thisfile_riff_litewave_raw['m_wReserved']        = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 32, 2));
437                                                        $thisfile_riff_litewave_raw['m_dwOrgSize']        = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 34, 4));
438                                                        $thisfile_riff_litewave_raw['m_bFactExists']      = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 38, 2));
439                                                        $thisfile_riff_litewave_raw['m_dwRiffChunkSize']  = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 40, 4));
440
441                                                        //$thisfile_riff_litewave['quality_factor'] = intval(round((2000 - $thisfile_riff_litewave_raw['m_dwScale']) / 20));
442                                                        $thisfile_riff_litewave['quality_factor'] = $thisfile_riff_litewave_raw['m_wQuality'];
443
444                                                        $thisfile_riff_litewave['flags']['raw_source']    = ($thisfile_riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
445                                                        $thisfile_riff_litewave['flags']['vbr_blocksize'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
446                                                        $thisfile_riff_litewave['flags']['seekpoints']    =        (bool) ($thisfile_riff_litewave_raw['compression_flags'] & 0x04);
447
448                                                        $thisfile_audio['lossless']        = (($thisfile_riff_litewave_raw['m_wQuality'] == 100) ? true : false);
449                                                        $thisfile_audio['encoder_options'] = '-q'.$thisfile_riff_litewave['quality_factor'];
450                                                        break;
451
452                                                default:
453                                                        break;
454                                        }
455                                }
456                                if ($ThisFileInfo['avdataend'] > $ThisFileInfo['filesize']) {
457                                        switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
458                                                case 'wavpack': // WavPack
459                                                case 'lpac':    // LPAC
460                                                case 'ofr':     // OptimFROG
461                                                case 'ofs':     // OptimFROG DualStream
462                                                        // lossless compressed audio formats that keep original RIFF headers - skip warning
463                                                        break;
464
465                                                case 'litewave':
466                                                        if (($ThisFileInfo['avdataend'] - $ThisFileInfo['filesize']) == 1) {
467                                                                // LiteWave appears to incorrectly *not* pad actual output file
468                                                                // to nearest WORD boundary so may appear to be short by one
469                                                                // byte, in which case - skip warning
470                                                        } else {
471                                                                // Short by more than one byte, throw warning
472                                                                $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset'])).' bytes)';
473                                                                $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'];
474                                                        }
475                                                        break;
476
477                                                default:
478                                                        if ((($ThisFileInfo['avdataend'] - $ThisFileInfo['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']) % 2) == 1)) {
479                                                                // output file appears to be incorrectly *not* padded to nearest WORD boundary
480                                                                // Output less severe warning
481                                                                $ThisFileInfo['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 '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset'])).' bytes)';
482                                                                $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'];
483                                                        } else {
484                                                                // Short by more than one byte, throw warning
485                                                                $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset'])).' bytes)';
486                                                                $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'];
487                                                        }
488                                                        break;
489                                        }
490                                }
491                                if (!empty($ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'])) {
492                                        if ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) - $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
493                                                $ThisFileInfo['avdataend']--;
494                                                $ThisFileInfo['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
495                                        }
496                                }
497                                if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
498                                        unset($thisfile_audio['bits_per_sample']);
499                                        if (!empty($ThisFileInfo['ac3']['bitrate']) && ($ThisFileInfo['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
500                                                $thisfile_audio['bitrate'] = $ThisFileInfo['ac3']['bitrate'];
501                                        }
502                                }
503                                break;
504
505                        case 'AVI ':
506                                $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
507                                $thisfile_video['dataformat']   = 'avi';
508                                $ThisFileInfo['mime_type']      = 'video/avi';
509
510                                if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
511                                        $ThisFileInfo['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
512                                        if (isset($thisfile_riff['AVIX'])) {
513                                                $ThisFileInfo['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
514                                        } else {
515                                                $ThisFileInfo['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
516                                        }
517                                        if ($ThisFileInfo['avdataend'] > $ThisFileInfo['filesize']) {
518                                                $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' bytes of data, only found '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' (short by '.($ThisFileInfo['avdataend'] - $ThisFileInfo['filesize']).' bytes)';
519                                                $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'];
520                                        }
521                                }
522
523                                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
524                                        //$bIndexType = array(
525                                        //      0x00 => 'AVI_INDEX_OF_INDEXES',
526                                        //      0x01 => 'AVI_INDEX_OF_CHUNKS',
527                                        //      0x80 => 'AVI_INDEX_IS_DATA',
528                                        //);
529                                        //$bIndexSubtype = array(
530                                        //      0x01 => array(
531                                        //              0x01 => 'AVI_INDEX_2FIELD',
532                                        //      ),
533                                        //);
534                                        foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
535                                                $thisfile_riff_avi_hdrl_strl_indx_stream_data = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
536
537                                                $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data,  0, 2));
538                                                $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']  = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data,  2, 1));
539                                                $thisfile_riff_raw['indx'][$streamnumber]['bIndexType']     = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data,  3, 1));
540                                                $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse']  = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data,  4, 4));
541                                                $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId']      =                                              substr($thisfile_riff_avi_hdrl_strl_indx_stream_data,  8, 4);
542                                                $thisfile_riff_raw['indx'][$streamnumber]['dwReserved']     = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_avi_hdrl_strl_indx_stream_data, 12, 4));
543
544                                                //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name']    =    $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
545                                                //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
546
547                                                unset($thisfile_riff_avi_hdrl_strl_indx_stream_data);
548                                        }
549                                }
550                                if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
551                                        $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
552
553                                        // shortcut
554                                        $thisfile_riff_raw['avih'] = array();
555                                        $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
556
557                                        $thisfile_riff_raw_avih['dwMicroSecPerFrame']    = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData,  0, 4)); // frame display rate (or 0L)
558                                        if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
559                                                $ThisFileInfo['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
560                                                return false;
561                                        }
562                                        $thisfile_riff_raw_avih['dwMaxBytesPerSec']      = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData,  4, 4)); // max. transfer rate
563                                        $thisfile_riff_raw_avih['dwPaddingGranularity']  = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData,  8, 4)); // pad to multiples of this size; normally 2K.
564                                        $thisfile_riff_raw_avih['dwFlags']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 12, 4)); // the ever-present flags
565                                        $thisfile_riff_raw_avih['dwTotalFrames']         = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 16, 4)); // # frames in file
566                                        $thisfile_riff_raw_avih['dwInitialFrames']       = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 20, 4));
567                                        $thisfile_riff_raw_avih['dwStreams']             = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 24, 4));
568                                        $thisfile_riff_raw_avih['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 28, 4));
569                                        $thisfile_riff_raw_avih['dwWidth']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 32, 4));
570                                        $thisfile_riff_raw_avih['dwHeight']              = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 36, 4));
571                                        $thisfile_riff_raw_avih['dwScale']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 40, 4));
572                                        $thisfile_riff_raw_avih['dwRate']                = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 44, 4));
573                                        $thisfile_riff_raw_avih['dwStart']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 48, 4));
574                                        $thisfile_riff_raw_avih['dwLength']              = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 52, 4));
575
576                                        $thisfile_riff_raw_avih['flags']['hasindex']     = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000010);
577                                        $thisfile_riff_raw_avih['flags']['mustuseindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000020);
578                                        $thisfile_riff_raw_avih['flags']['interleaved']  = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000100);
579                                        $thisfile_riff_raw_avih['flags']['trustcktype']  = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000800);
580                                        $thisfile_riff_raw_avih['flags']['capturedfile'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00010000);
581                                        $thisfile_riff_raw_avih['flags']['copyrighted']  = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00020010);
582
583                                        // shortcut
584                                        $thisfile_riff_video[$streamindex] = array();
585                                        $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
586
587                                        if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
588                                                $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
589                                                $thisfile_video['resolution_x']             = $thisfile_riff_video_current['frame_width'];
590                                        }
591                                        if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
592                                                $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
593                                                $thisfile_video['resolution_y']              = $thisfile_riff_video_current['frame_height'];
594                                        }
595                                        if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
596                                                $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
597                                                $thisfile_video['total_frames']              = $thisfile_riff_video_current['total_frames'];
598                                        }
599
600                                        $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
601                                        $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
602                                }
603                                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
604                                        if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
605                                                for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
606                                                        if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
607                                                                $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
608                                                                $strhfccType = substr($strhData,  0, 4);
609
610                                                                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
611                                                                        $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
612
613                                                                        // shortcut
614                                                                        $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
615
616                                                                        switch ($strhfccType) {
617                                                                                case 'auds':
618                                                                                        $thisfile_audio['bitrate_mode'] = 'cbr';
619                                                                                        $thisfile_audio_dataformat      = 'wav';
620                                                                                        if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
621                                                                                                $streamindex = count($thisfile_riff_audio);
622                                                                                        }
623
624                                                                                        $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($strfData);
625                                                                                        $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
626
627                                                                                        // shortcut
628                                                                                        $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
629                                                                                        $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
630
631                                                                                        if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
632                                                                                                unset($thisfile_audio_streams_currentstream['bits_per_sample']);
633                                                                                        }
634                                                                                        $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
635                                                                                        unset($thisfile_audio_streams_currentstream['raw']);
636
637                                                                                        // shortcut
638                                                                                        $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
639
640                                                                                        unset($thisfile_riff_audio[$streamindex]['raw']);
641                                                                                        $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
642
643                                                                                        $thisfile_audio['lossless'] = false;
644                                                                                        switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
645                                                                                                case 0x0001:  // PCM
646                                                                                                        $thisfile_audio_dataformat  = 'wav';
647                                                                                                        $thisfile_audio['lossless'] = true;
648                                                                                                        break;
649
650                                                                                                case 0x0050: // MPEG Layer 2 or Layer 1
651                                                                                                        $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
652                                                                                                        break;
653
654                                                                                                case 0x0055: // MPEG Layer 3
655                                                                                                        $thisfile_audio_dataformat = 'mp3';
656                                                                                                        break;
657
658                                                                                                case 0x00FF: // AAC
659                                                                                                        $thisfile_audio_dataformat = 'aac';
660                                                                                                        break;
661
662                                                                                                case 0x0161: // Windows Media v7 / v8 / v9
663                                                                                                case 0x0162: // Windows Media Professional v9
664                                                                                                case 0x0163: // Windows Media Lossess v9
665                                                                                                        $thisfile_audio_dataformat = 'wma';
666                                                                                                        break;
667
668                                                                                                case 0x2000: // AC-3
669                                                                                                        $thisfile_audio_dataformat = 'ac3';
670                                                                                                        break;
671
672                                                                                                case 0x2001: // DTS
673                                                                                                        $thisfile_audio_dataformat = 'dts';
674                                                                                                        break;
675
676                                                                                                default:
677                                                                                                        $thisfile_audio_dataformat = 'wav';
678                                                                                                        break;
679                                                                                        }
680                                                                                        $thisfile_audio_streams_currentstream['dataformat']   = $thisfile_audio_dataformat;
681                                                                                        $thisfile_audio_streams_currentstream['lossless']     = $thisfile_audio['lossless'];
682                                                                                        $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
683                                                                                        break;
684
685
686                                                                                case 'iavs':
687                                                                                case 'vids':
688                                                                                        // shortcut
689                                                                                        $thisfile_riff_raw['strh'][$i]                  = array();
690                                                                                        $thisfile_riff_raw_strh_current                 = &$thisfile_riff_raw['strh'][$i];
691
692                                                                                        $thisfile_riff_raw_strh_current['fccType']               =                  substr($strhData,  0, 4);  // same as $strhfccType;
693                                                                                        $thisfile_riff_raw_strh_current['fccHandler']            =                  substr($strhData,  4, 4);
694                                                                                        $thisfile_riff_raw_strh_current['dwFlags']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData,  8, 4)); // Contains AVITF_* flags
695                                                                                        $thisfile_riff_raw_strh_current['wPriority']             = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 12, 2));
696                                                                                        $thisfile_riff_raw_strh_current['wLanguage']             = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 14, 2));
697                                                                                        $thisfile_riff_raw_strh_current['dwInitialFrames']       = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 16, 4));
698                                                                                        $thisfile_riff_raw_strh_current['dwScale']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 20, 4));
699                                                                                        $thisfile_riff_raw_strh_current['dwRate']                = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 24, 4));
700                                                                                        $thisfile_riff_raw_strh_current['dwStart']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 28, 4));
701                                                                                        $thisfile_riff_raw_strh_current['dwLength']              = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 32, 4));
702                                                                                        $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 36, 4));
703                                                                                        $thisfile_riff_raw_strh_current['dwQuality']             = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 40, 4));
704                                                                                        $thisfile_riff_raw_strh_current['dwSampleSize']          = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 44, 4));
705                                                                                        $thisfile_riff_raw_strh_current['rcFrame']               = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 48, 4));
706
707                                                                                        $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
708                                                                                        $thisfile_video['fourcc']             = $thisfile_riff_raw_strh_current['fccHandler'];
709                                                                                        if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
710                                                                                                $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
711                                                                                                $thisfile_video['fourcc']             = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
712                                                                                        }
713                                                                                        $thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
714                                                                                        $thisfile_video['pixel_aspect_ratio'] = (float) 1;
715                                                                                        switch ($thisfile_riff_raw_strh_current['fccHandler']) {
716                                                                                                case 'HFYU': // Huffman Lossless Codec
717                                                                                                case 'IRAW': // Intel YUV Uncompressed
718                                                                                                case 'YUY2': // Uncompressed YUV 4:2:2
719                                                                                                        $thisfile_video['lossless'] = true;
720                                                                                                        break;
721
722                                                                                                default:
723                                                                                                        $thisfile_video['lossless'] = false;
724                                                                                                        break;
725                                                                                        }
726
727                                                                                        switch ($strhfccType) {
728                                                                                                case 'vids':
729                                                                                                        $thisfile_riff_raw_strf_strhfccType_streamindex = getid3_riff::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($ThisFileInfo['fileformat'] == 'riff'));
730                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biSize']          = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData,  0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
731                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biWidth']         = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData,  4, 4)); // width of the bitmap in pixels
732                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biHeight']        = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData,  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
733                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biPlanes']        = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
734                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount']      = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 14, 2)); // Specifies the number of bits per pixels
735                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']          =                                              substr($strfData, 16, 4);  //
736                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biSizeImage']     = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
737                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biXPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
738                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biYPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 28, 4)); // vertical resolution, in pixels per metre, of the target device
739                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biClrUsed']       = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 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
740                                                                                                        //$thisfile_riff_raw_strf_strhfccType_streamindex['biClrImportant']  = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
741
742                                                                                                        $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
743
744                                                                                                        if ($thisfile_riff_video_current['codec'] == 'DV') {
745                                                                                                                $thisfile_riff_video_current['dv_type'] = 2;
746                                                                                                        }
747                                                                                                        break;
748
749                                                                                                case 'iavs':
750                                                                                                        $thisfile_riff_video_current['dv_type'] = 1;
751                                                                                                        break;
752                                                                                        }
753                                                                                        break;
754
755                                                                                default:
756                                                                                        $ThisFileInfo['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
757                                                                                        break;
758
759                                                                        }
760                                                                }
761                                                        }
762
763                                                        if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
764
765                                                                $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
766                                                                $thisfile_video['codec']              = $thisfile_riff_video_current['codec'];
767                                                                $thisfile_video['fourcc']             = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
768
769                                                                switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
770                                                                        case 'HFYU': // Huffman Lossless Codec
771                                                                        case 'IRAW': // Intel YUV Uncompressed
772                                                                        case 'YUY2': // Uncompressed YUV 4:2:2
773                                                                                $thisfile_video['lossless']        = true;
774                                                                                $thisfile_video['bits_per_sample'] = 24;
775                                                                                break;
776
777                                                                        default:
778                                                                                $thisfile_video['lossless']        = false;
779                                                                                $thisfile_video['bits_per_sample'] = 24;
780                                                                                break;
781                                                                }
782
783                                                        }
784                                                }
785                                        }
786                                }
787                                break;
788
789                        case 'CDDA':
790                                $thisfile_audio['bitrate_mode'] = 'cbr';
791                                $thisfile_audio_dataformat      = 'cda';
792                                $thisfile_audio['lossless']     = true;
793                                unset($ThisFileInfo['mime_type']);
794
795                                $ThisFileInfo['avdataoffset'] = 44;
796
797                                if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
798                                        // shortcut
799                                        $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
800
801                                        $thisfile_riff_CDDA_fmt_0['unknown1']           = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'],  0, 2));
802                                        $thisfile_riff_CDDA_fmt_0['track_num']          = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'],  2, 2));
803                                        $thisfile_riff_CDDA_fmt_0['disc_id']            = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'],  4, 4));
804                                        $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'],  8, 4));
805                                        $thisfile_riff_CDDA_fmt_0['playtime_frames']    = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
806                                        $thisfile_riff_CDDA_fmt_0['unknown6']           = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
807                                        $thisfile_riff_CDDA_fmt_0['unknown7']           = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
808
809                                        $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
810                                        $thisfile_riff_CDDA_fmt_0['playtime_seconds']     = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
811                                        $ThisFileInfo['comments']['track']                = $thisfile_riff_CDDA_fmt_0['track_num'];
812                                        $ThisFileInfo['playtime_seconds']                 = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
813
814                                        // hardcoded data for CD-audio
815                                        $thisfile_audio['sample_rate']     = 44100;
816                                        $thisfile_audio['channels']        = 2;
817                                        $thisfile_audio['bits_per_sample'] = 16;
818                                        $thisfile_audio['bitrate']         = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
819                                        $thisfile_audio['bitrate_mode']    = 'cbr';
820                                }
821                                break;
822
823
824                        case 'AIFF':
825                        case 'AIFC':
826                                $thisfile_audio['bitrate_mode'] = 'cbr';
827                                $thisfile_audio_dataformat      = 'aiff';
828                                $thisfile_audio['lossless']     = true;
829                                $ThisFileInfo['mime_type']      = 'audio/x-aiff';
830
831                                if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
832                                        $ThisFileInfo['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
833                                        $ThisFileInfo['avdataend']    = $ThisFileInfo['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
834                                        if ($ThisFileInfo['avdataend'] > $ThisFileInfo['filesize']) {
835                                                if (($ThisFileInfo['avdataend'] == ($ThisFileInfo['filesize'] + 1)) && (($ThisFileInfo['filesize'] % 2) == 1)) {
836                                                        // structures rounded to 2-byte boundary, but dumb encoders
837                                                        // forget to pad end of file to make this actually work
838                                                } else {
839                                                        $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' bytes found';
840                                                }
841                                                $ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'];
842                                        }
843                                }
844
845                                if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
846
847                                        // shortcut
848                                        $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
849
850                                        $thisfile_riff_audio['channels']         =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  0,  2), true);
851                                        $thisfile_riff_audio['total_samples']    =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  2,  4), false);
852                                        $thisfile_riff_audio['bits_per_sample']  =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  6,  2), true);
853                                        $thisfile_riff_audio['sample_rate']      = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data,  8, 10));
854
855                                        if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
856                                                $thisfile_riff_audio['codec_fourcc'] =                                   substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18,  4);
857                                                $CodecNameSize                       =         getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22,  1), false);
858                                                $thisfile_riff_audio['codec_name']   =                                   substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23,  $CodecNameSize);
859                                                switch ($thisfile_riff_audio['codec_name']) {
860                                                        case 'NONE':
861                                                                $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
862                                                                $thisfile_audio['lossless'] = true;
863                                                                break;
864
865                                                        case '':
866                                                                switch ($thisfile_riff_audio['codec_fourcc']) {
867                                                                        // http://developer.apple.com/qa/snd/snd07.html
868                                                                        case 'sowt':
869                                                                                $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
870                                                                                $thisfile_audio['lossless'] = true;
871                                                                                break;
872
873                                                                        case 'twos':
874                                                                                $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
875                                                                                $thisfile_audio['lossless'] = true;
876                                                                                break;
877
878                                                                        default:
879                                                                                break;
880                                                                }
881                                                                break;
882
883                                                        default:
884                                                                $thisfile_audio['codec']    = $thisfile_riff_audio['codec_name'];
885                                                                $thisfile_audio['lossless'] = false;
886                                                                break;
887                                                }
888                                        }
889
890                                        $thisfile_audio['channels']        = $thisfile_riff_audio['channels'];
891                                        if ($thisfile_riff_audio['bits_per_sample'] > 0) {
892                                                $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
893                                        }
894                                        $thisfile_audio['sample_rate']     = $thisfile_riff_audio['sample_rate'];
895                                        if ($thisfile_audio['sample_rate'] == 0) {
896                                                $ThisFileInfo['error'][] = 'Corrupted AIFF file: sample_rate == zero';
897                                                return false;
898                                        }
899                                        $ThisFileInfo['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
900                                }
901
902                                if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
903                                        $offset = 0;
904                                        $CommentCount                                           = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
905                                        $offset += 2;
906                                        for ($i = 0; $i < $CommentCount; $i++) {
907                                                $ThisFileInfo['comments_raw'][$i]['timestamp']      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
908                                                $offset += 4;
909                                                $ThisFileInfo['comments_raw'][$i]['marker_id']      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
910                                                $offset += 2;
911                                                $CommentLength                                      = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
912                                                $offset += 2;
913                                                $ThisFileInfo['comments_raw'][$i]['comment']        =                           substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
914                                                $offset += $CommentLength;
915
916                                                $ThisFileInfo['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($ThisFileInfo['comments_raw'][$i]['timestamp']);
917                                                $thisfile_riff['comments']['comment'][] = $ThisFileInfo['comments_raw'][$i]['comment'];
918                                        }
919                                }
920
921                                $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
922                                foreach ($CommentsChunkNames as $key => $value) {
923                                        if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
924                                                $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
925                                        }
926                                }
927                                break;
928
929                        case '8SVX':
930                                $thisfile_audio['bitrate_mode']    = 'cbr';
931                                $thisfile_audio_dataformat         = '8svx';
932                                $thisfile_audio['bits_per_sample'] = 8;
933                                $thisfile_audio['channels']        = 1; // overridden below, if need be
934                                $ThisFileInfo['mime_type']                = 'audio/x-aiff';
935
936                                if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
937                                        $ThisFileInfo['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
938                                        $ThisFileInfo['avdataend']    = $ThisFileInfo['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
939                                        if ($ThisFileInfo['avdataend'] > $ThisFileInfo['filesize']) {
940                                                $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $ThisFileInfo['avdataoffset']).' bytes found';
941                                        }
942                                }
943
944                                if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
945                                        // shortcut
946                                        $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
947
948                                        $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples']  =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  0, 4));
949                                        $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples']   =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  4, 4));
950                                        $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'],  8, 4));
951                                        $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec']     =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
952                                        $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave']          =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
953                                        $thisfile_riff_RIFFsubtype_VHDR_0['sCompression']      =   getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
954                                        $thisfile_riff_RIFFsubtype_VHDR_0['Volume']            = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
955
956                                        $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
957
958                                        switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
959                                                case 0:
960                                                        $thisfile_audio['codec']    = 'Pulse Code Modulation (PCM)';
961                                                        $thisfile_audio['lossless'] = true;
962                                                        $ActualBitsPerSample               = 8;
963                                                        break;
964
965                                                case 1:
966                                                        $thisfile_audio['codec']    = 'Fibonacci-delta encoding';
967                                                        $thisfile_audio['lossless'] = false;
968                                                        $ActualBitsPerSample               = 4;
969                                                        break;
970
971                                                default:
972                                                        $ThisFileInfo['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
973                                                        break;
974                                        }
975                                }
976
977                                if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
978                                        $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
979                                        switch ($ChannelsIndex) {
980                                                case 6: // Stereo
981                                                        $thisfile_audio['channels'] = 2;
982                                                        break;
983
984                                                case 2: // Left channel only
985                                                case 4: // Right channel only
986                                                        $thisfile_audio['channels'] = 1;
987                                                        break;
988
989                                                default:
990                                                        $ThisFileInfo['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
991                                                        break;
992                                        }
993
994                                }
995
996                                $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
997                                foreach ($CommentsChunkNames as $key => $value) {
998                                        if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
999                                                $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1000                                        }
1001                                }
1002
1003                                $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
1004                                if (!empty($thisfile_audio['bitrate'])) {
1005                                        $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / ($thisfile_audio['bitrate'] / 8);
1006                                }
1007                                break;
1008
1009
1010                        case 'CDXA':
1011                                $ThisFileInfo['mime_type']      = 'video/mpeg';
1012                                if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
1013                                        $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1014                                        if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
1015                                                $dummy = $ThisFileInfo;
1016                                                $dummy['error'] = array();
1017                                                $mpeg_scanner = new getid3_mpeg($fd, $dummy);
1018                                                if (empty($dummy['error'])) {
1019                                                        $ThisFileInfo['audio']   = $dummy['audio'];
1020                                                        $ThisFileInfo['video']   = $dummy['video'];
1021                                                        $ThisFileInfo['mpeg']    = $dummy['mpeg'];
1022                                                        $ThisFileInfo['warning'] = $dummy['warning'];
1023                                                }
1024                                                unset($mpeg_scanner);
1025                                        }
1026                                }
1027                                break;
1028
1029
1030                        default:
1031                                $ThisFileInfo['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
1032                                unset($ThisFileInfo['fileformat']);
1033                                break;
1034                }
1035
1036                if (isset($thisfile_riff_raw['fmt ']['wFormatTag']) && ($thisfile_riff_raw['fmt ']['wFormatTag'] == 1)) {
1037                        // http://www.mega-nerd.com/erikd/Blog/Windiots/dts.html
1038                        fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
1039                        $FirstFourBytes = fread($fd, 4);
1040                        if (preg_match('/^\xFF\x1F\x00\xE8/s', $FirstFourBytes)) {
1041                                // DTSWAV
1042                                $thisfile_audio_dataformat = 'dts';
1043                        } elseif (preg_match('/^\x7F\xFF\x80\x01/s', $FirstFourBytes)) {
1044                                // DTS, but this probably shouldn't happen
1045                                $thisfile_audio_dataformat = 'dts';
1046                        }
1047                }
1048
1049
1050                if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
1051                        $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
1052                }
1053                if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
1054                        $this->RIFFcommentsParse($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
1055                }
1056                if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
1057                        $this->RIFFcommentsParse($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
1058                }
1059
1060                if (empty($thisfile_audio['encoder']) && !empty($ThisFileInfo['mpeg']['audio']['LAME']['short_version'])) {
1061                        $thisfile_audio['encoder'] = $ThisFileInfo['mpeg']['audio']['LAME']['short_version'];
1062                }
1063
1064                if (!isset($ThisFileInfo['playtime_seconds'])) {
1065                        $ThisFileInfo['playtime_seconds'] = 0;
1066                }
1067                if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1068                        // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie
1069                        $ThisFileInfo['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1070                } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1071                        $ThisFileInfo['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1072                }
1073
1074                if ($ThisFileInfo['playtime_seconds'] > 0) {
1075                        if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1076
1077                                if (!isset($ThisFileInfo['bitrate'])) {
1078                                        $ThisFileInfo['bitrate'] = ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']) * 8);
1079                                }
1080
1081                        } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
1082
1083                                if (!isset($thisfile_audio['bitrate'])) {
1084                                        $thisfile_audio['bitrate'] = ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']) * 8);
1085                                }
1086
1087                        } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1088
1089                                if (!isset($thisfile_video['bitrate'])) {
1090                                        $thisfile_video['bitrate'] = ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']) * 8);
1091                                }
1092
1093                        }
1094                }
1095
1096
1097                if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($ThisFileInfo['playtime_seconds'] > 0)) {
1098
1099                        $ThisFileInfo['bitrate'] = ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']) * 8);
1100                        $thisfile_audio['bitrate'] = 0;
1101                        $thisfile_video['bitrate'] = $ThisFileInfo['bitrate'];
1102                        foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
1103                                $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
1104                                $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
1105                        }
1106                        if ($thisfile_video['bitrate'] <= 0) {
1107                                unset($thisfile_video['bitrate']);
1108                        }
1109                        if ($thisfile_audio['bitrate'] <= 0) {
1110                                unset($thisfile_audio['bitrate']);
1111                        }
1112                }
1113
1114                if (isset($ThisFileInfo['mpeg']['audio'])) {
1115                        $thisfile_audio_dataformat      = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
1116                        $thisfile_audio['sample_rate']  = $ThisFileInfo['mpeg']['audio']['sample_rate'];
1117                        $thisfile_audio['channels']     = $ThisFileInfo['mpeg']['audio']['channels'];
1118                        $thisfile_audio['bitrate']      = $ThisFileInfo['mpeg']['audio']['bitrate'];
1119                        $thisfile_audio['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
1120                        if (!empty($ThisFileInfo['mpeg']['audio']['codec'])) {
1121                                $thisfile_audio['codec'] = $ThisFileInfo['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
1122                        }
1123                        if (!empty($thisfile_audio['streams'])) {
1124                                foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
1125                                        if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
1126                                                $thisfile_audio['streams'][$streamnumber]['sample_rate']  = $thisfile_audio['sample_rate'];
1127                                                $thisfile_audio['streams'][$streamnumber]['channels']     = $thisfile_audio['channels'];
1128                                                $thisfile_audio['streams'][$streamnumber]['bitrate']      = $thisfile_audio['bitrate'];
1129                                                $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
1130                                                $thisfile_audio['streams'][$streamnumber]['codec']        = $thisfile_audio['codec'];
1131                                        }
1132                                }
1133                        }
1134                        $thisfile_audio['encoder_options'] = getid3_mp3::GuessEncoderOptions($ThisFileInfo);
1135                }
1136
1137
1138                if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
1139                        switch ($thisfile_audio_dataformat) {
1140                                case 'ac3':
1141                                        // ignore bits_per_sample
1142                                        break;
1143
1144                                default:
1145                                        $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
1146                                        break;
1147                        }
1148                }
1149
1150
1151                if (empty($thisfile_riff_raw)) {
1152                        unset($thisfile_riff['raw']);
1153                }
1154                if (empty($thisfile_riff_audio)) {
1155                        unset($thisfile_riff['audio']);
1156                }
1157                if (empty($thisfile_riff_video)) {
1158                        unset($thisfile_riff['video']);
1159                }
1160
1161                return true;
1162        }
1163
1164
1165        static function RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray) {
1166                $RIFFinfoKeyLookup = array(
1167                        'IARL'=>'archivallocation',
1168                        'IART'=>'artist',
1169                        'ICDS'=>'costumedesigner',
1170                        'ICMS'=>'commissionedby',
1171                        'ICMT'=>'comment',
1172                        'ICNT'=>'country',
1173                        'ICOP'=>'copyright',
1174                        'ICRD'=>'creationdate',
1175                        'IDIM'=>'dimensions',
1176                        'IDIT'=>'digitizationdate',
1177                        'IDPI'=>'resolution',
1178                        'IDST'=>'distributor',
1179                        'IEDT'=>'editor',
1180                        'IENG'=>'engineers',
1181                        'IFRM'=>'accountofparts',
1182                        'IGNR'=>'genre',
1183                        'IKEY'=>'keywords',
1184                        'ILGT'=>'lightness',
1185                        'ILNG'=>'language',
1186                        'IMED'=>'orignalmedium',
1187                        'IMUS'=>'composer',
1188                        'INAM'=>'title',
1189                        'IPDS'=>'productiondesigner',
1190                        'IPLT'=>'palette',
1191                        'IPRD'=>'product',
1192                        'IPRO'=>'producer',
1193                        'IPRT'=>'part',
1194                        'IRTD'=>'rating',
1195                        'ISBJ'=>'subject',
1196                        'ISFT'=>'software',
1197                        'ISGN'=>'secondarygenre',
1198                        'ISHP'=>'sharpness',
1199                        'ISRC'=>'sourcesupplier',
1200                        'ISRF'=>'digitizationsource',
1201                        'ISTD'=>'productionstudio',
1202                        'ISTR'=>'starring',
1203                        'ITCH'=>'encoded_by',
1204                        'IWEB'=>'url',
1205                        'IWRI'=>'writer'
1206                );
1207                foreach ($RIFFinfoKeyLookup as $key => $value) {
1208                        if (isset($RIFFinfoArray[$key])) {
1209                                foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1210                                        if (trim($commentdata['data']) != '') {
1211                                                if (isset($CommentsTargetArray[$value])) {
1212                                                        $CommentsTargetArray[$value][] =     trim($commentdata['data']);
1213                                                } else {
1214                                                        $CommentsTargetArray[$value] = array(trim($commentdata['data']));
1215                                                }
1216                                        }
1217                                }
1218                        }
1219                }
1220                return true;
1221        }
1222
1223        static function ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo) {
1224                $maxoffset = min($maxoffset, $ThisFileInfo['avdataend']);
1225
1226                $RIFFchunk = false;
1227                $FoundAllChunksWeNeed = false;
1228
1229                if (($startoffset < 0) || !getid3_lib::intValueSupported($startoffset)) {
1230                        $ThisFileInfo['warning'][] = 'Unable to ParseRIFF() at '.$startoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1231                        return false;
1232                }
1233                $max_usable_offset = min(PHP_INT_MAX - 1024, $maxoffset);
1234                if ($maxoffset > $max_usable_offset) {
1235                        $ThisFileInfo['warning'][] = 'ParseRIFF() may return incomplete data for chunk starting at '.$startoffset.' because beyond it extends to '.$maxoffset.', which is beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1236                }
1237                fseek($fd, $startoffset, SEEK_SET);
1238
1239                while (ftell($fd) < $max_usable_offset) {
1240                        $chunknamesize = fread($fd, 8);
1241                        $chunkname =                                              substr($chunknamesize, 0, 4);
1242                        $chunksize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($chunknamesize, 4, 4));
1243                        if (strlen($chunkname) < 4) {
1244                                $ThisFileInfo['error'][] = 'Expecting chunk name at offset '.(ftell($fd) - 4).' but found nothing. Aborting RIFF parsing.';
1245                                break;
1246                        }
1247                        if ($chunksize == 0) {
1248                                if ($chunkname == 'JUNK') {
1249                                        // we'll allow zero-size JUNK frames
1250                                } else {
1251                                        $ThisFileInfo['warning'][] = 'Chunk size at offset '.(ftell($fd) - 4).' is zero. Aborting RIFF parsing.';
1252                                        break;
1253                                }
1254                        }
1255                        if (($chunksize % 2) != 0) {
1256                                // all structures are packed on word boundaries
1257                                $chunksize++;
1258                        }
1259
1260                        switch ($chunkname) {
1261                                case 'LIST':
1262                                        $listname = fread($fd, 4);
1263                                        if (preg_match('#^(movi|rec )$#i', $listname)) {
1264                                                $RIFFchunk[$listname]['offset'] = ftell($fd) - 4;
1265                                                $RIFFchunk[$listname]['size']   = $chunksize;
1266
1267                                                if ($FoundAllChunksWeNeed) {
1268
1269                                                        // skip over
1270
1271                                                } else {
1272
1273                                                        $WhereWeWere      = ftell($fd);
1274                                                        $AudioChunkHeader = fread($fd, 12);
1275                                                        $AudioChunkStreamNum  =                              substr($AudioChunkHeader, 0, 2);
1276                                                        $AudioChunkStreamType =                              substr($AudioChunkHeader, 2, 2);
1277                                                        $AudioChunkSize       = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1278
1279                                                        if ($AudioChunkStreamType == 'wb') {
1280                                                                $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1281                                                                if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1282                                                                        // MP3
1283                                                                        if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1284                                                                                $dummy = $ThisFileInfo;
1285                                                                                $dummy['avdataoffset'] = ftell($fd) - 4;
1286                                                                                $dummy['avdataend']    = ftell($fd) + $AudioChunkSize;
1287                                                                                getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $dummy['avdataoffset'], false);
1288                                                                                if (isset($dummy['mpeg']['audio'])) {
1289                                                                                        $ThisFileInfo = $dummy;
1290                                                                                        $ThisFileInfo['audio']['dataformat']   = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
1291                                                                                        $ThisFileInfo['audio']['sample_rate']  = $ThisFileInfo['mpeg']['audio']['sample_rate'];
1292                                                                                        $ThisFileInfo['audio']['channels']     = $ThisFileInfo['mpeg']['audio']['channels'];
1293                                                                                        $ThisFileInfo['audio']['bitrate']      = $ThisFileInfo['mpeg']['audio']['bitrate'];
1294                                                                                        $ThisFileInfo['bitrate']               = $ThisFileInfo['audio']['bitrate'];
1295                                                                                        $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
1296                                                                                }
1297                                                                                unset($dummy);
1298                                                                        }
1299
1300                                                                } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
1301
1302                                                                        // AC3
1303                                                                        $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1304                                                                        if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1305
1306                                                                                $dummy = $ThisFileInfo;
1307                                                                                $dummy['avdataoffset'] = ftell($fd) - 4;
1308                                                                                $dummy['avdataend']    = ftell($fd) + $AudioChunkSize;
1309                                                                                $dummy['error']        = array();
1310                                                                                $ac3_tag = new getid3_ac3($fd, $dummy);
1311                                                                                if (empty($dummy['error'])) {
1312                                                                                        $ThisFileInfo['audio']   = $dummy['audio'];
1313                                                                                        $ThisFileInfo['ac3']     = $dummy['ac3'];
1314                                                                                        $ThisFileInfo['warning'] = $dummy['warning'];
1315                                                                                }
1316                                                                                unset($ac3_tag);
1317
1318                                                                        }
1319
1320                                                                }
1321
1322                                                        }
1323
1324                                                        $FoundAllChunksWeNeed = true;
1325                                                        fseek($fd, $WhereWeWere, SEEK_SET);
1326
1327                                                }
1328                                                fseek($fd, $chunksize - 4, SEEK_CUR);
1329
1330                                        //} elseif (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#i', $listname)) {
1331                                        //
1332                                        //      // data chunk, ignore
1333                                        //
1334                                        } else {
1335
1336                                                if (!isset($RIFFchunk[$listname])) {
1337                                                        $RIFFchunk[$listname] = array();
1338                                                }
1339                                                $LISTchunkParent    = $listname;
1340                                                $LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
1341                                                if ($parsedChunk = getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
1342                                                        $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1343                                                }
1344
1345                                        }
1346                                        break;
1347
1348                                default:
1349                                        if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1350                                                $nextoffset = ftell($fd) + $chunksize;
1351                                                if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1352                                                        $ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1353                                                        break 2;
1354                                                }
1355                                                fseek($fd, $nextoffset, SEEK_SET);
1356                                                break;
1357                                        }
1358                                        $thisindex = 0;
1359                                        if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1360                                                $thisindex = count($RIFFchunk[$chunkname]);
1361                                        }
1362                                        $RIFFchunk[$chunkname][$thisindex]['offset'] = ftell($fd) - 8;
1363                                        $RIFFchunk[$chunkname][$thisindex]['size']   = $chunksize;
1364                                        switch ($chunkname) {
1365                                                case 'data':
1366                                                        $ThisFileInfo['avdataoffset'] = ftell($fd);
1367                                                        $ThisFileInfo['avdataend']    = $ThisFileInfo['avdataoffset'] + $chunksize;
1368
1369                                                        $RIFFdataChunkContentsTest = fread($fd, 36);
1370
1371                                                        if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1372
1373                                                                // Probably is MP3 data
1374                                                                if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
1375
1376                                                                        $dummy = $ThisFileInfo; // copy info array, only use if there's no error
1377                                                                        $getid3_mp3 = new getid3_mp3($fd, $dummy);
1378                                                                        $dummy = $ThisFileInfo; // copy info array, only use if there's no error
1379                                                                        $getid3_mp3->getOnlyMPEGaudioInfo($fd, $dummy, $RIFFchunk[$chunkname][$thisindex]['offset'], false);
1380
1381                                                                        // use dummy array unless error
1382                                                                        if (empty($dummy['error'])) {
1383                                                                                $ThisFileInfo = $dummy;
1384                                                                        }
1385                                                                }
1386
1387                                                        } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
1388
1389                                                                // This is probably AC-3 data
1390                                                                $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1391                                                                if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1392
1393                                                                        $dummy = $ThisFileInfo;
1394                                                                        $dummy['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1395                                                                        $dummy['avdataend']    = $dummy['avdataoffset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1396                                                                        $dummy['error']        = array();
1397
1398                                                                        $ac3_tag = new getid3_ac3($fd, $dummy);
1399                                                                        if (empty($dummy['error'])) {
1400                                                                                $ThisFileInfo['audio']   = $dummy['audio'];
1401                                                                                $ThisFileInfo['ac3']     = $dummy['ac3'];
1402                                                                                $ThisFileInfo['warning'] = $dummy['warning'];
1403                                                                        }
1404                                                                        unset($ac3_tag);
1405
1406                                                                }
1407
1408                                                        } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) == "\x77\x0B")) {
1409
1410                                                                // Dolby Digital WAV
1411                                                                // AC-3 content, but not encoded in same format as normal AC-3 file
1412                                                                // For one thing, byte order is swapped
1413
1414                                                                $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1415                                                                if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1416
1417                                                                        // ok to use tmpfile here - only 56 bytes
1418                                                                        if ($fd_temp = tmpfile()) {
1419
1420                                                                                for ($i = 0; $i < 28; $i += 2) {
1421                                                                                        // swap byte order
1422                                                                                        fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1423                                                                                        fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1424                                                                                }
1425
1426                                                                                $dummy = $ThisFileInfo;
1427                                                                                $dummy['avdataoffset'] = 0;
1428                                                                                $dummy['avdataend']    = 20;
1429                                                                                $dummy['error']        = array();
1430                                                                                $ac3_tag = new getid3_ac3($fd_temp, $dummy);
1431                                                                                fclose($fd_temp);
1432                                                                                if (empty($dummy['error'])) {
1433                                                                                        $ThisFileInfo['audio']   = $dummy['audio'];
1434                                                                                        $ThisFileInfo['ac3']     = $dummy['ac3'];
1435                                                                                        $ThisFileInfo['warning'] = $dummy['warning'];
1436                                                                                } else {
1437                                                                                        $ThisFileInfo['error'][] = 'Errors parsing DolbyDigital WAV: '.explode(';', $dummy['error']);
1438                                                                                }
1439                                                                                unset($ac3_tag);
1440
1441                                                                        } else {
1442
1443                                                                                $ThisFileInfo['error'][] = 'Could not create temporary file to analyze DolbyDigital WAV';
1444
1445                                                                        }
1446
1447                                                                }
1448
1449                                                        } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) == 'wvpk')) {
1450
1451                                                                // This is WavPack data
1452                                                                $ThisFileInfo['wavpack']['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1453                                                                $ThisFileInfo['wavpack']['size']   = getid3_lib::LittleEndian2Int(substr($RIFFdataChunkContentsTest, 4, 4));
1454                                                                getid3_riff::RIFFparseWavPackHeader(substr($RIFFdataChunkContentsTest, 8, 28), $ThisFileInfo);
1455
1456                                                        } else {
1457
1458                                                                // This is some other kind of data (quite possibly just PCM)
1459                                                                // do nothing special, just skip it
1460
1461                                                        }
1462                                                        $nextoffset = $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize;
1463                                                        if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1464                                                                $ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1465                                                                break 3;
1466                                                        }
1467                                                        fseek($fd, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
1468                                                        break;
1469
1470                                                case 'bext':
1471                                                case 'cart':
1472                                                case 'fmt ':
1473                                                case 'strh':
1474                                                case 'strf':
1475                                                case 'indx':
1476                                                case 'MEXT':
1477                                                case 'DISP':
1478                                                        // always read data in
1479                                                        $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1480                                                        break;
1481
1482                                                case 'JUNK':
1483                                                        // never read data in
1484                                                        $nextoffset = ftell($fd) + $chunksize;
1485                                                        if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1486                                                                $ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1487                                                                break 3;
1488                                                        }
1489                                                        fseek($fd, $nextoffset, SEEK_SET);
1490                                                        break;
1491
1492                                                default:
1493                                                        if (!preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname) && !empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1494                                                                $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1495                                                                $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size']   = $RIFFchunk[$chunkname][$thisindex]['size'];
1496                                                                unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1497                                                                unset($RIFFchunk[$chunkname][$thisindex]['size']);
1498                                                                if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1499                                                                        unset($RIFFchunk[$chunkname][$thisindex]);
1500                                                                }
1501                                                                if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1502                                                                        unset($RIFFchunk[$chunkname]);
1503                                                                }
1504                                                                $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1505                                                        } elseif (($chunksize > 0) && ($chunksize < 2048)) {
1506                                                                // only read data in if smaller than 2kB
1507                                                                $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1508                                                        } else {
1509                                                                $nextoffset = ftell($fd) + $chunksize;
1510                                                                if (($nextoffset < 0) || !getid3_lib::intValueSupported($nextoffset)) {
1511                                                                        $ThisFileInfo['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1512                                                                        break 3;
1513                                                                }
1514                                                                fseek($fd, $nextoffset, SEEK_SET);
1515                                                        }
1516                                                        break;
1517                                        }
1518                                        break;
1519
1520                        }
1521
1522                }
1523
1524                return $RIFFchunk;
1525        }
1526
1527
1528        static function ParseRIFFdata(&$RIFFdata, &$ThisFileInfo) {
1529                if ($RIFFdata) {
1530
1531                        $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
1532                        $fp_temp  = fopen($tempfile, 'wb');
1533                        $RIFFdataLength = strlen($RIFFdata);
1534                        $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1535                        for ($i = 0; $i < 4; $i++) {
1536                                $RIFFdata{$i + 4} = $NewLengthString{$i};
1537                        }
1538                        fwrite($fp_temp, $RIFFdata);
1539                        fclose($fp_temp);
1540
1541                        $fp_temp  = fopen($tempfile, 'rb');
1542                        $dummy = array('filesize'=>$RIFFdataLength, 'filenamepath'=>$ThisFileInfo['filenamepath'], 'tags'=>$ThisFileInfo['tags'], 'avdataoffset'=>0, 'avdataend'=>$RIFFdataLength, 'warning'=>$ThisFileInfo['warning'], 'error'=>$ThisFileInfo['error'], 'comments'=>$ThisFileInfo['comments'], 'audio'=>(isset($ThisFileInfo['audio']) ? $ThisFileInfo['audio'] : array()), 'video'=>(isset($ThisFileInfo['video']) ? $ThisFileInfo['video'] : array()));
1543                        $riff = new getid3_riff($fp_temp, $dummy);
1544                        $ThisFileInfo['riff']     = $dummy['riff'];
1545                        $ThisFileInfo['warning']  = $dummy['warning'];
1546                        $ThisFileInfo['error']    = $dummy['error'];
1547                        $ThisFileInfo['tags']     = $dummy['tags'];
1548                        $ThisFileInfo['comments'] = $dummy['comments'];
1549                        unset($riff);
1550                        fclose($fp_temp);
1551                        unlink($tempfile);
1552                        return true;
1553                }
1554                return false;
1555        }
1556
1557
1558        static function RIFFparseWAVEFORMATex($WaveFormatExData) {
1559                // shortcut
1560                $WaveFormatEx['raw'] = array();
1561                $WaveFormatEx_raw    = &$WaveFormatEx['raw'];
1562
1563                $WaveFormatEx_raw['wFormatTag']      = getid3_lib::LittleEndian2Int(substr($WaveFormatExData,  0, 2));
1564                $WaveFormatEx_raw['nChannels']       = getid3_lib::LittleEndian2Int(substr($WaveFormatExData,  2, 2));
1565                $WaveFormatEx_raw['nSamplesPerSec']  = getid3_lib::LittleEndian2Int(substr($WaveFormatExData,  4, 4));
1566                $WaveFormatEx_raw['nAvgBytesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData,  8, 4));
1567                $WaveFormatEx_raw['nBlockAlign']     = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 12, 2));
1568                $WaveFormatEx_raw['wBitsPerSample']  = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 14, 2));
1569                if (strlen($WaveFormatExData) > 16) {
1570                        $WaveFormatEx_raw['cbSize']      = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 16, 2));
1571                }
1572
1573                $WaveFormatEx['codec']           = getid3_riff::RIFFwFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1574                $WaveFormatEx['channels']        = $WaveFormatEx_raw['nChannels'];
1575                $WaveFormatEx['sample_rate']     = $WaveFormatEx_raw['nSamplesPerSec'];
1576                $WaveFormatEx['bitrate']         = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1577                $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1578
1579                return $WaveFormatEx;
1580        }
1581
1582
1583        static function RIFFparseWavPackHeader($WavPackChunkData, &$ThisFileInfo) {
1584                // typedef struct {
1585                //     char ckID [4];
1586                //     long ckSize;
1587                //     short version;
1588                //     short bits;                // added for version 2.00
1589                //     short flags, shift;        // added for version 3.00
1590                //     long total_samples, crc, crc2;
1591                //     char extension [4], extra_bc, extras [3];
1592                // } WavpackHeader;
1593
1594                // shortcut
1595                $ThisFileInfo['wavpack'] = array();
1596                $thisfile_wavpack        = &$ThisFileInfo['wavpack'];
1597
1598                $thisfile_wavpack['version']           = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  0, 2));
1599                if ($thisfile_wavpack['version'] >= 2) {
1600                        $thisfile_wavpack['bits']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  2, 2));
1601                }
1602                if ($thisfile_wavpack['version'] >= 3) {
1603                        $thisfile_wavpack['flags_raw']     = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  4, 2));
1604                        $thisfile_wavpack['shift']         = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  6, 2));
1605                        $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData,  8, 4));
1606                        $thisfile_wavpack['crc1']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1607                        $thisfile_wavpack['crc2']          = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1608                        $thisfile_wavpack['extension']     =                              substr($WavPackChunkData, 20, 4);
1609                        $thisfile_wavpack['extra_bc']      = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1610                        for ($i = 0; $i <= 2; $i++) {
1611                                $thisfile_wavpack['extras'][]  = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1612                        }
1613
1614                        // shortcut
1615                        $thisfile_wavpack['flags'] = array();
1616                        $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1617
1618                        $thisfile_wavpack_flags['mono']                 = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1619                        $thisfile_wavpack_flags['fast_mode']            = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1620                        $thisfile_wavpack_flags['raw_mode']             = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1621                        $thisfile_wavpack_flags['calc_noise']           = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1622                        $thisfile_wavpack_flags['high_quality']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1623                        $thisfile_wavpack_flags['3_byte_samples']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1624                        $thisfile_wavpack_flags['over_20_bits']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1625                        $thisfile_wavpack_flags['use_wvc']              = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1626                        $thisfile_wavpack_flags['noiseshaping']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1627                        $thisfile_wavpack_flags['very_fast_mode']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1628                        $thisfile_wavpack_flags['new_high_quality']     = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1629                        $thisfile_wavpack_flags['cancel_extreme']       = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1630                        $thisfile_wavpack_flags['cross_decorrelation']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1631                        $thisfile_wavpack_flags['new_decorrelation']    = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1632                        $thisfile_wavpack_flags['joint_stereo']         = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1633                        $thisfile_wavpack_flags['extra_decorrelation']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1634                        $thisfile_wavpack_flags['override_noiseshape']  = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1635                        $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1636                        $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1637                        $thisfile_wavpack_flags['create_exe']           = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1638                }
1639
1640                return true;
1641        }
1642
1643        static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
1644                // yes it's ugly to instantiate a getid3_lib object here, suggested alternative please?
1645                $getid3_lib = new getid3_lib();
1646                $functionname = ($littleEndian ? 'LittleEndian2Int' : 'BigEndian2Int');
1647                $parsed['biSize']          = $getid3_lib->$functionname(substr($BITMAPINFOHEADER,  0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
1648                $parsed['biWidth']         = $getid3_lib->$functionname(substr($BITMAPINFOHEADER,  4, 4)); // width of the bitmap in pixels
1649                $parsed['biHeight']        = $getid3_lib->$functionname(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
1650                $parsed['biPlanes']        = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
1651                $parsed['biBitCount']      = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 14, 2)); // Specifies the number of bits per pixels
1652                $parsed['fourcc']          =                            substr($BITMAPINFOHEADER, 16, 4);  // compression identifier
1653                $parsed['biSizeImage']     = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1654                $parsed['biXPelsPerMeter'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
1655                $parsed['biYPelsPerMeter'] = $getid3_lib->$functionname(substr($BITMAPINFOHEADER, 28, 4)); // vertical resolution, in pixels per metre, of the target device
1656                $parsed['biClrUsed']       = $getid3_lib->$functionname(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
1657                $parsed['biClrImportant']  = $getid3_lib->$functionname(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
1658                return $parsed;
1659        }
1660
1661        static function ParseDIVXTAG($DIVXTAG) {
1662                // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1663                // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1664                // 'Byte Layout:                   '1111111111111111
1665                // '32 for Movie - 1               '1111111111111111
1666                // '28 for Author - 6              '6666666666666666
1667                // '4  for year - 2                '6666666666662222
1668                // '3  for genre - 3               '7777777777777777
1669                // '48 for Comments - 7            '7777777777777777
1670                // '1  for Rating - 4              '7777777777777777
1671                // '5  for Future Additions - 0    '333400000DIVXTAG
1672                // '128 bytes total
1673
1674                static $DIVXTAGgenre  = array(
1675                         0 => 'Action',
1676                         1 => 'Action/Adventure',
1677                         2 => 'Adventure',
1678                         3 => 'Adult',
1679                         4 => 'Anime',
1680                         5 => 'Cartoon',
1681                         6 => 'Claymation',
1682                         7 => 'Comedy',
1683                         8 => 'Commercial',
1684                         9 => 'Documentary',
1685                        10 => 'Drama',
1686                        11 => 'Home Video',
1687                        12 => 'Horror',
1688                        13 => 'Infomercial',
1689                        14 => 'Interactive',
1690                        15 => 'Mystery',
1691                        16 => 'Music Video',
1692                        17 => 'Other',
1693                        18 => 'Religion',
1694                        19 => 'Sci Fi',
1695                        20 => 'Thriller',
1696                        21 => 'Western',
1697                );
1698                static $DIVXTAGrating = array(
1699                        0=>'Unrated',
1700                        1=>'G',
1701                        2=>'PG',
1702                        3=>'PG-13',
1703                        4=>'R',
1704                        5=>'NC-17'
1705                );
1706
1707                $parsed['title']     =        trim(substr($DIVXTAG,   0, 32));
1708                $parsed['artist']    =        trim(substr($DIVXTAG,  32, 28));
1709                $parsed['year']      = intval(trim(substr($DIVXTAG,  60,  4)));
1710                $parsed['comment']   =        trim(substr($DIVXTAG,  64, 48));
1711                $parsed['genre_id']  = intval(trim(substr($DIVXTAG, 112,  3)));
1712                $parsed['rating_id'] =         ord(substr($DIVXTAG, 115,  1));
1713                //$parsed['padding'] =             substr($DIVXTAG, 116,  5);  // 5-byte null
1714                //$parsed['magic']   =             substr($DIVXTAG, 121,  7);  // "DIVXTAG"
1715
1716                $parsed['genre']  = (isset($DIVXTAGgenre[$parsed['genre_id']])   ? $DIVXTAGgenre[$parsed['genre_id']]   : $parsed['genre_id']);
1717                $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1718                return $parsed;
1719        }
1720
1721        static function RIFFwaveSNDMtagLookup($tagshortname) {
1722                $begin = __LINE__;
1723
1724                /** This is not a comment!
1725
1726                        ©kwd    keywords
1727                        ©BPM    bpm
1728                        ©trt    tracktitle
1729                        ©des    description
1730                        ©gen    category
1731                        ©fin    featuredinstrument
1732                        ©LID    longid
1733                        ©bex    bwdescription
1734                        ©pub    publisher
1735                        ©cdt    cdtitle
1736                        ©alb    library
1737                        ©com    composer
1738
1739                */
1740
1741                return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1742        }
1743
1744        static function RIFFwFormatTagLookup($wFormatTag) {
1745
1746                $begin = __LINE__;
1747
1748                /** This is not a comment!
1749
1750                        0x0000  Microsoft Unknown Wave Format
1751                        0x0001  Pulse Code Modulation (PCM)
1752                        0x0002  Microsoft ADPCM
1753                        0x0003  IEEE Float
1754                        0x0004  Compaq Computer VSELP
1755                        0x0005  IBM CVSD
1756                        0x0006  Microsoft A-Law
1757                        0x0007  Microsoft mu-Law
1758                        0x0008  Microsoft DTS
1759                        0x0010  OKI ADPCM
1760                        0x0011  Intel DVI/IMA ADPCM
1761                        0x0012  Videologic MediaSpace ADPCM
1762                        0x0013  Sierra Semiconductor ADPCM
1763                        0x0014  Antex Electronics G.723 ADPCM
1764                        0x0015  DSP Solutions DigiSTD
1765                        0x0016  DSP Solutions DigiFIX
1766                        0x0017  Dialogic OKI ADPCM
1767                        0x0018  MediaVision ADPCM
1768                        0x0019  Hewlett-Packard CU
1769                        0x0020  Yamaha ADPCM
1770                        0x0021  Speech Compression Sonarc
1771                        0x0022  DSP Group TrueSpeech
1772                        0x0023  Echo Speech EchoSC1
1773                        0x0024  Audiofile AF36
1774                        0x0025  Audio Processing Technology APTX
1775                        0x0026  AudioFile AF10
1776                        0x0027  Prosody 1612
1777                        0x0028  LRC
1778                        0x0030  Dolby AC2
1779                        0x0031  Microsoft GSM 6.10
1780                        0x0032  MSNAudio
1781                        0x0033  Antex Electronics ADPCME
1782                        0x0034  Control Resources VQLPC
1783                        0x0035  DSP Solutions DigiREAL
1784                        0x0036  DSP Solutions DigiADPCM
1785                        0x0037  Control Resources CR10
1786                        0x0038  Natural MicroSystems VBXADPCM
1787                        0x0039  Crystal Semiconductor IMA ADPCM
1788                        0x003A  EchoSC3
1789                        0x003B  Rockwell ADPCM
1790                        0x003C  Rockwell Digit LK
1791                        0x003D  Xebec
1792                        0x0040  Antex Electronics G.721 ADPCM
1793                        0x0041  G.728 CELP
1794                        0x0042  MSG723
1795                        0x0050  MPEG Layer-2 or Layer-1
1796                        0x0052  RT24
1797                        0x0053  PAC
1798                        0x0055  MPEG Layer-3
1799                        0x0059  Lucent G.723
1800                        0x0060  Cirrus
1801                        0x0061  ESPCM
1802                        0x0062  Voxware
1803                        0x0063  Canopus Atrac
1804                        0x0064  G.726 ADPCM
1805                        0x0065  G.722 ADPCM
1806                        0x0066  DSAT
1807                        0x0067  DSAT Display
1808                        0x0069  Voxware Byte Aligned
1809                        0x0070  Voxware AC8
1810                        0x0071  Voxware AC10
1811                        0x0072  Voxware AC16
1812                        0x0073  Voxware AC20
1813                        0x0074  Voxware MetaVoice
1814                        0x0075  Voxware MetaSound
1815                        0x0076  Voxware RT29HW
1816                        0x0077  Voxware VR12
1817                        0x0078  Voxware VR18
1818                        0x0079  Voxware TQ40
1819                        0x0080  Softsound
1820                        0x0081  Voxware TQ60
1821                        0x0082  MSRT24
1822                        0x0083  G.729A
1823                        0x0084  MVI MV12
1824                        0x0085  DF G.726
1825                        0x0086  DF GSM610
1826                        0x0088  ISIAudio
1827                        0x0089  Onlive
1828                        0x0091  SBC24
1829                        0x0092  Dolby AC3 SPDIF
1830                        0x0093  MediaSonic G.723
1831                        0x0094  Aculab PLC    Prosody 8kbps
1832                        0x0097  ZyXEL ADPCM
1833                        0x0098  Philips LPCBB
1834                        0x0099  Packed
1835                        0x00FF  AAC
1836                        0x0100  Rhetorex ADPCM
1837                        0x0101  IBM mu-law
1838                        0x0102  IBM A-law
1839                        0x0103  IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
1840                        0x0111  Vivo G.723
1841                        0x0112  Vivo Siren
1842                        0x0123  Digital G.723
1843                        0x0125  Sanyo LD ADPCM
1844                        0x0130  Sipro Lab Telecom ACELP NET
1845                        0x0131  Sipro Lab Telecom ACELP 4800
1846                        0x0132  Sipro Lab Telecom ACELP 8V3
1847                        0x0133  Sipro Lab Telecom G.729
1848                        0x0134  Sipro Lab Telecom G.729A
1849                        0x0135  Sipro Lab Telecom Kelvin
1850                        0x0140  Windows Media Video V8
1851                        0x0150  Qualcomm PureVoice
1852                        0x0151  Qualcomm HalfRate
1853                        0x0155  Ring Zero Systems TUB GSM
1854                        0x0160  Microsoft Audio 1
1855                        0x0161  Windows Media Audio V7 / V8 / V9
1856                        0x0162  Windows Media Audio Professional V9
1857                        0x0163  Windows Media Audio Lossless V9
1858                        0x0200  Creative Labs ADPCM
1859                        0x0202  Creative Labs Fastspeech8
1860                        0x0203  Creative Labs Fastspeech10
1861                        0x0210  UHER Informatic GmbH ADPCM
1862                        0x0220  Quarterdeck
1863                        0x0230  I-link Worldwide VC
1864                        0x0240  Aureal RAW Sport
1865                        0x0250  Interactive Products HSX
1866                        0x0251  Interactive Products RPELP
1867                        0x0260  Consistent Software CS2
1868                        0x0270  Sony SCX
1869                        0x0300  Fujitsu FM Towns Snd
1870                        0x0400  BTV Digital
1871                        0x0401  Intel Music Coder
1872                        0x0450  QDesign Music
1873                        0x0680  VME VMPCM
1874                        0x0681  AT&T Labs TPC
1875                        0x08AE  ClearJump LiteWave
1876                        0x1000  Olivetti GSM
1877                        0x1001  Olivetti ADPCM
1878                        0x1002  Olivetti CELP
1879                        0x1003  Olivetti SBC
1880                        0x1004  Olivetti OPR
1881                        0x1100  Lernout & Hauspie Codec (0x1100)
1882                        0x1101  Lernout & Hauspie CELP Codec (0x1101)
1883                        0x1102  Lernout & Hauspie SBC Codec (0x1102)
1884                        0x1103  Lernout & Hauspie SBC Codec (0x1103)
1885                        0x1104  Lernout & Hauspie SBC Codec (0x1104)
1886                        0x1400  Norris
1887                        0x1401  AT&T ISIAudio
1888                        0x1500  Soundspace Music Compression
1889                        0x181C  VoxWare RT24 Speech
1890                        0x1FC4  NCT Soft ALF2CD (www.nctsoft.com)
1891                        0x2000  Dolby AC3
1892                        0x2001  Dolby DTS
1893                        0x2002  WAVE_FORMAT_14_4
1894                        0x2003  WAVE_FORMAT_28_8
1895                        0x2004  WAVE_FORMAT_COOK
1896                        0x2005  WAVE_FORMAT_DNET
1897                        0x674F  Ogg Vorbis 1
1898                        0x6750  Ogg Vorbis 2
1899                        0x6751  Ogg Vorbis 3
1900                        0x676F  Ogg Vorbis 1+
1901                        0x6770  Ogg Vorbis 2+
1902                        0x6771  Ogg Vorbis 3+
1903                        0x7A21  GSM-AMR (CBR, no SID)
1904                        0x7A22  GSM-AMR (VBR, including SID)
1905                        0xFFFE  WAVE_FORMAT_EXTENSIBLE
1906                        0xFFFF  WAVE_FORMAT_DEVELOPMENT
1907
1908                */
1909
1910                return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
1911
1912        }
1913
1914
1915        static function RIFFfourccLookup($fourcc) {
1916
1917                $begin = __LINE__;
1918
1919                /** This is not a comment!
1920
1921                        swot    http://developer.apple.com/qa/snd/snd07.html
1922                        ____    No Codec (____)
1923                        _BIT    BI_BITFIELDS (Raw RGB)
1924                        _JPG    JPEG compressed
1925                        _PNG    PNG compressed W3C/ISO/IEC (RFC-2083)
1926                        _RAW    Full Frames (Uncompressed)
1927                        _RGB    Raw RGB Bitmap
1928                        _RL4    RLE 4bpp RGB
1929                        _RL8    RLE 8bpp RGB
1930                        3IV1    3ivx MPEG-4 v1
1931                        3IV2    3ivx MPEG-4 v2
1932                        3IVX    3ivx MPEG-4
1933                        AASC    Autodesk Animator
1934                        ABYR    Kensington ?ABYR?
1935                        AEMI    Array Microsystems VideoONE MPEG1-I Capture
1936                        AFLC    Autodesk Animator FLC
1937                        AFLI    Autodesk Animator FLI
1938                        AMPG    Array Microsystems VideoONE MPEG
1939                        ANIM    Intel RDX (ANIM)
1940                        AP41    AngelPotion Definitive
1941                        ASV1    Asus Video v1
1942                        ASV2    Asus Video v2
1943                        ASVX    Asus Video 2.0 (audio)
1944                        AUR2    AuraVision Aura 2 Codec - YUV 4:2:2
1945                        AURA    AuraVision Aura 1 Codec - YUV 4:1:1
1946                        AVDJ    Independent JPEG Group\'s codec (AVDJ)
1947                        AVRN    Independent JPEG Group\'s codec (AVRN)
1948                        AYUV    4:4:4 YUV (AYUV)
1949                        AZPR    Quicktime Apple Video (AZPR)
1950                        BGR     Raw RGB32
1951                        BLZ0    Blizzard DivX MPEG-4
1952                        BTVC    Conexant Composite Video
1953                        BINK    RAD Game Tools Bink Video
1954                        BT20    Conexant Prosumer Video
1955                        BTCV    Conexant Composite Video Codec
1956                        BW10    Data Translation Broadway MPEG Capture
1957                        CC12    Intel YUV12
1958                        CDVC    Canopus DV
1959                        CFCC    Digital Processing Systems DPS Perception
1960                        CGDI    Microsoft Office 97 Camcorder Video
1961                        CHAM    Winnov Caviara Champagne
1962                        CJPG    Creative WebCam JPEG
1963                        CLJR    Cirrus Logic YUV 4:1:1
1964                        CMYK    Common Data Format in Printing (Colorgraph)
1965                        CPLA    Weitek 4:2:0 YUV Planar
1966                        CRAM    Microsoft Video 1 (CRAM)
1967                        cvid    Radius Cinepak
1968                        CVID    Radius Cinepak
1969                        CWLT    Microsoft Color WLT DIB
1970                        CYUV    Creative Labs YUV
1971                        CYUY    ATI YUV
1972                        D261    H.261
1973                        D263    H.263
1974                        DIB     Device Independent Bitmap
1975                        DIV1    FFmpeg OpenDivX
1976                        DIV2    Microsoft MPEG-4 v1/v2
1977                        DIV3    DivX ;-) MPEG-4 v3.x Low-Motion
1978                        DIV4    DivX ;-) MPEG-4 v3.x Fast-Motion
1979                        DIV5    DivX MPEG-4 v5.x
1980                        DIV6    DivX ;-) (MS MPEG-4 v3.x)
1981                        DIVX    DivX MPEG-4 v4 (OpenDivX / Project Mayo)
1982                        divx    DivX MPEG-4
1983                        DMB1    Matrox Rainbow Runner hardware MJPEG
1984                        DMB2    Paradigm MJPEG
1985                        DSVD    ?DSVD?
1986                        DUCK    Duck TrueMotion 1.0
1987                        DPS0    DPS/Leitch Reality Motion JPEG
1988                        DPSC    DPS/Leitch PAR Motion JPEG
1989                        DV25    Matrox DVCPRO codec
1990                        DV50    Matrox DVCPRO50 codec
1991                        DVC     IEC 61834 and SMPTE 314M (DVC/DV Video)
1992                        DVCP    IEC 61834 and SMPTE 314M (DVC/DV Video)
1993                        DVHD    IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
1994                        DVMA    Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
1995                        DVSL    IEC Standard DV compressed in SD (SDL)
1996                        DVAN    ?DVAN?
1997                        DVE2    InSoft DVE-2 Videoconferencing
1998                        dvsd    IEC 61834 and SMPTE 314M DVC/DV Video
1999                        DVSD    IEC 61834 and SMPTE 314M DVC/DV Video
2000                        DVX1    Lucent DVX1000SP Video Decoder
2001                        DVX2    Lucent DVX2000S Video Decoder
2002                        DVX3    Lucent DVX3000S Video Decoder
2003                        DX50    DivX v5
2004                        DXT1    Microsoft DirectX Compressed Texture (DXT1)
2005                        DXT2    Microsoft DirectX Compressed Texture (DXT2)
2006                        DXT3    Microsoft DirectX Compressed Texture (DXT3)
2007                        DXT4    Microsoft DirectX Compressed Texture (DXT4)
2008                        DXT5    Microsoft DirectX Compressed Texture (DXT5)
2009                        DXTC    Microsoft DirectX Compressed Texture (DXTC)
2010                        DXTn    Microsoft DirectX Compressed Texture (DXTn)
2011                        EM2V    Etymonix MPEG-2 I-frame (www.etymonix.com)
2012                        EKQ0    Elsa ?EKQ0?
2013                        ELK0    Elsa ?ELK0?
2014                        ESCP    Eidos Escape
2015                        ETV1    eTreppid Video ETV1
2016                        ETV2    eTreppid Video ETV2
2017                        ETVC    eTreppid Video ETVC
2018                        FLIC    Autodesk FLI/FLC Animation
2019                        FRWT    Darim Vision Forward Motion JPEG (www.darvision.com)
2020                        FRWU    Darim Vision Forward Uncompressed (www.darvision.com)
2021                        FLJP    D-Vision Field Encoded Motion JPEG
2022                        FRWA    SoftLab-Nsk Forward Motion JPEG w/ alpha channel
2023                        FRWD    SoftLab-Nsk Forward Motion JPEG
2024                        FVF1    Iterated Systems Fractal Video Frame
2025                        GLZW    Motion LZW (gabest@freemail.hu)
2026                        GPEG    Motion JPEG (gabest@freemail.hu)
2027                        GWLT    Microsoft Greyscale WLT DIB
2028                        H260    Intel ITU H.260 Videoconferencing
2029                        H261    Intel ITU H.261 Videoconferencing
2030                        H262    Intel ITU H.262 Videoconferencing
2031                        H263    Intel ITU H.263 Videoconferencing
2032                        H264    Intel ITU H.264 Videoconferencing
2033                        H265    Intel ITU H.265 Videoconferencing
2034                        H266    Intel ITU H.266 Videoconferencing
2035                        H267    Intel ITU H.267 Videoconferencing
2036                        H268    Intel ITU H.268 Videoconferencing
2037                        H269    Intel ITU H.269 Videoconferencing
2038                        HFYU    Huffman Lossless Codec
2039                        HMCR    Rendition Motion Compensation Format (HMCR)
2040                        HMRR    Rendition Motion Compensation Format (HMRR)
2041                        I263    FFmpeg I263 decoder
2042                        IF09    Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
2043                        IUYV    Interlaced version of UYVY (www.leadtools.com)
2044                        IY41    Interlaced version of Y41P (www.leadtools.com)
2045                        IYU1    12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
2046                        IYU2    24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
2047                        IYUV    Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes)
2048                        i263    Intel ITU H.263 Videoconferencing (i263)
2049                        I420    Intel Indeo 4
2050                        IAN     Intel Indeo 4 (RDX)
2051                        ICLB    InSoft CellB Videoconferencing
2052                        IGOR    Power DVD
2053                        IJPG    Intergraph JPEG
2054                        ILVC    Intel Layered Video
2055                        ILVR    ITU-T H.263+
2056                        IPDV    I-O Data Device Giga AVI DV Codec
2057                        IR21    Intel Indeo 2.1
2058                        IRAW    Intel YUV Uncompressed
2059                        IV30    Intel Indeo 3.0
2060                        IV31    Intel Indeo 3.1
2061                        IV32    Ligos Indeo 3.2
2062                        IV33    Ligos Indeo 3.3
2063                        IV34    Ligos Indeo 3.4
2064                        IV35    Ligos Indeo 3.5
2065                        IV36    Ligos Indeo 3.6
2066                        IV37    Ligos Indeo 3.7
2067                        IV38    Ligos Indeo 3.8
2068                        IV39    Ligos Indeo 3.9
2069                        IV40    Ligos Indeo Interactive 4.0
2070                        IV41    Ligos Indeo Interactive 4.1
2071                        IV42    Ligos Indeo Interactive 4.2
2072                        IV43    Ligos Indeo Interactive 4.3
2073                        IV44    Ligos Indeo Interactive 4.4
2074                        IV45    Ligos Indeo Interactive 4.5
2075                        IV46    Ligos Indeo Interactive 4.6
2076                        IV47    Ligos Indeo Interactive 4.7
2077                        IV48    Ligos Indeo Interactive 4.8
2078                        IV49    Ligos Indeo Interactive 4.9
2079                        IV50    Ligos Indeo Interactive 5.0
2080                        JBYR    Kensington ?JBYR?
2081                        JPEG    Still Image JPEG DIB
2082                        JPGL    Pegasus Lossless Motion JPEG
2083                        KMVC    Team17 Software Karl Morton\'s Video Codec
2084                        LSVM    Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
2085                        LEAD    LEAD Video Codec
2086                        Ljpg    LEAD MJPEG Codec
2087                        MDVD    Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
2088                        MJPA    Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
2089                        MJPB    Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
2090                        MMES    Matrox MPEG-2 I-frame
2091                        MP2v    Microsoft S-Mpeg 4 version 1 (MP2v)
2092                        MP42    Microsoft S-Mpeg 4 version 2 (MP42)
2093                        MP43    Microsoft S-Mpeg 4 version 3 (MP43)
2094                        MP4S    Microsoft S-Mpeg 4 version 3 (MP4S)
2095                        MP4V    FFmpeg MPEG-4
2096                        MPG1    FFmpeg MPEG 1/2
2097                        MPG2    FFmpeg MPEG 1/2
2098                        MPG3    FFmpeg DivX ;-) (MS MPEG-4 v3)
2099                        MPG4    Microsoft MPEG-4
2100                        MPGI    Sigma Designs MPEG
2101                        MPNG    PNG images decoder
2102                        MSS1    Microsoft Windows Screen Video
2103                        MSZH    LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2104                        M261    Microsoft H.261
2105                        M263    Microsoft H.263
2106                        M4S2    Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
2107                        m4s2    Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
2108                        MC12    ATI Motion Compensation Format (MC12)
2109                        MCAM    ATI Motion Compensation Format (MCAM)
2110                        MJ2C    Morgan Multimedia Motion JPEG2000
2111                        mJPG    IBM Motion JPEG w/ Huffman Tables
2112                        MJPG    Microsoft Motion JPEG DIB
2113                        MP42    Microsoft MPEG-4 (low-motion)
2114                        MP43    Microsoft MPEG-4 (fast-motion)
2115                        MP4S    Microsoft MPEG-4 (MP4S)
2116                        mp4s    Microsoft MPEG-4 (mp4s)
2117                        MPEG    Chromatic Research MPEG-1 Video I-Frame
2118                        MPG4    Microsoft MPEG-4 Video High Speed Compressor
2119                        MPGI    Sigma Designs MPEG
2120                        MRCA    FAST Multimedia Martin Regen Codec
2121                        MRLE    Microsoft Run Length Encoding
2122                        MSVC    Microsoft Video 1
2123                        MTX1    Matrox ?MTX1?
2124                        MTX2    Matrox ?MTX2?
2125                        MTX3    Matrox ?MTX3?
2126                        MTX4    Matrox ?MTX4?
2127                        MTX5    Matrox ?MTX5?
2128                        MTX6    Matrox ?MTX6?
2129                        MTX7    Matrox ?MTX7?
2130                        MTX8    Matrox ?MTX8?
2131                        MTX9    Matrox ?MTX9?
2132                        MV12    Motion Pixels Codec (old)
2133                        MWV1    Aware Motion Wavelets
2134                        nAVI    SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
2135                        NT00    NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
2136                        NUV1    NuppelVideo
2137                        NTN1    Nogatech Video Compression 1
2138                        NVS0    nVidia GeForce Texture (NVS0)
2139                        NVS1    nVidia GeForce Texture (NVS1)
2140                        NVS2    nVidia GeForce Texture (NVS2)
2141                        NVS3    nVidia GeForce Texture (NVS3)
2142                        NVS4    nVidia GeForce Texture (NVS4)
2143                        NVS5    nVidia GeForce Texture (NVS5)
2144                        NVT0    nVidia GeForce Texture (NVT0)
2145                        NVT1    nVidia GeForce Texture (NVT1)
2146                        NVT2    nVidia GeForce Texture (NVT2)
2147                        NVT3    nVidia GeForce Texture (NVT3)
2148                        NVT4    nVidia GeForce Texture (NVT4)
2149                        NVT5    nVidia GeForce Texture (NVT5)
2150                        PIXL    MiroXL, Pinnacle PCTV
2151                        PDVC    I-O Data Device Digital Video Capture DV codec
2152                        PGVV    Radius Video Vision
2153                        PHMO    IBM Photomotion
2154                        PIM1    MPEG Realtime (Pinnacle Cards)
2155                        PIM2    Pegasus Imaging ?PIM2?
2156                        PIMJ    Pegasus Imaging Lossless JPEG
2157                        PVEZ    Horizons Technology PowerEZ
2158                        PVMM    PacketVideo Corporation MPEG-4
2159                        PVW2    Pegasus Imaging Wavelet Compression
2160                        Q1.0    Q-Team\'s QPEG 1.0 (www.q-team.de)
2161                        Q1.1    Q-Team\'s QPEG 1.1 (www.q-team.de)
2162                        QPEG    Q-Team QPEG 1.0
2163                        qpeq    Q-Team QPEG 1.1
2164                        RGB     Raw BGR32
2165                        RGBA    Raw RGB w/ Alpha
2166                        RMP4    REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
2167                        ROQV    Id RoQ File Video Decoder
2168                        RPZA    Quicktime Apple Video (RPZA)
2169                        RUD0    Rududu video codec (http://rududu.ifrance.com/rududu/)
2170                        RV10    RealVideo 1.0 (aka RealVideo 5.0)
2171                        RV13    RealVideo 1.0 (RV13)
2172                        RV20    RealVideo G2
2173                        RV30    RealVideo 8
2174                        RV40    RealVideo 9
2175                        RGBT    Raw RGB w/ Transparency
2176                        RLE     Microsoft Run Length Encoder
2177                        RLE4    Run Length Encoded (4bpp, 16-color)
2178                        RLE8    Run Length Encoded (8bpp, 256-color)
2179                        RT21    Intel Indeo RealTime Video 2.1
2180                        rv20    RealVideo G2
2181                        rv30    RealVideo 8
2182                        RVX     Intel RDX (RVX )
2183                        SMC     Apple Graphics (SMC )
2184                        SP54    Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
2185                        SPIG    Radius Spigot
2186                        SVQ3    Sorenson Video 3 (Apple Quicktime 5)
2187                        s422    Tekram VideoCap C210 YUV 4:2:2
2188                        SDCC    Sun Communication Digital Camera Codec
2189                        SFMC    CrystalNet Surface Fitting Method
2190                        SMSC    Radius SMSC
2191                        SMSD    Radius SMSD
2192                        smsv    WorldConnect Wavelet Video
2193                        SPIG    Radius Spigot
2194                        SPLC    Splash Studios ACM Audio Codec (www.splashstudios.net)
2195                        SQZ2    Microsoft VXTreme Video Codec V2
2196                        STVA    ST Microelectronics CMOS Imager Data (Bayer)
2197                        STVB    ST Microelectronics CMOS Imager Data (Nudged Bayer)
2198                        STVC    ST Microelectronics CMOS Imager Data (Bunched)
2199                        STVX    ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
2200                        STVY    ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
2201                        SV10    Sorenson Video R1
2202                        SVQ1    Sorenson Video
2203                        T420    Toshiba YUV 4:2:0
2204                        TM2A    Duck TrueMotion Archiver 2.0 (www.duck.com)
2205                        TVJP    Pinnacle/Truevision Targa 2000 board (TVJP)
2206                        TVMJ    Pinnacle/Truevision Targa 2000 board (TVMJ)
2207                        TY0N    Tecomac Low-Bit Rate Codec (www.tecomac.com)
2208                        TY2C    Trident Decompression Driver
2209                        TLMS    TeraLogic Motion Intraframe Codec (TLMS)
2210                        TLST    TeraLogic Motion Intraframe Codec (TLST)
2211                        TM20    Duck TrueMotion 2.0
2212                        TM2X    Duck TrueMotion 2X
2213                        TMIC    TeraLogic Motion Intraframe Codec (TMIC)
2214                        TMOT    Horizons Technology TrueMotion S
2215                        tmot    Horizons TrueMotion Video Compression
2216                        TR20    Duck TrueMotion RealTime 2.0
2217                        TSCC    TechSmith Screen Capture Codec
2218                        TV10    Tecomac Low-Bit Rate Codec
2219                        TY2N    Trident ?TY2N?
2220                        U263    UB Video H.263/H.263+/H.263++ Decoder
2221                        UMP4    UB Video MPEG 4 (www.ubvideo.com)
2222                        UYNV    Nvidia UYVY packed 4:2:2
2223                        UYVP    Evans & Sutherland YCbCr 4:2:2 extended precision
2224                        UCOD    eMajix.com ClearVideo
2225                        ULTI    IBM Ultimotion
2226                        UYVY    UYVY packed 4:2:2
2227                        V261    Lucent VX2000S
2228                        VIFP    VFAPI Reader Codec (www.yks.ne.jp/~hori/)
2229                        VIV1    FFmpeg H263+ decoder
2230                        VIV2    Vivo H.263
2231                        VQC2    Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
2232                        VTLP    Alaris VideoGramPiX
2233                        VYU9    ATI YUV (VYU9)
2234                        VYUY    ATI YUV (VYUY)
2235                        V261    Lucent VX2000S
2236                        V422    Vitec Multimedia 24-bit YUV 4:2:2 Format
2237                        V655    Vitec Multimedia 16-bit YUV 4:2:2 Format
2238                        VCR1    ATI Video Codec 1
2239                        VCR2    ATI Video Codec 2
2240                        VCR3    ATI VCR 3.0
2241                        VCR4    ATI VCR 4.0
2242                        VCR5    ATI VCR 5.0
2243                        VCR6    ATI VCR 6.0
2244                        VCR7    ATI VCR 7.0
2245                        VCR8    ATI VCR 8.0
2246                        VCR9    ATI VCR 9.0
2247                        VDCT    Vitec Multimedia Video Maker Pro DIB
2248                        VDOM    VDOnet VDOWave
2249                        VDOW    VDOnet VDOLive (H.263)
2250                        VDTZ    Darim Vison VideoTizer YUV
2251                        VGPX    Alaris VideoGramPiX
2252                        VIDS    Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
2253                        VIVO    Vivo H.263 v2.00
2254                        vivo    Vivo H.263
2255                        VIXL    Miro/Pinnacle Video XL
2256                        VLV1    VideoLogic/PURE Digital Videologic Capture
2257                        VP30    On2 VP3.0
2258                        VP31    On2 VP3.1
2259                        VX1K    Lucent VX1000S Video Codec
2260                        VX2K    Lucent VX2000S Video Codec
2261                        VXSP    Lucent VX1000SP Video Codec
2262                        WBVC    Winbond W9960
2263                        WHAM    Microsoft Video 1 (WHAM)
2264                        WINX    Winnov Software Compression
2265                        WJPG    AverMedia Winbond JPEG
2266                        WMV1    Windows Media Video V7
2267                        WMV2    Windows Media Video V8
2268                        WMV3    Windows Media Video V9
2269                        WNV1    Winnov Hardware Compression
2270                        XYZP    Extended PAL format XYZ palette (www.riff.org)
2271                        x263    Xirlink H.263
2272                        XLV0    NetXL Video Decoder
2273                        XMPG    Xing MPEG (I-Frame only)
2274                        XVID    XviD MPEG-4 (www.xvid.org)
2275                        XXAN    ?XXAN?
2276                        YU92    Intel YUV (YU92)
2277                        YUNV    Nvidia Uncompressed YUV 4:2:2
2278                        YUVP    Extended PAL format YUV palette (www.riff.org)
2279                        Y211    YUV 2:1:1 Packed
2280                        Y411    YUV 4:1:1 Packed
2281                        Y41B    Weitek YUV 4:1:1 Planar
2282                        Y41P    Brooktree PC1 YUV 4:1:1 Packed
2283                        Y41T    Brooktree PC1 YUV 4:1:1 with transparency
2284                        Y42B    Weitek YUV 4:2:2 Planar
2285                        Y42T    Brooktree UYUV 4:2:2 with transparency
2286                        Y422    ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
2287                        Y800    Simple, single Y plane for monochrome images
2288                        Y8      Grayscale video
2289                        YC12    Intel YUV 12 codec
2290                        YUV8    Winnov Caviar YUV8
2291                        YUV9    Intel YUV9
2292                        YUY2    Uncompressed YUV 4:2:2
2293                        YUYV    Canopus YUV
2294                        YV12    YVU12 Planar
2295                        YVU9    Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
2296                        YVYU    YVYU 4:2:2 Packed
2297                        ZLIB    Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
2298                        ZPEG    Metheus Video Zipper
2299
2300                */
2301
2302                return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2303        }
2304
2305
2306        static function EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false) {
2307                if ($ThisFileInfo['fileformat'] == 'riff') {
2308                        return getid3_lib::LittleEndian2Int($byteword, $signed);
2309                }
2310                return getid3_lib::BigEndian2Int($byteword, false, $signed);
2311        }
2312
2313}
2314
2315?>
Note: See TracBrowser for help on using the repository browser.