diff -Nru mp3fs-0.12.orig/src/Makefile.am mp3fs-0.12/src/Makefile.am --- mp3fs-0.12.orig/src/Makefile.am 2007-11-15 14:34:32.000000000 +0900 +++ mp3fs-0.12/src/Makefile.am 2008-04-17 01:40:14.000000000 +0900 @@ -1,4 +1,4 @@ bin_PROGRAMS = mp3fs -mp3fs_SOURCES = mp3fs.c transcode.c transcode.h class.c class.h stringio.c stringio.h talloc.c talloc.h +mp3fs_SOURCES = mp3fs.c transcode.c transcode.h class.c class.h stringio.c stringio.h talloc.c talloc.h id3.cpp mp3fs_CFLAGS = $(fuse_CFLAGS) $(id3tag_CFLAGS) -mp3fs_LDFLAGS = -lFLAC -logg -lmp3lame $(fuse_LIBS) $(id3tag_LIBS) +mp3fs_LDFLAGS = -lFLAC -logg -lmp3lame -lid3 $(fuse_LIBS) $(id3tag_LIBS) diff -Nru mp3fs-0.12.orig/src/Makefile.in mp3fs-0.12/src/Makefile.in --- mp3fs-0.12.orig/src/Makefile.in 2008-03-09 16:30:47.000000000 +0900 +++ mp3fs-0.12/src/Makefile.in 2008-04-17 01:40:14.000000000 +0900 @@ -50,7 +50,7 @@ PROGRAMS = $(bin_PROGRAMS) am_mp3fs_OBJECTS = mp3fs-mp3fs.$(OBJEXT) mp3fs-transcode.$(OBJEXT) \ mp3fs-class.$(OBJEXT) mp3fs-stringio.$(OBJEXT) \ - mp3fs-talloc.$(OBJEXT) + mp3fs-talloc.$(OBJEXT) id3.$(OBJEXT) mp3fs_OBJECTS = $(am_mp3fs_OBJECTS) mp3fs_LDADD = $(LDADD) DEFAULT_INCLUDES = -I. -I$(srcdir) @@ -64,6 +64,14 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(mp3fs_SOURCES) DIST_SOURCES = $(mp3fs_SOURCES) ETAGS = etags @@ -176,13 +184,13 @@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -mp3fs_SOURCES = mp3fs.c transcode.c transcode.h class.c class.h stringio.c stringio.h talloc.c talloc.h +mp3fs_SOURCES = mp3fs.c transcode.c transcode.h class.c class.h stringio.c stringio.h talloc.c talloc.h id3.cpp mp3fs_CFLAGS = $(fuse_CFLAGS) $(id3tag_CFLAGS) -mp3fs_LDFLAGS = -lFLAC -logg -lmp3lame $(fuse_LIBS) $(id3tag_LIBS) +mp3fs_LDFLAGS = -lFLAC -logg -lmp3lame -lid3 $(fuse_LIBS) $(id3tag_LIBS) all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj +.SUFFIXES: .c .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -242,7 +250,7 @@ done mp3fs$(EXEEXT): $(mp3fs_OBJECTS) $(mp3fs_DEPENDENCIES) @rm -f mp3fs$(EXEEXT) - $(LINK) $(mp3fs_LDFLAGS) $(mp3fs_OBJECTS) $(mp3fs_LDADD) $(LIBS) + $(CXXLINK) $(mp3fs_LDFLAGS) $(mp3fs_OBJECTS) $(mp3fs_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -250,6 +258,7 @@ distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp3fs-class.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp3fs-mp3fs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mp3fs-stringio.Po@am__quote@ @@ -347,6 +356,27 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mp3fs_CFLAGS) $(CFLAGS) -c -o mp3fs-talloc.obj `if test -f 'talloc.c'; then $(CYGPATH_W) 'talloc.c'; else $(CYGPATH_W) '$(srcdir)/talloc.c'; fi` +.cpp.o: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + mostlyclean-libtool: -rm -f *.lo diff -Nru mp3fs-0.12.orig/src/id3.cpp mp3fs-0.12/src/id3.cpp --- mp3fs-0.12.orig/src/id3.cpp 1970-01-01 09:00:00.000000000 +0900 +++ mp3fs-0.12/src/id3.cpp 2008-04-19 17:59:16.000000000 +0900 @@ -0,0 +1,106 @@ +#include +#include + +static const char *id3tag_frame_ids[] = +{ + ID3_FRAME_TITLE, + ID3_FRAME_ARTIST, + ID3_FRAME_ALBUM, + ID3_FRAME_TRACK, + ID3_FRAME_YEAR, + ID3_FRAME_GENRE, + ID3_FRAME_COMMENT, + NULL, +}; + +static const ID3_FrameID id3lib_frame_ids[] = +{ + ID3FID_TITLE, + ID3FID_LEADARTIST, + ID3FID_ALBUM, + ID3FID_TRACKNUM, + ID3FID_YEAR, + ID3FID_CONTENTTYPE, + ID3FID_COMMENT, +}; + +const char *get_field_rawstring(const id3_ucs4_t *str, id3_field_textencoding encoding) +{ + if (encoding == ID3_FIELD_TEXTENCODING_UTF_16 || + encoding == ID3_FIELD_TEXTENCODING_UTF_16BE) + return reinterpret_cast(id3_ucs4_utf16duplicate(str)); + else if (encoding == ID3_FIELD_TEXTENCODING_UTF_8) + return reinterpret_cast(id3_ucs4_utf8duplicate(str)); + else + return reinterpret_cast(id3_ucs4_latin1duplicate(str)); +} + +extern "C" int id3lib_render_id3tag(struct id3_tag *tag, unsigned char *buffer) +{ + ID3_Tag t; + + const char **fid = id3tag_frame_ids; + for (int i = 0; *fid != NULL; fid++, i++) { + struct id3_frame *frame = id3_tag_findframe(tag, *fid, 0); + if (frame != NULL) { + ID3_Frame f(id3lib_frame_ids[i]); + id3_field_textencoding encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1; + + for (int j = 0;; j++) { + union id3_field *field = id3_frame_field(frame, j); + if (field == NULL) + break; + + enum id3_field_type type = id3_field_type(field); + switch (type) { + case ID3_FIELD_TYPE_TEXTENCODING: + encoding = id3_field_gettextencoding(field); + f.GetField(ID3FN_TEXTENC)->SetEncoding( + encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1 ? ID3TE_ISO8859_1 : + encoding == ID3_FIELD_TEXTENCODING_UTF_16 ? ID3TE_UTF16 : + encoding == ID3_FIELD_TEXTENCODING_UTF_16BE ? ID3TE_UTF16BE : + encoding == ID3_FIELD_TEXTENCODING_UTF_8 ? ID3TE_UTF8 : + ID3TE_NONE); + break; + case ID3_FIELD_TYPE_LATIN1: + f.GetField(ID3FN_TEXT)->Set(reinterpret_cast(id3_field_getlatin1(field))); + break; + case ID3_FIELD_TYPE_LATIN1FULL: + f.GetField(ID3FN_TEXT)->Set(reinterpret_cast(id3_field_getfulllatin1(field))); + break; + + case ID3_FIELD_TYPE_LATIN1LIST: + { + int size = id3_field_getnstrings(field); + for (int k = 0; k < size; k++) { + f.GetField(ID3FN_TEXT)->Add(reinterpret_cast(id3_field_getstrings(field, k))); + } + break; + } + case ID3_FIELD_TYPE_STRING: + f.GetField(ID3FN_TEXT)->Set(get_field_rawstring(id3_field_getstring(field), encoding)); + break; + case ID3_FIELD_TYPE_STRINGFULL: + f.GetField(ID3FN_TEXT)->Set(get_field_rawstring(id3_field_getfullstring(field), encoding)); + break; + + case ID3_FIELD_TYPE_STRINGLIST: + { + int size = id3_field_getnstrings(field); + for (int k = 0; k < size; k++) { + f.GetField(ID3FN_TEXT)->Add(get_field_rawstring(id3_field_getstrings(field, k), encoding)); + } + break; + } + } + } + + t.AddFrame(f); + } + } + + if (buffer == NULL) + return t.Size(); + else + return t.Render(buffer); +} diff -Nru mp3fs-0.12.orig/src/transcode.c mp3fs-0.12/src/transcode.c --- mp3fs-0.12.orig/src/transcode.c 2008-03-08 13:32:43.000000000 +0900 +++ mp3fs-0.12/src/transcode.c 2008-04-19 17:59:32.000000000 +0900 @@ -38,6 +38,8 @@ #include "transcode.h" #include "talloc.h" +int id3lib_render_id3tag(struct id3_tag *tag, unsigned char *buffer); + /******************************************************************* CALLBACKS and HELPERS for LAME and FLAC *******************************************************************/ @@ -228,16 +230,11 @@ *******************************************************************/ FileTranscoder FileTranscoder_Con(FileTranscoder self, char *filename) { + struct id3_file *id3file; + self->buffer = CONSTRUCT(StringIO, StringIO, Con, self); self->name = talloc_strdup(self, filename); - self->id3tag = id3_tag_new(); - if(self->id3tag == NULL) { - goto id3_fail; - } - - id3_tag_attachframe(self->id3tag, make_frame("TSSE", "MP3FS")); - // set the original (flac) filename self->orig_name = talloc_size(self, strlen(self->name) + 2); strncpy(self->orig_name, self->name, strlen(self->name)); @@ -249,6 +246,16 @@ if (strcmp(ptr, ".mp3") == 0) strcpy(ptr, ".flac"); } + + // try to read id3tag from the original file + id3file = id3_file_open(self->orig_name, ID3_FILE_MODE_READONLY); + if(id3file != NULL) + self->id3tag = id3_file_tag(id3file); + if(self->id3tag == NULL) + self->id3tag = id3_tag_new(); + if(self->id3tag == NULL) + goto id3_fail; + //id3_tag_attachframe(self->id3tag, make_frame("TSSE", "MP3FS")); // create and initialise decoder #ifdef LEGACY_FLAC @@ -333,8 +340,13 @@ // id3v1 tag is written into a fixed 128 byte buffer (it is a fixed size) // grow buffer and write v2 tag - CALL(self->buffer, seek, id3_tag_render(self->id3tag, 0), SEEK_SET); - id3_tag_render(self->id3tag, (id3_byte_t *)self->buffer->data); + if(0) { // libid3tag seems not to be able to write ID3v2 + CALL(self->buffer, seek, id3_tag_render(self->id3tag, 0), SEEK_SET); + id3_tag_render(self->id3tag, (id3_byte_t *)self->buffer->data); + } else { + CALL(self->buffer, seek, id3lib_render_id3tag(self->id3tag, NULL), SEEK_SET); + id3lib_render_id3tag(self->id3tag, self->buffer->data); + } // store v1 tag id3_tag_options(self->id3tag, ID3_TAG_OPTION_ID3V1, ~0); @@ -347,6 +359,8 @@ + 128; id3_tag_delete(self->id3tag); + if(id3file != NULL) + id3_file_close(id3file); return self; init_encoder_fail: @@ -362,6 +376,8 @@ flac_fail: id3_tag_delete(self->id3tag); + if (id3file != NULL) + id3_file_close(id3file); id3_fail: talloc_free(self);