summaryrefslogtreecommitdiff
path: root/junklib.c
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-02 12:45:39 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-02 12:45:39 +0100
commitd90852fcc0ce41ce30d39a7d50e8156863c4a7b9 (patch)
tree770532f7c0e2f46f4674975db2f0649503a80214 /junklib.c
parent3d295609190fa94f6a156a6e08aa3d646c628179 (diff)
extended id3v2 reader to support more frame types; fixed few bugs
Diffstat (limited to 'junklib.c')
-rw-r--r--junklib.c181
1 files changed, 172 insertions, 9 deletions
diff --git a/junklib.c b/junklib.c
index b2c9e8d4..53e07cc1 100644
--- a/junklib.c
+++ b/junklib.c
@@ -24,8 +24,8 @@
#include "utf8.h"
#include "plugins.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
@@ -790,7 +790,11 @@ junk_read_id3v2 (playItem_t *it, DB_FILE *fp) {
char *band = NULL;
char *track = NULL;
char *title = NULL;
+ char *year = NULL;
char *vendor = NULL;
+ char *comment = NULL;
+ char *copyright = NULL;
+ char *genre = NULL;
int err = 0;
while (readptr - tag <= size - 4) {
if (version_major == 3 || version_major == 4) {
@@ -934,7 +938,64 @@ junk_read_id3v2 (playItem_t *it, DB_FILE *fp) {
id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
album = convstr (str, sz);
}
+ else if (!strcmp (frameid, "TYER")) {
+ if (sz > 1000) {
+ err = 1;
+ break; // too large
+ }
+ char str[sz+2];
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ year = convstr (str, sz);
+ }
+ else if (!strcmp (frameid, "TCOP")) {
+ if (sz > 1000) {
+ err = 1;
+ break; // too large
+ }
+ char str[sz+2];
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ copyright = convstr (str, sz);
+ trace ("TCOP: %s\n", copyright);
+ }
+ else if (!strcmp (frameid, "TCON")) {
+ if (sz > 1000) {
+ err = 1;
+ break; // too large
+ }
+ char str[sz+2];
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ genre = convstr (str, sz);
+ trace ("TCON: %s\n", genre);
+ }
else if (!strcmp (frameid, "COMM")) {
+ if (sz < 4) {
+ trace ("COMM frame is too short, skipped\n");
+ readptr += sz; // bad tag
+ continue;
+ }
+ uint8_t enc = readptr[0];
+ char lang[4] = {readptr[1], readptr[2], readptr[3], 0};
+ if (strcmp (lang, "eng")) {
+ trace ("non-english comment, skip\n");
+ readptr += sz;
+ continue;
+ }
+ trace ("COMM enc is: %d\n", (int)enc);
+ trace ("COMM language is: %s\n", lang);
+ char *descr = readptr+4;
+ trace ("COMM descr: %s\n", descr);
+ if (!strcmp (descr, "iTunNORM")) {
+ // ignore itunes normalization metadata
+ readptr += sz;
+ continue;
+ }
+ int dlen = strlen(descr)+1;
+ int s = sz - 4 - dlen;
+ char str[s + 3];
+ id3v2_string_read (version_major, &str[1], s, unsync, descr+dlen);
+ str[0] = enc;
+ comment = convstr (str, s+1);
+ trace ("COMM text: %s\n", comment);
}
else if (!strcmp (frameid, "TXXX")) {
if (sz < 2) {
@@ -1001,59 +1062,127 @@ junk_read_id3v2 (playItem_t *it, DB_FILE *fp) {
// trace ("found id3v2.2 frame: %s, size=%d\n", frameid, sz);
if (!strcmp (frameid, "TEN")) {
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
vendor = convstr (str, sz);
}
else if (!strcmp (frameid, "TT2")) {
if (sz > 1000) {
+ readptr += sz;
continue;
}
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
title = convstr (str, sz);
}
else if (!strcmp (frameid, "TAL")) {
if (sz > 1000) {
+ readptr += sz;
continue;
}
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
album = convstr (str, sz);
}
else if (!strcmp (frameid, "TP1")) {
if (sz > 1000) {
+ readptr += sz;
continue;
}
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
artist = convstr (str, sz);
}
else if (!strcmp (frameid, "TP2")) {
if (sz > 1000) {
+ readptr += sz;
continue;
}
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
band = convstr (str, sz);
}
else if (!strcmp (frameid, "TRK")) {
if (sz > 1000) {
+ readptr += sz;
continue;
}
char str[sz+2];
- memcpy (str, readptr, sz);
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
str[sz] = 0;
track = convstr (str, sz);
}
+ else if (!strcmp (frameid, "TYE")) {
+ if (sz > 1000) {
+ readptr += sz;
+ continue;
+ }
+ char str[sz+2];
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ str[sz] = 0;
+ year = convstr (str, sz);
+ }
+ else if (!strcmp (frameid, "TCR")) {
+ if (sz > 1000) {
+ readptr += sz;
+ continue;
+ }
+ char str[sz+2];
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ str[sz] = 0;
+ copyright = convstr (str, sz);
+ }
+ else if (!strcmp (frameid, "TCO")) {
+ if (sz > 1000) {
+ readptr += sz;
+ continue;
+ }
+ char str[sz+2];
+ //memcpy (str, readptr, sz);
+ id3v2_string_read (version_major, &str[0], sz, unsync, readptr);
+ str[sz] = 0;
+ genre = convstr (str, sz);
+ }
+ else if (!strcmp (frameid, "COM")) {
+ if (sz > 1000) {
+ readptr += sz;
+ continue;
+ }
+ uint8_t enc = readptr[0];
+ char lang[4] = {readptr[1], readptr[2], readptr[3], 0};
+ if (strcmp (lang, "eng")) {
+ trace ("non-english comment, skip\n");
+ readptr += sz;
+ continue;
+ }
+ trace ("COM enc is: %d\n", (int)enc);
+ trace ("COM language is: %s\n", lang);
+ char *descr = readptr+4;
+ trace ("COM descr: %s\n", descr);
+ int dlen = strlen(descr)+1;
+ int s = sz - 4 - dlen;
+ char str[s + 3];
+ id3v2_string_read (version_major, &str[1], s, unsync, descr+dlen);
+ str[0] = enc;
+ comment = convstr (str, s+1);
+ trace ("COM text: %s\n", comment);
+ }
readptr += sz;
}
else {
-// trace ("id3v2.%d (unsupported!)\n", version_minor);
+ trace ("id3v2.%d (unsupported!)\n", version_minor);
}
}
if (!err) {
@@ -1077,10 +1206,44 @@ junk_read_id3v2 (playItem_t *it, DB_FILE *fp) {
pl_add_meta (it, "title", title);
free (title);
}
+ if (genre) {
+ if (genre[0] == '(') {
+ const char *v1genre = NULL;
+ // find matching parenthesis
+ const char *p = &genre[1];
+ while (*p && *p != ')') {
+ p++;
+ }
+ if (p > &genre[1]) {
+ int g = atoi (&genre[1]);
+ if (g < 148) {
+ v1genre = junk_genretbl[g];
+ }
+ }
+ if (v1genre) {
+ free (genre);
+ genre = strdup (v1genre);
+ }
+ }
+ pl_add_meta (it, "genre", genre);
+ free (genre);
+ }
+ if (year) {
+ pl_add_meta (it, "year", year);
+ free (year);
+ }
+ if (copyright) {
+ pl_add_meta (it, "copyright", copyright);
+ free (copyright);
+ }
if (vendor) {
pl_add_meta (it, "vendor", vendor);
free (vendor);
}
+ if (comment) {
+ pl_add_meta (it, "comment", comment);
+ free (comment);
+ }
if (!title) {
pl_add_meta (it, "title", NULL);
}