Mercurial > libavformat.hg
comparison mov.c @ 5790:dba191dda275 libavformat
In mov demuxer, convert mac encoded strings to utf-8
author | bcoudurier |
---|---|
date | Tue, 09 Mar 2010 01:03:42 +0000 |
parents | 8539cb618ae7 |
children | 536e5527c1e0 |
comparison
equal
deleted
inserted
replaced
5789:2c96c4c8b6e9 | 5790:dba191dda275 |
---|---|
91 get_be16(pb); // total tracks | 91 get_be16(pb); // total tracks |
92 | 92 |
93 return 0; | 93 return 0; |
94 } | 94 } |
95 | 95 |
96 static const uint32_t mac_to_unicode[128] = { | |
97 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, | |
98 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, | |
99 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3, | |
100 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC, | |
101 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF, | |
102 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8, | |
103 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211, | |
104 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8, | |
105 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB, | |
106 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153, | |
107 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA, | |
108 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02, | |
109 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1, | |
110 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4, | |
111 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC, | |
112 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7, | |
113 }; | |
114 | |
115 static int mov_read_mac_string(MOVContext *c, ByteIOContext *pb, int len, | |
116 char *dst, int dstlen) | |
117 { | |
118 char *p = dst; | |
119 char *end = dst+dstlen-1; | |
120 int i; | |
121 | |
122 for (i = 0; i < len; i++) { | |
123 uint8_t t, c = get_byte(pb); | |
124 if (c < 0x80 && p < end) | |
125 *p++ = c; | |
126 else | |
127 PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); | |
128 } | |
129 *p = 0; | |
130 return p - dst; | |
131 } | |
132 | |
96 static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom) | 133 static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom) |
97 { | 134 { |
98 #ifdef MOV_EXPORT_ALL_METADATA | 135 #ifdef MOV_EXPORT_ALL_METADATA |
99 char tmp_key[5]; | 136 char tmp_key[5]; |
100 #endif | 137 #endif |
101 char str[1024], key2[16], language[4] = {0}; | 138 char str[1024], key2[16], language[4] = {0}; |
102 const char *key = NULL; | 139 const char *key = NULL; |
103 uint16_t str_size; | 140 uint16_t str_size, langcode = 0; |
141 uint32_t data_type = 0; | |
104 int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL; | 142 int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL; |
105 | 143 |
106 switch (atom.type) { | 144 switch (atom.type) { |
107 case MKTAG(0xa9,'n','a','m'): key = "title"; break; | 145 case MKTAG(0xa9,'n','a','m'): key = "title"; break; |
108 case MKTAG(0xa9,'a','u','t'): | 146 case MKTAG(0xa9,'a','u','t'): |
128 | 166 |
129 if (c->itunes_metadata && atom.size > 8) { | 167 if (c->itunes_metadata && atom.size > 8) { |
130 int data_size = get_be32(pb); | 168 int data_size = get_be32(pb); |
131 int tag = get_le32(pb); | 169 int tag = get_le32(pb); |
132 if (tag == MKTAG('d','a','t','a')) { | 170 if (tag == MKTAG('d','a','t','a')) { |
133 get_be32(pb); // type | 171 data_type = get_be32(pb); // type |
134 get_be32(pb); // unknown | 172 get_be32(pb); // unknown |
135 str_size = data_size - 16; | 173 str_size = data_size - 16; |
136 atom.size -= 16; | 174 atom.size -= 16; |
137 } else return 0; | 175 } else return 0; |
138 } else if (atom.size > 4 && key && !c->itunes_metadata) { | 176 } else if (atom.size > 4 && key && !c->itunes_metadata) { |
139 str_size = get_be16(pb); // string length | 177 str_size = get_be16(pb); // string length |
140 ff_mov_lang_to_iso639(get_be16(pb), language); | 178 langcode = get_be16(pb); |
179 ff_mov_lang_to_iso639(langcode, language); | |
141 atom.size -= 4; | 180 atom.size -= 4; |
142 } else | 181 } else |
143 str_size = atom.size; | 182 str_size = atom.size; |
144 | 183 |
145 #ifdef MOV_EXPORT_ALL_METADATA | 184 #ifdef MOV_EXPORT_ALL_METADATA |
157 str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); | 196 str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); |
158 | 197 |
159 if (parse) | 198 if (parse) |
160 parse(c, pb, str_size); | 199 parse(c, pb, str_size); |
161 else { | 200 else { |
162 get_buffer(pb, str, str_size); | 201 if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded |
163 str[str_size] = 0; | 202 mov_read_mac_string(c, pb, str_size, str, sizeof(str)); |
203 } else { | |
204 get_buffer(pb, str, str_size); | |
205 str[str_size] = 0; | |
206 } | |
164 av_metadata_set(&c->fc->metadata, key, str); | 207 av_metadata_set(&c->fc->metadata, key, str); |
165 if (*language && strcmp(language, "und")) { | 208 if (*language && strcmp(language, "und")) { |
166 snprintf(key2, sizeof(key2), "%s-%s", key, language); | 209 snprintf(key2, sizeof(key2), "%s-%s", key, language); |
167 av_metadata_set(&c->fc->metadata, key2, str); | 210 av_metadata_set(&c->fc->metadata, key2, str); |
168 } | 211 } |
909 dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, | 952 dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size, |
910 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, | 953 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, |
911 (format >> 24) & 0xff, st->codec->codec_type); | 954 (format >> 24) & 0xff, st->codec->codec_type); |
912 | 955 |
913 if(st->codec->codec_type==CODEC_TYPE_VIDEO) { | 956 if(st->codec->codec_type==CODEC_TYPE_VIDEO) { |
914 uint8_t codec_name[32]; | 957 unsigned int color_depth, len; |
915 unsigned int color_depth; | |
916 int color_greyscale; | 958 int color_greyscale; |
917 | 959 |
918 st->codec->codec_id = id; | 960 st->codec->codec_id = id; |
919 get_be16(pb); /* version */ | 961 get_be16(pb); /* version */ |
920 get_be16(pb); /* revision level */ | 962 get_be16(pb); /* revision level */ |
928 get_be32(pb); /* horiz resolution */ | 970 get_be32(pb); /* horiz resolution */ |
929 get_be32(pb); /* vert resolution */ | 971 get_be32(pb); /* vert resolution */ |
930 get_be32(pb); /* data size, always 0 */ | 972 get_be32(pb); /* data size, always 0 */ |
931 get_be16(pb); /* frames per samples */ | 973 get_be16(pb); /* frames per samples */ |
932 | 974 |
933 get_buffer(pb, codec_name, 32); /* codec name, pascal string */ | 975 len = get_byte(pb); /* codec name, pascal string */ |
934 if (codec_name[0] <= 31) { | 976 if (len > 31) |
935 int i; | 977 len = 31; |
936 int pos = 0; | 978 mov_read_mac_string(c, pb, len, st->codec->codec_name, 32); |
937 for (i = 0; i < codec_name[0] && pos < sizeof(st->codec->codec_name) - 3; i++) { | 979 if (len < 31) |
938 uint8_t tmp; | 980 url_fskip(pb, 31 - len); |
939 PUT_UTF8(codec_name[i+1], tmp, st->codec->codec_name[pos++] = tmp;) | 981 /* codec_tag YV12 triggers an UV swap in rawdec.c */ |
940 } | 982 if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) |
941 st->codec->codec_name[pos] = 0; | 983 st->codec->codec_tag=MKTAG('I', '4', '2', '0'); |
942 /* codec_tag YV12 triggers an UV swap in rawdec.c */ | |
943 if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) | |
944 st->codec->codec_tag=MKTAG('I', '4', '2', '0'); | |
945 } | |
946 | 984 |
947 st->codec->bits_per_coded_sample = get_be16(pb); /* depth */ | 985 st->codec->bits_per_coded_sample = get_be16(pb); /* depth */ |
948 st->codec->color_table_id = get_be16(pb); /* colortable id */ | 986 st->codec->color_table_id = get_be16(pb); /* colortable id */ |
949 dprintf(c->fc, "depth %d, ctab id %d\n", | 987 dprintf(c->fc, "depth %d, ctab id %d\n", |
950 st->codec->bits_per_coded_sample, st->codec->color_table_id); | 988 st->codec->bits_per_coded_sample, st->codec->color_table_id); |