コード例 #1
0
ファイル: getid3.ape.php プロジェクト: BackupTheBerlios/sotf
function getAPEtagFilepointer(&$fd, &$ThisFileInfo)
{
    $id3v1tagsize = 128;
    $apetagheadersize = 32;
    fseek($fd, 0 - $id3v1tagsize - $apetagheadersize, SEEK_END);
    $APEfooterID3v1 = fread($fd, $id3v1tagsize + $apetagheadersize);
    if (substr($APEfooterID3v1, 0, strlen('APETAGEX')) == 'APETAGEX' && substr($APEfooterID3v1, $apetagheadersize, strlen('TAG')) == 'TAG') {
        // APE tag found before ID3v1
        $APEfooterData = substr($APEfooterID3v1, 0, $apetagheadersize);
        $APEfooterOffset = 0 - $apetagheadersize - $id3v1tagsize;
    } elseif (substr($APEfooterID3v1, $id3v1tagsize, strlen('APETAGEX')) == 'APETAGEX') {
        // APE tag found, no ID3v1
        $APEfooterData = substr($APEfooterID3v1, $id3v1tagsize, $apetagheadersize);
        $APEfooterOffset = 0 - $apetagheadersize;
    } else {
        // APE tag not found
        return false;
    }
    $ThisFileInfo['ape']['tag_offset_end'] = $ThisFileInfo['filesize'] - ($APEfooterOffset + $apetagheadersize);
    if (empty($ThisFileInfo['fileformat'])) {
        $ThisFileInfo['fileformat'] = 'ape';
    }
    if (!($ThisFileInfo['ape']['footer'] = parseAPEheaderFooter($APEfooterData))) {
        $ThisFileInfo['error'] .= "\n" . 'Error parsing APE footer at offset ' . $ThisFileInfo['ape']['tag_offset_end'];
        return false;
    }
    if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) {
        fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize - $apetagheadersize, SEEK_END);
        $ThisFileInfo['ape']['tag_offset_start'] = ftell($fd);
        $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize);
    } else {
        fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize, SEEK_END);
        $ThisFileInfo['ape']['tag_offset_start'] = ftell($fd);
        $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize']);
    }
    $offset = 0;
    if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) {
        if ($ThisFileInfo['ape']['header'] = parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize))) {
            $offset += $apetagheadersize;
        } else {
            $ThisFileInfo['error'] .= "\n" . 'Error parsing APE header at offset ' . $ThisFileInfo['ape']['tag_offset_start'];
            return false;
        }
    }
    for ($i = 0; $i < $ThisFileInfo['ape']['footer']['raw']['tag_items']; $i++) {
        $value_size = LittleEndian2Int(substr($APEtagData, $offset, 4));
        $offset += 4;
        $item_flags = LittleEndian2Int(substr($APEtagData, $offset, 4));
        $offset += 4;
        if (strstr(substr($APEtagData, $offset), chr(0)) === false) {
            $ThisFileInfo['error'] .= "\n" . 'Cannot find null-byte (0x00) seperator between ItemKey #' . $i . ' and value. ItemKey starts ' . $offset . ' bytes into the APE tag, at file offset ' . ($ThisFileInfo['ape']['tag_offset_start'] + $offset);
            return false;
        }
        $ItemKeyLength = strpos($APEtagData, chr(0), $offset) - $offset;
        $item_key = strtolower(substr($APEtagData, $offset, $ItemKeyLength));
        $offset += $ItemKeyLength + 1;
        // skip 0x00 terminator
        $ThisFileInfo['ape']['items']["{$item_key}"]['data'] = substr($APEtagData, $offset, $value_size);
        $offset += $value_size;
        if ($ThisFileInfo['ape']['footer']['tag_version'] >= 2) {
            $ThisFileInfo['ape']['items']["{$item_key}"]['flags'] = parseAPEtagFlags($item_flags);
        }
        switch ($ThisFileInfo['ape']['items']["{$item_key}"]['flags']['item_contents_raw']) {
            case 0:
                // UTF-8
            // UTF-8
            case 3:
                // Locator (URL, filename, etc), UTF-8 encoded
                $ThisFileInfo['ape']['items']["{$item_key}"]['data'] = explode(chr(0), $ThisFileInfo['ape']['items']["{$item_key}"]['data']);
                foreach ($ThisFileInfo['ape']['items']["{$item_key}"]['data'] as $key => $value) {
                    $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'][$key] = RoughTranslateUnicodeToASCII($value, 3);
                }
                break;
            default:
                // binary data
                //$ThisFileInfo['ape']['items']["$item_key"]['data_ascii'] = null;
                break;
        }
        switch ($item_key) {
            case 'replaygain_track_gain':
                $ThisFileInfo['replay_gain']['radio']['adjustment'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'][0];
                $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified';
                break;
            case 'replaygain_track_peak':
                $ThisFileInfo['replay_gain']['radio']['peak'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'][0];
                $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified';
                break;
            case 'replaygain_album_gain':
                $ThisFileInfo['replay_gain']['audiophile']['adjustment'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'][0];
                $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified';
                break;
            case 'replaygain_album_peak':
                $ThisFileInfo['replay_gain']['audiophile']['peak'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'][0];
                $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified';
                break;
            default:
                foreach ($ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'] as $comment) {
                    $ThisFileInfo['ape']['comments'][strtolower($item_key)][] = $comment;
                }
                break;
        }
    }
    if (isset($ThisFileInfo['ape']['comments'])) {
        CopyFormatCommentsToRootComments($ThisFileInfo['ape']['comments'], $ThisFileInfo, true, true, true);
    }
    return true;
}
コード例 #2
0
function getAPEtagFilepointer(&$fd, &$ThisFileInfo)
{
    $id3v1tagsize = 128;
    $apetagheadersize = 32;
    fseek($fd, 0 - $id3v1tagsize - $apetagheadersize, SEEK_END);
    $APEfooterID3v1 = fread($fd, $id3v1tagsize + $apetagheadersize);
    if (substr($APEfooterID3v1, 0, strlen('APETAGEX')) == 'APETAGEX') {
        // APE tag found before ID3v1
        $APEfooterData = substr($APEfooterID3v1, 0, $apetagheadersize);
        $APEfooterOffset = 0 - $apetagheadersize - $id3v1tagsize;
    } elseif (substr($APEfooterID3v1, $id3v1tagsize, strlen('APETAGEX')) == 'APETAGEX') {
        // APE tag found, no ID3v1
        $APEfooterData = substr($APEfooterID3v1, $id3v1tagsize, $apetagheadersize);
        $APEfooterOffset = 0 - $apetagheadersize;
    } else {
        // APE tag not found
        return false;
    }
    if (empty($ThisFileInfo['fileformat'])) {
        $ThisFileInfo['fileformat'] = 'ape';
    }
    $ThisFileInfo['ape']['footer'] = parseAPEheaderFooter($APEfooterData);
    if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) {
        fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize - $apetagheadersize, SEEK_END);
        $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize);
    } else {
        fseek($fd, $APEfooterOffset - $ThisFileInfo['ape']['footer']['raw']['tagsize'] + $apetagheadersize, SEEK_END);
        $APEtagData = fread($fd, $ThisFileInfo['ape']['footer']['raw']['tagsize']);
    }
    $offset = 0;
    if (isset($ThisFileInfo['ape']['footer']['flags']['header']) && $ThisFileInfo['ape']['footer']['flags']['header']) {
        $ThisFileInfo['ape']['header'] = parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize));
        $offset += $apetagheadersize;
    }
    for ($i = 0; $i < $ThisFileInfo['ape']['footer']['raw']['tag_items']; $i++) {
        $value_size = LittleEndian2Int(substr($APEtagData, $offset, 4));
        $offset += 4;
        $item_flags = LittleEndian2Int(substr($APEtagData, $offset, 4));
        $offset += 4;
        $ItemKeyLength = strpos($APEtagData, chr(0), $offset) - $offset;
        $item_key = strtolower(substr($APEtagData, $offset, $ItemKeyLength));
        $offset += $ItemKeyLength + 1;
        // skip 0x00 terminator
        $data = substr($APEtagData, $offset, $value_size);
        $offset += $value_size;
        $ThisFileInfo['ape']['items']["{$item_key}"]['raw']['value_size'] = $value_size;
        $ThisFileInfo['ape']['items']["{$item_key}"]['raw']['item_flags'] = $item_flags;
        if ($ThisFileInfo['ape']['footer']['tag_version'] >= 2) {
            $ThisFileInfo['ape']['items']["{$item_key}"]['flags'] = parseAPEtagFlags($item_flags);
        }
        $ThisFileInfo['ape']['items']["{$item_key}"]['data'] = $data;
        $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'] = $data;
        if (APEtagItemIsUTF8Lookup($item_key)) {
            $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'] = RoughTranslateUnicodeToASCII($ThisFileInfo['ape']['items']["{$item_key}"]['data'], 3);
        }
        switch ($item_key) {
            case 'replaygain_track_gain':
                $ThisFileInfo['replay_gain']['radio']['adjustment'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'];
                $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified';
                break;
            case 'replaygain_track_peak':
                $ThisFileInfo['replay_gain']['radio']['peak'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'];
                $ThisFileInfo['replay_gain']['radio']['originator'] = 'unspecified';
                break;
            case 'replaygain_album_gain':
                $ThisFileInfo['replay_gain']['audiophile']['adjustment'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'];
                $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified';
                break;
            case 'replaygain_album_peak':
                $ThisFileInfo['replay_gain']['audiophile']['peak'] = (double) $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'];
                $ThisFileInfo['replay_gain']['audiophile']['originator'] = 'unspecified';
                break;
            case 'title':
            case 'artist':
            case 'album':
            case 'track':
            case 'genre':
            case 'comment':
            case 'year':
                $ThisFileInfo['ape']['comments']["{$item_key}"][] = $ThisFileInfo['ape']['items']["{$item_key}"]['data_ascii'];
                break;
        }
    }
    if (isset($ThisFileInfo['ape']['comments'])) {
        CopyFormatCommentsToRootComments($ThisFileInfo['ape']['comments'], $ThisFileInfo, true, true, true);
    }
    return true;
}