Mercurial > audlegacy
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);