ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
getid3_riff Class Reference
+ Inheritance diagram for getid3_riff:
+ Collaboration diagram for getid3_riff:

Public Member Functions

 getid3_riff (&$fd, &$ThisFileInfo)
 
 RIFFcommentsParse (&$RIFFinfoArray, &$CommentsTargetArray)
 
 ParseRIFF (&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
 
 ParseRIFFdata (&$RIFFdata, &$ThisFileInfo)
 
 RIFFparseWAVEFORMATex ($WaveFormatExData)
 
 RIFFparseWavPackHeader ($WavPackChunkData, &$ThisFileInfo)
 
 RIFFwFormatTagLookup ($wFormatTag)
 
 RIFFfourccLookup ($fourcc)
 
 EitherEndian2Int (&$ThisFileInfo, $byteword, $signed=false)
 
 Analyze ()
 
 ParseRIFFAMV ($startoffset, $maxoffset)
 
 ParseRIFF ($startoffset, $maxoffset)
 
 ParseRIFFdata (&$RIFFdata)
 
 parseWavPackHeader ($WavPackChunkData)
 
- Public Member Functions inherited from getid3_handler
 __construct (getID3 $getid3, $call_module=null)
 
 Analyze ()
 
 AnalyzeString ($string)
 
 setStringMode ($string)
 
 saveAttachment ($name, $offset, $length, $image_mime=null)
 

Static Public Member Functions

static parseComments (&$RIFFinfoArray, &$CommentsTargetArray)
 
static parseWAVEFORMATex ($WaveFormatExData)
 
static ParseBITMAPINFOHEADER ($BITMAPINFOHEADER, $littleEndian=true)
 
static ParseDIVXTAG ($DIVXTAG, $raw=false)
 
static waveSNDMtagLookup ($tagshortname)
 
static wFormatTagLookup ($wFormatTag)
 
static fourccLookup ($fourcc)
 

Protected Attributes

 $container = 'riff'
 
- Protected Attributes inherited from getid3_handler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

Private Member Functions

 EitherEndian2Int ($byteword, $signed=false)
 

Additional Inherited Members

- Protected Member Functions inherited from getid3_handler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
 notice ($text)
 

Detailed Description

Definition at line 21 of file module.audio-video.riff.php.

Member Function Documentation

◆ Analyze()

getid3_riff::Analyze ( )

Reimplemented from getid3_handler.

Definition at line 34 of file module.audio-video.riff.php.

34 {
35 $info = &$this->getid3->info;
36
37 // initialize these values to an empty array, otherwise they default to NULL
38 // and you can't append array values to a NULL value
39 $info['riff'] = array('raw'=>array());
40
41 // Shortcuts
42 $thisfile_riff = &$info['riff'];
43 $thisfile_riff_raw = &$thisfile_riff['raw'];
44 $thisfile_audio = &$info['audio'];
45 $thisfile_video = &$info['video'];
46 $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
47 $thisfile_riff_audio = &$thisfile_riff['audio'];
48 $thisfile_riff_video = &$thisfile_riff['video'];
49
50 $Original['avdataoffset'] = $info['avdataoffset'];
51 $Original['avdataend'] = $info['avdataend'];
52
53 $this->fseek($info['avdataoffset']);
54 $RIFFheader = $this->fread(12);
55 $offset = $this->ftell();
56 $RIFFtype = substr($RIFFheader, 0, 4);
57 $RIFFsize = substr($RIFFheader, 4, 4);
58 $RIFFsubtype = substr($RIFFheader, 8, 4);
59
60 switch ($RIFFtype) {
61
62 case 'FORM': // AIFF, AIFC
63 //$info['fileformat'] = 'aiff';
64 $this->container = 'aiff';
65 $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
66 $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
67 break;
68
69 case 'RIFF': // AVI, WAV, etc
70 case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
71 case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
72 //$info['fileformat'] = 'riff';
73 $this->container = 'riff';
74 $thisfile_riff['header_size'] = $this->EitherEndian2Int($RIFFsize);
75 if ($RIFFsubtype == 'RMP3') {
76 // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
77 $RIFFsubtype = 'WAVE';
78 }
79 if ($RIFFsubtype != 'AMV ') {
80 // AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
81 // Handled separately in ParseRIFFAMV()
82 $thisfile_riff[$RIFFsubtype] = $this->ParseRIFF($offset, ($offset + $thisfile_riff['header_size'] - 4));
83 }
84 if (($info['avdataend'] - $info['filesize']) == 1) {
85 // LiteWave appears to incorrectly *not* pad actual output file
86 // to nearest WORD boundary so may appear to be short by one
87 // byte, in which case - skip warning
88 $info['avdataend'] = $info['filesize'];
89 }
90
91 $nextRIFFoffset = $Original['avdataoffset'] + 8 + $thisfile_riff['header_size']; // 8 = "RIFF" + 32-bit offset
92 while ($nextRIFFoffset < min($info['filesize'], $info['avdataend'])) {
93 try {
94 $this->fseek($nextRIFFoffset);
95 } catch (getid3_exception $e) {
96 if ($e->getCode() == 10) {
97 //$this->warning('RIFF parser: '.$e->getMessage());
98 $this->error('AVI extends beyond '.round(PHP_INT_MAX / 1073741824).'GB and PHP filesystem functions cannot read that far, playtime may be wrong');
99 $this->warning('[avdataend] value may be incorrect, multiple AVIX chunks may be present');
100 break;
101 } else {
102 throw $e;
103 }
104 }
105 $nextRIFFheader = $this->fread(12);
106 if ($nextRIFFoffset == ($info['avdataend'] - 1)) {
107 if (substr($nextRIFFheader, 0, 1) == "\x00") {
108 // RIFF padded to WORD boundary, we're actually already at the end
109 break;
110 }
111 }
112 $nextRIFFheaderID = substr($nextRIFFheader, 0, 4);
113 $nextRIFFsize = $this->EitherEndian2Int(substr($nextRIFFheader, 4, 4));
114 $nextRIFFtype = substr($nextRIFFheader, 8, 4);
115 $chunkdata = array();
116 $chunkdata['offset'] = $nextRIFFoffset + 8;
117 $chunkdata['size'] = $nextRIFFsize;
118 $nextRIFFoffset = $chunkdata['offset'] + $chunkdata['size'];
119
120 switch ($nextRIFFheaderID) {
121 case 'RIFF':
122 $chunkdata['chunks'] = $this->ParseRIFF($chunkdata['offset'] + 4, $nextRIFFoffset);
123 if (!isset($thisfile_riff[$nextRIFFtype])) {
124 $thisfile_riff[$nextRIFFtype] = array();
125 }
126 $thisfile_riff[$nextRIFFtype][] = $chunkdata;
127 break;
128
129 case 'AMV ':
130 unset($info['riff']);
131 $info['amv'] = $this->ParseRIFFAMV($chunkdata['offset'] + 4, $nextRIFFoffset);
132 break;
133
134 case 'JUNK':
135 // ignore
136 $thisfile_riff[$nextRIFFheaderID][] = $chunkdata;
137 break;
138
139 case 'IDVX':
140 $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunkdata['size']));
141 break;
142
143 default:
144 if ($info['filesize'] == ($chunkdata['offset'] - 8 + 128)) {
145 $DIVXTAG = $nextRIFFheader.$this->fread(128 - 12);
146 if (substr($DIVXTAG, -7) == 'DIVXTAG') {
147 // DIVXTAG is supposed to be inside an IDVX chunk in a LIST chunk, but some bad encoders just slap it on the end of a file
148 $this->warning('Found wrongly-structured DIVXTAG at offset '.($this->ftell() - 128).', parsing anyway');
149 $info['divxtag']['comments'] = self::ParseDIVXTAG($DIVXTAG);
150 break 2;
151 }
152 }
153 $this->warning('Expecting "RIFF|JUNK|IDVX" at '.$nextRIFFoffset.', found "'.$nextRIFFheaderID.'" ('.getid3_lib::PrintHexBytes($nextRIFFheaderID).') - skipping rest of file');
154 break 2;
155
156 }
157
158 }
159 if ($RIFFsubtype == 'WAVE') {
160 $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
161 }
162 break;
163
164 default:
165 $this->error('Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead');
166 //unset($info['fileformat']);
167 return false;
168 }
169
170 $streamindex = 0;
171 switch ($RIFFsubtype) {
172
173 // http://en.wikipedia.org/wiki/Wav
174 case 'WAVE':
175 $info['fileformat'] = 'wav';
176
177 if (empty($thisfile_audio['bitrate_mode'])) {
178 $thisfile_audio['bitrate_mode'] = 'cbr';
179 }
180 if (empty($thisfile_audio_dataformat)) {
181 $thisfile_audio_dataformat = 'wav';
182 }
183
184 if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
185 $info['avdataoffset'] = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
186 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff_WAVE['data'][0]['size'];
187 }
188 if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
189
190 $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
191 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
192 if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
193 $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
194 return false;
195 }
196 $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
197 unset($thisfile_riff_audio[$streamindex]['raw']);
198 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
199
200 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
201 if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
202 $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
203 }
204 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
205
206 if (empty($info['playtime_seconds'])) { // may already be set (e.g. DTS-WAV)
207 $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
208 }
209
210 $thisfile_audio['lossless'] = false;
211 if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
212 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
213
214 case 0x0001: // PCM
215 $thisfile_audio['lossless'] = true;
216 break;
217
218 case 0x2000: // AC-3
219 $thisfile_audio_dataformat = 'ac3';
220 break;
221
222 default:
223 // do nothing
224 break;
225
226 }
227 }
228 $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag'];
229 $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
230 $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless'];
231 $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat;
232 }
233
234 if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
235
236 // shortcuts
237 $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
238 $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array());
239 $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad'];
240 $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
241 $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
242
243 $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
244 $thisfile_riff_raw_rgad['nRadioRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 4, 2));
245 $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = $this->EitherEndian2Int(substr($rgadData, 6, 2));
246
247 $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
248 $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
249 $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
250 $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
251 $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
252 $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
253 $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
254 $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
255 $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
256 $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
257
258 $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
259 if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
260 $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
261 $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
262 $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
263 }
264 if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
265 $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
266 $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
267 $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
268 }
269 }
270
271 if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
272 $thisfile_riff_raw['fact']['NumberOfSamples'] = $this->EitherEndian2Int(substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
273
274 // This should be a good way of calculating exact playtime,
275 // but some sample files have had incorrect number of samples,
276 // so cannot use this method
277
278 // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
279 // $info['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
280 // }
281 }
282 if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
283 $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
284 }
285
286 if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
287 // shortcut
288 $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
289
290 $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256));
291 $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32));
292 $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32));
293 $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10);
294 $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8);
295 $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8));
296 $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1));
297 $thisfile_riff_WAVE_bext_0['reserved'] = substr($thisfile_riff_WAVE_bext_0['data'], 347, 254);
298 $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
299 if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
300 if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
301 list($dummy, $bext_timestamp['year'], $bext_timestamp['month'], $bext_timestamp['day']) = $matches_bext_date;
302 list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
303 $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
304 } else {
305 $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
306 }
307 } else {
308 $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
309 }
310 $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
311 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
312 }
313
314 if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
315 // shortcut
316 $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
317
318 $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
319 $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
320 if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
321 $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
322 $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
323 $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
324
325 $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
326 }
327 $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
328 $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
329 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
330 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
331 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
332 }
333
334 if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
335 // shortcut
336 $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
337
338 $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4);
339 $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64));
340 $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64));
341 $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
342 $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
343 $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
344 $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
345 $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
346 $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
347 $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8));
348 $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
349 $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8));
350 $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
351 $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
352 $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
353 $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true);
354 for ($i = 0; $i < 8; $i++) {
355 $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
356 $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));
357 }
358 $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024));
359 $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
360
361 $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
362 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title'];
363 }
364
365 if (isset($thisfile_riff_WAVE['SNDM'][0]['data'])) {
366 // SoundMiner metadata
367
368 // shortcuts
369 $thisfile_riff_WAVE_SNDM_0 = &$thisfile_riff_WAVE['SNDM'][0];
370 $thisfile_riff_WAVE_SNDM_0_data = &$thisfile_riff_WAVE_SNDM_0['data'];
371 $SNDM_startoffset = 0;
372 $SNDM_endoffset = $thisfile_riff_WAVE_SNDM_0['size'];
373
374 while ($SNDM_startoffset < $SNDM_endoffset) {
375 $SNDM_thisTagOffset = 0;
376 $SNDM_thisTagSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4));
377 $SNDM_thisTagOffset += 4;
378 $SNDM_thisTagKey = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 4);
379 $SNDM_thisTagOffset += 4;
380 $SNDM_thisTagDataSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
381 $SNDM_thisTagOffset += 2;
382 $SNDM_thisTagDataFlags = getid3_lib::BigEndian2Int(substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, 2));
383 $SNDM_thisTagOffset += 2;
384 $SNDM_thisTagDataText = substr($thisfile_riff_WAVE_SNDM_0_data, $SNDM_startoffset + $SNDM_thisTagOffset, $SNDM_thisTagDataSize);
385 $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
386
387 if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
388 $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
389 break;
390 } elseif ($SNDM_thisTagSize <= 0) {
391 $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
392 break;
393 }
394 $SNDM_startoffset += $SNDM_thisTagSize;
395
396 $thisfile_riff_WAVE_SNDM_0['parsed_raw'][$SNDM_thisTagKey] = $SNDM_thisTagDataText;
397 if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) {
398 $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
399 } else {
400 $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
401 }
402 }
403
404 $tagmapping = array(
405 'tracktitle'=>'title',
406 'category' =>'genre',
407 'cdtitle' =>'album',
408 'tracktitle'=>'title',
409 );
410 foreach ($tagmapping as $fromkey => $tokey) {
411 if (isset($thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey])) {
412 $thisfile_riff['comments'][$tokey][] = $thisfile_riff_WAVE_SNDM_0['parsed'][$fromkey];
413 }
414 }
415 }
416
417 if (isset($thisfile_riff_WAVE['iXML'][0]['data'])) {
418 // requires functions simplexml_load_string and get_object_vars
419 if ($parsedXML = getid3_lib::XML2array($thisfile_riff_WAVE['iXML'][0]['data'])) {
420 $thisfile_riff_WAVE['iXML'][0]['parsed'] = $parsedXML;
421 if (isset($parsedXML['SPEED']['MASTER_SPEED'])) {
422 @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['MASTER_SPEED']);
423 $thisfile_riff_WAVE['iXML'][0]['master_speed'] = $numerator / ($denominator ? $denominator : 1000);
424 }
425 if (isset($parsedXML['SPEED']['TIMECODE_RATE'])) {
426 @list($numerator, $denominator) = explode('/', $parsedXML['SPEED']['TIMECODE_RATE']);
427 $thisfile_riff_WAVE['iXML'][0]['timecode_rate'] = $numerator / ($denominator ? $denominator : 1000);
428 }
429 if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) {
430 $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0'));
431 $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE'];
432 $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600);
433 $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60);
434 $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60));
435 $f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate'];
436 $thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f);
437 $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f));
438 }
439 unset($parsedXML);
440 }
441 }
442
443
444
445 if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
446 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
447 $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
448 }
449
450 if (!empty($info['wavpack'])) {
451 $thisfile_audio_dataformat = 'wavpack';
452 $thisfile_audio['bitrate_mode'] = 'vbr';
453 $thisfile_audio['encoder'] = 'WavPack v'.$info['wavpack']['version'];
454
455 // Reset to the way it was - RIFF parsing will have messed this up
456 $info['avdataend'] = $Original['avdataend'];
457 $thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
458
459 $this->fseek($info['avdataoffset'] - 44);
460 $RIFFdata = $this->fread(44);
461 $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8;
462 $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
463
464 if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
465 $info['avdataend'] -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
466 $this->fseek($info['avdataend']);
467 $RIFFdata .= $this->fread($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
468 }
469
470 // move the data chunk after all other chunks (if any)
471 // so that the RIFF parser doesn't see EOF when trying
472 // to skip over the data chunk
473 $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
474 $getid3_riff = new getid3_riff($this->getid3);
475 $getid3_riff->ParseRIFFdata($RIFFdata);
476 unset($getid3_riff);
477 }
478
479 if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
480 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
481 case 0x0001: // PCM
482 if (!empty($info['ac3'])) {
483 // Dolby Digital WAV files masquerade as PCM-WAV, but they're not
484 $thisfile_audio['wformattag'] = 0x2000;
485 $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']);
486 $thisfile_audio['lossless'] = false;
487 $thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
488 $thisfile_audio['sample_rate'] = $info['ac3']['sample_rate'];
489 }
490 if (!empty($info['dts'])) {
491 // Dolby DTS files masquerade as PCM-WAV, but they're not
492 $thisfile_audio['wformattag'] = 0x2001;
493 $thisfile_audio['codec'] = self::wFormatTagLookup($thisfile_audio['wformattag']);
494 $thisfile_audio['lossless'] = false;
495 $thisfile_audio['bitrate'] = $info['dts']['bitrate'];
496 $thisfile_audio['sample_rate'] = $info['dts']['sample_rate'];
497 }
498 break;
499 case 0x08AE: // ClearJump LiteWave
500 $thisfile_audio['bitrate_mode'] = 'vbr';
501 $thisfile_audio_dataformat = 'litewave';
502
503 //typedef struct tagSLwFormat {
504 // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
505 // DWORD m_dwScale; // scale factor for lossy compression
506 // DWORD m_dwBlockSize; // number of samples in encoded blocks
507 // WORD m_wQuality; // alias for the scale factor
508 // WORD m_wMarkDistance; // distance between marks in bytes
509 // WORD m_wReserved;
510 //
511 // //following paramters are ignored if CF_FILESRC is not set
512 // DWORD m_dwOrgSize; // original file size in bytes
513 // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
514 // DWORD m_dwRiffChunkSize; // riff chunk size in the original file
515 //
516 // PCMWAVEFORMAT m_OrgWf; // original wave format
517 // }SLwFormat, *PSLwFormat;
518
519 // shortcut
520 $thisfile_riff['litewave']['raw'] = array();
521 $riff_litewave = &$thisfile_riff['litewave'];
522 $riff_litewave_raw = &$riff_litewave['raw'];
523
524 $flags = array(
525 'compression_method' => 1,
526 'compression_flags' => 1,
527 'm_dwScale' => 4,
528 'm_dwBlockSize' => 4,
529 'm_wQuality' => 2,
530 'm_wMarkDistance' => 2,
531 'm_wReserved' => 2,
532 'm_dwOrgSize' => 4,
533 'm_bFactExists' => 2,
534 'm_dwRiffChunkSize' => 4,
535 );
536 $litewave_offset = 18;
537 foreach ($flags as $flag => $length) {
538 $riff_litewave_raw[$flag] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], $litewave_offset, $length));
539 $litewave_offset += $length;
540 }
541
542 //$riff_litewave['quality_factor'] = intval(round((2000 - $riff_litewave_raw['m_dwScale']) / 20));
543 $riff_litewave['quality_factor'] = $riff_litewave_raw['m_wQuality'];
544
545 $riff_litewave['flags']['raw_source'] = ($riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
546 $riff_litewave['flags']['vbr_blocksize'] = ($riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
547 $riff_litewave['flags']['seekpoints'] = (bool) ($riff_litewave_raw['compression_flags'] & 0x04);
548
549 $thisfile_audio['lossless'] = (($riff_litewave_raw['m_wQuality'] == 100) ? true : false);
550 $thisfile_audio['encoder_options'] = '-q'.$riff_litewave['quality_factor'];
551 break;
552
553 default:
554 break;
555 }
556 }
557 if ($info['avdataend'] > $info['filesize']) {
558 switch (!empty($thisfile_audio_dataformat) ? $thisfile_audio_dataformat : '') {
559 case 'wavpack': // WavPack
560 case 'lpac': // LPAC
561 case 'ofr': // OptimFROG
562 case 'ofs': // OptimFROG DualStream
563 // lossless compressed audio formats that keep original RIFF headers - skip warning
564 break;
565
566 case 'litewave':
567 if (($info['avdataend'] - $info['filesize']) == 1) {
568 // LiteWave appears to incorrectly *not* pad actual output file
569 // to nearest WORD boundary so may appear to be short by one
570 // byte, in which case - skip warning
571 } else {
572 // Short by more than one byte, throw warning
573 $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
574 $info['avdataend'] = $info['filesize'];
575 }
576 break;
577
578 default:
579 if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) {
580 // output file appears to be incorrectly *not* padded to nearest WORD boundary
581 // Output less severe warning
582 $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
583 $info['avdataend'] = $info['filesize'];
584 } else {
585 // Short by more than one byte, throw warning
586 $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
587 $info['avdataend'] = $info['filesize'];
588 }
589 break;
590 }
591 }
592 if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) {
593 if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
594 $info['avdataend']--;
595 $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
596 }
597 }
598 if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
599 unset($thisfile_audio['bits_per_sample']);
600 if (!empty($info['ac3']['bitrate']) && ($info['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
601 $thisfile_audio['bitrate'] = $info['ac3']['bitrate'];
602 }
603 }
604 break;
605
606 // http://en.wikipedia.org/wiki/Audio_Video_Interleave
607 case 'AVI ':
608 $info['fileformat'] = 'avi';
609 $info['mime_type'] = 'video/avi';
610
611 $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
612 $thisfile_video['dataformat'] = 'avi';
613
614 if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
615 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
616 if (isset($thisfile_riff['AVIX'])) {
617 $info['avdataend'] = $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['offset'] + $thisfile_riff['AVIX'][(count($thisfile_riff['AVIX']) - 1)]['chunks']['movi']['size'];
618 } else {
619 $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
620 }
621 if ($info['avdataend'] > $info['filesize']) {
622 $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)';
623 $info['avdataend'] = $info['filesize'];
624 }
625 }
626
627 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['indx'])) {
628 //$bIndexType = array(
629 // 0x00 => 'AVI_INDEX_OF_INDEXES',
630 // 0x01 => 'AVI_INDEX_OF_CHUNKS',
631 // 0x80 => 'AVI_INDEX_IS_DATA',
632 //);
633 //$bIndexSubtype = array(
634 // 0x01 => array(
635 // 0x01 => 'AVI_INDEX_2FIELD',
636 // ),
637 //);
638 foreach ($thisfile_riff['AVI ']['hdrl']['strl']['indx'] as $streamnumber => $steamdataarray) {
639 $ahsisd = &$thisfile_riff['AVI ']['hdrl']['strl']['indx'][$streamnumber]['data'];
640
641 $thisfile_riff_raw['indx'][$streamnumber]['wLongsPerEntry'] = $this->EitherEndian2Int(substr($ahsisd, 0, 2));
642 $thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType'] = $this->EitherEndian2Int(substr($ahsisd, 2, 1));
643 $thisfile_riff_raw['indx'][$streamnumber]['bIndexType'] = $this->EitherEndian2Int(substr($ahsisd, 3, 1));
644 $thisfile_riff_raw['indx'][$streamnumber]['nEntriesInUse'] = $this->EitherEndian2Int(substr($ahsisd, 4, 4));
645 $thisfile_riff_raw['indx'][$streamnumber]['dwChunkId'] = substr($ahsisd, 8, 4);
646 $thisfile_riff_raw['indx'][$streamnumber]['dwReserved'] = $this->EitherEndian2Int(substr($ahsisd, 12, 4));
647
648 //$thisfile_riff_raw['indx'][$streamnumber]['bIndexType_name'] = $bIndexType[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']];
649 //$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType_name'] = $bIndexSubtype[$thisfile_riff_raw['indx'][$streamnumber]['bIndexType']][$thisfile_riff_raw['indx'][$streamnumber]['bIndexSubType']];
650
651 unset($ahsisd);
652 }
653 }
654 if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
655 $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
656
657 // shortcut
658 $thisfile_riff_raw['avih'] = array();
659 $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
660
661 $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L)
662 if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
663 $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
664 return false;
665 }
666
667 $flags = array(
668 'dwMaxBytesPerSec', // max. transfer rate
669 'dwPaddingGranularity', // pad to multiples of this size; normally 2K.
670 'dwFlags', // the ever-present flags
671 'dwTotalFrames', // # frames in file
672 'dwInitialFrames', //
673 'dwStreams', //
674 'dwSuggestedBufferSize', //
675 'dwWidth', //
676 'dwHeight', //
677 'dwScale', //
678 'dwRate', //
679 'dwStart', //
680 'dwLength', //
681 );
682 $avih_offset = 4;
683 foreach ($flags as $flag) {
684 $thisfile_riff_raw_avih[$flag] = $this->EitherEndian2Int(substr($avihData, $avih_offset, 4));
685 $avih_offset += 4;
686 }
687
688 $flags = array(
689 'hasindex' => 0x00000010,
690 'mustuseindex' => 0x00000020,
691 'interleaved' => 0x00000100,
692 'trustcktype' => 0x00000800,
693 'capturedfile' => 0x00010000,
694 'copyrighted' => 0x00020010,
695 );
696 foreach ($flags as $flag => $value) {
697 $thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
698 }
699
700 // shortcut
701 $thisfile_riff_video[$streamindex] = array();
702 $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
703
704 if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
705 $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
706 $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width'];
707 }
708 if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
709 $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
710 $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height'];
711 }
712 if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
713 $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
714 $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames'];
715 }
716
717 $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
718 $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
719 }
720 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
721 if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
722 for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
723 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
724 $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
725 $strhfccType = substr($strhData, 0, 4);
726
727 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
728 $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
729
730 // shortcut
731 $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
732
733 switch ($strhfccType) {
734 case 'auds':
735 $thisfile_audio['bitrate_mode'] = 'cbr';
736 $thisfile_audio_dataformat = 'wav';
737 if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
738 $streamindex = count($thisfile_riff_audio);
739 }
740
741 $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($strfData);
742 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
743
744 // shortcut
745 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
746 $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
747
748 if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
749 unset($thisfile_audio_streams_currentstream['bits_per_sample']);
750 }
751 $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
752 unset($thisfile_audio_streams_currentstream['raw']);
753
754 // shortcut
755 $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
756
757 unset($thisfile_riff_audio[$streamindex]['raw']);
758 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
759
760 $thisfile_audio['lossless'] = false;
761 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
762 case 0x0001: // PCM
763 $thisfile_audio_dataformat = 'wav';
764 $thisfile_audio['lossless'] = true;
765 break;
766
767 case 0x0050: // MPEG Layer 2 or Layer 1
768 $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
769 break;
770
771 case 0x0055: // MPEG Layer 3
772 $thisfile_audio_dataformat = 'mp3';
773 break;
774
775 case 0x00FF: // AAC
776 $thisfile_audio_dataformat = 'aac';
777 break;
778
779 case 0x0161: // Windows Media v7 / v8 / v9
780 case 0x0162: // Windows Media Professional v9
781 case 0x0163: // Windows Media Lossess v9
782 $thisfile_audio_dataformat = 'wma';
783 break;
784
785 case 0x2000: // AC-3
786 $thisfile_audio_dataformat = 'ac3';
787 break;
788
789 case 0x2001: // DTS
790 $thisfile_audio_dataformat = 'dts';
791 break;
792
793 default:
794 $thisfile_audio_dataformat = 'wav';
795 break;
796 }
797 $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat;
798 $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless'];
799 $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
800 break;
801
802
803 case 'iavs':
804 case 'vids':
805 // shortcut
806 $thisfile_riff_raw['strh'][$i] = array();
807 $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i];
808
809 $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType;
810 $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4);
811 $thisfile_riff_raw_strh_current['dwFlags'] = $this->EitherEndian2Int(substr($strhData, 8, 4)); // Contains AVITF_* flags
812 $thisfile_riff_raw_strh_current['wPriority'] = $this->EitherEndian2Int(substr($strhData, 12, 2));
813 $thisfile_riff_raw_strh_current['wLanguage'] = $this->EitherEndian2Int(substr($strhData, 14, 2));
814 $thisfile_riff_raw_strh_current['dwInitialFrames'] = $this->EitherEndian2Int(substr($strhData, 16, 4));
815 $thisfile_riff_raw_strh_current['dwScale'] = $this->EitherEndian2Int(substr($strhData, 20, 4));
816 $thisfile_riff_raw_strh_current['dwRate'] = $this->EitherEndian2Int(substr($strhData, 24, 4));
817 $thisfile_riff_raw_strh_current['dwStart'] = $this->EitherEndian2Int(substr($strhData, 28, 4));
818 $thisfile_riff_raw_strh_current['dwLength'] = $this->EitherEndian2Int(substr($strhData, 32, 4));
819 $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = $this->EitherEndian2Int(substr($strhData, 36, 4));
820 $thisfile_riff_raw_strh_current['dwQuality'] = $this->EitherEndian2Int(substr($strhData, 40, 4));
821 $thisfile_riff_raw_strh_current['dwSampleSize'] = $this->EitherEndian2Int(substr($strhData, 44, 4));
822 $thisfile_riff_raw_strh_current['rcFrame'] = $this->EitherEndian2Int(substr($strhData, 48, 4));
823
824 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
825 $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler'];
826 if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
827 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
828 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
829 }
830 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
831 $thisfile_video['pixel_aspect_ratio'] = (float) 1;
832 switch ($thisfile_riff_raw_strh_current['fccHandler']) {
833 case 'HFYU': // Huffman Lossless Codec
834 case 'IRAW': // Intel YUV Uncompressed
835 case 'YUY2': // Uncompressed YUV 4:2:2
836 $thisfile_video['lossless'] = true;
837 break;
838
839 default:
840 $thisfile_video['lossless'] = false;
841 break;
842 }
843
844 switch ($strhfccType) {
845 case 'vids':
846 $thisfile_riff_raw_strf_strhfccType_streamindex = self::ParseBITMAPINFOHEADER(substr($strfData, 0, 40), ($this->container == 'riff'));
847 $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
848
849 if ($thisfile_riff_video_current['codec'] == 'DV') {
850 $thisfile_riff_video_current['dv_type'] = 2;
851 }
852 break;
853
854 case 'iavs':
855 $thisfile_riff_video_current['dv_type'] = 1;
856 break;
857 }
858 break;
859
860 default:
861 $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
862 break;
863
864 }
865 }
866 }
867
868 if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
869
870 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
871 if (self::fourccLookup($thisfile_video['fourcc'])) {
872 $thisfile_riff_video_current['codec'] = self::fourccLookup($thisfile_video['fourcc']);
873 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
874 }
875
876 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
877 case 'HFYU': // Huffman Lossless Codec
878 case 'IRAW': // Intel YUV Uncompressed
879 case 'YUY2': // Uncompressed YUV 4:2:2
880 $thisfile_video['lossless'] = true;
881 //$thisfile_video['bits_per_sample'] = 24;
882 break;
883
884 default:
885 $thisfile_video['lossless'] = false;
886 //$thisfile_video['bits_per_sample'] = 24;
887 break;
888 }
889
890 }
891 }
892 }
893 }
894 break;
895
896
897 case 'AMV ':
898 $info['fileformat'] = 'amv';
899 $info['mime_type'] = 'video/amv';
900
901 $thisfile_video['bitrate_mode'] = 'vbr'; // it's MJPEG, presumably contant-quality encoding, thereby VBR
902 $thisfile_video['dataformat'] = 'mjpeg';
903 $thisfile_video['codec'] = 'mjpeg';
904 $thisfile_video['lossless'] = false;
905 $thisfile_video['bits_per_sample'] = 24;
906
907 $thisfile_audio['dataformat'] = 'adpcm';
908 $thisfile_audio['lossless'] = false;
909 break;
910
911
912 // http://en.wikipedia.org/wiki/CD-DA
913 case 'CDDA':
914 $info['fileformat'] = 'cda';
915 unset($info['mime_type']);
916
917 $thisfile_audio_dataformat = 'cda';
918
919 $info['avdataoffset'] = 44;
920
921 if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
922 // shortcut
923 $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
924
925 $thisfile_riff_CDDA_fmt_0['unknown1'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2));
926 $thisfile_riff_CDDA_fmt_0['track_num'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2));
927 $thisfile_riff_CDDA_fmt_0['disc_id'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4));
928 $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4));
929 $thisfile_riff_CDDA_fmt_0['playtime_frames'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
930 $thisfile_riff_CDDA_fmt_0['unknown6'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
931 $thisfile_riff_CDDA_fmt_0['unknown7'] = $this->EitherEndian2Int(substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
932
933 $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
934 $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
935 $info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
936 $info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
937
938 // hardcoded data for CD-audio
939 $thisfile_audio['lossless'] = true;
940 $thisfile_audio['sample_rate'] = 44100;
941 $thisfile_audio['channels'] = 2;
942 $thisfile_audio['bits_per_sample'] = 16;
943 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
944 $thisfile_audio['bitrate_mode'] = 'cbr';
945 }
946 break;
947
948 // http://en.wikipedia.org/wiki/AIFF
949 case 'AIFF':
950 case 'AIFC':
951 $info['fileformat'] = 'aiff';
952 $info['mime_type'] = 'audio/x-aiff';
953
954 $thisfile_audio['bitrate_mode'] = 'cbr';
955 $thisfile_audio_dataformat = 'aiff';
956 $thisfile_audio['lossless'] = true;
957
958 if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
959 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
960 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
961 if ($info['avdataend'] > $info['filesize']) {
962 if (($info['avdataend'] == ($info['filesize'] + 1)) && (($info['filesize'] % 2) == 1)) {
963 // structures rounded to 2-byte boundary, but dumb encoders
964 // forget to pad end of file to make this actually work
965 } else {
966 $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
967 }
968 $info['avdataend'] = $info['filesize'];
969 }
970 }
971
972 if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
973
974 // shortcut
975 $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
976
977 $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true);
978 $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false);
979 $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true);
980 $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10));
981
982 if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
983 $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
984 $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false);
985 $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
986 switch ($thisfile_riff_audio['codec_name']) {
987 case 'NONE':
988 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
989 $thisfile_audio['lossless'] = true;
990 break;
991
992 case '':
993 switch ($thisfile_riff_audio['codec_fourcc']) {
994 // http://developer.apple.com/qa/snd/snd07.html
995 case 'sowt':
996 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
997 $thisfile_audio['lossless'] = true;
998 break;
999
1000 case 'twos':
1001 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
1002 $thisfile_audio['lossless'] = true;
1003 break;
1004
1005 default:
1006 break;
1007 }
1008 break;
1009
1010 default:
1011 $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name'];
1012 $thisfile_audio['lossless'] = false;
1013 break;
1014 }
1015 }
1016
1017 $thisfile_audio['channels'] = $thisfile_riff_audio['channels'];
1018 if ($thisfile_riff_audio['bits_per_sample'] > 0) {
1019 $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
1020 }
1021 $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
1022 if ($thisfile_audio['sample_rate'] == 0) {
1023 $info['error'][] = 'Corrupted AIFF file: sample_rate == zero';
1024 return false;
1025 }
1026 $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
1027 }
1028
1029 if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
1030 $offset = 0;
1031 $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
1032 $offset += 2;
1033 for ($i = 0; $i < $CommentCount; $i++) {
1034 $info['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
1035 $offset += 4;
1036 $info['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
1037 $offset += 2;
1038 $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
1039 $offset += 2;
1040 $info['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
1041 $offset += $CommentLength;
1042
1043 $info['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($info['comments_raw'][$i]['timestamp']);
1044 $thisfile_riff['comments']['comment'][] = $info['comments_raw'][$i]['comment'];
1045 }
1046 }
1047
1048 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1049 foreach ($CommentsChunkNames as $key => $value) {
1050 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1051 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1052 }
1053 }
1054/*
1055 if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
1056 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1057 $getid3_temp = new getID3();
1058 $getid3_temp->openfile($this->getid3->filename);
1059 $getid3_id3v2 = new getid3_id3v2($getid3_temp);
1060 $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
1061 if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1062 $info['id3v2'] = $getid3_temp->info['id3v2'];
1063 }
1064 unset($getid3_temp, $getid3_id3v2);
1065 }
1066*/
1067 break;
1068
1069 // http://en.wikipedia.org/wiki/8SVX
1070 case '8SVX':
1071 $info['fileformat'] = '8svx';
1072 $info['mime_type'] = 'audio/8svx';
1073
1074 $thisfile_audio['bitrate_mode'] = 'cbr';
1075 $thisfile_audio_dataformat = '8svx';
1076 $thisfile_audio['bits_per_sample'] = 8;
1077 $thisfile_audio['channels'] = 1; // overridden below, if need be
1078
1079 if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
1080 $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
1081 $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
1082 if ($info['avdataend'] > $info['filesize']) {
1083 $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
1084 }
1085 }
1086
1087 if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
1088 // shortcut
1089 $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
1090
1091 $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4));
1092 $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4));
1093 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4));
1094 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
1095 $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
1096 $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
1097 $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
1098
1099 $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
1100
1101 switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
1102 case 0:
1103 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
1104 $thisfile_audio['lossless'] = true;
1105 $ActualBitsPerSample = 8;
1106 break;
1107
1108 case 1:
1109 $thisfile_audio['codec'] = 'Fibonacci-delta encoding';
1110 $thisfile_audio['lossless'] = false;
1111 $ActualBitsPerSample = 4;
1112 break;
1113
1114 default:
1115 $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
1116 break;
1117 }
1118 }
1119
1120 if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
1121 $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
1122 switch ($ChannelsIndex) {
1123 case 6: // Stereo
1124 $thisfile_audio['channels'] = 2;
1125 break;
1126
1127 case 2: // Left channel only
1128 case 4: // Right channel only
1129 $thisfile_audio['channels'] = 1;
1130 break;
1131
1132 default:
1133 $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
1134 break;
1135 }
1136
1137 }
1138
1139 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
1140 foreach ($CommentsChunkNames as $key => $value) {
1141 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
1142 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
1143 }
1144 }
1145
1146 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
1147 if (!empty($thisfile_audio['bitrate'])) {
1148 $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($thisfile_audio['bitrate'] / 8);
1149 }
1150 break;
1151
1152 case 'CDXA':
1153 $info['fileformat'] = 'vcd'; // Asume Video CD
1154 $info['mime_type'] = 'video/mpeg';
1155
1156 if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
1157 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
1158
1159 $getid3_temp = new getID3();
1160 $getid3_temp->openfile($this->getid3->filename);
1161 $getid3_mpeg = new getid3_mpeg($getid3_temp);
1162 $getid3_mpeg->Analyze();
1163 if (empty($getid3_temp->info['error'])) {
1164 $info['audio'] = $getid3_temp->info['audio'];
1165 $info['video'] = $getid3_temp->info['video'];
1166 $info['mpeg'] = $getid3_temp->info['mpeg'];
1167 $info['warning'] = $getid3_temp->info['warning'];
1168 }
1169 unset($getid3_temp, $getid3_mpeg);
1170 }
1171 break;
1172
1173
1174 default:
1175 $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
1176 //unset($info['fileformat']);
1177 }
1178
1179 switch ($RIFFsubtype) {
1180 case 'WAVE':
1181 case 'AIFF':
1182 case 'AIFC':
1183 $ID3v2_key_good = 'id3 ';
1184 $ID3v2_keys_bad = array('ID3 ', 'tag ');
1185 foreach ($ID3v2_keys_bad as $ID3v2_key_bad) {
1186 if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) {
1187 $thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad];
1188 $info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"';
1189 }
1190 }
1191
1192 if (isset($thisfile_riff[$RIFFsubtype]['id3 '])) {
1193 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1194
1195 $getid3_temp = new getID3();
1196 $getid3_temp->openfile($this->getid3->filename);
1197 $getid3_id3v2 = new getid3_id3v2($getid3_temp);
1198 $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
1199 if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
1200 $info['id3v2'] = $getid3_temp->info['id3v2'];
1201 }
1202 unset($getid3_temp, $getid3_id3v2);
1203 }
1204 break;
1205 }
1206
1207 if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
1208 $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
1209 }
1210 if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
1211 self::parseComments($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
1212 }
1213 if (isset($thisfile_riff['AVI ']['INFO']) && is_array($thisfile_riff['AVI ']['INFO'])) {
1214 self::parseComments($thisfile_riff['AVI ']['INFO'], $thisfile_riff['comments']);
1215 }
1216
1217 if (empty($thisfile_audio['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version'])) {
1218 $thisfile_audio['encoder'] = $info['mpeg']['audio']['LAME']['short_version'];
1219 }
1220
1221 if (!isset($info['playtime_seconds'])) {
1222 $info['playtime_seconds'] = 0;
1223 }
1224 if (isset($thisfile_riff_raw['strh'][0]['dwLength']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1225 // needed for >2GB AVIs where 'avih' chunk only lists number of frames in that chunk, not entire movie
1226 $info['playtime_seconds'] = $thisfile_riff_raw['strh'][0]['dwLength'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1227 } elseif (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
1228 $info['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
1229 }
1230
1231 if ($info['playtime_seconds'] > 0) {
1232 if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1233
1234 if (!isset($info['bitrate'])) {
1235 $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1236 }
1237
1238 } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
1239
1240 if (!isset($thisfile_audio['bitrate'])) {
1241 $thisfile_audio['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1242 }
1243
1244 } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
1245
1246 if (!isset($thisfile_video['bitrate'])) {
1247 $thisfile_video['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1248 }
1249
1250 }
1251 }
1252
1253
1254 if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($info['playtime_seconds'] > 0)) {
1255
1256 $info['bitrate'] = ((($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']) * 8);
1257 $thisfile_audio['bitrate'] = 0;
1258 $thisfile_video['bitrate'] = $info['bitrate'];
1259 foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
1260 $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
1261 $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
1262 }
1263 if ($thisfile_video['bitrate'] <= 0) {
1264 unset($thisfile_video['bitrate']);
1265 }
1266 if ($thisfile_audio['bitrate'] <= 0) {
1267 unset($thisfile_audio['bitrate']);
1268 }
1269 }
1270
1271 if (isset($info['mpeg']['audio'])) {
1272 $thisfile_audio_dataformat = 'mp'.$info['mpeg']['audio']['layer'];
1273 $thisfile_audio['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1274 $thisfile_audio['channels'] = $info['mpeg']['audio']['channels'];
1275 $thisfile_audio['bitrate'] = $info['mpeg']['audio']['bitrate'];
1276 $thisfile_audio['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1277 if (!empty($info['mpeg']['audio']['codec'])) {
1278 $thisfile_audio['codec'] = $info['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
1279 }
1280 if (!empty($thisfile_audio['streams'])) {
1281 foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
1282 if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
1283 $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate'];
1284 $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels'];
1285 $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
1286 $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
1287 $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec'];
1288 }
1289 }
1290 }
1291 $getid3_mp3 = new getid3_mp3($this->getid3);
1292 $thisfile_audio['encoder_options'] = $getid3_mp3->GuessEncoderOptions();
1293 unset($getid3_mp3);
1294 }
1295
1296
1297 if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
1298 switch ($thisfile_audio_dataformat) {
1299 case 'ac3':
1300 // ignore bits_per_sample
1301 break;
1302
1303 default:
1304 $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
1305 break;
1306 }
1307 }
1308
1309
1310 if (empty($thisfile_riff_raw)) {
1311 unset($thisfile_riff['raw']);
1312 }
1313 if (empty($thisfile_riff_audio)) {
1314 unset($thisfile_riff['audio']);
1315 }
1316 if (empty($thisfile_riff_video)) {
1317 unset($thisfile_riff['video']);
1318 }
1319
1320 return true;
1321 }
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
fread($bytes)
Definition: getid3.php:1685
warning($text)
Definition: getid3.php:1744
error($text)
Definition: getid3.php:1738
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
Dec2Bin($number)
Definition: getid3.lib.php:302
static XML2array($XMLstring)
Definition: getid3.lib.php:535
BigEndian2Float($byteword)
Definition: getid3.lib.php:159
RGADadjustmentLookup($rawadjustment, $signbit)
RGADoriginatorLookup($originatorcode)
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
array_merge_noclobber($array1, $array2)
Definition: getid3.lib.php:376
CastAsInt($floatnum)
Definition: getid3.lib.php:60
RGADnameLookup($namecode)
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
LittleEndian2Float($byteword)
Definition: getid3.lib.php:154
FixedPoint16_16($rawdata)
Definition: getid3.lib.php:454
DateMac2Unix($macdate)
Definition: getid3.lib.php:442
PrintHexBytes($string, $hex=true, $spaces=true, $htmlsafe=true)
Definition: getid3.lib.php:17
Bin2Dec($binstring, $signed=false)
Definition: getid3.lib.php:316
static parseComments(&$RIFFinfoArray, &$CommentsTargetArray)
static parseWAVEFORMATex($WaveFormatExData)
static wFormatTagLookup($wFormatTag)
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
static ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true)
static fourccLookup($fourcc)
static ParseDIVXTAG($DIVXTAG, $raw=false)
ParseRIFFAMV($startoffset, $maxoffset)
getid3_riff(&$fd, &$ThisFileInfo)
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)
$h
$info
Definition: example_052.php:80

References $h, $info, getid3_lib\array_merge_noclobber(), getid3_lib\BigEndian2Float(), getid3_lib\BigEndian2Int(), getid3_lib\Bin2Dec(), getid3_lib\CastAsInt(), getid3_lib\DateMac2Unix(), getid3_lib\Dec2Bin(), EitherEndian2Int(), getid3_handler\error(), getid3_lib\FixedPoint16_16(), fourccLookup(), getid3_handler\fread(), getid3_handler\fseek(), getid3_handler\ftell(), getid3_riff(), getid3_lib\IncludeDependency(), getid3_lib\LittleEndian2Float(), getid3_lib\LittleEndian2Int(), ParseBITMAPINFOHEADER(), parseComments(), ParseDIVXTAG(), ParseRIFF(), ParseRIFFAMV(), parseWAVEFORMATex(), getid3_lib\PrintHexBytes(), getid3_lib\RGADadjustmentLookup(), getid3_lib\RGADnameLookup(), getid3_lib\RGADoriginatorLookup(), getid3_handler\warning(), wFormatTagLookup(), and getid3_lib\XML2array().

+ Here is the call graph for this function:

◆ EitherEndian2Int() [1/2]

getid3_riff::EitherEndian2Int (   $byteword,
  $signed = false 
)
private

Definition at line 2579 of file module.audio-video.riff.php.

2579 {
2580 if ($this->container == 'riff') {
2581 return getid3_lib::LittleEndian2Int($byteword, $signed);
2582 }
2583 return getid3_lib::BigEndian2Int($byteword, false, $signed);
2584 }

References getid3_lib\BigEndian2Int(), and getid3_lib\LittleEndian2Int().

+ Here is the call graph for this function:

◆ EitherEndian2Int() [2/2]

getid3_riff::EitherEndian2Int ( $ThisFileInfo,
  $byteword,
  $signed = false 
)

Definition at line 1986 of file module.audio-video.riff.php.

1986 {
1987 if ($ThisFileInfo['fileformat'] == 'riff') {
1988 return getid3_lib::LittleEndian2Int($byteword, $signed);
1989 }
1990 return getid3_lib::BigEndian2Int($byteword, false, $signed);
1991 }

References getid3_lib\BigEndian2Int(), and getid3_lib\LittleEndian2Int().

Referenced by Analyze(), getid3_riff(), and ParseRIFF().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fourccLookup()

static getid3_riff::fourccLookup (   $fourcc)
static

This is not a comment!

swot        http://developer.apple.com/qa/snd/snd07.html
____        No Codec (____)
_BIT        BI_BITFIELDS (Raw RGB)
_JPG        JPEG compressed
_PNG        PNG compressed W3C/ISO/IEC (RFC-2083)
_RAW        Full Frames (Uncompressed)
_RGB        Raw RGB Bitmap
_RL4        RLE 4bpp RGB
_RL8        RLE 8bpp RGB
3IV1        3ivx MPEG-4 v1
3IV2        3ivx MPEG-4 v2
3IVX        3ivx MPEG-4
AASC        Autodesk Animator
ABYR        Kensington ?ABYR?
AEMI        Array Microsystems VideoONE MPEG1-I Capture
AFLC        Autodesk Animator FLC
AFLI        Autodesk Animator FLI
AMPG        Array Microsystems VideoONE MPEG
ANIM        Intel RDX (ANIM)
AP41        AngelPotion Definitive
ASV1        Asus Video v1
ASV2        Asus Video v2
ASVX        Asus Video 2.0 (audio)
AUR2        AuraVision Aura 2 Codec - YUV 4:2:2
AURA        AuraVision Aura 1 Codec - YUV 4:1:1
AVDJ        Independent JPEG Group\'s codec (AVDJ)
AVRN        Independent JPEG Group\'s codec (AVRN)
AYUV        4:4:4 YUV (AYUV)
AZPR        Quicktime Apple Video (AZPR)
BGR         Raw RGB32
BLZ0        Blizzard DivX MPEG-4
BTVC        Conexant Composite Video
BINK        RAD Game Tools Bink Video
BT20        Conexant Prosumer Video
BTCV        Conexant Composite Video Codec
BW10        Data Translation Broadway MPEG Capture
CC12        Intel YUV12
CDVC        Canopus DV
CFCC        Digital Processing Systems DPS Perception
CGDI        Microsoft Office 97 Camcorder Video
CHAM        Winnov Caviara Champagne
CJPG        Creative WebCam JPEG
CLJR        Cirrus Logic YUV 4:1:1
CMYK        Common Data Format in Printing (Colorgraph)
CPLA        Weitek 4:2:0 YUV Planar
CRAM        Microsoft Video 1 (CRAM)
cvid        Radius Cinepak
CVID        Radius Cinepak
CWLT        Microsoft Color WLT DIB
CYUV        Creative Labs YUV
CYUY        ATI YUV
D261        H.261
D263        H.263
DIB         Device Independent Bitmap
DIV1        FFmpeg OpenDivX
DIV2        Microsoft MPEG-4 v1/v2
DIV3        DivX ;-) MPEG-4 v3.x Low-Motion
DIV4        DivX ;-) MPEG-4 v3.x Fast-Motion
DIV5        DivX MPEG-4 v5.x
DIV6        DivX ;-) (MS MPEG-4 v3.x)
DIVX        DivX MPEG-4 v4 (OpenDivX / Project Mayo)
divx        DivX MPEG-4
DMB1        Matrox Rainbow Runner hardware MJPEG
DMB2        Paradigm MJPEG
DSVD        ?DSVD?
DUCK        Duck TrueMotion 1.0
DPS0        DPS/Leitch Reality Motion JPEG
DPSC        DPS/Leitch PAR Motion JPEG
DV25        Matrox DVCPRO codec
DV50        Matrox DVCPRO50 codec
DVC         IEC 61834 and SMPTE 314M (DVC/DV Video)
DVCP        IEC 61834 and SMPTE 314M (DVC/DV Video)
DVHD        IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
DVMA        Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
DVSL        IEC Standard DV compressed in SD (SDL)
DVAN        ?DVAN?
DVE2        InSoft DVE-2 Videoconferencing
dvsd        IEC 61834 and SMPTE 314M DVC/DV Video
DVSD        IEC 61834 and SMPTE 314M DVC/DV Video
DVX1        Lucent DVX1000SP Video Decoder
DVX2        Lucent DVX2000S Video Decoder
DVX3        Lucent DVX3000S Video Decoder
DX50        DivX v5
DXT1        Microsoft DirectX Compressed Texture (DXT1)
DXT2        Microsoft DirectX Compressed Texture (DXT2)
DXT3        Microsoft DirectX Compressed Texture (DXT3)
DXT4        Microsoft DirectX Compressed Texture (DXT4)
DXT5        Microsoft DirectX Compressed Texture (DXT5)
DXTC        Microsoft DirectX Compressed Texture (DXTC)
DXTn        Microsoft DirectX Compressed Texture (DXTn)
EM2V        Etymonix MPEG-2 I-frame (www.etymonix.com)
EKQ0        Elsa ?EKQ0?
ELK0        Elsa ?ELK0?
ESCP        Eidos Escape
ETV1        eTreppid Video ETV1
ETV2        eTreppid Video ETV2
ETVC        eTreppid Video ETVC
FLIC        Autodesk FLI/FLC Animation
FLV1        Sorenson Spark
FLV4        On2 TrueMotion VP6
FRWT        Darim Vision Forward Motion JPEG (www.darvision.com)
FRWU        Darim Vision Forward Uncompressed (www.darvision.com)
FLJP        D-Vision Field Encoded Motion JPEG
FPS1        FRAPS v1
FRWA        SoftLab-Nsk Forward Motion JPEG w/ alpha channel
FRWD        SoftLab-Nsk Forward Motion JPEG
FVF1        Iterated Systems Fractal Video Frame
GLZW        Motion LZW (gabest@freemail.hu)
GPEG        Motion JPEG (gabest@freemail.hu)
GWLT        Microsoft Greyscale WLT DIB
H260        Intel ITU H.260 Videoconferencing
H261        Intel ITU H.261 Videoconferencing
H262        Intel ITU H.262 Videoconferencing
H263        Intel ITU H.263 Videoconferencing
H264        Intel ITU H.264 Videoconferencing
H265        Intel ITU H.265 Videoconferencing
H266        Intel ITU H.266 Videoconferencing
H267        Intel ITU H.267 Videoconferencing
H268        Intel ITU H.268 Videoconferencing
H269        Intel ITU H.269 Videoconferencing
HFYU        Huffman Lossless Codec
HMCR        Rendition Motion Compensation Format (HMCR)
HMRR        Rendition Motion Compensation Format (HMRR)
I263        FFmpeg I263 decoder
IF09        Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
IUYV        Interlaced version of UYVY (www.leadtools.com)
IY41        Interlaced version of Y41P (www.leadtools.com)
IYU1        12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
IYU2        24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
IYUV        Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes)
i263        Intel ITU H.263 Videoconferencing (i263)
I420        Intel Indeo 4
IAN         Intel Indeo 4 (RDX)
ICLB        InSoft CellB Videoconferencing
IGOR        Power DVD
IJPG        Intergraph JPEG
ILVC        Intel Layered Video
ILVR        ITU-T H.263+
IPDV        I-O Data Device Giga AVI DV Codec
IR21        Intel Indeo 2.1
IRAW        Intel YUV Uncompressed
IV30        Intel Indeo 3.0
IV31        Intel Indeo 3.1
IV32        Ligos Indeo 3.2
IV33        Ligos Indeo 3.3
IV34        Ligos Indeo 3.4
IV35        Ligos Indeo 3.5
IV36        Ligos Indeo 3.6
IV37        Ligos Indeo 3.7
IV38        Ligos Indeo 3.8
IV39        Ligos Indeo 3.9
IV40        Ligos Indeo Interactive 4.0
IV41        Ligos Indeo Interactive 4.1
IV42        Ligos Indeo Interactive 4.2
IV43        Ligos Indeo Interactive 4.3
IV44        Ligos Indeo Interactive 4.4
IV45        Ligos Indeo Interactive 4.5
IV46        Ligos Indeo Interactive 4.6
IV47        Ligos Indeo Interactive 4.7
IV48        Ligos Indeo Interactive 4.8
IV49        Ligos Indeo Interactive 4.9
IV50        Ligos Indeo Interactive 5.0
JBYR        Kensington ?JBYR?
JPEG        Still Image JPEG DIB
JPGL        Pegasus Lossless Motion JPEG
KMVC        Team17 Software Karl Morton\'s Video Codec
LSVM        Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
LEAD        LEAD Video Codec
Ljpg        LEAD MJPEG Codec
MDVD        Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
MJPA        Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
MJPB        Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
MMES        Matrox MPEG-2 I-frame
MP2v        Microsoft S-Mpeg 4 version 1 (MP2v)
MP42        Microsoft S-Mpeg 4 version 2 (MP42)
MP43        Microsoft S-Mpeg 4 version 3 (MP43)
MP4S        Microsoft S-Mpeg 4 version 3 (MP4S)
MP4V        FFmpeg MPEG-4
MPG1        FFmpeg MPEG 1/2
MPG2        FFmpeg MPEG 1/2
MPG3        FFmpeg DivX ;-) (MS MPEG-4 v3)
MPG4        Microsoft MPEG-4
MPGI        Sigma Designs MPEG
MPNG        PNG images decoder
MSS1        Microsoft Windows Screen Video
MSZH        LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
M261        Microsoft H.261
M263        Microsoft H.263
M4S2        Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
m4s2        Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
MC12        ATI Motion Compensation Format (MC12)
MCAM        ATI Motion Compensation Format (MCAM)
MJ2C        Morgan Multimedia Motion JPEG2000
mJPG        IBM Motion JPEG w/ Huffman Tables
MJPG        Microsoft Motion JPEG DIB
MP42        Microsoft MPEG-4 (low-motion)
MP43        Microsoft MPEG-4 (fast-motion)
MP4S        Microsoft MPEG-4 (MP4S)
mp4s        Microsoft MPEG-4 (mp4s)
MPEG        Chromatic Research MPEG-1 Video I-Frame
MPG4        Microsoft MPEG-4 Video High Speed Compressor
MPGI        Sigma Designs MPEG
MRCA        FAST Multimedia Martin Regen Codec
MRLE        Microsoft Run Length Encoding
MSVC        Microsoft Video 1
MTX1        Matrox ?MTX1?
MTX2        Matrox ?MTX2?
MTX3        Matrox ?MTX3?
MTX4        Matrox ?MTX4?
MTX5        Matrox ?MTX5?
MTX6        Matrox ?MTX6?
MTX7        Matrox ?MTX7?
MTX8        Matrox ?MTX8?
MTX9        Matrox ?MTX9?
MV12        Motion Pixels Codec (old)
MWV1        Aware Motion Wavelets
nAVI        SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
NT00        NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
NUV1        NuppelVideo
NTN1        Nogatech Video Compression 1
NVS0        nVidia GeForce Texture (NVS0)
NVS1        nVidia GeForce Texture (NVS1)
NVS2        nVidia GeForce Texture (NVS2)
NVS3        nVidia GeForce Texture (NVS3)
NVS4        nVidia GeForce Texture (NVS4)
NVS5        nVidia GeForce Texture (NVS5)
NVT0        nVidia GeForce Texture (NVT0)
NVT1        nVidia GeForce Texture (NVT1)
NVT2        nVidia GeForce Texture (NVT2)
NVT3        nVidia GeForce Texture (NVT3)
NVT4        nVidia GeForce Texture (NVT4)
NVT5        nVidia GeForce Texture (NVT5)
PIXL        MiroXL, Pinnacle PCTV
PDVC        I-O Data Device Digital Video Capture DV codec
PGVV        Radius Video Vision
PHMO        IBM Photomotion
PIM1        MPEG Realtime (Pinnacle Cards)
PIM2        Pegasus Imaging ?PIM2?
PIMJ        Pegasus Imaging Lossless JPEG
PVEZ        Horizons Technology PowerEZ
PVMM        PacketVideo Corporation MPEG-4
PVW2        Pegasus Imaging Wavelet Compression
Q1.0        Q-Team\'s QPEG 1.0 (www.q-team.de)
Q1.1        Q-Team\'s QPEG 1.1 (www.q-team.de)
QPEG        Q-Team QPEG 1.0
qpeq        Q-Team QPEG 1.1
RGB         Raw BGR32
RGBA        Raw RGB w/ Alpha
RMP4        REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
ROQV        Id RoQ File Video Decoder
RPZA        Quicktime Apple Video (RPZA)
RUD0        Rududu video codec (http://rududu.ifrance.com/rududu/)
RV10        RealVideo 1.0 (aka RealVideo 5.0)
RV13        RealVideo 1.0 (RV13)
RV20        RealVideo G2
RV30        RealVideo 8
RV40        RealVideo 9
RGBT        Raw RGB w/ Transparency
RLE         Microsoft Run Length Encoder
RLE4        Run Length Encoded (4bpp, 16-color)
RLE8        Run Length Encoded (8bpp, 256-color)
RT21        Intel Indeo RealTime Video 2.1
rv20        RealVideo G2
rv30        RealVideo 8
RVX         Intel RDX (RVX )
SMC         Apple Graphics (SMC )
SP54        Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
SPIG        Radius Spigot
SVQ3        Sorenson Video 3 (Apple Quicktime 5)
s422        Tekram VideoCap C210 YUV 4:2:2
SDCC        Sun Communication Digital Camera Codec
SFMC        CrystalNet Surface Fitting Method
SMSC        Radius SMSC
SMSD        Radius SMSD
smsv        WorldConnect Wavelet Video
SPIG        Radius Spigot
SPLC        Splash Studios ACM Audio Codec (www.splashstudios.net)
SQZ2        Microsoft VXTreme Video Codec V2
STVA        ST Microelectronics CMOS Imager Data (Bayer)
STVB        ST Microelectronics CMOS Imager Data (Nudged Bayer)
STVC        ST Microelectronics CMOS Imager Data (Bunched)
STVX        ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
STVY        ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
SV10        Sorenson Video R1
SVQ1        Sorenson Video
T420        Toshiba YUV 4:2:0
TM2A        Duck TrueMotion Archiver 2.0 (www.duck.com)
TVJP        Pinnacle/Truevision Targa 2000 board (TVJP)
TVMJ        Pinnacle/Truevision Targa 2000 board (TVMJ)
TY0N        Tecomac Low-Bit Rate Codec (www.tecomac.com)
TY2C        Trident Decompression Driver
TLMS        TeraLogic Motion Intraframe Codec (TLMS)
TLST        TeraLogic Motion Intraframe Codec (TLST)
TM20        Duck TrueMotion 2.0
TM2X        Duck TrueMotion 2X
TMIC        TeraLogic Motion Intraframe Codec (TMIC)
TMOT        Horizons Technology TrueMotion S
tmot        Horizons TrueMotion Video Compression
TR20        Duck TrueMotion RealTime 2.0
TSCC        TechSmith Screen Capture Codec
TV10        Tecomac Low-Bit Rate Codec
TY2N        Trident ?TY2N?
U263        UB Video H.263/H.263+/H.263++ Decoder
UMP4        UB Video MPEG 4 (www.ubvideo.com)
UYNV        Nvidia UYVY packed 4:2:2
UYVP        Evans & Sutherland YCbCr 4:2:2 extended precision
UCOD        eMajix.com ClearVideo
ULTI        IBM Ultimotion
UYVY        UYVY packed 4:2:2
V261        Lucent VX2000S
VIFP        VFAPI Reader Codec (www.yks.ne.jp/~hori/)
VIV1        FFmpeg H263+ decoder
VIV2        Vivo H.263
VQC2        Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
VTLP        Alaris VideoGramPiX
VYU9        ATI YUV (VYU9)
VYUY        ATI YUV (VYUY)
V261        Lucent VX2000S
V422        Vitec Multimedia 24-bit YUV 4:2:2 Format
V655        Vitec Multimedia 16-bit YUV 4:2:2 Format
VCR1        ATI Video Codec 1
VCR2        ATI Video Codec 2
VCR3        ATI VCR 3.0
VCR4        ATI VCR 4.0
VCR5        ATI VCR 5.0
VCR6        ATI VCR 6.0
VCR7        ATI VCR 7.0
VCR8        ATI VCR 8.0
VCR9        ATI VCR 9.0
VDCT        Vitec Multimedia Video Maker Pro DIB
VDOM        VDOnet VDOWave
VDOW        VDOnet VDOLive (H.263)
VDTZ        Darim Vison VideoTizer YUV
VGPX        Alaris VideoGramPiX
VIDS        Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
VIVO        Vivo H.263 v2.00
vivo        Vivo H.263
VIXL        Miro/Pinnacle Video XL
VLV1        VideoLogic/PURE Digital Videologic Capture
VP30        On2 VP3.0
VP31        On2 VP3.1
VP6F        On2 TrueMotion VP6
VX1K        Lucent VX1000S Video Codec
VX2K        Lucent VX2000S Video Codec
VXSP        Lucent VX1000SP Video Codec
WBVC        Winbond W9960
WHAM        Microsoft Video 1 (WHAM)
WINX        Winnov Software Compression
WJPG        AverMedia Winbond JPEG
WMV1        Windows Media Video V7
WMV2        Windows Media Video V8
WMV3        Windows Media Video V9
WNV1        Winnov Hardware Compression
XYZP        Extended PAL format XYZ palette (www.riff.org)
x263        Xirlink H.263
XLV0        NetXL Video Decoder
XMPG        Xing MPEG (I-Frame only)
XVID        XviD MPEG-4 (www.xvid.org)
XXAN        ?XXAN?
YU92        Intel YUV (YU92)
YUNV        Nvidia Uncompressed YUV 4:2:2
YUVP        Extended PAL format YUV palette (www.riff.org)
Y211        YUV 2:1:1 Packed
Y411        YUV 4:1:1 Packed
Y41B        Weitek YUV 4:1:1 Planar
Y41P        Brooktree PC1 YUV 4:1:1 Packed
Y41T        Brooktree PC1 YUV 4:1:1 with transparency
Y42B        Weitek YUV 4:2:2 Planar
Y42T        Brooktree UYUV 4:2:2 with transparency
Y422        ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
Y800        Simple, single Y plane for monochrome images
Y8          Grayscale video
YC12        Intel YUV 12 codec
YUV8        Winnov Caviar YUV8
YUV9        Intel YUV9
YUY2        Uncompressed YUV 4:2:2
YUYV        Canopus YUV
YV12        YVU12 Planar
YVU9        Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
YVYU        YVYU 4:2:2 Packed
ZLIB        Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
ZPEG        Metheus Video Zipper

Definition at line 2185 of file module.audio-video.riff.php.

2185 {
2186
2187 $begin = __LINE__;
2188
2576 return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2577 }
EmbeddedLookup($key, $begin, $end, $file, $name)

References getid3_lib\EmbeddedLookup().

Referenced by getid3_asf\Analyze(), getid3_matroska\Analyze(), getid3_real\Analyze(), and Analyze().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getid3_riff()

getid3_riff::getid3_riff ( $fd,
$ThisFileInfo 
)

Definition at line 24 of file module.audio-video.riff.php.

24 {
25
26 // initialize these values to an empty array, otherwise they default to NULL
27 // and you can't append array values to a NULL value
28 $ThisFileInfo['riff'] = array('raw'=>array());
29
30 // Shortcuts
31 $thisfile_riff = &$ThisFileInfo['riff'];
32 $thisfile_riff_raw = &$thisfile_riff['raw'];
33 $thisfile_audio = &$ThisFileInfo['audio'];
34 $thisfile_video = &$ThisFileInfo['video'];
35 $thisfile_avdataoffset = &$ThisFileInfo['avdataoffset'];
36 $thisfile_avdataend = &$ThisFileInfo['avdataend'];
37 $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
38 $thisfile_riff_audio = &$thisfile_riff['audio'];
39 $thisfile_riff_video = &$thisfile_riff['video'];
40
41
42 $Original['avdataoffset'] = $thisfile_avdataoffset;
43 $Original['avdataend'] = $thisfile_avdataend;
44
45 fseek($fd, $thisfile_avdataoffset, SEEK_SET);
46 $RIFFheader = fread($fd, 12);
47 $RIFFsubtype = substr($RIFFheader, 8, 4);
48 switch (substr($RIFFheader, 0, 4)) {
49 case 'FORM':
50 $ThisFileInfo['fileformat'] = 'aiff';
51 $RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
52 $thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
53 $thisfile_riff['header_size'] = $RIFFheaderSize;
54 break;
55
56 case 'RIFF':
57 case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
58 case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
59 if ($RIFFsubtype == 'RMP3') {
60 // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
61 $RIFFsubtype = 'WAVE';
62 }
63
64 $ThisFileInfo['fileformat'] = 'riff';
65 $RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
66 $thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
67 $thisfile_riff['header_size'] = $RIFFheaderSize;
68 if ($RIFFsubtype == 'WAVE') {
69 $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
70 }
71 break;
72
73 default:
74 $ThisFileInfo['error'][] = 'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead';
75 unset($ThisFileInfo['fileformat']);
76 return false;
77 break;
78 }
79
80 $streamindex = 0;
81 switch ($RIFFsubtype) {
82 case 'WAVE':
83 if (empty($thisfile_audio['bitrate_mode'])) {
84 $thisfile_audio['bitrate_mode'] = 'cbr';
85 }
86 if (empty($thisfile_audio_dataformat)) {
87 $thisfile_audio_dataformat = 'wav';
88 }
89
90 if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
91 $thisfile_avdataoffset = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
92 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff_WAVE['data'][0]['size'];
93 }
94 if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
95
96 $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
97 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
98 if (@$thisfile_riff_audio[$streamindex]['bitrate'] == 0) {
99 $ThisFileInfo['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
100 return false;
101 }
102 $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
103 unset($thisfile_riff_audio[$streamindex]['raw']);
104 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
105
106 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
107 if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
108 $ThisFileInfo['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
109 }
110 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
111
112 $ThisFileInfo['playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio['bitrate']);
113
114 $thisfile_audio['lossless'] = false;
115 if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
116 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
117
118 case 0x0001: // PCM
119 $thisfile_audio['lossless'] = true;
120 break;
121
122 case 0x2000: // AC-3
123 $thisfile_audio_dataformat = 'ac3';
124 break;
125
126 default:
127 // do nothing
128 break;
129
130 }
131 }
132 $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag'];
133 $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
134 $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless'];
135 $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat;
136 }
137
138 if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
139
140 // shortcuts
141 $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
142 $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array());
143 $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad'];
144 $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
145 $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
146
147 $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
148 $thisfile_riff_raw_rgad['nRadioRgAdjust'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 4, 2));
149 $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 6, 2));
150
151 $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
152 $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
153 $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
154 $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
155 $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
156 $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
157 $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
158 $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
159 $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
160 $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
161
162 $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
163 if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
164 $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
165 $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
166 $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
167 }
168 if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
169 $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
170 $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
171 $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
172 }
173 }
174
175 if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
176 $thisfile_riff_raw['fact']['NumberOfSamples'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
177
178 // This should be a good way of calculating exact playtime,
179 // but some sample files have had incorrect number of samples,
180 // so cannot use this method
181
182 // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
183 // $ThisFileInfo['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
184 // }
185 }
186 if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
187 $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
188 }
189
190 if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
191 // shortcut
192 $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
193
194 $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256));
195 $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32));
196 $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32));
197 $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10);
198 $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8);
199 $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8));
200 $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1));
201 $thisfile_riff_WAVE_bext_0['reserved'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 347, 254));
202 $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
203
204 $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime(
205 substr($thisfile_riff_WAVE_bext_0['origin_time'], 0, 2),
206 substr($thisfile_riff_WAVE_bext_0['origin_time'], 3, 2),
207 substr($thisfile_riff_WAVE_bext_0['origin_time'], 6, 2),
208 substr($thisfile_riff_WAVE_bext_0['origin_date'], 5, 2),
209 substr($thisfile_riff_WAVE_bext_0['origin_date'], 8, 2),
210 substr($thisfile_riff_WAVE_bext_0['origin_date'], 0, 4));
211
212 $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
213 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
214 }
215
216 if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
217 // shortcut
218 $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
219
220 $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
221 $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
222 if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
223 $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
224 $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
225 $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
226
227 $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
228 }
229 $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
230 $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
231 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
232 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
233 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
234 }
235
236 if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
237 // shortcut
238 $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
239
240 $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4);
241 $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64));
242 $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64));
243 $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
244 $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
245 $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
246 $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
247 $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
248 $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
249 $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8));
250 $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
251 $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8));
252 $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
253 $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
254 $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
255 $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true);
256 for ($i = 0; $i < 8; $i++) {
257 $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
258 $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));
259 }
260 $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024));
261 $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
262
263 $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
264 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title'];
265 }
266
267 if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
268 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
269 $ThisFileInfo['playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio['bitrate']);
270 }
271
272 if (!empty($ThisFileInfo['wavpack'])) {
273 $thisfile_audio_dataformat = 'wavpack';
274 $thisfile_audio['bitrate_mode'] = 'vbr';
275 $thisfile_audio['encoder'] = 'WavPack v'.$ThisFileInfo['wavpack']['version'];
276
277 // Reset to the way it was - RIFF parsing will have messed this up
278 $thisfile_avdataend = $Original['avdataend'];
279 $thisfile_audio['bitrate'] = (($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $ThisFileInfo['playtime_seconds'];
280
281 fseek($fd, $thisfile_avdataoffset - 44, SEEK_SET);
282 $RIFFdata = fread($fd, 44);
283 $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8;
284 $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
285
286 if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
287 $thisfile_avdataend -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
288 fseek($fd, $thisfile_avdataend, SEEK_SET);
289 $RIFFdata .= fread($fd, $OrignalRIFFheaderSize - $OrignalRIFFdataSize);
290 }
291
292 // move the data chunk after all other chunks (if any)
293 // so that the RIFF parser doesn't see EOF when trying
294 // to skip over the data chunk
295 $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
296 getid3_riff::ParseRIFFdata($RIFFdata, $ThisFileInfo);
297 }
298
299 if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
300 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
301 case 0x08AE: // ClearJump LiteWave
302 $thisfile_audio['bitrate_mode'] = 'vbr';
303 $thisfile_audio_dataformat = 'litewave';
304
305 //typedef struct tagSLwFormat {
306 // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
307 // DWORD m_dwScale; // scale factor for lossy compression
308 // DWORD m_dwBlockSize; // number of samples in encoded blocks
309 // WORD m_wQuality; // alias for the scale factor
310 // WORD m_wMarkDistance; // distance between marks in bytes
311 // WORD m_wReserved;
312 //
313 // //following paramters are ignored if CF_FILESRC is not set
314 // DWORD m_dwOrgSize; // original file size in bytes
315 // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
316 // DWORD m_dwRiffChunkSize; // riff chunk size in the original file
317 //
318 // PCMWAVEFORMAT m_OrgWf; // original wave format
319 // }SLwFormat, *PSLwFormat;
320
321 // shortcut
322 $thisfile_riff['litewave']['raw'] = array();
323 $thisfile_riff_litewave = &$thisfile_riff['litewave'];
324 $thisfile_riff_litewave_raw = &$thisfile_riff_litewave['raw'];
325
326 $thisfile_riff_litewave_raw['compression_method'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 18, 1));
327 $thisfile_riff_litewave_raw['compression_flags'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 19, 1));
328 $thisfile_riff_litewave_raw['m_dwScale'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 20, 4));
329 $thisfile_riff_litewave_raw['m_dwBlockSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 24, 4));
330 $thisfile_riff_litewave_raw['m_wQuality'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 28, 2));
331 $thisfile_riff_litewave_raw['m_wMarkDistance'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 30, 2));
332 $thisfile_riff_litewave_raw['m_wReserved'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 32, 2));
333 $thisfile_riff_litewave_raw['m_dwOrgSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 34, 4));
334 $thisfile_riff_litewave_raw['m_bFactExists'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 38, 2));
335 $thisfile_riff_litewave_raw['m_dwRiffChunkSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 40, 4));
336
337 //$thisfile_riff_litewave['quality_factor'] = intval(round((2000 - $thisfile_riff_litewave_raw['m_dwScale']) / 20));
338 $thisfile_riff_litewave['quality_factor'] = $thisfile_riff_litewave_raw['m_wQuality'];
339
340 $thisfile_riff_litewave['flags']['raw_source'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
341 $thisfile_riff_litewave['flags']['vbr_blocksize'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
342 $thisfile_riff_litewave['flags']['seekpoints'] = (bool) ($thisfile_riff_litewave_raw['compression_flags'] & 0x04);
343
344 $thisfile_audio['lossless'] = (($thisfile_riff_litewave_raw['m_wQuality'] == 100) ? true : false);
345 $thisfile_audio['encoder_options'] = '-q'.$thisfile_riff_litewave['quality_factor'];
346 break;
347
348 default:
349 break;
350 }
351 }
352 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
353 switch (@$thisfile_audio_dataformat) {
354 case 'wavpack': // WavPack
355 case 'lpac': // LPAC
356 case 'ofr': // OptimFROG
357 case 'ofs': // OptimFROG DualStream
358 // lossless compressed audio formats that keep original RIFF headers - skip warning
359 break;
360
361 case 'litewave':
362 if (($thisfile_avdataend - $ThisFileInfo['filesize']) == 1) {
363 // LiteWave appears to incorrectly *not* pad actual output file
364 // to nearest WORD boundary so may appear to be short by one
365 // byte, in which case - skip warning
366 } else {
367 // Short by more than one byte, throw warning
368 $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)';
369 $thisfile_avdataend = $ThisFileInfo['filesize'];
370 }
371 break;
372
373 default:
374 if ((($thisfile_avdataend - $ThisFileInfo['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($ThisFileInfo['filesize'] - $thisfile_avdataoffset) % 2) == 1)) {
375 // output file appears to be incorrectly *not* padded to nearest WORD boundary
376 // Output less severe warning
377 $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)';
378 $thisfile_avdataend = $ThisFileInfo['filesize'];
379 break;
380 }
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 break;
385 }
386 }
387 if (!empty($ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'])) {
388 if ((($thisfile_avdataend - $thisfile_avdataoffset) - $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
389 $thisfile_avdataend--;
390 $ThisFileInfo['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
391 }
392 }
393 if (@$thisfile_audio_dataformat == 'ac3') {
394 unset($thisfile_audio['bits_per_sample']);
395 if (!empty($ThisFileInfo['ac3']['bitrate']) && ($ThisFileInfo['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
396 $thisfile_audio['bitrate'] = $ThisFileInfo['ac3']['bitrate'];
397 }
398 }
399 break;
400
401 case 'AVI ':
402 $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
403 $thisfile_video['dataformat'] = 'avi';
404 $ThisFileInfo['mime_type'] = 'video/avi';
405
406 if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
407 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
408 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['movi']['size'];
409 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
410 $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)';
411 $thisfile_avdataend = $ThisFileInfo['filesize'];
412 }
413 }
414
415 if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
416 $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
417
418 // shortcut
419 $thisfile_riff_raw['avih'] = array();
420 $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
421
422 $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 0, 4)); // frame display rate (or 0L)
423 if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
424 $ThisFileInfo['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
425 return false;
426 }
427 $thisfile_riff_raw_avih['dwMaxBytesPerSec'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 4, 4)); // max. transfer rate
428 $thisfile_riff_raw_avih['dwPaddingGranularity'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 8, 4)); // pad to multiples of this size; normally 2K.
429 $thisfile_riff_raw_avih['dwFlags'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 12, 4)); // the ever-present flags
430 $thisfile_riff_raw_avih['dwTotalFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 16, 4)); // # frames in file
431 $thisfile_riff_raw_avih['dwInitialFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 20, 4));
432 $thisfile_riff_raw_avih['dwStreams'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 24, 4));
433 $thisfile_riff_raw_avih['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 28, 4));
434 $thisfile_riff_raw_avih['dwWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 32, 4));
435 $thisfile_riff_raw_avih['dwHeight'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 36, 4));
436 $thisfile_riff_raw_avih['dwScale'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 40, 4));
437 $thisfile_riff_raw_avih['dwRate'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 44, 4));
438 $thisfile_riff_raw_avih['dwStart'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 48, 4));
439 $thisfile_riff_raw_avih['dwLength'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 52, 4));
440
441 $thisfile_riff_raw_avih['flags']['hasindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000010);
442 $thisfile_riff_raw_avih['flags']['mustuseindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000020);
443 $thisfile_riff_raw_avih['flags']['interleaved'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000100);
444 $thisfile_riff_raw_avih['flags']['trustcktype'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000800);
445 $thisfile_riff_raw_avih['flags']['capturedfile'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00010000);
446 $thisfile_riff_raw_avih['flags']['copyrighted'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00020010);
447
448 // shortcut
449 $thisfile_riff_video[$streamindex] = array();
450 $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
451
452 if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
453 $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
454 $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width'];
455 }
456 if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
457 $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
458 $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height'];
459 }
460 if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
461 $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
462 $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames'];
463 }
464
465 $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
466 $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
467 }
468 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
469 if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
470 for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
471 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
472 $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
473 $strhfccType = substr($strhData, 0, 4);
474
475 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
476 $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
477
478 // shortcut
479 $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
480
481 switch ($strhfccType) {
482 case 'auds':
483 $thisfile_audio['bitrate_mode'] = 'cbr';
484 $thisfile_audio_dataformat = 'wav';
485 if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
486 $streamindex = count($thisfile_riff_audio);
487 }
488
489 $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($strfData);
490 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
491
492 // shortcut
493 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
494 $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
495
496 if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
497 unset($thisfile_audio_streams_currentstream['bits_per_sample']);
498 }
499 $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
500 unset($thisfile_audio_streams_currentstream['raw']);
501
502 // shortcut
503 $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
504
505 unset($thisfile_riff_audio[$streamindex]['raw']);
506 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
507
508 $thisfile_audio['lossless'] = false;
509 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
510 case 0x0001: // PCM
511 $thisfile_audio_dataformat = 'wav';
512 $thisfile_audio['lossless'] = true;
513 break;
514
515 case 0x0050: // MPEG Layer 2 or Layer 1
516 $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
517 break;
518
519 case 0x0055: // MPEG Layer 3
520 $thisfile_audio_dataformat = 'mp3';
521 break;
522
523 case 0x00FF: // AAC
524 $thisfile_audio_dataformat = 'aac';
525 break;
526
527 case 0x0161: // Windows Media v7 / v8 / v9
528 case 0x0162: // Windows Media Professional v9
529 case 0x0163: // Windows Media Lossess v9
530 $thisfile_audio_dataformat = 'wma';
531 break;
532
533 case 0x2000: // AC-3
534 $thisfile_audio_dataformat = 'ac3';
535 break;
536
537 case 0x2001: // DTS
538 $thisfile_audio_dataformat = 'dts';
539 break;
540
541 default:
542 $thisfile_audio_dataformat = 'wav';
543 break;
544 }
545 $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat;
546 $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless'];
547 $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
548 break;
549
550
551 case 'iavs':
552 case 'vids':
553 // shortcut
554 $thisfile_riff_raw['strh'][$i] = array();
555 $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i];
556
557 $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType;
558 $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4);
559 $thisfile_riff_raw_strh_current['dwFlags'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 8, 4)); // Contains AVITF_* flags
560 $thisfile_riff_raw_strh_current['wPriority'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 12, 2));
561 $thisfile_riff_raw_strh_current['wLanguage'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 14, 2));
562 $thisfile_riff_raw_strh_current['dwInitialFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 16, 4));
563 $thisfile_riff_raw_strh_current['dwScale'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 20, 4));
564 $thisfile_riff_raw_strh_current['dwRate'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 24, 4));
565 $thisfile_riff_raw_strh_current['dwStart'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 28, 4));
566 $thisfile_riff_raw_strh_current['dwLength'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 32, 4));
567 $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 36, 4));
568 $thisfile_riff_raw_strh_current['dwQuality'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 40, 4));
569 $thisfile_riff_raw_strh_current['dwSampleSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 44, 4));
570 $thisfile_riff_raw_strh_current['rcFrame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 48, 4));
571
572 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
573 $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler'];
574 if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
575 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
576 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
577 }
578 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
579 $thisfile_video['pixel_aspect_ratio'] = (float) 1;
580 switch ($thisfile_riff_raw_strh_current['fccHandler']) {
581 case 'HFYU': // Huffman Lossless Codec
582 case 'IRAW': // Intel YUV Uncompressed
583 case 'YUY2': // Uncompressed YUV 4:2:2
584 $thisfile_video['lossless'] = true;
585 break;
586
587 default:
588 $thisfile_video['lossless'] = false;
589 break;
590 }
591
592 switch ($strhfccType) {
593 case 'vids':
594 $thisfile_riff_raw_strf_strhfccType_streamindex['biSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
595 $thisfile_riff_raw_strf_strhfccType_streamindex['biWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 4, 4)); // width of the bitmap in pixels
596 $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
597 $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
598 $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 14, 2)); // Specifies the number of bits per pixels
599 $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'] = substr($strfData, 16, 4); //
600 $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)
601 $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
602 $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
603 $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
604 $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
605
606 $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
607
608 if ($thisfile_riff_video_current['codec'] == 'DV') {
609 $thisfile_riff_video_current['dv_type'] = 2;
610 }
611 break;
612
613 case 'iavs':
614 $thisfile_riff_video_current['dv_type'] = 1;
615 break;
616 }
617 break;
618
619 default:
620 $ThisFileInfo['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
621 break;
622
623 }
624 }
625 }
626
627 if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
628
629 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
630 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
631 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
632
633 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
634 case 'HFYU': // Huffman Lossless Codec
635 case 'IRAW': // Intel YUV Uncompressed
636 case 'YUY2': // Uncompressed YUV 4:2:2
637 $thisfile_video['lossless'] = true;
638 $thisfile_video['bits_per_sample'] = 24;
639 break;
640
641 default:
642 $thisfile_video['lossless'] = false;
643 $thisfile_video['bits_per_sample'] = 24;
644 break;
645 }
646
647 }
648 }
649 }
650 }
651 break;
652
653 case 'CDDA':
654 $thisfile_audio['bitrate_mode'] = 'cbr';
655 $thisfile_audio_dataformat = 'cda';
656 $thisfile_audio['lossless'] = true;
657 unset($ThisFileInfo['mime_type']);
658
659 $thisfile_avdataoffset = 44;
660
661 if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
662 // shortcut
663 $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
664
665 $thisfile_riff_CDDA_fmt_0['unknown1'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2));
666 $thisfile_riff_CDDA_fmt_0['track_num'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2));
667 $thisfile_riff_CDDA_fmt_0['disc_id'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4));
668 $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4));
669 $thisfile_riff_CDDA_fmt_0['playtime_frames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
670 $thisfile_riff_CDDA_fmt_0['unknown6'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
671 $thisfile_riff_CDDA_fmt_0['unknown7'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
672
673 $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
674 $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
675 $ThisFileInfo['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
676 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
677
678 // hardcoded data for CD-audio
679 $thisfile_audio['sample_rate'] = 44100;
680 $thisfile_audio['channels'] = 2;
681 $thisfile_audio['bits_per_sample'] = 16;
682 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
683 $thisfile_audio['bitrate_mode'] = 'cbr';
684 }
685 break;
686
687
688 case 'AIFF':
689 case 'AIFC':
690 $thisfile_audio['bitrate_mode'] = 'cbr';
691 $thisfile_audio_dataformat = 'aiff';
692 $thisfile_audio['lossless'] = true;
693 $ThisFileInfo['mime_type'] = 'audio/x-aiff';
694
695 if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
696 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
697 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
698 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
699 if (($thisfile_avdataend == ($ThisFileInfo['filesize'] + 1)) && (($ThisFileInfo['filesize'] % 2) == 1)) {
700 // structures rounded to 2-byte boundary, but dumb encoders
701 // forget to pad end of file to make this actually work
702 } else {
703 $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' bytes found';
704 }
705 $thisfile_avdataend = $ThisFileInfo['filesize'];
706 }
707 }
708
709 if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
710
711 // shortcut
712 $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
713
714 $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true);
715 $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false);
716 $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true);
717 $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10));
718
719 if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
720 $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
721 $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false);
722 $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
723 switch ($thisfile_riff_audio['codec_name']) {
724 case 'NONE':
725 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
726 $thisfile_audio['lossless'] = true;
727 break;
728
729 case '':
730 switch ($thisfile_riff_audio['codec_fourcc']) {
731 // http://developer.apple.com/qa/snd/snd07.html
732 case 'sowt':
733 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
734 $thisfile_audio['lossless'] = true;
735 break;
736
737 case 'twos':
738 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
739 $thisfile_audio['lossless'] = true;
740 break;
741
742 default:
743 break;
744 }
745 break;
746
747 default:
748 $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name'];
749 $thisfile_audio['lossless'] = false;
750 break;
751 }
752 }
753
754 $thisfile_audio['channels'] = $thisfile_riff_audio['channels'];
755 if ($thisfile_riff_audio['bits_per_sample'] > 0) {
756 $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
757 }
758 $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
759 if ($thisfile_audio['sample_rate'] == 0) {
760 $ThisFileInfo['error'][] = 'Corrupted AIFF file: sample_rate == zero';
761 return false;
762 }
763 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
764 }
765
766 if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
767 $offset = 0;
768 $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
769 $offset += 2;
770 for ($i = 0; $i < $CommentCount; $i++) {
771 $ThisFileInfo['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
772 $offset += 4;
773 $ThisFileInfo['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
774 $offset += 2;
775 $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
776 $offset += 2;
777 $ThisFileInfo['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
778 $offset += $CommentLength;
779
780 $ThisFileInfo['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($ThisFileInfo['comments_raw'][$i]['timestamp']);
781 $thisfile_riff['comments']['comment'][] = $ThisFileInfo['comments_raw'][$i]['comment'];
782 }
783 }
784
785 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
786 foreach ($CommentsChunkNames as $key => $value) {
787 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
788 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
789 }
790 }
791 break;
792
793 case '8SVX':
794 $thisfile_audio['bitrate_mode'] = 'cbr';
795 $thisfile_audio_dataformat = '8svx';
796 $thisfile_audio['bits_per_sample'] = 8;
797 $thisfile_audio['channels'] = 1; // overridden below, if need be
798 $ThisFileInfo['mime_type'] = 'audio/x-aiff';
799
800 if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
801 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
802 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
803 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
804 $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' bytes found';
805 }
806 }
807
808 if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
809 // shortcut
810 $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
811
812 $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4));
813 $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4));
814 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4));
815 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
816 $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
817 $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
818 $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
819
820 $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
821
822 switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
823 case 0:
824 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
825 $thisfile_audio['lossless'] = true;
826 $ActualBitsPerSample = 8;
827 break;
828
829 case 1:
830 $thisfile_audio['codec'] = 'Fibonacci-delta encoding';
831 $thisfile_audio['lossless'] = false;
832 $ActualBitsPerSample = 4;
833 break;
834
835 default:
836 $ThisFileInfo['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
837 break;
838 }
839 }
840
841 if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
842 $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
843 switch ($ChannelsIndex) {
844 case 6: // Stereo
845 $thisfile_audio['channels'] = 2;
846 break;
847
848 case 2: // Left channel only
849 case 4: // Right channel only
850 $thisfile_audio['channels'] = 1;
851 break;
852
853 default:
854 $ThisFileInfo['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
855 break;
856 }
857
858 }
859
860 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
861 foreach ($CommentsChunkNames as $key => $value) {
862 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
863 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
864 }
865 }
866
867 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
868 if (!empty($thisfile_audio['bitrate'])) {
869 $ThisFileInfo['playtime_seconds'] = ($thisfile_avdataend - $thisfile_avdataoffset) / ($thisfile_audio['bitrate'] / 8);
870 }
871 break;
872
873
874 case 'CDXA':
875 $ThisFileInfo['mime_type'] = 'video/mpeg';
876 if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
877 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
878 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
879 $dummy = $ThisFileInfo;
880 $dummy['error'] = array();
881 $mpeg_scanner = new getid3_mpeg($fd, $dummy);
882 if (empty($dummy['error'])) {
883 $ThisFileInfo['audio'] = $dummy['audio'];
884 $ThisFileInfo['video'] = $dummy['video'];
885 $ThisFileInfo['mpeg'] = $dummy['mpeg'];
886 $ThisFileInfo['warning'] = $dummy['warning'];
887 }
888 }
889 }
890 break;
891
892
893 default:
894 $ThisFileInfo['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
895 unset($ThisFileInfo['fileformat']);
896 break;
897 }
898
899 if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
900 $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
901 }
902 if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
903 $this->RIFFcommentsParse($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
904 }
905
906 if (empty($thisfile_audio['encoder']) && !empty($ThisFileInfo['mpeg']['audio']['LAME']['short_version'])) {
907 $thisfile_audio['encoder'] = $ThisFileInfo['mpeg']['audio']['LAME']['short_version'];
908 }
909
910 if (!isset($ThisFileInfo['playtime_seconds'])) {
911 $ThisFileInfo['playtime_seconds'] = 0;
912 }
913 if (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
914 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
915 }
916
917 if ($ThisFileInfo['playtime_seconds'] > 0) {
918 if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
919
920 if (!isset($ThisFileInfo['bitrate'])) {
921 $ThisFileInfo['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
922 }
923
924 } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
925
926 if (!isset($thisfile_audio['bitrate'])) {
927 $thisfile_audio['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
928 }
929
930 } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
931
932 if (!isset($thisfile_video['bitrate'])) {
933 $thisfile_video['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
934 }
935
936 }
937 }
938
939
940 if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($ThisFileInfo['playtime_seconds'] > 0)) {
941
942 $ThisFileInfo['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
943 $thisfile_audio['bitrate'] = 0;
944 $thisfile_video['bitrate'] = $ThisFileInfo['bitrate'];
945 foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
946 $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
947 $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
948 }
949 if ($thisfile_video['bitrate'] <= 0) {
950 unset($thisfile_video['bitrate']);
951 }
952 if ($thisfile_audio['bitrate'] <= 0) {
953 unset($thisfile_audio['bitrate']);
954 }
955 }
956
957 if (isset($ThisFileInfo['mpeg']['audio'])) {
958 $thisfile_audio_dataformat = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
959 $thisfile_audio['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate'];
960 $thisfile_audio['channels'] = $ThisFileInfo['mpeg']['audio']['channels'];
961 $thisfile_audio['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
962 $thisfile_audio['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
963 if (!empty($ThisFileInfo['mpeg']['audio']['codec'])) {
964 $thisfile_audio['codec'] = $ThisFileInfo['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
965 }
966 if (!empty($thisfile_audio['streams'])) {
967 foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
968 if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
969 $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate'];
970 $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels'];
971 $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
972 $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
973 $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec'];
974 }
975 }
976 }
977 $thisfile_audio['encoder_options'] = getid3_mp3::GuessEncoderOptions($ThisFileInfo);
978 }
979
980
981 if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
982 switch ($thisfile_audio_dataformat) {
983 case 'ac3':
984 // ignore bits_per_sample
985 break;
986
987 default:
988 $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
989 break;
990 }
991 }
992
993
994 if (empty($thisfile_riff_raw)) {
995 unset($thisfile_riff['raw']);
996 }
997 if (empty($thisfile_riff_audio)) {
998 unset($thisfile_riff['audio']);
999 }
1000 if (empty($thisfile_riff_video)) {
1001 unset($thisfile_riff['video']);
1002 }
1003
1004 return true;
1005 }
RIFFparseWAVEFORMATex($WaveFormatExData)
RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray)
ParseRIFFdata(&$RIFFdata, &$ThisFileInfo)

References getid3_lib\array_merge_noclobber(), getid3_lib\BigEndian2Float(), getid3_lib\BigEndian2Int(), getid3_lib\Bin2Dec(), getid3_lib\CastAsInt(), getid3_lib\DateMac2Unix(), getid3_lib\Dec2Bin(), EitherEndian2Int(), getid3_lib\FixedPoint16_16(), getid3_handler\fread(), getid3_handler\fseek(), getid3_mp3\GuessEncoderOptions(), getid3_lib\IncludeDependency(), getid3_lib\LittleEndian2Float(), getid3_lib\LittleEndian2Int(), ParseRIFF(), ParseRIFFdata(), getid3_lib\RGADadjustmentLookup(), getid3_lib\RGADnameLookup(), getid3_lib\RGADoriginatorLookup(), RIFFcommentsParse(), RIFFfourccLookup(), and RIFFparseWAVEFORMATex().

Referenced by Analyze(), and ParseRIFFdata().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseBITMAPINFOHEADER()

static getid3_riff::ParseBITMAPINFOHEADER (   $BITMAPINFOHEADER,
  $littleEndian = true 
)
static

Definition at line 1900 of file module.audio-video.riff.php.

1900 {
1901
1902 $parsed['biSize'] = substr($BITMAPINFOHEADER, 0, 4); // number of bytes required by the BITMAPINFOHEADER structure
1903 $parsed['biWidth'] = substr($BITMAPINFOHEADER, 4, 4); // width of the bitmap in pixels
1904 $parsed['biHeight'] = substr($BITMAPINFOHEADER, 8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
1905 $parsed['biPlanes'] = substr($BITMAPINFOHEADER, 12, 2); // number of color planes on the target device. In most cases this value must be set to 1
1906 $parsed['biBitCount'] = substr($BITMAPINFOHEADER, 14, 2); // Specifies the number of bits per pixels
1907 $parsed['biSizeImage'] = substr($BITMAPINFOHEADER, 20, 4); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1908 $parsed['biXPelsPerMeter'] = substr($BITMAPINFOHEADER, 24, 4); // horizontal resolution, in pixels per metre, of the target device
1909 $parsed['biYPelsPerMeter'] = substr($BITMAPINFOHEADER, 28, 4); // vertical resolution, in pixels per metre, of the target device
1910 $parsed['biClrUsed'] = substr($BITMAPINFOHEADER, 32, 4); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
1911 $parsed['biClrImportant'] = substr($BITMAPINFOHEADER, 36, 4); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
1912 $parsed = array_map('getid3_lib::'.($littleEndian ? 'Little' : 'Big').'Endian2Int', $parsed);
1913
1914 $parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier
1915
1916 return $parsed;
1917 }

Referenced by getid3_matroska\Analyze(), and Analyze().

+ Here is the caller graph for this function:

◆ parseComments()

static getid3_riff::parseComments ( $RIFFinfoArray,
$CommentsTargetArray 
)
static

Definition at line 1755 of file module.audio-video.riff.php.

1755 {
1756 $RIFFinfoKeyLookup = array(
1757 'IARL'=>'archivallocation',
1758 'IART'=>'artist',
1759 'ICDS'=>'costumedesigner',
1760 'ICMS'=>'commissionedby',
1761 'ICMT'=>'comment',
1762 'ICNT'=>'country',
1763 'ICOP'=>'copyright',
1764 'ICRD'=>'creationdate',
1765 'IDIM'=>'dimensions',
1766 'IDIT'=>'digitizationdate',
1767 'IDPI'=>'resolution',
1768 'IDST'=>'distributor',
1769 'IEDT'=>'editor',
1770 'IENG'=>'engineers',
1771 'IFRM'=>'accountofparts',
1772 'IGNR'=>'genre',
1773 'IKEY'=>'keywords',
1774 'ILGT'=>'lightness',
1775 'ILNG'=>'language',
1776 'IMED'=>'orignalmedium',
1777 'IMUS'=>'composer',
1778 'INAM'=>'title',
1779 'IPDS'=>'productiondesigner',
1780 'IPLT'=>'palette',
1781 'IPRD'=>'product',
1782 'IPRO'=>'producer',
1783 'IPRT'=>'part',
1784 'IRTD'=>'rating',
1785 'ISBJ'=>'subject',
1786 'ISFT'=>'software',
1787 'ISGN'=>'secondarygenre',
1788 'ISHP'=>'sharpness',
1789 'ISRC'=>'sourcesupplier',
1790 'ISRF'=>'digitizationsource',
1791 'ISTD'=>'productionstudio',
1792 'ISTR'=>'starring',
1793 'ITCH'=>'encoded_by',
1794 'IWEB'=>'url',
1795 'IWRI'=>'writer',
1796 '____'=>'comment',
1797 );
1798 foreach ($RIFFinfoKeyLookup as $key => $value) {
1799 if (isset($RIFFinfoArray[$key])) {
1800 foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1801 if (trim($commentdata['data']) != '') {
1802 if (isset($CommentsTargetArray[$value])) {
1803 $CommentsTargetArray[$value][] = trim($commentdata['data']);
1804 } else {
1805 $CommentsTargetArray[$value] = array(trim($commentdata['data']));
1806 }
1807 }
1808 }
1809 }
1810 }
1811 return true;
1812 }

Referenced by Analyze(), and getid3_wavpack\Analyze().

+ Here is the caller graph for this function:

◆ ParseDIVXTAG()

static getid3_riff::ParseDIVXTAG (   $DIVXTAG,
  $raw = false 
)
static

Definition at line 1919 of file module.audio-video.riff.php.

1919 {
1920 // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1921 // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1922 // 'Byte Layout: '1111111111111111
1923 // '32 for Movie - 1 '1111111111111111
1924 // '28 for Author - 6 '6666666666666666
1925 // '4 for year - 2 '6666666666662222
1926 // '3 for genre - 3 '7777777777777777
1927 // '48 for Comments - 7 '7777777777777777
1928 // '1 for Rating - 4 '7777777777777777
1929 // '5 for Future Additions - 0 '333400000DIVXTAG
1930 // '128 bytes total
1931
1932 static $DIVXTAGgenre = array(
1933 0 => 'Action',
1934 1 => 'Action/Adventure',
1935 2 => 'Adventure',
1936 3 => 'Adult',
1937 4 => 'Anime',
1938 5 => 'Cartoon',
1939 6 => 'Claymation',
1940 7 => 'Comedy',
1941 8 => 'Commercial',
1942 9 => 'Documentary',
1943 10 => 'Drama',
1944 11 => 'Home Video',
1945 12 => 'Horror',
1946 13 => 'Infomercial',
1947 14 => 'Interactive',
1948 15 => 'Mystery',
1949 16 => 'Music Video',
1950 17 => 'Other',
1951 18 => 'Religion',
1952 19 => 'Sci Fi',
1953 20 => 'Thriller',
1954 21 => 'Western',
1955 ),
1956 $DIVXTAGrating = array(
1957 0 => 'Unrated',
1958 1 => 'G',
1959 2 => 'PG',
1960 3 => 'PG-13',
1961 4 => 'R',
1962 5 => 'NC-17',
1963 );
1964
1965 $parsed['title'] = trim(substr($DIVXTAG, 0, 32));
1966 $parsed['artist'] = trim(substr($DIVXTAG, 32, 28));
1967 $parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4)));
1968 $parsed['comment'] = trim(substr($DIVXTAG, 64, 48));
1969 $parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3)));
1970 $parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1));
1971 //$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null
1972 //$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG"
1973
1974 $parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']);
1975 $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1976
1977 if (!$raw) {
1978 unset($parsed['genre_id'], $parsed['rating_id']);
1979 foreach ($parsed as $key => $value) {
1980 if (!$value === '') {
1981 unset($parsed['key']);
1982 }
1983 }
1984 }
1985
1986 foreach ($parsed as $tag => $value) {
1987 $parsed[$tag] = array($value);
1988 }
1989
1990 return $parsed;
1991 }

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ ParseRIFF() [1/2]

getid3_riff::ParseRIFF (   $startoffset,
  $maxoffset 
)

Definition at line 1432 of file module.audio-video.riff.php.

1432 {
1433 $info = &$this->getid3->info;
1434
1435 $RIFFchunk = false;
1436 $FoundAllChunksWeNeed = false;
1437
1438 try {
1439 $this->fseek($startoffset);
1440 $maxoffset = min($maxoffset, $info['avdataend']);
1441 while ($this->ftell() < $maxoffset) {
1442 $chunknamesize = $this->fread(8);
1443 //$chunkname = substr($chunknamesize, 0, 4);
1444 $chunkname = str_replace("\x00", '_', substr($chunknamesize, 0, 4)); // note: chunk names of 4 null bytes do appear to be legal (has been observed inside INFO and PRMI chunks, for example), but makes traversing array keys more difficult
1445 $chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4));
1446 //if (strlen(trim($chunkname, "\x00")) < 4) {
1447 if (strlen($chunkname) < 4) {
1448 $this->error('Expecting chunk name at offset '.($this->ftell() - 8).' but found nothing. Aborting RIFF parsing.');
1449 break;
1450 }
1451 if (($chunksize == 0) && ($chunkname != 'JUNK')) {
1452 $this->warning('Chunk ('.$chunkname.') size at offset '.($this->ftell() - 4).' is zero. Aborting RIFF parsing.');
1453 break;
1454 }
1455 if (($chunksize % 2) != 0) {
1456 // all structures are packed on word boundaries
1457 $chunksize++;
1458 }
1459
1460 switch ($chunkname) {
1461 case 'LIST':
1462 $listname = $this->fread(4);
1463 if (preg_match('#^(movi|rec )$#i', $listname)) {
1464 $RIFFchunk[$listname]['offset'] = $this->ftell() - 4;
1465 $RIFFchunk[$listname]['size'] = $chunksize;
1466
1467 if (!$FoundAllChunksWeNeed) {
1468 $WhereWeWere = $this->ftell();
1469 $AudioChunkHeader = $this->fread(12);
1470 $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1471 $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1472 $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1473
1474 if ($AudioChunkStreamType == 'wb') {
1475 $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1476 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1477 // MP3
1478 if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1479 $getid3_temp = new getID3();
1480 $getid3_temp->openfile($this->getid3->filename);
1481 $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1482 $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
1483 $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
1484 $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1485 if (isset($getid3_temp->info['mpeg']['audio'])) {
1486 $info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio'];
1487 $info['audio'] = $getid3_temp->info['audio'];
1488 $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
1489 $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1490 $info['audio']['channels'] = $info['mpeg']['audio']['channels'];
1491 $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
1492 $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1493 //$info['bitrate'] = $info['audio']['bitrate'];
1494 }
1495 unset($getid3_temp, $getid3_mp3);
1496 }
1497
1498 } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
1499
1500 // AC3
1501 $getid3_temp = new getID3();
1502 $getid3_temp->openfile($this->getid3->filename);
1503 $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
1504 $getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
1505 $getid3_ac3 = new getid3_ac3($getid3_temp);
1506 $getid3_ac3->Analyze();
1507 if (empty($getid3_temp->info['error'])) {
1508 $info['audio'] = $getid3_temp->info['audio'];
1509 $info['ac3'] = $getid3_temp->info['ac3'];
1510 if (!empty($getid3_temp->info['warning'])) {
1511 foreach ($getid3_temp->info['warning'] as $key => $value) {
1512 $info['warning'][] = $value;
1513 }
1514 }
1515 }
1516 unset($getid3_temp, $getid3_ac3);
1517 }
1518 }
1519 $FoundAllChunksWeNeed = true;
1520 $this->fseek($WhereWeWere);
1521 }
1522 $this->fseek($chunksize - 4, SEEK_CUR);
1523
1524 } else {
1525
1526 if (!isset($RIFFchunk[$listname])) {
1527 $RIFFchunk[$listname] = array();
1528 }
1529 $LISTchunkParent = $listname;
1530 $LISTchunkMaxOffset = $this->ftell() - 4 + $chunksize;
1531 if ($parsedChunk = $this->ParseRIFF($this->ftell(), $LISTchunkMaxOffset)) {
1532 $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1533 }
1534
1535 }
1536 break;
1537
1538 default:
1539 if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1540 $this->fseek($chunksize, SEEK_CUR);
1541 break;
1542 }
1543 $thisindex = 0;
1544 if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1545 $thisindex = count($RIFFchunk[$chunkname]);
1546 }
1547 $RIFFchunk[$chunkname][$thisindex]['offset'] = $this->ftell() - 8;
1548 $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1549 switch ($chunkname) {
1550 case 'data':
1551 $info['avdataoffset'] = $this->ftell();
1552 $info['avdataend'] = $info['avdataoffset'] + $chunksize;
1553
1554 $testData = $this->fread(36);
1555 if ($testData === '') {
1556 break;
1557 }
1558 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($testData, 0, 4))) {
1559
1560 // Probably is MP3 data
1561 if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
1562 $getid3_temp = new getID3();
1563 $getid3_temp->openfile($this->getid3->filename);
1564 $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1565 $getid3_temp->info['avdataend'] = $info['avdataend'];
1566 $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
1567 $getid3_mp3->getOnlyMPEGaudioInfo($info['avdataoffset'], false);
1568 if (empty($getid3_temp->info['error'])) {
1569 $info['audio'] = $getid3_temp->info['audio'];
1570 $info['mpeg'] = $getid3_temp->info['mpeg'];
1571 }
1572 unset($getid3_temp, $getid3_mp3);
1573 }
1574
1575 } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
1576
1577 // This is probably AC-3 data
1578 $getid3_temp = new getID3();
1579 if ($isRegularAC3) {
1580 $getid3_temp->openfile($this->getid3->filename);
1581 $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1582 $getid3_temp->info['avdataend'] = $info['avdataend'];
1583 }
1584 $getid3_ac3 = new getid3_ac3($getid3_temp);
1585 if ($isRegularAC3) {
1586 $getid3_ac3->Analyze();
1587 } else {
1588 // Dolby Digital WAV
1589 // AC-3 content, but not encoded in same format as normal AC-3 file
1590 // For one thing, byte order is swapped
1591 $ac3_data = '';
1592 for ($i = 0; $i < 28; $i += 2) {
1593 $ac3_data .= substr($testData, 8 + $i + 1, 1);
1594 $ac3_data .= substr($testData, 8 + $i + 0, 1);
1595 }
1596 $getid3_ac3->AnalyzeString($ac3_data);
1597 }
1598
1599 if (empty($getid3_temp->info['error'])) {
1600 $info['audio'] = $getid3_temp->info['audio'];
1601 $info['ac3'] = $getid3_temp->info['ac3'];
1602 if (!empty($getid3_temp->info['warning'])) {
1603 foreach ($getid3_temp->info['warning'] as $newerror) {
1604 $this->warning('getid3_ac3() says: ['.$newerror.']');
1605 }
1606 }
1607 }
1608 unset($getid3_temp, $getid3_ac3);
1609
1610 } elseif (preg_match('/^('.implode('|', array_map('preg_quote', getid3_dts::$syncwords)).')/', $testData)) {
1611
1612 // This is probably DTS data
1613 $getid3_temp = new getID3();
1614 $getid3_temp->openfile($this->getid3->filename);
1615 $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
1616 $getid3_dts = new getid3_dts($getid3_temp);
1617 $getid3_dts->Analyze();
1618 if (empty($getid3_temp->info['error'])) {
1619 $info['audio'] = $getid3_temp->info['audio'];
1620 $info['dts'] = $getid3_temp->info['dts'];
1621 $info['playtime_seconds'] = $getid3_temp->info['playtime_seconds']; // may not match RIFF calculations since DTS-WAV often used 14/16 bit-word packing
1622 if (!empty($getid3_temp->info['warning'])) {
1623 foreach ($getid3_temp->info['warning'] as $newerror) {
1624 $this->warning('getid3_dts() says: ['.$newerror.']');
1625 }
1626 }
1627 }
1628
1629 unset($getid3_temp, $getid3_dts);
1630
1631 } elseif (substr($testData, 0, 4) == 'wvpk') {
1632
1633 // This is WavPack data
1634 $info['wavpack']['offset'] = $info['avdataoffset'];
1635 $info['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($testData, 4, 4));
1636 $this->parseWavPackHeader(substr($testData, 8, 28));
1637
1638 } else {
1639 // This is some other kind of data (quite possibly just PCM)
1640 // do nothing special, just skip it
1641 }
1642 $nextoffset = $info['avdataend'];
1643 $this->fseek($nextoffset);
1644 break;
1645
1646 case 'iXML':
1647 case 'bext':
1648 case 'cart':
1649 case 'fmt ':
1650 case 'strh':
1651 case 'strf':
1652 case 'indx':
1653 case 'MEXT':
1654 case 'DISP':
1655 // always read data in
1656 case 'JUNK':
1657 // should be: never read data in
1658 // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
1659 if ($chunksize < 1048576) {
1660 if ($chunksize > 0) {
1661 $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1662 if ($chunkname == 'JUNK') {
1663 if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) {
1664 // only keep text characters [chr(32)-chr(127)]
1665 $info['riff']['comments']['junk'][] = trim($matches[1]);
1666 }
1667 // but if nothing there, ignore
1668 // remove the key in either case
1669 unset($RIFFchunk[$chunkname][$thisindex]['data']);
1670 }
1671 }
1672 } else {
1673 $this->warning('Chunk "'.$chunkname.'" at offset '.$this->ftell().' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data');
1674 $this->fseek($chunksize, SEEK_CUR);
1675 }
1676 break;
1677
1678 //case 'IDVX':
1679 // $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
1680 // break;
1681
1682 default:
1683 if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1684 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1685 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1686 unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1687 unset($RIFFchunk[$chunkname][$thisindex]['size']);
1688 if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1689 unset($RIFFchunk[$chunkname][$thisindex]);
1690 }
1691 if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1692 unset($RIFFchunk[$chunkname]);
1693 }
1694 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1695 } elseif ($chunksize < 2048) {
1696 // only read data in if smaller than 2kB
1697 $RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
1698 } else {
1699 $this->fseek($chunksize, SEEK_CUR);
1700 }
1701 break;
1702 }
1703 break;
1704 }
1705 }
1706
1707 } catch (getid3_exception $e) {
1708 if ($e->getCode() == 10) {
1709 $this->warning('RIFF parser: '.$e->getMessage());
1710 } else {
1711 throw $e;
1712 }
1713 }
1714
1715 return $RIFFchunk;
1716 }
getID3() by James Heinrich info@getid3.org //
getID3() by James Heinrich info@getid3.org //
static $syncwords
Possible syncwords indicating bitstream encoding.
MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
parseWavPackHeader($WavPackChunkData)

References $info, getid3_dts\$syncwords, EitherEndian2Int(), getid3_handler\error(), getid3_handler\fread(), getid3_handler\fseek(), getid3_handler\ftell(), getid3_lib\LittleEndian2Int(), getid3_mp3\MPEGaudioHeaderBytesValid(), ParseRIFF(), parseWavPackHeader(), getid3_ac3\syncword, and getid3_handler\warning().

+ Here is the call graph for this function:

◆ ParseRIFF() [2/2]

getid3_riff::ParseRIFF ( $fd,
  $startoffset,
  $maxoffset,
$ThisFileInfo 
)

Definition at line 1062 of file module.audio-video.riff.php.

1062 {
1063
1064 $maxoffset = min($maxoffset, $ThisFileInfo['avdataend']);
1065
1066 $RIFFchunk = false;
1067
1068 fseek($fd, $startoffset, SEEK_SET);
1069
1070 while (ftell($fd) < $maxoffset) {
1071 $chunkname = fread($fd, 4);
1072 if (strlen($chunkname) < 4) {
1073 $ThisFileInfo['error'][] = 'Expecting chunk name at offset '.(ftell($fd) - 4).' but found nothing. Aborting RIFF parsing.';
1074 break;
1075 }
1076
1077 $chunksize = getid3_riff::EitherEndian2Int($ThisFileInfo, fread($fd, 4));
1078 if ($chunksize == 0) {
1079 $ThisFileInfo['error'][] = 'Chunk size at offset '.(ftell($fd) - 4).' is zero. Aborting RIFF parsing.';
1080 break;
1081 }
1082 if (($chunksize % 2) != 0) {
1083 // all structures are packed on word boundaries
1084 $chunksize++;
1085 }
1086
1087 switch ($chunkname) {
1088 case 'LIST':
1089 $listname = fread($fd, 4);
1090 switch ($listname) {
1091 case 'movi':
1092 case 'rec ':
1093 $RIFFchunk[$listname]['offset'] = ftell($fd) - 4;
1094 $RIFFchunk[$listname]['size'] = $chunksize;
1095
1096 static $ParsedAudioStream = false;
1097 if ($ParsedAudioStream) {
1098
1099 // skip over
1100
1101 } else {
1102
1103 $WhereWeWere = ftell($fd);
1104 $AudioChunkHeader = fread($fd, 12);
1105 $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1106 $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1107 $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1108
1109 if ($AudioChunkStreamType == 'wb') {
1110 $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1111 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1112
1113 // MP3
1114 if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1115 $dummy = $ThisFileInfo;
1116 $dummy['avdataoffset'] = ftell($fd) - 4;
1117 $dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
1118 getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $dummy['avdataoffset'], false);
1119 if (isset($dummy['mpeg']['audio'])) {
1120 $ThisFileInfo = $dummy;
1121 $ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
1122 $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate'];
1123 $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels'];
1124 $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
1125 $ThisFileInfo['bitrate'] = $ThisFileInfo['audio']['bitrate'];
1126 $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
1127 }
1128 }
1129
1130 } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
1131
1132 // AC3
1133 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1134 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1135
1136 $dummy = $ThisFileInfo;
1137 $dummy['avdataoffset'] = ftell($fd) - 4;
1138 $dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
1139 $dummy['error'] = array();
1140 $ac3_tag = new getid3_ac3($fd, $dummy);
1141 if (empty($dummy['error'])) {
1142 $ThisFileInfo['audio'] = $dummy['audio'];
1143 $ThisFileInfo['ac3'] = $dummy['ac3'];
1144 $ThisFileInfo['warning'] = $dummy['warning'];
1145 }
1146
1147 }
1148
1149 }
1150
1151 }
1152
1153 $ParsedAudioStream = true;
1154 fseek($fd, $WhereWeWere, SEEK_SET);
1155
1156 }
1157 fseek($fd, $chunksize - 4, SEEK_CUR);
1158 break;
1159
1160 default:
1161 if (!isset($RIFFchunk[$listname])) {
1162 $RIFFchunk[$listname] = array();
1163 }
1164 $LISTchunkParent = $listname;
1165 $LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
1166 if ($parsedChunk = getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
1167 $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1168 }
1169 break;
1170 }
1171 break;
1172
1173 default:
1174 $thisindex = 0;
1175 if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1176 $thisindex = count($RIFFchunk[$chunkname]);
1177 }
1178 $RIFFchunk[$chunkname][$thisindex]['offset'] = ftell($fd) - 8;
1179 $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1180 switch ($chunkname) {
1181 case 'data':
1182 $ThisFileInfo['avdataoffset'] = ftell($fd);
1183 $ThisFileInfo['avdataend'] = $ThisFileInfo['avdataoffset'] + $chunksize;
1184
1185 $RIFFdataChunkContentsTest = fread($fd, 36);
1186
1187 if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1188
1189 // Probably is MP3 data
1190 if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
1191 getid3_mp3::getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $RIFFchunk[$chunkname][$thisindex]['offset'], false);
1192 }
1193
1194 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
1195
1196 // This is probably AC-3 data
1197 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1198 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1199
1200 $dummy = $ThisFileInfo;
1201 $dummy['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1202 $dummy['avdataend'] = $dummy['avdataoffset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1203 $dummy['error'] = array();
1204
1205 $ac3_tag = new getid3_ac3($fd, $dummy);
1206 if (empty($dummy['error'])) {
1207 $ThisFileInfo['audio'] = $dummy['audio'];
1208 $ThisFileInfo['ac3'] = $dummy['ac3'];
1209 $ThisFileInfo['warning'] = $dummy['warning'];
1210 }
1211
1212 }
1213
1214 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) == "\x77\x0B")) {
1215
1216 // Dolby Digital WAV
1217 // AC-3 content, but not encoded in same format as normal AC-3 file
1218 // For one thing, byte order is swapped
1219
1220 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1221 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1222
1223 // ok to use tmpfile here - only 56 bytes
1224 if ($fd_temp = tmpfile()) {
1225
1226 for ($i = 0; $i < 28; $i += 2) {
1227 // swap byte order
1228 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1229 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1230 }
1231
1232 $dummy = $ThisFileInfo;
1233 $dummy['avdataoffset'] = 0;
1234 $dummy['avdataend'] = 20;
1235 $dummy['error'] = array();
1236 $ac3_tag = new getid3_ac3($fd_temp, $dummy);
1237 fclose($fd_temp);
1238 if (empty($dummy['error'])) {
1239 $ThisFileInfo['audio'] = $dummy['audio'];
1240 $ThisFileInfo['ac3'] = $dummy['ac3'];
1241 $ThisFileInfo['warning'] = $dummy['warning'];
1242 } else {
1243 $ThisFileInfo['error'][] = 'Errors parsing DolbyDigital WAV: '.explode(';', $dummy['error']);
1244 }
1245
1246 } else {
1247
1248 $ThisFileInfo['error'][] = 'Could not create temporary file to analyze DolbyDigital WAV';
1249
1250 }
1251
1252 }
1253
1254 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) == 'wvpk')) {
1255
1256 // This is WavPack data
1257 $ThisFileInfo['wavpack']['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1258 $ThisFileInfo['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($RIFFdataChunkContentsTest, 4, 4));
1259 getid3_riff::RIFFparseWavPackHeader(substr($RIFFdataChunkContentsTest, 8, 28), $ThisFileInfo);
1260
1261 } else {
1262
1263 // This is some other kind of data (quite possibly just PCM)
1264 // do nothing special, just skip it
1265
1266 }
1267 fseek($fd, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
1268 break;
1269
1270 case 'bext':
1271 case 'cart':
1272 case 'fmt ':
1273 case 'MEXT':
1274 case 'DISP':
1275 // always read data in
1276 $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1277 break;
1278
1279 default:
1280 if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1281 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1282 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1283 unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1284 unset($RIFFchunk[$chunkname][$thisindex]['size']);
1285 if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1286 unset($RIFFchunk[$chunkname][$thisindex]);
1287 }
1288 if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1289 unset($RIFFchunk[$chunkname]);
1290 }
1291 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1292 } elseif ($chunksize < 2048) {
1293 // only read data in if smaller than 2kB
1294 $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1295 } else {
1296 fseek($fd, $chunksize, SEEK_CUR);
1297 }
1298 break;
1299 }
1300 break;
1301
1302 }
1303
1304 }
1305
1306 return $RIFFchunk;
1307 }
getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false)
RIFFparseWavPackHeader($WavPackChunkData, &$ThisFileInfo)

References EitherEndian2Int(), getid3_handler\fread(), getid3_handler\fseek(), getid3_handler\ftell(), getid3_mp3\getOnlyMPEGaudioInfo(), getid3_lib\IncludeDependency(), getid3_lib\LittleEndian2Int(), getid3_mp3\MPEGaudioHeaderBytesValid(), ParseRIFF(), and RIFFparseWavPackHeader().

Referenced by Analyze(), getid3_riff(), getid3_wavpack\getid3_wavpack(), and ParseRIFF().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFFAMV()

getid3_riff::ParseRIFFAMV (   $startoffset,
  $maxoffset 
)

Definition at line 1323 of file module.audio-video.riff.php.

1323 {
1324 // AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
1325
1326 // https://code.google.com/p/amv-codec-tools/wiki/AmvDocumentation
1327 //typedef struct _amvmainheader {
1328 //FOURCC fcc; // 'amvh'
1329 //DWORD cb;
1330 //DWORD dwMicroSecPerFrame;
1331 //BYTE reserve[28];
1332 //DWORD dwWidth;
1333 //DWORD dwHeight;
1334 //DWORD dwSpeed;
1335 //DWORD reserve0;
1336 //DWORD reserve1;
1337 //BYTE bTimeSec;
1338 //BYTE bTimeMin;
1339 //WORD wTimeHour;
1340 //} AMVMAINHEADER;
1341
1342 $info = &$this->getid3->info;
1343 $RIFFchunk = false;
1344
1345 try {
1346
1347 $this->fseek($startoffset);
1348 $maxoffset = min($maxoffset, $info['avdataend']);
1349 $AMVheader = $this->fread(284);
1350 if (substr($AMVheader, 0, 8) != 'hdrlamvh') {
1351 throw new Exception('expecting "hdrlamv" at offset '.($startoffset + 0).', found "'.substr($AMVheader, 0, 8).'"');
1352 }
1353 if (substr($AMVheader, 8, 4) != "\x38\x00\x00\x00") { // "amvh" chunk size, hardcoded to 0x38 = 56 bytes
1354 throw new Exception('expecting "0x38000000" at offset '.($startoffset + 8).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 8, 4)).'"');
1355 }
1356 $RIFFchunk = array();
1357 $RIFFchunk['amvh']['us_per_frame'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 12, 4));
1358 $RIFFchunk['amvh']['reserved28'] = substr($AMVheader, 16, 28); // null? reserved?
1359 $RIFFchunk['amvh']['resolution_x'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 44, 4));
1360 $RIFFchunk['amvh']['resolution_y'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 48, 4));
1361 $RIFFchunk['amvh']['frame_rate_int'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 52, 4));
1362 $RIFFchunk['amvh']['reserved0'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 56, 4)); // 1? reserved?
1363 $RIFFchunk['amvh']['reserved1'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 60, 4)); // 0? reserved?
1364 $RIFFchunk['amvh']['runtime_sec'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 64, 1));
1365 $RIFFchunk['amvh']['runtime_min'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 65, 1));
1366 $RIFFchunk['amvh']['runtime_hrs'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 66, 2));
1367
1368 $info['video']['frame_rate'] = 1000000 / $RIFFchunk['amvh']['us_per_frame'];
1369 $info['video']['resolution_x'] = $RIFFchunk['amvh']['resolution_x'];
1370 $info['video']['resolution_y'] = $RIFFchunk['amvh']['resolution_y'];
1371 $info['playtime_seconds'] = ($RIFFchunk['amvh']['runtime_hrs'] * 3600) + ($RIFFchunk['amvh']['runtime_min'] * 60) + $RIFFchunk['amvh']['runtime_sec'];
1372
1373 // the rest is all hardcoded(?) and does not appear to be useful until you get to audio info at offset 256, even then everything is probably hardcoded
1374
1375 if (substr($AMVheader, 68, 20) != 'LIST'."\x00\x00\x00\x00".'strlstrh'."\x38\x00\x00\x00") {
1376 throw new Exception('expecting "LIST<0x00000000>strlstrh<0x38000000>" at offset '.($startoffset + 68).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 68, 20)).'"');
1377 }
1378 // followed by 56 bytes of null: substr($AMVheader, 88, 56) -> 144
1379 if (substr($AMVheader, 144, 8) != 'strf'."\x24\x00\x00\x00") {
1380 throw new Exception('expecting "strf<0x24000000>" at offset '.($startoffset + 144).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 144, 8)).'"');
1381 }
1382 // followed by 36 bytes of null: substr($AMVheader, 144, 36) -> 180
1383
1384 if (substr($AMVheader, 188, 20) != 'LIST'."\x00\x00\x00\x00".'strlstrh'."\x30\x00\x00\x00") {
1385 throw new Exception('expecting "LIST<0x00000000>strlstrh<0x30000000>" at offset '.($startoffset + 188).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 188, 20)).'"');
1386 }
1387 // followed by 48 bytes of null: substr($AMVheader, 208, 48) -> 256
1388 if (substr($AMVheader, 256, 8) != 'strf'."\x14\x00\x00\x00") {
1389 throw new Exception('expecting "strf<0x14000000>" at offset '.($startoffset + 256).', found "'.getid3_lib::PrintHexBytes(substr($AMVheader, 256, 8)).'"');
1390 }
1391 // followed by 20 bytes of a modified WAVEFORMATEX:
1392 // typedef struct {
1393 // WORD wFormatTag; //(Fixme: this is equal to PCM's 0x01 format code)
1394 // WORD nChannels; //(Fixme: this is always 1)
1395 // DWORD nSamplesPerSec; //(Fixme: for all known sample files this is equal to 22050)
1396 // DWORD nAvgBytesPerSec; //(Fixme: for all known sample files this is equal to 44100)
1397 // WORD nBlockAlign; //(Fixme: this seems to be 2 in AMV files, is this correct ?)
1398 // WORD wBitsPerSample; //(Fixme: this seems to be 16 in AMV files instead of the expected 4)
1399 // WORD cbSize; //(Fixme: this seems to be 0 in AMV files)
1400 // WORD reserved;
1401 // } WAVEFORMATEX;
1402 $RIFFchunk['strf']['wformattag'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 264, 2));
1403 $RIFFchunk['strf']['nchannels'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 266, 2));
1404 $RIFFchunk['strf']['nsamplespersec'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 268, 4));
1405 $RIFFchunk['strf']['navgbytespersec'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 272, 4));
1406 $RIFFchunk['strf']['nblockalign'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 276, 2));
1407 $RIFFchunk['strf']['wbitspersample'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 278, 2));
1408 $RIFFchunk['strf']['cbsize'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 280, 2));
1409 $RIFFchunk['strf']['reserved'] = getid3_lib::LittleEndian2Int(substr($AMVheader, 282, 2));
1410
1411
1412 $info['audio']['lossless'] = false;
1413 $info['audio']['sample_rate'] = $RIFFchunk['strf']['nsamplespersec'];
1414 $info['audio']['channels'] = $RIFFchunk['strf']['nchannels'];
1415 $info['audio']['bits_per_sample'] = $RIFFchunk['strf']['wbitspersample'];
1416 $info['audio']['bitrate'] = $info['audio']['sample_rate'] * $info['audio']['channels'] * $info['audio']['bits_per_sample'];
1417 $info['audio']['bitrate_mode'] = 'cbr';
1418
1419
1420 } catch (getid3_exception $e) {
1421 if ($e->getCode() == 10) {
1422 $this->warning('RIFFAMV parser: '.$e->getMessage());
1423 } else {
1424 throw $e;
1425 }
1426 }
1427
1428 return $RIFFchunk;
1429 }

References $info, getid3_handler\fread(), getid3_handler\fseek(), getid3_lib\LittleEndian2Int(), getid3_lib\PrintHexBytes(), and getid3_handler\warning().

Referenced by Analyze().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFFdata() [1/2]

getid3_riff::ParseRIFFdata ( $RIFFdata)

Definition at line 1718 of file module.audio-video.riff.php.

1718 {
1719 $info = &$this->getid3->info;
1720 if ($RIFFdata) {
1721 $tempfile = tempnam(GETID3_TEMP_DIR, 'getID3');
1722 $fp_temp = fopen($tempfile, 'wb');
1723 $RIFFdataLength = strlen($RIFFdata);
1724 $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1725 for ($i = 0; $i < 4; $i++) {
1726 $RIFFdata[($i + 4)] = $NewLengthString[$i];
1727 }
1728 fwrite($fp_temp, $RIFFdata);
1729 fclose($fp_temp);
1730
1731 $getid3_temp = new getID3();
1732 $getid3_temp->openfile($tempfile);
1733 $getid3_temp->info['filesize'] = $RIFFdataLength;
1734 $getid3_temp->info['filenamepath'] = $info['filenamepath'];
1735 $getid3_temp->info['tags'] = $info['tags'];
1736 $getid3_temp->info['warning'] = $info['warning'];
1737 $getid3_temp->info['error'] = $info['error'];
1738 $getid3_temp->info['comments'] = $info['comments'];
1739 $getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array());
1740 $getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array());
1741 $getid3_riff = new getid3_riff($getid3_temp);
1742 $getid3_riff->Analyze();
1743
1744 $info['riff'] = $getid3_temp->info['riff'];
1745 $info['warning'] = $getid3_temp->info['warning'];
1746 $info['error'] = $getid3_temp->info['error'];
1747 $info['tags'] = $getid3_temp->info['tags'];
1748 $info['comments'] = $getid3_temp->info['comments'];
1749 unset($getid3_riff, $getid3_temp);
1750 unlink($tempfile);
1751 }
1752 return false;
1753 }
LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: getid3.lib.php:343

References $info, getid3_riff(), and getid3_lib\LittleEndian2String().

+ Here is the call graph for this function:

◆ ParseRIFFdata() [2/2]

getid3_riff::ParseRIFFdata ( $RIFFdata,
$ThisFileInfo 
)

Definition at line 1310 of file module.audio-video.riff.php.

1310 {
1311 if ($RIFFdata) {
1312
1313 $tempfile = tempnam('*', 'getID3');
1314 $fp_temp = fopen($tempfile, "wb");
1315 $RIFFdataLength = strlen($RIFFdata);
1316 $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1317 for ($i = 0; $i < 4; $i++) {
1318 $RIFFdata{$i + 4} = $NewLengthString{$i};
1319 }
1320 fwrite($fp_temp, $RIFFdata);
1321 fclose($fp_temp);
1322
1323 $fp_temp = fopen($tempfile, "rb");
1324 $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()));
1325 $riff = new getid3_riff($fp_temp, $dummy);
1326 $ThisFileInfo['riff'] = $dummy['riff'];
1327 $ThisFileInfo['warning'] = $dummy['warning'];
1328 $ThisFileInfo['error'] = $dummy['error'];
1329 $ThisFileInfo['tags'] = $dummy['tags'];
1330 $ThisFileInfo['comments'] = $dummy['comments'];
1331 fclose($fp_temp);
1332 unlink($tempfile);
1333 return true;
1334 }
1335 return false;
1336 }

References getid3_riff(), and getid3_lib\LittleEndian2String().

Referenced by getid3_riff(), getid3_wavpack\getid3_wavpack(), getid3_optimfrog\ParseOptimFROGheader42(), and getid3_optimfrog\ParseOptimFROGheader45().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseWAVEFORMATex()

static getid3_riff::parseWAVEFORMATex (   $WaveFormatExData)
static

Definition at line 1814 of file module.audio-video.riff.php.

1814 {
1815 // shortcut
1816 $WaveFormatEx['raw'] = array();
1817 $WaveFormatEx_raw = &$WaveFormatEx['raw'];
1818
1819 $WaveFormatEx_raw['wFormatTag'] = substr($WaveFormatExData, 0, 2);
1820 $WaveFormatEx_raw['nChannels'] = substr($WaveFormatExData, 2, 2);
1821 $WaveFormatEx_raw['nSamplesPerSec'] = substr($WaveFormatExData, 4, 4);
1822 $WaveFormatEx_raw['nAvgBytesPerSec'] = substr($WaveFormatExData, 8, 4);
1823 $WaveFormatEx_raw['nBlockAlign'] = substr($WaveFormatExData, 12, 2);
1824 $WaveFormatEx_raw['wBitsPerSample'] = substr($WaveFormatExData, 14, 2);
1825 if (strlen($WaveFormatExData) > 16) {
1826 $WaveFormatEx_raw['cbSize'] = substr($WaveFormatExData, 16, 2);
1827 }
1828 $WaveFormatEx_raw = array_map('getid3_lib::LittleEndian2Int', $WaveFormatEx_raw);
1829
1830 $WaveFormatEx['codec'] = self::wFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1831 $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1832 $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1833 $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1834 $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1835
1836 return $WaveFormatEx;
1837 }

References wFormatTagLookup().

Referenced by getid3_asf\Analyze(), getid3_matroska\Analyze(), Analyze(), and getid3_shorten\Analyze().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseWavPackHeader()

getid3_riff::parseWavPackHeader (   $WavPackChunkData)

Definition at line 1839 of file module.audio-video.riff.php.

1839 {
1840 // typedef struct {
1841 // char ckID [4];
1842 // long ckSize;
1843 // short version;
1844 // short bits; // added for version 2.00
1845 // short flags, shift; // added for version 3.00
1846 // long total_samples, crc, crc2;
1847 // char extension [4], extra_bc, extras [3];
1848 // } WavpackHeader;
1849
1850 // shortcut
1851 $info = &$this->getid3->info;
1852 $info['wavpack'] = array();
1853 $thisfile_wavpack = &$info['wavpack'];
1854
1855 $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1856 if ($thisfile_wavpack['version'] >= 2) {
1857 $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1858 }
1859 if ($thisfile_wavpack['version'] >= 3) {
1860 $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1861 $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1862 $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1863 $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1864 $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1865 $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1866 $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1867 for ($i = 0; $i <= 2; $i++) {
1868 $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1869 }
1870
1871 // shortcut
1872 $thisfile_wavpack['flags'] = array();
1873 $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1874
1875 $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1876 $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1877 $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1878 $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1879 $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1880 $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1881 $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1882 $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1883 $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1884 $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1885 $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1886 $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1887 $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1888 $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1889 $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1890 $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1891 $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1892 $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1893 $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1894 $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1895 }
1896
1897 return true;
1898 }

References $info, and getid3_lib\LittleEndian2Int().

Referenced by ParseRIFF().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFcommentsParse()

getid3_riff::RIFFcommentsParse ( $RIFFinfoArray,
$CommentsTargetArray 
)

Definition at line 1008 of file module.audio-video.riff.php.

1008 {
1009 $RIFFinfoKeyLookup = array(
1010 'IARL'=>'archivallocation',
1011 'IART'=>'artist',
1012 'ICDS'=>'costumedesigner',
1013 'ICMS'=>'commissionedby',
1014 'ICMT'=>'comment',
1015 'ICNT'=>'country',
1016 'ICOP'=>'copyright',
1017 'ICRD'=>'creationdate',
1018 'IDIM'=>'dimensions',
1019 'IDIT'=>'digitizationdate',
1020 'IDPI'=>'resolution',
1021 'IDST'=>'distributor',
1022 'IEDT'=>'editor',
1023 'IENG'=>'engineers',
1024 'IFRM'=>'accountofparts',
1025 'IGNR'=>'genre',
1026 'IKEY'=>'keywords',
1027 'ILGT'=>'lightness',
1028 'ILNG'=>'language',
1029 'IMED'=>'orignalmedium',
1030 'IMUS'=>'composer',
1031 'INAM'=>'title',
1032 'IPDS'=>'productiondesigner',
1033 'IPLT'=>'palette',
1034 'IPRD'=>'product',
1035 'IPRO'=>'producer',
1036 'IPRT'=>'part',
1037 'IRTD'=>'rating',
1038 'ISBJ'=>'subject',
1039 'ISFT'=>'software',
1040 'ISGN'=>'secondarygenre',
1041 'ISHP'=>'sharpness',
1042 'ISRC'=>'sourcesupplier',
1043 'ISRF'=>'digitizationsource',
1044 'ISTD'=>'productionstudio',
1045 'ISTR'=>'starring',
1046 'ITCH'=>'encoded_by',
1047 'IWEB'=>'url',
1048 'IWRI'=>'writer'
1049 );
1050 foreach ($RIFFinfoKeyLookup as $key => $value) {
1051 if (isset($RIFFinfoArray[$key])) {
1052 foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1053 if (trim($commentdata['data']) != '') {
1054 @$CommentsTargetArray[$value][] = trim($commentdata['data']);
1055 }
1056 }
1057 }
1058 }
1059 return true;
1060 }

Referenced by getid3_riff(), and getid3_wavpack\getid3_wavpack().

+ Here is the caller graph for this function:

◆ RIFFfourccLookup()

getid3_riff::RIFFfourccLookup (   $fourcc)

This is not a comment!

swot        http://developer.apple.com/qa/snd/snd07.html
____        No Codec (____)
_BIT        BI_BITFIELDS (Raw RGB)
_JPG        JPEG compressed
_PNG        PNG compressed W3C/ISO/IEC (RFC-2083)
_RAW        Full Frames (Uncompressed)
_RGB        Raw RGB Bitmap
_RL4        RLE 4bpp RGB
_RL8        RLE 8bpp RGB
3IV1        3ivx MPEG-4 v1
3IV2        3ivx MPEG-4 v2
3IVX        3ivx MPEG-4
AASC        Autodesk Animator
ABYR        Kensington ?ABYR?
AEMI        Array Microsystems VideoONE MPEG1-I Capture
AFLC        Autodesk Animator FLC
AFLI        Autodesk Animator FLI
AMPG        Array Microsystems VideoONE MPEG
ANIM        Intel RDX (ANIM)
AP41        AngelPotion Definitive
ASV1        Asus Video v1
ASV2        Asus Video v2
ASVX        Asus Video 2.0 (audio)
AUR2        AuraVision Aura 2 Codec - YUV 4:2:2
AURA        AuraVision Aura 1 Codec - YUV 4:1:1
AVDJ        Independent JPEG Group\'s codec (AVDJ)
AVRN        Independent JPEG Group\'s codec (AVRN)
AYUV        4:4:4 YUV (AYUV)
AZPR        Quicktime Apple Video (AZPR)
BGR         Raw RGB32
BLZ0        Blizzard DivX MPEG-4
BTVC        Conexant Composite Video
BINK        RAD Game Tools Bink Video
BT20        Conexant Prosumer Video
BTCV        Conexant Composite Video Codec
BW10        Data Translation Broadway MPEG Capture
CC12        Intel YUV12
CDVC        Canopus DV
CFCC        Digital Processing Systems DPS Perception
CGDI        Microsoft Office 97 Camcorder Video
CHAM        Winnov Caviara Champagne
CJPG        Creative WebCam JPEG
CLJR        Cirrus Logic YUV 4:1:1
CMYK        Common Data Format in Printing (Colorgraph)
CPLA        Weitek 4:2:0 YUV Planar
CRAM        Microsoft Video 1 (CRAM)
cvid        Radius Cinepak
CVID        Radius Cinepak
CWLT        Microsoft Color WLT DIB
CYUV        Creative Labs YUV
CYUY        ATI YUV
D261        H.261
D263        H.263
DIB         Device Independent Bitmap
DIV1        FFmpeg OpenDivX
DIV2        Microsoft MPEG-4 v1/v2
DIV3        DivX ;-) MPEG-4 v3.x Low-Motion
DIV4        DivX ;-) MPEG-4 v3.x Fast-Motion
DIV5        DivX MPEG-4 v5.x
DIV6        DivX ;-) (MS MPEG-4 v3.x)
DIVX        DivX MPEG-4 v4 (OpenDivX / Project Mayo)
divx        DivX MPEG-4
DMB1        Matrox Rainbow Runner hardware MJPEG
DMB2        Paradigm MJPEG
DSVD        ?DSVD?
DUCK        Duck TrueMotion 1.0
DPS0        DPS/Leitch Reality Motion JPEG
DPSC        DPS/Leitch PAR Motion JPEG
DV25        Matrox DVCPRO codec
DV50        Matrox DVCPRO50 codec
DVC         IEC 61834 and SMPTE 314M (DVC/DV Video)
DVCP        IEC 61834 and SMPTE 314M (DVC/DV Video)
DVHD        IEC Standard DV 1125 lines @ 30fps / 1250 lines @ 25fps
DVMA        Darim Vision DVMPEG (dummy for MPEG compressor) (www.darvision.com)
DVSL        IEC Standard DV compressed in SD (SDL)
DVAN        ?DVAN?
DVE2        InSoft DVE-2 Videoconferencing
dvsd        IEC 61834 and SMPTE 314M DVC/DV Video
DVSD        IEC 61834 and SMPTE 314M DVC/DV Video
DVX1        Lucent DVX1000SP Video Decoder
DVX2        Lucent DVX2000S Video Decoder
DVX3        Lucent DVX3000S Video Decoder
DX50        DivX v5
DXT1        Microsoft DirectX Compressed Texture (DXT1)
DXT2        Microsoft DirectX Compressed Texture (DXT2)
DXT3        Microsoft DirectX Compressed Texture (DXT3)
DXT4        Microsoft DirectX Compressed Texture (DXT4)
DXT5        Microsoft DirectX Compressed Texture (DXT5)
DXTC        Microsoft DirectX Compressed Texture (DXTC)
DXTn        Microsoft DirectX Compressed Texture (DXTn)
EM2V        Etymonix MPEG-2 I-frame (www.etymonix.com)
EKQ0        Elsa ?EKQ0?
ELK0        Elsa ?ELK0?
ESCP        Eidos Escape
ETV1        eTreppid Video ETV1
ETV2        eTreppid Video ETV2
ETVC        eTreppid Video ETVC
FLIC        Autodesk FLI/FLC Animation
FRWT        Darim Vision Forward Motion JPEG (www.darvision.com)
FRWU        Darim Vision Forward Uncompressed (www.darvision.com)
FLJP        D-Vision Field Encoded Motion JPEG
FRWA        SoftLab-Nsk Forward Motion JPEG w/ alpha channel
FRWD        SoftLab-Nsk Forward Motion JPEG
FVF1        Iterated Systems Fractal Video Frame
GLZW        Motion LZW (gabest@freemail.hu)
GPEG        Motion JPEG (gabest@freemail.hu)
GWLT        Microsoft Greyscale WLT DIB
H260        Intel ITU H.260 Videoconferencing
H261        Intel ITU H.261 Videoconferencing
H262        Intel ITU H.262 Videoconferencing
H263        Intel ITU H.263 Videoconferencing
H264        Intel ITU H.264 Videoconferencing
H265        Intel ITU H.265 Videoconferencing
H266        Intel ITU H.266 Videoconferencing
H267        Intel ITU H.267 Videoconferencing
H268        Intel ITU H.268 Videoconferencing
H269        Intel ITU H.269 Videoconferencing
HFYU        Huffman Lossless Codec
HMCR        Rendition Motion Compensation Format (HMCR)
HMRR        Rendition Motion Compensation Format (HMRR)
I263        FFmpeg I263 decoder
IF09        Indeo YVU9 ("YVU9 with additional delta-frame info after the U plane")
IUYV        Interlaced version of UYVY (www.leadtools.com)
IY41        Interlaced version of Y41P (www.leadtools.com)
IYU1        12 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
IYU2        24 bit format used in mode 2 of the IEEE 1394 Digital Camera 1.04 spec    IEEE standard
IYUV        Planar YUV format (8-bpp Y plane, followed by 8-bpp 2×2 U and V planes)
i263        Intel ITU H.263 Videoconferencing (i263)
I420        Intel Indeo 4
IAN         Intel Indeo 4 (RDX)
ICLB        InSoft CellB Videoconferencing
IGOR        Power DVD
IJPG        Intergraph JPEG
ILVC        Intel Layered Video
ILVR        ITU-T H.263+
IPDV        I-O Data Device Giga AVI DV Codec
IR21        Intel Indeo 2.1
IRAW        Intel YUV Uncompressed
IV30        Intel Indeo 3.0
IV31        Intel Indeo 3.1
IV32        Ligos Indeo 3.2
IV33        Ligos Indeo 3.3
IV34        Ligos Indeo 3.4
IV35        Ligos Indeo 3.5
IV36        Ligos Indeo 3.6
IV37        Ligos Indeo 3.7
IV38        Ligos Indeo 3.8
IV39        Ligos Indeo 3.9
IV40        Ligos Indeo Interactive 4.0
IV41        Ligos Indeo Interactive 4.1
IV42        Ligos Indeo Interactive 4.2
IV43        Ligos Indeo Interactive 4.3
IV44        Ligos Indeo Interactive 4.4
IV45        Ligos Indeo Interactive 4.5
IV46        Ligos Indeo Interactive 4.6
IV47        Ligos Indeo Interactive 4.7
IV48        Ligos Indeo Interactive 4.8
IV49        Ligos Indeo Interactive 4.9
IV50        Ligos Indeo Interactive 5.0
JBYR        Kensington ?JBYR?
JPEG        Still Image JPEG DIB
JPGL        Pegasus Lossless Motion JPEG
KMVC        Team17 Software Karl Morton\'s Video Codec
LSVM        Vianet Lighting Strike Vmail (Streaming) (www.vianet.com)
LEAD        LEAD Video Codec
Ljpg        LEAD MJPEG Codec
MDVD        Alex MicroDVD Video (hacked MS MPEG-4) (www.tiasoft.de)
MJPA        Morgan Motion JPEG (MJPA) (www.morgan-multimedia.com)
MJPB        Morgan Motion JPEG (MJPB) (www.morgan-multimedia.com)
MMES        Matrox MPEG-2 I-frame
MP2v        Microsoft S-Mpeg 4 version 1 (MP2v)
MP42        Microsoft S-Mpeg 4 version 2 (MP42)
MP43        Microsoft S-Mpeg 4 version 3 (MP43)
MP4S        Microsoft S-Mpeg 4 version 3 (MP4S)
MP4V        FFmpeg MPEG-4
MPG1        FFmpeg MPEG 1/2
MPG2        FFmpeg MPEG 1/2
MPG3        FFmpeg DivX ;-) (MS MPEG-4 v3)
MPG4        Microsoft MPEG-4
MPGI        Sigma Designs MPEG
MPNG        PNG images decoder
MSS1        Microsoft Windows Screen Video
MSZH        LCL (Lossless Codec Library) (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
M261        Microsoft H.261
M263        Microsoft H.263
M4S2        Microsoft Fully Compliant MPEG-4 v2 simple profile (M4S2)
m4s2        Microsoft Fully Compliant MPEG-4 v2 simple profile (m4s2)
MC12        ATI Motion Compensation Format (MC12)
MCAM        ATI Motion Compensation Format (MCAM)
MJ2C        Morgan Multimedia Motion JPEG2000
mJPG        IBM Motion JPEG w/ Huffman Tables
MJPG        Microsoft Motion JPEG DIB
MP42        Microsoft MPEG-4 (low-motion)
MP43        Microsoft MPEG-4 (fast-motion)
MP4S        Microsoft MPEG-4 (MP4S)
mp4s        Microsoft MPEG-4 (mp4s)
MPEG        Chromatic Research MPEG-1 Video I-Frame
MPG4        Microsoft MPEG-4 Video High Speed Compressor
MPGI        Sigma Designs MPEG
MRCA        FAST Multimedia Martin Regen Codec
MRLE        Microsoft Run Length Encoding
MSVC        Microsoft Video 1
MTX1        Matrox ?MTX1?
MTX2        Matrox ?MTX2?
MTX3        Matrox ?MTX3?
MTX4        Matrox ?MTX4?
MTX5        Matrox ?MTX5?
MTX6        Matrox ?MTX6?
MTX7        Matrox ?MTX7?
MTX8        Matrox ?MTX8?
MTX9        Matrox ?MTX9?
MV12        Motion Pixels Codec (old)
MWV1        Aware Motion Wavelets
nAVI        SMR Codec (hack of Microsoft MPEG-4) (IRC #shadowrealm)
NT00        NewTek LightWave HDTV YUV w/ Alpha (www.newtek.com)
NUV1        NuppelVideo
NTN1        Nogatech Video Compression 1
NVS0        nVidia GeForce Texture (NVS0)
NVS1        nVidia GeForce Texture (NVS1)
NVS2        nVidia GeForce Texture (NVS2)
NVS3        nVidia GeForce Texture (NVS3)
NVS4        nVidia GeForce Texture (NVS4)
NVS5        nVidia GeForce Texture (NVS5)
NVT0        nVidia GeForce Texture (NVT0)
NVT1        nVidia GeForce Texture (NVT1)
NVT2        nVidia GeForce Texture (NVT2)
NVT3        nVidia GeForce Texture (NVT3)
NVT4        nVidia GeForce Texture (NVT4)
NVT5        nVidia GeForce Texture (NVT5)
PIXL        MiroXL, Pinnacle PCTV
PDVC        I-O Data Device Digital Video Capture DV codec
PGVV        Radius Video Vision
PHMO        IBM Photomotion
PIM1        MPEG Realtime (Pinnacle Cards)
PIM2        Pegasus Imaging ?PIM2?
PIMJ        Pegasus Imaging Lossless JPEG
PVEZ        Horizons Technology PowerEZ
PVMM        PacketVideo Corporation MPEG-4
PVW2        Pegasus Imaging Wavelet Compression
Q1.0        Q-Team\'s QPEG 1.0 (www.q-team.de)
Q1.1        Q-Team\'s QPEG 1.1 (www.q-team.de)
QPEG        Q-Team QPEG 1.0
qpeq        Q-Team QPEG 1.1
RGB         Raw BGR32
RGBA        Raw RGB w/ Alpha
RMP4        REALmagic MPEG-4 (unauthorized XVID copy) (www.sigmadesigns.com)
ROQV        Id RoQ File Video Decoder
RPZA        Quicktime Apple Video (RPZA)
RUD0        Rududu video codec (http://rududu.ifrance.com/rududu/)
RV10        RealVideo 1.0 (aka RealVideo 5.0)
RV13        RealVideo 1.0 (RV13)
RV20        RealVideo G2
RV30        RealVideo 8
RV40        RealVideo 9
RGBT        Raw RGB w/ Transparency
RLE         Microsoft Run Length Encoder
RLE4        Run Length Encoded (4bpp, 16-color)
RLE8        Run Length Encoded (8bpp, 256-color)
RT21        Intel Indeo RealTime Video 2.1
rv20        RealVideo G2
rv30        RealVideo 8
RVX         Intel RDX (RVX )
SMC         Apple Graphics (SMC )
SP54        Logitech Sunplus Sp54 Codec for Mustek GSmart Mini 2
SPIG        Radius Spigot
SVQ3        Sorenson Video 3 (Apple Quicktime 5)
s422        Tekram VideoCap C210 YUV 4:2:2
SDCC        Sun Communication Digital Camera Codec
SFMC        CrystalNet Surface Fitting Method
SMSC        Radius SMSC
SMSD        Radius SMSD
smsv        WorldConnect Wavelet Video
SPIG        Radius Spigot
SPLC        Splash Studios ACM Audio Codec (www.splashstudios.net)
SQZ2        Microsoft VXTreme Video Codec V2
STVA        ST Microelectronics CMOS Imager Data (Bayer)
STVB        ST Microelectronics CMOS Imager Data (Nudged Bayer)
STVC        ST Microelectronics CMOS Imager Data (Bunched)
STVX        ST Microelectronics CMOS Imager Data (Extended CODEC Data Format)
STVY        ST Microelectronics CMOS Imager Data (Extended CODEC Data Format with Correction Data)
SV10        Sorenson Video R1
SVQ1        Sorenson Video
T420        Toshiba YUV 4:2:0
TM2A        Duck TrueMotion Archiver 2.0 (www.duck.com)
TVJP        Pinnacle/Truevision Targa 2000 board (TVJP)
TVMJ        Pinnacle/Truevision Targa 2000 board (TVMJ)
TY0N        Tecomac Low-Bit Rate Codec (www.tecomac.com)
TY2C        Trident Decompression Driver
TLMS        TeraLogic Motion Intraframe Codec (TLMS)
TLST        TeraLogic Motion Intraframe Codec (TLST)
TM20        Duck TrueMotion 2.0
TM2X        Duck TrueMotion 2X
TMIC        TeraLogic Motion Intraframe Codec (TMIC)
TMOT        Horizons Technology TrueMotion S
tmot        Horizons TrueMotion Video Compression
TR20        Duck TrueMotion RealTime 2.0
TSCC        TechSmith Screen Capture Codec
TV10        Tecomac Low-Bit Rate Codec
TY2N        Trident ?TY2N?
U263        UB Video H.263/H.263+/H.263++ Decoder
UMP4        UB Video MPEG 4 (www.ubvideo.com)
UYNV        Nvidia UYVY packed 4:2:2
UYVP        Evans & Sutherland YCbCr 4:2:2 extended precision
UCOD        eMajix.com ClearVideo
ULTI        IBM Ultimotion
UYVY        UYVY packed 4:2:2
V261        Lucent VX2000S
VIFP        VFAPI Reader Codec (www.yks.ne.jp/~hori/)
VIV1        FFmpeg H263+ decoder
VIV2        Vivo H.263
VQC2        Vector-quantised codec 2 (research) http://eprints.ecs.soton.ac.uk/archive/00001310/01/VTC97-js.pdf)
VTLP        Alaris VideoGramPiX
VYU9        ATI YUV (VYU9)
VYUY        ATI YUV (VYUY)
V261        Lucent VX2000S
V422        Vitec Multimedia 24-bit YUV 4:2:2 Format
V655        Vitec Multimedia 16-bit YUV 4:2:2 Format
VCR1        ATI Video Codec 1
VCR2        ATI Video Codec 2
VCR3        ATI VCR 3.0
VCR4        ATI VCR 4.0
VCR5        ATI VCR 5.0
VCR6        ATI VCR 6.0
VCR7        ATI VCR 7.0
VCR8        ATI VCR 8.0
VCR9        ATI VCR 9.0
VDCT        Vitec Multimedia Video Maker Pro DIB
VDOM        VDOnet VDOWave
VDOW        VDOnet VDOLive (H.263)
VDTZ        Darim Vison VideoTizer YUV
VGPX        Alaris VideoGramPiX
VIDS        Vitec Multimedia YUV 4:2:2 CCIR 601 for V422
VIVO        Vivo H.263 v2.00
vivo        Vivo H.263
VIXL        Miro/Pinnacle Video XL
VLV1        VideoLogic/PURE Digital Videologic Capture
VP30        On2 VP3.0
VP31        On2 VP3.1
VX1K        Lucent VX1000S Video Codec
VX2K        Lucent VX2000S Video Codec
VXSP        Lucent VX1000SP Video Codec
WBVC        Winbond W9960
WHAM        Microsoft Video 1 (WHAM)
WINX        Winnov Software Compression
WJPG        AverMedia Winbond JPEG
WMV1        Windows Media Video V7
WMV2        Windows Media Video V8
WMV3        Windows Media Video V9
WNV1        Winnov Hardware Compression
XYZP        Extended PAL format XYZ palette (www.riff.org)
x263        Xirlink H.263
XLV0        NetXL Video Decoder
XMPG        Xing MPEG (I-Frame only)
XVID        XviD MPEG-4 (www.xvid.org)
XXAN        ?XXAN?
YU92        Intel YUV (YU92)
YUNV        Nvidia Uncompressed YUV 4:2:2
YUVP        Extended PAL format YUV palette (www.riff.org)
Y211        YUV 2:1:1 Packed
Y411        YUV 4:1:1 Packed
Y41B        Weitek YUV 4:1:1 Planar
Y41P        Brooktree PC1 YUV 4:1:1 Packed
Y41T        Brooktree PC1 YUV 4:1:1 with transparency
Y42B        Weitek YUV 4:2:2 Planar
Y42T        Brooktree UYUV 4:2:2 with transparency
Y422        ADS Technologies Copy of UYVY used in Pyro WebCam firewire camera
Y800        Simple, single Y plane for monochrome images
Y8          Grayscale video
YC12        Intel YUV 12 codec
YUV8        Winnov Caviar YUV8
YUV9        Intel YUV9
YUY2        Uncompressed YUV 4:2:2
YUYV        Canopus YUV
YV12        YVU12 Planar
YVU9        Intel YVU9 Planar (8-bpp Y plane, followed by 8-bpp 4x4 U and V planes)
YVYU        YVYU 4:2:2 Packed
ZLIB        Lossless Codec Library zlib compression (www.geocities.co.jp/Playtown-Denei/2837/LRC.htm)
ZPEG        Metheus Video Zipper

Definition at line 1595 of file module.audio-video.riff.php.

1595 {
1596
1597 $begin = __LINE__;
1598
1982 return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
1983 }

References getid3_lib\EmbeddedLookup().

Referenced by getid3_asf\getid3_asf(), getid3_real\getid3_real(), and getid3_riff().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFparseWAVEFORMATex()

getid3_riff::RIFFparseWAVEFORMATex (   $WaveFormatExData)

Definition at line 1339 of file module.audio-video.riff.php.

1339 {
1340 // shortcut
1341 $WaveFormatEx['raw'] = array();
1342 $WaveFormatEx_raw = &$WaveFormatEx['raw'];
1343
1344 $WaveFormatEx_raw['wFormatTag'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 0, 2));
1345 $WaveFormatEx_raw['nChannels'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 2, 2));
1346 $WaveFormatEx_raw['nSamplesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 4, 4));
1347 $WaveFormatEx_raw['nAvgBytesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 8, 4));
1348 $WaveFormatEx_raw['nBlockAlign'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 12, 2));
1349 $WaveFormatEx_raw['wBitsPerSample'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 14, 2));
1350 if (strlen($WaveFormatExData) > 16) {
1351 $WaveFormatEx_raw['cbSize'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 16, 2));
1352 }
1353
1354 $WaveFormatEx['codec'] = getid3_riff::RIFFwFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1355 $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1356 $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1357 $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1358 $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1359
1360 return $WaveFormatEx;
1361 }
RIFFwFormatTagLookup($wFormatTag)

References getid3_lib\LittleEndian2Int(), and RIFFwFormatTagLookup().

Referenced by getid3_asf\getid3_asf(), getid3_riff(), and getid3_shorten\getid3_shorten().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFparseWavPackHeader()

getid3_riff::RIFFparseWavPackHeader (   $WavPackChunkData,
$ThisFileInfo 
)

Definition at line 1364 of file module.audio-video.riff.php.

1364 {
1365 // typedef struct {
1366 // char ckID [4];
1367 // long ckSize;
1368 // short version;
1369 // short bits; // added for version 2.00
1370 // short flags, shift; // added for version 3.00
1371 // long total_samples, crc, crc2;
1372 // char extension [4], extra_bc, extras [3];
1373 // } WavpackHeader;
1374
1375 // shortcut
1376 $ThisFileInfo['wavpack'] = array();
1377 $thisfile_wavpack = &$ThisFileInfo['wavpack'];
1378
1379 $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1380 if ($thisfile_wavpack['version'] >= 2) {
1381 $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1382 }
1383 if ($thisfile_wavpack['version'] >= 3) {
1384 $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1385 $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1386 $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1387 $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1388 $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1389 $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1390 $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1391 for ($i = 0; $i <= 2; $i++) {
1392 $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1393 }
1394
1395 // shortcut
1396 $thisfile_wavpack['flags'] = array();
1397 $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1398
1399 $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1400 $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1401 $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1402 $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1403 $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1404 $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1405 $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1406 $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1407 $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1408 $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1409 $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1410 $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1411 $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1412 $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1413 $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1414 $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1415 $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1416 $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1417 $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1418 $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1419 }
1420
1421 return true;
1422 }

References getid3_lib\LittleEndian2Int().

Referenced by ParseRIFF().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFwFormatTagLookup()

getid3_riff::RIFFwFormatTagLookup (   $wFormatTag)

This is not a comment!

0x0000      Microsoft Unknown Wave Format
0x0001      Pulse Code Modulation (PCM)
0x0002      Microsoft ADPCM
0x0003      IEEE Float
0x0004      Compaq Computer VSELP
0x0005      IBM CVSD
0x0006      Microsoft A-Law
0x0007      Microsoft mu-Law
0x0008      Microsoft DTS
0x0010      OKI ADPCM
0x0011      Intel DVI/IMA ADPCM
0x0012      Videologic MediaSpace ADPCM
0x0013      Sierra Semiconductor ADPCM
0x0014      Antex Electronics G.723 ADPCM
0x0015      DSP Solutions DigiSTD
0x0016      DSP Solutions DigiFIX
0x0017      Dialogic OKI ADPCM
0x0018      MediaVision ADPCM
0x0019      Hewlett-Packard CU
0x0020      Yamaha ADPCM
0x0021      Speech Compression Sonarc
0x0022      DSP Group TrueSpeech
0x0023      Echo Speech EchoSC1
0x0024      Audiofile AF36
0x0025      Audio Processing Technology APTX
0x0026      AudioFile AF10
0x0027      Prosody 1612
0x0028      LRC
0x0030      Dolby AC2
0x0031      Microsoft GSM 6.10
0x0032      MSNAudio
0x0033      Antex Electronics ADPCME
0x0034      Control Resources VQLPC
0x0035      DSP Solutions DigiREAL
0x0036      DSP Solutions DigiADPCM
0x0037      Control Resources CR10
0x0038      Natural MicroSystems VBXADPCM
0x0039      Crystal Semiconductor IMA ADPCM
0x003A      EchoSC3
0x003B      Rockwell ADPCM
0x003C      Rockwell Digit LK
0x003D      Xebec
0x0040      Antex Electronics G.721 ADPCM
0x0041      G.728 CELP
0x0042      MSG723
0x0050      MPEG Layer-2 or Layer-1
0x0052      RT24
0x0053      PAC
0x0055      MPEG Layer-3
0x0059      Lucent G.723
0x0060      Cirrus
0x0061      ESPCM
0x0062      Voxware
0x0063      Canopus Atrac
0x0064      G.726 ADPCM
0x0065      G.722 ADPCM
0x0066      DSAT
0x0067      DSAT Display
0x0069      Voxware Byte Aligned
0x0070      Voxware AC8
0x0071      Voxware AC10
0x0072      Voxware AC16
0x0073      Voxware AC20
0x0074      Voxware MetaVoice
0x0075      Voxware MetaSound
0x0076      Voxware RT29HW
0x0077      Voxware VR12
0x0078      Voxware VR18
0x0079      Voxware TQ40
0x0080      Softsound
0x0081      Voxware TQ60
0x0082      MSRT24
0x0083      G.729A
0x0084      MVI MV12
0x0085      DF G.726
0x0086      DF GSM610
0x0088      ISIAudio
0x0089      Onlive
0x0091      SBC24
0x0092      Dolby AC3 SPDIF
0x0093      MediaSonic G.723
0x0094      Aculab PLC    Prosody 8kbps
0x0097      ZyXEL ADPCM
0x0098      Philips LPCBB
0x0099      Packed
0x00FF      AAC
0x0100      Rhetorex ADPCM
0x0101      IBM mu-law
0x0102      IBM A-law
0x0103      IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
0x0111      Vivo G.723
0x0112      Vivo Siren
0x0123      Digital G.723
0x0125      Sanyo LD ADPCM
0x0130      Sipro Lab Telecom ACELP NET
0x0131      Sipro Lab Telecom ACELP 4800
0x0132      Sipro Lab Telecom ACELP 8V3
0x0133      Sipro Lab Telecom G.729
0x0134      Sipro Lab Telecom G.729A
0x0135      Sipro Lab Telecom Kelvin
0x0140      Windows Media Video V8
0x0150      Qualcomm PureVoice
0x0151      Qualcomm HalfRate
0x0155      Ring Zero Systems TUB GSM
0x0160      Microsoft Audio 1
0x0161      Windows Media Audio V7 / V8 / V9
0x0162      Windows Media Audio Professional V9
0x0163      Windows Media Audio Lossless V9
0x0200      Creative Labs ADPCM
0x0202      Creative Labs Fastspeech8
0x0203      Creative Labs Fastspeech10
0x0210      UHER Informatic GmbH ADPCM
0x0220      Quarterdeck
0x0230      I-link Worldwide VC
0x0240      Aureal RAW Sport
0x0250      Interactive Products HSX
0x0251      Interactive Products RPELP
0x0260      Consistent Software CS2
0x0270      Sony SCX
0x0300      Fujitsu FM Towns Snd
0x0400      BTV Digital
0x0401      Intel Music Coder
0x0450      QDesign Music
0x0680      VME VMPCM
0x0681      AT&T Labs TPC
0x08AE      ClearJump LiteWave
0x1000      Olivetti GSM
0x1001      Olivetti ADPCM
0x1002      Olivetti CELP
0x1003      Olivetti SBC
0x1004      Olivetti OPR
0x1100      Lernout & Hauspie Codec (0x1100)
0x1101      Lernout & Hauspie CELP Codec (0x1101)
0x1102      Lernout & Hauspie SBC Codec (0x1102)
0x1103      Lernout & Hauspie SBC Codec (0x1103)
0x1104      Lernout & Hauspie SBC Codec (0x1104)
0x1400      Norris
0x1401      AT&T ISIAudio
0x1500      Soundspace Music Compression
0x181C      VoxWare RT24 Speech
0x1FC4      NCT Soft ALF2CD (www.nctsoft.com)
0x2000      Dolby AC3
0x2001      Dolby DTS
0x2002      WAVE_FORMAT_14_4
0x2003      WAVE_FORMAT_28_8
0x2004      WAVE_FORMAT_COOK
0x2005      WAVE_FORMAT_DNET
0x674F      Ogg Vorbis 1
0x6750      Ogg Vorbis 2
0x6751      Ogg Vorbis 3
0x676F      Ogg Vorbis 1+
0x6770      Ogg Vorbis 2+
0x6771      Ogg Vorbis 3+
0x7A21      GSM-AMR (CBR, no SID)
0x7A22      GSM-AMR (VBR, including SID)
0xFFFE      WAVE_FORMAT_EXTENSIBLE
0xFFFF      WAVE_FORMAT_DEVELOPMENT

Definition at line 1424 of file module.audio-video.riff.php.

1424 {
1425
1426 $begin = __LINE__;
1427
1590 return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
1591
1592 }

References getid3_lib\EmbeddedLookup().

Referenced by RIFFparseWAVEFORMATex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ waveSNDMtagLookup()

static getid3_riff::waveSNDMtagLookup (   $tagshortname)
static

This is not a comment!

©kwd        keywords
©BPM        bpm
©trt        tracktitle
©des        description
©gen        category
©fin        featuredinstrument
©LID        longid
©bex        bwdescription
©pub        publisher
©cdt        cdtitle
©alb        library
©com        composer

Definition at line 1993 of file module.audio-video.riff.php.

1993 {
1994 $begin = __LINE__;
1995
2013 return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
2014 }

References getid3_lib\EmbeddedLookup().

+ Here is the call graph for this function:

◆ wFormatTagLookup()

static getid3_riff::wFormatTagLookup (   $wFormatTag)
static

This is not a comment!

0x0000      Microsoft Unknown Wave Format
0x0001      Pulse Code Modulation (PCM)
0x0002      Microsoft ADPCM
0x0003      IEEE Float
0x0004      Compaq Computer VSELP
0x0005      IBM CVSD
0x0006      Microsoft A-Law
0x0007      Microsoft mu-Law
0x0008      Microsoft DTS
0x0010      OKI ADPCM
0x0011      Intel DVI/IMA ADPCM
0x0012      Videologic MediaSpace ADPCM
0x0013      Sierra Semiconductor ADPCM
0x0014      Antex Electronics G.723 ADPCM
0x0015      DSP Solutions DigiSTD
0x0016      DSP Solutions DigiFIX
0x0017      Dialogic OKI ADPCM
0x0018      MediaVision ADPCM
0x0019      Hewlett-Packard CU
0x0020      Yamaha ADPCM
0x0021      Speech Compression Sonarc
0x0022      DSP Group TrueSpeech
0x0023      Echo Speech EchoSC1
0x0024      Audiofile AF36
0x0025      Audio Processing Technology APTX
0x0026      AudioFile AF10
0x0027      Prosody 1612
0x0028      LRC
0x0030      Dolby AC2
0x0031      Microsoft GSM 6.10
0x0032      MSNAudio
0x0033      Antex Electronics ADPCME
0x0034      Control Resources VQLPC
0x0035      DSP Solutions DigiREAL
0x0036      DSP Solutions DigiADPCM
0x0037      Control Resources CR10
0x0038      Natural MicroSystems VBXADPCM
0x0039      Crystal Semiconductor IMA ADPCM
0x003A      EchoSC3
0x003B      Rockwell ADPCM
0x003C      Rockwell Digit LK
0x003D      Xebec
0x0040      Antex Electronics G.721 ADPCM
0x0041      G.728 CELP
0x0042      MSG723
0x0050      MPEG Layer-2 or Layer-1
0x0052      RT24
0x0053      PAC
0x0055      MPEG Layer-3
0x0059      Lucent G.723
0x0060      Cirrus
0x0061      ESPCM
0x0062      Voxware
0x0063      Canopus Atrac
0x0064      G.726 ADPCM
0x0065      G.722 ADPCM
0x0066      DSAT
0x0067      DSAT Display
0x0069      Voxware Byte Aligned
0x0070      Voxware AC8
0x0071      Voxware AC10
0x0072      Voxware AC16
0x0073      Voxware AC20
0x0074      Voxware MetaVoice
0x0075      Voxware MetaSound
0x0076      Voxware RT29HW
0x0077      Voxware VR12
0x0078      Voxware VR18
0x0079      Voxware TQ40
0x0080      Softsound
0x0081      Voxware TQ60
0x0082      MSRT24
0x0083      G.729A
0x0084      MVI MV12
0x0085      DF G.726
0x0086      DF GSM610
0x0088      ISIAudio
0x0089      Onlive
0x0091      SBC24
0x0092      Dolby AC3 SPDIF
0x0093      MediaSonic G.723
0x0094      Aculab PLC    Prosody 8kbps
0x0097      ZyXEL ADPCM
0x0098      Philips LPCBB
0x0099      Packed
0x00FF      AAC
0x0100      Rhetorex ADPCM
0x0101      IBM mu-law
0x0102      IBM A-law
0x0103      IBM AVC Adaptive Differential Pulse Code Modulation (ADPCM)
0x0111      Vivo G.723
0x0112      Vivo Siren
0x0123      Digital G.723
0x0125      Sanyo LD ADPCM
0x0130      Sipro Lab Telecom ACELP NET
0x0131      Sipro Lab Telecom ACELP 4800
0x0132      Sipro Lab Telecom ACELP 8V3
0x0133      Sipro Lab Telecom G.729
0x0134      Sipro Lab Telecom G.729A
0x0135      Sipro Lab Telecom Kelvin
0x0140      Windows Media Video V8
0x0150      Qualcomm PureVoice
0x0151      Qualcomm HalfRate
0x0155      Ring Zero Systems TUB GSM
0x0160      Microsoft Audio 1
0x0161      Windows Media Audio V7 / V8 / V9
0x0162      Windows Media Audio Professional V9
0x0163      Windows Media Audio Lossless V9
0x0200      Creative Labs ADPCM
0x0202      Creative Labs Fastspeech8
0x0203      Creative Labs Fastspeech10
0x0210      UHER Informatic GmbH ADPCM
0x0220      Quarterdeck
0x0230      I-link Worldwide VC
0x0240      Aureal RAW Sport
0x0250      Interactive Products HSX
0x0251      Interactive Products RPELP
0x0260      Consistent Software CS2
0x0270      Sony SCX
0x0300      Fujitsu FM Towns Snd
0x0400      BTV Digital
0x0401      Intel Music Coder
0x0450      QDesign Music
0x0680      VME VMPCM
0x0681      AT&T Labs TPC
0x08AE      ClearJump LiteWave
0x1000      Olivetti GSM
0x1001      Olivetti ADPCM
0x1002      Olivetti CELP
0x1003      Olivetti SBC
0x1004      Olivetti OPR
0x1100      Lernout & Hauspie Codec (0x1100)
0x1101      Lernout & Hauspie CELP Codec (0x1101)
0x1102      Lernout & Hauspie SBC Codec (0x1102)
0x1103      Lernout & Hauspie SBC Codec (0x1103)
0x1104      Lernout & Hauspie SBC Codec (0x1104)
0x1400      Norris
0x1401      AT&T ISIAudio
0x1500      Soundspace Music Compression
0x181C      VoxWare RT24 Speech
0x1FC4      NCT Soft ALF2CD (www.nctsoft.com)
0x2000      Dolby AC3
0x2001      Dolby DTS
0x2002      WAVE_FORMAT_14_4
0x2003      WAVE_FORMAT_28_8
0x2004      WAVE_FORMAT_COOK
0x2005      WAVE_FORMAT_DNET
0x674F      Ogg Vorbis 1
0x6750      Ogg Vorbis 2
0x6751      Ogg Vorbis 3
0x676F      Ogg Vorbis 1+
0x6770      Ogg Vorbis 2+
0x6771      Ogg Vorbis 3+
0x7A21      GSM-AMR (CBR, no SID)
0x7A22      GSM-AMR (VBR, including SID)
0xFFFE      WAVE_FORMAT_EXTENSIBLE
0xFFFF      WAVE_FORMAT_DEVELOPMENT

Definition at line 2016 of file module.audio-video.riff.php.

2016 {
2017
2018 $begin = __LINE__;
2019
2182 return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
2183 }

References getid3_lib\EmbeddedLookup().

Referenced by Analyze(), and parseWAVEFORMATex().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $container

getid3_riff::$container = 'riff'
protected

Definition at line 32 of file module.audio-video.riff.php.


The documentation for this class was generated from the following files: