[Ffmpeg-devel] PUT_UTF8 & asf format enhancement

Zuxy Meng zuxy.meng
Sun Nov 5 09:56:13 CET 2006


Hi,

Currently asf format parser's broken in handling utf16 strings.
Attached patches correct this by:

1. Add a PUT_UTF8 macro to common.h; code borrowed from libavcodec/flacenc.c.
2. Make use of the macro in asf.c

-- 
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6
-------------- next part --------------
Index: libavutil/common.h
===================================================================
--- libavutil/common.h	???????? 6897??
+++ libavutil/common.h	????????????
@@ -338,6 +338,26 @@
         }\
     }
 
+#define PUT_UTF8(val, tmp, PUT_BYTE)\
+    {\
+        int bytes, shift;\
+        uint32_t in = val;\
+        if (in < 0x80) {\
+            tmp = in;\
+            PUT_BYTE\
+        } else {\
+            bytes = (av_log2(in) + 4) / 5;\
+            shift = (bytes - 1) * 6;\
+            tmp = (256 - (256 >> bytes)) | (in >> shift);\
+            PUT_BYTE\
+            while (shift >= 6) {\
+                shift -= 6;\
+                tmp = 0x80 | ((in >> shift) & 0x3f);\
+                PUT_BYTE\
+            }\
+        }\
+    }
+
 #if defined(ARCH_X86) || defined(ARCH_POWERPC)
 #if defined(ARCH_X86_64)
 static inline uint64_t read_time(void)
-------------- next part --------------
Index: libavformat/asf.c
===================================================================
--- libavformat/asf.c	???????? 6897??
+++ libavformat/asf.c	????????????
@@ -22,6 +22,7 @@
 #include "riff.h"
 #include "mpegaudio.h"
 #include "asf.h"
+#include "common.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -107,15 +108,11 @@
 
 static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size)
 {
-    int c;
-    char *q;
-
-    q = buf;
-    while (len > 0) {
-        c = get_le16(pb);
-        if ((q - buf) < buf_size - 1)
-            *q++ = c;
-        len-=2;
+    char* q = buf;
+    len /= 2;
+    while (len--) {
+        uint8_t tmp;
+        PUT_UTF8(get_le16(pb), tmp, if (q - buf < buf_size - 1) *q++ = tmp;)
     }
     *q = '\0';
 }
@@ -361,14 +358,15 @@
                         char *name, *value;
 
                         name_len = get_le16(pb);
-                        name = (char *)av_mallocz(name_len);
-                        get_str16_nolen(pb, name_len, name, name_len);
+                        name = (char *)av_malloc(name_len * 2);
+                        get_str16_nolen(pb, name_len, name, name_len * 2);
                         value_type = get_le16(pb);
                         value_len = get_le16(pb);
                         if ((value_type == 0) || (value_type == 1)) // unicode or byte
                         {
-                                value = (char *)av_mallocz(value_len);
-                                get_str16_nolen(pb, value_len, value, value_len);
+                                value = (char *)av_malloc(value_len * 2);
+                                get_str16_nolen(pb, value_len, value,
+                                        value_len * 2);
                                 if (strcmp(name,"WM/AlbumTitle")==0) { pstrcpy(s->album, sizeof(s->album), value); }
                                 av_free(value);
                         }



More information about the ffmpeg-devel mailing list