440 {
441 $info = &$this->getid3->info;
442
443 $OriginalOffset = $this->
ftell();
444 $commentdataoffset = 0;
445 $VorbisCommentPage = 1;
446
447 switch (
$info[
'audio'][
'dataformat']) {
448 case 'vorbis':
449 case 'speex':
450 $CommentStartOffset =
$info[
'ogg'][
'pageheader'][$VorbisCommentPage][
'page_start_offset'];
451 $this->
fseek($CommentStartOffset);
452 $commentdataoffset = 27 +
$info[
'ogg'][
'pageheader'][$VorbisCommentPage][
'page_segments'];
453 $commentdata = $this->
fread(self::OggPageSegmentLength(
$info[
'ogg'][
'pageheader'][$VorbisCommentPage], 1) + $commentdataoffset);
454
455 if (
$info[
'audio'][
'dataformat'] ==
'vorbis') {
456 $commentdataoffset += (strlen('vorbis') + 1);
457 }
458 break;
459
460 case 'flac':
461 $CommentStartOffset =
$info[
'flac'][
'VORBIS_COMMENT'][
'raw'][
'offset'] + 4;
462 $this->
fseek($CommentStartOffset);
463 $commentdata = $this->
fread(
$info[
'flac'][
'VORBIS_COMMENT'][
'raw'][
'block_length']);
464 break;
465
466 default:
467 return false;
468 }
469
471 $commentdataoffset += 4;
472
473 $info[
'ogg'][
'vendor'] = substr($commentdata, $commentdataoffset, $VendorSize);
474 $commentdataoffset += $VendorSize;
475
477 $commentdataoffset += 4;
478 $info[
'avdataoffset'] = $CommentStartOffset + $commentdataoffset;
479
480 $basicfields = array('TITLE', 'ARTIST', 'ALBUM', 'TRACKNUMBER', 'GENRE', 'DATE', 'DESCRIPTION', 'COMMENT');
481 $ThisFileInfo_ogg_comments_raw = &
$info[
'ogg'][
'comments_raw'];
482 for ($i = 0; $i < $CommentsCount; $i++) {
483
484 $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset;
485
486 if ($this->
ftell() < ($ThisFileInfo_ogg_comments_raw[$i][
'dataoffset'] + 4)) {
488 $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
489
490 $VorbisCommentPage++;
491
492
493 $AsYetUnusedData = substr($commentdata, $commentdataoffset);
494
495
496 $commentdata = substr($commentdata, 0, $commentdataoffset);
497
498
499 $commentdata .= str_repeat(
"\x00", 27 +
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
500 $commentdataoffset += (27 +
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
501
502
503 $commentdata .= $AsYetUnusedData;
504
505
507 }
508
509 }
511
512
513 $info[
'avdataoffset'] = $ThisFileInfo_ogg_comments_raw[$i][
'dataoffset'] + $ThisFileInfo_ogg_comments_raw[$i][
'size'] + 4;
514
515 $commentdataoffset += 4;
516 while ((strlen($commentdata) - $commentdataoffset) < $ThisFileInfo_ogg_comments_raw[$i]['size']) {
517 if (($ThisFileInfo_ogg_comments_raw[$i][
'size'] >
$info[
'avdataend']) || ($ThisFileInfo_ogg_comments_raw[$i][
'size'] < 0)) {
518 $info[
'warning'][] =
'Invalid Ogg comment size (comment #'.$i.
', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[$i][
'size']).
' bytes) - aborting reading comments';
519 break 2;
520 }
521
522 $VorbisCommentPage++;
523
525 $info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']] = $oggpageinfo;
526
527
528 $AsYetUnusedData = substr($commentdata, $commentdataoffset);
529
530
531 $commentdata = substr($commentdata, 0, $commentdataoffset);
532
533
534 $commentdata .= str_repeat(
"\x00", 27 +
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
535 $commentdataoffset += (27 +
$info[
'ogg'][
'pageheader'][$oggpageinfo[
'page_seqno']][
'page_segments']);
536
537
538 $commentdata .= $AsYetUnusedData;
539
540
541 if (!isset(
$info[
'ogg'][
'pageheader'][$VorbisCommentPage])) {
542 $info[
'warning'][] =
'undefined Vorbis Comment page "'.$VorbisCommentPage.
'" at offset '.$this->
ftell();
543 break;
544 }
546 if ($readlength <= 0) {
547 $info[
'warning'][] =
'invalid length Vorbis Comment page "'.$VorbisCommentPage.
'" at offset '.$this->
ftell();
548 break;
549 }
550 $commentdata .= $this->
fread($readlength);
551
552
553 }
554 $ThisFileInfo_ogg_comments_raw[$i]['offset'] = $commentdataoffset;
555 $commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[$i]['size']);
556 $commentdataoffset += $ThisFileInfo_ogg_comments_raw[$i]['size'];
557
558 if (!$commentstring) {
559
560
561 $info[
'warning'][] =
'Blank Ogg comment ['.$i.
']';
562
563 } elseif (strstr($commentstring, '=')) {
564
565 $commentexploded = explode('=', $commentstring, 2);
566 $ThisFileInfo_ogg_comments_raw[$i]['key'] = strtoupper($commentexploded[0]);
567 $ThisFileInfo_ogg_comments_raw[$i]['value'] = (isset($commentexploded[1]) ? $commentexploded[1] : '');
568 $ThisFileInfo_ogg_comments_raw[$i]['data'] = base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value']);
569 $ThisFileInfo_ogg_comments_raw[$i]['data_length'] = strlen($ThisFileInfo_ogg_comments_raw[$i]['data']);
570
571 if ($ThisFileInfo_ogg_comments_raw[$i]['key'] == 'METADATA_BLOCK_PICTURE') {
572
573
574
575 $getid3_temp = new GetId3Core();
576 $getid3_flac = new Flac($getid3_temp);
577 $getid3_flac->data_string = $ThisFileInfo_ogg_comments_raw[$i]['data'];
578 $getid3_flac->data_string_flag = true;
579 if ($getid3_flac->parsePICTURE()) {
580 if (!empty($getid3_temp->info['flac']['PICTURE'])) {
581 foreach ($getid3_temp->info['flac']['PICTURE'] as $key => $value) {
582 $ThisFileInfo_ogg_comments_raw[$i]['data'] = $value['data'];
583 $ThisFileInfo_ogg_comments_raw[$i]['data_length'] = strlen($value['data']);
584 $ThisFileInfo_ogg_comments_raw[$i]['image_mime'] = $value['image_mime'];
585 $ThisFileInfo_ogg_comments_raw[$i]['width'] = $value['width'];
586 $ThisFileInfo_ogg_comments_raw[$i]['height'] = $value['height'];
587 $ThisFileInfo_ogg_comments_raw[$i]['type'] = $value['type'];
588 $ThisFileInfo_ogg_comments_raw[$i]['typeid'] = $value['typeid'];
589 $ThisFileInfo_ogg_comments_raw[$i]['color_depth'] = $value['color_depth'];
590 $ThisFileInfo_ogg_comments_raw[$i]['colors_indexed'] = $value['colors_indexed'];
591 }
592 }
593 } else {
594 $info[
'warning'][] =
'Failed to GetId3_flac.parsePICTURE()';
595 }
596 unset($getid3_flac, $getid3_temp);
597 }
598
599 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'])) {
600 $imageinfo = array();
602 unset($imageinfo);
603 if (!empty($imagechunkcheck)) {
604 $ThisFileInfo_ogg_comments_raw[$i]['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
605 if ($ThisFileInfo_ogg_comments_raw[$i]['image_mime'] && ($ThisFileInfo_ogg_comments_raw[$i]['image_mime'] != 'application/octet-stream')) {
606 unset($ThisFileInfo_ogg_comments_raw[$i]['value']);
607 }
608 }
609 }
610
611 if (isset($ThisFileInfo_ogg_comments_raw[$i]['value'])) {
612 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
613 $info[
'ogg'][
'comments'][strtolower($ThisFileInfo_ogg_comments_raw[$i][
'key'])][] = $ThisFileInfo_ogg_comments_raw[$i][
'value'];
614 } else {
615 do {
616 if ($this->inline_attachments === false) {
617
618 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
619 break;
620 }
621 if ($this->inline_attachments === true) {
622
623 } elseif (is_int($this->inline_attachments)) {
624 if ($this->inline_attachments < $ThisFileInfo_ogg_comments_raw[$i]['data_length']) {
625
626 $info[
'warning'][] =
'attachment at '.$ThisFileInfo_ogg_comments_raw[$i][
'offset'].
' is too large to process inline ('.number_format($ThisFileInfo_ogg_comments_raw[$i][
'data_length']).
' bytes)';
627 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
628 break;
629 }
630 } elseif (is_string($this->inline_attachments)) {
631 $this->inline_attachments = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->inline_attachments), DIRECTORY_SEPARATOR);
632 if (!is_dir($this->inline_attachments) || !is_writable($this->inline_attachments)) {
633
634 $info[
'warning'][] =
'attachment at '.$ThisFileInfo_ogg_comments_raw[$i][
'offset'].
' cannot be saved to "'.$this->inline_attachments.
'" (not writable)';
635 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
636 break;
637 }
638 }
639
640 if (is_string($this->inline_attachments)) {
641 $destination_filename = $this->inline_attachments.DIRECTORY_SEPARATOR.md5(
$info[
'filenamepath']).
'_'.$ThisFileInfo_ogg_comments_raw[$i][
'offset'];
642 if (!file_exists($destination_filename) || is_writable($destination_filename)) {
643 file_put_contents($destination_filename, $ThisFileInfo_ogg_comments_raw[$i]['data']);
644 } else {
645 $info[
'warning'][] =
'attachment at '.$ThisFileInfo_ogg_comments_raw[$i][
'offset'].
' cannot be saved to "'.$destination_filename.
'" (not writable)';
646 }
647 $ThisFileInfo_ogg_comments_raw[$i]['data_filename'] = $destination_filename;
648 unset($ThisFileInfo_ogg_comments_raw[$i]['data']);
649 } else {
650 $info[
'ogg'][
'comments'][
'picture'][] = array(
'data'=>$ThisFileInfo_ogg_comments_raw[$i][
'data'],
'image_mime'=>$ThisFileInfo_ogg_comments_raw[$i][
'image_mime']);
651 }
652 } while (false);
653
654 }
655
656 } else {
657
658 $info[
'warning'][] =
'[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.
']: '.$commentstring;
659
660 }
661 }
662
663
664
665 if (isset(
$info[
'ogg'][
'comments']) && is_array(
$info[
'ogg'][
'comments'])) {
666 foreach (
$info[
'ogg'][
'comments'] as $index => $commentvalue) {
667 switch ($index) {
668 case 'rg_audiophile':
669 case 'replaygain_album_gain':
670 $info[
'replay_gain'][
'album'][
'adjustment'] = (double) $commentvalue[0];
671 unset(
$info[
'ogg'][
'comments'][$index]);
672 break;
673
674 case 'rg_radio':
675 case 'replaygain_track_gain':
676 $info[
'replay_gain'][
'track'][
'adjustment'] = (double) $commentvalue[0];
677 unset(
$info[
'ogg'][
'comments'][$index]);
678 break;
679
680 case 'replaygain_album_peak':
681 $info[
'replay_gain'][
'album'][
'peak'] = (double) $commentvalue[0];
682 unset(
$info[
'ogg'][
'comments'][$index]);
683 break;
684
685 case 'rg_peak':
686 case 'replaygain_track_peak':
687 $info[
'replay_gain'][
'track'][
'peak'] = (double) $commentvalue[0];
688 unset(
$info[
'ogg'][
'comments'][$index]);
689 break;
690
691 case 'replaygain_reference_loudness':
692 $info[
'replay_gain'][
'reference_volume'] = (double) $commentvalue[0];
693 unset(
$info[
'ogg'][
'comments'][$index]);
694 break;
695
696 default:
697
698 break;
699 }
700 }
701 }
702
703 $this->
fseek($OriginalOffset);
704
705 return true;
706 }
static GetDataImageSize($imgData, &$imageinfo)
@staticvar string $tempdir
static OggPageSegmentLength($OggInfoArray, $SegmentNumber=1)