ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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)
 @staticvar array $DIVXTAGgenre @staticvar 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

Reimplemented from GetId3\Handler\BaseHandler.

Definition at line 49 of file Riff.php.

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 }
sprintf('%.4f', $callTime)
fseek($bytes, $whence=SEEK_SET)
static Bin2Dec($binstring, $signed=false)
Definition: Helper.php:496
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: Helper.php:374
static FixedPoint16_16($rawdata)
Definition: Helper.php:696
static RGADoriginatorLookup($originatorcode)
@staticvar array $RGADoriginator
Definition: Helper.php:1552
static LittleEndian2Float($byteword)
Definition: Helper.php:277
static intValueSupported($num)
@staticvar null $hasINT64
Definition: Helper.php:130
static XML2array($XMLstring)
Definition: Helper.php:798
static array_merge_noclobber($array1, $array2)
Definition: Helper.php:587
static BigEndian2Float($byteword)
ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic.
Definition: Helper.php:290
static LittleEndian2Int($byteword, $signed=false)
Definition: Helper.php:413
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
Definition: Helper.php:36
static RGADadjustmentLookup($rawadjustment, $signbit)
Definition: Helper.php:1571
static Dec2Bin($number)
Definition: Helper.php:472
static CastAsInt($floatnum)
Definition: Helper.php:107
static RGADnameLookup($namecode)
@staticvar array $RGADname
Definition: Helper.php:1534
static DateMac2Unix($macdate)
Definition: Helper.php:671
static RIFFfourccLookup($fourcc)
Definition: Riff.php:2101
ParseRIFF($startoffset, $maxoffset)
Definition: Riff.php:1331
static ParseDIVXTAG($DIVXTAG)
@staticvar array $DIVXTAGgenre @staticvar array $DIVXTAGrating
Definition: Riff.php:1830
static ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true)
Definition: Riff.php:1805
EitherEndian2Int($byteword, $signed=false)
Definition: Riff.php:2501
static RIFFwaveSNDMtagLookup($tagshortname)
Definition: Riff.php:1897
static RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray)
Definition: Riff.php:1265
static RIFFparseWAVEFORMATex($WaveFormatExData)
Definition: Riff.php:1707
static RIFFwFormatTagLookup($wFormatTag)
Definition: Riff.php:1926
$h
$info
Definition: example_052.php:80

References GetId3\Handler\BaseHandler\$getid3, $h, $info, 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\ParseBITMAPINFOHEADER(), 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\RIFFfourccLookup(), GetId3\Module\AudioVideo\Riff\RIFFparseWAVEFORMATex(), GetId3\Module\AudioVideo\Riff\RIFFwaveSNDMtagLookup(), GetId3\Module\AudioVideo\Riff\RIFFwFormatTagLookup(), sprintf, and GetId3\Lib\Helper\XML2array().

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

2502 {
2503 if ($this->getid3->info['fileformat'] == 'riff') {
2504 return Helper::LittleEndian2Int($byteword, $signed);
2505 }
2506
2507 return Helper::BigEndian2Int($byteword, false, $signed);
2508 }

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

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

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

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 }

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

+ Here is the caller graph for this function:

◆ ParseDIVXTAG()

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

@staticvar array $DIVXTAGgenre @staticvar array $DIVXTAGrating

Parameters
type$DIVXTAG
Returns
type

Definition at line 1830 of file Riff.php.

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 }

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

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

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 }
RIFFparseWavPackHeader($WavPackChunkData)
Definition: Riff.php:1737
static MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
Definition: Mp3.php:1930

References $info, 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(), GetId3\Module\AudioVideo\Riff\ParseRIFF(), and GetId3\Module\AudioVideo\Riff\RIFFparseWavPackHeader().

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

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

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 }
static LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: Helper.php:538

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

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

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 }

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

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

2102 {
2103 $begin = __LINE__;
2104
2492 return Helper::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
2493 }
static EmbeddedLookup($key, $begin, $end, $file, $name)
@staticvar type $cache
Definition: Helper.php:1759

References GetId3\Lib\Helper\EmbeddedLookup().

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

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

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 }

References GetId3\Lib\Helper\LittleEndian2Int(), and GetId3\Module\AudioVideo\Riff\RIFFwFormatTagLookup().

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

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

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 }

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

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

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

1898 {
1899 $begin = __LINE__;
1900
1918 return Helper::EmbeddedLookup($tagshortname, $begin, __LINE__, __FILE__, 'riff-sndm');
1919 }

References GetId3\Lib\Helper\EmbeddedLookup().

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

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

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 }

References GetId3\Lib\Helper\EmbeddedLookup().

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

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