source: extensions/charlies_content/getid3/getid3/module.audio-video.riff.php @ 3544

Last change on this file since 3544 was 3544, checked in by vdigital, 15 years ago

Change: getid3 upgraded to -> 1.7.9

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