summaryrefslogtreecommitdiffstats
path: root/media-libs/taglib/files
diff options
context:
space:
mode:
Diffstat (limited to 'media-libs/taglib/files')
-rw-r--r--media-libs/taglib/files/taglib-1.10-ds-rusxmms.patch1339
-rw-r--r--media-libs/taglib/files/taglib-1.6.1-install-examples.patch16
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-abi-breakage.patch107
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-bytevector-simpler.patch131
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-ds-rusxmms-enforce.patch20
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-ds-rusxmms.patch676
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-missing-deletes.patch48
-rw-r--r--media-libs/taglib/files/taglib-1.9.1-order-big-endian.patch33
8 files changed, 2370 insertions, 0 deletions
diff --git a/media-libs/taglib/files/taglib-1.10-ds-rusxmms.patch b/media-libs/taglib/files/taglib-1.10-ds-rusxmms.patch
new file mode 100644
index 0000000..584c237
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.10-ds-rusxmms.patch
@@ -0,0 +1,1339 @@
+diff -dPNur taglib-1.10/config.h.cmake taglib-1.10-ds/config.h.cmake
+--- taglib-1.10/config.h.cmake 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/config.h.cmake 2015-11-26 23:03:07.058061207 +0100
+@@ -25,4 +25,7 @@
+ /* Indicates whether debug messages are shown even in release mode */
+ #cmakedefine TRACE_IN_RELEASE 1
+
++/* Defined if you have LibRCC from RusXMMS project */
++#cmakedefine HAVE_LIBRCC 1
++
+ #cmakedefine TESTS_DIR "@TESTS_DIR@"
+diff -dPNur taglib-1.10/ConfigureChecks.cmake taglib-1.10-ds/ConfigureChecks.cmake
+--- taglib-1.10/ConfigureChecks.cmake 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/ConfigureChecks.cmake 2015-11-26 23:03:07.058061207 +0100
+@@ -201,6 +201,8 @@
+ endif()
+ endif()
+
++SET(HAVE_LIBRCC 1)
++
+ if(BUILD_TESTS)
+ find_package(CppUnit)
+ if(NOT CppUnit_FOUND)
+diff -dPNur taglib-1.10/examples/tagreader_c.c taglib-1.10-ds/examples/tagreader_c.c
+--- taglib-1.10/examples/tagreader_c.c 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/examples/tagreader_c.c 2015-11-26 23:03:07.059061228 +0100
+@@ -38,7 +38,7 @@
+ TagLib_Tag *tag;
+ const TagLib_AudioProperties *properties;
+
+- taglib_set_strings_unicode(FALSE);
++ //taglib_set_strings_unicode(FALSE);
+
+ for(i = 1; i < argc; i++) {
+ printf("******************** \"%s\" ********************\n", argv[i]);
+diff -dPNur taglib-1.10/examples/tagwriter.cpp taglib-1.10-ds/examples/tagwriter.cpp
+--- taglib-1.10/examples/tagwriter.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/examples/tagwriter.cpp 2015-11-26 23:03:07.059061228 +0100
+@@ -115,7 +115,7 @@
+ if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) {
+
+ char field = argv[i][1];
+- TagLib::String value = argv[i + 1];
++ TagLib::String value(argv[i + 1], TagLib::String::Locale);
+
+ TagLib::List<TagLib::FileRef>::ConstIterator it;
+ for(it = fileList.begin(); it != fileList.end(); ++it) {
+diff -dPNur taglib-1.10/taglib/CMakeLists.txt taglib-1.10-ds/taglib/CMakeLists.txt
+--- taglib-1.10/taglib/CMakeLists.txt 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/CMakeLists.txt 2015-11-26 23:03:07.059061228 +0100
+@@ -38,6 +38,7 @@
+ audioproperties.h
+ taglib_export.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h
++ toolkit/rccpatch.h
+ toolkit/taglib.h
+ toolkit/tstring.h
+ toolkit/tlist.h
+@@ -291,6 +292,7 @@
+ )
+
+ set(toolkit_SRCS
++ toolkit/rccpatch.cpp
+ toolkit/tstring.cpp
+ toolkit/tstringlist.cpp
+ toolkit/tbytevector.cpp
+@@ -337,7 +339,7 @@
+ add_library(tag ${tag_LIB_SRCS} ${tag_HDRS})
+
+ if(ZLIB_FOUND)
+- target_link_libraries(tag ${ZLIB_LIBRARIES})
++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES})
+ endif()
+
+ set_target_properties(tag PROPERTIES
+diff -dPNur taglib-1.10/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.10-ds/taglib/mpeg/id3v1/id3v1tag.cpp
+--- taglib-1.10/taglib/mpeg/id3v1/id3v1tag.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2015-11-26 23:03:07.059061228 +0100
+@@ -64,17 +64,18 @@
+
+ String ID3v1::StringHandler::parse(const ByteVector &data) const
+ {
+- return String(data, String::Latin1).stripWhiteSpace();
++ return String(data, String::Latin1ID3).stripWhiteSpace();
+ }
+
+ ByteVector ID3v1::StringHandler::render(const String &s) const
+ {
+ if(!s.isLatin1())
+ {
++ if (String::ID3WType(String::Latin1) == String::Latin1)
+ return ByteVector();
+ }
+
+- return s.data(String::Latin1);
++ return s.data(String::Latin1ID3);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+@@ -257,7 +258,7 @@
+ d->track = uchar(data[offset + 29]);
+ }
+ else
+- d->comment = data.mid(offset, 30);
++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30));
+
+ offset += 30;
+
+diff -dPNur taglib-1.10/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.10-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp
+--- taglib-1.10/taglib/mpeg/id3v2/frames/commentsframe.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2015-11-26 23:03:07.059061228 +0100
+@@ -150,10 +150,10 @@
+ return;
+ }
+
+- d->textEncoding = String::Type(data[0]);
++ d->textEncoding = String::ID3Type(data[0]);
+ d->language = data.mid(1, 3);
+
+- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
+
+ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
+
+@@ -173,11 +173,13 @@
+ ByteVector v;
+
+ String::Type encoding = d->textEncoding;
++
++ encoding = String::ID3WType(encoding);
+
+ encoding = checkTextEncoding(d->description, encoding);
+ encoding = checkTextEncoding(d->text, encoding);
+
+- v.append(char(encoding));
++ v.append(char(String::ID3RealType(encoding)));
+ v.append(d->language.size() == 3 ? d->language : "XXX");
+ v.append(d->description.data(encoding));
+ v.append(textDelimiter(encoding));
+diff -dPNur taglib-1.10/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.10-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
+--- taglib-1.10/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2015-11-26 23:03:07.059061228 +0100
+@@ -187,12 +187,12 @@
+
+ // read the string data type (the first byte of the field data)
+
+- d->textEncoding = String::Type(data[0]);
++ d->textEncoding = String::ID3Type(data[0]);
+
+ // split the byte array into chunks based on the string type (two byte delimiter
+ // for unicode encodings)
+
+- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
+
+ // build a small counter to strip nulls off the end of the field
+
+@@ -223,11 +223,14 @@
+
+ ByteVector TextIdentificationFrame::renderFields() const
+ {
+- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding);
++ String::Type encoding = d->textEncoding;
++
++ encoding = String::ID3WType(encoding);
++ encoding = checkTextEncoding(d->fieldList, encoding);
+
+ ByteVector v;
+
+- v.append(char(encoding));
++ v.append(char(String::ID3RealType(encoding)));
+
+ for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
+
+diff -dPNur taglib-1.10/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.10-ds/taglib/mpeg/id3v2/id3v2frame.cpp
+--- taglib-1.10/taglib/mpeg/id3v2/id3v2frame.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2015-11-26 23:03:07.060061249 +0100
+@@ -339,7 +339,7 @@
+ if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4)
+ return String::UTF16;
+
+- if(encoding != String::Latin1)
++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2))
+ return encoding;
+
+ for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
+diff -dPNur taglib-1.10/taglib/toolkit/rccpatch.cpp taglib-1.10-ds/taglib/toolkit/rccpatch.cpp
+--- taglib-1.10/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100
++++ taglib-1.10-ds/taglib/toolkit/rccpatch.cpp 2015-11-26 23:03:07.060061249 +0100
+@@ -0,0 +1,237 @@
++#include <stdlib.h>
++
++#include <string>
++#include "tstring.h"
++#include "tbytevector.h"
++
++//#define RCC_DEBUG
++
++
++#ifndef HAVE_LIBRCC
++# include <config.h>
++#endif
++
++#ifdef HAVE_LIBRCC
++# ifdef RCC_DEBUG
++# include <stdio.h>
++# endif /* RCC_DEBUG */
++# include <librcc.h>
++# include <string.h>
++#endif /* HAVE_LIBRCC */
++
++
++#ifdef HAVE_LIBRCC
++# define ID3_CLASS 0
++# define ID3V2_CLASS 1
++# define UTF_CLASS 2
++# define OUT_CLASS 3
++static rcc_class classes[] = {
++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 },
++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 },
++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0},
++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 },
++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 }
++};
++
++static int rcc_initialized = 0;
++
++static rcc_context ctx = NULL;
++#endif /* HAVE_LIBRCC */
++
++
++void rccTaglibPatchFree() {
++#ifdef HAVE_LIBRCC
++ if (rcc_initialized) {
++ rccFree();
++ rcc_initialized = 0;
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++void rccTaglibPatchInit() {
++#ifdef HAVE_LIBRCC
++ if (rcc_initialized) return;
++ rccInit();
++ rccInitDefaultContext(NULL, 0, 0, classes, 0);
++ rccLoad(NULL, "xmms");
++ rccInitDb4(NULL, NULL, 0);
++ rcc_initialized = 1;
++#endif /* HAVE_LIBRCC */
++}
++
++void rccTaglibPatchSetContext(void *newctx) {
++#ifdef HAVE_LIBRCC
++ if (newctx) {
++ ctx = (rcc_context)newctx;
++ rcc_initialized = 1;
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++static void rccTaglibPatchTryInit() {
++#ifdef HAVE_LIBRCC
++ if (!rcc_initialized) {
++ rccTaglibPatchInit();
++ if (rcc_initialized) atexit(rccTaglibPatchFree);
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++
++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else v.setData("", 0);
++ //v.setData(s.c_str(), s.length());
++
++ return v;
++#else
++ v.setData("", 0);
++
++ return v;
++#endif /* HAVE_LIBRCC */
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else v.setData("", 0);
++ //v.setData(s.c_str(), s.length());
++
++ return v;
++#else
++ v.setData("", 0);
++
++ return v;
++#endif /* HAVE_LIBRCC */
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else
++#endif /* HAVE_LIBRCC */
++ v.setData("", 0);
++
++ return v;
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++ if (res) v.setData(res, rlen + 1);
++ else
++#endif /* HAVE_LIBRCC */
++ v.setData("", 0);
++
++ return v;
++}
++
++TagLib::String::Type rccTaglibPatchGetLocaleType() {
++#ifdef HAVE_LIBRCC
++ size_t len;
++ char charset[32];
++
++ rccTaglibPatchTryInit();
++ if (!rccLocaleGetCharset(charset, NULL, 31)) {
++ if (!strncmp(charset, "UTF", 3)) {
++ len = strlen(charset);
++
++ if (charset[len-1]=='8') return TagLib::String::UTF8;
++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
++ }
++ return TagLib::String::Latin1;
++ }
++#endif /* HAVE_LIBRCC */
++ return TagLib::String::UTF8;
++}
++
++TagLib::String::Type rccTaglibPatchGetID3Type() {
++#ifdef HAVE_LIBRCC
++ size_t len;
++ const char *charset;
++
++ rccTaglibPatchTryInit();
++
++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS);
++ if (charset) {
++ if (!strncmp(charset, "UTF", 3)) {
++ len = strlen(charset);
++
++ if (charset[len-1]=='8') return TagLib::String::UTF8;
++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
++ }
++ return TagLib::String::Latin1ID3V2;
++ } else {
++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib
++ return TagLib::String::Latin1ID3V2;
++ }
++#endif /* HAVE_LIBRCC */
++ return TagLib::String::Latin1;
++}
+diff -dPNur taglib-1.10/taglib/toolkit/rccpatch.h taglib-1.10-ds/taglib/toolkit/rccpatch.h
+--- taglib-1.10/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100
++++ taglib-1.10-ds/taglib/toolkit/rccpatch.h 2015-11-26 23:03:07.060061249 +0100
+@@ -0,0 +1,20 @@
++#ifndef _RCC_PATCH_H
++#define _RCC_PATCH_H
++
++#include <string.h>
++#include "tstring.h"
++#include "tbytevector.h"
++
++void rccTaglibPatchFree();
++void rccTaglibPatchInit();
++void rccTaglibPatchSetContext(void *newctx);
++
++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s);
++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s);
++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false);
++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false);
++
++TagLib::String::Type rccTaglibPatchGetLocaleType();
++TagLib::String::Type rccTaglibPatchGetID3Type();
++
++#endif /* _RCC_PATCH_H */
+diff -dPNur taglib-1.10/taglib/toolkit/tstring.cpp taglib-1.10-ds/taglib/toolkit/tstring.cpp
+--- taglib-1.10/taglib/toolkit/tstring.cpp 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/toolkit/tstring.cpp 2015-11-26 23:10:01.286853654 +0100
+@@ -29,6 +29,7 @@
+ #include <config.h>
+ #endif
+
++#include "rccpatch.h"
+ #include "tstring.h"
+ #include "tdebug.h"
+ #include "tstringlist.h"
+@@ -167,8 +168,11 @@
+ String::String(const std::string &s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == Latin1)
+- copyFromLatin1(s.c_str(), s.length());
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(&s[0], s.length(), true, t);
+ else if(t == String::UTF8)
+ copyFromUTF8(s.c_str(), s.length());
+ else {
+@@ -215,8 +219,11 @@
+ String::String(const char *s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == Latin1)
+- copyFromLatin1(s, ::strlen(s));
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(s, ::strlen(s), true, t);
+ else if(t == String::UTF8)
+ copyFromUTF8(s, ::strlen(s));
+ else {
+@@ -237,7 +244,10 @@
+ String::String(char c, Type t)
+ : d(new StringPrivate(1, static_cast<uchar>(c)))
+ {
+- if(t != Latin1 && t != UTF8) {
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t != Latin1 && t != Latin1ID3 && t != Latin1ID3V2 && t != UTF8) {
+ debug("String::String() -- char should not contain UTF16.");
+ }
+ }
+@@ -248,8 +258,11 @@
+ if(v.isEmpty())
+ return;
+
+- if(t == Latin1)
+- copyFromLatin1(v.data(), v.size());
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(v.data(), v.size(), true, t);
+ else if(t == UTF8)
+ copyFromUTF8(v.data(), v.size());
+ else
+@@ -396,8 +409,38 @@
+
+ ByteVector String::data(Type t) const
+ {
+- switch(t)
+- {
++ ByteVector v;
++
++ if (t == Locale) {
++ // The source is either Unicode or real Latin1 (if rcc is bypassed)
++ std::string s = to8Bit(true);
++
++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich
++ v = rccTaglibPatchRecodeOutput(s);
++ if (v.size()) return v;
++
++ t = rccTaglibPatchGetLocaleType();
++ }
++
++ switch(t) {
++ case Latin1ID3:
++ case Latin1ID3V2:
++ {
++ std::string s = to8Bit(true);
++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false);
++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true);
++ if (v.size())
++ return v;
++
++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required
++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) {
++ v.setData(s.c_str(), s.length());
++ } else {
++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
++ v.append(char(*it));
++ }
++ return v;
++ }
+ case Latin1:
+ {
+ ByteVector v(size(), 0);
+@@ -738,12 +781,30 @@
+ // private members
+ ////////////////////////////////////////////////////////////////////////////////
+
+-void String::copyFromLatin1(const char *s, size_t length)
++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t)
+ {
+ d->data.resize(length);
+
+ for(size_t i = 0; i < length; ++i)
+ d->data[i] = static_cast<uchar>(s[i]);
++
++ // librcc conversation
++ if (prepare) {
++ std::string s = to8Bit(false);
++ ByteVector v;
++
++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false);
++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true);
++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s);
++
++ if (v.size()) {
++ copyFromUTF8(v.data(), v.size());
++ } else {
++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed,
++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8
++ //if (Unicode::isLegalUTF8(s)) t = UTF8;
++ }
++ }
+ }
+
+ void String::copyFromUTF8(const char *s, size_t length)
+@@ -859,7 +920,33 @@
+
+ std::ostream &operator<<(std::ostream &s, const TagLib::String &str)
+ {
+- s << str.to8Bit();
++ TagLib::ByteVector bv = str.data(TagLib::String::Locale);
++ s << bv;
+ return s;
+ }
+
++TagLib::String::Type TagLib::String::ID3Type(int i)
++{
++ if(i == Latin1)
++ return Latin1ID3V2;
++ return Type(i);
++};
++
++TagLib::String::Type TagLib::String::ID3WType(Type type)
++{
++ Type rcc_type = rccTaglibPatchGetID3Type();
++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) {
++ if(type == Latin1) return
++ rcc_type;
++ return type;
++ }
++
++ return rcc_type;
++};
++
++TagLib::String::Type TagLib::String::ID3RealType(Type type)
++{
++ if((type == Latin1ID3) || (type == Latin1ID3V2))
++ return Latin1;
++ return type;
++}
+diff -dPNur taglib-1.10/taglib/toolkit/tstring.h taglib-1.10-ds/taglib/toolkit/tstring.h
+--- taglib-1.10/taglib/toolkit/tstring.h 2015-11-11 22:41:59.000000000 +0100
++++ taglib-1.10-ds/taglib/toolkit/tstring.h 2015-11-26 23:03:07.061061271 +0100
+@@ -96,6 +96,18 @@
+ */
+ enum Type {
+ /*!
++ * Determine using current locale settings
++ */
++ Locale = -1,
++ /*!
++ * Latin1 for ID3 tags.
++ */
++ Latin1ID3 = 65,
++ /*!
++ * Latin1 for ID3v2 tags.
++ */
++ Latin1ID3V2 = 66,
++ /*!
+ * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters.
+ */
+ Latin1 = 0,
+@@ -117,6 +129,10 @@
+ */
+ UTF16LE = 4
+ };
++
++ static Type ID3Type(int i);
++ static Type ID3WType(Type type);
++ static Type ID3RealType(Type type);
+
+ /*!
+ * Constructs an empty String.
+@@ -519,7 +535,7 @@
+ * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order)
+ * and copies it to the internal buffer.
+ */
+- void copyFromLatin1(const char *s, size_t length);
++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1);
+
+ /*!
+ * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order)
+diff -dPNur taglib-1.10/taglib-1.10-ds-rusxmms.patch taglib-1.10-ds/taglib-1.10-ds-rusxmms.patch
+--- taglib-1.10/taglib-1.10-ds-rusxmms.patch 1970-01-01 01:00:00.000000000 +0100
++++ taglib-1.10-ds/taglib-1.10-ds-rusxmms.patch 2015-11-14 15:40:37.000000000 +0100
+@@ -0,0 +1,669 @@
++diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
++index 88980ea..e4f44d3 100644
++--- a/ConfigureChecks.cmake
+++++ b/ConfigureChecks.cmake
++@@ -201,6 +201,8 @@ if(NOT ZLIB_SOURCE)
++ endif()
++ endif()
++
+++SET(HAVE_LIBRCC 1)
+++
++ if(BUILD_TESTS)
++ find_package(CppUnit)
++ if(NOT CppUnit_FOUND)
++diff --git a/config.h.cmake b/config.h.cmake
++index ee0e67a..2abd49c 100644
++--- a/config.h.cmake
+++++ b/config.h.cmake
++@@ -25,4 +25,7 @@
++ /* Indicates whether debug messages are shown even in release mode */
++ #cmakedefine TRACE_IN_RELEASE 1
++
+++/* Defined if you have LibRCC from RusXMMS project */
+++#cmakedefine HAVE_LIBRCC 1
+++
++ #cmakedefine TESTS_DIR "@TESTS_DIR@"
++diff --git a/examples/tagreader_c.c b/examples/tagreader_c.c
++index 0436992..e0f17d8 100644
++--- a/examples/tagreader_c.c
+++++ b/examples/tagreader_c.c
++@@ -38,7 +38,7 @@ int main(int argc, char *argv[])
++ TagLib_Tag *tag;
++ const TagLib_AudioProperties *properties;
++
++- taglib_set_strings_unicode(FALSE);
+++ //taglib_set_strings_unicode(FALSE);
++
++ for(i = 1; i < argc; i++) {
++ printf("******************** \"%s\" ********************\n", argv[i]);
++diff --git a/examples/tagwriter.cpp b/examples/tagwriter.cpp
++index ed8b0d7..6a7a263 100644
++--- a/examples/tagwriter.cpp
+++++ b/examples/tagwriter.cpp
++@@ -115,7 +115,7 @@ int main(int argc, char *argv[])
++ if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) {
++
++ char field = argv[i][1];
++- TagLib::String value = argv[i + 1];
+++ TagLib::String value(argv[i + 1], TagLib::String::Locale);
++
++ TagLib::List<TagLib::FileRef>::ConstIterator it;
++ for(it = fileList.begin(); it != fileList.end(); ++it) {
++diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt
++index 73c1a2f..cd7ea22 100644
++--- a/taglib/CMakeLists.txt
+++++ b/taglib/CMakeLists.txt
++@@ -38,6 +38,7 @@ set(tag_HDRS
++ audioproperties.h
++ taglib_export.h
++ ${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h
+++ toolkit/rccpatch.h
++ toolkit/taglib.h
++ toolkit/tstring.h
++ toolkit/tlist.h
++@@ -291,6 +292,7 @@ set(xm_SRCS
++ )
++
++ set(toolkit_SRCS
+++ toolkit/rccpatch.cpp
++ toolkit/tstring.cpp
++ toolkit/tstringlist.cpp
++ toolkit/tbytevector.cpp
++@@ -337,7 +339,7 @@ set(tag_LIB_SRCS
++ add_library(tag ${tag_LIB_SRCS} ${tag_HDRS})
++
++ if(ZLIB_FOUND)
++- target_link_libraries(tag ${ZLIB_LIBRARIES})
+++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES})
++ endif()
++
++ set_target_properties(tag PROPERTIES
++diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp
++index 9fc8cfd..5352acc 100644
++--- a/taglib/mpeg/id3v1/id3v1tag.cpp
+++++ b/taglib/mpeg/id3v1/id3v1tag.cpp
++@@ -64,17 +64,18 @@ StringHandler::StringHandler()
++
++ String ID3v1::StringHandler::parse(const ByteVector &data) const
++ {
++- return String(data, String::Latin1).stripWhiteSpace();
+++ return String(data, String::Latin1ID3).stripWhiteSpace();
++ }
++
++ ByteVector ID3v1::StringHandler::render(const String &s) const
++ {
++ if(!s.isLatin1())
++ {
+++ if (String::ID3WType(String::Latin1) == String::Latin1)
++ return ByteVector();
++ }
++
++- return s.data(String::Latin1);
+++ return s.data(String::Latin1ID3);
++ }
++
++ ////////////////////////////////////////////////////////////////////////////////
++@@ -257,7 +258,7 @@ void ID3v1::Tag::parse(const ByteVector &data)
++ d->track = uchar(data[offset + 29]);
++ }
++ else
++- d->comment = data.mid(offset, 30);
+++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30));
++
++ offset += 30;
++
++diff --git a/taglib/mpeg/id3v2/frames/commentsframe.cpp b/taglib/mpeg/id3v2/frames/commentsframe.cpp
++index deaa9d9..c0aba2b 100644
++--- a/taglib/mpeg/id3v2/frames/commentsframe.cpp
+++++ b/taglib/mpeg/id3v2/frames/commentsframe.cpp
++@@ -150,10 +150,10 @@ void CommentsFrame::parseFields(const ByteVector &data)
++ return;
++ }
++
++- d->textEncoding = String::Type(data[0]);
+++ d->textEncoding = String::ID3Type(data[0]);
++ d->language = data.mid(1, 3);
++
++- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
+++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
++
++ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
++
++@@ -173,11 +173,13 @@ ByteVector CommentsFrame::renderFields() const
++ ByteVector v;
++
++ String::Type encoding = d->textEncoding;
+++
+++ encoding = String::ID3WType(encoding);
++
++ encoding = checkTextEncoding(d->description, encoding);
++ encoding = checkTextEncoding(d->text, encoding);
++
++- v.append(char(encoding));
+++ v.append(char(String::ID3RealType(encoding)));
++ v.append(d->language.size() == 3 ? d->language : "XXX");
++ v.append(d->description.data(encoding));
++ v.append(textDelimiter(encoding));
++diff --git a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
++index b77dd54..a4a7277 100644
++--- a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
+++++ b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
++@@ -187,12 +187,12 @@ void TextIdentificationFrame::parseFields(const ByteVector &data)
++
++ // read the string data type (the first byte of the field data)
++
++- d->textEncoding = String::Type(data[0]);
+++ d->textEncoding = String::ID3Type(data[0]);
++
++ // split the byte array into chunks based on the string type (two byte delimiter
++ // for unicode encodings)
++
++- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
+++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
++
++ // build a small counter to strip nulls off the end of the field
++
++@@ -223,11 +223,14 @@ void TextIdentificationFrame::parseFields(const ByteVector &data)
++
++ ByteVector TextIdentificationFrame::renderFields() const
++ {
++- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding);
+++ String::Type encoding = d->textEncoding;
+++
+++ encoding = String::ID3WType(encoding);
+++ encoding = checkTextEncoding(d->fieldList, encoding);
++
++ ByteVector v;
++
++- v.append(char(encoding));
+++ v.append(char(String::ID3RealType(encoding)));
++
++ for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
++
++diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp
++index bee5375..fea5ab3 100644
++--- a/taglib/mpeg/id3v2/id3v2frame.cpp
+++++ b/taglib/mpeg/id3v2/id3v2frame.cpp
++@@ -339,7 +339,7 @@ String::Type Frame::checkEncoding(const StringList &fields, String::Type encodin
++ if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4)
++ return String::UTF16;
++
++- if(encoding != String::Latin1)
+++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2))
++ return encoding;
++
++ for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
++diff --git a/taglib/toolkit/rccpatch.cpp b/taglib/toolkit/rccpatch.cpp
++new file mode 100644
++index 0000000..af99323
++--- /dev/null
+++++ b/taglib/toolkit/rccpatch.cpp
++@@ -0,0 +1,237 @@
+++#include <stdlib.h>
+++
+++#include <string>
+++#include "tstring.h"
+++#include "tbytevector.h"
+++
+++//#define RCC_DEBUG
+++
+++
+++#ifndef HAVE_LIBRCC
+++# include <config.h>
+++#endif
+++
+++#ifdef HAVE_LIBRCC
+++# ifdef RCC_DEBUG
+++# include <stdio.h>
+++# endif /* RCC_DEBUG */
+++# include <librcc.h>
+++# include <string.h>
+++#endif /* HAVE_LIBRCC */
+++
+++
+++#ifdef HAVE_LIBRCC
+++# define ID3_CLASS 0
+++# define ID3V2_CLASS 1
+++# define UTF_CLASS 2
+++# define OUT_CLASS 3
+++static rcc_class classes[] = {
+++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 },
+++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 },
+++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0},
+++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 },
+++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 }
+++};
+++
+++static int rcc_initialized = 0;
+++
+++static rcc_context ctx = NULL;
+++#endif /* HAVE_LIBRCC */
+++
+++
+++void rccTaglibPatchFree() {
+++#ifdef HAVE_LIBRCC
+++ if (rcc_initialized) {
+++ rccFree();
+++ rcc_initialized = 0;
+++ }
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++void rccTaglibPatchInit() {
+++#ifdef HAVE_LIBRCC
+++ if (rcc_initialized) return;
+++ rccInit();
+++ rccInitDefaultContext(NULL, 0, 0, classes, 0);
+++ rccLoad(NULL, "xmms");
+++ rccInitDb4(NULL, NULL, 0);
+++ rcc_initialized = 1;
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++void rccTaglibPatchSetContext(void *newctx) {
+++#ifdef HAVE_LIBRCC
+++ if (newctx) {
+++ ctx = (rcc_context)newctx;
+++ rcc_initialized = 1;
+++ }
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++static void rccTaglibPatchTryInit() {
+++#ifdef HAVE_LIBRCC
+++ if (!rcc_initialized) {
+++ rccTaglibPatchInit();
+++ if (rcc_initialized) atexit(rccTaglibPatchFree);
+++ }
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++
+++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) {
+++ TagLib::ByteVector v;
+++#ifdef HAVE_LIBRCC
+++ size_t rlen;
+++ char *res;
+++
+++ rccTaglibPatchTryInit();
+++
+++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen);
+++#ifdef RCC_DEBUG
+++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
+++ if (*c > 127) {
+++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null");
+++ break;
+++ }
+++ }
+++#endif /* RCC_DEBUG */
+++
+++ if (res) v.setData(res, rlen);
+++ else v.setData("", 0);
+++ //v.setData(s.c_str(), s.length());
+++
+++ return v;
+++#else
+++ v.setData("", 0);
+++
+++ return v;
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) {
+++ TagLib::ByteVector v;
+++#ifdef HAVE_LIBRCC
+++ size_t rlen;
+++ char *res;
+++
+++ rccTaglibPatchTryInit();
+++
+++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen);
+++#ifdef RCC_DEBUG
+++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
+++ if (*c > 127) {
+++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
+++ break;
+++ }
+++ }
+++#endif /* RCC_DEBUG */
+++
+++ if (res) v.setData(res, rlen);
+++ else v.setData("", 0);
+++ //v.setData(s.c_str(), s.length());
+++
+++ return v;
+++#else
+++ v.setData("", 0);
+++
+++ return v;
+++#endif /* HAVE_LIBRCC */
+++}
+++
+++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) {
+++ TagLib::ByteVector v;
+++#ifdef HAVE_LIBRCC
+++ size_t rlen;
+++ char *res;
+++
+++ rccTaglibPatchTryInit();
+++
+++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
+++#ifdef RCC_DEBUG
+++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
+++ if (*c > 127) {
+++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null");
+++ break;
+++ }
+++ }
+++#endif /* RCC_DEBUG */
+++
+++ if (res) v.setData(res, rlen);
+++ else
+++#endif /* HAVE_LIBRCC */
+++ v.setData("", 0);
+++
+++ return v;
+++}
+++
+++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) {
+++ TagLib::ByteVector v;
+++#ifdef HAVE_LIBRCC
+++ size_t rlen;
+++ char *res;
+++
+++ rccTaglibPatchTryInit();
+++
+++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
+++#ifdef RCC_DEBUG
+++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
+++ if (*c > 127) {
+++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
+++ break;
+++ }
+++ }
+++#endif /* RCC_DEBUG */
+++ if (res) v.setData(res, rlen + 1);
+++ else
+++#endif /* HAVE_LIBRCC */
+++ v.setData("", 0);
+++
+++ return v;
+++}
+++
+++TagLib::String::Type rccTaglibPatchGetLocaleType() {
+++#ifdef HAVE_LIBRCC
+++ size_t len;
+++ char charset[32];
+++
+++ rccTaglibPatchTryInit();
+++ if (!rccLocaleGetCharset(charset, NULL, 31)) {
+++ if (!strncmp(charset, "UTF", 3)) {
+++ len = strlen(charset);
+++
+++ if (charset[len-1]=='8') return TagLib::String::UTF8;
+++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
+++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
+++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
+++ }
+++ return TagLib::String::Latin1;
+++ }
+++#endif /* HAVE_LIBRCC */
+++ return TagLib::String::UTF8;
+++}
+++
+++TagLib::String::Type rccTaglibPatchGetID3Type() {
+++#ifdef HAVE_LIBRCC
+++ size_t len;
+++ const char *charset;
+++
+++ rccTaglibPatchTryInit();
+++
+++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS);
+++ if (charset) {
+++ if (!strncmp(charset, "UTF", 3)) {
+++ len = strlen(charset);
+++
+++ if (charset[len-1]=='8') return TagLib::String::UTF8;
+++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
+++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
+++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
+++ }
+++ return TagLib::String::Latin1ID3V2;
+++ } else {
+++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib
+++ return TagLib::String::Latin1ID3V2;
+++ }
+++#endif /* HAVE_LIBRCC */
+++ return TagLib::String::Latin1;
+++}
++diff --git a/taglib/toolkit/rccpatch.h b/taglib/toolkit/rccpatch.h
++new file mode 100644
++index 0000000..31f4410
++--- /dev/null
+++++ b/taglib/toolkit/rccpatch.h
++@@ -0,0 +1,20 @@
+++#ifndef _RCC_PATCH_H
+++#define _RCC_PATCH_H
+++
+++#include <string.h>
+++#include "tstring.h"
+++#include "tbytevector.h"
+++
+++void rccTaglibPatchFree();
+++void rccTaglibPatchInit();
+++void rccTaglibPatchSetContext(void *newctx);
+++
+++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s);
+++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s);
+++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false);
+++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false);
+++
+++TagLib::String::Type rccTaglibPatchGetLocaleType();
+++TagLib::String::Type rccTaglibPatchGetID3Type();
+++
+++#endif /* _RCC_PATCH_H */
++diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp
++index 258e1fc..70ff160 100644
++--- a/taglib/toolkit/tstring.cpp
+++++ b/taglib/toolkit/tstring.cpp
++@@ -29,6 +29,7 @@
++ #include <config.h>
++ #endif
++
+++#include "rccpatch.h"
++ #include "tstring.h"
++ #include "tdebug.h"
++ #include "tstringlist.h"
++@@ -167,8 +168,11 @@ String::String(const String &s)
++ String::String(const std::string &s, Type t)
++ : d(new StringPrivate())
++ {
++- if(t == Latin1)
++- copyFromLatin1(s.c_str(), s.length());
+++ if(t == Locale)
+++ t = rccTaglibPatchGetLocaleType();
+++
+++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
+++ copyFromLatin1(&s[0], s.length(), true, t);
++ else if(t == String::UTF8)
++ copyFromUTF8(s.c_str(), s.length());
++ else {
++@@ -215,8 +219,11 @@ String::String(const wchar_t *s, Type t)
++ String::String(const char *s, Type t)
++ : d(new StringPrivate())
++ {
++- if(t == Latin1)
++- copyFromLatin1(s, ::strlen(s));
+++ if(t == Locale)
+++ t = rccTaglibPatchGetLocaleType();
+++
+++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
+++ copyFromLatin1(s, ::strlen(s), true, t);
++ else if(t == String::UTF8)
++ copyFromUTF8(s, ::strlen(s));
++ else {
++@@ -248,8 +255,11 @@ String::String(const ByteVector &v, Type t)
++ if(v.isEmpty())
++ return;
++
++- if(t == Latin1)
++- copyFromLatin1(v.data(), v.size());
+++ if(t == Locale)
+++ t = rccTaglibPatchGetLocaleType();
+++
+++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
+++ copyFromLatin1(v.data(), v.size(), true, t);
++ else if(t == UTF8)
++ copyFromUTF8(v.data(), v.size());
++ else
++@@ -396,8 +406,38 @@ bool String::isNull() const
++
++ ByteVector String::data(Type t) const
++ {
++- switch(t)
++- {
+++ ByteVector v;
+++
+++ if (t == Locale) {
+++ // The source is either Unicode or real Latin1 (if rcc is bypassed)
+++ std::string s = to8Bit(true);
+++
+++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich
+++ v = rccTaglibPatchRecodeOutput(s);
+++ if (v.size()) return v;
+++
+++ t = rccTaglibPatchGetLocaleType();
+++ }
+++
+++ switch(t) {
+++ case Latin1ID3:
+++ case Latin1ID3V2:
+++ {
+++ std::string s = to8Bit(true);
+++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false);
+++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true);
+++ if (v.size())
+++ return v;
+++
+++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required
+++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) {
+++ v.setData(s.c_str(), s.length());
+++ } else {
+++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
+++ v.append(char(*it));
+++ }
+++ return v;
+++ }
++ case Latin1:
++ {
++ ByteVector v(size(), 0);
++@@ -738,12 +778,30 @@ void String::detach()
++ // private members
++ ////////////////////////////////////////////////////////////////////////////////
++
++-void String::copyFromLatin1(const char *s, size_t length)
+++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t)
++ {
++ d->data.resize(length);
++
++ for(size_t i = 0; i < length; ++i)
++ d->data[i] = static_cast<uchar>(s[i]);
+++
+++ // librcc conversation
+++ if (prepare) {
+++ std::string s = to8Bit(false);
+++ ByteVector v;
+++
+++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false);
+++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true);
+++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s);
+++
+++ if (v.size()) {
+++ copyFromUTF8(v.data(), v.size());
+++ } else {
+++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed,
+++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8
+++ //if (Unicode::isLegalUTF8(s)) t = UTF8;
+++ }
+++ }
++ }
++
++ void String::copyFromUTF8(const char *s, size_t length)
++@@ -859,7 +917,33 @@ const TagLib::String operator+(const TagLib::String &s1, const char *s2)
++
++ std::ostream &operator<<(std::ostream &s, const TagLib::String &str)
++ {
++- s << str.to8Bit();
+++ TagLib::ByteVector bv = str.data(TagLib::String::Locale);
+++ s << bv;
++ return s;
++ }
++
+++TagLib::String::Type TagLib::String::ID3Type(int i)
+++{
+++ if(i == Latin1)
+++ return Latin1ID3V2;
+++ return Type(i);
+++};
+++
+++TagLib::String::Type TagLib::String::ID3WType(Type type)
+++{
+++ Type rcc_type = rccTaglibPatchGetID3Type();
+++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) {
+++ if(type == Latin1) return
+++ rcc_type;
+++ return type;
+++ }
+++
+++ return rcc_type;
+++};
+++
+++TagLib::String::Type TagLib::String::ID3RealType(Type type)
+++{
+++ if((type == Latin1ID3) || (type == Latin1ID3V2))
+++ return Latin1;
+++ return type;
+++}
++diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h
++index 8b73988..8efca25 100644
++--- a/taglib/toolkit/tstring.h
+++++ b/taglib/toolkit/tstring.h
++@@ -96,6 +96,18 @@ namespace TagLib {
++ */
++ enum Type {
++ /*!
+++ * Determine using current locale settings
+++ */
+++ Locale = -1,
+++ /*!
+++ * Latin1 for ID3 tags.
+++ */
+++ Latin1ID3 = 65,
+++ /*!
+++ * Latin1 for ID3v2 tags.
+++ */
+++ Latin1ID3V2 = 66,
+++ /*!
++ * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters.
++ */
++ Latin1 = 0,
++@@ -117,6 +129,10 @@ namespace TagLib {
++ */
++ UTF16LE = 4
++ };
+++
+++ static Type ID3Type(int i);
+++ static Type ID3WType(Type type);
+++ static Type ID3RealType(Type type);
++
++ /*!
++ * Constructs an empty String.
++@@ -519,7 +535,7 @@ namespace TagLib {
++ * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order)
++ * and copies it to the internal buffer.
++ */
++- void copyFromLatin1(const char *s, size_t length);
+++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1);
++
++ /*!
++ * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order)
diff --git a/media-libs/taglib/files/taglib-1.6.1-install-examples.patch b/media-libs/taglib/files/taglib-1.6.1-install-examples.patch
new file mode 100644
index 0000000..f537681
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.6.1-install-examples.patch
@@ -0,0 +1,16 @@
+diff -purN taglib-1.6.1.orig/examples/CMakeLists.txt taglib-1.6.1/examples/CMakeLists.txt
+--- taglib-1.6.1.orig/examples/CMakeLists.txt 2009-09-09 14:16:38.000000000 -0400
++++ taglib-1.6.1/examples/CMakeLists.txt 2009-12-14 18:47:33.405385063 -0500
+@@ -45,6 +45,12 @@ ADD_EXECUTABLE(strip-id3v1 strip-id3v1.c
+
+ TARGET_LINK_LIBRARIES(strip-id3v1 tag )
+
++INSTALL(TARGETS
++ tagreader tagreader_c tagwriter framelist strip-id3v1
++ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
++ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
++ ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
++)
+
+ endif(BUILD_EXAMPLES)
+
diff --git a/media-libs/taglib/files/taglib-1.9.1-abi-breakage.patch b/media-libs/taglib/files/taglib-1.9.1-abi-breakage.patch
new file mode 100644
index 0000000..930439f
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-abi-breakage.patch
@@ -0,0 +1,107 @@
+From 3bf30af66c8fd77a88d9379a0956ddb2fc70dc20 Mon Sep 17 00:00:00 2001
+From: Tsuda Kageyu <tsuda.kageyu@gmail.com>
+Date: Wed, 6 Nov 2013 17:01:21 +0900
+Subject: [PATCH 2/6] Fixed ABI breakage in TagLib::String
+
+---
+ taglib/toolkit/tstring.cpp | 20 ++++++++++++++++++--
+ taglib/toolkit/tstring.h | 12 ++++++++++--
+ tests/test_string.cpp | 14 ++++++++++++++
+ 3 files changed, 42 insertions(+), 4 deletions(-)
+
+diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp
+index 75a9833..fb6e947 100644
+--- a/taglib/toolkit/tstring.cpp
++++ b/taglib/toolkit/tstring.cpp
+@@ -209,8 +209,16 @@ String::String(const std::string &s, Type t)
+ String::String(const wstring &s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == UTF16 || t == UTF16BE || t == UTF16LE)
++ if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
++ // This looks ugly but needed for the compatibility with TagLib1.8.
++ // Should be removed in TabLib2.0.
++ if (t == UTF16BE)
++ t = WCharByteOrder;
++ else if (t == UTF16LE)
++ t = (WCharByteOrder == UTF16LE ? UTF16BE : UTF16LE);
++
+ copyFromUTF16(s.c_str(), s.length(), t);
++ }
+ else {
+ debug("String::String() -- A TagLib::wstring should not contain Latin1 or UTF-8.");
+ }
+@@ -219,8 +227,16 @@ String::String(const wstring &s, Type t)
+ String::String(const wchar_t *s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == UTF16 || t == UTF16BE || t == UTF16LE)
++ if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
++ // This looks ugly but needed for the compatibility with TagLib1.8.
++ // Should be removed in TabLib2.0.
++ if (t == UTF16BE)
++ t = WCharByteOrder;
++ else if (t == UTF16LE)
++ t = (WCharByteOrder == UTF16LE ? UTF16BE : UTF16LE);
++
+ copyFromUTF16(s, ::wcslen(s), t);
++ }
+ else {
+ debug("String::String() -- A const wchar_t * should not contain Latin1 or UTF-8.");
+ }
+diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h
+index 57945be..605b9c2 100644
+--- a/taglib/toolkit/tstring.h
++++ b/taglib/toolkit/tstring.h
+@@ -134,13 +134,21 @@ namespace TagLib {
+
+ /*!
+ * Makes a deep copy of the data in \a s.
++ *
++ * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless
++ * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior
++ * will be changed in TagLib2.0.
+ */
+- String(const wstring &s, Type t = WCharByteOrder);
++ String(const wstring &s, Type t = UTF16BE);
+
+ /*!
+ * Makes a deep copy of the data in \a s.
++ *
++ * /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless
++ * of the CPU byte order. If UTF16BE, it will not be swapped. This behavior
++ * will be changed in TagLib2.0.
+ */
+- String(const wchar_t *s, Type t = WCharByteOrder);
++ String(const wchar_t *s, Type t = UTF16BE);
+
+ /*!
+ * Makes a deep copy of the data in \a c.
+diff --git a/tests/test_string.cpp b/tests/test_string.cpp
+index a815a0b..9a574b3 100644
+--- a/tests/test_string.cpp
++++ b/tests/test_string.cpp
+@@ -75,6 +75,20 @@ public:
+ String unicode3(L"\u65E5\u672C\u8A9E");
+ CPPUNIT_ASSERT(*(unicode3.toCWString() + 1) == L'\u672C');
+
++ String unicode4(L"\u65e5\u672c\u8a9e", String::UTF16BE);
++ CPPUNIT_ASSERT(unicode4[1] == L'\u672c');
++
++ String unicode5(L"\u65e5\u672c\u8a9e", String::UTF16LE);
++ CPPUNIT_ASSERT(unicode5[1] == L'\u2c67');
++
++ wstring stduni = L"\u65e5\u672c\u8a9e";
++
++ String unicode6(stduni, String::UTF16BE);
++ CPPUNIT_ASSERT(unicode6[1] == L'\u672c');
++
++ String unicode7(stduni, String::UTF16LE);
++ CPPUNIT_ASSERT(unicode7[1] == L'\u2c67');
++
+ CPPUNIT_ASSERT(strcmp(String::number(0).toCString(), "0") == 0);
+ CPPUNIT_ASSERT(strcmp(String::number(12345678).toCString(), "12345678") == 0);
+ CPPUNIT_ASSERT(strcmp(String::number(-12345678).toCString(), "-12345678") == 0);
+--
+1.8.4.2
+
diff --git a/media-libs/taglib/files/taglib-1.9.1-bytevector-simpler.patch b/media-libs/taglib/files/taglib-1.9.1-bytevector-simpler.patch
new file mode 100644
index 0000000..0b134ec
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-bytevector-simpler.patch
@@ -0,0 +1,131 @@
+From 4a7d31c87bf41c1de21cb725176d5b34c2a95720 Mon Sep 17 00:00:00 2001
+From: Tsuda Kageyu <tsuda.kageyu@gmail.com>
+Date: Thu, 14 Nov 2013 14:05:32 +0900
+Subject: [PATCH 3/6] Rewrote ByteVector::replace() simpler
+
+---
+ taglib/toolkit/tbytevector.cpp | 77 +++++++++++++++---------------------------
+ tests/test_bytevector.cpp | 5 +++
+ 2 files changed, 33 insertions(+), 49 deletions(-)
+
+diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp
+index b658246..566a20f 100644
+--- a/taglib/toolkit/tbytevector.cpp
++++ b/taglib/toolkit/tbytevector.cpp
+@@ -31,6 +31,7 @@
+ #include <iostream>
+ #include <cstdio>
+ #include <cstring>
++#include <cstddef>
+
+ #include <tstring.h>
+ #include <tdebug.h>
+@@ -508,62 +509,40 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
+ if(pattern.size() == 0 || pattern.size() > size())
+ return *this;
+
+- const uint withSize = with.size();
+- const uint patternSize = pattern.size();
+- int offset = 0;
++ const size_t withSize = with.size();
++ const size_t patternSize = pattern.size();
++ const ptrdiff_t diff = withSize - patternSize;
++
++ size_t offset = 0;
++ while (true)
++ {
++ offset = find(pattern, offset);
++ if(offset == static_cast<size_t>(-1)) // Use npos in taglib2.
++ break;
+
+- if(withSize == patternSize) {
+- // I think this case might be common enough to optimize it
+ detach();
+- offset = find(pattern);
+- while(offset >= 0) {
+- ::memcpy(data() + offset, with.data(), withSize);
+- offset = find(pattern, offset + withSize);
+- }
+- return *this;
+- }
+
+- // calculate new size:
+- uint newSize = 0;
+- for(;;) {
+- int next = find(pattern, offset);
+- if(next < 0) {
+- if(offset == 0)
+- // pattern not found, do nothing:
+- return *this;
+- newSize += size() - offset;
+- break;
++ if(diff < 0) {
++ ::memmove(
++ data() + offset + withSize,
++ data() + offset + patternSize,
++ size() - offset - patternSize);
++ resize(size() + diff);
+ }
+- newSize += (next - offset) + withSize;
+- offset = next + patternSize;
+- }
+-
+- // new private data of appropriate size:
+- ByteVectorPrivate *newData = new ByteVectorPrivate(newSize, 0);
+- char *target = DATA(newData);
+- const char *source = data();
+-
+- // copy modified data into new private data:
+- offset = 0;
+- for(;;) {
+- int next = find(pattern, offset);
+- if(next < 0) {
+- ::memcpy(target, source + offset, size() - offset);
+- break;
++ else if(diff > 0) {
++ resize(size() + diff);
++ ::memmove(
++ data() + offset + withSize,
++ data() + offset + patternSize,
++ size() - diff - offset - patternSize);
+ }
+- int chunkSize = next - offset;
+- ::memcpy(target, source + offset, chunkSize);
+- target += chunkSize;
+- ::memcpy(target, with.data(), withSize);
+- target += withSize;
+- offset += chunkSize + patternSize;
+- }
+
+- // replace private data:
+- if(d->deref())
+- delete d;
++ ::memcpy(data() + offset, with.data(), with.size());
+
+- d = newData;
++ offset += withSize;
++ if(offset > size() - patternSize)
++ break;
++ }
+
+ return *this;
+ }
+diff --git a/tests/test_bytevector.cpp b/tests/test_bytevector.cpp
+index 9efd23a..eca74f8 100644
+--- a/tests/test_bytevector.cpp
++++ b/tests/test_bytevector.cpp
+@@ -239,6 +239,11 @@ public:
+ a.replace(ByteVector("ab"), ByteVector());
+ CPPUNIT_ASSERT_EQUAL(ByteVector("cdf"), a);
+ }
++ {
++ ByteVector a("abcdabf");
++ a.replace(ByteVector("bf"), ByteVector("x"));
++ CPPUNIT_ASSERT_EQUAL(ByteVector("abcdax"), a);
++ }
+ }
+
+ };
+--
+1.8.4.2
+
diff --git a/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms-enforce.patch b/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms-enforce.patch
new file mode 100644
index 0000000..e980b7a
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms-enforce.patch
@@ -0,0 +1,20 @@
+--- taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.h 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-taurus/taglib/mpeg/id3v1/id3v1tag.h 2013-11-12 00:24:31.206495291 +0100
+@@ -68,7 +68,7 @@
+ * Decode a string from \a data. The default implementation assumes that
+ * \a data is an ISO-8859-1 (Latin1) character array.
+ */
+- virtual String parse(const ByteVector &data) const;
++ String parse(const ByteVector &data) const;
+
+ /*!
+ * Encode a ByteVector with the data from \a s. The default implementation
+@@ -79,7 +79,7 @@
+ * instead do not write an ID3v1 tag in the case that the data is not
+ * ISO-8859-1.
+ */
+- virtual ByteVector render(const String &s) const;
++ ByteVector render(const String &s) const;
+ };
+
+ //! The main class in the ID3v1 implementation
diff --git a/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms.patch b/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms.patch
new file mode 100644
index 0000000..b64b5b5
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-ds-rusxmms.patch
@@ -0,0 +1,676 @@
+diff -dPNur taglib-1.9.1/config.h.cmake taglib-1.9.1-ds/config.h.cmake
+--- taglib-1.9.1/config.h.cmake 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/config.h.cmake 2013-11-11 13:43:48.500304915 +0100
+@@ -31,6 +31,9 @@
+ /* Defined if you have libz */
+ #cmakedefine HAVE_ZLIB 1
+
++/* Defined if you have LibRCC from RusXMMS project */
++#cmakedefine HAVE_LIBRCC 1
++
+ /* Indicates whether debug messages are shown even in release mode */
+ #cmakedefine TRACE_IN_RELEASE 1
+
+diff -dPNur taglib-1.9.1/ConfigureChecks.cmake taglib-1.9.1-ds/ConfigureChecks.cmake
+--- taglib-1.9.1/ConfigureChecks.cmake 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/ConfigureChecks.cmake 2013-11-11 13:42:53.017126134 +0100
+@@ -216,6 +216,7 @@
+ set(HAVE_ZLIB 0)
+ endif()
+
++SET(HAVE_LIBRCC 1)
+
+ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
+
+diff -dPNur taglib-1.9.1/examples/tagreader_c.c taglib-1.9.1-ds/examples/tagreader_c.c
+--- taglib-1.9.1/examples/tagreader_c.c 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/examples/tagreader_c.c 2013-11-11 13:42:53.017126134 +0100
+@@ -38,7 +38,7 @@
+ TagLib_Tag *tag;
+ const TagLib_AudioProperties *properties;
+
+- taglib_set_strings_unicode(FALSE);
++// taglib_set_strings_unicode(FALSE);
+
+ for(i = 1; i < argc; i++) {
+ printf("******************** \"%s\" ********************\n", argv[i]);
+diff -dPNur taglib-1.9.1/examples/tagwriter.cpp taglib-1.9.1-ds/examples/tagwriter.cpp
+--- taglib-1.9.1/examples/tagwriter.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/examples/tagwriter.cpp 2013-11-11 13:42:53.028126368 +0100
+@@ -92,7 +92,7 @@
+ if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) {
+
+ char field = argv[i][1];
+- TagLib::String value = argv[i + 1];
++ TagLib::String value(argv[i + 1], TagLib::String::Locale);
+
+ TagLib::List<TagLib::FileRef>::Iterator it;
+ for(it = fileList.begin(); it != fileList.end(); ++it) {
+diff -dPNur taglib-1.9.1/taglib/CMakeLists.txt taglib-1.9.1-ds/taglib/CMakeLists.txt
+--- taglib-1.9.1/taglib/CMakeLists.txt 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/CMakeLists.txt 2013-11-11 13:42:53.042126665 +0100
+@@ -36,6 +36,7 @@
+ audioproperties.h
+ taglib_export.h
+ ${CMAKE_BINARY_DIR}/taglib_config.h
++ toolkit/rccpatch.h
+ toolkit/taglib.h
+ toolkit/tstring.h
+ toolkit/tlist.h
+@@ -281,6 +282,7 @@
+ )
+
+ set(toolkit_SRCS
++ toolkit/rccpatch.cpp
+ toolkit/tstring.cpp
+ toolkit/tstringlist.cpp
+ toolkit/tbytevector.cpp
+@@ -310,7 +312,7 @@
+ add_library(tag ${tag_LIB_SRCS} ${tag_HDRS})
+
+ if(ZLIB_FOUND)
+- target_link_libraries(tag ${ZLIB_LIBRARIES})
++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES})
+ endif()
+
+ set_target_properties(tag PROPERTIES
+diff -dPNur taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.9.1-ds/taglib/mpeg/id3v1/id3v1tag.cpp
+--- taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2013-11-11 13:42:53.043126686 +0100
+@@ -64,17 +64,18 @@
+
+ String ID3v1::StringHandler::parse(const ByteVector &data) const
+ {
+- return String(data, String::Latin1).stripWhiteSpace();
++ return String(data, String::Latin1ID3).stripWhiteSpace();
+ }
+
+ ByteVector ID3v1::StringHandler::render(const String &s) const
+ {
+ if(!s.isLatin1())
+ {
++ if (String::ID3WType(String::Latin1) == String::Latin1)
+ return ByteVector();
+ }
+
+- return s.data(String::Latin1);
++ return s.data(String::Latin1ID3);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+@@ -257,7 +258,7 @@
+ d->track = uchar(data[offset + 29]);
+ }
+ else
+- d->comment = data.mid(offset, 30);
++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30));
+
+ offset += 30;
+
+diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp
+--- taglib-1.9.1/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-11-11 13:42:53.043126686 +0100
+@@ -150,10 +150,10 @@
+ return;
+ }
+
+- d->textEncoding = String::Type(data[0]);
++ d->textEncoding = String::ID3Type(data[0]);
+ d->language = data.mid(1, 3);
+
+- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
+
+ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
+
+@@ -174,10 +174,12 @@
+
+ String::Type encoding = d->textEncoding;
+
++ encoding = String::ID3WType(encoding);
++
+ encoding = checkTextEncoding(d->description, encoding);
+ encoding = checkTextEncoding(d->text, encoding);
+
+- v.append(char(encoding));
++ v.append(char(String::ID3RealType(encoding)));
+ v.append(d->language.size() == 3 ? d->language : "XXX");
+ v.append(d->description.data(encoding));
+ v.append(textDelimiter(encoding));
+diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp
+--- taglib-1.9.1/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-11-11 13:42:53.044126708 +0100
+@@ -187,12 +187,12 @@
+
+ // read the string data type (the first byte of the field data)
+
+- d->textEncoding = String::Type(data[0]);
++ d->textEncoding = String::ID3Type(data[0]);
+
+ // split the byte array into chunks based on the string type (two byte delimiter
+ // for unicode encodings)
+
+- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
+
+ // build a small counter to strip nulls off the end of the field
+
+@@ -223,11 +223,14 @@
+
+ ByteVector TextIdentificationFrame::renderFields() const
+ {
+- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding);
++ String::Type encoding = d->textEncoding;
++
++ encoding = String::ID3WType(encoding);
++ encoding = checkTextEncoding(d->fieldList, encoding);
+
+ ByteVector v;
+
+- v.append(char(encoding));
++ v.append(char(String::ID3RealType(encoding)));
+
+ for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
+
+diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/id3v2frame.cpp
+--- taglib-1.9.1/taglib/mpeg/id3v2/id3v2frame.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2013-11-11 13:42:53.045126729 +0100
+@@ -302,7 +302,7 @@
+ if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4)
+ return String::UTF16;
+
+- if(encoding != String::Latin1)
++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2))
+ return encoding;
+
+ for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
+diff -dPNur taglib-1.9.1/taglib/toolkit/rccpatch.cpp taglib-1.9.1-ds/taglib/toolkit/rccpatch.cpp
+--- taglib-1.9.1/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100
++++ taglib-1.9.1-ds/taglib/toolkit/rccpatch.cpp 2013-11-11 13:42:53.045126729 +0100
+@@ -0,0 +1,237 @@
++#include <stdlib.h>
++
++#include <string>
++#include "tstring.h"
++#include "tbytevector.h"
++
++//#define RCC_DEBUG
++
++
++#ifndef HAVE_LIBRCC
++# include <config.h>
++#endif
++
++#ifdef HAVE_LIBRCC
++# ifdef RCC_DEBUG
++# include <stdio.h>
++# endif /* RCC_DEBUG */
++# include <librcc.h>
++# include <string.h>
++#endif /* HAVE_LIBRCC */
++
++
++#ifdef HAVE_LIBRCC
++# define ID3_CLASS 0
++# define ID3V2_CLASS 1
++# define UTF_CLASS 2
++# define OUT_CLASS 3
++static rcc_class classes[] = {
++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 },
++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 },
++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0},
++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 },
++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 }
++};
++
++static int rcc_initialized = 0;
++
++static rcc_context ctx = NULL;
++#endif /* HAVE_LIBRCC */
++
++
++void rccTaglibPatchFree() {
++#ifdef HAVE_LIBRCC
++ if (rcc_initialized) {
++ rccFree();
++ rcc_initialized = 0;
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++void rccTaglibPatchInit() {
++#ifdef HAVE_LIBRCC
++ if (rcc_initialized) return;
++ rccInit();
++ rccInitDefaultContext(NULL, 0, 0, classes, 0);
++ rccLoad(NULL, "xmms");
++ rccInitDb4(NULL, NULL, 0);
++ rcc_initialized = 1;
++#endif /* HAVE_LIBRCC */
++}
++
++void rccTaglibPatchSetContext(void *newctx) {
++#ifdef HAVE_LIBRCC
++ if (newctx) {
++ ctx = (rcc_context)newctx;
++ rcc_initialized = 1;
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++static void rccTaglibPatchTryInit() {
++#ifdef HAVE_LIBRCC
++ if (!rcc_initialized) {
++ rccTaglibPatchInit();
++ if (rcc_initialized) atexit(rccTaglibPatchFree);
++ }
++#endif /* HAVE_LIBRCC */
++}
++
++
++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else v.setData("", 0);
++ //v.setData(s.c_str(), s.length());
++
++ return v;
++#else
++ v.setData("", 0);
++
++ return v;
++#endif /* HAVE_LIBRCC */
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else v.setData("", 0);
++ //v.setData(s.c_str(), s.length());
++
++ return v;
++#else
++ v.setData("", 0);
++
++ return v;
++#endif /* HAVE_LIBRCC */
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++
++ if (res) v.setData(res, rlen);
++ else
++#endif /* HAVE_LIBRCC */
++ v.setData("", 0);
++
++ return v;
++}
++
++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) {
++ TagLib::ByteVector v;
++#ifdef HAVE_LIBRCC
++ size_t rlen;
++ char *res;
++
++ rccTaglibPatchTryInit();
++
++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
++#ifdef RCC_DEBUG
++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
++ if (*c > 127) {
++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
++ break;
++ }
++ }
++#endif /* RCC_DEBUG */
++ if (res) v.setData(res, rlen + 1);
++ else
++#endif /* HAVE_LIBRCC */
++ v.setData("", 0);
++
++ return v;
++}
++
++TagLib::String::Type rccTaglibPatchGetLocaleType() {
++#ifdef HAVE_LIBRCC
++ size_t len;
++ char charset[32];
++
++ rccTaglibPatchTryInit();
++ if (!rccLocaleGetCharset(charset, NULL, 31)) {
++ if (!strncmp(charset, "UTF", 3)) {
++ len = strlen(charset);
++
++ if (charset[len-1]=='8') return TagLib::String::UTF8;
++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
++ }
++ return TagLib::String::Latin1;
++ }
++#endif /* HAVE_LIBRCC */
++ return TagLib::String::UTF8;
++}
++
++TagLib::String::Type rccTaglibPatchGetID3Type() {
++#ifdef HAVE_LIBRCC
++ size_t len;
++ const char *charset;
++
++ rccTaglibPatchTryInit();
++
++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS);
++ if (charset) {
++ if (!strncmp(charset, "UTF", 3)) {
++ len = strlen(charset);
++
++ if (charset[len-1]=='8') return TagLib::String::UTF8;
++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
++ }
++ return TagLib::String::Latin1ID3V2;
++ } else {
++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib
++ return TagLib::String::Latin1ID3V2;
++ }
++#endif /* HAVE_LIBRCC */
++ return TagLib::String::Latin1;
++}
+diff -dPNur taglib-1.9.1/taglib/toolkit/rccpatch.h taglib-1.9.1-ds/taglib/toolkit/rccpatch.h
+--- taglib-1.9.1/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100
++++ taglib-1.9.1-ds/taglib/toolkit/rccpatch.h 2013-11-11 13:42:53.045126729 +0100
+@@ -0,0 +1,20 @@
++#ifndef _RCC_PATCH_H
++#define _RCC_PATCH_H
++
++#include <string.h>
++#include "tstring.h"
++#include "tbytevector.h"
++
++void rccTaglibPatchFree();
++void rccTaglibPatchInit();
++void rccTaglibPatchSetContext(void *newctx);
++
++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s);
++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s);
++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false);
++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false);
++
++TagLib::String::Type rccTaglibPatchGetLocaleType();
++TagLib::String::Type rccTaglibPatchGetID3Type();
++
++#endif /* _RCC_PATCH_H */
+diff -dPNur taglib-1.9.1/taglib/toolkit/tstring.cpp taglib-1.9.1-ds/taglib/toolkit/tstring.cpp
+--- taglib-1.9.1/taglib/toolkit/tstring.cpp 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/toolkit/tstring.cpp 2013-11-11 13:42:53.046126750 +0100
+@@ -29,6 +29,7 @@
+ #include <config.h>
+ #endif
+
++#include "rccpatch.h"
+ #include "tstring.h"
+ #include "tdebug.h"
+ #include "tstringlist.h"
+@@ -197,8 +198,11 @@
+ String::String(const std::string &s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == Latin1)
+- copyFromLatin1(&s[0], s.length());
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(&s[0], s.length(), true, t);
+ else if(t == String::UTF8)
+ copyFromUTF8(&s[0], s.length());
+ else {
+@@ -229,8 +233,11 @@
+ String::String(const char *s, Type t)
+ : d(new StringPrivate())
+ {
+- if(t == Latin1)
+- copyFromLatin1(s, ::strlen(s));
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(s, ::strlen(s), true, t);
+ else if(t == String::UTF8)
+ copyFromUTF8(s, ::strlen(s));
+ else {
+@@ -251,7 +258,10 @@
+ String::String(char c, Type t)
+ : d(new StringPrivate(1, static_cast<uchar>(c)))
+ {
+- if(t != Latin1 && t != UTF8) {
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t != Latin1 && t != Latin1ID3 && t != Latin1ID3V2 && t != UTF8) {
+ debug("String::String() -- A char should not contain UTF16.");
+ }
+ }
+@@ -262,8 +272,11 @@
+ if(v.isEmpty())
+ return;
+
+- if(t == Latin1)
+- copyFromLatin1(v.data(), v.size());
++ if(t == Locale)
++ t = rccTaglibPatchGetLocaleType();
++
++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
++ copyFromLatin1(v.data(), v.size(), true, t);
+ else if(t == UTF8)
+ copyFromUTF8(v.data(), v.size());
+ else
+@@ -428,16 +441,46 @@
+
+ ByteVector String::data(Type t) const
+ {
+- switch(t)
+- {
++ ByteVector v;
++
++ if (t == Locale) {
++ // The source is either Unicode or real Latin1 (if rcc is bypassed)
++ std::string s = to8Bit(true);
++
++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich
++ v = rccTaglibPatchRecodeOutput(s);
++ if (v.size()) return v;
++
++ t = rccTaglibPatchGetLocaleType();
++ }
++
++ switch(t) {
++ case Latin1ID3:
++ case Latin1ID3V2:
++ {
++ std::string s = to8Bit(true);
++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false);
++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true);
++ if (v.size())
++ return v;
++
++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required
++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) {
++ v.setData(s.c_str(), s.length());
++ } else {
++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
++ v.append(char(*it));
++ }
++ return v;
++ }
+ case Latin1:
+ {
+ ByteVector v(size(), 0);
+ char *p = v.data();
+-
++
+ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
+ *p++ = static_cast<char>(*it);
+-
++
+ return v;
+ }
+ case UTF8:
+@@ -763,12 +806,29 @@
+ // private members
+ ////////////////////////////////////////////////////////////////////////////////
+
+-void String::copyFromLatin1(const char *s, size_t length)
++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t)
+ {
+ d->data.resize(length);
+-
+ for(size_t i = 0; i < length; ++i)
+ d->data[i] = static_cast<uchar>(s[i]);
++
++ // librcc conversation
++ if (prepare) {
++ std::string s = to8Bit(false);
++ ByteVector v;
++
++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false);
++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true);
++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s);
++
++ if (v.size()) {
++ copyFromUTF8(v.data(), v.size());
++ } else {
++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed,
++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8
++ //if (Unicode::isLegalUTF8(s)) t = UTF8;
++ }
++ }
+ }
+
+ void String::copyFromUTF8(const char *s, size_t length)
+@@ -874,7 +934,33 @@
+
+ std::ostream &operator<<(std::ostream &s, const TagLib::String &str)
+ {
+- s << str.to8Bit();
++ TagLib::ByteVector bv = str.data(TagLib::String::Locale);
++ s << bv;
+ return s;
+ }
+
++TagLib::String::Type TagLib::String::ID3Type(int i)
++{
++ if(i == Latin1)
++ return Latin1ID3V2;
++ return Type(i);
++};
++
++TagLib::String::Type TagLib::String::ID3WType(Type type)
++{
++ Type rcc_type = rccTaglibPatchGetID3Type();
++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) {
++ if(type == Latin1) return
++ rcc_type;
++ return type;
++ }
++
++ return rcc_type;
++};
++
++TagLib::String::Type TagLib::String::ID3RealType(Type type)
++{
++ if((type == Latin1ID3) || (type == Latin1ID3V2))
++ return Latin1;
++ return type;
++}
+diff -dPNur taglib-1.9.1/taglib/toolkit/tstring.h taglib-1.9.1-ds/taglib/toolkit/tstring.h
+--- taglib-1.9.1/taglib/toolkit/tstring.h 2013-10-08 17:50:01.000000000 +0200
++++ taglib-1.9.1-ds/taglib/toolkit/tstring.h 2013-11-11 13:42:53.047126771 +0100
+@@ -90,6 +90,18 @@
+ */
+ enum Type {
+ /*!
++ * Determine using current locale settings
++ */
++ Locale = -1,
++ /*!
++ * Latin1 for ID3 tags.
++ */
++ Latin1ID3 = 65,
++ /*!
++ * Latin1 for ID3v2 tags.
++ */
++ Latin1ID3V2 = 66,
++ /*!
+ * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters.
+ */
+ Latin1 = 0,
+@@ -112,6 +124,10 @@
+ UTF16LE = 4
+ };
+
++ static Type ID3Type(int i);
++ static Type ID3WType(Type type);
++ static Type ID3RealType(Type type);
++
+ /*!
+ * Constructs an empty String.
+ */
+@@ -479,7 +495,7 @@
+ * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order)
+ * and copies it to the internal buffer.
+ */
+- void copyFromLatin1(const char *s, size_t length);
++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1);
+
+ /*!
+ * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order)
diff --git a/media-libs/taglib/files/taglib-1.9.1-missing-deletes.patch b/media-libs/taglib/files/taglib-1.9.1-missing-deletes.patch
new file mode 100644
index 0000000..9cdbdcf
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-missing-deletes.patch
@@ -0,0 +1,48 @@
+From c14a3b5c3d0831f7c113d0cf95840c4671d9ebd4 Mon Sep 17 00:00:00 2001
+From: Tsuda Kageyu <tsuda.kageyu@gmail.com>
+Date: Tue, 13 May 2014 20:07:02 +0900
+Subject: [PATCH] Added some missing deletes to test_flac.cpp.
+
+---
+ tests/test_flac.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/test_flac.cpp b/tests/test_flac.cpp
+index caec715..364fb11 100644
+--- a/tests/test_flac.cpp
++++ b/tests/test_flac.cpp
+@@ -91,6 +91,7 @@ public:
+ newpic->setData("JPEG data");
+ f->addPicture(newpic);
+ f->save();
++ delete f;
+
+ f = new FLAC::File(newname.c_str());
+ lst = f->pictureList();
+@@ -138,6 +139,7 @@ public:
+ f->removePictures();
+ f->addPicture(newpic);
+ f->save();
++ delete f;
+
+ f = new FLAC::File(newname.c_str());
+ lst = f->pictureList();
+@@ -165,6 +167,7 @@ public:
+
+ f->removePictures();
+ f->save();
++ delete f;
+
+ f = new FLAC::File(newname.c_str());
+ lst = f->pictureList();
+@@ -185,6 +188,7 @@ public:
+ tag->setTitle("NEW TITLE 2");
+ f->save();
+ CPPUNIT_ASSERT_EQUAL(String("NEW TITLE 2"), tag->title());
++ delete f;
+
+ f = new FLAC::File(newname.c_str());
+ tag = f->tag();
+--
+1.9.0
+
diff --git a/media-libs/taglib/files/taglib-1.9.1-order-big-endian.patch b/media-libs/taglib/files/taglib-1.9.1-order-big-endian.patch
new file mode 100644
index 0000000..86d5201
--- /dev/null
+++ b/media-libs/taglib/files/taglib-1.9.1-order-big-endian.patch
@@ -0,0 +1,33 @@
+From db3e961d1098d5efe57364f540f68a5996dc83c2 Mon Sep 17 00:00:00 2001
+From: Tsuda Kageyu <tsuda.kageyu@gmail.com>
+Date: Tue, 13 May 2014 18:22:16 +0900
+Subject: [PATCH] Fixed a wrong byte order handling on big-endian machines.
+
+---
+ taglib/toolkit/tstring.cpp | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp
+index 603455a..1ec083b 100644
+--- a/taglib/toolkit/tstring.cpp
++++ b/taglib/toolkit/tstring.cpp
+@@ -47,10 +47,14 @@
+
+ namespace
+ {
+-
+ inline unsigned short combine(unsigned char c1, unsigned char c2)
+ {
+- return (c1 << 8) | c2;
++ using namespace TagLib::Utils;
++
++ if(SystemByteOrder == LittleEndian)
++ return (c1 << 8) | c2;
++ else
++ return (c2 << 8) | c1;
+ }
+
+ void UTF16toUTF8(const wchar_t *src, size_t srcLength, char *dst, size_t dstLength)
+--
+1.9.0
+