mpd-0.16.2のid3tagのsjisパッチ

また、間が開いてしまった。
一昨年書いてデッドリンク化していたのをハードディスクから発掘してきた。

--- tag_id3.c.orig	2011-03-19 09:41:54.000000000 +0900
+++ tag_id3.c	2011-09-07 00:05:04.065856120 +0900
@@ -80,36 +80,70 @@
 /* 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));
@@ -132,7 +166,8 @@
 {
 	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;
 
@@ -199,21 +234,26 @@
 {
 	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;

設定ファイルに

id3v1_encoding			"cp932"

と書いておくとunicodeエンコーディングでないid3tag v2を、設定ファイルのid3v1_encodingに指定した文字コードで処理する改造。