23                $info = &$this->getid3->info;
 
   25                $info[
'fileformat'] = 
'ogg';
 
   28                if (isset(
$info[
'id3v2'])) {
 
   29                        $this->
warning(
'Illegal ID3v2 tag present.');
 
   31                if (isset(
$info[
'id3v1'])) {
 
   32                        $this->
warning(
'Illegal ID3v1 tag present.');
 
   34                if (isset(
$info[
'ape'])) {
 
   35                        $this->
warning(
'Illegal APE tag present.');
 
   44                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
 
   46                if ($this->
ftell() >= $this->getid3->fread_buffer_size()) {
 
   47                        $this->
error(
'Could not find start of Ogg page in the first '.$this->getid3->fread_buffer_size().
' bytes (this might not be an Ogg-Vorbis file?)');
 
   48                        unset(
$info[
'fileformat']);
 
   53                $filedata = $this->
fread($oggpageinfo[
'page_length']);
 
   56                if (substr($filedata, 0, 4) == 
'fLaC') {
 
   58                        $info[
'audio'][
'dataformat']   = 
'flac';
 
   59                        $info[
'audio'][
'bitrate_mode'] = 
'vbr';
 
   60                        $info[
'audio'][
'lossless']     = 
true;
 
   62                } elseif (substr($filedata, 1, 6) == 
'vorbis') {
 
   66                } elseif (substr($filedata, 0, 8) == 
'OpusHead') {
 
   72                } elseif (substr($filedata, 0, 8) == 
'Speex   ') {
 
   76                        $info[
'audio'][
'dataformat']   = 
'speex';
 
   77                        $info[
'mime_type']             = 
'audio/speex';
 
   78                        $info[
'audio'][
'bitrate_mode'] = 
'abr';
 
   79                        $info[
'audio'][
'lossless']     = 
false;
 
   81                        $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_string']           =                              substr($filedata, $filedataoffset, 8); 
 
   83                        $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_version']          =                              substr($filedata, $filedataoffset, 20);
 
   84                        $filedataoffset += 20;
 
  100                        $filedataoffset += 4;
 
  102                        $filedataoffset += 4;
 
  104                        $filedataoffset += 4;
 
  106                        $filedataoffset += 4;
 
  108                        $filedataoffset += 4;
 
  110                        $filedataoffset += 4;
 
  112                        $info[
'speex'][
'speex_version'] = trim(
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'speex_version']);
 
  113                        $info[
'speex'][
'sample_rate']   = 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'rate'];
 
  114                        $info[
'speex'][
'channels']      = 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'nb_channels'];
 
  115                        $info[
'speex'][
'vbr']           = (bool) 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'vbr'];
 
  118                        $info[
'audio'][
'sample_rate']   = 
$info[
'speex'][
'sample_rate'];
 
  119                        $info[
'audio'][
'channels']      = 
$info[
'speex'][
'channels'];
 
  120                        if (
$info[
'speex'][
'vbr']) {
 
  121                                $info[
'audio'][
'bitrate_mode'] = 
'vbr';
 
  124                } elseif (substr($filedata, 0, 7) == 
"\x80".
'theora') {
 
  128                        $info[
'ogg'][
'pageheader'][
'theora'][
'theora_magic']             =                           substr($filedata, $filedataoffset,  7); 
 
  129                        $filedataoffset += 7;
 
  131                        $filedataoffset += 1;
 
  133                        $filedataoffset += 1;
 
  135                        $filedataoffset += 1;
 
  137                        $filedataoffset += 2;
 
  139                        $filedataoffset += 2;
 
  141                        $filedataoffset += 3;
 
  143                        $filedataoffset += 3;
 
  145                        $filedataoffset += 1;
 
  147                        $filedataoffset += 1;
 
  149                        $filedataoffset += 4;
 
  151                        $filedataoffset += 4;
 
  153                        $filedataoffset += 3;
 
  155                        $filedataoffset += 3;
 
  157                        $filedataoffset += 1;
 
  159                        $filedataoffset += 3;
 
  161                        $filedataoffset += 2;
 
  163                        $info[
'ogg'][
'pageheader'][
'theora'][
'quality']         = (
$info[
'ogg'][
'pageheader'][
'theora'][
'flags'] & 0xFC00) >> 10;
 
  164                        $info[
'ogg'][
'pageheader'][
'theora'][
'kfg_shift']       = (
$info[
'ogg'][
'pageheader'][
'theora'][
'flags'] & 0x03E0) >>  5;
 
  165                        $info[
'ogg'][
'pageheader'][
'theora'][
'pixel_format_id'] = (
$info[
'ogg'][
'pageheader'][
'theora'][
'flags'] & 0x0018) >>  3;
 
  166                        $info[
'ogg'][
'pageheader'][
'theora'][
'reserved']        = (
$info[
'ogg'][
'pageheader'][
'theora'][
'flags'] & 0x0007) >>  0; 
 
  170                        $info[
'video'][
'dataformat']   = 
'theora';
 
  171                        $info[
'mime_type']             = 
'video/ogg';
 
  174                        $info[
'video'][
'resolution_x'] = 
$info[
'ogg'][
'pageheader'][
'theora'][
'resolution_x'];
 
  175                        $info[
'video'][
'resolution_y'] = 
$info[
'ogg'][
'pageheader'][
'theora'][
'resolution_y'];
 
  176                        if (
$info[
'ogg'][
'pageheader'][
'theora'][
'frame_rate_denominator'] > 0) {
 
  177                                $info[
'video'][
'frame_rate'] = (float) 
$info[
'ogg'][
'pageheader'][
'theora'][
'frame_rate_numerator'] / 
$info[
'ogg'][
'pageheader'][
'theora'][
'frame_rate_denominator'];
 
  179                        if (
$info[
'ogg'][
'pageheader'][
'theora'][
'pixel_aspect_denominator'] > 0) {
 
  180                                $info[
'video'][
'pixel_aspect_ratio'] = (float) 
$info[
'ogg'][
'pageheader'][
'theora'][
'pixel_aspect_numerator'] / 
$info[
'ogg'][
'pageheader'][
'theora'][
'pixel_aspect_denominator'];
 
  182$this->
warning(
'Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().
'] -- bitrate, playtime and all audio data are currently unavailable');
 
  185                } elseif (substr($filedata, 0, 8) == 
"fishead\x00") {
 
  189                        $filedataoffset += 8;
 
  191                        $filedataoffset += 2;
 
  193                        $filedataoffset += 2;
 
  195                        $filedataoffset += 8;
 
  197                        $filedataoffset += 8;
 
  199                        $filedataoffset += 8;
 
  201                        $filedataoffset += 8;
 
  203                        $filedataoffset += 20;
 
  205                        $info[
'ogg'][
'skeleton'][
'fishead'][
'version']          = 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'version_major'].
'.'.
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'version_minor'];
 
  206                        $info[
'ogg'][
'skeleton'][
'fishead'][
'presentationtime'] = 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'presentationtime_numerator'] / 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'presentationtime_denominator'];
 
  207                        $info[
'ogg'][
'skeleton'][
'fishead'][
'basetime']         = 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'basetime_numerator']         / 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'basetime_denominator'];
 
  208                        $info[
'ogg'][
'skeleton'][
'fishead'][
'utc']              = 
$info[
'ogg'][
'skeleton'][
'fishead'][
'raw'][
'utc'];
 
  214                                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno'].
'.'.
$counter++] = $oggpageinfo;
 
  215                                $filedata = $this->
fread($oggpageinfo[
'page_length']);
 
  216                                $this->
fseek($oggpageinfo[
'page_end_offset']);
 
  218                                if (substr($filedata, 0, 8) == 
"fisbone\x00") {
 
  222                                        $filedataoffset += 4;
 
  224                                        $filedataoffset += 4;
 
  226                                        $filedataoffset += 4;
 
  228                                        $filedataoffset += 8;
 
  230                                        $filedataoffset += 8;
 
  232                                        $filedataoffset += 8;
 
  234                                        $filedataoffset += 4;
 
  236                                        $filedataoffset += 1;
 
  237                                        $info[
'ogg'][
'skeleton'][
'fisbone'][
'raw'][
'padding']                 =                              substr($filedata, $filedataoffset,  3);
 
  238                                        $filedataoffset += 3;
 
  240                                } elseif (substr($filedata, 1, 6) == 
'theora') {
 
  242                                        $info[
'video'][
'dataformat'] = 
'theora1';
 
  243                                        $this->
error(
'Ogg Theora (v1) not correctly handled in this version of getID3 ['.$this->getid3->version().
']');
 
  246                                } elseif (substr($filedata, 1, 6) == 
'vorbis') {
 
  251                                        $this->
error(
'unexpected');
 
  255                        } 
while (($oggpageinfo[
'page_seqno'] == 0) && (substr($filedata, 0, 8) != 
"fisbone\x00"));
 
  257                        $this->
fseek($oggpageinfo[
'page_start_offset']);
 
  259                        $this->
error(
'Ogg Skeleton not correctly handled in this version of getID3 ['.$this->getid3->version().
']');
 
  264                        $this->
error(
'Expecting either "Speex   ", "OpusHead" or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).
'"');
 
  266                        unset(
$info[
'mime_type']);
 
  273                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
 
  275                switch (
$info[
'audio'][
'dataformat']) {
 
  277                                $filedata = $this->
fread(
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_length']);
 
  279                                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'stream_type'] =                              substr($filedata, 1, 6); 
 
  286                                if (!$flac->parseMETAdata()) {
 
  287                                        $this->
error(
'Failed to parse FLAC headers');
 
  294                                $this->
fseek(
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_length'], SEEK_CUR);
 
  299                                $filedata = $this->
fread(
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_length']);
 
  300                                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'stream_type'] = substr($filedata, 0, 8); 
 
  301                                if(substr($filedata, 0, 8)  != 
'OpusTags') {
 
  302                                        $this->
error(
'Expected "OpusTags" as header but got "'.substr($filedata, 0, 8).
'"');
 
  314                        $this->
warning(
'Unable to parse Ogg end chunk file (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).
'GB)');
 
  318                        $this->
fseek(max(
$info[
'avdataend'] - $this->getid3->fread_buffer_size(), 0));
 
  319                        $LastChunkOfOgg = strrev($this->
fread($this->getid3->fread_buffer_size()));
 
  320                        if ($LastOggSpostion = strpos($LastChunkOfOgg, 
'SggO')) {
 
  321                                $this->
fseek(
$info[
'avdataend'] - ($LastOggSpostion + strlen(
'SggO')));
 
  324                                $info[
'ogg'][
'samples']   = 
$info[
'ogg'][
'pageheader'][
'eos'][
'pcm_abs_position'];
 
  325                                if (
$info[
'ogg'][
'samples'] == 0) {
 
  326                                        $this->
error(
'Corrupt Ogg file: eos.number of samples == zero');
 
  329                                if (!empty(
$info[
'audio'][
'sample_rate'])) {
 
  330                                        $info[
'ogg'][
'bitrate_average'] = ((
$info[
'avdataend'] - 
$info[
'avdataoffset']) * 8) / (
$info[
'ogg'][
'samples'] / 
$info[
'audio'][
'sample_rate']);
 
  336                if (!empty(
$info[
'ogg'][
'bitrate_average'])) {
 
  337                        $info[
'audio'][
'bitrate'] = 
$info[
'ogg'][
'bitrate_average'];
 
  338                } elseif (!empty(
$info[
'ogg'][
'bitrate_nominal'])) {
 
  339                        $info[
'audio'][
'bitrate'] = 
$info[
'ogg'][
'bitrate_nominal'];
 
  340                } elseif (!empty(
$info[
'ogg'][
'bitrate_min']) && !empty(
$info[
'ogg'][
'bitrate_max'])) {
 
  341                        $info[
'audio'][
'bitrate'] = (
$info[
'ogg'][
'bitrate_min'] + 
$info[
'ogg'][
'bitrate_max']) / 2;
 
  343                if (isset(
$info[
'audio'][
'bitrate']) && !isset(
$info[
'playtime_seconds'])) {
 
  344                        if (
$info[
'audio'][
'bitrate'] == 0) {
 
  345                                $this->
error(
'Corrupt Ogg file: bitrate_audio == zero');
 
  348                        $info[
'playtime_seconds'] = (float) (((
$info[
'avdataend'] - 
$info[
'avdataoffset']) * 8) / 
$info[
'audio'][
'bitrate']);
 
  351                if (isset(
$info[
'ogg'][
'vendor'])) {
 
  352                        $info[
'audio'][
'encoder'] = preg_replace(
'/^Encoded with /', 
'', 
$info[
'ogg'][
'vendor']);
 
  355                        if (
$info[
'audio'][
'dataformat'] == 
'vorbis') {
 
  358                                if  (preg_match(
'/^Xiph.Org/', 
$info[
'audio'][
'encoder'])) {
 
  360                                        if (
$info[
'audio'][
'bitrate_mode'] == 
'abr') {
 
  363                                                $info[
'audio'][
'encoder_options'] = 
'-b '.round(
$info[
'ogg'][
'bitrate_nominal'] / 1000);
 
  365                                        } elseif ((
$info[
'audio'][
'bitrate_mode'] == 
'vbr') && (
$info[
'audio'][
'channels'] == 2) && (
$info[
'audio'][
'sample_rate'] >= 44100) && (
$info[
'audio'][
'sample_rate'] <= 48000)) {
 
  367                                                $info[
'audio'][
'encoder_options'] = 
'-q '.$this->get_quality_from_nominal_bitrate(
$info[
'ogg'][
'bitrate_nominal']);
 
  372                                if (empty(
$info[
'audio'][
'encoder_options']) && !empty(
$info[
'ogg'][
'bitrate_nominal'])) {
 
  373                                        $info[
'audio'][
'encoder_options'] = 
'Nominal bitrate: '.intval(round(
$info[
'ogg'][
'bitrate_nominal'] / 1000)).
'kbps';
 
  382                $info = &$this->getid3->info;
 
  383                $info[
'audio'][
'dataformat'] = 
'vorbis';
 
  384                $info[
'audio'][
'lossless']   = 
false;
 
  387                $filedataoffset += 1;
 
  388                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'stream_type'] = substr($filedata, $filedataoffset, 6); 
 
  389                $filedataoffset += 6;
 
  391                $filedataoffset += 4;
 
  393                $filedataoffset += 1;
 
  394                $info[
'audio'][
'channels']       = 
$info[
'ogg'][
'numberofchannels'];
 
  396                $filedataoffset += 4;
 
  397                if (
$info[
'ogg'][
'samplerate'] == 0) {
 
  398                        $this->
error(
'Corrupt Ogg file: sample rate == zero');
 
  401                $info[
'audio'][
'sample_rate']    = 
$info[
'ogg'][
'samplerate'];
 
  402                $info[
'ogg'][
'samples']          = 0; 
 
  403                $info[
'ogg'][
'bitrate_average']  = 0; 
 
  405                $filedataoffset += 4;
 
  407                $filedataoffset += 4;
 
  409                $filedataoffset += 4;
 
  414                $info[
'audio'][
'bitrate_mode'] = 
'vbr'; 
 
  415                if (
$info[
'ogg'][
'bitrate_max'] == 0xFFFFFFFF) {
 
  416                        unset(
$info[
'ogg'][
'bitrate_max']);
 
  417                        $info[
'audio'][
'bitrate_mode'] = 
'abr';
 
  419                if (
$info[
'ogg'][
'bitrate_nominal'] == 0xFFFFFFFF) {
 
  420                        unset(
$info[
'ogg'][
'bitrate_nominal']);
 
  422                if (
$info[
'ogg'][
'bitrate_min'] == 0xFFFFFFFF) {
 
  423                        unset(
$info[
'ogg'][
'bitrate_min']);
 
  424                        $info[
'audio'][
'bitrate_mode'] = 
'abr';
 
  431                $info = &$this->getid3->info;
 
  432                $info[
'audio'][
'dataformat']   = 
'opus';
 
  433                $info[
'mime_type']             = 
'audio/ogg; codecs=opus';
 
  436                $info[
'audio'][
'bitrate_mode'] = 
'vbr';
 
  438                $info[
'audio'][
'lossless']     = 
false;
 
  440                $info[
'ogg'][
'pageheader'][
'opus'][
'opus_magic'] = substr($filedata, $filedataoffset, 8); 
 
  441                $filedataoffset += 8;
 
  443                $filedataoffset += 1;
 
  445                if (
$info[
'ogg'][
'pageheader'][
'opus'][
'version'] < 1 || 
$info[
'ogg'][
'pageheader'][
'opus'][
'version'] > 15) {
 
  446                        $this->
error(
'Unknown opus version number (only accepting 1-15)');
 
  451                $filedataoffset += 1;
 
  453                if (
$info[
'ogg'][
'pageheader'][
'opus'][
'out_channel_count'] == 0) {
 
  454                        $this->
error(
'Invalid channel count in opus header (must not be zero)');
 
  459                $filedataoffset += 2;
 
  462                $filedataoffset += 4;
 
  470                $info[
'opus'][
'opus_version']      = 
$info[
'ogg'][
'pageheader'][
'opus'][
'version'];
 
  471                $info[
'opus'][
'sample_rate']       = 
$info[
'ogg'][
'pageheader'][
'opus'][
'sample_rate'];
 
  472                $info[
'opus'][
'out_channel_count'] = 
$info[
'ogg'][
'pageheader'][
'opus'][
'out_channel_count'];
 
  474                $info[
'audio'][
'channels']      = 
$info[
'opus'][
'out_channel_count'];
 
  475                $info[
'audio'][
'sample_rate']   = 
$info[
'opus'][
'sample_rate'];
 
  482                $oggheader[
'page_start_offset'] = $this->
ftell(); 
 
  484                $filedata = $this->
fread($this->getid3->fread_buffer_size());
 
  486                while ((substr($filedata, $filedataoffset++, 4) != 
'OggS')) {
 
  487                        if (($this->
ftell() - $oggheader[
'page_start_offset']) >= $this->getid3->fread_buffer_size()) {
 
  491                        if ((($filedataoffset + 28) > strlen($filedata)) || (strlen($filedata) < 28)) {
 
  492                                if ($this->
feof() || (($filedata .= $this->
fread($this->getid3->fread_buffer_size())) === 
false)) {
 
  498                $filedataoffset += strlen(
'OggS') - 1; 
 
  501                $filedataoffset += 1;
 
  503                $filedataoffset += 1;
 
  504                $oggheader[
'flags'][
'fresh']    = (bool) ($oggheader[
'flags_raw'] & 0x01); 
 
  505                $oggheader[
'flags'][
'bos']      = (bool) ($oggheader[
'flags_raw'] & 0x02); 
 
  506                $oggheader[
'flags'][
'eos']      = (bool) ($oggheader[
'flags_raw'] & 0x04); 
 
  509                $filedataoffset += 8;
 
  511                $filedataoffset += 4;
 
  513                $filedataoffset += 4;
 
  515                $filedataoffset += 4;
 
  517                $filedataoffset += 1;
 
  518                $oggheader[
'page_length'] = 0;
 
  519                for (
$i = 0; 
$i < $oggheader[
'page_segments']; 
$i++) {
 
  521                        $filedataoffset += 1;
 
  522                        $oggheader[
'page_length'] += $oggheader[
'segment_table'][
$i];
 
  524                $oggheader[
'header_end_offset'] = $oggheader[
'page_start_offset'] + $filedataoffset;
 
  525                $oggheader[
'page_end_offset']   = $oggheader[
'header_end_offset'] + $oggheader[
'page_length'];
 
  526                $this->
fseek($oggheader[
'header_end_offset']);
 
  533                $info = &$this->getid3->info;
 
  535                $OriginalOffset = $this->
ftell();
 
  536                $commentdataoffset = 0;
 
  537                $VorbisCommentPage = 1;
 
  539                switch (
$info[
'audio'][
'dataformat']) {
 
  543                                $CommentStartOffset = 
$info[
'ogg'][
'pageheader'][$VorbisCommentPage][
'page_start_offset'];  
 
  544                                $this->
fseek($CommentStartOffset);
 
  545                                $commentdataoffset = 27 + 
$info[
'ogg'][
'pageheader'][$VorbisCommentPage][
'page_segments'];
 
  546                                $commentdata = $this->
fread(self::OggPageSegmentLength(
$info[
'ogg'][
'pageheader'][$VorbisCommentPage], 1) + $commentdataoffset);
 
  548                                if (
$info[
'audio'][
'dataformat'] == 
'vorbis') {
 
  549                                        $commentdataoffset += (strlen(
'vorbis') + 1);
 
  551                                else if (
$info[
'audio'][
'dataformat'] == 
'opus') {
 
  552                                        $commentdataoffset += strlen(
'OpusTags');
 
  558                                $CommentStartOffset = 
$info[
'flac'][
'VORBIS_COMMENT'][
'raw'][
'offset'] + 4;
 
  559                                $this->
fseek($CommentStartOffset);
 
  560                                $commentdata = $this->
fread(
$info[
'flac'][
'VORBIS_COMMENT'][
'raw'][
'block_length']);
 
  569                $commentdataoffset += 4;
 
  571                $info[
'ogg'][
'vendor'] = substr($commentdata, $commentdataoffset, $VendorSize);
 
  572                $commentdataoffset += $VendorSize;
 
  575                $commentdataoffset += 4;
 
  576                $info[
'avdataoffset'] = $CommentStartOffset + $commentdataoffset;
 
  578                $basicfields = array(
'TITLE', 
'ARTIST', 
'ALBUM', 
'TRACKNUMBER', 
'GENRE', 
'DATE', 
'DESCRIPTION', 
'COMMENT');
 
  579                $ThisFileInfo_ogg_comments_raw = &
$info[
'ogg'][
'comments_raw'];
 
  580                for (
$i = 0; 
$i < $CommentsCount; 
$i++) {
 
  584                                $this->
warning(
'Unexpectedly large number ('.$CommentsCount.
') of Ogg comments - breaking after reading '.
$i.
' comments');
 
  588                        $ThisFileInfo_ogg_comments_raw[
$i][
'dataoffset'] = $CommentStartOffset + $commentdataoffset;
 
  590                        if ($this->
ftell() < ($ThisFileInfo_ogg_comments_raw[
$i][
'dataoffset'] + 4)) {
 
  592                                        $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
 
  594                                        $VorbisCommentPage++;
 
  597                                        $AsYetUnusedData = substr($commentdata, $commentdataoffset);
 
  600                                        $commentdata     = substr($commentdata, 0, $commentdataoffset);
 
  603                                        $commentdata .= str_repeat(
"\x00", 27 + 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
 
  604                                        $commentdataoffset += (27 + 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
 
  607                                        $commentdata .= $AsYetUnusedData;
 
  617                        $info[
'avdataoffset'] = $ThisFileInfo_ogg_comments_raw[
$i][
'dataoffset'] + $ThisFileInfo_ogg_comments_raw[
$i][
'size'] + 4;
 
  619                        $commentdataoffset += 4;
 
  620                        while ((strlen($commentdata) - $commentdataoffset) < $ThisFileInfo_ogg_comments_raw[
$i][
'size']) {
 
  621                                if (($ThisFileInfo_ogg_comments_raw[
$i][
'size'] > 
$info[
'avdataend']) || ($ThisFileInfo_ogg_comments_raw[
$i][
'size'] < 0)) {
 
  622                                        $this->
warning(
'Invalid Ogg comment size (comment #'.$i.
', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[
$i][
'size']).
' bytes) - aborting reading comments');
 
  626                                $VorbisCommentPage++;
 
  629                                $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
 
  632                                $AsYetUnusedData = substr($commentdata, $commentdataoffset);
 
  635                                $commentdata     = substr($commentdata, 0, $commentdataoffset);
 
  638                                $commentdata .= str_repeat(
"\x00", 27 + 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
 
  639                                $commentdataoffset += (27 + 
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
 
  642                                $commentdata .= $AsYetUnusedData;
 
  645                                if (!isset(
$info[
'ogg'][
'pageheader'][$VorbisCommentPage])) {
 
  646                                        $this->
warning(
'undefined Vorbis Comment page "'.$VorbisCommentPage.
'" at offset '.$this->ftell());
 
  650                                if ($readlength <= 0) {
 
  651                                        $this->
warning(
'invalid length Vorbis Comment page "'.$VorbisCommentPage.
'" at offset '.$this->ftell());
 
  654                                $commentdata .= $this->
fread($readlength);
 
  658                        $ThisFileInfo_ogg_comments_raw[
$i][
'offset'] = $commentdataoffset;
 
  659                        $commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[
$i][
'size']);
 
  660                        $commentdataoffset += $ThisFileInfo_ogg_comments_raw[
$i][
'size'];
 
  662                        if (!$commentstring) {
 
  665                                $this->
warning(
'Blank Ogg comment ['.$i.
']');
 
  667                        } elseif (strstr($commentstring, 
'=')) {
 
  669                                $commentexploded = explode(
'=', $commentstring, 2);
 
  670                                $ThisFileInfo_ogg_comments_raw[
$i][
'key']   = strtoupper($commentexploded[0]);
 
  671                                $ThisFileInfo_ogg_comments_raw[
$i][
'value'] = (isset($commentexploded[1]) ? $commentexploded[1] : 
'');
 
  673                                if ($ThisFileInfo_ogg_comments_raw[
$i][
'key'] == 
'METADATA_BLOCK_PICTURE') {
 
  679                                        $flac->setStringMode(base64_decode($ThisFileInfo_ogg_comments_raw[
$i][
'value']));
 
  680                                        $flac->parsePICTURE();
 
  681                                        $info[
'ogg'][
'comments'][
'picture'][] = $flac->getid3->info[
'flac'][
'PICTURE'][0];
 
  684                                } elseif ($ThisFileInfo_ogg_comments_raw[
$i][
'key'] == 
'COVERART') {
 
  686                                        $data = base64_decode($ThisFileInfo_ogg_comments_raw[
$i][
'value']);
 
  687                                        $this->
notice(
'Found deprecated COVERART tag, it should be replaced in honor of METADATA_BLOCK_PICTURE structure');
 
  690                                        if ($imageinfo === 
false || !isset($imageinfo[
'mime'])) {
 
  691                                                $this->
warning(
'COVERART vorbiscomment tag contains invalid image');
 
  696                                        $ogg->setStringMode(
$data);
 
  697                                        $info[
'ogg'][
'comments'][
'picture'][] = array(
 
  698                                                'image_mime'   => $imageinfo[
'mime'],
 
  699                                                'datalength'   => strlen(
$data),
 
  700                                                'picturetype'  => 
'cover art',
 
  701                                                'image_height' => $imageinfo[
'height'],
 
  702                                                'image_width'  => $imageinfo[
'width'],
 
  703                                                'data'         => $ogg->saveAttachment(
'coverart', 0, strlen(
$data), $imageinfo[
'mime']),
 
  709                                        $info[
'ogg'][
'comments'][strtolower($ThisFileInfo_ogg_comments_raw[
$i][
'key'])][] = $ThisFileInfo_ogg_comments_raw[
$i][
'value'];
 
  715                                $this->
warning(
'[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.
']: '.$commentstring);
 
  718                        unset($ThisFileInfo_ogg_comments_raw[
$i]);
 
  720                unset($ThisFileInfo_ogg_comments_raw);
 
  725                if (isset(
$info[
'ogg'][
'comments']) && is_array(
$info[
'ogg'][
'comments'])) {
 
  726                        foreach (
$info[
'ogg'][
'comments'] as 
$index => $commentvalue) {
 
  728                                        case 'rg_audiophile':
 
  729                                        case 'replaygain_album_gain':
 
  730                                                $info[
'replay_gain'][
'album'][
'adjustment'] = (double) $commentvalue[0];
 
  735                                        case 'replaygain_track_gain':
 
  736                                                $info[
'replay_gain'][
'track'][
'adjustment'] = (double) $commentvalue[0];
 
  740                                        case 'replaygain_album_peak':
 
  741                                                $info[
'replay_gain'][
'album'][
'peak'] = (double) $commentvalue[0];
 
  746                                        case 'replaygain_track_peak':
 
  747                                                $info[
'replay_gain'][
'track'][
'peak'] = (double) $commentvalue[0];
 
  751                                        case 'replaygain_reference_loudness':
 
  752                                                $info[
'replay_gain'][
'reference_volume'] = (double) $commentvalue[0];
 
  763                $this->
fseek($OriginalOffset);
 
  769                static $SpeexBandModeLookup = array();
 
  770                if (empty($SpeexBandModeLookup)) {
 
  771                        $SpeexBandModeLookup[0] = 
'narrow';
 
  772                        $SpeexBandModeLookup[1] = 
'wide';
 
  773                        $SpeexBandModeLookup[2] = 
'ultra-wide';
 
  775                return (isset($SpeexBandModeLookup[$mode]) ? $SpeexBandModeLookup[$mode] : 
null);
 
  780                for (
$i = 0; 
$i < $SegmentNumber; 
$i++) {
 
  782                        foreach ($OggInfoArray[
'segment_table'] as 
$key => $value) {
 
  783                                $segmentlength += $value;
 
  789                return $segmentlength;
 
  796                $nominal_bitrate = $nominal_bitrate / 1000;
 
  798                if ($nominal_bitrate < 128) {
 
  800                        $qval = ($nominal_bitrate - 64) / 16;
 
  801                } elseif ($nominal_bitrate < 256) {
 
  803                        $qval = $nominal_bitrate / 32;
 
  804                } elseif ($nominal_bitrate < 320) {
 
  806                        $qval = ($nominal_bitrate + 256) / 64;
 
  809                        $qval = ($nominal_bitrate + 1300) / 180;
 
  813                return round($qval, 1); 
 
  818                static $TheoraColorSpaceLookup = array();
 
  819                if (empty($TheoraColorSpaceLookup)) {
 
  820                        $TheoraColorSpaceLookup[0] = 
'Undefined';
 
  821                        $TheoraColorSpaceLookup[1] = 
'Rec. 470M';
 
  822                        $TheoraColorSpaceLookup[2] = 
'Rec. 470BG';
 
  823                        $TheoraColorSpaceLookup[3] = 
'Reserved';
 
  825                return (isset($TheoraColorSpaceLookup[$colorspace_id]) ? $TheoraColorSpaceLookup[$colorspace_id] : 
null);
 
  830                static $TheoraPixelFormatLookup = array();
 
  831                if (empty($TheoraPixelFormatLookup)) {
 
  832                        $TheoraPixelFormatLookup[0] = 
'4:2:0';
 
  833                        $TheoraPixelFormatLookup[1] = 
'Reserved';
 
  834                        $TheoraPixelFormatLookup[2] = 
'4:2:2';
 
  835                        $TheoraPixelFormatLookup[3] = 
'4:4:4';
 
  837                return (isset($TheoraPixelFormatLookup[$pixelformat_id]) ? $TheoraPixelFormatLookup[$pixelformat_id] : 
null);
 
An exception for terminatinating execution or to throw for unit testing.
@tutorial http://flac.sourceforge.net/format.html
fseek($bytes, $whence=SEEK_SET)
static LittleEndian2Int($byteword, $signed=false)
static intValueSupported($num)
static GetDataImageSize($imgData, &$imageinfo=array())
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
static TheoraPixelFormat($pixelformat_id)
ParseOpusPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo)
static get_quality_from_nominal_bitrate($nominal_bitrate)
static SpeexBandModeLookup($mode)
ParseVorbisPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo)
static OggPageSegmentLength($OggInfoArray, $SegmentNumber=1)
static TheoraColorSpace($colorspace_id)