• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/apetag.c

Go to the documentation of this file.
00001 /*
00002  * APE tag handling
00003  * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
00004  *  based upon libdemac from Dave Chapman.
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include "libavutil/intreadwrite.h"
00024 #include "avformat.h"
00025 #include "apetag.h"
00026 
00027 #define ENABLE_DEBUG 0
00028 
00029 #define APE_TAG_VERSION               2000
00030 #define APE_TAG_FOOTER_BYTES          32
00031 #define APE_TAG_FLAG_CONTAINS_HEADER  (1 << 31)
00032 #define APE_TAG_FLAG_IS_HEADER        (1 << 29)
00033 
00034 static int ape_tag_read_field(AVFormatContext *s)
00035 {
00036     ByteIOContext *pb = s->pb;
00037     uint8_t key[1024], *value;
00038     uint32_t size, flags;
00039     int i, c;
00040 
00041     size = get_le32(pb);  /* field size */
00042     flags = get_le32(pb); /* field flags */
00043     for (i = 0; i < sizeof(key) - 1; i++) {
00044         c = get_byte(pb);
00045         if (c < 0x20 || c > 0x7E)
00046             break;
00047         else
00048             key[i] = c;
00049     }
00050     key[i] = 0;
00051     if (c != 0) {
00052         av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key);
00053         return -1;
00054     }
00055     if (size >= UINT_MAX)
00056         return -1;
00057     value = av_malloc(size+1);
00058     if (!value)
00059         return AVERROR(ENOMEM);
00060     get_buffer(pb, value, size);
00061     value[size] = 0;
00062     av_metadata_set2(&s->metadata, key, value, AV_METADATA_DONT_STRDUP_VAL);
00063     return 0;
00064 }
00065 
00066 void ff_ape_parse_tag(AVFormatContext *s)
00067 {
00068     ByteIOContext *pb = s->pb;
00069     int file_size = url_fsize(pb);
00070     uint32_t val, fields, tag_bytes;
00071     uint8_t buf[8];
00072     int i;
00073 
00074     if (file_size < APE_TAG_FOOTER_BYTES)
00075         return;
00076 
00077     url_fseek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);
00078 
00079     get_buffer(pb, buf, 8);    /* APETAGEX */
00080     if (strncmp(buf, "APETAGEX", 8)) {
00081         return;
00082     }
00083 
00084     val = get_le32(pb);        /* APE tag version */
00085     if (val > APE_TAG_VERSION) {
00086         av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
00087         return;
00088     }
00089 
00090     tag_bytes = get_le32(pb);  /* tag size */
00091     if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
00092         av_log(s, AV_LOG_ERROR, "Tag size is way too big\n");
00093         return;
00094     }
00095 
00096     fields = get_le32(pb);     /* number of fields */
00097     if (fields > 65536) {
00098         av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields);
00099         return;
00100     }
00101 
00102     val = get_le32(pb);        /* flags */
00103     if (val & APE_TAG_FLAG_IS_HEADER) {
00104         av_log(s, AV_LOG_ERROR, "APE Tag is a header\n");
00105         return;
00106     }
00107 
00108     url_fseek(pb, file_size - tag_bytes, SEEK_SET);
00109 
00110     for (i=0; i<fields; i++)
00111         if (ape_tag_read_field(s) < 0) break;
00112 }

Generated on Fri Sep 16 2011 17:17:47 for FFmpeg by  doxygen 1.7.1