예제 #1
0
파일: apetag.c 프로젝트: BrianNewsom/FFmpeg
int64_t ff_ape_parse_tag(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    int64_t file_size = avio_size(pb);
    uint32_t val, fields, tag_bytes;
    uint8_t buf[8];
    int64_t tag_start;
    int i;

    if (file_size < APE_TAG_FOOTER_BYTES)
        return 0;

    avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);

    avio_read(pb, buf, 8);     /* APETAGEX */
    if (strncmp(buf, APE_TAG_PREAMBLE, 8)) {
        return 0;
    }

    val = avio_rl32(pb);       /* APE tag version */
    if (val > APE_TAG_VERSION) {
        av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
        return 0;
    }

    tag_bytes = avio_rl32(pb); /* tag size */
    if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
        av_log(s, AV_LOG_ERROR, "Tag size is way too big\n");
        return 0;
    }

    if (tag_bytes > file_size - APE_TAG_FOOTER_BYTES) {
        av_log(s, AV_LOG_ERROR, "Invalid tag size %"PRIu32".\n", tag_bytes);
        return 0;
    }
    tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES;

    fields = avio_rl32(pb);    /* number of fields */
    if (fields > 65536) {
        av_log(s, AV_LOG_ERROR, "Too many tag fields (%"PRIu32")\n", fields);
        return 0;
    }

    val = avio_rl32(pb);       /* flags */
    if (val & APE_TAG_FLAG_IS_HEADER) {
        av_log(s, AV_LOG_ERROR, "APE Tag is a header\n");
        return 0;
    }

    avio_seek(pb, file_size - tag_bytes, SEEK_SET);

    for (i=0; i<fields; i++)
        if (ape_tag_read_field(s) < 0) break;

    return tag_start;
}
예제 #2
0
static void ape_parse_tag(AVFormatContext *s)
{
    ByteIOContext *pb = &s->pb;
    int file_size = url_fsize(pb);
    uint32_t val, fields, tag_bytes;
    uint8_t buf[8];
    int i;

    if (file_size < APE_TAG_FOOTER_BYTES)
        return;

    url_fseek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);

    get_buffer(pb, buf, 8);    /* APETAGEX */
    if (strncmp(buf, "APETAGEX", 8)) {
        av_log(NULL, AV_LOG_ERROR, "Invalid APE Tags\n");
        return;
    }

    val = get_le32(pb);        /* APE tag version */
    if (val > APE_TAG_VERSION) {
        av_log(NULL, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
        return;
    }

    tag_bytes = get_le32(pb);  /* tag size */
    if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
        av_log(NULL, AV_LOG_ERROR, "Tag size is way too big\n");
        return;
    }

    fields = get_le32(pb);     /* number of fields */
    if (fields > 65536) {
        av_log(NULL, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields);
        return;
    }

    val = get_le32(pb);        /* flags */
    if (val & APE_TAG_FLAG_IS_HEADER) {
        av_log(NULL, AV_LOG_ERROR, "APE Tag is a header\n");
        return;
    }

    if (val & APE_TAG_FLAG_CONTAINS_HEADER)
        tag_bytes += 2*APE_TAG_FOOTER_BYTES;

    url_fseek(pb, file_size - tag_bytes, SEEK_SET);

    for (i=0; i<fields; i++)
        ape_tag_read_field(s);

#if ENABLE_DEBUG
    av_log(NULL, AV_LOG_DEBUG, "\nAPE Tags:\n\n");
    av_log(NULL, AV_LOG_DEBUG, "title     = %s\n", s->title);
    av_log(NULL, AV_LOG_DEBUG, "author    = %s\n", s->author);
    av_log(NULL, AV_LOG_DEBUG, "copyright = %s\n", s->copyright);
    av_log(NULL, AV_LOG_DEBUG, "comment   = %s\n", s->comment);
    av_log(NULL, AV_LOG_DEBUG, "album     = %s\n", s->album);
    av_log(NULL, AV_LOG_DEBUG, "year      = %d\n", s->year);
    av_log(NULL, AV_LOG_DEBUG, "track     = %d\n", s->track);
    av_log(NULL, AV_LOG_DEBUG, "genre     = %s\n", s->genre);
#endif
}