Exemplo n.º 1
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'rar';
     if ($this->option_use_rar_extension === true) {
         if (function_exists('rar_open')) {
             if ($rp = rar_open($info['filenamepath'])) {
                 $info['rar']['files'] = array();
                 $entries = rar_list($rp);
                 foreach ($entries as $entry) {
                     $info['rar']['files'] = GetId3_Lib_Helper::array_merge_clobber($info['rar']['files'], GetId3_Lib_Helper::CreateDeepArray($entry->getName(), '/', $entry->getUnpackedSize()));
                 }
                 rar_close($rp);
                 return true;
             } else {
                 $info['error'][] = 'failed to rar_open(' . $info['filename'] . ')';
             }
         } else {
             $info['error'][] = 'RAR support does not appear to be available in this PHP installation';
         }
     } else {
         $info['error'][] = 'PHP-RAR processing has been disabled (set $getid3_rar->option_use_rar_extension=true to enable)';
     }
     return false;
 }
Exemplo n.º 2
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $DSSheader = fread($this->getid3->fp, 1256);
     if (!preg_match('#^(\\x02|\\x03)dss#', $DSSheader)) {
         $info['error'][] = 'Expecting "[02-03] 64 73 73" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($DSSheader, 0, 4)) . '"';
         return false;
     }
     // some structure information taken from http://cpansearch.perl.org/src/RGIBSON/Audio-DSS-0.02/lib/Audio/DSS.pm
     // shortcut
     $info['dss'] = array();
     $thisfile_dss =& $info['dss'];
     $info['fileformat'] = 'dss';
     $info['audio']['dataformat'] = 'dss';
     $info['audio']['bitrate_mode'] = 'cbr';
     //$thisfile_dss['encoding']              = 'ISO-8859-1';
     $thisfile_dss['version'] = ord(substr($DSSheader, 0, 1));
     $thisfile_dss['date_create'] = self::DSSdateStringToUnixDate(substr($DSSheader, 38, 12));
     $thisfile_dss['date_complete'] = self::DSSdateStringToUnixDate(substr($DSSheader, 50, 12));
     //$thisfile_dss['length']         =                         intval(substr($DSSheader,  62,   6)); // I thought time was in seconds, it's actually HHMMSS
     $thisfile_dss['length'] = intval(substr($DSSheader, 62, 2) * 3600 + substr($DSSheader, 64, 2) * 60 + substr($DSSheader, 66, 2));
     $thisfile_dss['priority'] = ord(substr($DSSheader, 793, 1));
     $thisfile_dss['comments'] = trim(substr($DSSheader, 798, 100));
     //$info['audio']['bits_per_sample']  = ?;
     //$info['audio']['sample_rate']      = ?;
     $info['audio']['channels'] = 1;
     $info['playtime_seconds'] = $thisfile_dss['length'];
     $info['audio']['bitrate'] = $info['filesize'] * 8 / $info['playtime_seconds'];
     return true;
 }
Exemplo n.º 3
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $EXEheader = fread($this->getid3->fp, 28);
     $magic = 'MZ';
     if (substr($EXEheader, 0, 2) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($EXEheader, 0, 2)) . '"';
         return false;
     }
     $info['fileformat'] = 'exe';
     $info['exe']['mz']['magic'] = 'MZ';
     $info['exe']['mz']['raw']['last_page_size'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 2, 2));
     $info['exe']['mz']['raw']['page_count'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 4, 2));
     $info['exe']['mz']['raw']['relocation_count'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 6, 2));
     $info['exe']['mz']['raw']['header_paragraphs'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 8, 2));
     $info['exe']['mz']['raw']['min_memory_paragraphs'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 10, 2));
     $info['exe']['mz']['raw']['max_memory_paragraphs'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 12, 2));
     $info['exe']['mz']['raw']['initial_ss'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 14, 2));
     $info['exe']['mz']['raw']['initial_sp'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 16, 2));
     $info['exe']['mz']['raw']['checksum'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 18, 2));
     $info['exe']['mz']['raw']['cs_ip'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 20, 4));
     $info['exe']['mz']['raw']['relocation_table_offset'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 24, 2));
     $info['exe']['mz']['raw']['overlay_number'] = GetId3_Lib_Helper::LittleEndian2Int(substr($EXEheader, 26, 2));
     $info['exe']['mz']['byte_size'] = ($info['exe']['mz']['raw']['page_count'] - 1) * 512 + $info['exe']['mz']['raw']['last_page_size'];
     $info['exe']['mz']['header_size'] = $info['exe']['mz']['raw']['header_paragraphs'] * 16;
     $info['exe']['mz']['memory_minimum'] = $info['exe']['mz']['raw']['min_memory_paragraphs'] * 16;
     $info['exe']['mz']['memory_recommended'] = $info['exe']['mz']['raw']['max_memory_paragraphs'] * 16;
     $info['error'][] = 'EXE parsing not enabled in this version of GetId3() [' . $this->getid3->version() . ']';
     return false;
 }
Exemplo n.º 4
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $SZIPHeader = fread($this->getid3->fp, 6);
     if (substr($SZIPHeader, 0, 4) != "SZ\n") {
         $info['error'][] = 'Expecting "53 5A 0A 04" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($SZIPHeader, 0, 4)) . '"';
         return false;
     }
     $info['fileformat'] = 'szip';
     $info['szip']['major_version'] = GetId3_Lib_Helper::BigEndian2Int(substr($SZIPHeader, 4, 1));
     $info['szip']['minor_version'] = GetId3_Lib_Helper::BigEndian2Int(substr($SZIPHeader, 5, 1));
     while (!feof($this->getid3->fp)) {
         $NextBlockID = fread($this->getid3->fp, 2);
         switch ($NextBlockID) {
             case 'SZ':
                 // Note that szip files can be concatenated, this has the same effect as
                 // concatenating the files. this also means that global header blocks
                 // might be present between directory/data blocks.
                 fseek($this->getid3->fp, 4, SEEK_CUR);
                 break;
             case 'BH':
                 $BHheaderbytes = GetId3_Lib_Helper::BigEndian2Int(fread($this->getid3->fp, 3));
                 $BHheaderdata = fread($this->getid3->fp, $BHheaderbytes);
                 $BHheaderoffset = 0;
                 while (strpos($BHheaderdata, "", $BHheaderoffset) > 0) {
                     //filename as \0 terminated string  (empty string indicates end)
                     //owner as \0 terminated string (empty is same as last file)
                     //group as \0 terminated string (empty is same as last file)
                     //3 byte filelength in this block
                     //2 byte access flags
                     //4 byte creation time (like in unix)
                     //4 byte modification time (like in unix)
                     //4 byte access time (like in unix)
                     $BHdataArray['filename'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, ""));
                     $BHheaderoffset += strlen($BHdataArray['filename']) + 1;
                     $BHdataArray['owner'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, ""));
                     $BHheaderoffset += strlen($BHdataArray['owner']) + 1;
                     $BHdataArray['group'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, ""));
                     $BHheaderoffset += strlen($BHdataArray['group']) + 1;
                     $BHdataArray['filelength'] = GetId3_Lib_Helper::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 3));
                     $BHheaderoffset += 3;
                     $BHdataArray['access_flags'] = GetId3_Lib_Helper::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 2));
                     $BHheaderoffset += 2;
                     $BHdataArray['creation_time'] = GetId3_Lib_Helper::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
                     $BHheaderoffset += 4;
                     $BHdataArray['modification_time'] = GetId3_Lib_Helper::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
                     $BHheaderoffset += 4;
                     $BHdataArray['access_time'] = GetId3_Lib_Helper::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
                     $BHheaderoffset += 4;
                     $info['szip']['BH'][] = $BHdataArray;
                 }
                 break;
             default:
                 break 2;
         }
     }
     return true;
 }
Exemplo n.º 5
0
 /**
  *
  * @return boolean
  */
 public function ParseBink()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'bink';
     $info['video']['dataformat'] = 'bink';
     $fileData = 'BIK' . fread($this->getid3->fp, 13);
     $info['bink']['data_size'] = GetId3_Lib_Helper::LittleEndian2Int(substr($fileData, 4, 4));
     $info['bink']['frame_count'] = GetId3_Lib_Helper::LittleEndian2Int(substr($fileData, 8, 2));
     if ($info['avdataend'] - $info['avdataoffset'] != $info['bink']['data_size'] + 8) {
         $info['error'][] = 'Probably truncated file: expecting ' . $info['bink']['data_size'] . ' bytes, found ' . ($info['avdataend'] - $info['avdataoffset']);
     }
     return true;
 }
Exemplo n.º 6
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $RKAUHeader = fread($this->getid3->fp, 20);
     $magic = 'RKA';
     if (substr($RKAUHeader, 0, 3) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($RKAUHeader, 0, 3)) . '"';
         return false;
     }
     $info['fileformat'] = 'rkau';
     $info['audio']['dataformat'] = 'rkau';
     $info['audio']['bitrate_mode'] = 'vbr';
     $info['rkau']['raw']['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 3, 1));
     $info['rkau']['version'] = '1.' . str_pad($info['rkau']['raw']['version'] & 0xf, 2, '0', STR_PAD_LEFT);
     if ($info['rkau']['version'] > 1.07 || $info['rkau']['version'] < 1.06) {
         $info['error'][] = 'This version of GetId3() [' . $this->getid3->version() . '] can only parse RKAU files v1.06 and 1.07 (this file is v' . $info['rkau']['version'] . ')';
         unset($info['rkau']);
         return false;
     }
     $info['rkau']['source_bytes'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 4, 4));
     $info['rkau']['sample_rate'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 8, 4));
     $info['rkau']['channels'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 12, 1));
     $info['rkau']['bits_per_sample'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 13, 1));
     $info['rkau']['raw']['quality'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 14, 1));
     $this->RKAUqualityLookup($info['rkau']);
     $info['rkau']['raw']['flags'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 15, 1));
     $info['rkau']['flags']['joint_stereo'] = (bool) (!($info['rkau']['raw']['flags'] & 0x1));
     $info['rkau']['flags']['streaming'] = (bool) ($info['rkau']['raw']['flags'] & 0x2);
     $info['rkau']['flags']['vrq_lossy_mode'] = (bool) ($info['rkau']['raw']['flags'] & 0x4);
     if ($info['rkau']['flags']['streaming']) {
         $info['avdataoffset'] += 20;
         $info['rkau']['compressed_bytes'] = GetId3_Lib_Helper::LittleEndian2Int(substr($RKAUHeader, 16, 4));
     } else {
         $info['avdataoffset'] += 16;
         $info['rkau']['compressed_bytes'] = $info['avdataend'] - $info['avdataoffset'] - 1;
     }
     // Note: compressed_bytes does not always equal what appears to be the actual number of compressed bytes,
     // sometimes it's more, sometimes less. No idea why(?)
     $info['audio']['lossless'] = $info['rkau']['lossless'];
     $info['audio']['channels'] = $info['rkau']['channels'];
     $info['audio']['bits_per_sample'] = $info['rkau']['bits_per_sample'];
     $info['audio']['sample_rate'] = $info['rkau']['sample_rate'];
     $info['playtime_seconds'] = $info['rkau']['source_bytes'] / ($info['rkau']['sample_rate'] * $info['rkau']['channels'] * ($info['rkau']['bits_per_sample'] / 8));
     $info['audio']['bitrate'] = $info['rkau']['compressed_bytes'] * 8 / $info['playtime_seconds'];
     return true;
 }
Exemplo n.º 7
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $AUheader = fread($this->getid3->fp, 8);
     $magic = '.snd';
     if (substr($AUheader, 0, 4) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" (".snd") at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($AUheader, 0, 4)) . '"';
         return false;
     }
     // shortcut
     $info['au'] = array();
     $thisfile_au =& $info['au'];
     $info['fileformat'] = 'au';
     $info['audio']['dataformat'] = 'au';
     $info['audio']['bitrate_mode'] = 'cbr';
     $thisfile_au['encoding'] = 'ISO-8859-1';
     $thisfile_au['header_length'] = GetId3_Lib_Helper::BigEndian2Int(substr($AUheader, 4, 4));
     $AUheader .= fread($this->getid3->fp, $thisfile_au['header_length'] - 8);
     $info['avdataoffset'] += $thisfile_au['header_length'];
     $thisfile_au['data_size'] = GetId3_Lib_Helper::BigEndian2Int(substr($AUheader, 8, 4));
     $thisfile_au['data_format_id'] = GetId3_Lib_Helper::BigEndian2Int(substr($AUheader, 12, 4));
     $thisfile_au['sample_rate'] = GetId3_Lib_Helper::BigEndian2Int(substr($AUheader, 16, 4));
     $thisfile_au['channels'] = GetId3_Lib_Helper::BigEndian2Int(substr($AUheader, 20, 4));
     $thisfile_au['comments']['comment'][] = trim(substr($AUheader, 24));
     $thisfile_au['data_format'] = $this->AUdataFormatNameLookup($thisfile_au['data_format_id']);
     $thisfile_au['used_bits_per_sample'] = $this->AUdataFormatUsedBitsPerSampleLookup($thisfile_au['data_format_id']);
     if ($thisfile_au['bits_per_sample'] = $this->AUdataFormatBitsPerSampleLookup($thisfile_au['data_format_id'])) {
         $info['audio']['bits_per_sample'] = $thisfile_au['bits_per_sample'];
     } else {
         unset($thisfile_au['bits_per_sample']);
     }
     $info['audio']['sample_rate'] = $thisfile_au['sample_rate'];
     $info['audio']['channels'] = $thisfile_au['channels'];
     if ($info['avdataoffset'] + $thisfile_au['data_size'] > $info['avdataend']) {
         $info['warning'][] = 'Possible truncated file - expecting "' . $thisfile_au['data_size'] . '" bytes of audio data, only found ' . ($info['avdataend'] - $info['avdataoffset']) . ' bytes"';
     }
     $info['playtime_seconds'] = $thisfile_au['data_size'] / ($thisfile_au['sample_rate'] * $thisfile_au['channels'] * ($thisfile_au['used_bits_per_sample'] / 8));
     $info['audio']['bitrate'] = $thisfile_au['data_size'] * 8 / $info['playtime_seconds'];
     return true;
 }
Exemplo n.º 8
0
 /**
  *
  * @staticvar type $shorten_present
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $ShortenHeader = fread($this->getid3->fp, 8);
     $magic = 'ajkg';
     if (substr($ShortenHeader, 0, 4) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($ShortenHeader, 0, 4)) . '"';
         return false;
     }
     $info['fileformat'] = 'shn';
     $info['audio']['dataformat'] = 'shn';
     $info['audio']['lossless'] = true;
     $info['audio']['bitrate_mode'] = 'vbr';
     $info['shn']['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ShortenHeader, 4, 1));
     fseek($this->getid3->fp, $info['avdataend'] - 12, SEEK_SET);
     $SeekTableSignatureTest = fread($this->getid3->fp, 12);
     $info['shn']['seektable']['present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) == 'SHNAMPSK');
     if ($info['shn']['seektable']['present']) {
         $info['shn']['seektable']['length'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SeekTableSignatureTest, 0, 4));
         $info['shn']['seektable']['offset'] = $info['avdataend'] - $info['shn']['seektable']['length'];
         fseek($this->getid3->fp, $info['shn']['seektable']['offset'], SEEK_SET);
         $SeekTableMagic = fread($this->getid3->fp, 4);
         $magic = 'SEEK';
         if ($SeekTableMagic != $magic) {
             $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['shn']['seektable']['offset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($SeekTableMagic) . '"';
             return false;
         } else {
             // typedef struct tag_TSeekEntry
             // {
             //   unsigned long SampleNumber;
             //   unsigned long SHNFileByteOffset;
             //   unsigned long SHNLastBufferReadPosition;
             //   unsigned short SHNByteGet;
             //   unsigned short SHNBufferOffset;
             //   unsigned short SHNFileBitOffset;
             //   unsigned long SHNGBuffer;
             //   unsigned short SHNBitShift;
             //   long CBuf0[3];
             //   long CBuf1[3];
             //   long Offset0[4];
             //   long Offset1[4];
             // }TSeekEntry;
             $SeekTableData = fread($this->getid3->fp, $info['shn']['seektable']['length'] - 16);
             $info['shn']['seektable']['entry_count'] = floor(strlen($SeekTableData) / 80);
             //$info['shn']['seektable']['entries'] = array();
             //$SeekTableOffset = 0;
             //for ($i = 0; $i < $info['shn']['seektable']['entry_count']; $i++) {
             //	$SeekTableEntry['sample_number'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_file_byte_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_last_buffer_read_position'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_byte_get'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_buffer_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_file_bit_offset'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	$SeekTableEntry['shn_gbuffer'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //	$SeekTableOffset += 4;
             //	$SeekTableEntry['shn_bit_shift'] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
             //	$SeekTableOffset += 2;
             //	for ($j = 0; $j < 3; $j++) {
             //		$SeekTableEntry['cbuf0'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 3; $j++) {
             //		$SeekTableEntry['cbuf1'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 4; $j++) {
             //		$SeekTableEntry['offset0'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //	for ($j = 0; $j < 4; $j++) {
             //		$SeekTableEntry['offset1'][$j] = GetId3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
             //		$SeekTableOffset += 4;
             //	}
             //
             //	$info['shn']['seektable']['entries'][] = $SeekTableEntry;
             //}
         }
     }
     if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
         $info['error'][] = 'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files';
         return false;
     }
     if (GetId3_GetId3::environmentIsWindows()) {
         $RequiredFiles = array('shorten.exe', 'cygwin1.dll', 'head.exe');
         foreach ($RequiredFiles as $required_file) {
             if (!is_readable(GetId3_GetId3::getHelperAppsDir() . $required_file)) {
                 $info['error'][] = GetId3_GetId3::getHelperAppsDir() . $required_file . ' does not exist';
                 return false;
             }
         }
         $commandline = GetId3_GetId3::getHelperAppsDir() . 'shorten.exe -x "' . $info['filenamepath'] . '" - | ' . GetId3_GetId3::getHelperAppsDir() . 'head.exe -c 64';
         $commandline = str_replace('/', '\\', $commandline);
     } else {
         static $shorten_present;
         if (!isset($shorten_present)) {
             $shorten_present = file_exists('/usr/local/bin/shorten') || `which shorten`;
         }
         if (!$shorten_present) {
             $info['error'][] = 'shorten binary was not found in path or /usr/local/bin';
             return false;
         }
         $commandline = (file_exists('/usr/local/bin/shorten') ? '/usr/local/bin/' : '') . 'shorten -x ' . escapeshellarg($info['filenamepath']) . ' - | head -c 64';
     }
     $output = `{$commandline}`;
     if (!empty($output) && substr($output, 12, 4) == 'fmt ') {
         $fmt_size = GetId3_Lib_Helper::LittleEndian2Int(substr($output, 16, 4));
         $DecodedWAVFORMATEX = GetId3_Module_AudioVideo_Riff::RIFFparseWAVEFORMATex(substr($output, 20, $fmt_size));
         $info['audio']['channels'] = $DecodedWAVFORMATEX['channels'];
         $info['audio']['bits_per_sample'] = $DecodedWAVFORMATEX['bits_per_sample'];
         $info['audio']['sample_rate'] = $DecodedWAVFORMATEX['sample_rate'];
         if (substr($output, 20 + $fmt_size, 4) == 'data') {
             $info['playtime_seconds'] = GetId3_Lib_Helper::LittleEndian2Int(substr($output, 20 + 4 + $fmt_size, 4)) / $DecodedWAVFORMATEX['raw']['nAvgBytesPerSec'];
         } else {
             $info['error'][] = 'shorten failed to decode DATA chunk to expected location, cannot determine playtime';
             return false;
         }
         $info['audio']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'] * 8;
     } else {
         $info['error'][] = 'shorten failed to decode file to WAV for parsing';
         return false;
     }
     return true;
 }
Exemplo n.º 9
0
 public function RemoveID3v1()
 {
     // File MUST be writeable - CHMOD(646) at least
     if (!empty($this->filename) && is_readable($this->filename) && is_writable($this->filename) && is_file($this->filename)) {
         $this->setRealFileSize();
         if ($this->filesize <= 0 || !GetId3_Lib_Helper::intValueSupported($this->filesize)) {
             $this->errors[] = 'Unable to RemoveID3v1(' . $this->filename . ') because filesize (' . $this->filesize . ') is larger than ' . round(PHP_INT_MAX / 1073741824) . 'GB';
             return false;
         }
         if ($fp_source = fopen($this->filename, 'r+b')) {
             fseek($fp_source, -128, SEEK_END);
             if (fread($fp_source, 3) == 'TAG') {
                 ftruncate($fp_source, $this->filesize - 128);
             } else {
                 // no ID3v1 tag to begin with - do nothing
             }
             fclose($fp_source);
             return true;
         } else {
             $this->errors[] = 'Could not fopen(' . $this->filename . ', "r+b")';
         }
     } else {
         $this->errors[] = $this->filename . ' is not writeable';
     }
     return false;
 }
Exemplo n.º 10
0
 /**
  *
  * @return boolean
  */
 public function ParseMPCsv6()
 {
     // this is SV4 - SV6
     $info =& $this->getid3->info;
     $thisfile_mpc_header =& $info['mpc']['header'];
     $offset = 0;
     $thisfile_mpc_header['size'] = 8;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $MPCheaderData = fread($this->getid3->fp, $thisfile_mpc_header['size']);
     // add size of file header to avdataoffset - calc bitrate correctly + MD5 data
     $info['avdataoffset'] += $thisfile_mpc_header['size'];
     // Most of this code adapted from Jurgen Faul's MPEGplus source code - thanks Jurgen! :)
     $HeaderDWORD[0] = GetId3_Lib_Helper::LittleEndian2Int(substr($MPCheaderData, 0, 4));
     $HeaderDWORD[1] = GetId3_Lib_Helper::LittleEndian2Int(substr($MPCheaderData, 4, 4));
     // DDDD DDDD  CCCC CCCC  BBBB BBBB  AAAA AAAA
     // aaaa aaaa  abcd dddd  dddd deee  eeff ffff
     //
     // a = bitrate       = anything
     // b = IS            = anything
     // c = MS            = anything
     // d = streamversion = 0000000004 or 0000000005 or 0000000006
     // e = maxband       = anything
     // f = blocksize     = 000001 for SV5+, anything(?) for SV4
     $thisfile_mpc_header['target_bitrate'] = ($HeaderDWORD[0] & 0xff800000) >> 23;
     $thisfile_mpc_header['intensity_stereo'] = (bool) (($HeaderDWORD[0] & 0x400000) >> 22);
     $thisfile_mpc_header['mid_side_stereo'] = (bool) (($HeaderDWORD[0] & 0x200000) >> 21);
     $thisfile_mpc_header['stream_version_major'] = ($HeaderDWORD[0] & 0x1ff800) >> 11;
     $thisfile_mpc_header['stream_version_minor'] = 0;
     // no sub-version numbers before SV7
     $thisfile_mpc_header['max_band'] = ($HeaderDWORD[0] & 0x7c0) >> 6;
     // related to lowpass frequency, not sure how it translates exactly
     $thisfile_mpc_header['block_size'] = $HeaderDWORD[0] & 0x3f;
     switch ($thisfile_mpc_header['stream_version_major']) {
         case 4:
             $thisfile_mpc_header['frame_count'] = $HeaderDWORD[1] >> 16;
             break;
         case 5:
         case 6:
             $thisfile_mpc_header['frame_count'] = $HeaderDWORD[1];
             break;
         default:
             $info['error'] = 'Expecting 4, 5 or 6 in version field, found ' . $thisfile_mpc_header['stream_version_major'] . ' instead';
             unset($info['mpc']);
             return false;
             break;
     }
     if ($thisfile_mpc_header['stream_version_major'] > 4 && $thisfile_mpc_header['block_size'] != 1) {
         $info['warning'][] = 'Block size expected to be 1, actual value found: ' . $thisfile_mpc_header['block_size'];
     }
     $thisfile_mpc_header['sample_rate'] = 44100;
     // AB: used by all files up to SV7
     $info['audio']['sample_rate'] = $thisfile_mpc_header['sample_rate'];
     $thisfile_mpc_header['samples'] = $thisfile_mpc_header['frame_count'] * 1152 * $info['audio']['channels'];
     if ($thisfile_mpc_header['target_bitrate'] == 0) {
         $info['audio']['bitrate_mode'] = 'vbr';
     } else {
         $info['audio']['bitrate_mode'] = 'cbr';
     }
     $info['mpc']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 * 44100 / $thisfile_mpc_header['frame_count'] / 1152;
     $info['audio']['bitrate'] = $info['mpc']['bitrate'];
     $info['audio']['encoder'] = 'SV' . $thisfile_mpc_header['stream_version_major'];
     return true;
 }
Exemplo n.º 11
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'gif';
     $info['video']['dataformat'] = 'gif';
     $info['video']['lossless'] = true;
     $info['video']['pixel_aspect_ratio'] = (double) 1;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $GIFheader = fread($this->getid3->fp, 13);
     $offset = 0;
     $info['gif']['header']['raw']['identifier'] = substr($GIFheader, $offset, 3);
     $offset += 3;
     $magic = 'GIF';
     if ($info['gif']['header']['raw']['identifier'] != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($info['gif']['header']['raw']['identifier']) . '"';
         unset($info['fileformat']);
         unset($info['gif']);
         return false;
     }
     $info['gif']['header']['raw']['version'] = substr($GIFheader, $offset, 3);
     $offset += 3;
     $info['gif']['header']['raw']['width'] = GetId3_Lib_Helper::LittleEndian2Int(substr($GIFheader, $offset, 2));
     $offset += 2;
     $info['gif']['header']['raw']['height'] = GetId3_Lib_Helper::LittleEndian2Int(substr($GIFheader, $offset, 2));
     $offset += 2;
     $info['gif']['header']['raw']['flags'] = GetId3_Lib_Helper::LittleEndian2Int(substr($GIFheader, $offset, 1));
     $offset += 1;
     $info['gif']['header']['raw']['bg_color_index'] = GetId3_Lib_Helper::LittleEndian2Int(substr($GIFheader, $offset, 1));
     $offset += 1;
     $info['gif']['header']['raw']['aspect_ratio'] = GetId3_Lib_Helper::LittleEndian2Int(substr($GIFheader, $offset, 1));
     $offset += 1;
     $info['video']['resolution_x'] = $info['gif']['header']['raw']['width'];
     $info['video']['resolution_y'] = $info['gif']['header']['raw']['height'];
     $info['gif']['version'] = $info['gif']['header']['raw']['version'];
     $info['gif']['header']['flags']['global_color_table'] = (bool) ($info['gif']['header']['raw']['flags'] & 0x80);
     if ($info['gif']['header']['raw']['flags'] & 0x80) {
         // Number of bits per primary color available to the original image, minus 1
         $info['gif']['header']['bits_per_pixel'] = 3 * ((($info['gif']['header']['raw']['flags'] & 0x70) >> 4) + 1);
     } else {
         $info['gif']['header']['bits_per_pixel'] = 0;
     }
     $info['gif']['header']['flags']['global_color_sorted'] = (bool) ($info['gif']['header']['raw']['flags'] & 0x40);
     if ($info['gif']['header']['flags']['global_color_table']) {
         // the number of bytes contained in the Global Color Table. To determine that
         // actual size of the color table, raise 2 to [the value of the field + 1]
         $info['gif']['header']['global_color_size'] = pow(2, ($info['gif']['header']['raw']['flags'] & 0x7) + 1);
         $info['video']['bits_per_sample'] = ($info['gif']['header']['raw']['flags'] & 0x7) + 1;
     } else {
         $info['gif']['header']['global_color_size'] = 0;
     }
     if ($info['gif']['header']['raw']['aspect_ratio'] != 0) {
         // Aspect Ratio = (Pixel Aspect Ratio + 15) / 64
         $info['gif']['header']['aspect_ratio'] = ($info['gif']['header']['raw']['aspect_ratio'] + 15) / 64;
     }
     //		if ($info['gif']['header']['flags']['global_color_table']) {
     //			$GIFcolorTable = fread($this->getid3->fp, 3 * $info['gif']['header']['global_color_size']);
     //			$offset = 0;
     //			for ($i = 0; $i < $info['gif']['header']['global_color_size']; $i++) {
     //				$red   = GetId3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1));
     //				$green = GetId3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1));
     //				$blue  = GetId3_lib::LittleEndian2Int(substr($GIFcolorTable, $offset++, 1));
     //				$info['gif']['global_color_table'][$i] = (($red << 16) | ($green << 8) | ($blue));
     //			}
     //		}
     //
     //		// Image Descriptor
     //		while (!feof($this->getid3->fp)) {
     //			$NextBlockTest = fread($this->getid3->fp, 1);
     //			switch ($NextBlockTest) {
     //
     //				case ',': // ',' - Image separator character
     //
     //					$ImageDescriptorData = $NextBlockTest.fread($this->getid3->fp, 9);
     //					$ImageDescriptor = array();
     //					$ImageDescriptor['image_left']   = GetId3_lib::LittleEndian2Int(substr($ImageDescriptorData, 1, 2));
     //					$ImageDescriptor['image_top']    = GetId3_lib::LittleEndian2Int(substr($ImageDescriptorData, 3, 2));
     //					$ImageDescriptor['image_width']  = GetId3_lib::LittleEndian2Int(substr($ImageDescriptorData, 5, 2));
     //					$ImageDescriptor['image_height'] = GetId3_lib::LittleEndian2Int(substr($ImageDescriptorData, 7, 2));
     //					$ImageDescriptor['flags_raw']    = GetId3_lib::LittleEndian2Int(substr($ImageDescriptorData, 9, 1));
     //					$ImageDescriptor['flags']['use_local_color_map'] = (bool) ($ImageDescriptor['flags_raw'] & 0x80);
     //					$ImageDescriptor['flags']['image_interlaced']    = (bool) ($ImageDescriptor['flags_raw'] & 0x40);
     //					$info['gif']['image_descriptor'][] = $ImageDescriptor;
     //
     //					if ($ImageDescriptor['flags']['use_local_color_map']) {
     //
     //						$info['warning'][] = 'This version of GetId3() cannot parse local color maps for GIFs';
     //						return true;
     //
     //					}
     //echo 'Start of raster data: '.ftell($this->getid3->fp).'<BR>';
     //					$RasterData = array();
     //					$RasterData['code_size']        = GetId3_lib::LittleEndian2Int(fread($this->getid3->fp, 1));
     //					$RasterData['block_byte_count'] = GetId3_lib::LittleEndian2Int(fread($this->getid3->fp, 1));
     //					$info['gif']['raster_data'][count($info['gif']['image_descriptor']) - 1] = $RasterData;
     //
     //					$CurrentCodeSize = $RasterData['code_size'] + 1;
     //					for ($i = 0; $i < pow(2, $RasterData['code_size']); $i++) {
     //						$DefaultDataLookupTable[$i] = chr($i);
     //					}
     //					$DefaultDataLookupTable[pow(2, $RasterData['code_size']) + 0] = ''; // Clear Code
     //					$DefaultDataLookupTable[pow(2, $RasterData['code_size']) + 1] = ''; // End Of Image Code
     //
     //
     //					$NextValue = $this->GetLSBits($CurrentCodeSize);
     //					echo 'Clear Code: '.$NextValue.'<BR>';
     //
     //					$NextValue = $this->GetLSBits($CurrentCodeSize);
     //					echo 'First Color: '.$NextValue.'<BR>';
     //
     //					$Prefix = $NextValue;
     //$i = 0;
     //					while ($i++ < 20) {
     //						$NextValue = $this->GetLSBits($CurrentCodeSize);
     //						echo $NextValue.'<BR>';
     //					}
     //return true;
     //					break;
     //
     //				case '!':
     //					// GIF Extension Block
     //					$ExtensionBlockData = $NextBlockTest.fread($this->getid3->fp, 2);
     //					$ExtensionBlock = array();
     //					$ExtensionBlock['function_code']  = GetId3_lib::LittleEndian2Int(substr($ExtensionBlockData, 1, 1));
     //					$ExtensionBlock['byte_length']    = GetId3_lib::LittleEndian2Int(substr($ExtensionBlockData, 2, 1));
     //					$ExtensionBlock['data']           = fread($this->getid3->fp, $ExtensionBlock['byte_length']);
     //					$info['gif']['extension_blocks'][] = $ExtensionBlock;
     //					break;
     //
     //				case ';':
     //					$info['gif']['terminator_offset'] = ftell($this->getid3->fp) - 1;
     //					// GIF Terminator
     //					break;
     //
     //				default:
     //					break;
     //
     //
     //			}
     //		}
     return true;
 }
Exemplo n.º 12
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $LPACheader = fread($this->getid3->fp, 14);
     if (substr($LPACheader, 0, 4) != 'LPAC') {
         $info['error'][] = 'Expected "LPAC" at offset ' . $info['avdataoffset'] . ', found "' . $StreamMarker . '"';
         return false;
     }
     $info['avdataoffset'] += 14;
     $info['fileformat'] = 'lpac';
     $info['audio']['dataformat'] = 'lpac';
     $info['audio']['lossless'] = true;
     $info['audio']['bitrate_mode'] = 'vbr';
     $info['lpac']['file_version'] = GetId3_Lib_Helper::BigEndian2Int(substr($LPACheader, 4, 1));
     $flags['audio_type'] = GetId3_Lib_Helper::BigEndian2Int(substr($LPACheader, 5, 1));
     $info['lpac']['total_samples'] = GetId3_Lib_Helper::BigEndian2Int(substr($LPACheader, 6, 4));
     $flags['parameters'] = GetId3_Lib_Helper::BigEndian2Int(substr($LPACheader, 10, 4));
     $info['lpac']['flags']['is_wave'] = (bool) ($flags['audio_type'] & 0x40);
     $info['lpac']['flags']['stereo'] = (bool) ($flags['audio_type'] & 0x4);
     $info['lpac']['flags']['24_bit'] = (bool) ($flags['audio_type'] & 0x2);
     $info['lpac']['flags']['16_bit'] = (bool) ($flags['audio_type'] & 0x1);
     if ($info['lpac']['flags']['24_bit'] && $info['lpac']['flags']['16_bit']) {
         $info['warning'][] = '24-bit and 16-bit flags cannot both be set';
     }
     $info['lpac']['flags']['fast_compress'] = (bool) ($flags['parameters'] & 0x40000000);
     $info['lpac']['flags']['random_access'] = (bool) ($flags['parameters'] & 0x8000000);
     $info['lpac']['block_length'] = pow(2, ($flags['parameters'] & 0x7000000) >> 24) * 256;
     $info['lpac']['flags']['adaptive_prediction_order'] = (bool) ($flags['parameters'] & 0x800000);
     $info['lpac']['flags']['adaptive_quantization'] = (bool) ($flags['parameters'] & 0x400000);
     $info['lpac']['flags']['joint_stereo'] = (bool) ($flags['parameters'] & 0x40000);
     $info['lpac']['quantization'] = ($flags['parameters'] & 0x1f00) >> 8;
     $info['lpac']['max_prediction_order'] = $flags['parameters'] & 0x3f;
     if ($info['lpac']['flags']['fast_compress'] && $info['lpac']['max_prediction_order'] != 3) {
         $info['warning'][] = 'max_prediction_order expected to be "3" if fast_compress is true, actual value is "' . $info['lpac']['max_prediction_order'] . '"';
     }
     switch ($info['lpac']['file_version']) {
         case 6:
             if ($info['lpac']['flags']['adaptive_quantization']) {
                 $info['warning'][] = 'adaptive_quantization expected to be false in LPAC file stucture v6, actually true';
             }
             if ($info['lpac']['quantization'] != 20) {
                 $info['warning'][] = 'Quantization expected to be 20 in LPAC file stucture v6, actually ' . $info['lpac']['flags']['Q'];
             }
             break;
         default:
             //$info['warning'][] = 'This version of GetId3() ['.$this->getid3->version().'] only supports LPAC file format version 6, this file is version '.$info['lpac']['file_version'].' - please report to info@getid3.org';
             break;
     }
     $getid3_temp = new GetId3_GetId3();
     $getid3_temp->openfile($this->getid3->filename);
     $getid3_temp->info = $info;
     $getid3_riff = new GetId3_Module_AudioVideo_Riff($getid3_temp);
     $getid3_riff->Analyze();
     $info['avdataoffset'] = $getid3_temp->info['avdataoffset'];
     $info['riff'] = $getid3_temp->info['riff'];
     $info['error'] = $getid3_temp->info['error'];
     $info['warning'] = $getid3_temp->info['warning'];
     $info['lpac']['comments']['comment'] = $getid3_temp->info['comments'];
     $info['audio']['sample_rate'] = $getid3_temp->info['audio']['sample_rate'];
     unset($getid3_temp, $getid3_riff);
     $info['audio']['channels'] = $info['lpac']['flags']['stereo'] ? 2 : 1;
     if ($info['lpac']['flags']['24_bit']) {
         $info['audio']['bits_per_sample'] = $info['riff']['audio'][0]['bits_per_sample'];
     } elseif ($info['lpac']['flags']['16_bit']) {
         $info['audio']['bits_per_sample'] = 16;
     } else {
         $info['audio']['bits_per_sample'] = 8;
     }
     if ($info['lpac']['flags']['fast_compress']) {
         // fast
         $info['audio']['encoder_options'] = '-1';
     } else {
         switch ($info['lpac']['max_prediction_order']) {
             case 20:
                 // simple
                 $info['audio']['encoder_options'] = '-2';
                 break;
             case 30:
                 // medium
                 $info['audio']['encoder_options'] = '-3';
                 break;
             case 40:
                 // high
                 $info['audio']['encoder_options'] = '-4';
                 break;
             case 60:
                 // extrahigh
                 $info['audio']['encoder_options'] = '-5';
                 break;
         }
     }
     $info['playtime_seconds'] = $info['lpac']['total_samples'] / $info['audio']['sample_rate'];
     $info['audio']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     return true;
 }
Exemplo n.º 13
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $offset = 0;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $rawdata = fread($this->getid3->fp, $this->getid3->fread_buffer_size());
     switch (substr($rawdata, $offset, 4)) {
         case 'LA02':
         case 'LA03':
         case 'LA04':
             $info['fileformat'] = 'la';
             $info['audio']['dataformat'] = 'la';
             $info['audio']['lossless'] = true;
             $info['la']['version_major'] = (int) substr($rawdata, $offset + 2, 1);
             $info['la']['version_minor'] = (int) substr($rawdata, $offset + 3, 1);
             $info['la']['version'] = (double) $info['la']['version_major'] + $info['la']['version_minor'] / 10;
             $offset += 4;
             $info['la']['uncompressed_size'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             if ($info['la']['uncompressed_size'] == 0) {
                 $info['error'][] = 'Corrupt LA file: uncompressed_size == zero';
                 return false;
             }
             $WAVEchunk = substr($rawdata, $offset, 4);
             if ($WAVEchunk !== 'WAVE') {
                 $info['error'][] = 'Expected "WAVE" (' . GetId3_Lib_Helper::PrintHexBytes('WAVE') . ') at offset ' . $offset . ', found "' . $WAVEchunk . '" (' . GetId3_Lib_Helper::PrintHexBytes($WAVEchunk) . ') instead.';
                 return false;
             }
             $offset += 4;
             $info['la']['fmt_size'] = 24;
             if ($info['la']['version'] >= 0.3) {
                 $info['la']['fmt_size'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
                 $info['la']['header_size'] = 49 + $info['la']['fmt_size'] - 24;
                 $offset += 4;
             } else {
                 // version 0.2 didn't support additional data blocks
                 $info['la']['header_size'] = 41;
             }
             $fmt_chunk = substr($rawdata, $offset, 4);
             if ($fmt_chunk !== 'fmt ') {
                 $info['error'][] = 'Expected "fmt " (' . GetId3_Lib_Helper::PrintHexBytes('fmt ') . ') at offset ' . $offset . ', found "' . $fmt_chunk . '" (' . GetId3_Lib_Helper::PrintHexBytes($fmt_chunk) . ') instead.';
                 return false;
             }
             $offset += 4;
             $fmt_size = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $info['la']['raw']['format'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $info['la']['channels'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             if ($info['la']['channels'] == 0) {
                 $info['error'][] = 'Corrupt LA file: channels == zero';
                 return false;
             }
             $info['la']['sample_rate'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             if ($info['la']['sample_rate'] == 0) {
                 $info['error'][] = 'Corrupt LA file: sample_rate == zero';
                 return false;
             }
             $info['la']['bytes_per_second'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $info['la']['bytes_per_sample'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $info['la']['bits_per_sample'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 2));
             $offset += 2;
             $info['la']['samples'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             $info['la']['raw']['flags'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 1));
             $offset += 1;
             $info['la']['flags']['seekable'] = (bool) ($info['la']['raw']['flags'] & 0x1);
             if ($info['la']['version'] >= 0.4) {
                 $info['la']['flags']['high_compression'] = (bool) ($info['la']['raw']['flags'] & 0x2);
             }
             $info['la']['original_crc'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
             $offset += 4;
             // mikeØbevin*de
             // Basically, the blocksize/seekevery are 61440/19 in La0.4 and 73728/16
             // in earlier versions. A seekpoint is added every blocksize * seekevery
             // samples, so 4 * int(totalSamples / (blockSize * seekEvery)) should
             // give the number of bytes used for the seekpoints. Of course, if seeking
             // is disabled, there are no seekpoints stored.
             if ($info['la']['version'] >= 0.4) {
                 $info['la']['blocksize'] = 61440;
                 $info['la']['seekevery'] = 19;
             } else {
                 $info['la']['blocksize'] = 73728;
                 $info['la']['seekevery'] = 16;
             }
             $info['la']['seekpoint_count'] = 0;
             if ($info['la']['flags']['seekable']) {
                 $info['la']['seekpoint_count'] = floor($info['la']['samples'] / ($info['la']['blocksize'] * $info['la']['seekevery']));
                 for ($i = 0; $i < $info['la']['seekpoint_count']; $i++) {
                     $info['la']['seekpoints'][] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
                     $offset += 4;
                 }
             }
             if ($info['la']['version'] >= 0.3) {
                 // Following the main header information, the program outputs all of the
                 // seekpoints. Following these is what I called the 'footer start',
                 // i.e. the position immediately after the La audio data is finished.
                 $info['la']['footerstart'] = GetId3_Lib_Helper::LittleEndian2Int(substr($rawdata, $offset, 4));
                 $offset += 4;
                 if ($info['la']['footerstart'] > $info['filesize']) {
                     $info['warning'][] = 'FooterStart value points to offset ' . $info['la']['footerstart'] . ' which is beyond end-of-file (' . $info['filesize'] . ')';
                     $info['la']['footerstart'] = $info['filesize'];
                 }
             } else {
                 // La v0.2 didn't have FooterStart value
                 $info['la']['footerstart'] = $info['avdataend'];
             }
             if ($info['la']['footerstart'] < $info['avdataend']) {
                 if ($RIFFtempfilename = tempnam(GetId3_GetId3::getTempDir(), 'id3')) {
                     if ($RIFF_fp = fopen($RIFFtempfilename, 'w+b')) {
                         $RIFFdata = 'WAVE';
                         if ($info['la']['version'] == 0.2) {
                             $RIFFdata .= substr($rawdata, 12, 24);
                         } else {
                             $RIFFdata .= substr($rawdata, 16, 24);
                         }
                         if ($info['la']['footerstart'] < $info['avdataend']) {
                             fseek($this->getid3->fp, $info['la']['footerstart'], SEEK_SET);
                             $RIFFdata .= fread($this->getid3->fp, $info['avdataend'] - $info['la']['footerstart']);
                         }
                         $RIFFdata = 'RIFF' . GetId3_Lib_Helper::LittleEndian2String(strlen($RIFFdata), 4, false) . $RIFFdata;
                         fwrite($RIFF_fp, $RIFFdata, strlen($RIFFdata));
                         fclose($RIFF_fp);
                         $getid3_temp = new GetId3_GetId3();
                         $getid3_temp->openfile($RIFFtempfilename);
                         $getid3_riff = new GetId3_Module_AudioVideo_Riff($getid3_temp);
                         $getid3_riff->Analyze();
                         if (empty($getid3_temp->info['error'])) {
                             $info['riff'] = $getid3_temp->info['riff'];
                         } else {
                             $info['warning'][] = 'Error parsing RIFF portion of La file: ' . implode($getid3_temp->info['error']);
                         }
                         unset($getid3_temp, $getid3_riff);
                     }
                     unlink($RIFFtempfilename);
                 }
             }
             // $info['avdataoffset'] should be zero to begin with, but just in case it's not, include the addition anyway
             $info['avdataend'] = $info['avdataoffset'] + $info['la']['footerstart'];
             $info['avdataoffset'] = $info['avdataoffset'] + $offset;
             //$info['la']['codec']                = RIFFwFormatTagLookup($info['la']['raw']['format']);
             $info['la']['compression_ratio'] = (double) (($info['avdataend'] - $info['avdataoffset']) / $info['la']['uncompressed_size']);
             $info['playtime_seconds'] = (double) ($info['la']['samples'] / $info['la']['sample_rate']) / $info['la']['channels'];
             if ($info['playtime_seconds'] == 0) {
                 $info['error'][] = 'Corrupt LA file: playtime_seconds == zero';
                 return false;
             }
             $info['audio']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
             //$info['audio']['codec']              = $info['la']['codec'];
             $info['audio']['bits_per_sample'] = $info['la']['bits_per_sample'];
             break;
         default:
             if (substr($rawdata, $offset, 2) == 'LA') {
                 $info['error'][] = 'This version of GetId3() [' . $this->getid3->version() . '] does not support LA version ' . substr($rawdata, $offset + 2, 1) . '.' . substr($rawdata, $offset + 3, 1) . ' which this appears to be - check http://getid3.sourceforge.net for updates.';
             } else {
                 $info['error'][] = 'Not a LA (Lossless-Audio) file';
             }
             return false;
             break;
     }
     $info['audio']['channels'] = $info['la']['channels'];
     $info['audio']['sample_rate'] = (int) $info['la']['sample_rate'];
     $info['audio']['encoder'] = 'LA v' . $info['la']['version'];
     return true;
 }
Exemplo n.º 14
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $FLVdataLength = $info['avdataend'] - $info['avdataoffset'];
     $FLVheader = fread($this->getid3->fp, 5);
     $info['fileformat'] = 'flv';
     $info['flv']['header']['signature'] = substr($FLVheader, 0, 3);
     $info['flv']['header']['version'] = GetId3_Lib_Helper::BigEndian2Int(substr($FLVheader, 3, 1));
     $TypeFlags = GetId3_Lib_Helper::BigEndian2Int(substr($FLVheader, 4, 1));
     $magic = 'FLV';
     if ($info['flv']['header']['signature'] != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($info['flv']['header']['signature']) . '"';
         unset($info['flv']);
         unset($info['fileformat']);
         return false;
     }
     $info['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x4);
     $info['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x1);
     $FrameSizeDataLength = GetId3_Lib_Helper::BigEndian2Int(fread($this->getid3->fp, 4));
     $FLVheaderFrameLength = 9;
     if ($FrameSizeDataLength > $FLVheaderFrameLength) {
         fseek($this->getid3->fp, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
     }
     $Duration = 0;
     $found_video = false;
     $found_audio = false;
     $found_meta = false;
     $found_valid_meta_playtime = false;
     $tagParseCount = 0;
     $info['flv']['framecount'] = array('total' => 0, 'audio' => 0, 'video' => 0);
     $flv_framecount =& $info['flv']['framecount'];
     while (ftell($this->getid3->fp) + 16 < $info['avdataend'] && ($tagParseCount++ <= $this->max_frames || !$found_valid_meta_playtime)) {
         $ThisTagHeader = fread($this->getid3->fp, 16);
         $PreviousTagLength = GetId3_Lib_Helper::BigEndian2Int(substr($ThisTagHeader, 0, 4));
         $TagType = GetId3_Lib_Helper::BigEndian2Int(substr($ThisTagHeader, 4, 1));
         $DataLength = GetId3_Lib_Helper::BigEndian2Int(substr($ThisTagHeader, 5, 3));
         $Timestamp = GetId3_Lib_Helper::BigEndian2Int(substr($ThisTagHeader, 8, 3));
         $LastHeaderByte = GetId3_Lib_Helper::BigEndian2Int(substr($ThisTagHeader, 15, 1));
         $NextOffset = ftell($this->getid3->fp) - 1 + $DataLength;
         if ($Timestamp > $Duration) {
             $Duration = $Timestamp;
         }
         $flv_framecount['total']++;
         switch ($TagType) {
             case self::GETID3_FLV_TAG_AUDIO:
                 $flv_framecount['audio']++;
                 if (!$found_audio) {
                     $found_audio = true;
                     $info['flv']['audio']['audioFormat'] = $LastHeaderByte >> 4 & 0xf;
                     $info['flv']['audio']['audioRate'] = $LastHeaderByte >> 2 & 0x3;
                     $info['flv']['audio']['audioSampleSize'] = $LastHeaderByte >> 1 & 0x1;
                     $info['flv']['audio']['audioType'] = $LastHeaderByte & 0x1;
                 }
                 break;
             case self::GETID3_FLV_TAG_VIDEO:
                 $flv_framecount['video']++;
                 if (!$found_video) {
                     $found_video = true;
                     $info['flv']['video']['videoCodec'] = $LastHeaderByte & 0x7;
                     $FLVvideoHeader = fread($this->getid3->fp, 11);
                     if ($info['flv']['video']['videoCodec'] == self::GETID3_FLV_VIDEO_H264) {
                         // this code block contributed by: moysevichØgmail*com
                         $AVCPacketType = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 0, 1));
                         if ($AVCPacketType == GetId3_Module_AudioVideo_AVCSequenceParameterSetReader::H264_AVC_SEQUENCE_HEADER) {
                             //	read AVCDecoderConfigurationRecord
                             $configurationVersion = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 4, 1));
                             $AVCProfileIndication = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 5, 1));
                             $profile_compatibility = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 6, 1));
                             $lengthSizeMinusOne = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 7, 1));
                             $numOfSequenceParameterSets = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 8, 1));
                             if (($numOfSequenceParameterSets & 0x1f) != 0) {
                                 //	there is at least one SequenceParameterSet
                                 //	read size of the first SequenceParameterSet
                                 //$spsSize = GetId3_lib::BigEndian2Int(substr($FLVvideoHeader, 9, 2));
                                 $spsSize = GetId3_Lib_Helper::LittleEndian2Int(substr($FLVvideoHeader, 9, 2));
                                 //	read the first SequenceParameterSet
                                 $sps = fread($this->getid3->fp, $spsSize);
                                 if (strlen($sps) == $spsSize) {
                                     //	make sure that whole SequenceParameterSet was red
                                     $spsReader = new GetId3_Module_AudioVideo_AVCSequenceParameterSetReader($sps);
                                     $spsReader->readData();
                                     $info['video']['resolution_x'] = $spsReader->getWidth();
                                     $info['video']['resolution_y'] = $spsReader->getHeight();
                                 }
                             }
                         }
                         // end: moysevichØgmail*com
                     } elseif ($info['flv']['video']['videoCodec'] == self::GETID3_FLV_VIDEO_H263) {
                         $PictureSizeType = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 3, 2)) >> 7;
                         $PictureSizeType = $PictureSizeType & 0x7;
                         $info['flv']['header']['videoSizeType'] = $PictureSizeType;
                         switch ($PictureSizeType) {
                             case 0:
                                 //$PictureSizeEnc = GetId3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$info['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 //$PictureSizeEnc = GetId3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$info['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 $PictureSizeEnc['x'] = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 4, 2));
                                 $PictureSizeEnc['y'] = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xff;
                                 $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xff;
                                 break;
                             case 1:
                                 $PictureSizeEnc['x'] = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 4, 3));
                                 $PictureSizeEnc['y'] = GetId3_Lib_Helper::BigEndian2Int(substr($FLVvideoHeader, 6, 3));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xffff;
                                 $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xffff;
                                 break;
                             case 2:
                                 $info['video']['resolution_x'] = 352;
                                 $info['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $info['video']['resolution_x'] = 176;
                                 $info['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $info['video']['resolution_x'] = 128;
                                 $info['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $info['video']['resolution_x'] = 320;
                                 $info['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $info['video']['resolution_x'] = 160;
                                 $info['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $info['video']['resolution_x'] = 0;
                                 $info['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                     $info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y'];
                 }
                 break;
                 // Meta tag
             // Meta tag
             case self::GETID3_FLV_TAG_META:
                 if (!$found_meta) {
                     $found_meta = true;
                     fseek($this->getid3->fp, -1, SEEK_CUR);
                     $datachunk = fread($this->getid3->fp, $DataLength);
                     $AMFstream = new GetId3_Module_AudioVideo_AMFStream($datachunk);
                     $reader = new GetId3_Module_AudioVideo_AMFReader($AMFstream);
                     $eventName = $reader->readData();
                     $info['flv']['meta'][$eventName] = $reader->readData();
                     unset($reader);
                     $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate');
                     foreach ($copykeys as $sourcekey => $destkey) {
                         if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) {
                             switch ($sourcekey) {
                                 case 'width':
                                 case 'height':
                                     $info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey]));
                                     break;
                                 case 'audiodatarate':
                                     $info['audio'][$destkey] = GetId3_Lib_Helper::CastAsInt(round($info['flv']['meta']['onMetaData'][$sourcekey] * 1000));
                                     break;
                                 case 'videodatarate':
                                 case 'frame_rate':
                                 default:
                                     $info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey];
                                     break;
                             }
                         }
                     }
                     if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
                         $found_valid_meta_playtime = true;
                     }
                 }
                 break;
             default:
                 // noop
                 break;
         }
         fseek($this->getid3->fp, $NextOffset, SEEK_SET);
     }
     $info['playtime_seconds'] = $Duration / 1000;
     if ($info['playtime_seconds'] > 0) {
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     }
     if ($info['flv']['header']['hasAudio']) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['audio']['audioFormat']);
         $info['audio']['sample_rate'] = $this->FLVaudioRate($info['flv']['audio']['audioRate']);
         $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info['flv']['audio']['audioSampleSize']);
         $info['audio']['channels'] = $info['flv']['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $info['audio']['lossless'] = $info['flv']['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $info['audio']['dataformat'] = 'flv';
     }
     if (!empty($info['flv']['header']['hasVideo'])) {
         $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['video']['videoCodec']);
         $info['video']['dataformat'] = 'flv';
         $info['video']['lossless'] = false;
     }
     // Set information from meta
     if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
         $info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration'];
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     }
     if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['meta']['onMetaData']['audiocodecid']);
     }
     if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) {
         $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['meta']['onMetaData']['videocodecid']);
     }
     return true;
 }
Exemplo n.º 15
0
 public function Analyze()
 {
     $info =& $this->getid3->info;
     // http://cui.unige.ch/OSG/info/AudioFormats/ap11.html
     // http://www.btinternet.com/~AnthonyJ/Atari/programming/avr_format.html
     // offset    type    length    name        comments
     // ---------------------------------------------------------------------
     // 0    char    4    ID        format ID == "2BIT"
     // 4    char    8    name        sample name (unused space filled with 0)
     // 12    short    1    mono/stereo    0=mono, -1 (0xFFFF)=stereo
     //                     With stereo, samples are alternated,
     //                     the first voice is the left :
     //                     (LRLRLRLRLRLRLRLRLR...)
     // 14    short    1    resolution    8, 12 or 16 (bits)
     // 16    short    1    signed or not    0=unsigned, -1 (0xFFFF)=signed
     // 18    short    1    loop or not    0=no loop, -1 (0xFFFF)=loop on
     // 20    short    1    MIDI note    0xFFnn, where 0 <= nn <= 127
     //                     0xFFFF means "no MIDI note defined"
     // 22    byte    1    Replay speed    Frequence in the Replay software
     //                     0=5.485 Khz, 1=8.084 Khz, 2=10.971 Khz,
     //                     3=16.168 Khz, 4=21.942 Khz, 5=32.336 Khz
     //                     6=43.885 Khz, 7=47.261 Khz
     //                     -1 (0xFF)=no defined Frequence
     // 23    byte    3    sample rate    in Hertz
     // 26    long    1    size in bytes (2 * bytes in stereo)
     // 30    long    1    loop begin    0 for no loop
     // 34    long    1    loop size    equal to 'size' for no loop
     // 38  short   2   Reserved, MIDI keyboard split */
     // 40  short   2   Reserved, sample compression */
     // 42  short   2   Reserved */
     // 44  char   20;  Additional filename space, used if (name[7] != 0)
     // 64    byte    64    user data
     // 128    bytes    ?    sample data    (12 bits samples are coded on 16 bits:
     //                     0000 xxxx xxxx xxxx)
     // ---------------------------------------------------------------------
     // Note that all values are in motorola (big-endian) format, and that long is
     // assumed to be 4 bytes, and short 2 bytes.
     // When reading the samples, you should handle both signed and unsigned data,
     // and be prepared to convert 16->8 bit, or mono->stereo if needed. To convert
     // 8-bit data between signed/unsigned just add 127 to the sample values.
     // Simularly for 16-bit data you should add 32769
     $info['fileformat'] = 'avr';
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $AVRheader = fread($this->getid3->fp, 128);
     $info['avr']['raw']['magic'] = substr($AVRheader, 0, 4);
     $magic = '2BIT';
     if ($info['avr']['raw']['magic'] != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($info['avr']['raw']['magic']) . '"';
         unset($info['fileformat']);
         unset($info['avr']);
         return false;
     }
     $info['avdataoffset'] += 128;
     $info['avr']['sample_name'] = rtrim(substr($AVRheader, 4, 8));
     $info['avr']['raw']['mono'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 12, 2));
     $info['avr']['bits_per_sample'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 14, 2));
     $info['avr']['raw']['signed'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 16, 2));
     $info['avr']['raw']['loop'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 18, 2));
     $info['avr']['raw']['midi'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 20, 2));
     $info['avr']['raw']['replay_freq'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 22, 1));
     $info['avr']['sample_rate'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 23, 3));
     $info['avr']['sample_length'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 26, 4));
     $info['avr']['loop_start'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 30, 4));
     $info['avr']['loop_end'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 34, 4));
     $info['avr']['midi_split'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 38, 2));
     $info['avr']['sample_compression'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 40, 2));
     $info['avr']['reserved'] = GetId3_Lib_Helper::BigEndian2Int(substr($AVRheader, 42, 2));
     $info['avr']['sample_name_extra'] = rtrim(substr($AVRheader, 44, 20));
     $info['avr']['comment'] = rtrim(substr($AVRheader, 64, 64));
     $info['avr']['flags']['stereo'] = $info['avr']['raw']['mono'] == 0 ? false : true;
     $info['avr']['flags']['signed'] = $info['avr']['raw']['signed'] == 0 ? false : true;
     $info['avr']['flags']['loop'] = $info['avr']['raw']['loop'] == 0 ? false : true;
     $info['avr']['midi_notes'] = array();
     if (($info['avr']['raw']['midi'] & 0xff00) != 0xff00) {
         $info['avr']['midi_notes'][] = ($info['avr']['raw']['midi'] & 0xff00) >> 8;
     }
     if (($info['avr']['raw']['midi'] & 0xff) != 0xff) {
         $info['avr']['midi_notes'][] = $info['avr']['raw']['midi'] & 0xff;
     }
     if ($info['avdataend'] - $info['avdataoffset'] != $info['avr']['sample_length'] * ($info['avr']['bits_per_sample'] == 8 ? 1 : 2)) {
         $info['warning'][] = 'Probable truncated file: expecting ' . $info['avr']['sample_length'] * ($info['avr']['bits_per_sample'] == 8 ? 1 : 2) . ' bytes of audio data, found ' . ($info['avdataend'] - $info['avdataoffset']);
     }
     $info['audio']['dataformat'] = 'avr';
     $info['audio']['lossless'] = true;
     $info['audio']['bitrate_mode'] = 'cbr';
     $info['audio']['bits_per_sample'] = $info['avr']['bits_per_sample'];
     $info['audio']['sample_rate'] = $info['avr']['sample_rate'];
     $info['audio']['channels'] = $info['avr']['flags']['stereo'] ? 2 : 1;
     $info['playtime_seconds'] = $info['avr']['sample_length'] / $info['audio']['channels'] / $info['avr']['sample_rate'];
     $info['audio']['bitrate'] = $info['avr']['sample_length'] * ($info['avr']['bits_per_sample'] == 8 ? 8 : 16) / $info['playtime_seconds'];
     return true;
 }
Exemplo n.º 16
0
 /**
  *
  * @return string
  */
 public function GenerateCONTchunk()
 {
     foreach ($this->tag_data as $key => $value) {
         // limit each value to 0xFFFF bytes
         $this->tag_data[$key] = substr($value, 0, 65535);
     }
     $CONTchunk = "";
     // object version
     $CONTchunk .= GetId3_Lib_Helper::BigEndian2String(!empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : 0, 2);
     $CONTchunk .= !empty($this->tag_data['title']) ? strlen($this->tag_data['title']) : '';
     $CONTchunk .= GetId3_Lib_Helper::BigEndian2String(!empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : 0, 2);
     $CONTchunk .= !empty($this->tag_data['artist']) ? strlen($this->tag_data['artist']) : '';
     $CONTchunk .= GetId3_Lib_Helper::BigEndian2String(!empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : 0, 2);
     $CONTchunk .= !empty($this->tag_data['copyright']) ? strlen($this->tag_data['copyright']) : '';
     $CONTchunk .= GetId3_Lib_Helper::BigEndian2String(!empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : 0, 2);
     $CONTchunk .= !empty($this->tag_data['comment']) ? strlen($this->tag_data['comment']) : '';
     if ($this->paddedlength > strlen($CONTchunk) + 8) {
         $CONTchunk .= str_repeat("", $this->paddedlength - strlen($CONTchunk) - 8);
     }
     $CONTchunk = 'CONT' . GetId3_Lib_Helper::BigEndian2String(strlen($CONTchunk) + 8, 4) . $CONTchunk;
     // CONT chunk identifier + chunk length
     return $CONTchunk;
 }
Exemplo n.º 17
0
 /**
  *
  * @staticvar array $decbin
  * @param type $MaxFramesToScan
  * @param type $ReturnExtendedInfo
  * @return boolean
  */
 public function getAACADTSheaderFilepointer($MaxFramesToScan = 1000000, $ReturnExtendedInfo = false)
 {
     $info =& $this->getid3->info;
     // based loosely on code from AACfile by Jurgen Faul  <jfaulØgmx.de>
     // http://jfaul.de/atl  or  http://j-faul.virtualave.net/atl/atl.html
     // http://faac.sourceforge.net/wiki/index.php?page=ADTS // dead link
     // http://wiki.multimedia.cx/index.php?title=ADTS
     // * ADTS Fixed Header: these don't change from frame to frame
     // syncword                                       12    always: '111111111111'
     // ID                                              1    0: MPEG-4, 1: MPEG-2
     // MPEG layer                                      2    If you send AAC in MPEG-TS, set to 0
     // protection_absent                               1    0: CRC present; 1: no CRC
     // profile                                         2    0: AAC Main; 1: AAC LC (Low Complexity); 2: AAC SSR (Scalable Sample Rate); 3: AAC LTP (Long Term Prediction)
     // sampling_frequency_index                        4    15 not allowed
     // private_bit                                     1    usually 0
     // channel_configuration                           3
     // original/copy                                   1    0: original; 1: copy
     // home                                            1    usually 0
     // emphasis                                        2    only if ID == 0 (ie MPEG-4)  // not present in some documentation?
     // * ADTS Variable Header: these can change from frame to frame
     // copyright_identification_bit                    1
     // copyright_identification_start                  1
     // aac_frame_length                               13    length of the frame including header (in bytes)
     // adts_buffer_fullness                           11    0x7FF indicates VBR
     // no_raw_data_blocks_in_frame                     2
     // * ADTS Error check
     // crc_check                                      16    only if protection_absent == 0
     $byteoffset = $info['avdataoffset'];
     $framenumber = 0;
     // Init bit pattern array
     static $decbin = array();
     // Populate $bindec
     for ($i = 0; $i < 256; $i++) {
         $decbin[chr($i)] = str_pad(decbin($i), 8, '0', STR_PAD_LEFT);
     }
     // used to calculate bitrate below
     $BitrateCache = array();
     while (true) {
         // breaks out when end-of-file encountered, or invalid data found,
         // or MaxFramesToScan frames have been scanned
         if (!GetId3_Lib_Helper::intValueSupported($byteoffset)) {
             $info['warning'][] = 'Unable to parse AAC file beyond ' . ftell($this->getid3->fp) . ' (PHP does not support file operations beyond ' . round(PHP_INT_MAX / 1073741824) . 'GB)';
             return false;
         }
         fseek($this->getid3->fp, $byteoffset, SEEK_SET);
         // First get substring
         $substring = fread($this->getid3->fp, 9);
         // header is 7 bytes (or 9 if CRC is present)
         $substringlength = strlen($substring);
         if ($substringlength != 9) {
             $info['error'][] = 'Failed to read 7 bytes at offset ' . (ftell($this->getid3->fp) - $substringlength) . ' (only read ' . $substringlength . ' bytes)';
             return false;
         }
         // this would be easier with 64-bit math, but split it up to allow for 32-bit:
         $header1 = GetId3_Lib_Helper::BigEndian2Int(substr($substring, 0, 2));
         $header2 = GetId3_Lib_Helper::BigEndian2Int(substr($substring, 2, 4));
         $header3 = GetId3_Lib_Helper::BigEndian2Int(substr($substring, 6, 1));
         $info['aac']['header']['raw']['syncword'] = ($header1 & 0xfff0) >> 4;
         if ($info['aac']['header']['raw']['syncword'] != 0xfff) {
             $info['error'][] = 'Synch pattern (0x0FFF) not found at offset ' . (ftell($this->getid3->fp) - $substringlength) . ' (found 0x0' . strtoupper(dechex($info['aac']['header']['raw']['syncword'])) . ' instead)';
             //if ($info['fileformat'] == 'aac') {
             //	return true;
             //}
             unset($info['aac']);
             return false;
         }
         // Gather info for first frame only - this takes time to do 1000 times!
         if ($framenumber == 0) {
             $info['aac']['header_type'] = 'ADTS';
             $info['fileformat'] = 'aac';
             $info['audio']['dataformat'] = 'aac';
             $info['aac']['header']['raw']['mpeg_version'] = ($header1 & 0x8) >> 3;
             $info['aac']['header']['raw']['mpeg_layer'] = ($header1 & 0x6) >> 1;
             $info['aac']['header']['raw']['protection_absent'] = ($header1 & 0x1) >> 0;
             $info['aac']['header']['raw']['profile_code'] = ($header2 & 0xc0000000) >> 30;
             $info['aac']['header']['raw']['sample_rate_code'] = ($header2 & 0x3c000000) >> 26;
             $info['aac']['header']['raw']['private_stream'] = ($header2 & 0x2000000) >> 25;
             $info['aac']['header']['raw']['channels_code'] = ($header2 & 0x1c00000) >> 22;
             $info['aac']['header']['raw']['original'] = ($header2 & 0x200000) >> 21;
             $info['aac']['header']['raw']['home'] = ($header2 & 0x100000) >> 20;
             $info['aac']['header']['raw']['copyright_stream'] = ($header2 & 0x80000) >> 19;
             $info['aac']['header']['raw']['copyright_start'] = ($header2 & 0x40000) >> 18;
             $info['aac']['header']['raw']['frame_length'] = ($header2 & 0x3ffe0) >> 5;
             $info['aac']['header']['mpeg_version'] = $info['aac']['header']['raw']['mpeg_version'] ? 2 : 4;
             $info['aac']['header']['crc_present'] = $info['aac']['header']['raw']['protection_absent'] ? false : true;
             $info['aac']['header']['profile'] = self::AACprofileLookup($info['aac']['header']['raw']['profile_code'], $info['aac']['header']['mpeg_version']);
             $info['aac']['header']['sample_frequency'] = self::AACsampleRateLookup($info['aac']['header']['raw']['sample_rate_code']);
             $info['aac']['header']['private'] = (bool) $info['aac']['header']['raw']['private_stream'];
             $info['aac']['header']['original'] = (bool) $info['aac']['header']['raw']['original'];
             $info['aac']['header']['home'] = (bool) $info['aac']['header']['raw']['home'];
             $info['aac']['header']['channels'] = $info['aac']['header']['raw']['channels_code'] == 7 ? 8 : $info['aac']['header']['raw']['channels_code'];
             if ($ReturnExtendedInfo) {
                 $info['aac'][$framenumber]['copyright_id_bit'] = (bool) $info['aac']['header']['raw']['copyright_stream'];
                 $info['aac'][$framenumber]['copyright_id_start'] = (bool) $info['aac']['header']['raw']['copyright_start'];
             }
             if ($info['aac']['header']['raw']['mpeg_layer'] != 0) {
                 $info['warning'][] = 'Layer error - expected "0", found "' . $info['aac']['header']['raw']['mpeg_layer'] . '" instead';
             }
             if ($info['aac']['header']['sample_frequency'] == 0) {
                 $info['error'][] = 'Corrupt AAC file: sample_frequency == zero';
                 return false;
             }
             $info['audio']['sample_rate'] = $info['aac']['header']['sample_frequency'];
             $info['audio']['channels'] = $info['aac']['header']['channels'];
         }
         $FrameLength = ($header2 & 0x3ffe0) >> 5;
         if (!isset($BitrateCache[$FrameLength])) {
             $BitrateCache[$FrameLength] = $info['aac']['header']['sample_frequency'] / 1024 * $FrameLength * 8;
         }
         GetId3_Lib_Helper::safe_inc($info['aac']['bitrate_distribution'][$BitrateCache[$FrameLength]], 1);
         $info['aac'][$framenumber]['aac_frame_length'] = $FrameLength;
         $info['aac'][$framenumber]['adts_buffer_fullness'] = ($header2 & 0x1f) << 6 & ($header3 & 0xfc) >> 2;
         if ($info['aac'][$framenumber]['adts_buffer_fullness'] == 0x7ff) {
             $info['audio']['bitrate_mode'] = 'vbr';
         } else {
             $info['audio']['bitrate_mode'] = 'cbr';
         }
         $info['aac'][$framenumber]['num_raw_data_blocks'] = ($header3 & 0x3) >> 0;
         if ($info['aac']['header']['crc_present']) {
             //$info['aac'][$framenumber]['crc'] = GetId3_lib::BigEndian2Int(substr($substring, 7, 2);
         }
         if (!$ReturnExtendedInfo) {
             unset($info['aac'][$framenumber]);
         }
         /*
         $rounded_precision = 5000;
         $info['aac']['bitrate_distribution_rounded'] = array();
         foreach ($info['aac']['bitrate_distribution'] as $bitrate => $count) {
         	$rounded_bitrate = round($bitrate / $rounded_precision) * $rounded_precision;
         	getid3_lib::safe_inc($info['aac']['bitrate_distribution_rounded'][$rounded_bitrate], $count);
         }
         ksort($info['aac']['bitrate_distribution_rounded']);
         */
         $byteoffset += $FrameLength;
         if (++$framenumber < $MaxFramesToScan && $byteoffset + 10 < $info['avdataend']) {
             // keep scanning
         } else {
             $info['aac']['frames'] = $framenumber;
             $info['playtime_seconds'] = $info['avdataend'] / $byteoffset * ($framenumber * 1024 / $info['aac']['header']['sample_frequency']);
             // (1 / % of file scanned) * (samples / (samples/sec)) = seconds
             if ($info['playtime_seconds'] == 0) {
                 $info['error'][] = 'Corrupt AAC file: playtime_seconds == zero';
                 return false;
             }
             $info['audio']['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
             ksort($info['aac']['bitrate_distribution']);
             $info['audio']['encoder_options'] = $info['aac']['header_type'] . ' ' . $info['aac']['header']['profile'];
             return true;
         }
     }
     // should never get here.
 }
Exemplo n.º 18
0
 /**
  *
  * @return boolean
  */
 public function ZIPparseEndOfCentralDirectory()
 {
     $EndOfCentralDirectory['offset'] = ftell($this->getid3->fp);
     $ZIPendOfCentralDirectory = fread($this->getid3->fp, 22);
     $EndOfCentralDirectory['signature'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 0, 4));
     if ($EndOfCentralDirectory['signature'] != 0x6054b50) {
         // invalid End Of Central Directory Signature
         fseek($this->getid3->fp, $EndOfCentralDirectory['offset'], SEEK_SET);
         // seek back to where filepointer originally was so it can be handled properly
         return false;
     }
     $EndOfCentralDirectory['disk_number_current'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 4, 2));
     $EndOfCentralDirectory['disk_number_start_directory'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 6, 2));
     $EndOfCentralDirectory['directory_entries_this_disk'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 8, 2));
     $EndOfCentralDirectory['directory_entries_total'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 10, 2));
     $EndOfCentralDirectory['directory_size'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 12, 4));
     $EndOfCentralDirectory['directory_offset'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 16, 4));
     $EndOfCentralDirectory['comment_length'] = GetId3_Lib_Helper::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 20, 2));
     if ($EndOfCentralDirectory['comment_length'] > 0) {
         $EndOfCentralDirectory['comment'] = fread($this->getid3->fp, $EndOfCentralDirectory['comment_length']);
     }
     return $EndOfCentralDirectory;
 }
Exemplo n.º 19
0
 /**
  *
  * @param type $items
  * @param type $isheader
  * @return type
  */
 public function GenerateAPEtagHeaderFooter(&$items, $isheader = false)
 {
     $tagdatalength = 0;
     foreach ($items as $itemdata) {
         $tagdatalength += strlen($itemdata);
     }
     $APEheader = 'APETAGEX';
     $APEheader .= GetId3_Lib_Helper::LittleEndian2String(2000, 4);
     $APEheader .= GetId3_Lib_Helper::LittleEndian2String(32 + $tagdatalength, 4);
     $APEheader .= GetId3_Lib_Helper::LittleEndian2String(count($items), 4);
     $APEheader .= $this->GenerateAPEtagFlags(true, true, $isheader, 0, false);
     $APEheader .= str_repeat("", 8);
     return $APEheader;
 }
Exemplo n.º 20
0
 /**
  *
  * @return boolean
  */
 public function CalculateReplayGain()
 {
     if (isset($this->info['replay_gain'])) {
         if (!isset($this->info['replay_gain']['reference_volume'])) {
             $this->info['replay_gain']['reference_volume'] = (double) 89.0;
         }
         if (isset($this->info['replay_gain']['track']['adjustment'])) {
             $this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
         }
         if (isset($this->info['replay_gain']['album']['adjustment'])) {
             $this->info['replay_gain']['album']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['album']['adjustment'];
         }
         if (isset($this->info['replay_gain']['track']['peak'])) {
             $this->info['replay_gain']['track']['max_noclip_gain'] = 0 - GetId3_Lib_Helper::RGADamplitude2dB($this->info['replay_gain']['track']['peak']);
         }
         if (isset($this->info['replay_gain']['album']['peak'])) {
             $this->info['replay_gain']['album']['max_noclip_gain'] = 0 - GetId3_Lib_Helper::RGADamplitude2dB($this->info['replay_gain']['album']['peak']);
         }
     }
     return true;
 }
Exemplo n.º 21
0
 /**
  *
  * @param type $byteword
  * @param type $signed
  * @return type
  */
 public function EitherEndian2Int($byteword, $signed = false)
 {
     if ($this->getid3->info['fileformat'] == 'riff') {
         return GetId3_Lib_Helper::LittleEndian2Int($byteword, $signed);
     }
     return GetId3_Lib_Helper::BigEndian2Int($byteword, false, $signed);
 }
Exemplo n.º 22
0
 /**
  *
  * @param type $EBMLstring
  * @return type
  * @link http://matroska.org/specs/
  */
 private static function EBML2Int($EBMLstring)
 {
     // Element ID coded with an UTF-8 like system:
     // 1xxx xxxx                                  - Class A IDs (2^7 -2 possible values) (base 0x8X)
     // 01xx xxxx  xxxx xxxx                       - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX)
     // 001x xxxx  xxxx xxxx  xxxx xxxx            - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX)
     // 0001 xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX)
     // Values with all x at 0 and 1 are reserved (hence the -2).
     // Data size, in octets, is also coded with an UTF-8 like system :
     // 1xxx xxxx                                                                              - value 0 to  2^7-2
     // 01xx xxxx  xxxx xxxx                                                                   - value 0 to 2^14-2
     // 001x xxxx  xxxx xxxx  xxxx xxxx                                                        - value 0 to 2^21-2
     // 0001 xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx                                             - value 0 to 2^28-2
     // 0000 1xxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx                                  - value 0 to 2^35-2
     // 0000 01xx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx                       - value 0 to 2^42-2
     // 0000 001x  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx            - value 0 to 2^49-2
     // 0000 0001  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx  xxxx xxxx - value 0 to 2^56-2
     $first_byte_int = ord($EBMLstring[0]);
     if (0x80 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x7f);
     } elseif (0x40 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x3f);
     } elseif (0x20 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x1f);
     } elseif (0x10 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0xf);
     } elseif (0x8 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x7);
     } elseif (0x4 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x3);
     } elseif (0x2 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x1);
     } elseif (0x1 & $first_byte_int) {
         $EBMLstring[0] = chr($first_byte_int & 0x0);
     }
     return GetId3_Lib_Helper::BigEndian2Int($EBMLstring);
 }
Exemplo n.º 23
0
 /**
  *
  * @return type
  */
 public function readDouble()
 {
     return GetId3_Lib_Helper::BigEndian2Float($this->read(8));
 }
Exemplo n.º 24
0
 /**
  *
  * @param type $endoffset
  * @param type $version
  * @param type $length
  * @return boolean
  * @link http://www.volweb.cz/str/tags.htm
  */
 public function getLyrics3Data($endoffset, $version, $length)
 {
     $info =& $this->getid3->info;
     if (!GetId3_Lib_Helper::intValueSupported($endoffset)) {
         $info['warning'][] = 'Unable to check for Lyrics3 because file is larger than ' . round(PHP_INT_MAX / 1073741824) . 'GB';
         return false;
     }
     fseek($this->getid3->fp, $endoffset, SEEK_SET);
     if ($length <= 0) {
         return false;
     }
     $rawdata = fread($this->getid3->fp, $length);
     $ParsedLyrics3['raw']['lyrics3version'] = $version;
     $ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
     $ParsedLyrics3['tag_offset_start'] = $endoffset;
     $ParsedLyrics3['tag_offset_end'] = $endoffset + $length - 1;
     if (substr($rawdata, 0, 11) != 'LYRICSBEGIN') {
         if (strpos($rawdata, 'LYRICSBEGIN') !== false) {
             $info['warning'][] = '"LYRICSBEGIN" expected at ' . $endoffset . ' but actually found at ' . ($endoffset + strpos($rawdata, 'LYRICSBEGIN')) . ' - this is invalid for Lyrics3 v' . $version;
             $info['avdataend'] = $endoffset + strpos($rawdata, 'LYRICSBEGIN');
             $rawdata = substr($rawdata, strpos($rawdata, 'LYRICSBEGIN'));
             $length = strlen($rawdata);
             $ParsedLyrics3['tag_offset_start'] = $info['avdataend'];
             $ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
         } else {
             $info['error'][] = '"LYRICSBEGIN" expected at ' . $endoffset . ' but found "' . substr($rawdata, 0, 11) . '" instead';
             return false;
         }
     }
     switch ($version) {
         case 1:
             if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICSEND') {
                 $ParsedLyrics3['raw']['LYR'] = trim(substr($rawdata, 11, strlen($rawdata) - 11 - 9));
                 $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
             } else {
                 $info['error'][] = '"LYRICSEND" expected at ' . (ftell($this->getid3->fp) - 11 + $length - 9) . ' but found "' . substr($rawdata, strlen($rawdata) - 9, 9) . '" instead';
                 return false;
             }
             break;
         case 2:
             if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICS200') {
                 $ParsedLyrics3['raw']['unparsed'] = substr($rawdata, 11, strlen($rawdata) - 11 - 9 - 6);
                 // LYRICSBEGIN + LYRICS200 + LSZ
                 $rawdata = $ParsedLyrics3['raw']['unparsed'];
                 while (strlen($rawdata) > 0) {
                     $fieldname = substr($rawdata, 0, 3);
                     $fieldsize = (int) substr($rawdata, 3, 5);
                     $ParsedLyrics3['raw'][$fieldname] = substr($rawdata, 8, $fieldsize);
                     $rawdata = substr($rawdata, 3 + 5 + $fieldsize);
                 }
                 if (isset($ParsedLyrics3['raw']['IND'])) {
                     $i = 0;
                     $flagnames = array('lyrics', 'timestamps', 'inhibitrandom');
                     foreach ($flagnames as $flagname) {
                         if (strlen($ParsedLyrics3['raw']['IND']) > $i++) {
                             $ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1 - 1));
                         }
                     }
                 }
                 $fieldnametranslation = array('ETT' => 'title', 'EAR' => 'artist', 'EAL' => 'album', 'INF' => 'comment', 'AUT' => 'author');
                 foreach ($fieldnametranslation as $key => $value) {
                     if (isset($ParsedLyrics3['raw'][$key])) {
                         $ParsedLyrics3['comments'][$value][] = trim($ParsedLyrics3['raw'][$key]);
                     }
                 }
                 if (isset($ParsedLyrics3['raw']['IMG'])) {
                     $imagestrings = explode("\r\n", $ParsedLyrics3['raw']['IMG']);
                     foreach ($imagestrings as $key => $imagestring) {
                         if (strpos($imagestring, '||') !== false) {
                             $imagearray = explode('||', $imagestring);
                             $ParsedLyrics3['images'][$key]['filename'] = isset($imagearray[0]) ? $imagearray[0] : '';
                             $ParsedLyrics3['images'][$key]['description'] = isset($imagearray[1]) ? $imagearray[1] : '';
                             $ParsedLyrics3['images'][$key]['timestamp'] = $this->Lyrics3Timestamp2Seconds(isset($imagearray[2]) ? $imagearray[2] : '');
                         }
                     }
                 }
                 if (isset($ParsedLyrics3['raw']['LYR'])) {
                     $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
                 }
             } else {
                 $info['error'][] = '"LYRICS200" expected at ' . (ftell($this->getid3->fp) - 11 + $length - 9) . ' but found "' . substr($rawdata, strlen($rawdata) - 9, 9) . '" instead';
                 return false;
             }
             break;
         default:
             $info['error'][] = 'Cannot process Lyrics3 version ' . $version . ' (only v1 and v2)';
             return false;
             break;
     }
     if (isset($info['id3v1']['tag_offset_start']) && $info['id3v1']['tag_offset_start'] <= $ParsedLyrics3['tag_offset_end']) {
         $info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data';
         unset($info['id3v1']);
         foreach ($info['warning'] as $key => $value) {
             if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
                 unset($info['warning'][$key]);
                 sort($info['warning']);
                 break;
             }
         }
     }
     $info['lyrics3'] = $ParsedLyrics3;
     return true;
 }
Exemplo n.º 25
0
 /**
  *
  * @param type $bytestring
  * @param type $byteorder
  * @return boolean
  */
 public function TIFFendian2Int($bytestring, $byteorder)
 {
     if ($byteorder == 'Intel') {
         return GetId3_Lib_Helper::LittleEndian2Int($bytestring);
     } elseif ($byteorder == 'Motorola') {
         return GetId3_Lib_Helper::BigEndian2Int($bytestring);
     }
     return false;
 }
Exemplo n.º 26
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'tar';
     $info['tar']['files'] = array();
     $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155prefix';
     $null_512k = str_repeat("", 512);
     // end-of-file marker
     fseek($this->getid3->fp, 0);
     while (!feof($this->getid3->fp)) {
         $buffer = fread($this->getid3->fp, 512);
         if (strlen($buffer) < 512) {
             break;
         }
         // check the block
         $checksum = 0;
         for ($i = 0; $i < 148; $i++) {
             $checksum += ord($buffer[$i]);
         }
         for ($i = 148; $i < 156; $i++) {
             $checksum += ord(' ');
         }
         for ($i = 156; $i < 512; $i++) {
             $checksum += ord($buffer[$i]);
         }
         $attr = unpack($unpack_header, $buffer);
         $name = isset($attr['fname']) ? trim($attr['fname']) : '';
         $mode = octdec(isset($attr['mode']) ? trim($attr['mode']) : '');
         $uid = octdec(isset($attr['uid']) ? trim($attr['uid']) : '');
         $gid = octdec(isset($attr['gid']) ? trim($attr['gid']) : '');
         $size = octdec(isset($attr['size']) ? trim($attr['size']) : '');
         $mtime = octdec(isset($attr['mtime']) ? trim($attr['mtime']) : '');
         $chksum = octdec(isset($attr['chksum']) ? trim($attr['chksum']) : '');
         $typflag = isset($attr['typflag']) ? trim($attr['typflag']) : '';
         $lnkname = isset($attr['lnkname']) ? trim($attr['lnkname']) : '';
         $magic = isset($attr['magic']) ? trim($attr['magic']) : '';
         $ver = isset($attr['ver']) ? trim($attr['ver']) : '';
         $uname = isset($attr['uname']) ? trim($attr['uname']) : '';
         $gname = isset($attr['gname']) ? trim($attr['gname']) : '';
         $devmaj = octdec(isset($attr['devmaj']) ? trim($attr['devmaj']) : '');
         $devmin = octdec(isset($attr['devmin']) ? trim($attr['devmin']) : '');
         $prefix = isset($attr['prefix']) ? trim($attr['prefix']) : '';
         if ($checksum == 256 && $chksum == 0) {
             // EOF Found
             break;
         }
         if ($prefix) {
             $name = $prefix . '/' . $name;
         }
         if (preg_match('#/$#', $name) && !$name) {
             $typeflag = 5;
         }
         if ($buffer == $null_512k) {
             // it's the end of the tar-file...
             break;
         }
         // Read to the next chunk
         fseek($this->getid3->fp, $size, SEEK_CUR);
         $diff = $size % 512;
         if ($diff != 0) {
             // Padding, throw away
             fseek($this->getid3->fp, 512 - $diff, SEEK_CUR);
         }
         // Protect against tar-files with garbage at the end
         if ($name == '') {
             break;
         }
         $info['tar']['file_details'][$name] = array('name' => $name, 'mode_raw' => $mode, 'mode' => self::display_perms($mode), 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => self::get_flag_type($typflag), 'linkname' => $lnkname, 'magic' => $magic, 'version' => $ver, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmaj, 'devminor' => $devmin);
         $info['tar']['files'] = GetId3_Lib_Helper::array_merge_clobber($info['tar']['files'], GetId3_Lib_Helper::CreateDeepArray($info['tar']['file_details'][$name]['name'], '/', $size));
     }
     return true;
 }
Exemplo n.º 27
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'swf';
     $info['video']['dataformat'] = 'swf';
     // http://www.openswf.org/spec/SWFfileformat.html
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $SWFfileData = fread($this->getid3->fp, $info['avdataend'] - $info['avdataoffset']);
     // 8 + 2 + 2 + max(9) bytes NOT including Frame_Size RECT data
     $info['swf']['header']['signature'] = substr($SWFfileData, 0, 3);
     switch ($info['swf']['header']['signature']) {
         case 'FWS':
             $info['swf']['header']['compressed'] = false;
             break;
         case 'CWS':
             $info['swf']['header']['compressed'] = true;
             break;
         default:
             $info['error'][] = 'Expecting "FWS" or "CWS" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes($info['swf']['header']['signature']) . '"';
             unset($info['swf']);
             unset($info['fileformat']);
             return false;
             break;
     }
     $info['swf']['header']['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, 3, 1));
     $info['swf']['header']['length'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, 4, 4));
     if ($info['swf']['header']['compressed']) {
         $SWFHead = substr($SWFfileData, 0, 8);
         $SWFfileData = substr($SWFfileData, 8);
         if ($decompressed = @gzuncompress($SWFfileData)) {
             $SWFfileData = $SWFHead . $decompressed;
         } else {
             $info['error'][] = 'Error decompressing compressed SWF data (' . strlen($SWFfileData) . ' bytes compressed, should be ' . ($info['swf']['header']['length'] - 8) . ' bytes uncompressed)';
             return false;
         }
     }
     $FrameSizeBitsPerValue = (ord(substr($SWFfileData, 8, 1)) & 0xf8) >> 3;
     $FrameSizeDataLength = ceil((5 + 4 * $FrameSizeBitsPerValue) / 8);
     $FrameSizeDataString = str_pad(decbin(ord(substr($SWFfileData, 8, 1)) & 0x7), 3, '0', STR_PAD_LEFT);
     for ($i = 1; $i < $FrameSizeDataLength; $i++) {
         $FrameSizeDataString .= str_pad(decbin(ord(substr($SWFfileData, 8 + $i, 1))), 8, '0', STR_PAD_LEFT);
     }
     list($X1, $X2, $Y1, $Y2) = explode("\n", wordwrap($FrameSizeDataString, $FrameSizeBitsPerValue, "\n", 1));
     $info['swf']['header']['frame_width'] = GetId3_Lib_Helper::Bin2Dec($X2);
     $info['swf']['header']['frame_height'] = GetId3_Lib_Helper::Bin2Dec($Y2);
     // http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
     // Next in the header is the frame rate, which is kind of weird.
     // It is supposed to be stored as a 16bit integer, but the first byte
     // (or last depending on how you look at it) is completely ignored.
     // Example: 0x000C  ->  0x0C  ->  12     So the frame rate is 12 fps.
     // Byte at (8 + $FrameSizeDataLength) is always zero and ignored
     $info['swf']['header']['frame_rate'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, 9 + $FrameSizeDataLength, 1));
     $info['swf']['header']['frame_count'] = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, 10 + $FrameSizeDataLength, 2));
     $info['video']['frame_rate'] = $info['swf']['header']['frame_rate'];
     $info['video']['resolution_x'] = intval(round($info['swf']['header']['frame_width'] / 20));
     $info['video']['resolution_y'] = intval(round($info['swf']['header']['frame_height'] / 20));
     $info['video']['pixel_aspect_ratio'] = (double) 1;
     if ($info['swf']['header']['frame_count'] > 0 && $info['swf']['header']['frame_rate'] > 0) {
         $info['playtime_seconds'] = $info['swf']['header']['frame_count'] / $info['swf']['header']['frame_rate'];
     }
     //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
     // SWF tags
     $CurrentOffset = 12 + $FrameSizeDataLength;
     $SWFdataLength = strlen($SWFfileData);
     while ($CurrentOffset < $SWFdataLength) {
         //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
         $TagIDTagLength = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 2));
         $TagID = ($TagIDTagLength & 0xfffc) >> 6;
         $TagLength = $TagIDTagLength & 0x3f;
         $CurrentOffset += 2;
         if ($TagLength == 0x3f) {
             $TagLength = GetId3_Lib_Helper::LittleEndian2Int(substr($SWFfileData, $CurrentOffset, 4));
             $CurrentOffset += 4;
         }
         unset($TagData);
         $TagData['offset'] = $CurrentOffset;
         $TagData['size'] = $TagLength;
         $TagData['id'] = $TagID;
         $TagData['data'] = substr($SWFfileData, $CurrentOffset, $TagLength);
         switch ($TagID) {
             case 0:
                 // end of movie
                 break 2;
             case 9:
                 // Set background color
                 //$info['swf']['tags'][] = $TagData;
                 $info['swf']['bgcolor'] = strtoupper(str_pad(dechex(GetId3_Lib_Helper::BigEndian2Int($TagData['data'])), 6, '0', STR_PAD_LEFT));
                 break;
             default:
                 if ($this->ReturnAllTagData) {
                     $info['swf']['tags'][] = $TagData;
                 }
                 break;
         }
         $CurrentOffset += $TagLength;
     }
     return true;
 }
Exemplo n.º 28
0
 /**
  *
  * @return boolean
  */
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $OriginalAVdataOffset = $info['avdataoffset'];
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $VOCheader = fread($this->getid3->fp, 26);
     $magic = 'Creative Voice File';
     if (substr($VOCheader, 0, 19) != $magic) {
         $info['error'][] = 'Expecting "' . GetId3_Lib_Helper::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . GetId3_Lib_Helper::PrintHexBytes(substr($VOCheader, 0, 19)) . '"';
         return false;
     }
     // shortcuts
     $thisfile_audio =& $info['audio'];
     $info['voc'] = array();
     $thisfile_voc =& $info['voc'];
     $info['fileformat'] = 'voc';
     $thisfile_audio['dataformat'] = 'voc';
     $thisfile_audio['bitrate_mode'] = 'cbr';
     $thisfile_audio['lossless'] = true;
     $thisfile_audio['channels'] = 1;
     // might be overriden below
     $thisfile_audio['bits_per_sample'] = 8;
     // might be overriden below
     // byte #     Description
     // ------     ------------------------------------------
     // 00-12      'Creative Voice File'
     // 13         1A (eof to abort printing of file)
     // 14-15      Offset of first datablock in .voc file (std 1A 00 in Intel Notation)
     // 16-17      Version number (minor,major) (VOC-HDR puts 0A 01)
     // 18-19      2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11)
     $thisfile_voc['header']['datablock_offset'] = GetId3_Lib_Helper::LittleEndian2Int(substr($VOCheader, 20, 2));
     $thisfile_voc['header']['minor_version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($VOCheader, 22, 1));
     $thisfile_voc['header']['major_version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($VOCheader, 23, 1));
     do {
         $BlockOffset = ftell($this->getid3->fp);
         $BlockData = fread($this->getid3->fp, 4);
         $BlockType = ord($BlockData[0]);
         $BlockSize = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 1, 3));
         $ThisBlock = array();
         GetId3_Lib_Helper::safe_inc($thisfile_voc['blocktypes'][$BlockType], 1);
         switch ($BlockType) {
             case 0:
                 // Terminator
                 // do nothing, we'll break out of the loop down below
                 break;
             case 1:
                 // Sound data
                 $BlockData .= fread($this->getid3->fp, 2);
                 if ($info['avdataoffset'] <= $OriginalAVdataOffset) {
                     $info['avdataoffset'] = ftell($this->getid3->fp);
                 }
                 fseek($this->getid3->fp, $BlockSize - 2, SEEK_CUR);
                 $ThisBlock['sample_rate_id'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 4, 1));
                 $ThisBlock['compression_type'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 5, 1));
                 $ThisBlock['compression_name'] = $this->VOCcompressionTypeLookup($ThisBlock['compression_type']);
                 if ($ThisBlock['compression_type'] <= 3) {
                     $thisfile_voc['compressed_bits_per_sample'] = GetId3_Lib_Helper::CastAsInt(str_replace('-bit', '', $ThisBlock['compression_name']));
                 }
                 // Less accurate sample_rate calculation than the Extended block (#8) data (but better than nothing if Extended Block is not available)
                 if (empty($thisfile_audio['sample_rate'])) {
                     // SR byte = 256 - (1000000 / sample_rate)
                     $thisfile_audio['sample_rate'] = GetId3_Lib_Helper::trunc(1000000 / (256 - $ThisBlock['sample_rate_id']) / $thisfile_audio['channels']);
                 }
                 break;
             case 2:
                 // Sound continue
             // Sound continue
             case 3:
                 // Silence
             // Silence
             case 4:
                 // Marker
             // Marker
             case 6:
                 // Repeat
             // Repeat
             case 7:
                 // End repeat
                 // nothing useful, just skip
                 fseek($this->getid3->fp, $BlockSize, SEEK_CUR);
                 break;
             case 8:
                 // Extended
                 $BlockData .= fread($this->getid3->fp, 4);
                 //00-01  Time Constant:
                 //   Mono: 65536 - (256000000 / sample_rate)
                 // Stereo: 65536 - (256000000 / (sample_rate * 2))
                 $ThisBlock['time_constant'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 4, 2));
                 $ThisBlock['pack_method'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 6, 1));
                 $ThisBlock['stereo'] = (bool) GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 7, 1));
                 $thisfile_audio['channels'] = $ThisBlock['stereo'] ? 2 : 1;
                 $thisfile_audio['sample_rate'] = GetId3_Lib_Helper::trunc(256000000 / (65536 - $ThisBlock['time_constant']) / $thisfile_audio['channels']);
                 break;
             case 9:
                 // data block that supersedes blocks 1 and 8. Used for stereo, 16 bit
                 $BlockData .= fread($this->getid3->fp, 12);
                 if ($info['avdataoffset'] <= $OriginalAVdataOffset) {
                     $info['avdataoffset'] = ftell($this->getid3->fp);
                 }
                 fseek($this->getid3->fp, $BlockSize - 12, SEEK_CUR);
                 $ThisBlock['sample_rate'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 4, 4));
                 $ThisBlock['bits_per_sample'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 8, 1));
                 $ThisBlock['channels'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 9, 1));
                 $ThisBlock['wFormat'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BlockData, 10, 2));
                 $ThisBlock['compression_name'] = $this->VOCwFormatLookup($ThisBlock['wFormat']);
                 if ($this->VOCwFormatActualBitsPerSampleLookup($ThisBlock['wFormat'])) {
                     $thisfile_voc['compressed_bits_per_sample'] = $this->VOCwFormatActualBitsPerSampleLookup($ThisBlock['wFormat']);
                 }
                 $thisfile_audio['sample_rate'] = $ThisBlock['sample_rate'];
                 $thisfile_audio['bits_per_sample'] = $ThisBlock['bits_per_sample'];
                 $thisfile_audio['channels'] = $ThisBlock['channels'];
                 break;
             default:
                 $info['warning'][] = 'Unhandled block type "' . $BlockType . '" at offset ' . $BlockOffset;
                 fseek($this->getid3->fp, $BlockSize, SEEK_CUR);
                 break;
         }
         if (!empty($ThisBlock)) {
             $ThisBlock['block_offset'] = $BlockOffset;
             $ThisBlock['block_size'] = $BlockSize;
             $ThisBlock['block_type_id'] = $BlockType;
             $thisfile_voc['blocks'][] = $ThisBlock;
         }
     } while (!feof($this->getid3->fp) && $BlockType != 0);
     // Terminator block doesn't have size field, so seek back 3 spaces
     fseek($this->getid3->fp, -3, SEEK_CUR);
     ksort($thisfile_voc['blocktypes']);
     if (!empty($thisfile_voc['compressed_bits_per_sample'])) {
         $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / ($thisfile_voc['compressed_bits_per_sample'] * $thisfile_audio['channels'] * $thisfile_audio['sample_rate']);
         $thisfile_audio['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     }
     return true;
 }
Exemplo n.º 29
0
 /**
  *
  * @param type $compre
  * @return type
  */
 public static function heavyCompression($compre)
 {
     // The first four bits indicate gain changes in 6.02dB increments which can be
     // implemented with an arithmetic shift operation. The following four bits
     // indicate linear gain changes, and require a 5-bit multiply.
     // We will represent the two 4-bit fields of compr as follows:
     //   X0 X1 X2 X3 . Y4 Y5 Y6 Y7
     // The meaning of the X values is most simply described by considering X to represent a 4-bit
     // signed integer with values from –8 to +7. The gain indicated by X is then (X + 1) * 6.02 dB. The
     // following table shows this in detail.
     // Meaning of 4 msb of compr
     //  7    +48.16 dB
     //  6    +42.14 dB
     //  5    +36.12 dB
     //  4    +30.10 dB
     //  3    +24.08 dB
     //  2    +18.06 dB
     //  1    +12.04 dB
     //  0     +6.02 dB
     // -1         0 dB
     // -2     –6.02 dB
     // -3    –12.04 dB
     // -4    –18.06 dB
     // -5    –24.08 dB
     // -6    –30.10 dB
     // -7    –36.12 dB
     // -8    –42.14 dB
     $fourbit = str_pad(decbin(($compre & 0xf0) >> 4), 4, '0', STR_PAD_LEFT);
     if ($fourbit[0] == '1') {
         $log_gain = -8 + bindec(substr($fourbit, 1));
     } else {
         $log_gain = bindec(substr($fourbit, 1));
     }
     $log_gain = ($log_gain + 1) * GetId3_Lib_Helper::RGADamplitude2dB(2);
     // The value of Y is a linear representation of a gain change of up to –6 dB. Y is considered to
     // be an unsigned fractional integer, with a leading value of 1, or: 0.1 Y4 Y5 Y6 Y7 (base 2). Y can
     // represent values between 0.111112 (or 31/32) and 0.100002 (or 1/2). Thus, Y can represent gain
     // changes from –0.28 dB to –6.02 dB.
     $lin_gain = (16 + ($compre & 0xf)) / 32;
     // The combination of X and Y values allows compr to indicate gain changes from
     //  48.16 – 0.28 = +47.89 dB, to
     // –42.14 – 6.02 = –48.16 dB.
     return $log_gain - $lin_gain;
 }
Exemplo n.º 30
0
 /**
  *
  * @param type $BonkTagName
  */
 public function HandleBonkTags($BonkTagName)
 {
     $info =& $this->getid3->info;
     switch ($BonkTagName) {
         case 'BONK':
             // shortcut
             $thisfile_bonk_BONK =& $info['bonk']['BONK'];
             $BonkData = "" . 'BONK' . fread($this->getid3->fp, 17);
             $thisfile_bonk_BONK['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 5, 1));
             $thisfile_bonk_BONK['number_samples'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 6, 4));
             $thisfile_bonk_BONK['sample_rate'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 10, 4));
             $thisfile_bonk_BONK['channels'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 14, 1));
             $thisfile_bonk_BONK['lossless'] = (bool) GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 15, 1));
             $thisfile_bonk_BONK['joint_stereo'] = (bool) GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 16, 1));
             $thisfile_bonk_BONK['number_taps'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 17, 2));
             $thisfile_bonk_BONK['downsampling_ratio'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 19, 1));
             $thisfile_bonk_BONK['samples_per_packet'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 20, 2));
             $info['avdataoffset'] = $thisfile_bonk_BONK['offset'] + 5 + 17;
             $info['avdataend'] = $thisfile_bonk_BONK['offset'] + $thisfile_bonk_BONK['size'];
             $info['fileformat'] = 'bonk';
             $info['audio']['dataformat'] = 'bonk';
             $info['audio']['bitrate_mode'] = 'vbr';
             // assumed
             $info['audio']['channels'] = $thisfile_bonk_BONK['channels'];
             $info['audio']['sample_rate'] = $thisfile_bonk_BONK['sample_rate'];
             $info['audio']['channelmode'] = $thisfile_bonk_BONK['joint_stereo'] ? 'joint stereo' : 'stereo';
             $info['audio']['lossless'] = $thisfile_bonk_BONK['lossless'];
             $info['audio']['codec'] = 'bonk';
             $info['playtime_seconds'] = $thisfile_bonk_BONK['number_samples'] / ($thisfile_bonk_BONK['sample_rate'] * $thisfile_bonk_BONK['channels']);
             if ($info['playtime_seconds'] > 0) {
                 $info['audio']['bitrate'] = ($info['bonk']['dataend'] - $info['bonk']['dataoffset']) * 8 / $info['playtime_seconds'];
             }
             break;
         case 'INFO':
             // shortcut
             $thisfile_bonk_INFO =& $info['bonk']['INFO'];
             $thisfile_bonk_INFO['version'] = GetId3_Lib_Helper::LittleEndian2Int(fread($this->getid3->fp, 1));
             $thisfile_bonk_INFO['entries_count'] = 0;
             $NextInfoDataPair = fread($this->getid3->fp, 5);
             if (!$this->BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
                 while (!feof($this->getid3->fp)) {
                     //$CurrentSeekInfo['offset']  = GetId3_lib::LittleEndian2Int(substr($NextInfoDataPair, 0, 4));
                     //$CurrentSeekInfo['nextbit'] = GetId3_lib::LittleEndian2Int(substr($NextInfoDataPair, 4, 1));
                     //$thisfile_bonk_INFO[] = $CurrentSeekInfo;
                     $NextInfoDataPair = fread($this->getid3->fp, 5);
                     if ($this->BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
                         fseek($this->getid3->fp, -5, SEEK_CUR);
                         break;
                     }
                     $thisfile_bonk_INFO['entries_count']++;
                 }
             }
             break;
         case 'META':
             $BonkData = "" . 'META' . fread($this->getid3->fp, $info['bonk']['META']['size'] - 5);
             $info['bonk']['META']['version'] = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, 5, 1));
             $MetaTagEntries = floor((strlen($BonkData) - 8 - 6) / 8);
             // BonkData - xxxxmeta - ØMETA
             $offset = 6;
             for ($i = 0; $i < $MetaTagEntries; $i++) {
                 $MetaEntryTagName = substr($BonkData, $offset, 4);
                 $offset += 4;
                 $MetaEntryTagOffset = GetId3_Lib_Helper::LittleEndian2Int(substr($BonkData, $offset, 4));
                 $offset += 4;
                 $info['bonk']['META']['tags'][$MetaEntryTagName] = $MetaEntryTagOffset;
             }
             break;
         case ' ID3':
             $info['audio']['encoder'] = 'Extended BONK v0.9+';
             // ID3v2 checking is optional
             if (class_exists('GetId3_Module_Tag_Id3v2')) {
                 $getid3_temp = new GetId3_GetId3();
                 $getid3_temp->openfile($this->getid3->filename);
                 $getid3_id3v2 = new GetId3_Module_Tag_Id3v2($getid3_temp);
                 $getid3_id3v2->StartingOffset = $info['bonk'][' ID3']['offset'] + 2;
                 $info['bonk'][' ID3']['valid'] = $getid3_id3v2->Analyze();
                 if ($info['bonk'][' ID3']['valid']) {
                     $info['id3v2'] = $getid3_temp->info['id3v2'];
                 }
                 unset($getid3_temp, $getid3_id3v2);
             }
             break;
         default:
             $info['warning'][] = 'Unexpected Bonk tag "' . $BonkTagName . '" at offset ' . $info['bonk'][$BonkTagName]['offset'];
             break;
     }
 }