/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at https://github.com/JamesHeinrich/getID3 //
// or https://www.getid3.org //
// or http://getid3.sourceforge.net //
// see readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.audio-video.riff.php //
// module for analyzing RIFF files //
// multiple formats supported by this module: //
// Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
// dependencies: module.audio.mp3.php //
// module.audio.ac3.php //
// module.audio.dts.php //
// ///
/////////////////////////////////////////////////////////////////
/**
* @todo Parse AC-3/DTS audio inside WAVE correctly
* @todo Rewrite RIFF parser totally
*/
if (!defined("GETID3_INCLUDEPATH")) {
// prevent path-exposing attacks that access modules directly on public webservers
}
getid3_lib::IncludeDependency(
GETID3_INCLUDEPATH . "module.audio.mp3.php",
__FILE__,
true
);
getid3_lib::IncludeDependency(
GETID3_INCLUDEPATH . "module.audio.ac3.php",
__FILE__,
true
);
getid3_lib::IncludeDependency(
GETID3_INCLUDEPATH . "module.audio.dts.php",
__FILE__,
true
);
class getid3_riff extends getid3_handler
{
protected $container = "riff"; // default
/**
* @return bool
*
* @throws getid3_exception
*/
public function Analyze()
{
$info = &$this->getid3->info;
// initialize these values to an empty array, otherwise they default to NULL
// and you can't append array values to a NULL value
$info["riff"] = ["raw" => []];
// Shortcuts
$thisfile_riff = &$info["riff"];
$thisfile_riff_raw = &$thisfile_riff["raw"];
$thisfile_audio = &$info["audio"];
$thisfile_video = &$info["video"];
$thisfile_audio_dataformat = &$thisfile_audio["dataformat"];
$thisfile_riff_audio = &$thisfile_riff["audio"];
$thisfile_riff_video = &$thisfile_riff["video"];
$thisfile_riff_WAVE = [];
$Original = [];
$Original["avdataoffset"] = $info["avdataoffset"];
$Original["avdataend"] = $info["avdataend"];
$this->fseek($info["avdataoffset"]);
$RIFFheader = $this->fread(12);
$offset = $this->ftell();
$RIFFtype = substr($RIFFheader, 0, 4);
$RIFFsize = substr($RIFFheader, 4, 4);
$RIFFsubtype = substr($RIFFheader, 8, 4);
switch ($RIFFtype) {
case "FORM": // AIFF, AIFC
//$info['fileformat'] = 'aiff';
$this->container = "aiff";
$thisfile_riff["header_size"] = $this->EitherEndian2Int(
$RIFFsize
);
$thisfile_riff[$RIFFsubtype] = $this->ParseRIFF(
$offset,
$offset + $thisfile_riff["header_size"] - 4
);
break;
case "RIFF": // AVI, WAV, etc
case "SDSS": // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
case "RMP3": // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
//$info['fileformat'] = 'riff';
$this->container = "riff";
$thisfile_riff["header_size"] = $this->EitherEndian2Int(
$RIFFsize
);
if ($RIFFsubtype == "RMP3") {
// RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
$RIFFsubtype = "WAVE";
}
if ($RIFFsubtype != "AMV ") {
// AMV files are RIFF-AVI files with parts of the spec deliberately broken, such as chunk size fields hardcoded to zero (because players known in hardware that these fields are always a certain size
// Handled separately in ParseRIFFAMV()
$thisfile_riff[$RIFFsubtype] = $this->ParseRIFF(
$offset,
$offset + $thisfile_riff["header_size"] - 4
);
}
if ($info["avdataend"] - $info["filesize"] == 1) {
// LiteWave appears to incorrectly *not* pad actual output file
// to nearest WORD boundary so may appear to be short by one
// byte, in which case - skip warning
$info["avdataend"] = $info["filesize"];
}
$nextRIFFoffset =
$Original["avdataoffset"] +
8 +
$thisfile_riff["header_size"]; // 8 = "RIFF" + 32-bit offset
while (
$nextRIFFoffset < min($info["filesize"], $info["avdataend"])
) {
try {
$this->fseek($nextRIFFoffset);
} catch (getid3_exception $e) {
if ($e->getCode() == 10) {
//$this->warning('RIFF parser: '.$e->getMessage());
$this->error(
"AVI extends beyond " .
round(PHP_INT_MAX / 1073741824) .
"GB and PHP filesystem functions cannot read that far, playtime may be wrong"
);
$this->warning(
"[avdataend] value may be incorrect, multiple AVIX chunks may be present"
);
break;
} else {
throw $e;
}
}
$nextRIFFheader = $this->fread(12);
if ($nextRIFFoffset == $info["avdataend"] - 1) {
if (substr($nextRIFFheader, 0, 1) == "