Commit aad7aa72 authored by Josh Coalson's avatar Josh Coalson
Browse files

rewrite to use new functionality in plugin_common

parent d426aee0
......@@ -25,16 +25,9 @@
#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"
......@@ -43,212 +36,145 @@
****************/
#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
......@@ -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__ */
......@@ -29,58 +29,19 @@
#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.