static function ParseVorbisCommentsFilepointer(&$fd, &$ThisFileInfo)
 {
     $OriginalOffset = ftell($fd);
     $CommentStartOffset = $OriginalOffset;
     $commentdataoffset = 0;
     $VorbisCommentPage = 1;
     switch ($ThisFileInfo['audio']['dataformat']) {
         case 'vorbis':
             $CommentStartOffset = $ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset'];
             // Second Ogg page, after header block
             fseek($fd, $CommentStartOffset, SEEK_SET);
             $commentdataoffset = 27 + $ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage]['page_segments'];
             $commentdata = fread($fd, getid3_ogg::OggPageSegmentLength($ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage], 1) + $commentdataoffset);
             $commentdataoffset += strlen('vorbis') + 1;
             break;
         case 'flac':
             fseek($fd, $ThisFileInfo['flac']['VORBIS_COMMENT']['raw']['offset'] + 4, SEEK_SET);
             $commentdata = fread($fd, $ThisFileInfo['flac']['VORBIS_COMMENT']['raw']['block_length']);
             break;
         case 'speex':
             $CommentStartOffset = $ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset'];
             // Second Ogg page, after header block
             fseek($fd, $CommentStartOffset, SEEK_SET);
             $commentdataoffset = 27 + $ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage]['page_segments'];
             $commentdata = fread($fd, getid3_ogg::OggPageSegmentLength($ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage], 1) + $commentdataoffset);
             break;
         default:
             return false;
             break;
     }
     $VendorSize = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
     $commentdataoffset += 4;
     $ThisFileInfo['ogg']['vendor'] = substr($commentdata, $commentdataoffset, $VendorSize);
     $commentdataoffset += $VendorSize;
     $CommentsCount = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
     $commentdataoffset += 4;
     $ThisFileInfo['avdataoffset'] = $CommentStartOffset + $commentdataoffset;
     $basicfields = array('TITLE', 'ARTIST', 'ALBUM', 'TRACKNUMBER', 'GENRE', 'DATE', 'DESCRIPTION', 'COMMENT');
     $ThisFileInfo_ogg_comments_raw =& $ThisFileInfo['ogg']['comments_raw'];
     for ($i = 0; $i < $CommentsCount; $i++) {
         $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset;
         if (ftell($fd) < $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + 4) {
             $VorbisCommentPage++;
             $oggpageinfo = getid3_ogg::ParseOggPageHeader($fd);
             $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
             // First, save what we haven't read yet
             $AsYetUnusedData = substr($commentdata, $commentdataoffset);
             // Then take that data off the end
             $commentdata = substr($commentdata, 0, $commentdataoffset);
             // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
             $commentdata .= str_repeat("", 27 + $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
             $commentdataoffset += 27 + $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments'];
             // Finally, stick the unused data back on the end
             $commentdata .= $AsYetUnusedData;
             //$commentdata .= fread($fd, $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
             $commentdata .= fread($fd, getid3_ogg::OggPageSegmentLength($ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage], 1));
         }
         $ThisFileInfo_ogg_comments_raw[$i]['size'] = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
         // replace avdataoffset with position just after the last vorbiscomment
         $ThisFileInfo['avdataoffset'] = $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + $ThisFileInfo_ogg_comments_raw[$i]['size'] + 4;
         $commentdataoffset += 4;
         while (strlen($commentdata) - $commentdataoffset < $ThisFileInfo_ogg_comments_raw[$i]['size']) {
             if ($ThisFileInfo_ogg_comments_raw[$i]['size'] > $ThisFileInfo['avdataend'] || $ThisFileInfo_ogg_comments_raw[$i]['size'] < 0) {
                 $ThisFileInfo['warning'][] = 'Invalid Ogg comment size (comment #' . $i . ', claims to be ' . number_format($ThisFileInfo_ogg_comments_raw[$i]['size']) . ' bytes) - aborting reading comments';
                 break 2;
             }
             $VorbisCommentPage++;
             $oggpageinfo = getid3_ogg::ParseOggPageHeader($fd);
             $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
             // First, save what we haven't read yet
             $AsYetUnusedData = substr($commentdata, $commentdataoffset);
             // Then take that data off the end
             $commentdata = substr($commentdata, 0, $commentdataoffset);
             // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
             $commentdata .= str_repeat("", 27 + $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
             $commentdataoffset += 27 + $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments'];
             // Finally, stick the unused data back on the end
             $commentdata .= $AsYetUnusedData;
             //$commentdata .= fread($fd, $ThisFileInfo['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
             if (!isset($ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage])) {
                 $ThisFileInfo['warning'][] = 'undefined Vorbis Comment page "' . $VorbisCommentPage . '" at offset ' . ftell($fd);
                 break;
             }
             $readlength = getid3_ogg::OggPageSegmentLength($ThisFileInfo['ogg']['pageheader'][$VorbisCommentPage], 1);
             if ($readlength <= 0) {
                 $ThisFileInfo['warning'][] = 'invalid length Vorbis Comment page "' . $VorbisCommentPage . '" at offset ' . ftell($fd);
                 break;
             }
             $commentdata .= fread($fd, $readlength);
             //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
         }
         $commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[$i]['size']);
         $commentdataoffset += $ThisFileInfo_ogg_comments_raw[$i]['size'];
         if (!$commentstring) {
             // no comment?
             $ThisFileInfo['warning'][] = 'Blank Ogg comment [' . $i . ']';
         } elseif (strstr($commentstring, '=')) {
             $commentexploded = explode('=', $commentstring, 2);
             $ThisFileInfo_ogg_comments_raw[$i]['key'] = strtoupper($commentexploded[0]);
             $ThisFileInfo_ogg_comments_raw[$i]['value'] = isset($commentexploded[1]) ? $commentexploded[1] : '';
             $ThisFileInfo_ogg_comments_raw[$i]['data'] = base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value']);
             if (preg_match('#^(BM|GIF|\\xFF\\xD8\\xFF|\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A|II\\x2A\\x00|MM\\x00\\x2A)#s', $ThisFileInfo_ogg_comments_raw[$i]['data'])) {
                 $imageinfo = array();
                 $imagechunkcheck = getid3_lib::GetDataImageSize($ThisFileInfo_ogg_comments_raw[$i]['data'], $imageinfo);
                 unset($imageinfo);
                 if (!empty($imagechunkcheck)) {
                     $ThisFileInfo_ogg_comments_raw[$i]['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
                     if ($ThisFileInfo_ogg_comments_raw[$i]['image_mime'] && $ThisFileInfo_ogg_comments_raw[$i]['image_mime'] != 'application/octet-stream') {
                         unset($ThisFileInfo_ogg_comments_raw[$i]['value']);
                     }
                 }
             }
             if (isset($ThisFileInfo_ogg_comments_raw[$i]['value'])) {
                 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
                 $ThisFileInfo['ogg']['comments'][strtolower($ThisFileInfo_ogg_comments_raw[$i]['key'])][] = $ThisFileInfo_ogg_comments_raw[$i]['value'];
             } else {
                 $ThisFileInfo['ogg']['comments']['picture'][] = array('data' => $ThisFileInfo_ogg_comments_raw[$i]['data'], 'image_mime' => $ThisFileInfo_ogg_comments_raw[$i]['image_mime']);
             }
         } else {
             $ThisFileInfo['warning'][] = '[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair [' . $i . ']: ' . $commentstring;
         }
     }
     // Replay Gain Adjustment
     // http://privatewww.essex.ac.uk/~djmrob/replaygain/
     if (isset($ThisFileInfo['ogg']['comments']) && is_array($ThisFileInfo['ogg']['comments'])) {
         foreach ($ThisFileInfo['ogg']['comments'] as $index => $commentvalue) {
             switch ($index) {
                 case 'rg_audiophile':
                 case 'replaygain_album_gain':
                     $ThisFileInfo['replay_gain']['album']['adjustment'] = (double) $commentvalue[0];
                     unset($ThisFileInfo['ogg']['comments'][$index]);
                     break;
                 case 'rg_radio':
                 case 'replaygain_track_gain':
                     $ThisFileInfo['replay_gain']['track']['adjustment'] = (double) $commentvalue[0];
                     unset($ThisFileInfo['ogg']['comments'][$index]);
                     break;
                 case 'replaygain_album_peak':
                     $ThisFileInfo['replay_gain']['album']['peak'] = (double) $commentvalue[0];
                     unset($ThisFileInfo['ogg']['comments'][$index]);
                     break;
                 case 'rg_peak':
                 case 'replaygain_track_peak':
                     $ThisFileInfo['replay_gain']['track']['peak'] = (double) $commentvalue[0];
                     unset($ThisFileInfo['ogg']['comments'][$index]);
                     break;
                 default:
                     // do nothing
                     break;
             }
         }
     }
     fseek($fd, $OriginalOffset, SEEK_SET);
     return true;
 }