rewrite to use new functionality in plugin_common
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 29 Aug 2002 08:13:01 +0000 (08:13 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 29 Aug 2002 08:13:01 +0000 (08:13 +0000)
src/plugin_xmms/charset.c
src/plugin_xmms/charset.h
src/plugin_xmms/wrap_id3.c

index 8a8091e..0ad7a8c 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-#ifdef HAVE_ICONV
-#include <iconv.h>
-#endif
-
-#ifdef HAVE_LANGINFO_CODESET
-#include <langinfo.h>
-#endif
-
+#include "plugin_common/charset.h"
+#include "plugin_common/locale_hack.h"
 #include "charset.h"
-#include "mylocale.h"
 #include "configure.h"
 
 
  ****************/
 
 #define CHARSET_TRANS_ARRAY_LEN ( sizeof(charset_trans_array) / sizeof((charset_trans_array)[0]) )
-const CharsetInfo charset_trans_array[] = { 
-    {N_("Arabic (IBM-864)"),                  "IBM864"        },
-    {N_("Arabic (ISO-8859-6)"),               "ISO-8859-6"    },
-    {N_("Arabic (Windows-1256)"),             "windows-1256"  },
-    {N_("Baltic (ISO-8859-13)"),              "ISO-8859-13"   },
-    {N_("Baltic (ISO-8859-4)"),               "ISO-8859-4"    },
-    {N_("Baltic (Windows-1257)"),             "windows-1257"  },
-    {N_("Celtic (ISO-8859-14)"),              "ISO-8859-14"   },
-    {N_("Central European (IBM-852)"),        "IBM852"        },
-    {N_("Central European (ISO-8859-2)"),     "ISO-8859-2"    },
-    {N_("Central European (Windows-1250)"),   "windows-1250"  },
-    {N_("Chinese Simplified (GB18030)"),      "gb18030"       },
-    {N_("Chinese Simplified (GB2312)"),       "GB2312"        },
-    {N_("Chinese Traditional (Big5)"),        "Big5"          },
-    {N_("Chinese Traditional (Big5-HKSCS)"),  "Big5-HKSCS"    },
-    {N_("Cyrillic (IBM-855)"),                "IBM855"        },
-    {N_("Cyrillic (ISO-8859-5)"),             "ISO-8859-5"    },
-    {N_("Cyrillic (ISO-IR-111)"),             "ISO-IR-111"    },
-    {N_("Cyrillic (KOI8-R)"),                 "KOI8-R"        },
-    {N_("Cyrillic (Windows-1251)"),           "windows-1251"  },
-    {N_("Cyrillic/Russian (CP-866)"),         "IBM866"        },
-    {N_("Cyrillic/Ukrainian (KOI8-U)"),       "KOI8-U"        },
-    {N_("English (US-ASCII)"),                "us-ascii"      },
-    {N_("Greek (ISO-8859-7)"),                "ISO-8859-7"    },
-    {N_("Greek (Windows-1253)"),              "windows-1253"  },
-    {N_("Hebrew (IBM-862)"),                  "IBM862"        },
-    {N_("Hebrew (Windows-1255)"),             "windows-1255"  },
-    {N_("Japanese (EUC-JP)"),                 "EUC-JP"        },
-    {N_("Japanese (ISO-2022-JP)"),            "ISO-2022-JP"   },
-    {N_("Japanese (Shift_JIS)"),              "Shift_JIS"     },
-    {N_("Korean (EUC-KR)"),                   "EUC-KR"        },
-    {N_("Nordic (ISO-8859-10)"),              "ISO-8859-10"   },
-    {N_("South European (ISO-8859-3)"),       "ISO-8859-3"    },
-    {N_("Thai (TIS-620)"),                    "TIS-620"       },
-    {N_("Turkish (IBM-857)"),                 "IBM857"        },
-    {N_("Turkish (ISO-8859-9)"),              "ISO-8859-9"    },
-    {N_("Turkish (Windows-1254)"),            "windows-1254"  },
-    {N_("Unicode (UTF-7)"),                   "UTF-7"         },
-    {N_("Unicode (UTF-8)"),                   "UTF-8"         },
-    {N_("Unicode (UTF-16BE)"),                "UTF-16BE"      },
-    {N_("Unicode (UTF-16LE)"),                "UTF-16LE"      },
-    {N_("Unicode (UTF-32BE)"),                "UTF-32BE"      },
-    {N_("Unicode (UTF-32LE)"),                "UTF-32LE"      },
-    {N_("Vietnamese (VISCII)"),               "VISCII"        },
-    {N_("Vietnamese (Windows-1258)"),         "windows-1258"  },
-    {N_("Visual Hebrew (ISO-8859-8)"),        "ISO-8859-8"    },
-    {N_("Western (IBM-850)"),                 "IBM850"        },
-    {N_("Western (ISO-8859-1)"),              "ISO-8859-1"    },
-    {N_("Western (ISO-8859-15)"),             "ISO-8859-15"   },
-    {N_("Western (Windows-1252)"),            "windows-1252"  }
-
-    /*
-     * From this point, character sets aren't supported by iconv
-     */
-/*    {N_("Arabic (IBM-864-I)"),                "IBM864i"              },
-    {N_("Arabic (ISO-8859-6-E)"),             "ISO-8859-6-E"         },
-    {N_("Arabic (ISO-8859-6-I)"),             "ISO-8859-6-I"         },
-    {N_("Arabic (MacArabic)"),                "x-mac-arabic"         },
-    {N_("Armenian (ARMSCII-8)"),              "armscii-8"            },
-    {N_("Central European (MacCE)"),          "x-mac-ce"             },
-    {N_("Chinese Simplified (GBK)"),          "x-gbk"                },
-    {N_("Chinese Simplified (HZ)"),           "HZ-GB-2312"           },
-    {N_("Chinese Traditional (EUC-TW)"),      "x-euc-tw"             },
-    {N_("Croatian (MacCroatian)"),            "x-mac-croatian"       },
-    {N_("Cyrillic (MacCyrillic)"),            "x-mac-cyrillic"       },
-    {N_("Cyrillic/Ukrainian (MacUkrainian)"), "x-mac-ukrainian"      },
-    {N_("Farsi (MacFarsi)"),                  "x-mac-farsi"},
-    {N_("Greek (MacGreek)"),                  "x-mac-greek"          },
-    {N_("Gujarati (MacGujarati)"),            "x-mac-gujarati"       },
-    {N_("Gurmukhi (MacGurmukhi)"),            "x-mac-gurmukhi"       },
-    {N_("Hebrew (ISO-8859-8-E)"),             "ISO-8859-8-E"         },
-    {N_("Hebrew (ISO-8859-8-I)"),             "ISO-8859-8-I"         },
-    {N_("Hebrew (MacHebrew)"),                "x-mac-hebrew"         },
-    {N_("Hindi (MacDevanagari)"),             "x-mac-devanagari"     },
-    {N_("Icelandic (MacIcelandic)"),          "x-mac-icelandic"      },
-    {N_("Korean (JOHAB)"),                    "x-johab"              },
-    {N_("Korean (UHC)"),                      "x-windows-949"        },
-    {N_("Romanian (MacRomanian)"),            "x-mac-romanian"       },
-    {N_("Turkish (MacTurkish)"),              "x-mac-turkish"        },
-    {N_("User Defined"),                      "x-user-defined"       },
-    {N_("Vietnamese (TCVN)"),                 "x-viet-tcvn5712"      },
-    {N_("Vietnamese (VPS)"),                  "x-viet-vps"           },
-    {N_("Western (MacRoman)"),                "x-mac-roman"          },
-    // charsets whithout posibly translatable names
-    {"T61.8bit",                              "T61.8bit"             },
-    {"x-imap4-modified-utf7",                 "x-imap4-modified-utf7"},
-    {"x-u-escaped",                           "x-u-escaped"          },
-    {"windows-936",                           "windows-936"          }
-*/
+const CharsetInfo charset_trans_array[] = {
+       {N_("Arabic (IBM-864)"),                  "IBM864"        },
+       {N_("Arabic (ISO-8859-6)"),               "ISO-8859-6"    },
+       {N_("Arabic (Windows-1256)"),             "windows-1256"  },
+       {N_("Baltic (ISO-8859-13)"),              "ISO-8859-13"   },
+       {N_("Baltic (ISO-8859-4)"),               "ISO-8859-4"    },
+       {N_("Baltic (Windows-1257)"),             "windows-1257"  },
+       {N_("Celtic (ISO-8859-14)"),              "ISO-8859-14"   },
+       {N_("Central European (IBM-852)"),        "IBM852"        },
+       {N_("Central European (ISO-8859-2)"),     "ISO-8859-2"    },
+       {N_("Central European (Windows-1250)"),   "windows-1250"  },
+       {N_("Chinese Simplified (GB18030)"),      "gb18030"       },
+       {N_("Chinese Simplified (GB2312)"),       "GB2312"        },
+       {N_("Chinese Traditional (Big5)"),        "Big5"          },
+       {N_("Chinese Traditional (Big5-HKSCS)"),  "Big5-HKSCS"    },
+       {N_("Cyrillic (IBM-855)"),                "IBM855"        },
+       {N_("Cyrillic (ISO-8859-5)"),             "ISO-8859-5"    },
+       {N_("Cyrillic (ISO-IR-111)"),             "ISO-IR-111"    },
+       {N_("Cyrillic (KOI8-R)"),                 "KOI8-R"        },
+       {N_("Cyrillic (Windows-1251)"),           "windows-1251"  },
+       {N_("Cyrillic/Russian (CP-866)"),         "IBM866"        },
+       {N_("Cyrillic/Ukrainian (KOI8-U)"),       "KOI8-U"        },
+       {N_("English (US-ASCII)"),                "us-ascii"      },
+       {N_("Greek (ISO-8859-7)"),                "ISO-8859-7"    },
+       {N_("Greek (Windows-1253)"),              "windows-1253"  },
+       {N_("Hebrew (IBM-862)"),                  "IBM862"        },
+       {N_("Hebrew (Windows-1255)"),             "windows-1255"  },
+       {N_("Japanese (EUC-JP)"),                 "EUC-JP"        },
+       {N_("Japanese (ISO-2022-JP)"),            "ISO-2022-JP"   },
+       {N_("Japanese (Shift_JIS)"),              "Shift_JIS"     },
+       {N_("Korean (EUC-KR)"),                   "EUC-KR"        },
+       {N_("Nordic (ISO-8859-10)"),              "ISO-8859-10"   },
+       {N_("South European (ISO-8859-3)"),       "ISO-8859-3"    },
+       {N_("Thai (TIS-620)"),                    "TIS-620"       },
+       {N_("Turkish (IBM-857)"),                 "IBM857"        },
+       {N_("Turkish (ISO-8859-9)"),              "ISO-8859-9"    },
+       {N_("Turkish (Windows-1254)"),            "windows-1254"  },
+       {N_("Unicode (UTF-7)"),                   "UTF-7"         },
+       {N_("Unicode (UTF-8)"),                   "UTF-8"         },
+       {N_("Unicode (UTF-16BE)"),                "UTF-16BE"      },
+       {N_("Unicode (UTF-16LE)"),                "UTF-16LE"      },
+       {N_("Unicode (UTF-32BE)"),                "UTF-32BE"      },
+       {N_("Unicode (UTF-32LE)"),                "UTF-32LE"      },
+       {N_("Vietnamese (VISCII)"),               "VISCII"        },
+       {N_("Vietnamese (Windows-1258)"),         "windows-1258"  },
+       {N_("Visual Hebrew (ISO-8859-8)"),        "ISO-8859-8"    },
+       {N_("Western (IBM-850)"),                 "IBM850"        },
+       {N_("Western (ISO-8859-1)"),              "ISO-8859-1"    },
+       {N_("Western (ISO-8859-15)"),             "ISO-8859-15"   },
+       {N_("Western (Windows-1252)"),            "windows-1252"  }
+
+       /*
+        * From this point, character sets aren't supported by iconv
+        */
+#if 0
+       {N_("Arabic (IBM-864-I)"),                "IBM864i"              },
+       {N_("Arabic (ISO-8859-6-E)"),             "ISO-8859-6-E"         },
+       {N_("Arabic (ISO-8859-6-I)"),             "ISO-8859-6-I"         },
+       {N_("Arabic (MacArabic)"),                "x-mac-arabic"         },
+       {N_("Armenian (ARMSCII-8)"),              "armscii-8"            },
+       {N_("Central European (MacCE)"),          "x-mac-ce"             },
+       {N_("Chinese Simplified (GBK)"),          "x-gbk"                },
+       {N_("Chinese Simplified (HZ)"),           "HZ-GB-2312"           },
+       {N_("Chinese Traditional (EUC-TW)"),      "x-euc-tw"             },
+       {N_("Croatian (MacCroatian)"),            "x-mac-croatian"       },
+       {N_("Cyrillic (MacCyrillic)"),            "x-mac-cyrillic"       },
+       {N_("Cyrillic/Ukrainian (MacUkrainian)"), "x-mac-ukrainian"      },
+       {N_("Farsi (MacFarsi)"),                  "x-mac-farsi"},
+       {N_("Greek (MacGreek)"),                  "x-mac-greek"          },
+       {N_("Gujarati (MacGujarati)"),            "x-mac-gujarati"       },
+       {N_("Gurmukhi (MacGurmukhi)"),            "x-mac-gurmukhi"       },
+       {N_("Hebrew (ISO-8859-8-E)"),             "ISO-8859-8-E"         },
+       {N_("Hebrew (ISO-8859-8-I)"),             "ISO-8859-8-I"         },
+       {N_("Hebrew (MacHebrew)"),                "x-mac-hebrew"         },
+       {N_("Hindi (MacDevanagari)"),             "x-mac-devanagari"     },
+       {N_("Icelandic (MacIcelandic)"),          "x-mac-icelandic"      },
+       {N_("Korean (JOHAB)"),                    "x-johab"              },
+       {N_("Korean (UHC)"),                      "x-windows-949"        },
+       {N_("Romanian (MacRomanian)"),            "x-mac-romanian"       },
+       {N_("Turkish (MacTurkish)"),              "x-mac-turkish"        },
+       {N_("User Defined"),                      "x-user-defined"       },
+       {N_("Vietnamese (TCVN)"),                 "x-viet-tcvn5712"      },
+       {N_("Vietnamese (VPS)"),                  "x-viet-vps"           },
+       {N_("Western (MacRoman)"),                "x-mac-roman"          },
+       /* charsets whithout posibly translatable names */
+       {"T61.8bit",                              "T61.8bit"             },
+       {"x-imap4-modified-utf7",                 "x-imap4-modified-utf7"},
+       {"x-u-escaped",                           "x-u-escaped"          },
+       {"windows-936",                           "windows-936"          }
+#endif
 };
 
 /*************
  * Functions *
  *************/
 
-char* get_current_charset (void)
+/*
+ * Commons conversion functions
+ */
+char *convert_from_file_to_user(const char *string)
 {
-    char *charset = getenv("CHARSET");
-
-#ifdef HAVE_LANGINFO_CODESET
-    if (!charset)
-        charset = nl_langinfo(CODESET);
-#endif
-    if (!charset)
-        charset = "ISO-8859-1";
-
-    return charset;
+       return FLAC_plugin__charset_convert_string(string, flac_cfg.file_char_set, flac_cfg.user_char_set);
 }
 
-
-#ifdef HAVE_ICONV
-static char* convert_string (const char *string, char *from, char *to)
+char *convert_from_user_to_file(const char *string)
 {
-    size_t outleft, outsize, length;
-    iconv_t cd;
-    char *out, *outptr;
-    const char *input = string;
-
-    if (!string)
-        return NULL;
-
-    length = strlen(string);
-
-    /*  g_message("converting %s from %s to %s", string, from, to); */
-    if ((cd = iconv_open(to, from)) == (iconv_t)-1)
-    {
-        g_warning("convert_string(): Conversion not supported. Charsets: %s -> %s", from, to);
-        return g_strdup(string);
-    }
-
-    /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
-    /* + 1 for nul in case len == 1 */
-    outsize = ((length + 3) & ~3) + 1;
-    out = g_malloc(outsize);
-    outleft = outsize - 1;
-    outptr = out;
-
- retry:
-    if (iconv(cd, &input, &length, &outptr, &outleft) == -1)
-    {
-        int used;
-        switch (errno)
-        {
-            case E2BIG:
-                used = outptr - out;
-                outsize = (outsize - 1) * 2 + 1;
-                out = g_realloc(out, outsize);
-                outptr = out + used;
-                outleft = outsize - 1 - used;
-                goto retry;
-            case EINVAL:
-                break;
-            case EILSEQ:
-                /* Invalid sequence, try to get the
-                                   rest of the string */
-                input++;
-                length = strlen(input);
-                goto retry;
-            default:
-                g_warning("convert_string(): Conversion failed. Inputstring: %s; Error: %s", string, strerror(errno));
-                break;
-        }
-    }
-    *outptr = '\0';
-
-    iconv_close(cd);
-    return out;
+       return FLAC_plugin__charset_convert_string(string, flac_cfg.user_char_set, flac_cfg.file_char_set);
 }
-#else
-static char* convert_string (const char *string, char *from, char *to)
-{
-       (void)from, (void)to;
-    if (!string)
-        return NULL;
-    return g_strdup(string);
-}
-#endif
 
-/*
- * Commons conversion functions
- */
-char* convert_from_file_to_user (const char *string)
+void convert_from_file_to_user_in_place(char **string)
 {
-    char *file_charset = flac_cfg.file_char_set;
-    char *user_charset = flac_cfg.user_char_set;
+       if(0 != *string) {
+               char *tmp;
 
-    return convert_string(string,file_charset,user_charset);
+               tmp = convert_from_file_to_user(*string);
+               free(*string);
+               *string = tmp;
+       }
 }
 
-char* convert_from_user_to_file (const char *string)
+void convert_from_user_to_file_in_place(char **string)
 {
-    char *file_charset = flac_cfg.file_char_set;
-    char *user_charset = flac_cfg.user_char_set;
+       if(0 != *string) {
+               char *tmp;
 
-    return convert_string(string,user_charset,file_charset);
+               tmp = convert_from_user_to_file(*string);
+               free(*string);
+               *string = tmp;
+       }
 }
 
-
 GList *Charset_Create_List (void)
 {
-    GList *list = NULL;
-    guint i;
+       GList *list = NULL;
+       guint i;
 
-    for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
-        list = g_list_append(list,_(charset_trans_array[i].charset_title));
-    return list;
+       for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+               list = g_list_append(list,_(charset_trans_array[i].charset_title));
+       return list;
 }
 
 
@@ -257,13 +183,13 @@ GList *Charset_Create_List (void)
  */
 gchar *Charset_Get_Name_From_Title (gchar *charset_title)
 {
-    guint i;
+       guint i;
 
-    if (charset_title)
-        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
-            if ( strcasecmp(_(charset_title),_(charset_trans_array[i].charset_title)) == 0 )
-                return charset_trans_array[i].charset_name;
-    return "";
+       if (charset_title)
+               for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+                       if ( strcasecmp(_(charset_title),_(charset_trans_array[i].charset_title)) == 0 )
+                               return charset_trans_array[i].charset_name;
+       return "";
 }
 
 
@@ -272,37 +198,11 @@ gchar *Charset_Get_Name_From_Title (gchar *charset_title)
  */
 gchar *Charset_Get_Title_From_Name (gchar *charset_name)
 {
-    guint i;
-
-    if (charset_name)
-        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
-            if ( strcasecmp(charset_name,charset_trans_array[i].charset_name) == 0 )
-                return _(charset_trans_array[i].charset_title);
-    return "";
-}
-
-
-
-/*
- * Test if the conversion is supported between two character sets ('from' and 'to)
- */
-#ifdef HAVE_ICONV
-gboolean test_conversion_charset (char *from, char *to)
-{
-    iconv_t cd;
+       guint i;
 
-    if ((cd=iconv_open(to,from)) == (iconv_t)-1)
-    {
-        /* Conversion not supported */
-        return FALSE;
-    }
-    iconv_close(cd);
-    return TRUE;
-}
-#else
-gboolean test_conversion_charset (char *from, char *to)
-{
-       (void)from, (void)to;
-    return TRUE;
+       if (charset_name)
+               for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+                       if ( strcasecmp(charset_name,charset_trans_array[i].charset_name) == 0 )
+                               return _(charset_trans_array[i].charset_title);
+       return "";
 }
-#endif
index 0a65dae..14e74a7 100644 (file)
@@ -41,17 +41,14 @@ extern const CharsetInfo charset_trans_array[];
  * Prototypes *
  **************/
 
-gchar* get_current_charset (void);
-
-gchar* convert_from_file_to_user (const gchar *string);
-gchar* convert_from_user_to_file (const gchar *string);
+char *convert_from_file_to_user(const char *string);
+char *convert_from_user_to_file(const char *string);
+void convert_from_file_to_user_in_place(char **string);
+void convert_from_user_to_file_in_place(char **string);
 
 GList *Charset_Create_List (void);
 gchar *Charset_Get_Name_From_Title (gchar *charset_title);
 gchar *Charset_Get_Title_From_Name (gchar *charset_name);
 
-gboolean test_conversion_charset (char *from, char *to);
-
-
 #endif /* __CHARSET_H__ */
 
index 09d810d..e9ecb42 100644 (file)
 #include <xmms/titlestring.h>
 
 #include "FLAC/metadata.h"
-
-#include "mylocale.h"
-#include "configure.h"
-
-#ifdef FLAC__HAS_ID3LIB
-#include <id3.h>
-#include "id3_tag.h"
-
-#else
+#include "plugin_common/id3v1.h"
+#include "plugin_common/id3v2.h"
 #include "charset.h"
-#include "genres.h"
-
-typedef struct id3v1tag_t {
-       char tag[3]; /* always "TAG": defines ID3v1 tag 128 bytes before EOF */
-       char title[30];
-       char artist[30];
-       char album[30];
-       char year[4];
-       union {
-               struct {
-                       char comment[30];
-               } v1_0;
-               struct {
-                       char comment[28];
-                       char __zero;
-                       unsigned char track;
-               } v1_1;
-       } u;
-       unsigned char genre;
-} id3v1_struct;
-
-typedef struct id3tag_t {
-       char title[64];
-       char artist[64];
-       char album[64];
-       char comment[256];
-       char genre[256];
-       char year[16];
-       char track[16];
-} id3v2_struct;
+#include "configure.h"
 
-static gboolean local__get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *tag);
-static void local__id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2);
-static const char *local__get_id3_genre(unsigned char genre_code);
-#endif /* FLAC__HAS_ID3LIB */
+static FLAC__bool local__get_id3v1_tag_as_canonical(const char *filename, FLAC_Plugin__CanonicalTag *tag);
 
-static gchar *local__extname(const char *filename);
+static char *local__extname(const char *filename);
 static char* local__getstr(char* str);
 static int local__getnum(char* str);
 
 static int local__vcentry_matches(const char *field_name, const FLAC__StreamMetadata_VorbisComment_Entry *entry);
-static void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, gchar **dest);
+static void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, char **dest);
 
 /*
  * Function flac_format_song_title (tag, filename)
@@ -89,28 +50,21 @@ static void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_
  *    return it.  The title must be subsequently freed using g_free().
  *
  */
-gchar *flac_format_song_title(gchar * filename)
+char *flac_format_song_title(char *filename)
 {
-       gchar *ret = NULL;
+       char *ret = NULL;
        TitleInput *input = NULL;
-       gboolean rc;
-#ifdef FLAC__HAS_ID3LIB
-       File_Tag tag;
-#else
-       id3v2_struct tag;
-#endif
-       int got_vorbis_comments = 0;
+       FLAC_Plugin__CanonicalTag tag, id3v1_tag, id3v2_tag;
 
-#ifdef FLAC__HAS_ID3LIB
-       Initialize_File_Tag_Item (&tag);
-#else
-       memset(&tag, 0, sizeof(tag));
-#endif
+       FLAC_plugin__canonical_tag_init(&tag);
+       FLAC_plugin__canonical_tag_init(&id3v1_tag);
+       FLAC_plugin__canonical_tag_init(&id3v2_tag);
 
        /* first, parse vorbis comments if they exist */
        {
                FLAC__Metadata_SimpleIterator *iterator = FLAC__metadata_simple_iterator_new();
                if(0 != iterator) {
+                       FLAC__bool got_vorbis_comments = false;
                        do {
                                if(FLAC__metadata_simple_iterator_get_block_type(iterator) == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
                                        FLAC__StreamMetadata *block = FLAC__metadata_simple_iterator_get_block(iterator);
@@ -118,26 +72,23 @@ gchar *flac_format_song_title(gchar * filename)
                                                unsigned i;
                                                const FLAC__StreamMetadata_VorbisComment *vc = &block->data.vorbis_comment;
                                                for(i = 0; i < vc->num_comments; i++) {
-#if 0
-@@@@@
                                                        if(local__vcentry_matches("artist", &vc->comments[i]))
-                                                               local__vcentry_parse_value(&vc->comments[i], &tag.artist);
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.composer);
                                                        else if(local__vcentry_matches("performer", &vc->comments[i]))
-                                                               local__vcentry_parse_value(&vc->comments[i], &tag.artist);
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.performer);
                                                        else if(local__vcentry_matches("album", &vc->comments[i]))
                                                                local__vcentry_parse_value(&vc->comments[i], &tag.album);
                                                        else if(local__vcentry_matches("title", &vc->comments[i]))
                                                                local__vcentry_parse_value(&vc->comments[i], &tag.title);
                                                        else if(local__vcentry_matches("tracknumber", &vc->comments[i]))
-                                                               local__vcentry_parse_value(&vc->comments[i], &tag.track);
+                                                               local__vcentry_parse_value(&vc->comments[i], &tag.track_number);
                                                        else if(local__vcentry_matches("genre", &vc->comments[i]))
                                                                local__vcentry_parse_value(&vc->comments[i], &tag.genre);
                                                        else if(local__vcentry_matches("description", &vc->comments[i]))
                                                                local__vcentry_parse_value(&vc->comments[i], &tag.comment);
-#endif
                                                }
                                                FLAC__metadata_object_delete(block);
-                                               got_vorbis_comments = 1;
+                                               got_vorbis_comments = true;
                                        }
                                }
                        } while (!got_vorbis_comments && FLAC__metadata_simple_iterator_next(iterator));
@@ -145,34 +96,43 @@ gchar *flac_format_song_title(gchar * filename)
                }
        }
 
-       if(!got_vorbis_comments) {
-#ifdef FLAC__HAS_ID3LIB
-               rc = Id3tag_Read_File_Tag(filename, &tag);
-#else
-               rc = local__get_id3v1_tag_as_v2_(filename, &tag);
-#endif
-       }
+       (void)FLAC_plugin__id3v2_tag_get(filename, &id3v2_tag);
+       (void)local__get_id3v1_tag_as_canonical(filename, &id3v1_tag);
 
        XMMS_NEW_TITLEINPUT(input);
 
-       if (got_vorbis_comments || rc)
-       {
-               input->performer = local__getstr(tag.artist);
-               input->album_name = local__getstr(tag.album);
-               input->track_name = local__getstr(tag.title);
-               input->track_number = local__getnum(tag.track);
-               input->year = local__getnum(tag.year);
-               input->genre = local__getstr(tag.genre);
-               input->comment = local__getstr(tag.comment);
+       /* merge tags, preferring, in order: vorbis comments, id3v2, id3v1 */
+       FLAC_plugin__canonical_tag_merge(&tag, &id3v2_tag);
+       FLAC_plugin__canonical_tag_merge(&tag, &id3v1_tag);
+
+       if(flac_cfg.convert_char_set) {
+               convert_from_file_to_user_in_place(&tag.title);
+               convert_from_file_to_user_in_place(&tag.composer);
+               convert_from_file_to_user_in_place(&tag.performer);
+               convert_from_file_to_user_in_place(&tag.album);
+               convert_from_file_to_user_in_place(&tag.year_recorded);
+               convert_from_file_to_user_in_place(&tag.year_performed);
+               convert_from_file_to_user_in_place(&tag.track_number);
+               convert_from_file_to_user_in_place(&tag.tracks_in_album);
+               convert_from_file_to_user_in_place(&tag.genre);
+               convert_from_file_to_user_in_place(&tag.comment);
        }
+
+       input->performer = local__getstr(tag.performer);
+       input->album_name = local__getstr(tag.album);
+       input->track_name = local__getstr(tag.title);
+       input->track_number = local__getnum(tag.track_number);
+       input->year = local__getnum(tag.year_performed);
+       input->genre = local__getstr(tag.genre);
+       input->comment = local__getstr(tag.comment);
+
        input->file_name = g_basename(filename);
        input->file_path = filename;
        input->file_ext = local__extname(filename);
        ret = xmms_get_titlestring(flac_cfg.tag_override ? flac_cfg.tag_format : xmms_get_gentitle_format(), input);
        g_free(input);
 
-       if (!ret)
-       {
+       if (!ret) {
                /*
                 * Format according to filename.
                 */
@@ -181,116 +141,22 @@ gchar *flac_format_song_title(gchar * filename)
                        *(local__extname(ret) - 1) = '\0';      /* removes period */
        }
 
-#ifdef FLAC__HAS_ID3LIB
-       Free_File_Tag_Item  (&tag);
-#endif
+       FLAC_plugin__canonical_tag_clear(&tag);
+       FLAC_plugin__canonical_tag_clear(&id3v1_tag);
+       FLAC_plugin__canonical_tag_clear(&id3v2_tag);
        return ret;
 }
 
-#ifndef FLAC__HAS_ID3LIB
-/*
- * Function get_idv2_tag_(filename, ID3v2tag)
- *
- *    Get ID3v2 tag from file.
- *
- */
-gboolean local__get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2tag)
+FLAC__bool local__get_id3v1_tag_as_canonical(const char *filename, FLAC_Plugin__CanonicalTag *tag)
 {
-       FILE *file;
-       id3v1_struct id3v1tag;
-
-       memset(id3v2tag, 0, sizeof(id3v2_struct));
-
-       if ((file = fopen(filename, "rb")) != 0)
-       {
-               if ((fseek(file, -1 * sizeof (id3v1tag), SEEK_END) == 0) &&
-                   (fread(&id3v1tag, 1, sizeof (id3v1tag), file) == sizeof (id3v1tag)) &&
-                   (strncmp(id3v1tag.tag, "TAG", 3) == 0))
-               {
-                       local__id3v1_to_id3v2(&id3v1tag, id3v2tag);
-
-                       if (flac_cfg.convert_char_set)
-                       {
-                               gchar *string;
-
-                               string = convert_from_file_to_user(id3v2tag->title);
-                               strcpy(id3v2tag->title, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->artist);
-                               strcpy(id3v2tag->artist, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->album);
-                               strcpy(id3v2tag->album, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->comment);
-                               strcpy(id3v2tag->comment, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->genre);
-                               strcpy(id3v2tag->genre, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->year);
-                               strcpy(id3v2tag->year, string);
-                               g_free(string);
-
-                               string = convert_from_file_to_user(id3v2tag->track);
-                               strcpy(id3v2tag->track, string);
-                               g_free(string);
-                       }
-               }
+       FLAC_Plugin__Id3v1_Tag id3v1_tag;
 
+       if(FLAC_plugin__id3v1_tag_get(filename, &id3v1_tag)) {
+               FLAC_plugin__canonical_tag_convert_from_id3v1(tag, &id3v1_tag);
+               return true;
        }
-       else
-       {
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-/*
- * Function local__id3v1_to_id3v2 (v1, v2)
- *
- *    Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
- *
- */
-void local__id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
-{
-       memset(v2,0,sizeof(id3v2_struct));
-       strncpy(v2->title, v1->title, 30);
-       strncpy(v2->artist, v1->artist, 30);
-       strncpy(v2->album, v1->album, 30);
-       strncpy(v2->comment, v1->u.v1_0.comment, 30);
-       strncpy(v2->genre, local__get_id3_genre(v1->genre), sizeof (v2->genre));
-       strncpy(v2->year, v1->year, 4);
-
-       /* Check for v1.1 tags. */
-       if (v1->u.v1_1.__zero == 0)
-               sprintf(v2->track, "%d", v1->u.v1_1.track);
-       else
-               strcpy(v2->track, "0");
-
-       g_strstrip(v2->title);
-       g_strstrip(v2->artist);
-       g_strstrip(v2->album);
-       g_strstrip(v2->comment);
-       g_strstrip(v2->genre);
-       g_strstrip(v2->year);
-       g_strstrip(v2->track);
-}
-
-const char *local__get_id3_genre(unsigned char genre_code)
-{
-       if (genre_code < GENRE_MAX)
-               return gettext(id3_genres[genre_code]);
-
-       return "";
+       return false;
 }
-#endif /* ifndef FLAC__HAS_ID3LIB */
 
 /*
  * Function local__extname (filename)
@@ -299,9 +165,9 @@ const char *local__get_id3_genre(unsigned char genre_code)
  *    filename has no extension.
  *
  */
-gchar *local__extname(const char *filename)
+char *local__extname(const char *filename)
 {
-       gchar *ext = strrchr(filename, '.');
+       char *ext = strrchr(filename, '.');
 
        if (ext != NULL)
                ++ext;
@@ -330,7 +196,7 @@ int local__vcentry_matches(const char *field_name, const FLAC__StreamMetadata_Vo
        return (0 != eq && (unsigned)(eq-entry->entry) == field_name_length && 0 == strncasecmp(field_name, entry->entry, field_name_length));
 }
 
-void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, gchar **dest)
+void local__vcentry_parse_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, char **dest)
 {
        const FLAC__byte *eq = memchr(entry->entry, '=', entry->length);