summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/demuxers/id3.c89
-rw-r--r--src/demuxers/id3.h70
2 files changed, 115 insertions, 44 deletions
diff --git a/src/demuxers/id3.c b/src/demuxers/id3.c
index d29449ded..d7f58fc39 100644
--- a/src/demuxers/id3.c
+++ b/src/demuxers/id3.c
@@ -20,11 +20,19 @@
* ID3 tag parser
*
* Supported versions: v1, v2.2, v2.3
- * TODO: v2.4
+ * TODO:
+ * v1: genre
+ * v1.1: track info
+ * v2.2: unicode
+ * unsynchronize ?
+ * v2.3: unicode
+ * unsynchronize ?
+ * unzip support ?
+ * v2.4: parsing
*
* ID3v2 specs: http://www.id3.org/
*
- * $Id: id3.c,v 1.3 2003/12/07 23:17:07 tmattern Exp $
+ * $Id: id3.c,v 1.4 2003/12/08 22:10:20 tmattern Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -173,37 +181,53 @@ int id3v22_parse_tag(input_plugin_t *input,
if (id3v2_parse_header(input, mp3_frame_header, &tag_header)) {
+ if (tag_header.flags & ID3V22_ZERO_FLAG) {
+ /* invalid flags */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: invalid header flags\n");
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
+ return 0;
+ }
if (tag_header.flags & ID3V22_COMPRESS_FLAG) {
- /* compressed tag ? just skip it */
+ /* compressed tag: not supported */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: compressed tags are not supported\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
- } else {
- /* frame parsing */
- while ((pos + ID3V22_FRAME_HEADER_SIZE) <= tag_header.size) {
- if (id3v22_parse_frame_header(input, &tag_frame_header)) {
- pos += ID3V22_FRAME_HEADER_SIZE;
- if (tag_frame_header.id && tag_frame_header.size) {
- if ((pos + tag_frame_header.size) <= tag_header.size) {
- if (!id3v22_interp_frame(input, stream, &tag_frame_header)) {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame content\n");
- }
- } else {
+ return 0;
+ }
+ if (tag_header.flags & ID3V22_UNSYNCH_FLAG) {
+ /* unsynchronized tag: not supported */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: unsynchronized tags are not supported\n");
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
+ return 0;
+ }
+ /* frame parsing */
+ while ((pos + ID3V22_FRAME_HEADER_SIZE) <= tag_header.size) {
+ if (id3v22_parse_frame_header(input, &tag_frame_header)) {
+ pos += ID3V22_FRAME_HEADER_SIZE;
+ if (tag_frame_header.id && tag_frame_header.size) {
+ if ((pos + tag_frame_header.size) <= tag_header.size) {
+ if (!id3v22_interp_frame(input, stream, &tag_frame_header)) {
xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: invalid frame header\n");
- input->seek (input, tag_header.size - pos, SEEK_CUR);
- return 1;
+ "id3: invalid frame content\n");
}
- pos += tag_frame_header.size;
} else {
- /* end of frames, the rest is padding */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: invalid frame header\n");
input->seek (input, tag_header.size - pos, SEEK_CUR);
return 1;
}
+ pos += tag_frame_header.size;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
- "id3: id3v2_parse_frame_header problem\n");
- return 0;
+ /* end of frames, the rest is padding */
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
+ return 1;
}
+ } else {
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: id3v2_parse_frame_header problem\n");
+ return 0;
}
}
return 1;
@@ -340,13 +364,26 @@ int id3v23_parse_tag(input_plugin_t *input,
if (id3v2_parse_header(input, mp3_frame_header, &tag_header)) {
- if (tag_header.flags & ID3V23_EXTHEAD_FLAG) {
+ if (tag_header.flags & ID3V23_ZERO_FLAG) {
+ /* invalid flags */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: invalid header flags\n");
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
+ return 0;
+ }
+ if (tag_header.flags & ID3V23_UNSYNCH_FLAG) {
+ /* unsynchronized tag: not supported */
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG,
+ "id3: unsynchronized tags are not supported\n");
+ input->seek (input, tag_header.size - pos, SEEK_CUR);
+ return 0;
+ }
+ if (tag_header.flags & ID3V23_EXT_HEADER_FLAG) {
/* extended header */
if (!id3v23_parse_frame_ext_header(input, &tag_frame_ext_header)) {
return 0;
}
}
-
/* frame parsing */
while ((pos + ID3V23_FRAME_HEADER_SIZE) <= tag_header.size) {
if (id3v23_parse_frame_header(input, &tag_frame_header)) {
@@ -377,7 +414,7 @@ int id3v23_parse_tag(input_plugin_t *input,
}
return 1;
} else {
- xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "id3v22: id3v2_parse_header problem\n");
+ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "id3v23: id3v2_parse_header problem\n");
return 0;
}
}
diff --git a/src/demuxers/id3.h b/src/demuxers/id3.h
index 09fc950b0..2da088e2b 100644
--- a/src/demuxers/id3.h
+++ b/src/demuxers/id3.h
@@ -22,7 +22,7 @@
* Supported versions: v1, v2.2
* TODO: v2.3, v2.4
*
- * $Id: id3.h,v 1.1 2003/12/07 23:05:41 tmattern Exp $
+ * $Id: id3.h,v 1.2 2003/12/08 22:10:20 tmattern Exp $
*/
#ifndef ID3_H
@@ -38,23 +38,57 @@
#define ID3V23_TAG FOURCC_TAG('I', 'D', '3', 3) /* id3 v2.3 tags */
#define ID3V24_TAG FOURCC_TAG('I', 'D', '3', 4) /* id3 v2.4 tags */
-/* id2v2.2 */
-#define ID3V22_FRAME_HEADER_SIZE 6
-#define ID3V22_UNSYNCH_FLAG 0x8000
-#define ID3V22_COMPRESS_FLAG 0x4000
-
-/* id2v2.3 */
-#define ID3V23_FRAME_HEADER_SIZE 10
-#define ID3V23_UNSYNCH_FLAG 0x8000
-#define ID3V23_EXTHEAD_FLAG 0x4000
-#define ID3V23_EXP_FLAG 0x2000
-
-/* id2v2.4 */
-#define ID3V24_FRAME_HEADER_SIZE 10
-#define ID3V24_UNSYNCH_FLAG 0x8000
-#define ID3V24_EXTHEAD_FLAG 0x4000
-#define ID3V24_EXP_FLAG 0x2000
-#define ID3V24_FOOTER_FLAG 0x1000
+/*
+ * ID3 v2.2
+ */
+/* tag header */
+#define ID3V22_UNSYNCH_FLAG 0x80
+#define ID3V22_COMPRESS_FLAG 0x40
+#define ID3V22_ZERO_FLAG 0x3F
+
+/* frame header */
+#define ID3V22_FRAME_HEADER_SIZE 6
+
+/*
+ * ID3 v2.3
+ */
+/* tag header */
+#define ID3V23_UNSYNCH_FLAG 0x80
+#define ID3V23_EXT_HEADER_FLAG 0x40
+#define ID3V23_EXPERIMENTAL_FLAG 0x20
+#define ID3V23_ZERO_FLAG 0x1F
+
+/* frame header */
+#define ID3V23_FRAME_HEADER_SIZE 10
+#define ID3V23_FRAME_TAG_PRESERV_FLAG 0x8000
+#define ID3V23_FRAME_FILE_PRESERV_FLAG 0x4000
+#define ID3V23_FRAME_READ_ONLY_FLAG 0x2000
+#define ID3V23_FRAME_COMPRESS_FLAG 0x0080
+#define ID3V23_FRAME_ENCRYPT_FLAG 0x0040
+#define ID3V23_FRAME_GROUP_ID_FLAG 0x0020
+#define ID3V23_FRAME_ZERO_FLAG 0x1F1F
+
+/*
+ * ID3 v2.4
+ */
+/* tag header */
+#define ID3V24_UNSYNCH_FLAG 0x80
+#define ID3V24_EXT_HEADER_FLAG 0x40
+#define ID3V24_EXPERIMENTAL_FLAG 0x20
+#define ID3V24_FOOTER_FLAG 0x10
+#define ID3V24_ZERO_FLAG 0x0F
+
+/* frame header */
+#define ID3V24_FRAME_HEADER_SIZE 10
+#define ID3V24_FRAME_TAG_PRESERV_FLAG 0x4000
+#define ID3V24_FRAME_FILE_PRESERV_FLAG 0x2000
+#define ID3V24_FRAME_READ_ONLY_FLAG 0x1000
+#define ID3V24_FRAME_GROUP_ID_FLAG 0x0040
+#define ID3V24_FRAME_COMPRESS_FLAG 0x0008
+#define ID3V24_FRAME_ENCRYPT_FLAG 0x0004
+#define ID3V24_FRAME_UNSYNCH_FLAG 0x0002
+#define ID3V24_FRAME_DATA_LEN_FLAG 0x0001
+#define ID3V24_FRAME_ZERO_FLAG 0x8FB0
typedef struct {
uint32_t id;