Add codepage translation for non-utf8 id3v1 tags

This commit is contained in:
Ron Pedde 2007-09-03 21:39:20 +00:00
parent 00cbda5e95
commit 9aaff066d3
5 changed files with 45 additions and 19 deletions

View File

@ -116,6 +116,13 @@
</item> </item>
</section> </section>
<section name="Scanning" advanced="true"> <section name="Scanning" advanced="true">
<item id="scanning:mp3_tag_codepage">
<name>MP3 Tag Codepage</name>
<short_description>
What codepage non-utf mp3 tags should be converted from (default: ISO-8859-1)
</short_description>
<type>text</type>
</item>
<item id="scanning:process_playlists"> <item id="scanning:process_playlists">
<name>Process Playlists</name> <name>Process Playlists</name>
<short_description> <short_description>
@ -335,4 +342,4 @@
<type size="80">text</type> <type size="80">text</type>
</item> </item>
</section> </section>
</config> </config>

View File

@ -146,6 +146,7 @@ static CONF_ELEMENTS conf_elements[] = {
{ 0, 0, CONF_T_INT,"scanning","case_sensitive" }, { 0, 0, CONF_T_INT,"scanning","case_sensitive" },
{ 0, 0, CONF_T_INT,"scanning","follow_symlinks" }, { 0, 0, CONF_T_INT,"scanning","follow_symlinks" },
{ 0, 0, CONF_T_INT,"scanning","skip_first" }, { 0, 0, CONF_T_INT,"scanning","skip_first" },
{ 0, 0, CONF_T_STRING,"scanning","mp3_tag_codepage" },
{ 0, 0, CONF_T_INT,"scan","correct_order" }, { 0, 0, CONF_T_INT,"scan","correct_order" },
/* remapped values */ /* remapped values */

View File

@ -303,6 +303,7 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
char *tmp; char *tmp;
int got_numeric_genre; int got_numeric_genre;
int rating; int rating;
char *conversion_codepage;
pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY); pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);
if(!pid3file) { if(!pid3file) {
@ -322,6 +323,9 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
DPRINTF(E_SPAM,L_SCAN,"Starting mp3 tag scan\n"); DPRINTF(E_SPAM,L_SCAN,"Starting mp3 tag scan\n");
conversion_codepage = conf_alloc_string("scanning","mp3_tag_codepage",
"ISO-8859-1");
index=0; index=0;
while((pid3frame=id3_tag_findframe(pid3tag,"",index))) { while((pid3frame=id3_tag_findframe(pid3tag,"",index))) {
used=0; used=0;
@ -345,20 +349,15 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
native_text=id3_field_getstrings(&pid3frame->fields[1],0); native_text=id3_field_getstrings(&pid3frame->fields[1],0);
if(native_text) { if(native_text) {
/* FIXME: I didn't understand what was happening here.
* this should really be a switch to evaluate latin1
* tags as native codepage. Not only is this hackish,
* it's just plain wrong.
*/
have_utf8=1; have_utf8=1;
if(conf_get_int("general","latin1_tags",0)) { utf8_text = util_xtoutf8_alloc(native_text,strlen(native_text),
utf8_text=(char *)id3_ucs4_latin1duplicate(native_text); conversion_codepage);
} else {
utf8_text=(char *)id3_ucs4_utf8duplicate(native_text);
}
if(utf8_text) if(!utf8_text) {
mem_register(utf8_text,0); utf8_text = (char*)id3_ucs4_latin1duplicate(native_text);
if(utf8_text)
mem_register(utf8_text,0);
}
if(!strcmp(pid3frame->id,"TIT2")) { /* Title */ if(!strcmp(pid3frame->id,"TIT2")) { /* Title */
used=1; used=1;
@ -509,6 +508,7 @@ int scan_mp3_get_mp3tags(char *file, MP3FILE *pmp3) {
index++; index++;
} }
free(conversion_codepage);
id3_file_close(pid3file); id3_file_close(pid3file);
DPRINTF(E_DBG,L_SCAN,"Got id3 tag successfully\n"); DPRINTF(E_DBG,L_SCAN,"Got id3 tag successfully\n");
return TRUE; return TRUE;
@ -766,7 +766,7 @@ void scan_mp3_get_frame_count(IOHANDLE hfile, SCAN_FRAMEINFO *pfi) {
DPRINTF(E_SPAM,L_SCAN,"Seeking to %ld\n",pos); DPRINTF(E_SPAM,L_SCAN,"Seeking to %ld\n",pos);
io_setpos(hfile,pos,SEEK_SET); io_setpos(hfile,pos,SEEK_SET);
len = sizeof(frame_buffer); len = sizeof(frame_buffer);
if(!io_read(hfile,frame_buffer,&len) || (len != sizeof(frame_buffer))) { if(!io_read(hfile,frame_buffer,&len) || (len != sizeof(frame_buffer))) {
/* check for valid frame */ /* check for valid frame */

View File

@ -102,19 +102,19 @@ int util_utf16_byte_len(unsigned char *utf16) {
unsigned char *util_utf8toutf16_alloc(unsigned char *utf8) { unsigned char *util_utf8toutf16_alloc(unsigned char *utf8) {
char *utf16; unsigned char *utf16;
utf16 = calloc(1,strlen((char*)utf8) * 4 + 1); utf16 = calloc(1,strlen((char*)utf8) * 4 + 1);
if(util_xtoy(utf16,strlen((char*)utf8) * 4 + 1, utf8, strlen((char*)utf8),"UTF-8","UTF-16LE")) { if(util_xtoy(utf16,strlen((char*)utf8) * 4 + 1, utf8, strlen((char*)utf8),"UTF-8","UTF-16LE")) {
return utf16; return utf16;
} }
free(utf16); free(utf16);
return NULL; return NULL;
} }
unsigned char *util_utf16toutf8_alloc(unsigned char *utf16, int slen) { unsigned char *util_utf16toutf8_alloc(unsigned char *utf16, int slen) {
char *utf8; unsigned char *utf8;
utf8=calloc(1, slen * 2 + 1); utf8=calloc(1, slen * 2 + 1);
if(util_xtoy(utf8,slen * 2 + 1,utf16,slen,"UTF-16LE","UTF-8")) { if(util_xtoy(utf8,slen * 2 + 1,utf16,slen,"UTF-16LE","UTF-8")) {
@ -125,17 +125,33 @@ unsigned char *util_utf16toutf8_alloc(unsigned char *utf16, int slen) {
return NULL; return NULL;
} }
unsigned char *util_xtoutf8_alloc(unsigned char *x, int slen, char *from) {
unsigned char *utf8;
utf8 = calloc(1, slen * 4 + 1);
if(util_xtoy(utf8,slen * 4 + 1, x, slen, from, "UTF-8")) {
return utf8;
}
free(utf8);
return NULL;
}
int util_xtoy(unsigned char *dbuffer, int dlen, unsigned char *sbuffer, int slen, char *from, char *to) { int util_xtoy(unsigned char *dbuffer, int dlen, unsigned char *sbuffer, int slen, char *from, char *to) {
iconv_t iv; iconv_t iv;
size_t csize; size_t csize;
size_t st_dlen = dlen;
size_t st_slen = slen;
memset(dbuffer,0,dlen); memset(dbuffer,0,dlen);
iv=iconv_open(to,from); iv=iconv_open(to,from);
if(iv == (iconv_t)-1) { if(iv == (iconv_t)-1) {
DPRINTF(E_LOG,L_MISC,"iconv error: iconv_open failed with %d\n",errno); DPRINTF(E_LOG,L_MISC,"iconv error: iconv_open failed with %d\n",errno);
} }
csize = iconv(iv,&sbuffer,&slen,&dbuffer,&dlen); csize = iconv(iv,(const char **)&sbuffer,&st_slen,
(char **)&dbuffer,&st_dlen);
if(csize == (size_t)-1) { if(csize == (size_t)-1) {
switch(errno) { switch(errno) {
case EILSEQ: case EILSEQ:
@ -397,6 +413,7 @@ char *util_vasprintf(char *fmt, va_list ap) {
if(!outbuf) if(!outbuf)
DPRINTF(E_FATAL,L_MISC,"Could not allocate buffer in vasprintf\n"); DPRINTF(E_FATAL,L_MISC,"Could not allocate buffer in vasprintf\n");
ap2=ap; /* shut up lint warnings */
VA_COPY(ap2,ap); VA_COPY(ap2,ap);
while(1) { while(1) {

View File

@ -46,6 +46,7 @@ extern unsigned char *util_utf16touft8_alloc(unsigned char *utf16, int slen);
extern int util_utf8toutf16(unsigned char *utf16, int dlen, unsigned char *utf8, int slen); extern int util_utf8toutf16(unsigned char *utf16, int dlen, unsigned char *utf8, int slen);
extern int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, int slen); extern int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, int slen);
extern int util_xtoy(unsigned char *dbuffer, int dlen, unsigned char *sbuffer, int slen, char *from, char *to); extern int util_xtoy(unsigned char *dbuffer, int dlen, unsigned char *sbuffer, int slen, char *from, char *to);
extern unsigned char *util_xtoutf8_alloc(unsigned char *x,int slen,char *from);
extern int util_utf16_byte_len(unsigned char *utf16); extern int util_utf16_byte_len(unsigned char *utf16);
extern void util_hexdump(unsigned char *block, int len); extern void util_hexdump(unsigned char *block, int len);