[MPlayer-dev-eng] [PATCH] Convert UCS-2LE encoded asf tag
Zuxy Meng
zuxy.meng at gmail.com
Wed Aug 23 07:32:45 CEST 2006
Hi,
Currently the simple pack_asf_string() in libmpdemux/asfheader.c only
allows single-byte western letters to be converted, messing up CJK
characters. This patch properly converts UCS-2LE encoded asf tags to
the charset that mplayer internally uses, with the help of iconv.
--
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6
-------------- next part --------------
Index: libmpdemux/asfheader.c
===================================================================
--- libmpdemux/asfheader.c ???????? 19503??
+++ libmpdemux/asfheader.c ????????????
@@ -9,6 +9,11 @@
#include "mp_msg.h"
#include "help_mp.h"
+#ifdef USE_ICONV
+extern char* mp_msg_charset;
+#include <iconv.h>
+#endif
+
#include "stream.h"
#include "demuxer.h"
#include "stheader.h"
@@ -62,7 +67,7 @@
// the variable string is modify in this function
-void pack_asf_string(char* string, int length) {
+static void pack_asf_string(char* string, int length) {
int i,j;
if( string==NULL ) return;
for( i=0, j=0; i<length && string[i]!='\0'; i+=2, j++) {
@@ -71,9 +76,7 @@
string[j]='\0';
}
-// the variable string is modify in this function
-void print_asf_string(const char* name, char* string, int length) {
- pack_asf_string(string, length);
+static void print_asf_string(const char* name, char* string, int length) {
mp_msg(MSGT_HEADER,MSGL_V,"%s%s\n", name, string);
}
@@ -192,6 +195,36 @@
return 1;
}
+/* *p_string must be either NULL or a malloc'ed pointer */
+static void ucs2tolocal(char** p_string,
+ uint16_t const* wstring, size_t srclen)
+{
+#ifdef USE_ICONV
+ iconv_t ucs2iconv;
+ size_t outlen;
+ char* tocode;
+ char* outbuf;
+
+#ifndef MSG_CHARSET
+ tocode = MSG_CHARSET;
+#else
+ tocode = mp_msg_charset;
+#endif
+ ucs2iconv = iconv_open(tocode, "UCS-2LE");
+ if (ucs2iconv != (iconv_t)(-1)) {
+ outlen = srclen * 2 + 1;
+ *p_string = outbuf = realloc(*p_string, outlen);
+ if (outbuf)
+ iconv(ucs2iconv, &wstring, &srclen, &outbuf, &outlen);
+ iconv_close(ucs2iconv);
+ return;
+ }
+#endif
+ *p_string = realloc(*p_string, srclen);
+ memcpy(*p_string, wstring, srclen);
+ pack_asf_string(*p_string, srclen);
+}
+
int read_asf_header(demuxer_t *demuxer,struct asf_priv* asf){
int hdr_len = asf->header.objh.size - sizeof(asf->header);
char *hdr = NULL;
@@ -207,6 +240,7 @@
ASF_stream_header_t *streamh;
uint8_t *buffer;
int audio_pos=0;
+ char *string=NULL;
if(hdr_len < 0) {
mp_msg(MSGT_HEADER, MSGL_FATAL, "Header size is too small.\n");
@@ -339,64 +373,64 @@
pos = find_asf_guid(hdr, asf_content_desc_guid, 0, hdr_len);
if (pos >= 0) {
ASF_content_description_t *contenth = (ASF_content_description_t *)&hdr[pos];
- char *string=NULL;
+ uint16_t* wstring = NULL;
+ size_t wtoclen = 0;
pos += sizeof(ASF_content_description_t);
if (pos > hdr_len) goto len_err_out;
le2me_ASF_content_description_t(contenth);
mp_msg(MSGT_HEADER,MSGL_V,"\n");
// extract the title
if( contenth->title_size!=0 ) {
- string = &hdr[pos];
+ wstring = (uint16_t*)(&hdr[pos]);
pos += contenth->title_size;
if (pos > hdr_len) goto len_err_out;
+ ucs2tolocal(&string, wstring, contenth->title_size);
if( mp_msg_test(MSGT_HEADER,MSGL_V) )
print_asf_string(" Title: ", string, contenth->title_size);
- else
- pack_asf_string(string, contenth->title_size);
demux_info_add(demuxer, "name", string);
}
// extract the author
if( contenth->author_size!=0 ) {
- string = &hdr[pos];
+ wstring = (uint16_t*)&hdr[pos];
pos += contenth->author_size;
if (pos > hdr_len) goto len_err_out;
+ ucs2tolocal(&string, wstring, contenth->title_size);
if( mp_msg_test(MSGT_HEADER,MSGL_V) )
print_asf_string(" Author: ", string, contenth->author_size);
- else
- pack_asf_string(string, contenth->author_size);
demux_info_add(demuxer, "author", string);
}
// extract the copyright
if( contenth->copyright_size!=0 ) {
- string = &hdr[pos];
+ wstring = (uint16_t*)&hdr[pos];
pos += contenth->copyright_size;
if (pos > hdr_len) goto len_err_out;
+ ucs2tolocal(&string, wstring, contenth->title_size);
if( mp_msg_test(MSGT_HEADER,MSGL_V) )
print_asf_string(" Copyright: ", string, contenth->copyright_size);
- else
- pack_asf_string(string, contenth->copyright_size);
demux_info_add(demuxer, "copyright", string);
}
// extract the comment
if( contenth->comment_size!=0 ) {
- string = &hdr[pos];
+ wstring = (uint16_t*)&hdr[pos];
pos += contenth->comment_size;
if (pos > hdr_len) goto len_err_out;
+ ucs2tolocal(&string, wstring, contenth->title_size);
if( mp_msg_test(MSGT_HEADER,MSGL_V) )
print_asf_string(" Comment: ", string, contenth->comment_size);
- else
- pack_asf_string(string, contenth->comment_size);
demux_info_add(demuxer, "comments", string);
}
// extract the rating
if( contenth->rating_size!=0 ) {
- string = &hdr[pos];
+ wstring = (uint16_t*)&hdr[pos];
pos += contenth->rating_size;
if (pos > hdr_len) goto len_err_out;
+ ucs2tolocal(&string, wstring, contenth->title_size);
if( mp_msg_test(MSGT_HEADER,MSGL_V) )
print_asf_string(" Rating: ", string, contenth->rating_size);
}
mp_msg(MSGT_HEADER,MSGL_V,"\n");
+ free(string);
+ string = NULL;
}
// find content header
@@ -500,5 +534,6 @@
err_out:
if (hdr) free(hdr);
if (streams) free(streams);
+ if (string) free(string);
return 0;
}
More information about the MPlayer-dev-eng
mailing list