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 ( )

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

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(), getid3_handler\fread(), getid3_handler\fseek(), getid3_handler\ftell(), getid3_riff(), getid3_lib\IncludeDependency(), getid3_lib\LittleEndian2Float(), getid3_lib\LittleEndian2Int(), ParseRIFF(), ParseRIFFAMV(), getid3_lib\PrintHexBytes(), getid3_lib\RGADadjustmentLookup(), getid3_lib\RGADnameLookup(), getid3_lib\RGADoriginatorLookup(), getid3_handler\warning(), and getid3_lib\XML2array().

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  }
getid3_riff(&$fd, &$ThisFileInfo)
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
ParseRIFFAMV($startoffset, $maxoffset)
$h
error($text)
Definition: getid3.php:1738
RGADadjustmentLookup($rawadjustment, $signbit)
Bin2Dec($binstring, $signed=false)
Definition: getid3.lib.php:316
DateMac2Unix($macdate)
Definition: getid3.lib.php:442
warning($text)
Definition: getid3.php:1744
FixedPoint16_16($rawdata)
Definition: getid3.lib.php:454
RGADnameLookup($namecode)
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
array_merge_noclobber($array1, $array2)
Definition: getid3.lib.php:376
$info
Definition: example_052.php:80
static XML2array($XMLstring)
Definition: getid3.lib.php:535
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)
fread($bytes)
Definition: getid3.php:1685
Dec2Bin($number)
Definition: getid3.lib.php:302
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
BigEndian2Float($byteword)
Definition: getid3.lib.php:159
CastAsInt($floatnum)
Definition: getid3.lib.php:60
RGADoriginatorLookup($originatorcode)
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
LittleEndian2Float($byteword)
Definition: getid3.lib.php:154
PrintHexBytes($string, $hex=true, $spaces=true, $htmlsafe=true)
Definition: getid3.lib.php:17
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
+ Here is the call graph for this function:

◆ EitherEndian2Int() [1/2]

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

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

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

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

1986  {
1987  if ($ThisFileInfo['fileformat'] == 'riff') {
1988  return getid3_lib::LittleEndian2Int($byteword, $signed);
1989  }
1990  return getid3_lib::BigEndian2Int($byteword, false, $signed);
1991  }
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EitherEndian2Int() [2/2]

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

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

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

2579  {
2580  if ($this->container == 'riff') {
2581  return getid3_lib::LittleEndian2Int($byteword, $signed);
2582  }
2583  return getid3_lib::BigEndian2Int($byteword, false, $signed);
2584  }
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
+ Here is the call 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.

References getid3_lib\EmbeddedLookup().

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

2185  {
2186 
2187  $begin = __LINE__;
2188 
2576  return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2577  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ 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.

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().

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  }
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
RGADadjustmentLookup($rawadjustment, $signbit)
Bin2Dec($binstring, $signed=false)
Definition: getid3.lib.php:316
DateMac2Unix($macdate)
Definition: getid3.lib.php:442
FixedPoint16_16($rawdata)
Definition: getid3.lib.php:454
RGADnameLookup($namecode)
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
array_merge_noclobber($array1, $array2)
Definition: getid3.lib.php:376
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)
fread($bytes)
Definition: getid3.php:1685
Dec2Bin($number)
Definition: getid3.lib.php:302
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
BigEndian2Float($byteword)
Definition: getid3.lib.php:159
CastAsInt($floatnum)
Definition: getid3.lib.php:60
ParseRIFFdata(&$RIFFdata, &$ThisFileInfo)
RGADoriginatorLookup($originatorcode)
RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray)
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
LittleEndian2Float($byteword)
Definition: getid3.lib.php:154
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
RIFFparseWAVEFORMATex($WaveFormatExData)
+ 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.

Referenced by getid3_matroska\Analyze().

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  }
+ 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.

Referenced by getid3_wavpack\Analyze().

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  }
+ 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  }

◆ ParseRIFF() [1/2]

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

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

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

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

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  }
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
RIFFparseWavPackHeader($WavPackChunkData, &$ThisFileInfo)
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)
fread($bytes)
Definition: getid3.php:1685
MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false)
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
getID3() by James Heinrich info@getid3.org //
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFF() [2/2]

getid3_riff::ParseRIFF (   $startoffset,
  $maxoffset 
)

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

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().

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  }
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
static $syncwords
Possible syncwords indicating bitstream encoding.
error($text)
Definition: getid3.php:1738
warning($text)
Definition: getid3.php:1744
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
$info
Definition: example_052.php:80
parseWavPackHeader($WavPackChunkData)
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)
fread($bytes)
Definition: getid3.php:1685
MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
getID3() by James Heinrich info@getid3.org //
getID3() by James Heinrich info@getid3.org //
+ Here is the call graph for this function:

◆ ParseRIFFAMV()

getid3_riff::ParseRIFFAMV (   $startoffset,
  $maxoffset 
)

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

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

Referenced by Analyze().

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  }
warning($text)
Definition: getid3.php:1744
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
$info
Definition: example_052.php:80
fread($bytes)
Definition: getid3.php:1685
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
PrintHexBytes($string, $hex=true, $spaces=true, $htmlsafe=true)
Definition: getid3.lib.php:17
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFFdata() [1/2]

getid3_riff::ParseRIFFdata ( $RIFFdata,
$ThisFileInfo 
)

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

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

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

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  }
getid3_riff(&$fd, &$ThisFileInfo)
LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: getid3.lib.php:343
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFFdata() [2/2]

getid3_riff::ParseRIFFdata ( $RIFFdata)

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

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

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  }
getid3_riff(&$fd, &$ThisFileInfo)
LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: getid3.lib.php:343
$info
Definition: example_052.php:80
+ Here is the call graph for this function:

◆ parseWAVEFORMATex()

static getid3_riff::parseWAVEFORMATex (   $WaveFormatExData)
static

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

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

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  }
+ Here is the caller graph for this function:

◆ parseWavPackHeader()

getid3_riff::parseWavPackHeader (   $WavPackChunkData)

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

References $info, and getid3_lib\LittleEndian2Int().

Referenced by ParseRIFF().

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  }
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
$info
Definition: example_052.php:80
+ 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.

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

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  }
+ 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.

References getid3_lib\EmbeddedLookup().

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

1595  {
1596 
1597  $begin = __LINE__;
1598 
1982  return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
1983  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ 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.

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

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

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  }
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
RIFFwFormatTagLookup($wFormatTag)
+ 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.

References getid3_lib\LittleEndian2Int().

Referenced by ParseRIFF().

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  }
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
+ 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.

References getid3_lib\EmbeddedLookup().

Referenced by RIFFparseWAVEFORMATex().

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  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ 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.

References getid3_lib\EmbeddedLookup().

1993  {
1994  $begin = __LINE__;
1995 
2013  return getid3_lib::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
2014  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ 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.

References getid3_lib\EmbeddedLookup().

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  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ Here is the call 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 file: