diff -dPNur libid3tag-0.15.1b/configure.ac libid3tag-0.15.1b-ds/configure.ac
--- libid3tag-0.15.1b/configure.ac 2004-01-24 00:22:46.000000000 +0100
+++ libid3tag-0.15.1b-ds/configure.ac 2008-04-12 21:36:35.000000000 +0200
@@ -145,6 +145,22 @@
*** environment variable to specify its installed location, e.g. -L
.])
])
+
+AC_CHECK_LIB(rcc, rccInit,[
+ AC_CHECK_HEADERS(librcc.h,[
+ LIBRCC_LIBS="-lrcc"
+ LIBRCC_INCLUDES="-DHAVE_LIBRCC"
+ ],[
+ LIBRCC_LIBS=""
+ LIBRCC_INCLUDES=""
+])],[
+ LIBRCC_LIBS=""
+ LIBRCC_INCLUDES=""
+])
+AC_SUBST(LIBRCC_LIBS)
+AC_SUBST(LIBRCC_INCLUDES)
+
+
dnl handle --enable and --disable options
AC_CACHE_SAVE
diff -dPNur libid3tag-0.15.1b/latin1.c libid3tag-0.15.1b-ds/latin1.c
--- libid3tag-0.15.1b/latin1.c 2004-01-23 10:41:32.000000000 +0100
+++ libid3tag-0.15.1b-ds/latin1.c 2008-04-12 21:36:35.000000000 +0200
@@ -31,6 +31,9 @@
# include "latin1.h"
# include "ucs4.h"
+# include "utf8.h"
+# include "rccpatch.h"
+
/*
* NAME: latin1->length()
* DESCRIPTION: return the number of ucs4 chars represented by a latin1 string
@@ -172,6 +175,11 @@
id3_length_t size = 0;
id3_latin1_t latin1[1], *out;
+/*
+ Theoretically, we should add here a code for converting ucs4 to
+ recoded latin1 string. However, using non-standard latin1 tags
+ in ID3v.2 tags is completely idiotic. So, I'll not do that.
+*/
while (*ucs4) {
switch (id3_latin1_encodechar(out = latin1, *ucs4++)) {
case 1: size += id3_latin1_put(ptr, *out++);
@@ -193,6 +201,7 @@
{
id3_byte_t const *end;
id3_latin1_t *latin1ptr, *latin1;
+ id3_utf8_t *utf8;
id3_ucs4_t *ucs4;
end = *ptr + length;
@@ -207,6 +216,19 @@
*latin1ptr = 0;
+
+ utf8 = rccPatchLatin2UTF(latin1);
+ if (utf8) {
+ ucs4 = malloc((id3_utf8_length(utf8) + 1) * sizeof(*ucs4));
+ if (ucs4)
+ id3_utf8_decode(utf8, ucs4);
+ free(utf8);
+ free(latin1);
+
+
+ return ucs4;
+ }
+
ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4));
if (ucs4)
id3_latin1_decode(latin1, ucs4);
diff -dPNur libid3tag-0.15.1b/Makefile.am libid3tag-0.15.1b-ds/Makefile.am
--- libid3tag-0.15.1b/Makefile.am 2004-02-17 03:11:28.000000000 +0100
+++ libid3tag-0.15.1b-ds/Makefile.am 2008-04-12 21:36:35.000000000 +0200
@@ -81,6 +81,7 @@
libid3tag_la_SOURCES = version.c ucs4.c latin1.c utf16.c utf8.c \
parse.c render.c field.c frametype.c compat.c \
genre.c frame.c crc.c util.c tag.c file.c \
+ rccpatch.c rccpatch.h \
version.h ucs4.h latin1.h utf16.h utf8.h \
parse.h render.h field.h frametype.h compat.h \
genre.h frame.h crc.h util.h tag.h file.h \
@@ -90,7 +91,8 @@
frametype.gperf compat.gperf genre.dat.in \
debug.c debug.h
-libid3tag_la_LDFLAGS = -version-info $(version_info)
+INCLUDES = @LIBRCC_INCLUDES@
+libid3tag_la_LDFLAGS = -version-info $(version_info) @LIBRCC_LIBS@
BUILT_SOURCES = frametype.c compat.c genre.dat
diff -dPNur libid3tag-0.15.1b/rccpatch.c libid3tag-0.15.1b-ds/rccpatch.c
--- libid3tag-0.15.1b/rccpatch.c 1970-01-01 01:00:00.000000000 +0100
+++ libid3tag-0.15.1b-ds/rccpatch.c 2008-04-12 21:36:35.000000000 +0200
@@ -0,0 +1,96 @@
+#include
+#include "rccpatch.h"
+
+#ifdef HAVE_LIBRCC
+# include
+#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 rccPatchFree() {
+#ifdef HAVE_LIBRCC
+ if (rcc_initialized) {
+ rccFree();
+ rcc_initialized = 0;
+ }
+#endif /* HAVE_LIBRCC */
+}
+
+void rccPatchInit() {
+#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 rccPatchSetContext(void *newctx) {
+#ifdef HAVE_LIBRCC
+ if (newctx) {
+ ctx = (rcc_context)newctx;
+ rcc_initialized = 1;
+ }
+#endif /* HAVE_LIBRCC */
+}
+
+static void rccPatchTryInit() {
+#ifdef HAVE_LIBRCC
+ if (!rcc_initialized) {
+ rccPatchInit();
+ if (rcc_initialized) atexit(rccPatchFree);
+ }
+#endif /* HAVE_LIBRCC */
+}
+
+
+id3_utf8_t *rccPatchLatin2UTF(id3_latin1_t *str) {
+#ifdef HAVE_LIBRCC
+ rccPatchTryInit();
+
+ return rccRecode(ctx, ID3_CLASS, UTF_CLASS, str);
+#else
+ return NULL;
+#endif /* HAVE_LIBRCC */
+}
+
+id3_latin1_t *rccPatchUTF2Latin(id3_utf8_t *str) {
+#ifdef HAVE_LIBRCC
+ rccPatchTryInit();
+
+ return rccRecode(ctx, UTF_CLASS, ID3_CLASS, str);
+#else
+ return NULL;
+#endif /* HAVE_LIBRCC */
+}
+
+id3_latin1_t *rccPatchUTF2Out(id3_utf8_t *str) {
+#ifdef HAVE_LIBRCC
+ rccPatchTryInit();
+
+ return rccRecode(ctx, UTF_CLASS, OUT_CLASS, str);
+#else
+ return NULL;
+#endif /* HAVE_LIBRCC */
+}
+
diff -dPNur libid3tag-0.15.1b/rccpatch.h libid3tag-0.15.1b-ds/rccpatch.h
--- libid3tag-0.15.1b/rccpatch.h 1970-01-01 01:00:00.000000000 +0100
+++ libid3tag-0.15.1b-ds/rccpatch.h 2008-04-12 21:36:35.000000000 +0200
@@ -0,0 +1,15 @@
+#ifndef _RCC_PATCH_H
+#define _RCC_PATCH_H
+
+#include "id3tag.h"
+
+void rccPatchFree();
+void rccPatchInit();
+void rccPatchSetContext(void *newctx);
+
+id3_utf8_t *rccPatchLatin2UTF(id3_latin1_t *str);
+id3_latin1_t *rccPatchUTF2Latin(id3_utf8_t *str);
+id3_latin1_t *rccPatchUTF2Out(id3_utf8_t *str);
+
+
+#endif /* _RCC_PATCH_H */
diff -dPNur libid3tag-0.15.1b/tag.c libid3tag-0.15.1b-ds/tag.c
--- libid3tag-0.15.1b/tag.c 2004-02-17 03:04:10.000000000 +0100
+++ libid3tag-0.15.1b-ds/tag.c 2008-04-12 21:37:12.000000000 +0200
@@ -45,6 +45,9 @@
# include "field.h"
# include "util.h"
+# include "utf8.h"
+# include "rccpatch.h"
+
/*
* NAME: tag->new()
* DESCRIPTION: allocate and return a new, empty tag
@@ -335,6 +338,8 @@
{
struct id3_frame *frame;
id3_ucs4_t ucs4[31];
+
+ id3_utf8_t *utf8;
if (text) {
trim(text);
@@ -350,9 +355,15 @@
ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1)
goto fail;
- if (text)
+ if (text) {
+ utf8 = rccPatchLatin2UTF(text);
+ if (utf8) {
+ if (strlen(utf8) > 30) utf8[30] = 0;
+ id3_utf8_decode(utf8, ucs4);
+ free(utf8);
+ } else
id3_latin1_decode(text, ucs4);
- else
+ } else
id3_ucs4_putnumber(ucs4, number);
if (strcmp(id, ID3_FRAME_COMMENT) == 0) {
diff -dPNur libid3tag-0.15.1b/ucs4.c libid3tag-0.15.1b-ds/ucs4.c
--- libid3tag-0.15.1b/ucs4.c 2004-01-23 10:41:32.000000000 +0100
+++ libid3tag-0.15.1b-ds/ucs4.c 2008-04-12 21:36:35.000000000 +0200
@@ -33,6 +33,9 @@
# include "utf16.h"
# include "utf8.h"
+# include
+# include "rccpatch.h"
+
id3_ucs4_t const id3_ucs4_empty[] = { 0 };
/*
@@ -125,6 +128,27 @@
{
id3_latin1_t *latin1;
+
+ id3_latin1_t *ltmp;
+ id3_utf8_t *utf8;
+
+ utf8 = malloc(id3_ucs4_utf8size(ucs4) * sizeof(*utf8));
+ if (utf8) {
+ id3_utf8_encode(utf8, ucs4);
+ ltmp = rccPatchUTF2Out(utf8);
+ free(utf8);
+
+ if (ltmp) {
+ latin1 = malloc((1+strlen(ltmp))*sizeof(char));
+ if (latin1) {
+ memcpy(latin1, ltmp, (1+strlen(ltmp)));
+ free(ltmp);
+ return release(latin1);
+ }
+ free(ltmp);
+ }
+ }
+
latin1 = malloc(id3_ucs4_latin1size(ucs4) * sizeof(*latin1));
if (latin1)
id3_latin1_encode(latin1, ucs4);