Created
November 29, 2012 22:35
-
-
Save ousttrue/4172369 to your computer and use it in GitHub Desktop.
id3v2 character encoding patch for mpd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- src/tag_id3.c.orig 2012-11-28 09:27:00.009431866 +0900 | |
+++ src/tag_id3.c 2012-11-28 10:16:23.205446028 +0900 | |
@@ -78,38 +78,72 @@ | |
} | |
/* This will try to convert a string to utf-8, | |
- */ | |
+*/ | |
static id3_utf8_t * | |
-import_id3_string(bool is_id3v1, const id3_ucs4_t *ucs4) | |
+import_id3_string(enum id3_field_textencoding text_encoding, const id3_ucs4_t *ucs4) | |
{ | |
id3_utf8_t *utf8, *utf8_stripped; | |
id3_latin1_t *isostr; | |
const char *encoding; | |
- /* use encoding field here? */ | |
- if (is_id3v1 && | |
- (encoding = config_get_string(CONF_ID3V1_ENCODING, NULL)) != NULL) { | |
- isostr = id3_ucs4_latin1duplicate(ucs4); | |
- if (G_UNLIKELY(!isostr)) { | |
- return NULL; | |
- } | |
- | |
- utf8 = (id3_utf8_t *) | |
- g_convert_with_fallback((const char*)isostr, -1, | |
- "utf-8", encoding, | |
- NULL, NULL, NULL, NULL); | |
- if (utf8 == NULL) { | |
- g_debug("Unable to convert %s string to UTF-8: '%s'", | |
- encoding, isostr); | |
- g_free(isostr); | |
- return NULL; | |
- } | |
- g_free(isostr); | |
- } else { | |
- utf8 = id3_ucs4_utf8duplicate(ucs4); | |
- if (G_UNLIKELY(!utf8)) { | |
- return NULL; | |
- } | |
+ if(ucs4==NULL){ | |
+ return NULL; | |
+ } | |
+ | |
+ /* | |
+ * check text encoding | |
+ * refer http://www.id3.org/id3v2.4.0-structure | |
+ */ | |
+ switch(text_encoding) | |
+ { | |
+ case ID3_FIELD_TEXTENCODING_ISO_8859_1: /* ISO-8859-1 */ | |
+ /** | |
+ * process as none unicode string | |
+ * include isId3v1(tag) | |
+ */ | |
+ isostr = id3_ucs4_latin1duplicate(ucs4); | |
+ if (G_UNLIKELY(!isostr)) { | |
+ g_debug("fail to id3_ucs4_latin1duplicate\n"); | |
+ return NULL; | |
+ } | |
+ | |
+ /* determine text encoding */ | |
+ encoding = config_get_string(CONF_ID3V1_ENCODING, NULL); | |
+ if(!encoding) | |
+ encoding="ISO-8859-1"; | |
+ | |
+ /* convert to UTF-8 */ | |
+ { | |
+ GError *error = NULL; | |
+ utf8 = (id3_utf8_t *) | |
+ g_convert_with_fallback((const char*)isostr, -1, | |
+ "utf-8", encoding, | |
+ NULL, NULL, NULL, &error); | |
+ | |
+ if (utf8 == NULL) { | |
+ g_debug("Unable to convert %s(%d) string to UTF-8: " | |
+ "'%s'\n", encoding, text_encoding, isostr); | |
+ g_error_free(error); | |
+ free(isostr); | |
+ return NULL; | |
+ } | |
+ free(isostr); | |
+ } | |
+ break; | |
+ | |
+ case ID3_FIELD_TEXTENCODING_UTF_16: /* UTF-16 with BOM */ | |
+ case ID3_FIELD_TEXTENCODING_UTF_16BE: /* UTF-16BE withouot BOM */ | |
+ case ID3_FIELD_TEXTENCODING_UTF_8: /* UTF-8 */ | |
+ default: | |
+ /** | |
+ * unicode string | |
+ */ | |
+ utf8=id3_ucs4_utf8duplicate(ucs4); | |
+ if (utf8 == NULL) { | |
+ g_debug("fail to id3_ucs4_utf8duplicate\n"); | |
+ return NULL; | |
+ } | |
+ break; | |
} | |
utf8_stripped = (id3_utf8_t *)g_strdup(g_strstrip((gchar *)utf8)); | |
@@ -127,12 +161,13 @@ | |
*/ | |
static void | |
tag_id3_import_text_frame(struct tag *dest, struct id3_tag *tag, | |
- const struct id3_frame *frame, | |
- enum tag_type type) | |
+ const struct id3_frame *frame, | |
+ enum tag_type type) | |
{ | |
id3_ucs4_t const *ucs4; | |
id3_utf8_t *utf8; | |
- union id3_field const *field; | |
+ union id3_field const *field0; | |
+ union id3_field const *field1; | |
unsigned int nstrings, i; | |
if (frame->nfields != 2) | |
@@ -140,27 +175,27 @@ | |
/* check the encoding field */ | |
- field = id3_frame_field(frame, 0); | |
- if (field == NULL || field->type != ID3_FIELD_TYPE_TEXTENCODING) | |
+ field0 = id3_frame_field(frame, 0); | |
+ if (field0 == NULL || field0->type != ID3_FIELD_TYPE_TEXTENCODING) | |
return; | |
/* process the value(s) */ | |
- field = id3_frame_field(frame, 1); | |
- if (field == NULL || field->type != ID3_FIELD_TYPE_STRINGLIST) | |
+ field1 = id3_frame_field(frame, 1); | |
+ if (field1 == NULL || field1->type != ID3_FIELD_TYPE_STRINGLIST) | |
return; | |
/* Get the number of strings available */ | |
- nstrings = id3_field_getnstrings(field); | |
+ nstrings = id3_field_getnstrings(field1); | |
for (i = 0; i < nstrings; i++) { | |
- ucs4 = id3_field_getstrings(field, i); | |
+ ucs4 = id3_field_getstrings(field1, i); | |
if (ucs4 == NULL) | |
continue; | |
if (type == TAG_GENRE) | |
ucs4 = id3_genre_name(ucs4); | |
- utf8 = import_id3_string(tag_is_id3v1(tag), ucs4); | |
+ utf8 = import_id3_string(id3_field_gettextencoding(field0), ucs4); | |
if (utf8 == NULL) | |
continue; | |
@@ -175,11 +210,11 @@ | |
*/ | |
static void | |
tag_id3_import_text(struct tag *dest, struct id3_tag *tag, const char *id, | |
- enum tag_type type) | |
+ enum tag_type type) | |
{ | |
const struct id3_frame *frame; | |
for (unsigned i = 0; | |
- (frame = id3_tag_findframe(tag, id, i)) != NULL; ++i) | |
+ (frame = id3_tag_findframe(tag, id, i)) != NULL; ++i) | |
tag_id3_import_text_frame(dest, tag, frame, type); | |
} | |
@@ -194,26 +229,31 @@ | |
*/ | |
static void | |
tag_id3_import_comment_frame(struct tag *dest, struct id3_tag *tag, | |
- const struct id3_frame *frame, | |
- enum tag_type type) | |
+ const struct id3_frame *frame, | |
+ enum tag_type type) | |
{ | |
id3_ucs4_t const *ucs4; | |
id3_utf8_t *utf8; | |
- union id3_field const *field; | |
+ union id3_field const *field0; | |
+ union id3_field const *field3; | |
if (frame->nfields != 4) | |
return; | |
+ field0 = id3_frame_field(frame, 0); | |
+ if (field0 == NULL) | |
+ return; | |
+ | |
/* for now I only read the 4th field, with the fullstring */ | |
- field = id3_frame_field(frame, 3); | |
- if (field == NULL) | |
+ field3 = id3_frame_field(frame, 3); | |
+ if (field3 == NULL) | |
return; | |
- ucs4 = id3_field_getfullstring(field); | |
+ ucs4 = id3_field_getfullstring(field3); | |
if (ucs4 == NULL) | |
return; | |
- utf8 = import_id3_string(tag_is_id3v1(tag), ucs4); | |
+ utf8 = import_id3_string(id3_field_gettextencoding(field0), ucs4); | |
if (utf8 == NULL) | |
return; | |
@@ -227,11 +267,11 @@ | |
*/ | |
static void | |
tag_id3_import_comment(struct tag *dest, struct id3_tag *tag, const char *id, | |
- enum tag_type type) | |
+ enum tag_type type) | |
{ | |
const struct id3_frame *frame; | |
for (unsigned i = 0; | |
- (frame = id3_tag_findframe(tag, id, i)) != NULL; ++i) | |
+ (frame = id3_tag_findframe(tag, id, i)) != NULL; ++i) | |
tag_id3_import_comment_frame(dest, tag, frame, type); | |
} | |
@@ -250,7 +290,7 @@ | |
{ TAG_MUSICBRAINZ_ARTISTID, "MusicBrainz Artist Id" }, | |
{ TAG_MUSICBRAINZ_ALBUMID, "MusicBrainz Album Id" }, | |
{ TAG_MUSICBRAINZ_ALBUMARTISTID, | |
- "MusicBrainz Album Artist Id" }, | |
+ "MusicBrainz Album Artist Id" }, | |
{ TAG_MUSICBRAINZ_TRACKID, "MusicBrainz Track Id" }, | |
}; | |
@@ -318,7 +358,7 @@ | |
name = id3_field_getlatin1(field); | |
if (name == NULL || | |
- strcmp((const char *)name, "http://musicbrainz.org") != 0) | |
+ strcmp((const char *)name, "http://musicbrainz.org") != 0) | |
continue; | |
field = id3_frame_field(frame, 1); | |
@@ -330,7 +370,7 @@ | |
continue; | |
tag_add_item_n(mpd_tag, TAG_MUSICBRAINZ_TRACKID, | |
- (const char*)value, length); | |
+ (const char*)value, length); | |
} | |
} | |
@@ -340,11 +380,11 @@ | |
tag_id3_import_text(ret, tag, ID3_FRAME_ARTIST, TAG_ARTIST); | |
tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM_ARTIST, | |
- TAG_ALBUM_ARTIST); | |
+ TAG_ALBUM_ARTIST); | |
tag_id3_import_text(ret, tag, ID3_FRAME_ARTIST_SORT, | |
- TAG_ARTIST_SORT); | |
+ TAG_ARTIST_SORT); | |
tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM_ARTIST_SORT, | |
- TAG_ALBUM_ARTIST_SORT); | |
+ TAG_ALBUM_ARTIST_SORT); | |
tag_id3_import_text(ret, tag, ID3_FRAME_TITLE, TAG_TITLE); | |
tag_id3_import_text(ret, tag, ID3_FRAME_ALBUM, TAG_ALBUM); | |
tag_id3_import_text(ret, tag, ID3_FRAME_TRACK, TAG_TRACK); | |
@@ -397,7 +437,7 @@ | |
/* It's ok if we get less than we asked for */ | |
query_buffer_size = fill_buffer(query_buffer, ID3_TAG_QUERYSIZE, | |
- stream, offset, whence); | |
+ stream, offset, whence); | |
if (query_buffer_size <= 0) return NULL; | |
/* Look for a tag header */ | |
@@ -524,7 +564,7 @@ | |
stream = fopen(file, "rb"); | |
if (!stream) { | |
g_debug("tag_id3_load: Failed to open file: '%s', %s", | |
- file, strerror(errno)); | |
+ file, strerror(errno)); | |
return NULL; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment