changeset 957:12f57026da8f trunk

[svn] First attempt at introducing taglib here. Very rough, needs polishing. Please wear protective goggles before opening the file dialog. It *will* explode.
author chainsaw
date Sun, 23 Apr 2006 15:50:33 -0700
parents 6bd91d768233
children ff0cc786ebeb
files Plugins/Input/mpg123/Makefile.in Plugins/Input/mpg123/common.c Plugins/Input/mpg123/fileinfo.c Plugins/Input/mpg123/id3.c Plugins/Input/mpg123/id3_frame.c Plugins/Input/mpg123/id3_frame_content.c Plugins/Input/mpg123/id3_frame_text.c Plugins/Input/mpg123/id3_frame_url.c Plugins/Input/mpg123/id3_header.h Plugins/Input/mpg123/id3_tag.c Plugins/Input/mpg123/mpg123.c Plugins/Input/mpg123/mpg123.h
diffstat 12 files changed, 98 insertions(+), 3258 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/mpg123/Makefile.in	Sun Apr 23 15:11:43 2006 -0700
+++ b/Plugins/Input/mpg123/Makefile.in	Sun Apr 23 15:50:33 2006 -0700
@@ -9,12 +9,10 @@
 	decode_2to1.c decode_4to1.c \
 	layer1.c layer2.c layer3.c \
 	tabinit.c equalizer.c http.c \
-	dxhead.c \
-	id3.c id3_frame.c id3_frame_content.c id3_frame_text.c \
-	id3_frame_url.c id3_tag.c decode.c dct64.c
+	dxhead.c decode.c dct64.c
 
 OBJECTS = ${SOURCES:.c=.o}
 
-CFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../..
+CFLAGS += -fPIC -DPIC $(GTK_CFLAGS) $(TAGLIB_CFLAGS) $(ARCH_DEFINES) -I../../../intl -I../../..
 
-LIBADD = $(GTK_LIBS) $(ID3LIBS)
+LIBADD = -ltag_c $(GTK_LIBS) $(ID3LIBS)
--- a/Plugins/Input/mpg123/common.c	Sun Apr 23 15:11:43 2006 -0700
+++ b/Plugins/Input/mpg123/common.c	Sun Apr 23 15:50:33 2006 -0700
@@ -8,8 +8,6 @@
 #include <fcntl.h>
 
 #include "mpg123.h"
-#include "xmms-id3.h"
-#include "id3_header.h"
 
 const int tabsel_123[2][3][16] = {
     {{0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416,
@@ -213,84 +211,6 @@
     mpg123_info->output_audio = FALSE;
 }
 
-/*
- * Function read_id3v2_tag (head)
- *
- *    Read ID3v2 tag from stream.  Return TRUE upon success, or FALSE if
- *    an error occurred.
- *
- */
-static gboolean
-read_id3v2_tag(unsigned long head)
-{
-    guchar *id3buf;
-    gsize hdrsize;
-    struct id3_tag *id3d;
-    struct id3tag_t tag;
-    guchar buf[7];
-
-    buf[0] = head & 0xff;
-    /*
-     * Read ID3tag header.
-     */
-    if (fullread(filept, buf + 1, 6) != 6)
-        return FALSE;
-
-    hdrsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]);
-
-    /*
-     * A invalid header could fool us into requesting insane
-     * amounts of memory.  Make sure the header size is
-     * reasonable.
-     */
-    if ((mpg123_info->filesize && hdrsize > mpg123_info->filesize) ||
-        (!mpg123_info->filesize && hdrsize > 1000000))
-        return FALSE;
-
-    if (mpg123_cfg.disable_id3v2) {
-        guint8 *tmp = g_malloc(hdrsize);
-        gboolean ret;
-        ret = ((gsize)fullread(filept, tmp, hdrsize) == hdrsize);
-        g_free(tmp);
-        return ret;
-    }
-
-    id3buf = g_malloc(hdrsize + ID3_TAGHDR_SIZE + 3);
-    memcpy(id3buf, "ID3", 3);
-    memcpy(id3buf + 3, buf, ID3_TAGHDR_SIZE);
-
-    /*
-     * Read ID3tag body.
-     */
-    if ((gsize)fullread(filept, id3buf + ID3_TAGHDR_SIZE + 3, hdrsize) != hdrsize) {
-        g_free(id3buf);
-        return FALSE;
-    }
-
-    /*
-     * Get info from tag.
-     */
-    if ((id3d = id3_open_mem(id3buf, 0)) != NULL) {
-        mpg123_get_id3v2(id3d, &tag);
-        if (!mpg123_info->first_frame) {
-            char *songname = mpg123_title;
-            mpg123_title = mpg123_format_song_title(&tag, mpg123_filename);
-            mpg123_ip.set_info(mpg123_title, mpg123_length,
-                               mpg123_bitrate * 1000,
-                               mpg123_frequency, mpg123_stereo);
-            if (songname)
-                g_free(songname);
-        }
-        else {
-            mpg123_title = mpg123_format_song_title(&tag, mpg123_filename);
-        }
-        id3_close(id3d);
-    }
-    g_free(id3buf);
-
-    return TRUE;
-}
-
 int
 mpg123_head_check(unsigned long head)
 {
@@ -333,7 +253,6 @@
             try++;
             if ((newhead & 0xffffff00) ==
                 ('I' << 24) + ('D' << 16) + ('3' << 8)) {
-                read_id3v2_tag(newhead);
                 if (!stream_head_read(&newhead))
                     return FALSE;
             }
--- a/Plugins/Input/mpg123/fileinfo.c	Sun Apr 23 15:11:43 2006 -0700
+++ b/Plugins/Input/mpg123/fileinfo.c	Sun Apr 23 15:50:33 2006 -0700
@@ -21,9 +21,7 @@
 
 #include "mpg123.h"
 
-#ifdef HAVE_ID3LIB
-# include <id3.h>
-#endif
+#include <tag_c.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -39,9 +37,9 @@
 #include <errno.h>
 
 #include "audacious/util.h"
-#include <libaudacious/util.h>
-#include <libaudacious/vfs.h>
-#include <libaudacious/xentry.h>
+#include "libaudacious/util.h"
+#include "libaudacious/vfs.h"
+#include "libaudacious/xentry.h"
 
 #include "mp3.xpm"
 
@@ -50,9 +48,6 @@
 static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry,
     *tracknum_entry, *comment_entry;
 static GtkWidget *genre_combo;
-#ifdef HAVE_ID3LIB
-static GtkWidget * totaltracks_entry;
-#endif
 static GtkWidget *mpeg_level, *mpeg_bitrate, *mpeg_samplerate, *mpeg_flags,
     *mpeg_error, *mpeg_copy, *mpeg_orig, *mpeg_emph, *mpeg_frames,
     *mpeg_filesize;
@@ -66,16 +61,11 @@
 GtkWidget *bbox;
 GtkWidget *remove_id3, *cancel, *save;
 GtkWidget *boxx;
-#if 0
-GtkWidget *revert;
-#endif
 
 VFSFile *fh;
-struct id3v1tag_t tag;
 const gchar *emphasis[4];
 const gchar *bool_label[2];
 
-
 static GList *genre_list = NULL;
 static gchar *current_filename = NULL;
 
@@ -86,159 +76,14 @@
 
 glong info_rate;
 
+static TagLib_File *taglib_file;
+static TagLib_Tag *taglib_tag;
+static const TagLib_AudioProperties *taglib_ap;
+
 void fill_entries(GtkWidget * w, gpointer data);
 
 #define MAX_STR_LEN 100
 
-#ifndef HAVE_ID3LIB
-
-static void
-set_entry_tag(GtkEntry * entry, gchar * tag, gint length)
-{
-    gint stripped_len;
-    gchar *text, *text_utf8;
-
-    stripped_len = mpg123_strip_spaces(tag, length);
-    text = g_strdup_printf("%-*.*s", stripped_len, stripped_len, tag);
-
-    if ((text_utf8 = str_to_utf8(text))) {
-        gtk_entry_set_text(entry, text_utf8);
-        g_free(text_utf8);
-    }
-    else {
-        gtk_entry_set_text(entry, "");
-    }
-
-    g_free(text);
-}
-
-static void
-get_entry_tag(GtkEntry * entry, gchar * tag, gint length)
-{
-    gchar *text = str_to_utf8(gtk_entry_get_text(entry));
-    memset(tag, ' ', length);
-    memcpy(tag, text, strlen(text) > length ? length : strlen(text));
-}
-
-static gint
-find_genre_id(const gchar * text)
-{
-    gint i;
-
-    for (i = 0; i < GENRE_MAX; i++) {
-        if (!strcmp(mpg123_id3_genres[i], text))
-            return i;
-    }
-    if (text[0] == '\0')
-        return 0xff;
-    return 0;
-}
-
-static void
-press_save(GtkWidget * w, gpointer data)
-{
-    gtk_button_clicked(GTK_BUTTON(save));
-}
-
-#else
-
-GtkWidget * copy_album_tags_but, * paste_album_tags_but;
-
-struct album_tags_t {
-  char * performer;
-  char * album;
-  char * year;
-  char * total_tracks;
-};
-
-struct album_tags_t album_tags = { NULL, NULL, NULL, NULL };
-
-#define FREE_AND_ZERO(x) do { g_free(x); x = NULL; } while (0)
-
-static void free_album_tags()
-{
-  FREE_AND_ZERO(album_tags.performer);
-  FREE_AND_ZERO(album_tags.album);
-  FREE_AND_ZERO(album_tags.year);
-  FREE_AND_ZERO(album_tags.total_tracks);
-}
-
-static inline char * entry_text_dup_or_null(GtkWidget * e)
-{
-  const char * text = gtk_entry_get_text(GTK_ENTRY(e));
-  if (strlen(text) > 0)
-    return g_strdup(text);
-  else
-    return NULL;
-}
-
-static inline void 
-update_paste_sensitive()
-{
-  gtk_widget_set_sensitive(GTK_WIDGET(paste_album_tags_but), 
-			   album_tags.performer ||
-			   album_tags.album ||
-			   album_tags.year ||
-			   album_tags.total_tracks);
-
-}
-
-static void validate_zeropad_tracknums()
-{
-  const char * tn_str, * tt_str, * end;
-  char buf[5];
-  int tn, tt;
-
-  tn_str = gtk_entry_get_text(GTK_ENTRY(tracknum_entry));
-  tt_str = gtk_entry_get_text(GTK_ENTRY(totaltracks_entry));
-
-  end = tt_str;
-  tt = strtol(tt_str,(char**)&end,10);
-  if (end != tt_str) {
-    sprintf(buf,"%02d",tt);
-    gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),buf);
-  } else {
-    gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),"");
-    tt = 1000; /* any tracknum is valid */
-  }
-
-  end = tn_str;
-  tn = strtol(tn_str,(char**)&end,10);
-  if (end != tn_str && tn <= tt) {
-    sprintf(buf,"%02d",tn);
-    gtk_entry_set_text(GTK_ENTRY(tracknum_entry),buf);
-  } else
-    gtk_entry_set_text(GTK_ENTRY(tracknum_entry),"");
-
-}
-
-static void 
-copy_album_tags()
-{
-  validate_zeropad_tracknums();
-  free_album_tags();
-  album_tags.performer = entry_text_dup_or_null(artist_entry);
-  album_tags.album = entry_text_dup_or_null(album_entry);
-  album_tags.year = entry_text_dup_or_null(year_entry);
-  album_tags.total_tracks = entry_text_dup_or_null(totaltracks_entry);
-  update_paste_sensitive();
-}
-
-static void 
-paste_album_tags()
-{
-  if (album_tags.performer)
-    gtk_entry_set_text(GTK_ENTRY(artist_entry),album_tags.performer);
-  if (album_tags.album)
-    gtk_entry_set_text(GTK_ENTRY(album_entry),album_tags.album);
-  if (album_tags.year)
-    gtk_entry_set_text(GTK_ENTRY(year_entry),album_tags.year);
-  if (album_tags.total_tracks)
-    gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),album_tags.total_tracks);
-}
-
-#endif
-
 static gint
 genre_comp_func(gconstpointer a, gconstpointer b)
 {
@@ -264,234 +109,35 @@
     return TRUE;
 }
 
-#ifdef HAVE_ID3LIB
-/* some helper id3(v2) functions */
-
-static void str_to_id3v2_frame(const char * str, ID3Tag * tag, ID3_FrameID frame_id)
-{
-  ID3Frame * frame = ID3Tag_FindFrameWithID(tag,frame_id);
-  ID3Field * text_field;
-  gboolean new_frame = frame?FALSE:TRUE;
-
-  if (new_frame) {
-    frame = ID3Frame_NewID(frame_id);
-  }
-
-  text_field = ID3Frame_GetField(frame,ID3FN_TEXT);
-  ID3Field_SetASCII(text_field, str);
-
-  if (new_frame) 
-    ID3Tag_AddFrame(tag,frame);
-}
-
-static void genre_combo_to_tag(GtkWidget * combo, ID3Tag * tag)
-{
-  int idx = -1, i;
-  const char * genre = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry));
-  for(i=0;i<ID3_NR_OF_V1_GENRES;i++)
-    if (!strcmp(genre,ID3_v1_genre_description[i])) {
-      idx = i; break;
-    }
-  if (idx>-1) {
-    char code[7];
-    snprintf(code,7,"(%d)",idx);
-    str_to_id3v2_frame(code,tag,ID3FID_CONTENTTYPE);
-  }  
-}
-
-static void id3v2_frame_to_entry(GtkWidget * entry,ID3Tag * tag, ID3_FrameID frame_id)
-{
-  ID3Frame * frame = ID3Tag_FindFrameWithID(tag,frame_id);
-  ID3Field * text_field;
-  if (frame) {
-  	gchar *text;
-    char buf[4096];
-    text_field = ID3Frame_GetField(frame,ID3FN_TEXT);
-    ID3Field_GetASCII(text_field,buf,4096);
-	text = str_to_utf8(buf);
-    gtk_entry_set_text(GTK_ENTRY(entry),text);
-	g_free(text);
-  } else
-    gtk_entry_set_text(GTK_ENTRY(entry),"");    
-}
-
-static void id3v2_frame_to_text_view(GtkWidget * entry,ID3Tag * tag, ID3_FrameID frame_id)
-{
-  ID3Frame * frame = ID3Tag_FindFrameWithID(tag,frame_id);
-  ID3Field * text_field;
-  if (frame) {
-    char buf[4096];
-    text_field = ID3Frame_GetField(frame,ID3FN_TEXT);
-    ID3Field_GetASCII(text_field,buf,4096);
-    gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)),buf,-1);
-  } else
-    gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)),"",-1);
-}
-
-static void id3v2_tracknum_to_entries(GtkWidget * tracknum_entry,
-				      GtkWidget * totaltracks_entry,
-				      ID3Tag * tag)
-{
-  ID3Frame * frame = ID3Tag_FindFrameWithID(tag,ID3FID_TRACKNUM);
-  ID3Field * text_field;
-  if (frame) {
-    char buf[4096];
-    char * slash;
-    text_field = ID3Frame_GetField(frame,ID3FN_TEXT);
-    ID3Field_GetASCII(text_field,buf,4096);
-    slash = strchr(buf,'/');
-    if (slash) {
-      slash[0] = 0;
-      gtk_entry_set_text(GTK_ENTRY(tracknum_entry),buf);
-      gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),slash+1);
-    } else {
-      gtk_entry_set_text(GTK_ENTRY(tracknum_entry),buf);
-      gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),"");
-    }
-  } else {
-    gtk_entry_set_text(GTK_ENTRY(tracknum_entry),"");    
-    gtk_entry_set_text(GTK_ENTRY(totaltracks_entry),"");    
-  }
-}
-
-/* 
-   if has v2 - link with v2, if not - attempt to link with v1 
-   use this only for reading - always save v2 
-*/
-size_t ID3Tag_LinkPreferV2(ID3Tag *tag, const char *fileName)
-{
-  size_t r;
-
-  r = ID3Tag_Link(tag,fileName);
-  if (ID3Tag_HasTagType(tag,ID3TT_ID3V2)) {
-    ID3Tag_Clear(tag);
-    r = ID3Tag_LinkWithFlags(tag,fileName,ID3TT_ID3V2);
-  }
-  return r;
-}
-
-#endif /* HAVE_ID3LIB */
-
-#ifdef HAVE_ID3LIB
-
 static void
 save_cb(GtkWidget * w, gpointer data)
 {
-  ID3Tag * id3tag;
-  const char * tracks_str, * trackno_str, * endptr;
-  int trackno, tracks; 
+  int result;
 
   if (str_has_prefix_nocase(current_filename, "http://"))
     return;
 
-  validate_zeropad_tracknums();
-  
-  id3tag = ID3Tag_New();
-  ID3Tag_LinkWithFlags(id3tag, current_filename, ID3TT_ID3);
-
-  str_to_id3v2_frame(gtk_entry_get_text(GTK_ENTRY(title_entry)),id3tag,ID3FID_TITLE);
-  str_to_id3v2_frame(gtk_entry_get_text(GTK_ENTRY(artist_entry)),id3tag,ID3FID_LEADARTIST);
-  str_to_id3v2_frame(gtk_entry_get_text(GTK_ENTRY(album_entry)),id3tag,ID3FID_ALBUM);
-  {
-    GtkTextIter start, end;
-    GtkTextBuffer * buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_entry));
-    gtk_text_buffer_get_start_iter(buffer,&start);
-    gtk_text_buffer_get_end_iter(buffer,&end);
-    str_to_id3v2_frame(gtk_text_buffer_get_text(buffer,&start,&end,FALSE),id3tag,ID3FID_COMMENT);
-  }
-  str_to_id3v2_frame(gtk_entry_get_text(GTK_ENTRY(year_entry)),id3tag,ID3FID_YEAR);
-
-  /* saving trackno -> may be with album tracks number */
-  trackno_str = gtk_entry_get_text(GTK_ENTRY(tracknum_entry));
-  endptr = trackno_str;
-  trackno = strtol(trackno_str,(char**)&endptr,10);
-  if (endptr != trackno_str) {
-    char buf[10];
-    tracks_str = gtk_entry_get_text(GTK_ENTRY(totaltracks_entry));
-    endptr = tracks_str;
-    tracks = strtol(tracks_str,(char**)&endptr,10);
-    if (endptr != tracks_str) 
-      snprintf(buf,10,"%02d/%02d",trackno,tracks);
-    else
-      snprintf(buf,10,"%02d",trackno);
-    str_to_id3v2_frame(buf,id3tag,ID3FID_TRACKNUM);
-  } else 
-    str_to_id3v2_frame("",id3tag,ID3FID_TRACKNUM);
-  
-
-  genre_combo_to_tag(genre_combo,id3tag);
-  gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
-
-  ID3Tag_Update(id3tag);
-
-  ID3Tag_Delete(id3tag);
-}
-
-#else /* ! HAVE_ID3LIB */
-
-static void
-save_cb(GtkWidget * widget,
-        gpointer data)
-{
-    VFSFile *file;
-    gchar *msg = NULL;
+  taglib_file = taglib_file_new(current_filename);
+  if(taglib_file) {
+    taglib_tag = taglib_file_tag(taglib_file);
+    taglib_ap = taglib_file_audioproperties(taglib_file);
+  } else return;
 
-    if (str_has_prefix_nocase(current_filename, "http://"))
-        return;
-
-    if ((file = vfs_fopen(current_filename, "r+b")) != NULL) {
-        gint tracknum;
-
-        vfs_fseek(file, -128, SEEK_END);
-        vfs_fread(&tag, 1, sizeof(struct id3v1tag_t), file);
-
-        if (g_str_has_prefix(tag.tag, "TAG"))
-            vfs_fseek(file, -128L, SEEK_END);
-        else
-            vfs_fseek(file, 0L, SEEK_END);
-
-        tag.tag[0] = 'T';
-        tag.tag[1] = 'A';
-        tag.tag[2] = 'G';
-
-        get_entry_tag(GTK_ENTRY(title_entry), tag.title, 30);
-        get_entry_tag(GTK_ENTRY(artist_entry), tag.artist, 30);
-        get_entry_tag(GTK_ENTRY(album_entry), tag.album, 30);
-        get_entry_tag(GTK_ENTRY(year_entry), tag.year, 4);
+  taglib_tag_set_title(taglib_tag, gtk_entry_get_text(GTK_ENTRY(title_entry)));
+  taglib_tag_set_artist(taglib_tag, gtk_entry_get_text(GTK_ENTRY(artist_entry)));
+  taglib_tag_set_album(taglib_tag, gtk_entry_get_text(GTK_ENTRY(album_entry)));
+  taglib_tag_set_comment(taglib_tag, gtk_entry_get_text(GTK_ENTRY(comment_entry)));
+  taglib_tag_set_year(taglib_tag, atoi(gtk_entry_get_text(GTK_ENTRY(year_entry))));
+  taglib_tag_set_track(taglib_tag, atoi(gtk_entry_get_text(GTK_ENTRY(tracknum_entry))));
+  taglib_tag_set_genre(taglib_tag, gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(genre_combo)->entry)));
+  gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
+  gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);
 
-        tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(tracknum_entry)));
-        if (tracknum > 0) {
-            get_entry_tag(GTK_ENTRY(comment_entry), tag.u.v1_1.comment, 28);
-            tag.u.v1_1.__zero = 0;
-            tag.u.v1_1.track_number = MIN(tracknum, 255);
-        }
-        else
-            get_entry_tag(GTK_ENTRY(comment_entry), tag.u.v1_0.comment, 30);
-
-        tag.genre = find_genre_id(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO
-                                                      (genre_combo)->entry)));
-        if (vfs_fwrite(&tag, 1, sizeof(tag), file) != sizeof(tag))
-            msg = g_strdup_printf(_("%s\nUnable to write to file: %s"),
-                                  _("Couldn't write tag!"), strerror(errno));
-        vfs_fclose(file);
-    }
-    else
-        msg = g_strdup_printf(_("%s\nUnable to open file: %s"),
-                              _("Couldn't write tag!"), strerror(errno));
-    if (msg) {
-        GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("Ok"),
-                                            FALSE, NULL, NULL);
-        gtk_window_set_transient_for(GTK_WINDOW(mwin), GTK_WINDOW(window));
-        g_free(msg);
-    }
-    else {
-        gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE);
-        gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE);
-    }
+  result = taglib_file_save(taglib_file);
+  taglib_file_free(taglib_file);
+  taglib_tag_free_strings();
 }
 
-#endif /* HAVE_ID3LIB */
-
 static void
 label_set_text(GtkWidget * label, gchar * str, ...)
 {
@@ -505,91 +151,42 @@
     gtk_label_set_text(GTK_LABEL(label), tempstr);
 }
 
-#ifdef HAVE_ID3LIB
-
 static void
 remove_id3_cb(GtkWidget * w, gpointer data)
 {
-  ID3Tag * id3tag;
+  int result;
 
   if (str_has_prefix_nocase(current_filename, "http://"))
     return;
   
-  id3tag = ID3Tag_New();
-  ID3Tag_LinkWithFlags(id3tag, current_filename, ID3TT_ID3);
+  taglib_file = taglib_file_new(current_filename);
+  if(taglib_file) {
+    taglib_tag = taglib_file_tag(taglib_file);
+    taglib_ap = taglib_file_audioproperties(taglib_file);
+  } else return;
 
-  ID3Tag_Strip(id3tag,ID3TT_ALL);
-  ID3Tag_Update(id3tag);
-
-  ID3Tag_Delete(id3tag);
+  taglib_tag_set_title(taglib_tag, "");
   gtk_entry_set_text(GTK_ENTRY(title_entry), "");
+  taglib_tag_set_artist(taglib_tag, "");
   gtk_entry_set_text(GTK_ENTRY(artist_entry), "");
+  taglib_tag_set_album(taglib_tag, "");
   gtk_entry_set_text(GTK_ENTRY(album_entry), "");
-  gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_entry)), "",-1);
+  taglib_tag_set_comment(taglib_tag, "");
+  gtk_entry_set_text(GTK_ENTRY(comment_entry), "");
+  taglib_tag_set_year(taglib_tag, 0);
   gtk_entry_set_text(GTK_ENTRY(year_entry), "");
-  gtk_entry_set_text(GTK_ENTRY(album_entry), "");
+  taglib_tag_set_track(taglib_tag, 0);
   gtk_entry_set_text(GTK_ENTRY(tracknum_entry), "");
-  gtk_entry_set_text(GTK_ENTRY(totaltracks_entry), "");
+  taglib_tag_set_genre(taglib_tag, "");
   gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), "");
   gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
   gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);
+
+  result = taglib_file_save(taglib_file);
+  taglib_file_free(taglib_file);
+  taglib_tag_free_strings();
 }
 
-#else
-
-static void
-remove_id3_cb(GtkWidget * w, gpointer data)
-{
-    VFSFile *file;
-    gint len;
-    struct id3v1tag_t tag;
-    gchar *msg = NULL;
-
-    if (str_has_prefix_nocase(current_filename, "http://"))
-        return;
-
-    if ((file = vfs_fopen(current_filename, "rb+")) != NULL) {
-        vfs_fseek(file, -128, SEEK_END);
-        len = vfs_ftell(file);
-
-        vfs_fread(&tag, 1, sizeof(struct id3v1tag_t), file);
-
-        if (g_str_has_prefix(tag.tag, "TAG")) {
-            if (vfs_truncate(file, len))
-                msg = g_strdup_printf(_("%s\n"
-                                        "Unable to truncate file: %s"),
-                                      _("Couldn't remove tag!"),
-                                      strerror(errno));
-        }
-        else
-            msg = strdup(_("No tag to remove!"));
-
-        vfs_fclose(file);
-    }
-    else
-        msg = g_strdup_printf(_("%s\nUnable to open file: %s"),
-                              _("Couldn't remove tag!"), strerror(errno));
-    if (msg) {
-        GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("Ok"),
-                                            FALSE, NULL, NULL);
-        gtk_window_set_transient_for(GTK_WINDOW(mwin), GTK_WINDOW(window));
-        g_free(msg);
-    }
-    else {
-        gtk_entry_set_text(GTK_ENTRY(title_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(artist_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(album_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(comment_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(year_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(album_entry), "");
-        gtk_entry_set_text(GTK_ENTRY(tracknum_entry), "");
-        gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
-        gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);
-    }
-}
-
-#endif
-
 static void
 set_mpeg_level_label(gboolean mpeg25, gint lsf, gint layer)
 {
@@ -628,9 +225,6 @@
 change_buttons(GtkObject * object)
 {
     gtk_widget_set_sensitive(GTK_WIDGET(object), TRUE);
-#if 0
-    gtk_widget_set_sensitive(GTK_WIDGET(revert),TRUE);
-#endif
 }
 
 void
@@ -653,9 +247,7 @@
         PangoAttribute *attr;
         GtkWidget *test_table = gtk_table_new(2, 11, FALSE);
         GtkWidget *urk, *blark;
-#ifdef HAVE_ID3LIB
-	GtkWidget * tracknum_box, * comment_frame;
-#endif
+	GtkWidget * comment_frame;
 
         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
         gtk_window_set_type_hint(GTK_WINDOW(window),
@@ -878,11 +470,7 @@
         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL,
                          GTK_FILL, 5, 5);
 
-#ifdef HAVE_ID3LIB
 	title_entry = gtk_entry_new();
-#else
-        title_entry = gtk_entry_new_with_max_length(30);
-#endif
         gtk_table_attach(GTK_TABLE(table), title_entry, 1, 6, 0, 1,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
@@ -893,11 +481,7 @@
         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL,
                          GTK_FILL, 5, 5);
 
-#ifdef HAVE_ID3LIB
 	artist_entry = gtk_entry_new();
-#else
-        artist_entry = gtk_entry_new_with_max_length(30);
-#endif
         gtk_table_attach(GTK_TABLE(table), artist_entry, 1, 6, 1, 2,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
@@ -908,11 +492,7 @@
         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL,
                          GTK_FILL, 5, 5);
 
-#ifdef HAVE_ID3LIB
 	album_entry = gtk_entry_new();
-#else
-        album_entry = gtk_entry_new_with_max_length(30);
-#endif
         gtk_table_attach(GTK_TABLE(table), album_entry, 1, 6, 2, 3,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
@@ -923,21 +503,13 @@
         gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, GTK_FILL,
                          GTK_FILL, 5, 5);
 
-#ifdef HAVE_ID3LIB
 	comment_frame = gtk_frame_new(NULL);
-	gtk_frame_set_shadow_type(GTK_FRAME(comment_frame),GTK_SHADOW_IN);
-	comment_entry = gtk_text_view_new();
-	gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(comment_entry),FALSE);
+	/* gtk_frame_set_shadow_type(GTK_FRAME(comment_frame),GTK_SHADOW_IN); */
+	comment_entry = gtk_entry_new();
 	gtk_container_add(GTK_CONTAINER(comment_frame),comment_entry);
         gtk_table_attach(GTK_TABLE(table), comment_frame, 1, 6, 3, 4,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
-#else
-        comment_entry = gtk_entry_new_with_max_length(30);
-        gtk_table_attach(GTK_TABLE(table), comment_entry, 1, 6, 3, 4,
-                         GTK_FILL | GTK_EXPAND | GTK_SHRINK,
-                         GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
-#endif
 
         label = gtk_label_new(_("Year:"));
         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
@@ -957,31 +529,11 @@
         gtk_table_attach(GTK_TABLE(table), label, 2, 3, 4, 5, GTK_FILL,
                          GTK_FILL, 5, 5);
 
-#ifdef HAVE_ID3LIB
-	tracknum_box = gtk_hbox_new(FALSE,0);
-	tracknum_entry = gtk_entry_new_with_max_length(2);
-        gtk_entry_set_width_chars(GTK_ENTRY(tracknum_entry),2);
-	totaltracks_entry = gtk_entry_new_with_max_length(2);
-        gtk_entry_set_width_chars(GTK_ENTRY(totaltracks_entry),2);
-	gtk_box_pack_start(GTK_BOX(tracknum_box),
-			   tracknum_entry, TRUE, TRUE, 1);
-	gtk_box_pack_start(GTK_BOX(tracknum_box),
-			   gtk_label_new(" / "), FALSE, FALSE, 1);
-	gtk_box_pack_start(GTK_BOX(tracknum_box),
-			   totaltracks_entry, TRUE, TRUE, 1);
-        gtk_table_attach(GTK_TABLE(table), 
-			 tracknum_box,
-			 3, 4, 4, 5,
-                         GTK_FILL | GTK_EXPAND | GTK_SHRINK,
-                         GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
-	
-#else
         tracknum_entry = gtk_entry_new_with_max_length(3);
         gtk_widget_set_usize(tracknum_entry, 40, -1);
         gtk_table_attach(GTK_TABLE(table), tracknum_entry, 3, 4, 4, 5,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK,
                          GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
-#endif
 
         label = gtk_label_new(_("Genre:"));
         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
@@ -1014,25 +566,6 @@
         remove_id3 = gtk_button_new_from_stock(GTK_STOCK_DELETE);
         gtk_container_add(GTK_CONTAINER(boxx), remove_id3);
 
-#if 0
-        revert = gtk_button_new_from_stock(GTK_STOCK_REVERT_TO_SAVED);
-        gtk_container_add(GTK_CONTAINER(boxx), revert);
-#endif
-
-#ifdef HAVE_ID3LIB
-	copy_album_tags_but = gtk_button_new_with_label(_("Copy album tags"));
-	paste_album_tags_but = gtk_button_new_with_label(_("Paste album tags"));
-
-        gtk_container_add(GTK_CONTAINER(boxx), copy_album_tags_but);
-        gtk_container_add(GTK_CONTAINER(boxx), paste_album_tags_but);
-
-        g_signal_connect(G_OBJECT(copy_album_tags_but), "clicked",
-                         G_CALLBACK(copy_album_tags), NULL);
-        g_signal_connect(G_OBJECT(paste_album_tags_but), "clicked",
-                         G_CALLBACK(paste_album_tags), NULL);
-
-	gtk_widget_set_sensitive(GTK_WIDGET(paste_album_tags_but), FALSE);
-#endif
         save = gtk_button_new_from_stock(GTK_STOCK_SAVE);
         gtk_container_add(GTK_CONTAINER(boxx), save);
 
@@ -1040,11 +573,6 @@
                          G_CALLBACK(remove_id3_cb), save);
         g_signal_connect(G_OBJECT(save), "clicked", G_CALLBACK(save_cb),
                          remove_id3);
-#if 0
-        g_signal_connect(G_OBJECT(revert), "clicked", G_CALLBACK(fill_entries),
-                         NULL);
-#endif
-
 
         gtk_table_attach(GTK_TABLE(table), boxx, 0, 5, 6, 7, GTK_FILL, 0,
                          0, 8);
@@ -1075,15 +603,8 @@
                                  G_CALLBACK(change_buttons), save);
         g_signal_connect_swapped(G_OBJECT(year_entry), "changed",
                                  G_CALLBACK(change_buttons), save);
-#ifdef HAVE_ID3LIB
-        g_signal_connect_swapped(G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_entry))), "changed",
-                                 G_CALLBACK(change_buttons), save);
-        g_signal_connect_swapped(G_OBJECT(totaltracks_entry), "changed",
-                                 G_CALLBACK(change_buttons), save);
-#else
         g_signal_connect_swapped(G_OBJECT(comment_entry), "changed",
                                  G_CALLBACK(change_buttons), save);
-#endif
         g_signal_connect_swapped(G_OBJECT(tracknum_entry), "changed",
                                  G_CALLBACK(change_buttons), save);
         g_signal_connect_swapped(G_OBJECT(GTK_COMBO(genre_combo)->entry), "changed",
@@ -1127,11 +648,7 @@
     gtk_entry_set_text(GTK_ENTRY(album_entry), "");
     gtk_entry_set_text(GTK_ENTRY(year_entry), "");
     gtk_entry_set_text(GTK_ENTRY(tracknum_entry), "");
-#ifdef HAVE_ID3LIB
-    gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(comment_entry)),"",-1);
-#else
     gtk_entry_set_text(GTK_ENTRY(comment_entry), "");
-#endif
     gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list),
                          g_list_index(genre_list, ""));
 
@@ -1176,58 +693,39 @@
     fill_entries(NULL, NULL);
 
     gtk_widget_set_sensitive(GTK_WIDGET(save), FALSE);
-#if 0
-    gtk_widget_set_sensitive(GTK_WIDGET(revert), FALSE);
-#endif
     gtk_widget_show_all(window);
 }
 
-#ifdef HAVE_ID3LIB
-
 void
 fill_entries(GtkWidget * w, gpointer data)
 {
   VFSFile *fh;
-  ID3Tag * id3tag;
 
   if (str_has_prefix_nocase(current_filename, "http://"))
     return;
   
-  id3tag = ID3Tag_New();
-  ID3Tag_LinkPreferV2(id3tag, current_filename);
+  taglib_file = taglib_file_new(current_filename);
+  if(taglib_file) {
+    taglib_tag = taglib_file_tag(taglib_file);
+    taglib_ap = taglib_file_audioproperties(taglib_file);
+  } else return;
 
-  id3v2_frame_to_entry(title_entry, id3tag, ID3FID_TITLE);
-  id3v2_frame_to_entry(artist_entry, id3tag, ID3FID_LEADARTIST);
-  id3v2_frame_to_entry(album_entry, id3tag, ID3FID_ALBUM);
-  id3v2_frame_to_text_view(comment_entry, id3tag, ID3FID_COMMENT);
-  id3v2_frame_to_entry(year_entry, id3tag, ID3FID_YEAR);
-  id3v2_tracknum_to_entries(tracknum_entry, totaltracks_entry, id3tag);
-  {
-    ID3Frame * frame = ID3Tag_FindFrameWithID(id3tag, ID3FID_CONTENTTYPE);
-	    
-    if (frame) {
-      int genre_idx = -1;
-      char genre[64];
-      const char * genre2;
-      ID3Field * text_field = ID3Frame_GetField(frame,ID3FN_TEXT);
-      ID3Field_GetASCII(text_field,genre,64);
+  gtk_entry_set_text(GTK_ENTRY(title_entry), taglib_tag_title(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(artist_entry), taglib_tag_artist(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(album_entry), taglib_tag_album(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(comment_entry), taglib_tag_comment(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(year_entry), (gchar*)taglib_tag_year(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(tracknum_entry), (gchar*)taglib_tag_track(taglib_tag));
+  gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), taglib_tag_genre(taglib_tag));
 
-      /* attempt to find corresponding genre */
-      g_strstrip(genre);
-      sscanf(genre,"(%d)",&genre_idx);
-      if ((genre2 = ID3_V1GENRE2DESCRIPTION(genre_idx)))
-	gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(genre_combo)->entry),
-			   genre2);
-    }
-  }
+  gtk_widget_set_sensitive(GTK_WIDGET(w), FALSE);
+  gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE);
 
+  taglib_file_free(taglib_file);
+  taglib_tag_free_strings();
   gtk_widget_set_sensitive(GTK_WIDGET(remove_id3), TRUE);
   gtk_widget_set_sensitive(GTK_WIDGET(save), FALSE);
 
-  update_paste_sensitive();
-
-  ID3Tag_Delete(id3tag);  
-
   if ((fh = vfs_fopen(current_filename, "rb")) != NULL) {
     guint32 head;
     guchar tmp[4];
@@ -1295,125 +793,3 @@
 
 }
 
-#else /* ! HAVE_ID3LIB */
-
-void
-fill_entries(GtkWidget * w, gpointer data)
-{
-    if ((fh = vfs_fopen(current_filename, "rb")) != NULL) {
-        guint32 head;
-        guchar tmp[4];
-        struct frame frm;
-        gboolean id3_found = FALSE;
-
-        vfs_fseek(fh, -sizeof(tag), SEEK_END);
-        if (vfs_fread(&tag, 1, sizeof(tag), fh) == sizeof(tag)) {
-            if (!strncmp(tag.tag, "TAG", 3)) {
-                id3_found = TRUE;
-                set_entry_tag(GTK_ENTRY(title_entry), tag.title, 30);
-                set_entry_tag(GTK_ENTRY(artist_entry), tag.artist, 30);
-                set_entry_tag(GTK_ENTRY(album_entry), tag.album, 30);
-                set_entry_tag(GTK_ENTRY(year_entry), tag.year, 4);
-                /* Check for v1.1 tags */
-                if (tag.u.v1_1.__zero == 0) {
-                    gchar *temp =
-                        g_strdup_printf("%d", tag.u.v1_1.track_number);
-                    set_entry_tag(GTK_ENTRY(comment_entry),
-                                  tag.u.v1_1.comment, 28);
-                    gtk_entry_set_text(GTK_ENTRY(tracknum_entry), temp);
-                    g_free(temp);
-                }
-                else {
-                    set_entry_tag(GTK_ENTRY(comment_entry),
-                                  tag.u.v1_0.comment, 30);
-                    gtk_entry_set_text(GTK_ENTRY(tracknum_entry), "");
-                }
-
-                gtk_list_select_item(GTK_LIST
-                                     (GTK_COMBO(genre_combo)->list),
-                                     g_list_index(genre_list, (gchar *)
-                                                  mpg123_id3_genres[tag.
-                                                                    genre]));
-                gtk_widget_set_sensitive(GTK_WIDGET(remove_id3), TRUE);
-                gtk_widget_set_sensitive(GTK_WIDGET(save), FALSE);
-#if 0
-                gtk_widget_set_sensitive(GTK_WIDGET(revert), FALSE);
-#endif
-            }
-            else {
-                gtk_entry_set_text(GTK_ENTRY(title_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(artist_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(album_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(comment_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(year_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(album_entry), "");
-                gtk_entry_set_text(GTK_ENTRY(tracknum_entry), "");
-                gtk_widget_set_sensitive(GTK_WIDGET(remove_id3), FALSE);
-                gtk_widget_set_sensitive(GTK_WIDGET(save), FALSE);
-#if 0
-                gtk_widget_set_sensitive(GTK_WIDGET(revert), FALSE);
-#endif
-            }
-        }
-        vfs_rewind(fh);
-        if (vfs_fread(tmp, 1, 4, fh) != 4) {
-            vfs_fclose(fh);
-            return;
-        }
-        head =
-            ((guint32) tmp[0] << 24) | ((guint32) tmp[1] << 16) |
-            ((guint32) tmp[2] << 8) | (guint32) tmp[3];
-        while (!mpg123_head_check(head)) {
-            head <<= 8;
-            if (vfs_fread(tmp, 1, 1, fh) != 1) {
-                vfs_fclose(fh);
-                return;
-            }
-            head |= tmp[0];
-        }
-        if (mpg123_decode_header(&frm, head)) {
-            guchar *buf;
-            gdouble tpf;
-            gint pos;
-            xing_header_t xing_header;
-            guint32 num_frames;
-
-            buf = g_malloc(frm.framesize + 4);
-            vfs_fseek(fh, -4, SEEK_CUR);
-            vfs_fread(buf, 1, frm.framesize + 4, fh);
-            tpf = mpg123_compute_tpf(&frm);
-            set_mpeg_level_label(frm.mpeg25, frm.lsf, frm.lay);
-            pos = vfs_ftell(fh);
-            vfs_fseek(fh, 0, SEEK_END);
-            if (mpg123_get_xing_header(&xing_header, buf)) {
-                num_frames = xing_header.frames;
-                label_set_text(mpeg_bitrate_val,
-                               _("Variable,\navg. bitrate: %d KBit/s"),
-                               (gint) ((xing_header.bytes * 8) /
-                                       (tpf * xing_header.frames * 1000)));
-            }
-            else {
-                num_frames =
-                    ((vfs_ftell(fh) - pos -
-                      (id3_found ? 128 : 0)) / mpg123_compute_bpf(&frm)) + 1;
-                label_set_text(mpeg_bitrate_val, _("%d KBit/s"),
-                               tabsel_123[frm.lsf][frm.lay -
-                                                   1][frm.bitrate_index]);
-            }
-            label_set_text(mpeg_samplerate_val, _("%ld Hz"),
-                           mpg123_freqs[frm.sampling_frequency]);
-            label_set_text(mpeg_error_val, _("%s"),
-                           bool_label[frm.error_protection]);
-            label_set_text(mpeg_copy_val, _("%s"), bool_label[frm.copyright]);
-            label_set_text(mpeg_orig_val, _("%s"), bool_label[frm.original]);
-            label_set_text(mpeg_emph_val, _("%s"), emphasis[frm.emphasis]);
-            label_set_text(mpeg_frames_val, _("%d"), num_frames);
-            label_set_text(mpeg_filesize_val, _("%lu Bytes"), vfs_ftell(fh));
-            label_set_text(mpeg_flags_val, _("%s"), channel_mode_name(frm.mode));
-            g_free(buf);
-        }
-        vfs_fclose(fh);
-    }
-}
-
-#endif
--- a/Plugins/Input/mpg123/id3.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,640 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999, 2001,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3.c
- * Description:   Code for accessing ID3 tags.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Fri Feb  5 23:55:13 1999
- *                
- * $Id: id3.c,v 1.6 2004/07/20 21:47:22 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- * 
- ********************************************************************/
-#include "config.h"
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <glib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "xmms-id3.h"
-#include "id3_header.h"
-
-
-/*
-**
-** Functions for accessing the ID3 tag using a memory pointer.
-**
-*/
-
-/*
- * Function id3_seek_mem (id3, offset)
- *
- *    Seek `offset' bytes forward in the indicated ID3-tag.  Return 0
- *    upon success, or -1 if an error occured.
- *
- */
-static int
-id3_seek_mem(struct id3_tag *id3, int offset)
-{
-    if (id3->id3_pos + offset > id3->id3_tagsize || id3->id3_pos + offset < 0) {
-        id3_error(id3, "seeking beyond tag boundary");
-        return -1;
-    }
-    id3->s.me.id3_ptr = (char *) id3->s.me.id3_ptr + offset;
-    id3->id3_pos += offset;
-
-    return 0;
-}
-
-
-/*
- * Function id3_read_mem (id3, buf, size)
- *
- *    Read `size' bytes from indicated ID3-tag.  If `buf' is non-NULL,
- *    read into that buffer.  Return a pointer to the data which was
- *    read, or NULL upon error.
- *
- */
-static void *
-id3_read_mem(struct id3_tag *id3, void *buf, int size)
-{
-    void *ret = id3->s.me.id3_ptr;
-
-    /*
-     * Check boundary.
-     */
-    if (id3->id3_pos + size > id3->id3_tagsize) {
-        return NULL;
-    }
-
-    /*
-     * If buffer is non-NULL, we have to copy the data.
-     */
-    if (buf != NULL) {
-        if (size > ID3_FD_BUFSIZE)
-            return NULL;
-        memcpy(buf, id3->s.me.id3_ptr, size);
-    }
-
-    /*
-     * Update memory pointer.
-     */
-    id3->s.me.id3_ptr = (char *) id3->s.me.id3_ptr + size;
-    id3->id3_pos += size;
-
-    return ret;
-}
-
-
-/*
-**
-** Functions for accessing the ID3 tag using a file descriptor.
-**
-*/
-
-/*
- * Function id3_seek_fd (id3, offset)
- *
- *    Seek `offset' bytes forward in the indicated ID3-tag.  Return 0
- *    upon success, or -1 if an error occured.
- *
- */
-static int
-id3_seek_fd(struct id3_tag *id3, int offset)
-{
-    /*
-     * Check boundary.
-     */
-    if (id3->id3_pos + offset > id3->id3_tagsize || id3->id3_pos + offset < 0)
-        return -1;
-
-    if (lseek(id3->s.fd.id3_fd, offset, SEEK_CUR) == -1) {
-        id3_error(id3, "seeking beyond tag boundary");
-        return -1;
-    }
-    id3->id3_pos += offset;
-
-    return 0;
-}
-
-
-/*
- * Function id3_read_fd (id3, buf, size)
- *
- *    Read `size' bytes from indicated ID3-tag.  If `buf' is non-NULL,
- *    read into that buffer.  Return a pointer to the data which was
- *    read, or NULL upon error.
- *
- */
-static void *
-id3_read_fd(struct id3_tag *id3, void *buf, int size)
-{
-    int done = 0;
-
-    /*
-     * Check boundary.
-     */
-    if (id3->id3_pos + size > id3->id3_tagsize) {
-        return NULL;
-    }
-
-    /*
-     * If buffer is NULL, we use the default buffer.
-     */
-    if (buf == NULL) {
-        if (size > ID3_FD_BUFSIZE)
-            return NULL;
-        buf = id3->s.fd.id3_buf;
-    }
-
-    /*
-     * Read until we have slurped as much data as we wanted.
-     */
-    while (done < size) {
-        char *buffer = (char *) buf + done;
-        int ret;
-
-        /*
-         * Try reading from file.
-         */
-        ret = read(id3->s.fd.id3_fd, buffer, size);
-        if (ret <= 0) {
-            id3_error(id3, "read(2) failed");
-            return NULL;
-        }
-
-        id3->id3_pos += ret;
-        done += ret;
-    }
-
-    return buf;
-}
-
-
-/*
-**
-** Functions for accessing the ID3 tag using a file pointer.
-**
-*/
-
-/*
- * Function id3_seek_fp (id3, offset)
- *
- *    Seek `offset' bytes forward in the indicated ID3-tag.  Return 0
- *    upon success, or -1 if an error occured.
- *
- */
-static int
-id3_seek_fp(struct id3_tag *id3, int offset)
-{
-    /*
-     * Check boundary.
-     */
-    if (id3->id3_pos + offset > id3->id3_tagsize || id3->id3_pos + offset < 0)
-        return -1;
-
-    if (offset > 0) {
-        /*
-         * If offset is positive, we use vfs_fread() instead of vfs_fseek().  This
-         * is more robust with respect to streams.
-         */
-        char buf[64];
-        int r, remain = offset;
-
-        while (remain > 0) {
-            int size = MIN(64, remain);
-            r = vfs_fread(buf, 1, size, id3->s.fp.id3_fp);
-            if (r == 0) {
-                id3_error(id3, "vfs_fread() failed");
-                return -1;
-            }
-            remain -= r;
-        }
-    }
-    else {
-        /*
-         * If offset is negative, we ahve to use vfs_fseek().  Let us hope
-         * that it works.
-         */
-        if (vfs_fseek(id3->s.fp.id3_fp, offset, SEEK_CUR) == -1) {
-            id3_error(id3, "seeking beyond tag boundary");
-            return -1;
-        }
-    }
-    id3->id3_pos += offset;
-
-    return 0;
-}
-
-
-/*
- * Function id3_read_fp (id3, buf, size)
- *
- *    Read `size' bytes from indicated ID3-tag.  If `buf' is non-NULL,
- *    read into that buffer.  Return a pointer to the data which was
- *    read, or NULL upon error.
- *
- */
-static void *
-id3_read_fp(struct id3_tag *id3, void *buf, int size)
-{
-    int ret;
-
-    /*
-     * Check boundary.
-     */
-    if (id3->id3_pos + size > id3->id3_tagsize) {
-        size = id3->id3_tagsize - id3->id3_pos;
-    }
-
-    /*
-     * If buffer is NULL, we use the default buffer.
-     */
-    if (buf == NULL) {
-        if (size > ID3_FD_BUFSIZE)
-            return NULL;
-        buf = id3->s.fd.id3_buf;
-    }
-
-    /*
-     * Try reading from file.
-     */
-    ret = vfs_fread(buf, 1, size, id3->s.fp.id3_fp);
-    if (ret != size) {
-        id3_error(id3, "vfs_fread() failed");
-        return NULL;
-    }
-
-    id3->id3_pos += ret;
-
-    return buf;
-}
-
-
-
-
-/*
- * Function id3_open_mem (ptr, flags)
- *
- *    Open an ID3 tag using a memory pointer.  Return a pointer to a
- *    structure describing the ID3 tag, or NULL if an error occured.
- *
- */
-struct id3_tag *
-id3_open_mem(void *ptr, int flags)
-{
-    struct id3_tag *id3;
-
-    /*
-     * Allocate ID3 structure.
-     */
-    id3 = g_malloc0(sizeof(struct id3_tag));
-
-    /*
-     * Initialize access pointers.
-     */
-    id3->id3_seek = id3_seek_mem;
-    id3->id3_read = id3_read_mem;
-
-    id3->id3_oflags = flags;
-    id3->id3_type = ID3_TYPE_MEM;
-    id3->id3_pos = 0;
-    id3->s.me.id3_ptr = ptr;
-
-    /*
-     * Try reading ID3 tag.
-     */
-    if (id3_read_tag(id3) == -1) {
-        if (~flags & ID3_OPENF_CREATE)
-            goto Return_NULL;
-        id3_init_tag(id3);
-    }
-
-    return id3;
-
-  Return_NULL:
-    g_free(id3);
-    return NULL;
-}
-
-
-/*
- * Function id3_open_fd (fd, flags)
- *
- *    Open an ID3 tag using a file descriptor.  Return a pointer to a
- *    structure describing the ID3 tag, or NULL if an error occured.
- *
- */
-struct id3_tag *
-id3_open_fd(int fd, int flags)
-{
-    struct id3_tag *id3;
-
-    /*
-     * Allocate ID3 structure.
-     */
-    id3 = g_malloc0(sizeof(struct id3_tag));
-
-    /*
-     * Initialize access pointers.
-     */
-    id3->id3_seek = id3_seek_fd;
-    id3->id3_read = id3_read_fd;
-
-    id3->id3_oflags = flags;
-    id3->id3_type = ID3_TYPE_FD;
-    id3->id3_pos = 0;
-    id3->s.fd.id3_fd = fd;
-
-    /*
-     * Allocate buffer to hold read data.
-     */
-    id3->s.fd.id3_buf = g_malloc(ID3_FD_BUFSIZE);
-
-    /*
-     * Try reading ID3 tag.
-     */
-    if (id3_read_tag(id3) == -1) {
-        if (~flags & ID3_OPENF_CREATE)
-            goto Return_NULL;
-        id3_init_tag(id3);
-    }
-
-    return id3;
-
-    /*
-     * Cleanup code.
-     */
-  Return_NULL:
-    g_free(id3->s.fd.id3_buf);
-    g_free(id3);
-    return NULL;
-}
-
-
-/*
- * Function id3_open_fp (fp, flags)
- *
- *    Open an ID3 tag using a file pointer.  Return a pointer to a
- *    structure describing the ID3 tag, or NULL if an error occured.
- *
- */
-struct id3_tag *
-id3_open_fp(VFSFile * fp, int flags)
-{
-    struct id3_tag *id3;
-
-    if (fp == NULL)
-	return NULL;
-
-    /*
-     * Allocate ID3 structure.
-     */
-    id3 = g_malloc0(sizeof(struct id3_tag));
-
-    /*
-     * Initialize access pointers.
-     */
-    id3->id3_seek = id3_seek_fp;
-    id3->id3_read = id3_read_fp;
-
-    id3->id3_oflags = flags;
-    id3->id3_type = ID3_TYPE_FP;
-    id3->id3_pos = 0;
-    id3->s.fp.id3_fp = fp;
-
-    /*
-     * Allocate buffer to hold read data.
-     */
-    id3->s.fp.id3_buf = g_malloc(ID3_FD_BUFSIZE);
-
-    /*
-     * Try reading ID3 tag.
-     */
-    if (id3_read_tag(id3) == -1) {
-        if (~flags & ID3_OPENF_CREATE)
-            goto Return_NULL;
-        id3_init_tag(id3);
-    }
-
-
-    return id3;
-
-    /*
-     * Cleanup code.
-     */
-  Return_NULL:
-    g_free(id3->s.fp.id3_buf);
-    g_free(id3);
-    return NULL;
-}
-
-
-/*
- * Function id3_close (id3)
- *
- *    Free all resources assoicated with the ID3 tag.
- *
- */
-int
-id3_close(struct id3_tag *id3)
-{
-    int ret = 0;
-
-    switch (id3->id3_type) {
-    case ID3_TYPE_MEM:
-        break;
-    case ID3_TYPE_FD:
-        g_free(id3->s.fd.id3_buf);
-        break;
-    case ID3_TYPE_FP:
-        g_free(id3->s.fp.id3_buf);
-        break;
-    case ID3_TYPE_NONE:
-        id3_error(id3, "unknown ID3 type");
-        ret = -1;
-    }
-
-    id3_destroy_frames(id3);
-
-    g_free(id3);
-
-    return ret;
-}
-
-
-/*
- * Function id3_tell (id3)
- *
- *    Return the current position in ID3 tag.  This will always be
- *    directly after the tag.
- *
- */
-#if 0
-int
-id3_tell(struct id3_tag *id3)
-{
-    if (id3->id3_newtag) {
-        return 0;
-    }
-    else {
-        return id3->id3_tagsize + 3 + sizeof(id3_taghdr_t);
-    }
-}
-#endif
-
-
-/*
- * Function id3_alter_file (id3)
- *
- *    When altering a file, some ID3 tags should be discarded.  As the ID3
- *    library has no means of knowing when a file has been altered
- *    outside of the library, this function must be called manually
- *    whenever the file is altered.
- *
- */
-int
-id3_alter_file(struct id3_tag *id3)
-{
-    /*
-     * List of frame classes that should be discarded whenever the
-     * file is altered.
-     */
-    static guint32 discard_list[] = {
-        ID3_ETCO, ID3_EQUA, ID3_MLLT, ID3_POSS, ID3_SYLT,
-        ID3_SYTC, ID3_RVAD, ID3_TENC, ID3_TLEN, ID3_TSIZ,
-        0
-    };
-    struct id3_frame *fr;
-    guint32 id, i = 0;
-
-    /*
-     * Go through list of frame types that should be discarded.
-     */
-    while ((id = discard_list[i++]) != 0) {
-        /*
-         * Discard all frames of that type.
-         */
-        while ((fr = id3_get_frame(id3, id, 1))) {
-            id3_delete_frame(fr);
-        }
-    }
-
-    return 0;
-}
-
-
-/*
- * Function safe_write (fd, buf, size)
- *
- *    Like write(2), except that the whole buffer will be written.
- *
- */
-static int
-safe_write(int fd, void *buf, int size)
-{
-    int remaining = size;
-    char *ptr = buf;
-    int r;
-
-    while (remaining > 0) {
-        if ((r = write(fd, ptr, remaining)) == -1)
-            return -1;
-        remaining -= r;
-        ptr += r;
-    }
-
-    return 0;
-}
-
-
-/*
- * Function id3_write_tag (id3, fd)
- *
- *    Wrtite the ID3 tag to the indicated file descriptor.  Return 0
- *    upon success, or -1 if an error occured.
- *
- */
-int
-id3_write_tag(struct id3_tag *id3, int fd)
-{
-    struct id3_frame *fr;
-    GList *node;
-    int size = 0;
-    char buf[ID3_TAGHDR_SIZE];
-
-    /*
-     * Calculate size of ID3 tag.
-     */
-    for (node = id3->id3_frame; node != NULL; node = node->next) {
-        fr = node->data;
-        size += fr->fr_size + ID3_FRAMEHDR_SIZE;
-    }
-
-    /*
-     * Write tag header.
-     */
-    buf[0] = id3->id3_version;
-    buf[1] = id3->id3_revision;
-    buf[2] = id3->id3_flags;
-    ID3_SET_SIZE28(size, buf[3], buf[4], buf[5], buf[6]);
-
-    if (safe_write(fd, "ID3", 3) == -1)
-        return -1;
-    if (safe_write(fd, buf, ID3_TAGHDR_SIZE) == -1)
-        return -1;
-
-    /*
-     * TODO: Write extended header.
-     */
-#if 0
-    if (id3->id3_flags & ID3_THFLAG_EXT) {
-        id3_exthdr_t exthdr;
-    }
-#endif
-
-    for (node = id3->id3_frame; node != NULL; node = node->next) {
-        char fhdr[ID3_FRAMEHDR_SIZE];
-
-        fr = node->data;
-
-        /*
-         * TODO: Support compressed headers, encoded
-         * headers, and grouping info.
-         */
-        /*  fhdr.fh_id = fr->fr_desc ? g_htonl(fr->fr_desc->fd_id) : 0; */
-        fhdr[3] = (fr->fr_size >> 24) & 0xff;
-        fhdr[4] = (fr->fr_size >> 16) & 0xff;
-        fhdr[5] = (fr->fr_size >> 8) & 0xff;
-        fhdr[6] = fr->fr_size & 0xff;
-        fhdr[7] = (fr->fr_flags >> 8) & 0xff;
-        fhdr[8] = fr->fr_flags & 0xff;
-
-        if (safe_write(fd, fhdr, sizeof(fhdr)) == -1)
-            return -1;
-
-        if (safe_write(fd, fr->fr_data, fr->fr_size) == -1)
-            return -1;
-    }
-    return 0;
-}
--- a/Plugins/Input/mpg123/id3_frame.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,770 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999-2000, 2001,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_frame.c
- * Description:   Code for handling ID3 frames.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Fri Feb  5 23:47:08 1999
- * 
- * $Id: id3_frame.c,v 1.5 2004/07/20 21:47:22 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *                
- ********************************************************************/
-#include "config.h"
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "xmms-id3.h"
-#include "id3_header.h"
-
-static void *id3_frame_get_dataptr(struct id3_frame *frame);
-static int id3_frame_get_size(struct id3_frame *frame);
-static int id3_read_frame_v22(struct id3_tag *id3);
-
-
-/*
- * Description of all valid ID3v2 frames.
- */
-static struct id3_framedesc framedesc[] = {
-    {ID3_AENC, "AENC", "Audio encryption"},
-    {ID3_APIC, "APIC", "Attached picture"},
-    {ID3_ASPI, "ASPI", "Audio seek point index"},   /* v4 only */
-
-    {ID3_COMM, "COMM", "Comments"},
-    {ID3_COMR, "COMR", "Commercial frame"},
-
-    {ID3_ENCR, "ENCR", "Encryption method registration"},
-    {ID3_EQUA, "EQUA", "Equalization"}, /* v3 only */
-    {ID3_EQU2, "EQU2", "Equalization (2)"}, /* v4 only */
-    {ID3_ETCO, "ETCO", "Event timing codes"},
-
-    {ID3_GEOB, "GEOB", "General encapsulated object"},
-    {ID3_GRID, "GRID", "Group identification registration"},
-
-    {ID3_IPLS, "IPLS", "Involved people list"}, /* v3 only */
-
-    {ID3_LINK, "LINK", "Linked information"},
-
-    {ID3_MCDI, "MCDI", "Music CD identifier"},
-    {ID3_MLLT, "MLLT", "MPEG location lookup table"},
-
-    {ID3_OWNE, "OWNE", "Ownership frame"},
-
-    {ID3_PRIV, "PRIV", "Private frame"},
-    {ID3_PCNT, "PCNT", "Play counter"},
-    {ID3_POPM, "POPM", "Popularimeter"},
-    {ID3_POSS, "POSS", "Position synchronisation frame"},
-
-    {ID3_RBUF, "RBUF", "Recommended buffer size"},
-    {ID3_RVAD, "RVAD", "Relative volume adjustment"},   /* v3 only */
-    {ID3_RVA2, "RVA2", "RVA2 Relative volume adjustment (2)"},  /* v4 only */
-    {ID3_RVRB, "RVRB", "Reverb"},
-
-    {ID3_SEEK, "SEEK", "Seek frame"},   /* v4 only */
-    {ID3_SIGN, "SIGN", "Signature frame"},  /* v4 only */
-    {ID3_SYLT, "SYLT", "Synchronized lyric/text"},
-    {ID3_SYTC, "SYTC", "Synchronized tempo codes"},
-
-    {ID3_TALB, "TALB", "Album/Movie/Show title"},
-    {ID3_TBPM, "TBPM", "BPM (beats per minute)"},
-    {ID3_TCOM, "TCOM", "Composer"},
-    {ID3_TCON, "TCON", "Content type"},
-    {ID3_TCOP, "TCOP", "Copyright message"},
-    {ID3_TDAT, "TDAT", "Date"}, /* v3 only */
-    {ID3_TDEN, "TDEN", "Encoding time"},    /* v4 only */
-    {ID3_TDLY, "TDLY", "Playlist delay"},
-    {ID3_TDOR, "TDOR", "Original release time"},    /* v4 only */
-    {ID3_TDRC, "TDRC", "Recording time"},   /* v4 only */
-    {ID3_TDRL, "TDRL", "Release time"}, /* v4 only */
-    {ID3_TDTG, "TDTG", "Tagging time"}, /* v4 only */
-
-    {ID3_TENC, "TENC", "Encoded by"},
-    {ID3_TEXT, "TEXT", "Lyricist/Text writer"},
-    {ID3_TFLT, "TFLT", "File type"},
-    {ID3_TIME, "TIME", "Time"}, /* v3 only */
-    {ID3_TIPL, "TIPL", "Involved people list"}, /* v4 only */
-    {ID3_TIT1, "TIT1", "Content group description"},
-    {ID3_TIT2, "TIT2", "Title/songname/content description"},
-    {ID3_TIT3, "TIT3", "Subtitle/Description refinement"},
-    {ID3_TKEY, "TKEY", "Initial key"},
-    {ID3_TLAN, "TLAN", "Language(s)"},
-    {ID3_TLEN, "TLEN", "Length"},
-    {ID3_TMCL, "TMCL", "Musician credits list"},    /* v4 only */
-    {ID3_TMOO, "TMOO", "Mood"}, /* v4 only */
-    {ID3_TMED, "TMED", "Media type"},
-    {ID3_TOAL, "TOAL", "Original album/movie/show title"},
-    {ID3_TOFN, "TOFN", "Original filename"},
-    {ID3_TOLY, "TOLY", "Original lyricist(s)/text writer(s)"},
-    {ID3_TOPE, "TOPE", "Original artist(s)/performer(s)"},
-    {ID3_TORY, "TORY", "Original release year"},    /* v3 only */
-    {ID3_TOWN, "TOWN", "File owner/licensee"},
-    {ID3_TPE1, "TPE1", "Lead performer(s)/Soloist(s)"},
-    {ID3_TPE2, "TPE2", "Band/orchestra/accompaniment"},
-    {ID3_TPE3, "TPE3", "Conductor/performer refinement"},
-    {ID3_TPE4, "TPE4", "Interpreted, remixed, or otherwise modified by"},
-    {ID3_TPOS, "TPOS", "Part of a set"},
-    {ID3_TPRO, "TPRO", "Produced notice"},  /* v4 only */
-    {ID3_TPUB, "TPUB", "Publisher"},
-    {ID3_TRCK, "TRCK", "Track number/Position in set"},
-    {ID3_TRDA, "TRDA", "Recording dates"},  /* v3 only */
-    {ID3_TRSN, "TRSN", "Internet radio station name"},
-    {ID3_TRSO, "TRSO", "Internet radio station owner"},
-    {ID3_TSIZ, "TSIZ", "Size"}, /* v3 only */
-    {ID3_TSOA, "TSOA", "Album sort order"}, /* v4 only */
-    {ID3_TSOP, "TSOP", "Performer sort order"}, /* v4 only */
-    {ID3_TSOT, "TSOT", "Title sort order"}, /* v4 only */
-
-    {ID3_TSRC, "TSRC", "ISRC (international standard recording code)"},
-    {ID3_TSSE, "TSSE", "Software/Hardware and settings used for encoding"},
-    {ID3_TSST, "TSST", "Set subtitle"}, /* v4 only */
-    {ID3_TYER, "TYER", "Year"}, /* v3 only */
-    {ID3_TXXX, "TXXX", "User defined text information frame"},
-
-    {ID3_UFID, "UFID", "Unique file identifier"},
-    {ID3_USER, "USER", "Terms of use"},
-    {ID3_USLT, "USLT", "Unsychronized lyric/text transcription"},
-
-    {ID3_WCOM, "WCOM", "Commercial information"},
-    {ID3_WCOP, "WCOP", "Copyright/Legal information"},
-    {ID3_WOAF, "WOAF", "Official audio file webpage"},
-    {ID3_WOAR, "WOAR", "Official artist/performer webpage"},
-    {ID3_WOAS, "WOAS", "Official audio source webpage"},
-    {ID3_WORS, "WORS", "Official internet radio station homepage"},
-    {ID3_WPAY, "WPAY", "Payment"},
-    {ID3_WPUB, "WPUB", "Publishers official webpage"},
-    {ID3_WXXX, "WXXX", "User defined URL link frame"},
-};
-
-struct id3_framedesc22 {
-    guint32 fd_v22, fd_v24;
-};
-
-static struct id3_framedesc22 framedesc22[] = {
-    {ID3_BUF, ID3_RBUF},        /* Recommended buffer size */
-
-    {ID3_CNT, ID3_PCNT},        /* Play counter */
-    {ID3_COM, ID3_COMM},        /* Comments */
-    {ID3_CRA, ID3_AENC},        /* Audio encryption */
-    {ID3_CRM, 0},               /* Encrypted meta frame */
-
-    {ID3_ETC, ID3_ETCO},        /* Event timing codes */
-    /* Could be converted to EQU2 */
-    {ID3_EQU, 0},               /* Equalization */
-
-    {ID3_GEO, ID3_GEOB},        /* General encapsulated object */
-
-    /* Would need conversion to TIPL */
-    {ID3_IPL, 0},               /* Involved people list */
-
-    /* This is so fragile it's not worth trying to save */
-    {ID3_LNK, 0},               /* Linked information */
-
-    {ID3_MCI, ID3_MCDI},        /* Music CD Identifier */
-    {ID3_MLL, ID3_MLLT},        /* MPEG location lookup table */
-
-    /* Would need to convert header for APIC */
-    {ID3_PIC, 0},               /* Attached picture */
-    {ID3_POP, ID3_POPM},        /* Popularimeter */
-
-    {ID3_REV, ID3_RVRB},        /* Reverb */
-    /* Could be converted to RVA2 */
-    {ID3_RVA, 0},               /* Relative volume adjustment */
-
-    {ID3_SLT, ID3_SYLT},        /* Synchronized lyric/text */
-    {ID3_STC, ID3_SYTC},        /* Synced tempo codes */
-
-    {ID3_TAL, ID3_TALB},        /* Album/Movie/Show title */
-    {ID3_TBP, ID3_TBPM},        /* BPM (Beats Per Minute) */
-    {ID3_TCM, ID3_TCOM},        /* Composer */
-    {ID3_TCO, ID3_TCON},        /* Content type */
-    {ID3_TCR, ID3_TCOP},        /* Copyright message */
-    /* This could be incorporated into TDRC */
-    {ID3_TDA, 0},               /* Date */
-    {ID3_TDY, ID3_TDLY},        /* Playlist delay */
-    {ID3_TEN, ID3_TENC},        /* Encoded by */
-    {ID3_TFT, ID3_TFLT},        /* File type */
-    /* This could be incorporated into TDRC */
-    {ID3_TIM, 0},               /* Time */
-    {ID3_TKE, ID3_TKEY},        /* Initial key */
-    {ID3_TLA, ID3_TLAN},        /* Language(s) */
-    {ID3_TLE, ID3_TLEN},        /* Length */
-    {ID3_TMT, ID3_TMED},        /* Media type */
-    {ID3_TOA, ID3_TOPE},        /* Original artist(s)/performer(s) */
-    {ID3_TOF, ID3_TOFN},        /* Original filename */
-    {ID3_TOL, ID3_TOLY},        /* Original Lyricist(s)/text writer(s) */
-    /*
-     * The docs says that original release year should be in
-     * milliseconds!  Hopefully that is a typo.
-     */
-    {ID3_TOR, ID3_TDOR},        /* Original release year */
-    {ID3_TOT, ID3_TOAL},        /* Original album/Movie/Show title */
-    {ID3_TP1, ID3_TPE1},        /* Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group */
-    {ID3_TP2, ID3_TPE2},        /* Band/Orchestra/Accompaniment */
-    {ID3_TP3, ID3_TPE3},        /* Conductor/Performer refinement */
-    {ID3_TP4, ID3_TPE4},        /* Interpreted, remixed, or otherwise modified by */
-    {ID3_TPA, ID3_TPOS},        /* Part of a set */
-    {ID3_TPB, ID3_TPUB},        /* Publisher */
-    {ID3_TRC, ID3_TSRC},        /* ISRC (International Standard Recording Code) */
-    {ID3_TRD, 0},               /* Recording dates */
-    {ID3_TRK, ID3_TRCK},        /* Track number/Position in set */
-    {ID3_TSI, 0},               /* Size */
-    {ID3_TSS, ID3_TSSE},        /* Software/hardware and settings used for encoding */
-    {ID3_TT1, ID3_TIT1},        /* Content group description */
-    {ID3_TT2, ID3_TIT2},        /* Title/Songname/Content description */
-    {ID3_TT3, ID3_TIT3},        /* Subtitle/Description refinement */
-    {ID3_TXT, ID3_TEXT},        /* Lyricist/text writer */
-    {ID3_TXX, ID3_TXXX},        /* User defined text information frame */
-    {ID3_TYE, ID3_TDRC},        /* Year */
-
-    {ID3_UFI, ID3_UFID},        /* Unique file identifier */
-    {ID3_ULT, ID3_USLT},        /* Unsychronized lyric/text transcription */
-
-    {ID3_WAF, ID3_WOAF},        /* Official audio file webpage */
-    {ID3_WAR, ID3_WOAR},        /* Official artist/performer webpage */
-    {ID3_WAS, ID3_WOAS},        /* Official audio source webpage */
-    {ID3_WCM, ID3_WCOM},        /* Commercial information */
-    {ID3_WCP, ID3_WCOP},        /* Copyright/Legal information */
-    {ID3_WPB, ID3_WPUB},        /* Publishers official webpage */
-    {ID3_WXX, ID3_WXXX},        /* User defined URL link frame */
-};
-
-/*
- * These need to be signed, because otherwise this code will get wonky.
- * BTW, I hate this code and I hope it dies someday.
- *   --nenolod
- */
-static struct id3_framedesc *
-find_frame_description(guint32 id)
-{
-    int i;
-    for (i = 0; i < (int) sizeof(framedesc) / (int) sizeof(struct id3_framedesc); i++)
-        if (framedesc[i].fd_id == id)
-            return &framedesc[i];
-    return NULL;
-}
-
-
-/*
- * Function id3_read_frame (id3)
- *
- *    Read next frame from the indicated ID3 tag.  Return 0 upon
- *    success, or -1 if an error occured.
- *
- */
-int
-id3_read_frame(struct id3_tag *id3)
-{
-    struct id3_frame *frame;
-    guint32 id;
-    char *buf;
-
-    if (id3->id3_version == 2)
-        return id3_read_frame_v22(id3);
-
-    /*
-     * Read frame header.
-     */
-    buf = id3->id3_read(id3, NULL, ID3_FRAMEHDR_SIZE);
-    if (buf == NULL)
-        return -1;
-
-    /*
-     * If we encounter an invalid frame id, we assume that there is
-     * some padding in the header.  We just skip the rest of the ID3
-     * tag.
-     */
-    if (!((buf[0] >= '0' && buf[0] <= '9')
-          || (buf[0] >= 'A' && buf[0] <= 'Z'))) {
-        id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos);
-        return 0;
-    }
-    id = ID3_FRAME_ID(buf[0], buf[1], buf[2], buf[3]);
-
-    /*
-     * Allocate frame.
-     */
-    frame = g_malloc0(sizeof(struct id3_frame));
-
-    frame->fr_owner = id3;
-    /* FIXME v2.4.0 */
-    frame->fr_raw_size = buf[4] << 24 | buf[5] << 16 | buf[6] << 8 | buf[7];
-    if (frame->fr_raw_size < 0 || frame->fr_raw_size > 1000000) {
-        g_free(frame);
-        return -1;
-    }
-    frame->fr_flags = buf[8] << 8 | buf[9];
-
-    /*
-     * Determine the type of the frame.
-     */
-
-    frame->fr_desc = find_frame_description(id);
-
-    /*
-     * Check if frame had a valid id.
-     */
-    if (frame->fr_desc == NULL) {
-        /*
-         * No. Ignore the frame.
-         */
-        if (id3->id3_seek(id3, frame->fr_raw_size) < 0) {
-            g_free(frame);
-            return -1;
-        }
-        return 0;
-    }
-
-    /*
-     * Initialize frame.
-     */
-
-    /*
-     * We allocate 2 extra bytes.  This simplifies retrieval of
-     * text strings.
-     */
-    frame->fr_raw_data = g_malloc0(frame->fr_raw_size + 2);
-    if (id3->id3_read(id3, frame->fr_raw_data, frame->fr_raw_size) == NULL) {
-        g_free(frame->fr_raw_data);
-        g_free(frame);
-        return -1;
-    }
-
-    /*
-     * Insert frame into linked list.
-     */
-    id3->id3_frame = g_list_append(id3->id3_frame, frame);
-
-    /*
-     * Check if frame is compressed using zlib.
-     */
-    if (frame->fr_flags & ID3_FHFLAG_COMPRESS)
-        return 0;
-
-    frame->fr_data = id3_frame_get_dataptr(frame);
-    frame->fr_size = id3_frame_get_size(frame);
-
-    return 0;
-}
-
-
-/*
- * Function id3_get_frame (id3, type, num)
- *
- *    Search in the list of frames for the ID3-tag, and return a frame
- *    of the indicated type.  If tag contains several frames of the
- *    indicated type, the third argument tells which of the frames to
- *    return.
- *
- */
-struct id3_frame *
-id3_get_frame(struct id3_tag *id3, guint32 type, int num)
-{
-    GList *node;
-
-    for (node = id3->id3_frame; node != NULL; node = node->next) {
-        struct id3_frame *fr = node->data;
-        if (fr->fr_desc && fr->fr_desc->fd_id == type) {
-            if (--num <= 0)
-                return fr;
-        }
-    }
-    return NULL;
-}
-
-/*
- * Function decompress_frame(frame)
- *
- *    Uncompress the indicated frame.  Return 0 upon success, or -1 if
- *    an error occured.
- *
- */
-static int
-decompress_frame(struct id3_frame *frame)
-{
-#ifdef HAVE_LIBZ
-    z_stream z;
-    int r;
-
-    /*
-     * Fetch the size of the decompressed data.
-     */
-    frame->fr_size_z = g_ntohl(*((guint32 *) frame->fr_raw_data));
-    if (frame->fr_size_z < 0 || frame->fr_size_z > 1000000)
-        return -1;
-
-    /*
-     * Allocate memory to hold uncompressed frame.
-     */
-    frame->fr_data_z = g_malloc(frame->fr_size_z +
-                                (id3_frame_is_text(frame) ? 2 : 0));
-
-    /*
-     * Initialize zlib.
-     */
-    z.next_in = id3_frame_get_dataptr(frame);
-    z.avail_in = id3_frame_get_size(frame);
-    z.zalloc = NULL;
-    z.zfree = NULL;
-    z.opaque = NULL;
-
-    r = inflateInit(&z);
-    switch (r) {
-    case Z_OK:
-        break;
-    case Z_MEM_ERROR:
-        id3_error(frame->fr_owner, "zlib - no memory");
-        goto Error_init;
-    case Z_VERSION_ERROR:
-        id3_error(frame->fr_owner, "zlib - invalid version");
-        goto Error_init;
-    default:
-        id3_error(frame->fr_owner, "zlib - unknown error");
-        goto Error_init;
-    }
-
-    /*
-     * Decompress frame.
-     */
-    z.next_out = frame->fr_data_z;
-    z.avail_out = frame->fr_size_z;
-    r = inflate(&z, Z_SYNC_FLUSH);
-    switch (r) {
-    case Z_STREAM_END:
-        break;
-    case Z_OK:
-        if (z.avail_in == 0)
-            /*
-             * This should not be possible with a correct stream.
-             * We will be nice however, and try to go on.
-             */
-            break;
-        id3_error(frame->fr_owner, "zlib - buffer exhausted");
-        goto Error_inflate;
-    default:
-        id3_error(frame->fr_owner, "zlib - unknown error");
-        goto Error_inflate;
-    }
-
-    r = inflateEnd(&z);
-    if (r != Z_OK)
-        id3_error(frame->fr_owner, "zlib - inflateEnd error");
-
-    /*
-     * Null-terminate text frames.
-     */
-    if (id3_frame_is_text(frame)) {
-        ((char *) frame->fr_data_z)[frame->fr_size_z] = 0;
-        ((char *) frame->fr_data_z)[frame->fr_size_z + 1] = 0;
-    }
-    frame->fr_data = frame->fr_data_z;
-    frame->fr_size = frame->fr_size_z + (id3_frame_is_text(frame) ? 2 : 0);
-
-    return 0;
-
-    /*
-     * Cleanup code.
-     */
-  Error_inflate:
-    r = inflateEnd(&z);
-  Error_init:
-    g_free(frame->fr_data_z);
-    frame->fr_data_z = NULL;
-#endif
-    return -1;
-}
-
-/*
- * Function id3_decompress_frame(frame)
- *
- *    Check if frame is compressed, and uncompress if necessary.
- *    Return 0 upon success, or -1 if an error occured.
- *
- */
-int
-id3_decompress_frame(struct id3_frame *frame)
-{
-    if (!(frame->fr_flags & ID3_FHFLAG_COMPRESS))
-        /* Frame not compressed */
-        return 0;
-    if (frame->fr_data_z)
-        /* Frame already decompressed */
-        return 0;
-    /* Do decompression */
-    return decompress_frame(frame);
-}
-
-
-/*
- * Function id3_delete_frame (frame)
- *
- *    Remove frame from ID3 tag and release memory ocupied by it.
- *
- */
-int
-id3_delete_frame(struct id3_frame *frame)
-{
-    GList *list = frame->fr_owner->id3_frame;
-    int ret;
-
-    /*
-     * Search for frame in list.
-     */
-
-    if (g_list_find(list, frame) != NULL) {
-        /*
-         * Frame does not exist in frame list.
-         */
-        ret = -1;
-
-    }
-    else {
-        /*
-         * Remove frame from frame list.
-         */
-        list = g_list_remove(list, frame);
-        frame->fr_owner->id3_altered = 1;
-        ret = 0;
-    }
-
-    /*
-     * Release memory occupied by frame.
-     */
-    if (frame->fr_raw_data)
-        g_free(frame->fr_raw_data);
-    if (frame->fr_data_z)
-        g_free(frame->fr_data_z);
-    g_free(frame);
-
-    return ret;
-}
-
-
-/*
- * Function id3_add_frame (id3, type)
- *
- *    Add a new frame to the ID3 tag.  Return a pointer to the new
- *    frame, or NULL if an error occured.
- *
- */
-struct id3_frame *
-id3_add_frame(struct id3_tag *id3, guint32 type)
-{
-    struct id3_frame *frame;
-    int i;
-
-    /*
-     * Allocate frame.
-     */
-    frame = g_malloc0(sizeof(struct id3_frame));
-
-    /*
-     * Initialize frame
-     */
-    frame->fr_owner = id3;
-
-    /*
-     * Try finding the correct frame descriptor.
-     */
-    for (i = 0; i < (int) sizeof(framedesc) / (int) sizeof(struct id3_framedesc); i++) {
-        if (framedesc[i].fd_id == type) {
-            frame->fr_desc = &framedesc[i];
-            break;
-        }
-    }
-
-    /*
-     * Insert frame into linked list.
-     */
-    id3->id3_frame = g_list_append(id3->id3_frame, frame);
-    id3->id3_altered = 1;
-
-    return frame;
-}
-
-
-/*
- * Destroy all frames  in an id3 tag, and free all data
- */
-void
-id3_destroy_frames(struct id3_tag *id)
-{
-    GList *node;
-
-    for (node = id->id3_frame; node != NULL; node = node->next) {
-        struct id3_frame *frame = node->data;
-        /*
-         * Release memory occupied by frame.
-         */
-        if (frame->fr_raw_data)
-            g_free(frame->fr_raw_data);
-        if (frame->fr_data_z)
-            g_free(frame->fr_data_z);
-        g_free(frame);
-    }
-    g_list_free(id->id3_frame);
-    id->id3_frame = NULL;
-}
-
-static int
-id3_frame_extra_headers(struct id3_frame *frame)
-{
-    int retv = 0;
-    /*
-     * If frame is encrypted, we have four extra bytes in the
-     * header.
-     */
-    if (frame->fr_flags & ID3_FHFLAG_COMPRESS)
-        retv += 4;
-    /*
-     * If frame is encrypted, we have one extra byte in the
-     * header.
-     */
-    if (frame->fr_flags & ID3_FHFLAG_ENCRYPT)
-        retv += 1;
-
-    /*
-     * If frame has grouping identity, we have one extra byte in
-     * the header.
-     */
-    if (frame->fr_flags & ID3_FHFLAG_GROUP)
-        retv += 1;
-
-    return retv;
-}
-
-static void *
-id3_frame_get_dataptr(struct id3_frame *frame)
-{
-    char *ptr = frame->fr_raw_data;
-
-    ptr += id3_frame_extra_headers(frame);
-
-    return ptr;
-}
-
-static int
-id3_frame_get_size(struct id3_frame *frame)
-{
-    return frame->fr_raw_size - id3_frame_extra_headers(frame);
-}
-
-void
-id3_frame_clear_data(struct id3_frame *frame)
-{
-    if (frame->fr_raw_data)
-        g_free(frame->fr_raw_data);
-    if (frame->fr_data_z)
-        g_free(frame->fr_data_z);
-    frame->fr_raw_data = NULL;
-    frame->fr_raw_size = 0;
-    frame->fr_data = NULL;
-    frame->fr_size = 0;
-    frame->fr_data_z = NULL;
-    frame->fr_size_z = 0;
-}
-
-static guint32
-find_v24_id(guint32 v22)
-{
-    int i;
-    for (i = 0; i < (int) sizeof(framedesc22) / (int) sizeof(struct id3_framedesc22); i++)
-        if (framedesc22[i].fd_v22 == v22)
-            return framedesc22[i].fd_v24;
-
-    return 0;
-}
-
-static int
-id3_read_frame_v22(struct id3_tag *id3)
-{
-    struct id3_frame *frame;
-    guint32 id, idv24;
-    char *buf;
-    int size;
-
-    /*
-     * Read frame header.
-     */
-    buf = id3->id3_read(id3, NULL, ID3_FRAMEHDR_SIZE_22);
-    if (buf == NULL)
-        return -1;
-
-    /*
-     * If we encounter an invalid frame id, we assume that there
-     * is some.  We just skip the rest of the ID3 tag.
-     */
-    if (!((buf[0] >= '0' && buf[0] <= '9')
-          || (buf[0] >= 'A' && buf[0] <= 'Z'))) {
-        id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos);
-        return 0;
-    }
-
-    id = ID3_FRAME_ID_22(buf[0], buf[1], buf[2]);
-    size = buf[3] << 16 | buf[4] << 8 | buf[5];
-
-    if ((idv24 = find_v24_id(id)) == 0) {
-        if (id3->id3_seek(id3, size) < 0)
-            return -1;
-        return 0;
-    }
-
-    /*
-     * Allocate frame.
-     */
-    frame = g_malloc0(sizeof(struct id3_frame));
-
-    frame->fr_owner = id3;
-    frame->fr_raw_size = size;
-    if (frame->fr_raw_size < 0 || frame->fr_raw_size > 1000000) {
-        g_free(frame);
-        return -1;
-    }
-
-    /*
-     * Initialize frame.
-     */
-    frame->fr_desc = find_frame_description(idv24);
-
-    /*
-     * We allocate 2 extra bytes.  This simplifies retrieval of
-     * text strings.
-     */
-    frame->fr_raw_data = g_malloc0(frame->fr_raw_size + 2);
-    if (id3->id3_read(id3, frame->fr_raw_data, frame->fr_raw_size) == NULL) {
-        g_free(frame->fr_raw_data);
-        g_free(frame);
-        return -1;
-    }
-
-    /*
-     * Insert frame into linked list.
-     */
-    id3->id3_frame = g_list_append(id3->id3_frame, frame);
-
-    frame->fr_data = frame->fr_raw_data;
-    frame->fr_size = frame->fr_raw_size;
-
-    return 0;
-}
--- a/Plugins/Input/mpg123/id3_frame_content.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999, 2002,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_frame_content.c
- * Description:   Code for handling ID3 content frames.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Mon Feb  8 17:13:46 1999
- *                
- * $Id: id3_frame_content.c,v 1.7 2004/07/20 21:47:22 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- * 
- ********************************************************************/
-
-#include <glib.h>
-#include <glib/gi18n.h>
-
-#include "xmms-id3.h"
-
-#include "mpg123.h"
-
-
-/*
- * Function id3_get_content (frame)
- *
- *    Expand content type string of frame and return it.  Return NULL
- *    upon error.
- *
- */
-char *
-id3_get_content(struct id3_frame *frame)
-{
-    char *text, *text_beg, *ptr;
-    char buffer[256];
-    int spc = sizeof(buffer) - 1;
-
-    /* Type check */
-    if (frame->fr_desc->fd_id != ID3_TCON)
-        return NULL;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return NULL;
-
-    if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
-        text_beg = text = g_strdup((char *) frame->fr_data + 1);
-    else
-        text_beg = text = id3_utf16_to_ascii((char *) frame->fr_data + 1);
-
-    /*
-     * If content is just plain text, return it.
-     */
-    if (text[0] != '(') {
-        return text;
-    }
-
-    /*
-     * Expand ID3v1 genre numbers.
-     */
-    ptr = buffer;
-    while (text[0] == '(' && text[1] != '(' && spc > 0) {
-        const char *genre;
-        size_t num = 0;
-
-        if (text[1] == 'R' && text[2] == 'X') {
-            text += 4;
-            genre = _(" (Remix)");
-            if (ptr == buffer)
-                genre++;
-
-        }
-        else if (text[1] == 'C' && text[2] == 'R') {
-            text += 4;
-            genre = _(" (Cover)");
-            if (ptr == buffer)
-                genre++;
-
-        }
-        else {
-            /* Get ID3v1 genre number */
-            text++;
-            while (*text != ')') {
-                num *= 10;
-                num += *text++ - '0';
-            }
-            text++;
-
-            /* Boundary check */
-            if (num >= sizeof(mpg123_id3_genres) / sizeof(char *))
-                continue;
-
-            genre = gettext(mpg123_id3_genres[num]);
-
-            if (ptr != buffer && spc-- > 0)
-                *ptr++ = '/';
-        }
-
-        /* Expand string into buffer */
-        while (*genre != '\0' && spc > 0) {
-            *ptr++ = *genre++;
-            spc--;
-        }
-    }
-
-    /*
-     * Add plaintext refinement.
-     */
-    if (*text == '(')
-        text++;
-    if (*text != '\0' && ptr != buffer && spc-- > 0)
-        *ptr++ = ' ';
-    while (*text != '\0' && spc > 0) {
-        *ptr++ = *text++;
-        spc--;
-    }
-    *ptr = '\0';
-
-    g_free(text_beg);
-
-    /*
-     * Return the expanded content string.
-     */
-    return g_strdup(buffer);
-}
--- a/Plugins/Input/mpg123/id3_frame_text.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,366 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999, 2001, 2002,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_frame_text.c
- * Description:   Code for handling ID3 text frames.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Fri Feb  5 23:50:33 1999
- *                
- * $Id: id3_frame_text.c,v 1.7 2004/08/21 13:04:47 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *                
- ********************************************************************/
-#include "config.h"
-
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "xmms-id3.h"
-#include "id3_header.h"
-
-
-char *
-id3_utf16_to_ascii(void *utf16)
-{
-    char ascii[256];
-    char *uc = (char *) utf16 + 2;
-    size_t i;
-
-    for (i = 0; *uc != 0 && i < sizeof(ascii); i++, uc += 2)
-        ascii[i] = *uc;
-
-    ascii[i] = 0;
-    return g_strdup(ascii);
-}
-
-
-/*
- * Function id3_get_encoding (frame)
- *
- *    Return text encoding for frame, or -1 if frame does not have any
- *    text encoding.
- *
- */
-gint8
-id3_get_encoding(struct id3_frame * frame)
-{
-    /* Type check */
-    if (!id3_frame_is_text(frame) &&
-        frame->fr_desc->fd_id != ID3_WXXX &&
-        frame->fr_desc->fd_id != ID3_IPLS &&
-        frame->fr_desc->fd_id != ID3_USLT &&
-        frame->fr_desc->fd_id != ID3_SYLT &&
-        frame->fr_desc->fd_id != ID3_COMM &&
-        frame->fr_desc->fd_id != ID3_APIC &&
-        frame->fr_desc->fd_id != ID3_GEOB &&
-        frame->fr_desc->fd_id != ID3_USER &&
-        frame->fr_desc->fd_id != ID3_OWNE &&
-        frame->fr_desc->fd_id != ID3_COMR)
-        return -1;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return -1;
-
-    return *(gint8 *) frame->fr_data;
-}
-
-
-/*
- * Function id3_set_encoding (frame, encoding)
- *
- *    Set text encoding for frame.  Return 0 upon success, or -1 if an
- *    error occured. 
- *
- */
-int
-id3_set_encoding(struct id3_frame *frame, gint8 encoding)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'T' &&
-        frame->fr_desc->fd_id != ID3_WXXX &&
-        frame->fr_desc->fd_id != ID3_IPLS &&
-        frame->fr_desc->fd_id != ID3_USLT &&
-        frame->fr_desc->fd_id != ID3_SYLT &&
-        frame->fr_desc->fd_id != ID3_COMM &&
-        frame->fr_desc->fd_id != ID3_APIC &&
-        frame->fr_desc->fd_id != ID3_GEOB &&
-        frame->fr_desc->fd_id != ID3_USER &&
-        frame->fr_desc->fd_id != ID3_OWNE &&
-        frame->fr_desc->fd_id != ID3_COMR)
-        return -1;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return -1;
-
-    /* Changing the encoding of frames is not supported yet */
-    if (*(gint8 *) frame->fr_data != encoding)
-        return -1;
-
-    /* Set encoding */
-    *(gint8 *) frame->fr_data = encoding;
-    return 0;
-}
-
-
-/*
- * Function id3_get_text (frame)
- *
- *    Return string contents of frame.
- *
- */
-char *
-id3_get_text(struct id3_frame *frame)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'T' && frame->fr_desc->fd_id != ID3_COMM)
-        return NULL;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return NULL;
-
-    if (frame->fr_desc->fd_id == ID3_TXXX || frame->fr_desc->fd_id == ID3_COMM) {
-        /*
-         * This is a user defined text frame.  Skip the description.
-         */
-        switch (*(guint8 *) frame->fr_data) {
-        case ID3_ENCODING_ISO_8859_1:
-            {
-                char *text = (char *) frame->fr_data + 1;
-
-                while (*text != 0)
-                    text++;
-
-                return g_strdup(++text);
-            }
-        case ID3_ENCODING_UTF16:
-            {
-                char *text16 = (char *) frame->fr_data + 1;
-
-                while (*text16 != 0 || *(text16 + 1) != 0)
-                    text16 += 2;
-
-                return id3_utf16_to_ascii(text16 + 2);
-            }
-        default:
-            return NULL;
-        }
-    }
-
-    if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
-        return g_strdup((char *) frame->fr_data + 1);
-    else
-        return id3_utf16_to_ascii(((char *) frame->fr_data + 1));
-}
-
-
-/*
- * Function id3_get_text_desc (frame)
- *
- *    Get description part of a text frame.
- *
- */
-char *
-id3_get_text_desc(struct id3_frame *frame)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'T')
-        return NULL;
-
-    /* If predefined text frame, return description. */
-    if (frame->fr_desc->fd_id != ID3_TXXX)
-        return frame->fr_desc->fd_description;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return NULL;
-
-    if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
-        return g_strdup((char *) frame->fr_data + 1);
-    else
-        return id3_utf16_to_ascii((char *) frame->fr_data + 1);
-}
-
-
-/*
- * Function id3_get_text_number (frame)
- *
- *    Return string contents of frame translated to a positive
- *    integer, or -1 if an error occured.
- *
- */
-int
-id3_get_text_number(struct id3_frame *frame)
-{
-    int number = 0;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return -1;
-
-    /*
-     * Generate integer according to encoding.
-     */
-    switch (*(guint8 *) frame->fr_data) {
-    case ID3_ENCODING_ISO_8859_1:
-        {
-            char *text = ((char *) frame->fr_data) + 1;
-
-            while (*text >= '0' && *text <= '9') {
-                number *= 10;
-                number += *text - '0';
-                text++;
-            }
-
-            return number;
-        }
-    case ID3_ENCODING_UTF16:
-        {
-            char *text = ((char *) frame->fr_data) + 3;
-
-/*  	if (*(gint16 *) frame->fr_data == 0xfeff) */
-/*  	    text++; */
-
-            while (*text >= '0' && *text <= '9') {
-                number *= 10;
-                number += *text - '0';
-                text++;
-            }
-
-            return number;
-        }
-
-    default:
-        return -1;
-    }
-}
-
-
-/*
- * Function id3_set_text (frame, text)
- *
- *    Set text for the indicated frame (only ISO-8859-1 is currently
- *    supported).  Return 0 upon success, or -1 if an error occured.
- *
- */
-int
-id3_set_text(struct id3_frame *frame, char *text)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'T')
-        return -1;
-
-    /*
-     * Release memory occupied by previous data.
-     */
-    id3_frame_clear_data(frame);
-
-    /*
-     * Allocate memory for new data.
-     */
-    frame->fr_raw_size = strlen(text) + 1;
-    frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1);
-
-    /*
-     * Copy contents.
-     */
-    *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1;
-    memcpy((char *) frame->fr_raw_data + 1, text, frame->fr_raw_size);
-
-    frame->fr_altered = 1;
-    frame->fr_owner->id3_altered = 1;
-
-    frame->fr_data = frame->fr_raw_data;
-    frame->fr_size = frame->fr_raw_size;
-
-    return 0;
-}
-
-
-/*
- * Function id3_set_text_number (frame, number)
- *
- *    Set number for the indicated frame (only ISO-8859-1 is currently
- *    supported).  Return 0 upon success, or -1 if an error occured.
- *
- */
-int
-id3_set_text_number(struct id3_frame *frame, int number)
-{
-    char buf[64];
-    int pos;
-    char *text;
-
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'T')
-        return -1;
-
-    /*
-     * Release memory occupied by previous data.
-     */
-    id3_frame_clear_data(frame);
-
-    /*
-     * Create a string with a reversed number.
-     */
-    pos = 0;
-    while (number > 0 && pos < 64) {
-        buf[pos++] = (number % 10) + '0';
-        number /= 10;
-    }
-    if (pos == 64)
-        return -1;
-    if (pos == 0)
-        buf[pos++] = '0';
-
-    /*
-     * Allocate memory for new data.
-     */
-    frame->fr_raw_size = pos + 1;
-    frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1);
-
-    /*
-     * Insert contents.
-     */
-    *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1;
-    text = (char *) frame->fr_raw_data + 1;
-    while (--pos >= 0)
-        *text++ = buf[pos];
-    *text = '\0';
-
-    frame->fr_altered = 1;
-    frame->fr_owner->id3_altered = 1;
-
-    frame->fr_data = frame->fr_raw_data;
-    frame->fr_size = frame->fr_raw_size;
-
-    return 0;
-}
-
-gboolean
-id3_frame_is_text(struct id3_frame * frame)
-{
-    if (frame && frame->fr_desc &&
-        (frame->fr_desc->fd_idstr[0] == 'T' ||
-         frame->fr_desc->fd_idstr[0] == 'W'))
-        return TRUE;
-    return FALSE;
-}
--- a/Plugins/Input/mpg123/id3_frame_url.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999, 2001, 2002,
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_frame_url.c
- * Description:   Code for handling ID3 URL frames.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Tue Feb  9 21:10:45 1999
- *                
- * $Id: id3_frame_url.c,v 1.6 2004/07/20 21:47:22 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *                
- ********************************************************************/
-#include "config.h"
-
-#include "xmms-id3.h"
-#include "id3_header.h"
-
-
-
-/*
- * Function id3_get_url (frame)
- *
- *    Return URL of frame.
- *
- */
-char *
-id3_get_url(struct id3_frame *frame)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'W')
-        return NULL;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return NULL;
-
-    if (frame->fr_desc->fd_id == ID3_WXXX) {
-        /*
-         * This is a user defined link frame.  Skip the description.
-         */
-        switch (*(guint8 *) frame->fr_data) {
-        case ID3_ENCODING_ISO_8859_1:
-            {
-                char *text = (char *) frame->fr_data + 1;
-
-                while (*text != 0)
-                    text++;
-
-                return g_strdup(++text);
-            }
-        case ID3_ENCODING_UTF16:
-            {
-                gint16 *text16 = (gint16 *) ((glong) frame->fr_data + 1);
-
-                while (*text16 != 0)
-                    text16++;
-
-                return g_strdup((char *) (++text16));
-            }
-        default:
-            return NULL;
-        }
-    }
-
-    return g_strdup((char *) frame->fr_data);
-}
-
-
-/*
- * Function id3_get_url_desc (frame)
- *
- *    Get description of a URL.
- *
- */
-char *
-id3_get_url_desc(struct id3_frame *frame)
-{
-    /* Type check */
-    if (frame->fr_desc->fd_idstr[0] != 'W')
-        return NULL;
-
-    /* If predefined link frame, return description. */
-    if (frame->fr_desc->fd_id != ID3_WXXX)
-        return frame->fr_desc->fd_description;
-
-    /* Check if frame is compressed */
-    if (id3_decompress_frame(frame) == -1)
-        return NULL;
-
-    if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1)
-        return g_strdup((char *) frame->fr_data + 1);
-    else
-        return id3_utf16_to_ascii((gint16 *) ((glong) frame->fr_data + 1));
-}
--- a/Plugins/Input/mpg123/id3_header.h	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1998, 1999,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_header.h
- * Description:   Definitions for various ID3 headers.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Thu Nov  5 15:55:10 1998
- *                
- * $Id: id3_header.h,v 1.4 2004/04/13 23:53:01 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *                
- ********************************************************************/
-#ifndef ID3_HEADER_H
-#define ID3_HEADER_H
-
-#include <stdio.h>
-
-/*
- * Layout for the ID3 tag header.
- */
-#if 0
-struct id3_taghdr {
-    guint8 th_version;
-    guint8 th_revision;
-    guint8 th_flags;
-    guint32 th_size;
-};
-#endif
-
-/* Header size excluding "ID3" */
-#define ID3_TAGHDR_SIZE 7       /* Size on disk */
-
-#define ID3_THFLAG_USYNC	0x80000000
-#define ID3_THFLAG_EXT		0x40000000
-#define ID3_THFLAG_EXP		0x20000000
-
-#if 0
-#define ID3_SET_SIZE28(size)		\
-    ( ((size << 3) & 0x7f000000) |	\
-      ((size << 2) & 0x007f0000) |	\
-      ((size << 1) & 0x00007f00) |	\
-      ((size     ) & 0x0000007f) )
-
-#define ID3_GET_SIZE28(size)		\
-    ( ((size & 0x7f000000) >> 3) |	\
-      ((size & 0x007f0000) >> 2) |	\
-      ((size & 0x00007f00) >> 1) |	\
-      ((size & 0x0000007f)     ) )
-#endif
-
-#define ID3_SET_SIZE28(size, a, b, c, d)	\
-do {						\
-	a = (size >> (24 + 3)) & 0x7f;		\
-	b = (size >> (16 + 2)) & 0x7f;		\
-	c = (size >> ( 8 + 1)) & 0x7f;		\
-	d = size & 0x7f;			\
-} while (0)
-
-#define ID3_GET_SIZE28(a, b, c, d)		\
-(((a & 0x7f) << (24 - 3)) |			\
- ((b & 0x7f) << (16 - 2)) |			\
- ((c & 0x7f) << ( 8 - 1)) |			\
- ((d & 0x7f)))
-
-
-
-/*
- * Layout for the extended header.
- */
-#if 0
-struct id3_exthdr {
-    guint32 eh_size;
-    guint16 eh_flags;
-    guint32 eh_padsize;
-};
-#endif
-
-#define ID3_EXTHDR_SIZE 10
-
-#define ID3_EHFLAG_CRC		0x80000000
-
-
-
-/*
- * Layout for the frame header.
- */
-#if 0
-struct id3_framehdr {
-    guint32 fh_id;
-    guint32 fh_size;
-    guint16 fh_flags;
-};
-#endif
-
-#define ID3_FRAMEHDR_SIZE 10
-
-
-#define ID3_FHFLAG_TAGALT	0x8000
-#define ID3_FHFLAG_FILEALT	0x4000
-#define ID3_FHFLAG_RO		0x2000
-#define ID3_FHFLAG_COMPRESS	0x0080
-#define ID3_FHFLAG_ENCRYPT	0x0040
-#define ID3_FHFLAG_GROUP	0x0020
-
-
-typedef enum {
-    ID3_UNI_LATIN = 0x007f,
-    ID3_UNI_LATIN_1 = 0x00ff,
-
-    ID3_UNI_SUPPORTED = 0x00ff,
-    ID3_UNI_UNSUPPORTED = 0xffff,
-} id3_unicode_blocks;
-
-#define DEBUG_ID3
-#ifdef DEBUG_ID3
-#define id3_error(id3, error)		\
-  (void) ( id3->id3_error_msg = error,	\
-           printf( "Error %s, line %d: %s\n", __FILE__, __LINE__, error ) )
-
-
-#else
-#define id3_error(id3, error)		\
-  (void) ( id3->id3_error_msg = error )
-
-#endif
-
-/*
- * Version 2.2.0 
- */
-
-/*
- * Layout for the frame header.
- */
-#if 0
-struct id3_framehdr {
-    char fh_id[3];
-    guint8 fh_size[3];
-};
-#endif
-
-#define ID3_FRAMEHDR_SIZE_22 6
-
-#endif                          /* ID3_HEADER_H */
--- a/Plugins/Input/mpg123/id3_tag.c	Sun Apr 23 15:11:43 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*********************************************************************
- * 
- *    Copyright (C) 1999-2000,  Espen Skoglund
- *    Department of Computer Science, University of Tromsų
- * 
- * Filename:      id3_tag.c
- * Description:   Code for handling ID3 tags.
- * Author:        Espen Skoglund <espensk@stud.cs.uit.no>
- * Created at:    Tue Feb  9 21:13:19 1999
- *                
- * $Id: id3_tag.c,v 1.6 2004/07/20 21:47:22 descender Exp $
- * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *                
- ********************************************************************/
-#include <glib.h>
-
-#include "xmms-id3.h"
-#include "id3_header.h"
-
-
-/*
- * Function id3_init_tag (id3)
- *
- *    Initialize an empty ID3 tag.
- *
- */
-void
-id3_init_tag(struct id3_tag *id3)
-{
-    /*
-     * Initialize header.
-     */
-    id3->id3_version = 3;
-    id3->id3_revision = 0;
-    id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP;
-    id3->id3_tagsize = 0;
-
-    id3->id3_altered = 1;
-    id3->id3_newtag = 1;
-    id3->id3_pos = 0;
-
-    /*
-     * Initialize frames.
-     */
-    id3->id3_frame = NULL;
-}
-
-
-/*
- * Function id3_read_tag (id3)
- *
- *    Read the ID3 tag from the input stream.  The start of the tag
- *    must be positioned in the next tag in the stream.  Return 0 upon
- *    success, or -1 if an error occured.
- *
- */
-int
-id3_read_tag(struct id3_tag *id3)
-{
-    char *buf;
-    gint  cyc = 0;	/* deal with malformed tags gracefully through iteration pacing */
-
-    /*
-     * We know that the tag will be at least this big.
-     *
-     * tag header + "ID3"
-     */
-    id3->id3_tagsize = ID3_TAGHDR_SIZE + 3;
-
-    if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) {
-        /*
-         * Check if we have a valid ID3 tag.
-         */
-        char *id = id3->id3_read(id3, NULL, 3);
-        if (id == NULL)
-            return -1;
-
-        if (id[0] != 'I' || id[1] != 'D' || id[2] != '3') {
-            /*
-             * ID3 tag was not detected.
-             */
-            id3->id3_seek(id3, -3);
-            return -1;
-        }
-    }
-
-    /*
-     * Read ID3 tag-header.
-     */
-    buf = id3->id3_read(id3, NULL, ID3_TAGHDR_SIZE);
-    if (buf == NULL)
-        return -1;
-
-    id3->id3_version = buf[0];
-    id3->id3_revision = buf[1];
-    id3->id3_flags = buf[2];
-    id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]);
-    id3->id3_newtag = 0;
-    id3->id3_pos = 0;
-
-    if (id3->id3_version < 2 || id3->id3_version > 4)
-        return -1;
-
-    /*
-     * Parse extended header.
-     */
-    if (id3->id3_flags & ID3_THFLAG_EXT) {
-        buf = id3->id3_read(id3, NULL, ID3_EXTHDR_SIZE);
-        if (buf == NULL)
-            return -1;
-    }
-
-    /*
-     * Parse frames.
-     */
-    while (id3->id3_pos < id3->id3_tagsize) {
-        if (id3_read_frame(id3) == -1)
-            return -1;
-
-	/* 100 iterations, this ID3 is definately hosed */
-	if (++cyc == 100)
-            return -1;
-    }
-
-    if (id3->id3_frame == NULL)
-	return -1;
-
-    return 0;
-}
--- a/Plugins/Input/mpg123/mpg123.c	Sun Apr 23 15:11:43 2006 -0700
+++ b/Plugins/Input/mpg123/mpg123.c	Sun Apr 23 15:50:33 2006 -0700
@@ -18,12 +18,12 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
-#include <libaudacious/util.h>
-#include <libaudacious/configdb.h>
-#include <libaudacious/vfs.h>
-#include <libaudacious/titlestring.h>
-
+#include "libaudacious/util.h"
+#include "libaudacious/configdb.h"
+#include "libaudacious/vfs.h"
+#include "libaudacious/titlestring.h"
 #include "audacious/util.h"
+#include <tag_c.h>
 
 static const long outscale = 32768;
 
@@ -45,6 +45,10 @@
 
 gchar **mpg123_id3_encoding_list = NULL;
 
+static TagLib_File *taglib_file;
+static TagLib_Tag *taglib_tag;
+static const TagLib_AudioProperties *taglib_ap;
+
 const char *mpg123_id3_genres[GENRE_MAX] = {
     N_("Blues"), N_("Classic Rock"), N_("Country"), N_("Dance"),
     N_("Disco"), N_("Funk"), N_("Grunge"), N_("Hip-Hop"),
@@ -455,38 +459,6 @@
         v2->track_number = 0;
 }
 
-static char *
-mpg123_getstr(char *str)
-{
-    if (str && strlen(str) > 0)
-        return str;
-    return NULL;
-}
-
-static gchar *
-convert_id3_title(gchar * title)
-{
-    gchar **encoding = mpg123_id3_encoding_list;
-    gchar *new_title = NULL;
-
-    if (g_utf8_validate(title, -1, NULL))
-        return title;
-
-    while (*encoding && !new_title) {
-        new_title = g_convert(title, strlen(title), "UTF-8", *encoding++,
-                              NULL, NULL, NULL);
-    }
-
-    if (new_title) {
-        g_free(title);
-        return new_title;
-    }
-
-    /* FIXME: We're relying on BMP core to provide fallback
-     * conversion */
-    return title;
-}
-
 /*
  * Function mpg123_format_song_title (tag, filename)
  *
@@ -495,21 +467,21 @@
  *
  */
 gchar *
-mpg123_format_song_title(struct id3tag_t * tag, gchar * filename)
+mpg123_format_song_title(TagLib_Tag *taglib_tag, gchar * filename)
 {
     gchar *title = NULL;
     TitleInput *input;
 
     input = bmp_title_input_new();
 
-    if (tag) {
-        input->performer = mpg123_getstr(tag->artist);
-        input->album_name = mpg123_getstr(tag->album);
-        input->track_name = mpg123_getstr(tag->title);
-        input->year = tag->year;
-        input->track_number = tag->track_number;
-        input->genre = mpg123_getstr(tag->genre);
-        input->comment = mpg123_getstr(tag->comment);
+    if (taglib_tag) {
+        input->performer = taglib_tag_artist(taglib_tag);
+        input->album_name = taglib_tag_album(taglib_tag);
+        input->track_name = taglib_tag_title(taglib_tag);
+        input->year = taglib_tag_year(taglib_tag);
+        input->track_number = taglib_tag_track(taglib_tag);
+        input->genre = taglib_tag_genre(taglib_tag);
+        input->comment = taglib_tag_comment(taglib_tag);
     }
 
     input->file_name = g_path_get_basename(filename);
@@ -531,127 +503,27 @@
     g_free(input->file_name);
     g_free(input);
 
-    if (mpg123_cfg.title_encoding_enabled)
-        title = convert_id3_title(title);
-
     return title;
 }
 
 /*
- * Function mpg123_get_id3v2 (id3d, tag)
- *
- *    Get desired contents from the indicated id3tag and store it in
- *    `tag'. 
- *
- */
-void
-mpg123_get_id3v2(struct id3_tag *id3d, struct id3tag_t *tag)
-{
-    struct id3_frame *id3frm;
-    gchar *txt;
-    gsize tlen;
-    gint num;
-
-#define ID3_SET(_tid,_fld)                                              \
-{                                                                       \
-        id3frm = id3_get_frame( id3d, _tid, 1 );                        \
-        if (id3frm) {                                                   \
-                txt = _tid == ID3_TCON ? id3_get_content(id3frm)        \
-                    : id3_get_text(id3frm);                             \
-                if(txt)                                                 \
-                {                                                       \
-                        tlen = strlen(txt);                             \
-                        if ( tlen >= sizeof(tag->_fld) )                \
-                                tlen = sizeof(tag->_fld)-1;             \
-                        strncpy( tag->_fld, txt, tlen );                \
-                        tag->_fld[tlen] = 0;                            \
-                        g_free(txt);                                    \
-                }                                                       \
-                else                                                    \
-                        tag->_fld[0] = 0;                               \
-        } else {                                                        \
-                tag->_fld[0] = 0;                                       \
-        }                                                               \
-}
-
-#define ID3_SET_NUM(_tid,_fld)                          \
-{                                                       \
-        id3frm = id3_get_frame(id3d, _tid, 1);          \
-        if (id3frm) {                                   \
-                num = id3_get_text_number(id3frm);      \
-                tag->_fld = num >= 0 ? num : 0;         \
-        } else                                          \
-                tag->_fld = 0;                          \
-}
-
-    ID3_SET(ID3_TIT2, title);
-    ID3_SET(ID3_TPE1, artist);
-    if (strlen(tag->artist) == 0)
-        ID3_SET(ID3_TPE2, artist);
-    ID3_SET(ID3_TALB, album);
-    ID3_SET_NUM(ID3_TYER, year);
-    ID3_SET_NUM(ID3_TRCK, track_number);
-    ID3_SET(ID3_COMM, comment);
-    ID3_SET(ID3_TCON, genre);
-}
-
-
-/*
- * Function get_song_title (fd, filename)
- *
- *    Get song title of file.  File position of `fd' will be
- *    clobbered.  `fd' may be NULL, in which case `filename' is opened
- *    separately.  The returned song title must be subsequently freed
- *    using g_free().
+ * Function get_song_title (filename)
  *
  */
 static gchar *
-get_song_title(VFSFile * fd, char *filename)
+get_song_title(char *filename)
 {
-    VFSFile *file = fd;
     char *ret = NULL;
-    struct id3v1tag_t id3v1tag;
-    struct id3tag_t id3tag;
-
-    if (file || (file = vfs_fopen(filename, "rb")) != 0) {
-        struct id3_tag *id3 = NULL;
-
-        /*
-         * Try reading ID3v2 tag.
-         */
-        if (!mpg123_cfg.disable_id3v2) {
-            vfs_fseek(file, 0, SEEK_SET);
-            id3 = id3_open_fp(file, 0);
-            if (id3) {
-                mpg123_get_id3v2(id3, &id3tag);
-                ret = mpg123_format_song_title(&id3tag, filename);
-                id3_close(id3);
-            }
-        }
-
-        /*
-         * Try reading ID3v1 tag.
-         */
-        if (!id3 && (vfs_fseek(file, -1 * sizeof(id3v1tag), SEEK_END) == 0) &&
-            (vfs_fread(&id3v1tag, 1, sizeof(id3v1tag), file) ==
-             sizeof(id3v1tag)) && (strncmp(id3v1tag.tag, "TAG", 3) == 0)) {
-            mpg123_id3v1_to_id3v2(&id3v1tag, &id3tag);
-            ret = mpg123_format_song_title(&id3tag, filename);
-        }
-
-        if (!fd)
-            /*
-             * File was opened in this function.
-             */
-            vfs_fclose(file);
+    taglib_file = taglib_file_new(filename);
+    if(taglib_file) {
+      taglib_tag = taglib_file_tag(taglib_file);
+      taglib_ap = taglib_file_audioproperties(taglib_file);
     }
 
-    if (ret == NULL)
-        /*
-         * Unable to get ID3 tag.
-         */
-        ret = mpg123_format_song_title(NULL, filename);
-
+    ret = mpg123_format_song_title(taglib_tag, filename);
+   
+    taglib_file_free(taglib_file);
+    taglib_tag_free_strings();
     return ret;
 }
 
@@ -729,8 +601,7 @@
 
     if ((file = vfs_fopen(filename, "rb")) != NULL) {
         (*len_real) = get_song_time(file);
-        (*title_real) = get_song_title(file, filename);
-        vfs_fclose(file);
+        (*title_real) = get_song_title(filename);
     }
 }
 
@@ -849,7 +720,7 @@
         if (strncasecmp(filename, "http://", 7)) {
             mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000;
             if (!mpg123_title)
-                mpg123_title = get_song_title(NULL, filename);
+                mpg123_title = get_song_title(filename);
         }
         else {
             if (!mpg123_title)
--- a/Plugins/Input/mpg123/mpg123.h	Sun Apr 23 15:11:43 2006 -0700
+++ b/Plugins/Input/mpg123/mpg123.h	Sun Apr 23 15:50:33 2006 -0700
@@ -11,7 +11,7 @@
 #endif
 
 #include <glib.h>
-
+#include <tag_c.h>
 
 enum {
     SYNTH_AUTO,
@@ -302,8 +302,7 @@
 double mpg123_compute_bpf(struct frame *fr);
 double mpg123_compute_tpf(struct frame *fr);
 guint mpg123_strip_spaces(char *src, size_t n);
-void mpg123_get_id3v2(struct id3_tag *id3d, struct id3tag_t *tag);
-gchar *mpg123_format_song_title(struct id3tag_t *tag, gchar * filename);
+gchar *mpg123_format_song_title(TagLib_Tag *taglib_tag, gchar * filename);
 double mpg123_relative_pos(void);