download this file: class.ogg.php view text/plain: class.ogg.php file encoding: UTF-8 [goback]
<?php
##
## getID3() by James Heinrich <info@getid3.org>
## available at http://getid3.sourceforge.net
## or http://www.getid3.org
##
## getid3.ogg.php - part of getID3()
## See getid3.readme.txt for more details
##
## renew 'class.ogg.php' file
## author : san2(at)linuxchannel.net
## url : http://linuxchannel.net/
## changes :
## - 2003.05.27
##
## ogg file header infomation
##
class ogg
{
var $file = ''; // ogg file
var $error = ''; // for error debugging
var $bitrate = 0;
var $filesize = 0;
var $crc = false; // Frames are crc protected?
var $frequency= 0; // Frequency
var $padding = false; // Frames padded
var $private = false; // Private bit set?
var $mode = ''; // Mode (Stereo etc)
var $length = ''; // length of mp3 format hh:ss
var $lengths = 0; // length of mp3 in seconds
var $tmp = array('Unknown','Mono','Stereo',''=>'Unknown');
## initial function
##
function ogg($debug=0)
{
define('FREAD_BUFFER_SIZE',16384);
}
function gettag($file)
{
$info = array();
$info['ogg'] = array();
$info['audio'] = array();
$this->file = $file;
if(!$fd = @fopen($this->file,'rb'))
{
$this->error = 'Unable to open : '.$this->file;
return;
}
$info = $this->getoggheaderfilepointer($fd);
@fclose($fd);
//$this->info = $info;
## $info['ogg'] copy to $this;
##
$this->array2this($info['ogg']);
unset($info['ogg']);
## $info['audio'] copy to $this;
##
$this->array2this($info['audio']);
unset($info['audio']);
## $info copy to $this;
##
$this->array2this($info);
unset($info);
$this->filesize = $this->hsize($this->filesize);
$this->mode = $this->tmp[$this->channels];
if($this->samplerate) $this->frequency = $this->samplerate .'Hz';
if($this->bitrate = round($this->bitrate))
{
$s = (float)((($this->avdataend-$this->avdataoffset)*8)/$this->bitrate);
$this->length = sprintf('%02d:%02d',floor($s/60),floor($s-(floor($s/60)*60)));
$this->lengths = (int)$s;
$this->bitrate = (int)($this->bitrate/1024).'Kbps';
}
}
function hsize($bfsize, $sub=0)
{
$bytes = number_format($bfsize).' Bytes';
if($bfsize < 1024) return $bytes;
else if($bfsize < 1048576) $bfsize = number_format(round($bfsize/1024)).' KB';
else if($bfsize < 1073741827) $bfsize = number_format($bfsize/1048576,1).'MB';
else $bfsize = number_format($bfsize/1073741827,1).' GB';
if($sub) $bfsize .= "($bytes)";
return $bfsize;
}
function array2this($array)
{
if(!is_array($array)) return;
foreach($array AS $k=>$v)
{ $this->$k = $v; }
}
function getOggHeaderFilepointer(&$fd)
{
$ThisFileInfo = array();
$ThisFileInfo['avdataoffset'] = 0;
fseek($fd,0,SEEK_END); // end to file pinter
$ThisFileInfo['avdataend'] = $ThisFileInfo['filesize'] = ftell($fd); // for 2^32 over
// Page 1 - Stream Header
//fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
rewind($fd);
if(!$oggpageinfo = $this->ParseOggPageHeader($fd))
{
$ThisFileInfo['error'] .= "\n".'not Ogg file';
return $ThisFileInfo;
}
$ThisFileInfo['fileformat'] = 'ogg';
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
if(ftell($fd) >= FREAD_BUFFER_SIZE)
{
$ThisFileInfo['error'] .= "\n".'Could not find start of Ogg page in the first '.
FREAD_BUFFER_SIZE.' bytes (this might not be an Ogg-Vorbis file?)';
unset($ThisFileInfo['fileformat']);
unset($ThisFileInfo['ogg']);
return $ThisFileInfo;
}
$filedata = fread($fd, $oggpageinfo['page_length']);
$filedataoffset = 0;
if(substr($filedata, 0, 4) == 'fLaC')
{
$ThisFileInfo['audio']['dataformat'] = 'flac';
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
$ThisFileInfo['audio']['lossless'] = true;
}
else if(substr($filedata, 1, 6) == 'vorbis')
{
$ThisFileInfo['audio']['dataformat'] = 'vorbis';
$ThisFileInfo['audio']['lossless'] = false;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type']
= substr($filedata, $filedataoffset, 6); // hard-coded to 'vorbis'
$filedataoffset += 6;
$ThisFileInfo['ogg']['bitstreamversion']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['numberofchannels']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$ThisFileInfo['audio']['channels']
= $ThisFileInfo['ogg']['numberofchannels'];
$ThisFileInfo['ogg']['samplerate']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
if($ThisFileInfo['ogg']['samplerate'] == 0)
{
$ThisFileInfo['error'] .= "\n".'Corrupt Ogg file: sample rate == zero';
return $ThisFileInfo;
}
$ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['ogg']['samplerate'];
$ThisFileInfo['ogg']['samples'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_average'] = 0; // filled in later
$ThisFileInfo['ogg']['bitrate_max']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_nominal']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['bitrate_min']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['blocksize_small']
= pow(2, $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0x0F);
$ThisFileInfo['ogg']['blocksize_large'] = pow(2, ($this->LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0xF0) >> 4);
$ThisFileInfo['ogg']['stop_bit']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1)); // must be 1, marks end of packet
$ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; // overridden if actually abr
if($ThisFileInfo['ogg']['bitrate_max'] == 0xFFFFFFFF)
{
unset($ThisFileInfo['ogg']['bitrate_max']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
if($ThisFileInfo['ogg']['bitrate_nominal'] == 0xFFFFFFFF)
{
unset($ThisFileInfo['ogg']['bitrate_nominal']);
}
if($ThisFileInfo['ogg']['bitrate_min'] == 0xFFFFFFFF)
{
unset($ThisFileInfo['ogg']['bitrate_min']);
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
}
}
// http://www.speex.org/manual/node10.html
//
else if(substr($filedata, 0, 8) == 'Speex ')
{
$ThisFileInfo['audio']['dataformat'] = 'speex';
$ThisFileInfo['mime_type'] = 'audio/speex';
$ThisFileInfo['audio']['bitrate_mode'] = 'abr';
$ThisFileInfo['audio']['lossless'] = false;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_string']
= substr($filedata, $filedataoffset, 8); // hard-coded to 'Speex '
$filedataoffset += 8;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version']
= substr($filedata, $filedataoffset, 20);
$filedataoffset += 20;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version_id']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['header_size']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode_bitstream_version']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['bitrate']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['framesize']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['frames_per_packet']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['extra_headers']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved1']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved2']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$ThisFileInfo['speex']['speex_version']
= trim($ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version']);
$ThisFileInfo['speex']['sample_rate']
= $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate'];
$ThisFileInfo['speex']['channels']
= $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels'];
$ThisFileInfo['speex']['vbr']
= (bool) $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr'];
$ThisFileInfo['speex']['band_type']
= $this->SpeexBandModeLookup($ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode']);
$ThisFileInfo['audio']['sample_rate']
= $ThisFileInfo['speex']['sample_rate'];
$ThisFileInfo['audio']['channels']
= $ThisFileInfo['speex']['channels'];
if($ThisFileInfo['speex']['vbr'])
{ $ThisFileInfo['audio']['bitrate_mode'] = 'vbr'; }
}
else
{
$ThisFileInfo['error'] .=
"\n".'Expecting either "Speex " or '.
'"vorbis" identifier strings, found neither';
unset($ThisFileInfo['ogg']);
unset($ThisFileInfo['mime_type']);
return $ThisFileInfo;
}
// Last Page - Number of Samples
fseek($fd, max($ThisFileInfo['avdataend'] - FREAD_BUFFER_SIZE, 0), SEEK_SET);
$LastChunkOfOgg = strrev(fread($fd, FREAD_BUFFER_SIZE));
if($LastOggSpostion = strpos($LastChunkOfOgg, 'SggO'))
{
fseek($fd, $ThisFileInfo['avdataend'] - ($LastOggSpostion + strlen('SggO')), SEEK_SET);
$ThisFileInfo['avdataend'] = ftell($fd);
$ThisFileInfo['ogg']['pageheader']['eos'] = $this->ParseOggPageHeader($fd);
$ThisFileInfo['ogg']['samples']
= $ThisFileInfo['ogg']['pageheader']['eos']['pcm_abs_position'];
if($ThisFileInfo['ogg']['samples'] == 0)
{
$ThisFileInfo['error'] .= "\n".'Corrupt Ogg file: eos.number of samples == zero';
return $ThisFileInfo;
}
$ThisFileInfo['ogg']['bitrate_average']
= (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8)
/ ($ThisFileInfo['ogg']['samples'] / $ThisFileInfo['audio']['sample_rate']);
}
if(isset($ThisFileInfo['ogg']['bitrate_average'])
&& ($ThisFileInfo['ogg']['bitrate_average'] > 0))
{
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['ogg']['bitrate_average'];
}
else if(isset($ThisFileInfo['ogg']['bitrate_nominal'])
&& ($ThisFileInfo['ogg']['bitrate_nominal'] > 0))
{
$ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['ogg']['bitrate_nominal'];
}
else if(isset($ThisFileInfo['ogg']['bitrate_min'])
&& isset($ThisFileInfo['ogg']['bitrate_max']))
{
$ThisFileInfo['audio']['bitrate']
= ($ThisFileInfo['ogg']['bitrate_min'] + $ThisFileInfo['ogg']['bitrate_max']) / 2;
}
/***
if (isset($ThisFileInfo['audio']['bitrate']) && !isset($ThisFileInfo['playtime_seconds'])) {
if ($ThisFileInfo['audio']['bitrate'] == 0) {
$ThisFileInfo['error'] .= "\n".'Corrupt Ogg file: bitrate_audio == zero';
return false;
}
}
***/
//$ThisFileInfo['playtime_seconds']
// = (float) ((($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['audio']['bitrate']);
if(isset($ThisFileInfo['ogg']['vendor']))
{
$ThisFileInfo['audio']['encoder']
= preg_replace('/^Encoded with /', '', $ThisFileInfo['ogg']['vendor']);
}
return $ThisFileInfo;
}
// http://xiph.org/ogg/vorbis/doc/framing.html
//
function ParseOggPageHeader(&$fd)
{
$oggheader['page_start_offset'] = ftell($fd); // where we started from in the file
$filedata = fread($fd, FREAD_BUFFER_SIZE);
$filedataoffset = 0;
while((substr($filedata, $filedataoffset++, 4) != 'OggS'))
{
if((ftell($fd) - $oggheader['page_start_offset']) >= FREAD_BUFFER_SIZE) {
// should be found before here
return false;
}
if((($filedataoffset + 28) > strlen($filedata)) || (strlen($filedata) < 28)) {
if (feof($fd) || (($filedata .= fread($fd, FREAD_BUFFER_SIZE)) === false)) {
// get some more data, unless eof, in which case fail
return false;
}
}
}
$filedataoffset += strlen('OggS') - 1; // page, delimited by 'OggS'
$oggheader['stream_structver']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$oggheader['flags_raw']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$oggheader['flags']['fresh']
= (bool) ($oggheader['flags_raw'] & 0x01); // fresh packet
$oggheader['flags']['bos']
= (bool) ($oggheader['flags_raw'] & 0x02); // first page of logical bitstream (bos)
$oggheader['flags']['eos']
= (bool) ($oggheader['flags_raw'] & 0x04); // last page of logical bitstream (eos)
$oggheader['pcm_abs_position']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 8));
$filedataoffset += 8;
$oggheader['stream_serialno']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$oggheader['page_seqno']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$oggheader['page_checksum']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 4));
$filedataoffset += 4;
$oggheader['page_segments']
= $this->LittleEndian2Int(substr($filedata, $filedataoffset, 1));
$filedataoffset += 1;
$oggheader['page_length'] = 0;
for($i=0; $i<$oggheader['page_segments']; $i++)
{
$oggheader['segment_table'][$i]
= $this->LittleEndian2Int(substr($filedata,$filedataoffset,1));
$filedataoffset += 1;
$oggheader['page_length'] += $oggheader['segment_table'][$i];
}
$oggheader['header_end_offset'] = $oggheader['page_start_offset']+$filedataoffset;
$oggheader['page_end_offset'] = $oggheader['header_end_offset']+$oggheader['page_length'];
fseek($fd, $oggheader['header_end_offset'], SEEK_SET);
return $oggheader;
}
function SpeexBandModeLookup($mode)
{
static $SpeexBandModeLookup = array();
if(empty($SpeexBandModeLookup))
{
$SpeexBandModeLookup[0] = 'narrow';
$SpeexBandModeLookup[1] = 'wide';
$SpeexBandModeLookup[2] = 'ultra-wide';
}
return (isset($SpeexBandModeLookup[$mode]) ? $SpeexBandModeLookup[$mode] : null);
}
function OggPageSegmentLength($OggInfoArray, $SegmentNumber=1)
{
for($i=0; $i<$SegmentNumber; $i++)
{
$segmentlength = 0;
foreach ($OggInfoArray['segment_table'] AS $key => $value)
{
$segmentlength += $value;
if ($value < 255) break;
}
}
return $segmentlength;
}
function DecimalBinary2Float($binarynumerator)
{
$numerator = BinDec($binarynumerator);
$denominator = BinDec(str_repeat('1', strlen($binarynumerator)));
return ($numerator / $denominator);
}
function LittleEndian2Float($byteword)
{
return $this->BigEndian2Float(strrev($byteword));
}
// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
// http://www.psc.edu/general/software/packages/ieee/ieee.html
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
//
function BigEndian2Float($byteword)
{
$bitword = $this->BigEndian2Bin($byteword);
$signbit = $bitword{0};
switch(strlen($byteword) * 8)
{
case 32:
$exponentbits = 8;
$fractionbits = 23;
break;
case 64:
$exponentbits = 11;
$fractionbits = 52;
break;
case 80:
$exponentbits = 16;
$fractionbits = 64;
break;
default:
return false;
break;
}
$exponentstring = substr($bitword, 1, $exponentbits - 1);
$fractionstring = substr($bitword, $exponentbits, $fractionbits);
$exponent = BinDec($exponentstring);
$fraction = BinDec($fractionstring);
if(($exponentbits == 16) && ($fractionbits == 64))
{
// 80-bit
// As used in Apple AIFF for sample_rate
// A bit of a hack, but it works ;)
return pow(2, ($exponent - 16382)) * $this->DecimalBinary2Float($fractionstring);
}
if(($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0))
{
// Not a Number
$floatvalue = false;
}
else if(($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0))
{
if ($signbit == '1') {
$floatvalue = '-infinity';
} else {
$floatvalue = '+infinity';
}
}
else if(($exponent == 0) && ($fraction == 0))
{
if ($signbit == '1') {
$floatvalue = -0;
} else {
$floatvalue = 0;
}
$floatvalue = ($signbit ? 0 : -0);
}
else if(($exponent == 0) && ($fraction != 0))
{
// These are 'unnormalized' values
$floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2)))
* $this->DecimalBinary2Float($fractionstring);
if ($signbit == '1') {
$floatvalue *= -1;
}
}
else if($exponent != 0)
{
$floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1)))
* (1 + $this->DecimalBinary2Float($fractionstring));
if ($signbit == '1') {
$floatvalue *= -1;
}
}
return (float) $floatvalue;
}
// truncates a floating-point number at the decimal point
// returns int (if possible, otherwise float)
//
function trunc($floatnumber)
{
if ($floatnumber >= 1)
{
$truncatednumber = floor($floatnumber);
}
else if($floatnumber <= -1)
{
$truncatednumber = ceil($floatnumber);
}
else {
$truncatednumber = 0;
}
if($truncatednumber <= pow(2, 30))
{
$truncatednumber = (int) $truncatednumber;
}
return $truncatednumber;
}
function CastAsInt($floatnum)
{
// convert to float if not already
$floatnum = (float) $floatnum;
// convert a float to type int, only if possible
if($this->trunc($floatnum) == $floatnum)
{
// it's not floating point
if($floatnum <= pow(2, 30))
{
// it's within int range
$floatnum = (int) $floatnum;
}
}
return $floatnum;
}
function BigEndian2Int($byteword, $synchsafe=false, $signed=false)
{
$intvalue = 0;
$bytewordlen = strlen($byteword);
for($i=0; $i<$bytewordlen; $i++)
{
// disregard MSB, effectively 7-bit bytes
if($synchsafe)
{
$intvalue = $intvalue
| (ord($byteword{$i})&0x7F)
<< (($bytewordlen-1-$i)*7);
} else
{
$intvalue += ord($byteword{$i})
* pow(256,($bytewordlen-1-$i));
}
}
if($signed && !$synchsafe)
{
// synchsafe ints are not allowed to be signed
switch($bytewordlen)
{
case 1:
case 2:
case 3:
case 4:
$signmaskbit = 0x80 << (8*($bytewordlen-1));
if($intvalue & $signmaskbit)
{ $intvalue = 0-($intvalue&($signmaskbit-1)); }
break;
default:
//die('ERROR: Cannot have signed integers '.
// 'larger than 32-bits in BigEndian2Int()');
return;
break;
}
}
return $this->CastAsInt($intvalue);
}
function LittleEndian2Int($byteword, $signed=false)
{
return $this->BigEndian2Int(strrev($byteword), false, $signed);
}
function BigEndian2Bin($byteword)
{
$binvalue = '';
$bytewordlen = strlen($byteword);
for($i=0; $i<$bytewordlen; $i++)
{
$binvalue .= str_pad(
decbin(ord($byteword{$i})),8,'0',STR_PAD_LEFT
);
}
return $binvalue;
}
function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false)
{
if($number < 0) return false;
$maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF);
$intstring = '';
if($signed)
{
if($minbytes > 4)
{
//die('ERROR: Cannot have signed integers '.
// 'larger than 32-bits in BigEndian2String()');
return;
}
$number = $number & (0x80 << (8 * ($minbytes - 1)));
}
while($number != 0)
{
$quotient = ($number / ($maskbyte + 1));
$intstring = chr(ceil(
($quotient-floor($quotient))*$maskbyte
)).$intstring;
$number = floor($quotient);
}
return str_pad($intstring, $minbytes, chr(0), STR_PAD_LEFT);
}
function LittleEndian2String($number, $minbytes=1, $synchsafe=false)
{
$intstring = '';
while($number > 0)
{
if ($synchsafe) {
$intstring = $intstring.chr($number & 127);
$number >>= 7;
} else {
$intstring = $intstring.chr($number & 255);
$number >>= 8;
}
}
return str_pad($intstring, $minbytes, chr(0), STR_PAD_RIGHT);
}
} // end of class
?>