aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/song.c1
-rw-r--r--src/tag.c120
-rw-r--r--src/tag.h2
-rw-r--r--src/tag_ape.c145
-rw-r--r--src/tag_ape.h31
6 files changed, 179 insertions, 122 deletions
diff --git a/Makefile.am b/Makefile.am
index 7316a6539..613f9ef2a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -120,6 +120,7 @@ mpd_headers = \
src/tag.h \
src/tag_internal.h \
src/tag_pool.h \
+ src/tag_ape.h \
src/tag_id3.h \
src/tag_print.h \
src/tag_save.h \
@@ -209,6 +210,7 @@ src_mpd_SOURCES = \
src/tag_pool.c \
src/tag_print.c \
src/tag_save.c \
+ src/tag_ape.c \
src/strset.c \
src/uri.c \
src/utils.c \
diff --git a/src/song.c b/src/song.c
index 0262d4b1a..823e71fc7 100644
--- a/src/song.c
+++ b/src/song.c
@@ -22,6 +22,7 @@
#include "mapper.h"
#include "decoder_list.h"
#include "decoder_plugin.h"
+#include "tag_ape.h"
#include "tag_id3.h"
#include "tag.h"
diff --git a/src/tag.c b/src/tag.c
index 960dd4b17..e4aa6bf0e 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -117,126 +117,6 @@ void tag_lib_init(void)
g_free(temp);
}
-struct tag *tag_ape_load(const char *file)
-{
- struct tag *ret = NULL;
- FILE *fp;
- int tagCount;
- char *buffer = NULL;
- char *p;
- size_t tagLen;
- size_t size;
- unsigned long flags;
- int i;
- char *key;
-
- struct {
- unsigned char id[8];
- uint32_t version;
- uint32_t length;
- uint32_t tagCount;
- unsigned char flags[4];
- unsigned char reserved[8];
- } footer;
-
- const char *apeItems[7] = {
- "title",
- "artist",
- "album",
- "comment",
- "genre",
- "track",
- "year"
- };
-
- int tagItems[7] = {
- TAG_ITEM_TITLE,
- TAG_ITEM_ARTIST,
- TAG_ITEM_ALBUM,
- TAG_ITEM_COMMENT,
- TAG_ITEM_GENRE,
- TAG_ITEM_TRACK,
- TAG_ITEM_DATE,
- };
-
- fp = fopen(file, "r");
- if (!fp)
- return NULL;
-
- /* determine if file has an apeV2 tag */
- if (fseek(fp, 0, SEEK_END))
- goto fail;
- size = (size_t)ftell(fp);
- if (fseek(fp, size - sizeof(footer), SEEK_SET))
- goto fail;
- if (fread(&footer, 1, sizeof(footer), fp) != sizeof(footer))
- goto fail;
- if (memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0)
- goto fail;
- if (GUINT32_FROM_LE(footer.version) != 2000)
- goto fail;
-
- /* find beginning of ape tag */
- tagLen = GUINT32_FROM_LE(footer.length);
- if (tagLen < sizeof(footer))
- goto fail;
- if (fseek(fp, size - tagLen, SEEK_SET))
- goto fail;
-
- /* read tag into buffer */
- tagLen -= sizeof(footer);
- if (tagLen <= 0)
- goto fail;
- buffer = g_malloc(tagLen);
- if (fread(buffer, 1, tagLen, fp) != tagLen)
- goto fail;
-
- /* read tags */
- tagCount = GUINT32_FROM_LE(footer.tagCount);
- p = buffer;
- while (tagCount-- && tagLen > 10) {
- size = GUINT32_FROM_LE(*(const uint32_t *)p);
- p += 4;
- tagLen -= 4;
- flags = GUINT32_FROM_LE(*(const uint32_t *)p);
- p += 4;
- tagLen -= 4;
-
- /* get the key */
- key = p;
- while (tagLen - size > 0 && *p != '\0') {
- p++;
- tagLen--;
- }
- p++;
- tagLen--;
-
- /* get the value */
- if (tagLen < size)
- goto fail;
-
- /* we only care about utf-8 text tags */
- if (!(flags & (0x3 << 1))) {
- for (i = 0; i < 7; i++) {
- if (strcasecmp(key, apeItems[i]) == 0) {
- if (!ret)
- ret = tag_new();
- tag_add_item_n(ret, tagItems[i],
- p, size);
- }
- }
- }
- p += size;
- tagLen -= size;
- }
-
-fail:
- if (fp)
- fclose(fp);
- g_free(buffer);
- return ret;
-}
-
struct tag *tag_new(void)
{
struct tag *ret = g_new(struct tag, 1);
diff --git a/src/tag.h b/src/tag.h
index 9f1549be4..026ded5c4 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -61,8 +61,6 @@ struct tag {
unsigned num_items;
};
-struct tag *tag_ape_load(const char *file);
-
struct tag *tag_new(void);
void tag_lib_init(void);
diff --git a/src/tag_ape.c b/src/tag_ape.c
new file mode 100644
index 000000000..c38b07a55
--- /dev/null
+++ b/src/tag_ape.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2003-2009 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "tag_ape.h"
+#include "tag.h"
+
+#include <glib.h>
+
+#include <stdio.h>
+
+struct tag *
+tag_ape_load(const char *file)
+{
+ struct tag *ret = NULL;
+ FILE *fp;
+ int tagCount;
+ char *buffer = NULL;
+ char *p;
+ size_t tagLen;
+ size_t size;
+ unsigned long flags;
+ int i;
+ char *key;
+
+ struct {
+ unsigned char id[8];
+ uint32_t version;
+ uint32_t length;
+ uint32_t tagCount;
+ unsigned char flags[4];
+ unsigned char reserved[8];
+ } footer;
+
+ const char *apeItems[7] = {
+ "title",
+ "artist",
+ "album",
+ "comment",
+ "genre",
+ "track",
+ "year"
+ };
+
+ int tagItems[7] = {
+ TAG_ITEM_TITLE,
+ TAG_ITEM_ARTIST,
+ TAG_ITEM_ALBUM,
+ TAG_ITEM_COMMENT,
+ TAG_ITEM_GENRE,
+ TAG_ITEM_TRACK,
+ TAG_ITEM_DATE,
+ };
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return NULL;
+
+ /* determine if file has an apeV2 tag */
+ if (fseek(fp, 0, SEEK_END))
+ goto fail;
+ size = (size_t)ftell(fp);
+ if (fseek(fp, size - sizeof(footer), SEEK_SET))
+ goto fail;
+ if (fread(&footer, 1, sizeof(footer), fp) != sizeof(footer))
+ goto fail;
+ if (memcmp(footer.id, "APETAGEX", sizeof(footer.id)) != 0)
+ goto fail;
+ if (GUINT32_FROM_LE(footer.version) != 2000)
+ goto fail;
+
+ /* find beginning of ape tag */
+ tagLen = GUINT32_FROM_LE(footer.length);
+ if (tagLen < sizeof(footer))
+ goto fail;
+ if (fseek(fp, size - tagLen, SEEK_SET))
+ goto fail;
+
+ /* read tag into buffer */
+ tagLen -= sizeof(footer);
+ if (tagLen <= 0)
+ goto fail;
+ buffer = g_malloc(tagLen);
+ if (fread(buffer, 1, tagLen, fp) != tagLen)
+ goto fail;
+
+ /* read tags */
+ tagCount = GUINT32_FROM_LE(footer.tagCount);
+ p = buffer;
+ while (tagCount-- && tagLen > 10) {
+ size = GUINT32_FROM_LE(*(const uint32_t *)p);
+ p += 4;
+ tagLen -= 4;
+ flags = GUINT32_FROM_LE(*(const uint32_t *)p);
+ p += 4;
+ tagLen -= 4;
+
+ /* get the key */
+ key = p;
+ while (tagLen - size > 0 && *p != '\0') {
+ p++;
+ tagLen--;
+ }
+ p++;
+ tagLen--;
+
+ /* get the value */
+ if (tagLen < size)
+ goto fail;
+
+ /* we only care about utf-8 text tags */
+ if (!(flags & (0x3 << 1))) {
+ for (i = 0; i < 7; i++) {
+ if (strcasecmp(key, apeItems[i]) == 0) {
+ if (!ret)
+ ret = tag_new();
+ tag_add_item_n(ret, tagItems[i],
+ p, size);
+ }
+ }
+ }
+ p += size;
+ tagLen -= size;
+ }
+
+fail:
+ if (fp)
+ fclose(fp);
+ g_free(buffer);
+ return ret;
+}
diff --git a/src/tag_ape.h b/src/tag_ape.h
new file mode 100644
index 000000000..abd10d631
--- /dev/null
+++ b/src/tag_ape.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2003-2009 The Music Player Daemon Project
+ * http://www.musicpd.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef MPD_TAG_APE_H
+#define MPD_TAG_APE_H
+
+/**
+ * Loads the APE tag from a file.
+ *
+ * @param path_fs the path of the file in filesystem encoding
+ * @return a tag object, or NULL if the file has no APE tag
+ */
+struct tag *
+tag_ape_load(const char *path_fs);
+
+#endif