ILIAS  release_5-2 Revision v5.2.25-18-g3f80b82851
GetId3\Module\AudioVideo\Riff Class Reference

GetId3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //. More...

+ Inheritance diagram for GetId3\Module\AudioVideo\Riff:
+ Collaboration diagram for GetId3\Module\AudioVideo\Riff:

Public Member Functions

 analyze ()
 
 ParseRIFF ($startoffset, $maxoffset)
 
 ParseRIFFdata (&$RIFFdata)
 
 RIFFparseWavPackHeader ($WavPackChunkData)
 
 EitherEndian2Int ($byteword, $signed=false)
 
- Public Member Functions inherited from GetId3\Handler\BaseHandler
 __construct (GetId3Core $getid3, $call_module=null)
 
 analyze ()
 Analyze from file pointer. More...
 
 AnalyzeString (&$string)
 Analyze from string instead. More...
 
 saveAttachment (&$ThisFileInfoIndex, $filename, $offset, $length)
 

Static Public Member Functions

static RIFFcommentsParse (&$RIFFinfoArray, &$CommentsTargetArray)
 
static RIFFparseWAVEFORMATex ($WaveFormatExData)
 
static ParseBITMAPINFOHEADER ($BITMAPINFOHEADER, $littleEndian=true)
 
static ParseDIVXTAG ($DIVXTAG)
 array $DIVXTAGgenre array $DIVXTAGrating More...
 
static RIFFwaveSNDMtagLookup ($tagshortname)
 
static RIFFwFormatTagLookup ($wFormatTag)
 
static RIFFfourccLookup ($fourcc)
 

Additional Inherited Members

- Protected Member Functions inherited from GetId3\Handler\BaseHandler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
- Protected Attributes inherited from GetId3\Handler\BaseHandler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

Detailed Description

GetId3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //.

module for analyzing RIFF files multiple formats supported by this module Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX

Author
James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g http://www.getid3.org GetId3 GetId3 (optional) GetId3 (optional)

Definition at line 42 of file Riff.php.

Member Function Documentation

◆ analyze()

GetId3\Module\AudioVideo\Riff::analyze ( )
Returns
boolean

Definition at line 49 of file Riff.php.

References GetId3\Handler\BaseHandler\$getid3, $h, $info, array, GetId3\Lib\Helper\array_merge_noclobber(), GetId3\Lib\Helper\BigEndian2Float(), GetId3\Lib\Helper\BigEndian2Int(), GetId3\Lib\Helper\Bin2Dec(), GetId3\Lib\Helper\CastAsInt(), GetId3\Lib\Helper\DateMac2Unix(), GetId3\Lib\Helper\Dec2Bin(), GetId3\Module\AudioVideo\Riff\EitherEndian2Int(), GetId3\Lib\Helper\FixedPoint16_16(), GetId3\Handler\BaseHandler\fread(), GetId3\Handler\BaseHandler\fseek(), GetId3\Lib\Helper\intValueSupported(), GetId3\Lib\Helper\LittleEndian2Float(), GetId3\Lib\Helper\LittleEndian2Int(), GetId3\Module\AudioVideo\Riff\ParseDIVXTAG(), GetId3\Module\AudioVideo\Riff\ParseRIFF(), GetId3\Lib\Helper\PrintHexBytes(), GetId3\Lib\Helper\RGADadjustmentLookup(), GetId3\Lib\Helper\RGADnameLookup(), GetId3\Lib\Helper\RGADoriginatorLookup(), GetId3\Module\AudioVideo\Riff\RIFFcommentsParse(), GetId3\Module\AudioVideo\Riff\RIFFwaveSNDMtagLookup(), GetId3\Module\AudioVideo\Riff\RIFFwFormatTagLookup(), and GetId3\Lib\Helper\XML2array().

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

◆ EitherEndian2Int()

GetId3\Module\AudioVideo\Riff::EitherEndian2Int (   $byteword,
  $signed = false 
)
Parameters
type$byteword
type$signed
Returns
type

Definition at line 2501 of file Riff.php.

References GetId3\Lib\Helper\BigEndian2Int(), and GetId3\Lib\Helper\LittleEndian2Int().

Referenced by GetId3\Module\AudioVideo\Riff\analyze(), and GetId3\Module\AudioVideo\Riff\ParseRIFF().

2502  {
2503  if ($this->getid3->info['fileformat'] == 'riff') {
2504  return Helper::LittleEndian2Int($byteword, $signed);
2505  }
2506 
2507  return Helper::BigEndian2Int($byteword, false, $signed);
2508  }
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: Helper.php:374
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseBITMAPINFOHEADER()

static GetId3\Module\AudioVideo\Riff::ParseBITMAPINFOHEADER (   $BITMAPINFOHEADER,
  $littleEndian = true 
)
static
Parameters
type$BITMAPINFOHEADER
type$littleEndian
Returns
type

Definition at line 1805 of file Riff.php.

Referenced by GetId3\Module\AudioVideo\Matroska\analyze().

1806  {
1807  $functionname = ($littleEndian ? 'LittleEndian2Int' : 'BigEndian2Int');
1808  $parsed['biSize'] = Helper::$functionname(substr($BITMAPINFOHEADER, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
1809  $parsed['biWidth'] = Helper::$functionname(substr($BITMAPINFOHEADER, 4, 4)); // width of the bitmap in pixels
1810  $parsed['biHeight'] = Helper::$functionname(substr($BITMAPINFOHEADER, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
1811  $parsed['biPlanes'] = Helper::$functionname(substr($BITMAPINFOHEADER, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
1812  $parsed['biBitCount'] = Helper::$functionname(substr($BITMAPINFOHEADER, 14, 2)); // Specifies the number of bits per pixels
1813  $parsed['fourcc'] = substr($BITMAPINFOHEADER, 16, 4); // compression identifier
1814  $parsed['biSizeImage'] = Helper::$functionname(substr($BITMAPINFOHEADER, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
1815  $parsed['biXPelsPerMeter'] = Helper::$functionname(substr($BITMAPINFOHEADER, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
1816  $parsed['biYPelsPerMeter'] = Helper::$functionname(substr($BITMAPINFOHEADER, 28, 4)); // vertical resolution, in pixels per metre, of the target device
1817  $parsed['biClrUsed'] = Helper::$functionname(substr($BITMAPINFOHEADER, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
1818  $parsed['biClrImportant'] = Helper::$functionname(substr($BITMAPINFOHEADER, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
1819 
1820  return $parsed;
1821  }
+ Here is the caller graph for this function:

◆ ParseDIVXTAG()

static GetId3\Module\AudioVideo\Riff::ParseDIVXTAG (   $DIVXTAG)
static

array $DIVXTAGgenre array $DIVXTAGrating

Parameters
type$DIVXTAG
Returns
type

Definition at line 1830 of file Riff.php.

References array.

Referenced by GetId3\Module\AudioVideo\Riff\analyze().

1831  {
1832  // structure from "IDivX" source, Form1.frm, by "Greg Frazier of Daemonic Software Group", email: gfrazier@icestorm.net, web: http://dsg.cjb.net/
1833  // source available at http://files.divx-digest.com/download/c663efe7ef8ad2e90bf4af4d3ea6188a/on0SWN2r/edit/IDivX.zip
1834  // 'Byte Layout: '1111111111111111
1835  // '32 for Movie - 1 '1111111111111111
1836  // '28 for Author - 6 '6666666666666666
1837  // '4 for year - 2 '6666666666662222
1838  // '3 for genre - 3 '7777777777777777
1839  // '48 for Comments - 7 '7777777777777777
1840  // '1 for Rating - 4 '7777777777777777
1841  // '5 for Future Additions - 0 '333400000DIVXTAG
1842  // '128 bytes total
1843 
1844  static $DIVXTAGgenre = array(
1845  0 => 'Action',
1846  1 => 'Action/Adventure',
1847  2 => 'Adventure',
1848  3 => 'Adult',
1849  4 => 'Anime',
1850  5 => 'Cartoon',
1851  6 => 'Claymation',
1852  7 => 'Comedy',
1853  8 => 'Commercial',
1854  9 => 'Documentary',
1855  10 => 'Drama',
1856  11 => 'Home Video',
1857  12 => 'Horror',
1858  13 => 'Infomercial',
1859  14 => 'Interactive',
1860  15 => 'Mystery',
1861  16 => 'Music Video',
1862  17 => 'Other',
1863  18 => 'Religion',
1864  19 => 'Sci Fi',
1865  20 => 'Thriller',
1866  21 => 'Western',
1867  );
1868  static $DIVXTAGrating = array(
1869  0=>'Unrated',
1870  1=>'G',
1871  2=>'PG',
1872  3=>'PG-13',
1873  4=>'R',
1874  5=>'NC-17'
1875  );
1876 
1877  $parsed['title'] = trim(substr($DIVXTAG, 0, 32));
1878  $parsed['artist'] = trim(substr($DIVXTAG, 32, 28));
1879  $parsed['year'] = intval(trim(substr($DIVXTAG, 60, 4)));
1880  $parsed['comment'] = trim(substr($DIVXTAG, 64, 48));
1881  $parsed['genre_id'] = intval(trim(substr($DIVXTAG, 112, 3)));
1882  $parsed['rating_id'] = ord(substr($DIVXTAG, 115, 1));
1883  //$parsed['padding'] = substr($DIVXTAG, 116, 5); // 5-byte null
1884  //$parsed['magic'] = substr($DIVXTAG, 121, 7); // "DIVXTAG"
1885 
1886  $parsed['genre'] = (isset($DIVXTAGgenre[$parsed['genre_id']]) ? $DIVXTAGgenre[$parsed['genre_id']] : $parsed['genre_id']);
1887  $parsed['rating'] = (isset($DIVXTAGrating[$parsed['rating_id']]) ? $DIVXTAGrating[$parsed['rating_id']] : $parsed['rating_id']);
1888 
1889  return $parsed;
1890  }
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ ParseRIFF()

GetId3\Module\AudioVideo\Riff::ParseRIFF (   $startoffset,
  $maxoffset 
)
Parameters
type$startoffset
type$maxoffset
Returns
boolean

Definition at line 1331 of file Riff.php.

References $info, array, GetId3\Module\AudioVideo\Riff\EitherEndian2Int(), GetId3\Handler\BaseHandler\fread(), GetId3\Handler\BaseHandler\fseek(), GetId3\Handler\BaseHandler\ftell(), GetId3\GetId3Core\getTempDir(), GetId3\Lib\Helper\intValueSupported(), GetId3\Lib\Helper\LittleEndian2Int(), GetId3\Module\Audio\Mp3\MPEGaudioHeaderBytesValid(), and GetId3\Module\AudioVideo\Riff\RIFFparseWavPackHeader().

Referenced by GetId3\Module\AudioVideo\Riff\analyze().

1332  {
1333  $info = &$this->getid3->info;
1334 
1335  $maxoffset = min($maxoffset, $info['avdataend']);
1336 
1337  $RIFFchunk = false;
1338  $FoundAllChunksWeNeed = false;
1339 
1340  if (($startoffset < 0) || !Helper::intValueSupported($startoffset)) {
1341  $info['warning'][] = 'Unable to ParseRIFF() at '.$startoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1342 
1343  return false;
1344  }
1345  $max_usable_offset = min(PHP_INT_MAX - 1024, $maxoffset);
1346  if ($maxoffset > $max_usable_offset) {
1347  $info['warning'][] = 'ParseRIFF() may return incomplete data for chunk starting at '.$startoffset.' because beyond it extends to '.$maxoffset.', which is beyond the '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1348  }
1349  fseek($this->getid3->fp, $startoffset, SEEK_SET);
1350 
1351  while (ftell($this->getid3->fp) < $max_usable_offset) {
1352  $chunknamesize = fread($this->getid3->fp, 8);
1353  $chunkname = substr($chunknamesize, 0, 4);
1354  $chunksize = $this->EitherEndian2Int(substr($chunknamesize, 4, 4));
1355  if (strlen($chunkname) < 4) {
1356  $info['error'][] = 'Expecting chunk name at offset '.(ftell($this->getid3->fp) - 4).' but found nothing. Aborting RIFF parsing.';
1357  break;
1358  }
1359  if ($chunksize == 0) {
1360  if ($chunkname == 'JUNK') {
1361  // we'll allow zero-size JUNK frames
1362  } else {
1363  $info['warning'][] = 'Chunk size at offset '.(ftell($this->getid3->fp) - 4).' is zero. Aborting RIFF parsing.';
1364  break;
1365  }
1366  }
1367  if (($chunksize % 2) != 0) {
1368  // all structures are packed on word boundaries
1369  $chunksize++;
1370  }
1371 
1372  switch ($chunkname) {
1373  case 'LIST':
1374  $listname = fread($this->getid3->fp, 4);
1375  if (preg_match('#^(movi|rec )$#i', $listname)) {
1376  $RIFFchunk[$listname]['offset'] = ftell($this->getid3->fp) - 4;
1377  $RIFFchunk[$listname]['size'] = $chunksize;
1378 
1379  if ($FoundAllChunksWeNeed) {
1380 
1381  // skip over
1382 
1383  } else {
1384 
1385  $WhereWeWere = ftell($this->getid3->fp);
1386  $AudioChunkHeader = fread($this->getid3->fp, 12);
1387  $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1388  $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1389  $AudioChunkSize = Helper::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1390 
1391  if ($AudioChunkStreamType == 'wb') {
1392  $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1393  if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1394  // MP3
1395  if (GGetId3\Module\Audio\Mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1396  $getid3_temp = new GetId3Core();
1397  $getid3_temp->openfile($this->getid3->filename);
1398  $getid3_temp->info['avdataoffset'] = ftell($this->getid3->fp) - 4;
1399  $getid3_temp->info['avdataend'] = ftell($this->getid3->fp) + $AudioChunkSize;
1400  $getid3_mp3 = new Mp3($getid3_temp);
1401  $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
1402  if (isset($getid3_temp->info['mpeg']['audio'])) {
1403  $info['mpeg']['audio'] = $getid3_temp->info['mpeg']['audio'];
1404  $info['audio'] = $getid3_temp->info['audio'];
1405  $info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
1406  $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
1407  $info['audio']['channels'] = $info['mpeg']['audio']['channels'];
1408  $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
1409  $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
1410  //$info['bitrate'] = $info['audio']['bitrate'];
1411  }
1412  unset($getid3_temp, $getid3_mp3);
1413  }
1414 
1415  } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
1416 
1417  // AC3
1418  if (class_exists('GetId3\\Module\\Audio\\Ac3')) {
1419  $getid3_temp = new GetId3Core();
1420  $getid3_temp->openfile($this->getid3->filename);
1421  $getid3_temp->info['avdataoffset'] = ftell($this->getid3->fp) - 4;
1422  $getid3_temp->info['avdataend'] = ftell($this->getid3->fp) + $AudioChunkSize;
1423  $getid3_ac3 = new Ac3($getid3_temp);
1424  $getid3_ac3->analyze();
1425  if (empty($getid3_temp->info['error'])) {
1426  $info['audio'] = $getid3_temp->info['audio'];
1427  $info['ac3'] = $getid3_temp->info['ac3'];
1428  if (!empty($getid3_temp->info['warning'])) {
1429  foreach ($getid3_temp->info['warning'] as $key => $value) {
1430  $info['warning'][] = $value;
1431  }
1432  }
1433  }
1434  unset($getid3_temp, $getid3_ac3);
1435  }
1436 
1437  }
1438 
1439  }
1440 
1441  $FoundAllChunksWeNeed = true;
1442  fseek($this->getid3->fp, $WhereWeWere, SEEK_SET);
1443 
1444  }
1445  fseek($this->getid3->fp, $chunksize - 4, SEEK_CUR);
1446 
1447  //} elseif (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#i', $listname)) {
1448  //
1449  // // data chunk, ignore
1450  //
1451  } else {
1452 
1453  if (!isset($RIFFchunk[$listname])) {
1454  $RIFFchunk[$listname] = array();
1455  }
1456  $LISTchunkParent = $listname;
1457  $LISTchunkMaxOffset = ftell($this->getid3->fp) - 4 + $chunksize;
1458  if ($parsedChunk = $this->ParseRIFF(ftell($this->getid3->fp), ftell($this->getid3->fp) + $chunksize - 4)) {
1459  $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1460  }
1461 
1462  }
1463  break;
1464 
1465  default:
1466  if (preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname)) {
1467  $nextoffset = ftell($this->getid3->fp) + $chunksize;
1468  if (($nextoffset < 0) || !Helper::intValueSupported($nextoffset)) {
1469  $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1470  break 2;
1471  }
1472  fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1473  break;
1474  }
1475  $thisindex = 0;
1476  if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1477  $thisindex = count($RIFFchunk[$chunkname]);
1478  }
1479  $RIFFchunk[$chunkname][$thisindex]['offset'] = ftell($this->getid3->fp) - 8;
1480  $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1481  switch ($chunkname) {
1482  case 'data':
1483  $info['avdataoffset'] = ftell($this->getid3->fp);
1484  $info['avdataend'] = $info['avdataoffset'] + $chunksize;
1485 
1486  $RIFFdataChunkContentsTest = fread($this->getid3->fp, 36);
1487 
1488  if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1489 
1490  // Probably is MP3 data
1491  if (GetId3\Module\Audio\Mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
1492  $getid3_temp = new GetId3Core();
1493  $getid3_temp->openfile($this->getid3->filename);
1494  $getid3_temp->info['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1495  $getid3_temp->info['avdataend'] = $RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1496  $getid3_mp3 = new Mp3($getid3_temp);
1497  $getid3_mp3->getOnlyMPEGaudioInfo($RIFFchunk[$chunkname][$thisindex]['offset'], false);
1498  if (empty($getid3_temp->info['error'])) {
1499  $info['mpeg'] = $getid3_temp->info['mpeg'];
1500  $info['audio'] = $getid3_temp->info['audio'];
1501  }
1502  unset($getid3_temp, $getid3_mp3);
1503  }
1504 
1505  } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
1506 
1507  // This is probably AC-3 data
1508  if (class_exists('GetId3\\Module\\Audio\\Ac3')) {
1509  $getid3_temp = new GetId3Core();
1510  $getid3_temp->openfile($this->getid3->filename);
1511  $getid3_temp->info['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1512  $getid3_temp->info['avdataend'] = $RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1513  $getid3_ac3 = new Ac3($getid3_temp);
1514  $getid3_ac3->analyze();
1515  if (empty($getid3_temp->info['error'])) {
1516  $info['audio'] = $getid3_temp->info['audio'];
1517  $info['ac3'] = $getid3_temp->info['ac3'];
1518  $info['warning'] = $getid3_temp->info['warning'];
1519  }
1520  unset($getid3_temp, $getid3_ac3);
1521  }
1522 
1523  } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) == "\x77\x0B")) {
1524 
1525  // Dolby Digital WAV
1526  // AC-3 content, but not encoded in same format as normal AC-3 file
1527  // For one thing, byte order is swapped
1528 
1529  if (class_exists('GetId3\\Module\\Audio\\Ac3')) {
1530  // ok to use tmpfile here - only 56 bytes
1531  if ($RIFFtempfilename = tempnam(GetId3Core::getTempDir(), 'id3')) {
1532  if ($fd_temp = fopen($RIFFtempfilename, 'wb')) {
1533  for ($i = 0; $i < 28; $i += 2) {
1534  // swap byte order
1535  fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1536  fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1537  }
1538  fclose($fd_temp);
1539 
1540  $getid3_temp = new GetId3Core();
1541  $getid3_temp->openfile($RIFFtempfilename);
1542  $getid3_temp->info['avdataend'] = 20;
1543  $getid3_ac3 = new Ac3($getid3_temp);
1544  $getid3_ac3->analyze();
1545  if (empty($getid3_temp->info['error'])) {
1546  $info['audio'] = $getid3_temp->info['audio'];
1547  $info['ac3'] = $getid3_temp->info['ac3'];
1548  $info['warning'] = $getid3_temp->info['warning'];
1549  } else {
1550  $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): '.implode(';', $getid3_temp->info['error']);
1551  }
1552  unset($getid3_ac3, $getid3_temp);
1553  } else {
1554  $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): failed to write temp file';
1555  }
1556  unlink($RIFFtempfilename);
1557 
1558  } else {
1559  $info['error'][] = 'Error parsing Dolby Digital WAV (AC3-in-RIFF): failed to write temp file';
1560  }
1561 
1562  }
1563 
1564  } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) == 'wvpk')) {
1565 
1566  // This is WavPack data
1567  $info['wavpack']['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1568  $info['wavpack']['size'] = Helper::LittleEndian2Int(substr($RIFFdataChunkContentsTest, 4, 4));
1569  $this->RIFFparseWavPackHeader(substr($RIFFdataChunkContentsTest, 8, 28));
1570 
1571  } else {
1572 
1573  // This is some other kind of data (quite possibly just PCM)
1574  // do nothing special, just skip it
1575 
1576  }
1577  $nextoffset = $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize;
1578  if (($nextoffset < 0) || !Helper::intValueSupported($nextoffset)) {
1579  $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1580  break 3;
1581  }
1582  fseek($this->getid3->fp, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
1583  break;
1584 
1585  case 'iXML':
1586  case 'bext':
1587  case 'cart':
1588  case 'fmt ':
1589  case 'strh':
1590  case 'strf':
1591  case 'indx':
1592  case 'MEXT':
1593  case 'DISP':
1594  // always read data in
1595  case 'JUNK':
1596  // should be: never read data in
1597  // but some programs write their version strings in a JUNK chunk (e.g. VirtualDub, AVIdemux, etc)
1598  if ($chunksize < 1048576) {
1599  if ($chunksize > 0) {
1600  $RIFFchunk[$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1601  if ($chunkname == 'JUNK') {
1602  if (preg_match('#^([\\x20-\\x7F]+)#', $RIFFchunk[$chunkname][$thisindex]['data'], $matches)) {
1603  // only keep text characters [chr(32)-chr(127)]
1604  $info['riff']['comments']['junk'][] = trim($matches[1]);
1605  }
1606  // but if nothing there, ignore
1607  // remove the key in either case
1608  unset($RIFFchunk[$chunkname][$thisindex]['data']);
1609  }
1610  }
1611  } else {
1612  $info['warning'][] = 'chunk "'.$chunkname.'" at offset '.ftell($this->getid3->fp).' is unexpectedly larger than 1MB (claims to be '.number_format($chunksize).' bytes), skipping data';
1613  $nextoffset = ftell($this->getid3->fp) + $chunksize;
1614  if (($nextoffset < 0) || !Helper::intValueSupported($nextoffset)) {
1615  $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1616  break 3;
1617  }
1618  fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1619  }
1620  break;
1621 
1622  default:
1623  if (!preg_match('#^[0-9]{2}(wb|pc|dc|db)$#', $chunkname) && !empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1624  $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1625  $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1626  unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1627  unset($RIFFchunk[$chunkname][$thisindex]['size']);
1628  if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1629  unset($RIFFchunk[$chunkname][$thisindex]);
1630  }
1631  if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1632  unset($RIFFchunk[$chunkname]);
1633  }
1634  $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1635  //} elseif (in_array($chunkname, array('ID3 ')) || (($chunksize > 0) && ($chunksize < 2048))) {
1636  } elseif (($chunksize > 0) && ($chunksize < 2048)) {
1637  // only read data in if smaller than 2kB
1638  $RIFFchunk[$chunkname][$thisindex]['data'] = fread($this->getid3->fp, $chunksize);
1639  } else {
1640  $nextoffset = ftell($this->getid3->fp) + $chunksize;
1641  if (($nextoffset < 0) || !Helper::intValueSupported($nextoffset)) {
1642  $info['warning'][] = 'Unable to parse chunk at offset '.$nextoffset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
1643  break 3;
1644  }
1645  fseek($this->getid3->fp, $nextoffset, SEEK_SET);
1646  }
1647  break;
1648  }
1649  break;
1650 
1651  }
1652 
1653  }
1654 
1655  return $RIFFchunk;
1656  }
ParseRIFF($startoffset, $maxoffset)
Definition: Riff.php:1331
RIFFparseWavPackHeader($WavPackChunkData)
Definition: Riff.php:1737
fseek($bytes, $whence=SEEK_SET)
$info
Definition: example_052.php:80
Create styles array
The data for the language used.
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
static MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
Definition: Mp3.php:1930
static intValueSupported($num)
null $hasINT64
Definition: Helper.php:130
EitherEndian2Int($byteword, $signed=false)
Definition: Riff.php:2501
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ParseRIFFdata()

GetId3\Module\AudioVideo\Riff::ParseRIFFdata ( $RIFFdata)
Parameters
type$RIFFdata
Returns
boolean

Definition at line 1663 of file Riff.php.

References $info, array, GetId3\GetId3Core\getTempDir(), and GetId3\Lib\Helper\LittleEndian2String().

1664  {
1665  $info = &$this->getid3->info;
1666  if ($RIFFdata) {
1667  $tempfile = tempnam(GetId3Core::getTempDir(), 'getID3');
1668  $fp_temp = fopen($tempfile, 'wb');
1669  $RIFFdataLength = strlen($RIFFdata);
1670  $NewLengthString = Helper::LittleEndian2String($RIFFdataLength, 4);
1671  for ($i = 0; $i < 4; $i++) {
1672  $RIFFdata{$i + 4} = $NewLengthString{$i};
1673  }
1674  fwrite($fp_temp, $RIFFdata);
1675  fclose($fp_temp);
1676 
1677  $getid3_temp = new GetId3Core();
1678  $getid3_temp->openfile($tempfile);
1679  $getid3_temp->info['filesize'] = $RIFFdataLength;
1680  $getid3_temp->info['filenamepath'] = $info['filenamepath'];
1681  $getid3_temp->info['tags'] = $info['tags'];
1682  $getid3_temp->info['warning'] = $info['warning'];
1683  $getid3_temp->info['error'] = $info['error'];
1684  $getid3_temp->info['comments'] = $info['comments'];
1685  $getid3_temp->info['audio'] = (isset($info['audio']) ? $info['audio'] : array());
1686  $getid3_temp->info['video'] = (isset($info['video']) ? $info['video'] : array());
1687  $getid3_riff = new self($getid3_temp);
1688  $getid3_riff->analyze();
1689 
1690  $info['riff'] = $getid3_temp->info['riff'];
1691  $info['warning'] = $getid3_temp->info['warning'];
1692  $info['error'] = $getid3_temp->info['error'];
1693  $info['tags'] = $getid3_temp->info['tags'];
1694  $info['comments'] = $getid3_temp->info['comments'];
1695  unset($getid3_riff, $getid3_temp);
1696  unlink($tempfile);
1697  }
1698 
1699  return false;
1700  }
$info
Definition: example_052.php:80
static LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: Helper.php:538
Create styles array
The data for the language used.
+ Here is the call graph for this function:

◆ RIFFcommentsParse()

static GetId3\Module\AudioVideo\Riff::RIFFcommentsParse ( $RIFFinfoArray,
$CommentsTargetArray 
)
static
Parameters
type$RIFFinfoArray
type$CommentsTargetArray
Returns
boolean

Definition at line 1265 of file Riff.php.

References array.

Referenced by GetId3\Module\AudioVideo\Riff\analyze().

1266  {
1267  $RIFFinfoKeyLookup = array(
1268  'IARL'=>'archivallocation',
1269  'IART'=>'artist',
1270  'ICDS'=>'costumedesigner',
1271  'ICMS'=>'commissionedby',
1272  'ICMT'=>'comment',
1273  'ICNT'=>'country',
1274  'ICOP'=>'copyright',
1275  'ICRD'=>'creationdate',
1276  'IDIM'=>'dimensions',
1277  'IDIT'=>'digitizationdate',
1278  'IDPI'=>'resolution',
1279  'IDST'=>'distributor',
1280  'IEDT'=>'editor',
1281  'IENG'=>'engineers',
1282  'IFRM'=>'accountofparts',
1283  'IGNR'=>'genre',
1284  'IKEY'=>'keywords',
1285  'ILGT'=>'lightness',
1286  'ILNG'=>'language',
1287  'IMED'=>'orignalmedium',
1288  'IMUS'=>'composer',
1289  'INAM'=>'title',
1290  'IPDS'=>'productiondesigner',
1291  'IPLT'=>'palette',
1292  'IPRD'=>'product',
1293  'IPRO'=>'producer',
1294  'IPRT'=>'part',
1295  'IRTD'=>'rating',
1296  'ISBJ'=>'subject',
1297  'ISFT'=>'software',
1298  'ISGN'=>'secondarygenre',
1299  'ISHP'=>'sharpness',
1300  'ISRC'=>'sourcesupplier',
1301  'ISRF'=>'digitizationsource',
1302  'ISTD'=>'productionstudio',
1303  'ISTR'=>'starring',
1304  'ITCH'=>'encoded_by',
1305  'IWEB'=>'url',
1306  'IWRI'=>'writer'
1307  );
1308  foreach ($RIFFinfoKeyLookup as $key => $value) {
1309  if (isset($RIFFinfoArray[$key])) {
1310  foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1311  if (trim($commentdata['data']) != '') {
1312  if (isset($CommentsTargetArray[$value])) {
1313  $CommentsTargetArray[$value][] = trim($commentdata['data']);
1314  } else {
1315  $CommentsTargetArray[$value] = array(trim($commentdata['data']));
1316  }
1317  }
1318  }
1319  }
1320  }
1321 
1322  return true;
1323  }
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ RIFFfourccLookup()

static GetId3\Module\AudioVideo\Riff::RIFFfourccLookup (   $fourcc)
static
Parameters
type$fourcc
Returns
type

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 (gabes.nosp@m.t@fr.nosp@m.eemai.nosp@m.l.hu) GPEG Motion JPEG (gabes.nosp@m.t@fr.nosp@m.eemai.nosp@m.l.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 2101 of file Riff.php.

References GetId3\Lib\Helper\EmbeddedLookup().

Referenced by GetId3\Module\AudioVideo\Real\analyze(), GetId3\Module\AudioVideo\Asf\analyze(), and GetId3\Module\AudioVideo\Matroska\analyze().

2102  {
2103  $begin = __LINE__;
2104 
2492  return Helper::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2493  }
static EmbeddedLookup($key, $begin, $end, $file, $name)
type $cache
Definition: Helper.php:1759
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFparseWAVEFORMATex()

static GetId3\Module\AudioVideo\Riff::RIFFparseWAVEFORMATex (   $WaveFormatExData)
static
Parameters
type$WaveFormatExData
Returns
type

Definition at line 1707 of file Riff.php.

References array, and GetId3\Lib\Helper\LittleEndian2Int().

Referenced by GetId3\Module\Audio\Shorten\analyze(), GetId3\Module\AudioVideo\Asf\analyze(), and GetId3\Module\AudioVideo\Matroska\analyze().

1708  {
1709  // shortcut
1710  $WaveFormatEx['raw'] = array();
1711  $WaveFormatEx_raw = &$WaveFormatEx['raw'];
1712 
1713  $WaveFormatEx_raw['wFormatTag'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 0, 2));
1714  $WaveFormatEx_raw['nChannels'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 2, 2));
1715  $WaveFormatEx_raw['nSamplesPerSec'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 4, 4));
1716  $WaveFormatEx_raw['nAvgBytesPerSec'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 8, 4));
1717  $WaveFormatEx_raw['nBlockAlign'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 12, 2));
1718  $WaveFormatEx_raw['wBitsPerSample'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 14, 2));
1719  if (strlen($WaveFormatExData) > 16) {
1720  $WaveFormatEx_raw['cbSize'] = Helper::LittleEndian2Int(substr($WaveFormatExData, 16, 2));
1721  }
1722 
1723  $WaveFormatEx['codec'] = self::RIFFwFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1724  $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1725  $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1726  $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1727  $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1728 
1729  return $WaveFormatEx;
1730  }
Create styles array
The data for the language used.
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFparseWavPackHeader()

GetId3\Module\AudioVideo\Riff::RIFFparseWavPackHeader (   $WavPackChunkData)
Parameters
type$WavPackChunkData
Returns
boolean

Definition at line 1737 of file Riff.php.

References $info, array, and GetId3\Lib\Helper\LittleEndian2Int().

Referenced by GetId3\Module\AudioVideo\Riff\ParseRIFF().

1738  {
1739  // typedef struct {
1740  // char ckID [4];
1741  // long ckSize;
1742  // short version;
1743  // short bits; // added for version 2.00
1744  // short flags, shift; // added for version 3.00
1745  // long total_samples, crc, crc2;
1746  // char extension [4], extra_bc, extras [3];
1747  // } WavpackHeader;
1748 
1749  // shortcut
1750  $info = &$this->getid3->info;
1751  $info['wavpack'] = array();
1752  $thisfile_wavpack = &$info['wavpack'];
1753 
1754  $thisfile_wavpack['version'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1755  if ($thisfile_wavpack['version'] >= 2) {
1756  $thisfile_wavpack['bits'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1757  }
1758  if ($thisfile_wavpack['version'] >= 3) {
1759  $thisfile_wavpack['flags_raw'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1760  $thisfile_wavpack['shift'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1761  $thisfile_wavpack['total_samples'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1762  $thisfile_wavpack['crc1'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1763  $thisfile_wavpack['crc2'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1764  $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1765  $thisfile_wavpack['extra_bc'] = Helper::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1766  for ($i = 0; $i <= 2; $i++) {
1767  $thisfile_wavpack['extras'][] = Helper::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1768  }
1769 
1770  // shortcut
1771  $thisfile_wavpack['flags'] = array();
1772  $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1773 
1774  $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1775  $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1776  $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1777  $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1778  $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1779  $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1780  $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1781  $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1782  $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1783  $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1784  $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1785  $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1786  $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1787  $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1788  $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1789  $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1790  $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1791  $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1792  $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1793  $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1794  }
1795 
1796  return true;
1797  }
$info
Definition: example_052.php:80
Create styles array
The data for the language used.
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFwaveSNDMtagLookup()

static GetId3\Module\AudioVideo\Riff::RIFFwaveSNDMtagLookup (   $tagshortname)
static
Parameters
type$tagshortname
Returns
type

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 1897 of file Riff.php.

References GetId3\Lib\Helper\EmbeddedLookup().

Referenced by GetId3\Module\AudioVideo\Riff\analyze().

1898  {
1899  $begin = __LINE__;
1900 
1918  return Helper::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1919  }
static EmbeddedLookup($key, $begin, $end, $file, $name)
type $cache
Definition: Helper.php:1759
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RIFFwFormatTagLookup()

static GetId3\Module\AudioVideo\Riff::RIFFwFormatTagLookup (   $wFormatTag)
static
Parameters
type$wFormatTag
Returns
type

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 1926 of file Riff.php.

References GetId3\Lib\Helper\EmbeddedLookup().

Referenced by GetId3\Module\AudioVideo\Riff\analyze().

1927  {
1928  $begin = __LINE__;
1929 
2092  return Helper::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
2093 
2094  }
static EmbeddedLookup($key, $begin, $end, $file, $name)
type $cache
Definition: Helper.php:1759
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

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