Filter:   InfoImg
download getid3.bonk.php
Language: PHP
LOC: 150
Project Info
Tunez
Server: SourceForge
Type: cvs
...tunez\tunez\tunez\html\id3\
   getid3.aac.php
   getid3.ape.php
   getid3.asf.php
   getid3.au.php
   getid3.avr.php
   getid3.bmp.php
   getid3.bonk.php
   getid3.check.php
   getid3.exe.php
   getid3.flac.php
   getid3.frames.php
   getid3.functions.php
   getid3.getimagesize.php
   getid3.gif.php
   getid3.id3v1.php
   getid3.id3v2.php
   getid3.iso.php
   getid3.jpg.php
   getid3.la.php
   getid3.lookup.php
   getid3.lpac.php
   getid3.lyrics3.php
   getid3.matroska.php
   getid3.midi.php
   getid3.mod.php
   getid3.monkey.php
   getid3.mp3.php
   getid3.mpc.php
   getid3.mpeg.php
   getid3.nsv.php
   getid3.ogg.php
   getid3.ogginfo.php
   getid3.optimfrog.php
   getid3.php
   getid3.png.php
   getid3.putid3.php
   getid3.quicktime.php
   getid3.rar.php
   getid3.real.php
   getid3.rgad.php
   getid3.riff.php
   getid3.shorten.php
   getid3.swf.php
   getid3.thumbnail.php
   getid3.voc.php
   getid3.vqf.php
   getid3.write.php
   getid3.zip.php

<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                ///
//            or http://www.getid3.org                        ///
/////////////////////////////////////////////////////////////////
//                                                             //
// getid3.bonk.php - part of getID3()                          //
// See getid3.readme.txt for more details                      //
//                                                             //
/////////////////////////////////////////////////////////////////

function getBonkHeaderFilepointer(&$fd, &$ThisFileInfo) {

	$ThisFileInfo['bonk']['dataoffset'] = $ThisFileInfo['avdataoffset'];
	$ThisFileInfo['bonk']['dataend']    = $ThisFileInfo['avdataend'];
	$ThisFileInfo['audio']['encoder']   = 'Extended BONK v0.9+'; // overridden below if different

	// scan-from-end method, for v0.6 and higher
	fseek($fd, $ThisFileInfo['bonk']['dataend'] - 8, SEEK_SET);
	$PossibleBonkTag = fread($fd, 8);
	while (BonkIsValidTagName(substr($PossibleBonkTag, 4, 4), true)) {
		$BonkTagSize = LittleEndian2Int(substr($PossibleBonkTag, 0, 4));
		fseek($fd, 0 - $BonkTagSize, SEEK_CUR);
		$BonkTagOffset = ftell($fd);
		$TagHeaderTest = fread($fd, 5);
		if (($TagHeaderTest{0} != "\x00") || (substr($PossibleBonkTag, 4, 4) != strtolower(substr($PossibleBonkTag, 4, 4)))) {
			$ThisFileInfo['error'] .= "\n".'Expecting "'.strtoupper(substr($PossibleBonkTag, 4, 4)).'" at offset '.$BonkTagOffset.', found "'.$TagHeaderTest.'"';
			return false;
		}
		$BonkTagName = substr($TagHeaderTest, 1, 4);

		$ThisFileInfo['bonk']["$BonkTagName"]['size']   = $BonkTagSize;
		$ThisFileInfo['bonk']["$BonkTagName"]['offset'] = $BonkTagOffset;
		HandleBonkTags($fd, $BonkTagName, $ThisFileInfo);
		$NextTagEndOffset = $BonkTagOffset - 8;
		if ($NextTagEndOffset < $ThisFileInfo['bonk']['dataoffset']) {
			return true;
		}
		fseek($fd, $NextTagEndOffset, SEEK_SET);
		$PossibleBonkTag = fread($fd, 8);
	}

	// seek-from-beginning method for v0.4 and v0.5
	if (empty($ThisFileInfo['bonk']['BONK'])) {
		fseek($fd, $ThisFileInfo['bonk']['dataoffset'], SEEK_SET);
		do {
			$TagHeaderTest = fread($fd, 5);
			switch ($TagHeaderTest) {
				case "\x00".'BONK':
					if (empty($ThisFileInfo['audio']['encoder'])) {
						$ThisFileInfo['audio']['encoder'] = 'BONK v0.4';
					}
					break;

				case "\x00".'INFO':
					$ThisFileInfo['audio']['encoder'] = 'Extended BONK v0.5';
					break;

				default:
					break 2;
			}
			$BonkTagName = substr($TagHeaderTest, 1, 4);
			$ThisFileInfo['bonk']["$BonkTagName"]['size']   = $ThisFileInfo['bonk']['dataend'] - $ThisFileInfo['bonk']['dataoffset'];
			$ThisFileInfo['bonk']["$BonkTagName"]['offset'] = $ThisFileInfo['bonk']['dataoffset'];
			HandleBonkTags($fd, $BonkTagName, $ThisFileInfo);

		} while (true);
	}

	// parse META block for v0.6 - v0.8
	if (empty($ThisFileInfo['bonk']['INFO']) && isset($ThisFileInfo['bonk']['META']['tags']['info'])) {
		fseek($fd, $ThisFileInfo['bonk']['META']['tags']['info'], SEEK_SET);
		$TagHeaderTest = fread($fd, 5);
		if ($TagHeaderTest == "\x00".'INFO') {
			$ThisFileInfo['audio']['encoder'] = 'Extended BONK v0.6 - v0.8';

			$BonkTagName = substr($TagHeaderTest, 1, 4);
			$ThisFileInfo['bonk']["$BonkTagName"]['size']   = $ThisFileInfo['bonk']['dataend'] - $ThisFileInfo['bonk']['dataoffset'];
			$ThisFileInfo['bonk']["$BonkTagName"]['offset'] = $ThisFileInfo['bonk']['dataoffset'];
			HandleBonkTags($fd, $BonkTagName, $ThisFileInfo);
		}
	}

	if (empty($ThisFileInfo['bonk']['BONK'])) {
		unset($ThisFileInfo['bonk']);
	}
	return true;

}

function HandleBonkTags(&$fd, &$BonkTagName, &$ThisFileInfo) {

	switch ($BonkTagName) {
		case 'BONK':
			$BonkData = "\x00".$BonkTagName.fread($fd, 17);
			$ThisFileInfo['bonk']['BONK']['version']            =        LittleEndian2Int(substr($BonkData,  5, 1));
			$ThisFileInfo['bonk']['BONK']['number_samples']     =        LittleEndian2Int(substr($BonkData,  6, 4));
			$ThisFileInfo['bonk']['BONK']['sample_rate']        =        LittleEndian2Int(substr($BonkData, 10, 4));

			$ThisFileInfo['bonk']['BONK']['channels']           =        LittleEndian2Int(substr($BonkData, 14, 1));
			$ThisFileInfo['bonk']['BONK']['lossless']           = (bool) LittleEndian2Int(substr($BonkData, 15, 1));
			$ThisFileInfo['bonk']['BONK']['joint_stereo']       = (bool) LittleEndian2Int(substr($BonkData, 16, 1));
			$ThisFileInfo['bonk']['BONK']['number_taps']        =        LittleEndian2Int(substr($BonkData, 17, 2));
			$ThisFileInfo['bonk']['BONK']['downsampling_ratio'] =        LittleEndian2Int(substr($BonkData, 19, 1));
			$ThisFileInfo['bonk']['BONK']['samples_per_packet'] =        LittleEndian2Int(substr($BonkData, 20, 2));


			$ThisFileInfo['avdataoffset'] = $ThisFileInfo['bonk']["$BonkTagName"]['offset'] + 5 + 17;
			$ThisFileInfo['avdataend']    = $ThisFileInfo['bonk']["$BonkTagName"]['offset'] + $ThisFileInfo['bonk']["$BonkTagName"]['size'];

			$ThisFileInfo['fileformat']               = 'bonk';
			$ThisFileInfo['audio']['dataformat']      = 'bonk';
			$ThisFileInfo['audio']['bitrate_mode']    = 'vbr'; // assumed
			$ThisFileInfo['audio']['bits_per_sample'] = 16;    // assumed
			$ThisFileInfo['audio']['channels']        = $ThisFileInfo['bonk']['BONK']['channels'];
			$ThisFileInfo['audio']['sample_rate']     = $ThisFileInfo['bonk']['BONK']['sample_rate'];
			$ThisFileInfo['audio']['channelmode']     = ($ThisFileInfo['bonk']['BONK']['joint_stereo'] ? 'joint stereo' : 'stereo');
			$ThisFileInfo['audio']['lossless']        = $ThisFileInfo['bonk']['BONK']['lossless'];
			$ThisFileInfo['audio']['codec']           = 'bonk';

			$ThisFileInfo['playtime_seconds'] = $ThisFileInfo['bonk']['BONK']['number_samples'] / ($ThisFileInfo['bonk']['BONK']['sample_rate'] * $ThisFileInfo['bonk']['BONK']['channels']);
			if ($ThisFileInfo['playtime_seconds'] > 0) {
				$ThisFileInfo['audio']['bitrate'] = (($ThisFileInfo['bonk']['dataend'] - $ThisFileInfo['bonk']['dataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
			}
			break;

		case 'INFO':
			$ThisFileInfo['bonk']['INFO']['version'] = LittleEndian2Int(fread($fd, 1));
			$ThisFileInfo['bonk']['INFO']['entries_count'] = 0;
			$NextInfoDataPair = fread($fd, 5);
			if (!BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
				while (!feof($fd)) {
					//$CurrentSeekInfo['offset']  = LittleEndian2Int(substr($NextInfoDataPair, 0, 4));
					//$CurrentSeekInfo['nextbit'] = LittleEndian2Int(substr($NextInfoDataPair, 4, 1));
					//$ThisFileInfo['bonk']['INFO'][] = $CurrentSeekInfo;

					$NextInfoDataPair = fread($fd, 5);
					if (BonkIsValidTagName(substr($NextInfoDataPair, 1, 4))) {
						fseek($fd, -5, SEEK_CUR);
						break;
					}
					$ThisFileInfo['bonk']['INFO']['entries_count']++;
				}
			}
			break;

		case 'META':
			$BonkData = "\x00".$BonkTagName.fread($fd, $ThisFileInfo['bonk']["$BonkTagName"]['size'] - 5);
			$ThisFileInfo['bonk']['META']['version'] = 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 = LittleEndian2Int(substr($BonkData, $offset, 4));
				$offset += 4;
				$ThisFileInfo['bonk']['META']['tags']["$MetaEntryTagName"] = $MetaEntryTagOffset;
			}
			break;

		case ' ID3':
			$ThisFileInfo['audio']['encoder'] = 'Extended BONK v0.9+';
			require_once(GETID3_INCLUDEPATH.'getid3.id3v2.php');
			$ThisFileInfo['bonk'][' ID3']['valid'] = HandleID3v2Tag($fd, $ThisFileInfo, $ThisFileInfo['bonk']["$BonkTagName"]['offset'] + 2);
			break;

		default:
			$ThisFileInfo['warning'] .= "\n".'Unexpected Bonk tag "'.$BonkTagName.'" at offset '.$ThisFileInfo['bonk']["$BonkTagName"]['offset'];
			break;

	}
}

function BonkIsValidTagName($PossibleBonkTag, $ignorecase=false) {
	static $BonkIsValidTagName = array();
	if (empty($BonkIsValidTagName)) {
		$BonkIsValidTagName[] = 'BONK';
		$BonkIsValidTagName[] = 'INFO';
		$BonkIsValidTagName[] = ' ID3';
		$BonkIsValidTagName[] = 'META';
	}
	foreach ($BonkIsValidTagName as $validtagname) {
		if ($ignorecase && (strtolower($validtagname) == strtolower($PossibleBonkTag))) {
			return true;
		} elseif ($validtagname == $PossibleBonkTag) {
			return true;
		}
	}
	return false;
}

?>