summaryrefslogtreecommitdiff
path: root/libavformat/id3v2.c (plain)
blob: d4f1390b9db5a5584936d72ada64dd466c844f0a
1/*
2 * Copyright (c) 2003 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * ID3v2 header parser
24 *
25 * Specifications available at:
26 * http://id3.org/Developer_Information
27 */
28
29#include "config.h"
30
31#if CONFIG_ZLIB
32#include <zlib.h>
33#endif
34
35#include "libavutil/avstring.h"
36#include "libavutil/dict.h"
37#include "libavutil/intreadwrite.h"
38#include "avio_internal.h"
39#include "internal.h"
40#include "id3v1.h"
41#include "id3v2.h"
42
43const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
44 { "TALB", "album" },
45 { "TCOM", "composer" },
46 { "TCON", "genre" },
47 { "TCOP", "copyright" },
48 { "TENC", "encoded_by" },
49 { "TIT2", "title" },
50 { "TLAN", "language" },
51 { "TPE1", "artist" },
52 { "TPE2", "album_artist" },
53 { "TPE3", "performer" },
54 { "TPOS", "disc" },
55 { "TPUB", "publisher" },
56 { "TRCK", "track" },
57 { "TSSE", "encoder" },
58 { "USLT", "lyrics" },
59 { 0 }
60};
61
62const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
63 { "TCMP", "compilation" },
64 { "TDRC", "date" },
65 { "TDRL", "date" },
66 { "TDEN", "creation_time" },
67 { "TSOA", "album-sort" },
68 { "TSOP", "artist-sort" },
69 { "TSOT", "title-sort" },
70 { 0 }
71};
72
73static const AVMetadataConv id3v2_2_metadata_conv[] = {
74 { "TAL", "album" },
75 { "TCO", "genre" },
76 { "TCP", "compilation" },
77 { "TT2", "title" },
78 { "TEN", "encoded_by" },
79 { "TP1", "artist" },
80 { "TP2", "album_artist" },
81 { "TP3", "performer" },
82 { "TRK", "track" },
83 { 0 }
84};
85
86const char ff_id3v2_tags[][4] = {
87 "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
88 "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
89 "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
90 "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
91 { 0 },
92};
93
94const char ff_id3v2_4_tags[][4] = {
95 "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
96 "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
97 { 0 },
98};
99
100const char ff_id3v2_3_tags[][4] = {
101 "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
102 { 0 },
103};
104
105const char *ff_id3v2_picture_types[21] = {
106 "Other",
107 "32x32 pixels 'file icon'",
108 "Other file icon",
109 "Cover (front)",
110 "Cover (back)",
111 "Leaflet page",
112 "Media (e.g. label side of CD)",
113 "Lead artist/lead performer/soloist",
114 "Artist/performer",
115 "Conductor",
116 "Band/Orchestra",
117 "Composer",
118 "Lyricist/text writer",
119 "Recording Location",
120 "During recording",
121 "During performance",
122 "Movie/video screen capture",
123 "A bright coloured fish",
124 "Illustration",
125 "Band/artist logotype",
126 "Publisher/Studio logotype",
127};
128
129const CodecMime ff_id3v2_mime_tags[] = {
130 { "image/gif", AV_CODEC_ID_GIF },
131 { "image/jpeg", AV_CODEC_ID_MJPEG },
132 { "image/jpg", AV_CODEC_ID_MJPEG },
133 { "image/png", AV_CODEC_ID_PNG },
134 { "image/tiff", AV_CODEC_ID_TIFF },
135 { "image/bmp", AV_CODEC_ID_BMP },
136 { "JPG", AV_CODEC_ID_MJPEG }, /* ID3v2.2 */
137 { "PNG", AV_CODEC_ID_PNG }, /* ID3v2.2 */
138 { "", AV_CODEC_ID_NONE },
139};
140
141int ff_id3v2_match(const uint8_t *buf, const char *magic)
142{
143 return buf[0] == magic[0] &&
144 buf[1] == magic[1] &&
145 buf[2] == magic[2] &&
146 buf[3] != 0xff &&
147 buf[4] != 0xff &&
148 (buf[6] & 0x80) == 0 &&
149 (buf[7] & 0x80) == 0 &&
150 (buf[8] & 0x80) == 0 &&
151 (buf[9] & 0x80) == 0;
152}
153
154int ff_id3v2_tag_len(const uint8_t *buf)
155{
156 int len = ((buf[6] & 0x7f) << 21) +
157 ((buf[7] & 0x7f) << 14) +
158 ((buf[8] & 0x7f) << 7) +
159 (buf[9] & 0x7f) +
160 ID3v2_HEADER_SIZE;
161 if (buf[5] & 0x10)
162 len += ID3v2_HEADER_SIZE;
163 return len;
164}
165
166static unsigned int get_size(AVIOContext *s, int len)
167{
168 int v = 0;
169 while (len--)
170 v = (v << 7) + (avio_r8(s) & 0x7F);
171 return v;
172}
173
174static unsigned int size_to_syncsafe(unsigned int size)
175{
176 return (((size) & (0x7f << 0)) >> 0) +
177 (((size) & (0x7f << 8)) >> 1) +
178 (((size) & (0x7f << 16)) >> 2) +
179 (((size) & (0x7f << 24)) >> 3);
180}
181
182/* No real verification, only check that the tag consists of
183 * a combination of capital alpha-numerical characters */
184static int is_tag(const char *buf, unsigned int len)
185{
186 if (!len)
187 return 0;
188
189 while (len--)
190 if ((buf[len] < 'A' ||
191 buf[len] > 'Z') &&
192 (buf[len] < '0' ||
193 buf[len] > '9'))
194 return 0;
195
196 return 1;
197}
198
199/**
200 * Return 1 if the tag of length len at the given offset is valid, 0 if not, -1 on error
201 */
202static int check_tag(AVIOContext *s, int offset, unsigned int len)
203{
204 char tag[4];
205
206 if (len > 4 ||
207 avio_seek(s, offset, SEEK_SET) < 0 ||
208 avio_read(s, tag, len) < (int)len)
209 return -1;
210 else if (!AV_RB32(tag) || is_tag(tag, len))
211 return 1;
212
213 return 0;
214}
215
216/**
217 * Free GEOB type extra metadata.
218 */
219static void free_geobtag(void *obj)
220{
221 ID3v2ExtraMetaGEOB *geob = obj;
222 av_freep(&geob->mime_type);
223 av_freep(&geob->file_name);
224 av_freep(&geob->description);
225 av_freep(&geob->data);
226 av_free(geob);
227}
228
229/**
230 * Decode characters to UTF-8 according to encoding type. The decoded buffer is
231 * always null terminated. Stop reading when either *maxread bytes are read from
232 * pb or U+0000 character is found.
233 *
234 * @param dst Pointer where the address of the buffer with the decoded bytes is
235 * stored. Buffer must be freed by caller.
236 * @param maxread Pointer to maximum number of characters to read from the
237 * AVIOContext. After execution the value is decremented by the number of bytes
238 * actually read.
239 * @returns 0 if no error occurred, dst is uninitialized on error
240 */
241static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
242 uint8_t **dst, int *maxread)
243{
244 int ret;
245 uint8_t tmp;
246 uint32_t ch = 1;
247 int left = *maxread;
248 unsigned int (*get)(AVIOContext*) = avio_rb16;
249 AVIOContext *dynbuf;
250
251 if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
252 av_log(s, AV_LOG_ERROR, "Error opening memory stream\n");
253 return ret;
254 }
255
256 switch (encoding) {
257 case ID3v2_ENCODING_ISO8859:
258#if 0
259 while (left && ch) {
260 ch = avio_r8(pb);
261 PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
262 left--;
263 }
264#endif
265 while (left && ch) {
266 ch = avio_r8(pb);
267 avio_w8(dynbuf, ch);
268 left--;
269 }
270 break;
271
272 case ID3v2_ENCODING_UTF16BOM:
273 if ((left -= 2) < 0) {
274 av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n");
275 ffio_free_dyn_buf(&dynbuf);
276 *dst = NULL;
277 return AVERROR_INVALIDDATA;
278 }
279 switch (avio_rb16(pb)) {
280 case 0xfffe:
281 get = avio_rl16;
282 case 0xfeff:
283 break;
284 default:
285 av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n");
286 ffio_free_dyn_buf(&dynbuf);
287 *dst = NULL;
288 *maxread = left;
289 return AVERROR_INVALIDDATA;
290 }
291
292 int i = 0;
293 int len = left / 2;
294 int tlen = left;
295 int eightBit = 1;
296 uint16_t *framedata = malloc(left+1);
297 memset(framedata, 0, left+1);
298 for (i = 0; i < len; i++) {
299 framedata[i] = get(pb);
300 left -= 2;
301 if (framedata[i] > 0xff) {
302 eightBit = 0;
303 }
304 }
305 if (eightBit) {
306 for (i = 0; i < len; i++) {
307 avio_w8(dynbuf, framedata[i]);
308 }
309 free(framedata);
310 break;
311 }
312 else {
313 free(framedata);
314 left = tlen - left;
315 avio_seek(pb, -left, SEEK_CUR);
316 }
317 // fall-through
318
319 case ID3v2_ENCODING_UTF16BE:
320 while ((left > 1) && ch) {
321 GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;)
322 PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
323 }
324 if (left < 0)
325 left += 2; /* did not read last char from pb */
326 break;
327
328 case ID3v2_ENCODING_UTF8:
329 while (left && ch) {
330 ch = avio_r8(pb);
331 avio_w8(dynbuf, ch);
332 left--;
333 }
334 break;
335 default:
336 av_log(s, AV_LOG_WARNING, "Unknown encoding\n");
337 }
338
339 if (ch)
340 avio_w8(dynbuf, 0);
341
342 avio_close_dyn_buf(dynbuf, dst);
343 *maxread = left;
344
345 return 0;
346}
347
348/**
349 * Parse a text tag.
350 */
351static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
352 AVDictionary **metadata, const char *key)
353{
354 uint8_t *dst;
355 int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
356 unsigned genre;
357
358 if (taglen < 1)
359 return;
360
361 encoding = avio_r8(pb);
362 taglen--; /* account for encoding type byte */
363
364 if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
365 av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
366 return;
367 }
368
369 if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) &&
370 (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
371 genre <= ID3v1_GENRE_MAX) {
372 av_freep(&dst);
373 dst = av_strdup(ff_id3v1_genre_str[genre]);
374 } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
375 /* dst now contains the key, need to get value */
376 key = dst;
377 if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
378 av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
379 av_freep(&key);
380 return;
381 }
382 dict_flags |= AV_DICT_DONT_STRDUP_KEY;
383 } else if (!*dst)
384 av_freep(&dst);
385
386 if (dst)
387 av_dict_set(metadata, key, dst, dict_flags);
388}
389
390static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen,
391 AVDictionary **metadata)
392{
393 uint8_t lang[4];
394 uint8_t *descriptor = NULL; // 'Content descriptor'
395 uint8_t *text = NULL;
396 char *key = NULL;
397 int encoding;
398 int ok = 0;
399
400 if (taglen < 1)
401 goto error;
402
403 encoding = avio_r8(pb);
404 taglen--;
405
406 if (avio_read(pb, lang, 3) < 3)
407 goto error;
408 lang[3] = '\0';
409 taglen -= 3;
410
411 if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0)
412 goto error;
413
414 if (decode_str(s, pb, encoding, &text, &taglen) < 0)
415 goto error;
416
417 // FFmpeg does not support hierarchical metadata, so concatenate the keys.
418 key = av_asprintf("lyrics-%s%s%s", descriptor[0] ? (char *)descriptor : "",
419 descriptor[0] ? "-" : "",
420 lang);
421 if (!key)
422 goto error;
423
424 av_dict_set(metadata, key, text, 0);
425
426 ok = 1;
427error:
428 if (!ok)
429 av_log(s, AV_LOG_ERROR, "Error reading lyrics, skipped\n");
430 av_free(descriptor);
431 av_free(text);
432 av_free(key);
433}
434
435/**
436 * Parse a comment tag.
437 */
438static void read_comment(AVFormatContext *s, AVIOContext *pb, int taglen,
439 AVDictionary **metadata)
440{
441 const char *key = "comment";
442 uint8_t *dst;
443 int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
444 av_unused int language;
445
446 if (taglen < 4)
447 return;
448
449 encoding = avio_r8(pb);
450 language = avio_rl24(pb);
451 taglen -= 4;
452
453 if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
454 av_log(s, AV_LOG_ERROR, "Error reading comment frame, skipped\n");
455 return;
456 }
457
458 if (dst && !*dst)
459 av_freep(&dst);
460
461 if (dst) {
462 key = (const char *) dst;
463 dict_flags |= AV_DICT_DONT_STRDUP_KEY;
464 }
465
466 if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
467 av_log(s, AV_LOG_ERROR, "Error reading comment frame, skipped\n");
468 if (dict_flags & AV_DICT_DONT_STRDUP_KEY)
469 av_freep((void*)&key);
470 return;
471 }
472
473 if (dst)
474 av_dict_set(metadata, key, (const char *) dst, dict_flags);
475}
476
477/**
478 * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
479 */
480static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
481 const char *tag, ID3v2ExtraMeta **extra_meta,
482 int isv34)
483{
484 ID3v2ExtraMetaGEOB *geob_data = NULL;
485 ID3v2ExtraMeta *new_extra = NULL;
486 char encoding;
487 unsigned int len;
488
489 if (taglen < 1)
490 return;
491
492 geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
493 if (!geob_data) {
494 av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
495 sizeof(ID3v2ExtraMetaGEOB));
496 return;
497 }
498
499 new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
500 if (!new_extra) {
501 av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
502 sizeof(ID3v2ExtraMeta));
503 goto fail;
504 }
505
506 /* read encoding type byte */
507 encoding = avio_r8(pb);
508 taglen--;
509
510 /* read MIME type (always ISO-8859) */
511 if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
512 &taglen) < 0 ||
513 taglen <= 0)
514 goto fail;
515
516 /* read file name */
517 if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
518 taglen <= 0)
519 goto fail;
520
521 /* read content description */
522 if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
523 taglen < 0)
524 goto fail;
525
526 if (taglen) {
527 /* save encapsulated binary data */
528 geob_data->data = av_malloc(taglen);
529 if (!geob_data->data) {
530 av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
531 goto fail;
532 }
533 if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
534 av_log(s, AV_LOG_WARNING,
535 "Error reading GEOB frame, data truncated.\n");
536 geob_data->datasize = len;
537 } else {
538 geob_data->data = NULL;
539 geob_data->datasize = 0;
540 }
541
542 /* add data to the list */
543 new_extra->tag = "GEOB";
544 new_extra->data = geob_data;
545 new_extra->next = *extra_meta;
546 *extra_meta = new_extra;
547
548 return;
549
550fail:
551 av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
552 free_geobtag(geob_data);
553 av_free(new_extra);
554 return;
555}
556
557static int is_number(const char *str)
558{
559 while (*str >= '0' && *str <= '9')
560 str++;
561 return !*str;
562}
563
564static AVDictionaryEntry *get_date_tag(AVDictionary *m, const char *tag)
565{
566 AVDictionaryEntry *t;
567 if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
568 strlen(t->value) == 4 && is_number(t->value))
569 return t;
570 return NULL;
571}
572
573static void merge_date(AVDictionary **m)
574{
575 AVDictionaryEntry *t;
576 char date[17] = { 0 }; // YYYY-MM-DD hh:mm
577
578 if (!(t = get_date_tag(*m, "TYER")) &&
579 !(t = get_date_tag(*m, "TYE")))
580 return;
581 av_strlcpy(date, t->value, 5);
582 av_dict_set(m, "TYER", NULL, 0);
583 av_dict_set(m, "TYE", NULL, 0);
584
585 if (!(t = get_date_tag(*m, "TDAT")) &&
586 !(t = get_date_tag(*m, "TDA")))
587 goto finish;
588 snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
589 av_dict_set(m, "TDAT", NULL, 0);
590 av_dict_set(m, "TDA", NULL, 0);
591
592 if (!(t = get_date_tag(*m, "TIME")) &&
593 !(t = get_date_tag(*m, "TIM")))
594 goto finish;
595 snprintf(date + 10, sizeof(date) - 10,
596 " %.2s:%.2s", t->value, t->value + 2);
597 av_dict_set(m, "TIME", NULL, 0);
598 av_dict_set(m, "TIM", NULL, 0);
599
600finish:
601 if (date[0])
602 av_dict_set(m, "date", date, 0);
603}
604
605static void free_apic(void *obj)
606{
607 ID3v2ExtraMetaAPIC *apic = obj;
608 av_buffer_unref(&apic->buf);
609 av_freep(&apic->description);
610 av_freep(&apic);
611}
612
613static void rstrip_spaces(char *buf)
614{
615 size_t len = strlen(buf);
616 while (len > 0 && buf[len - 1] == ' ')
617 buf[--len] = 0;
618}
619
620static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
621 const char *tag, ID3v2ExtraMeta **extra_meta,
622 int isv34)
623{
624 int enc, pic_type;
625 char mimetype[64];
626 const CodecMime *mime = ff_id3v2_mime_tags;
627 enum AVCodecID id = AV_CODEC_ID_NONE;
628 ID3v2ExtraMetaAPIC *apic = NULL;
629 ID3v2ExtraMeta *new_extra = NULL;
630 int64_t end = avio_tell(pb) + taglen;
631
632 if (taglen <= 4 || (!isv34 && taglen <= 6))
633 goto fail;
634
635 new_extra = av_mallocz(sizeof(*new_extra));
636 apic = av_mallocz(sizeof(*apic));
637 if (!new_extra || !apic)
638 goto fail;
639
640 enc = avio_r8(pb);
641 taglen--;
642
643 /* mimetype */
644 if (isv34) {
645 taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype));
646 } else {
647 avio_read(pb, mimetype, 3);
648 mimetype[3] = 0;
649 taglen -= 3;
650 }
651
652 while (mime->id != AV_CODEC_ID_NONE) {
653 if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) {
654 id = mime->id;
655 break;
656 }
657 mime++;
658 }
659 if (id == AV_CODEC_ID_NONE) {
660 av_log(s, AV_LOG_WARNING,
661 "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
662 goto fail;
663 }
664 apic->id = id;
665
666 /* picture type */
667 pic_type = avio_r8(pb);
668 taglen--;
669 if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
670 av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
671 pic_type);
672 pic_type = 0;
673 }
674 apic->type = ff_id3v2_picture_types[pic_type];
675
676 /* description and picture data */
677 if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
678 av_log(s, AV_LOG_ERROR,
679 "Error decoding attached picture description.\n");
680 goto fail;
681 }
682
683 apic->buf = av_buffer_alloc(taglen + AV_INPUT_BUFFER_PADDING_SIZE);
684 if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)
685 goto fail;
686 memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
687
688 new_extra->tag = "APIC";
689 new_extra->data = apic;
690 new_extra->next = *extra_meta;
691 *extra_meta = new_extra;
692
693 // The description must be unique, and some ID3v2 tag writers add spaces
694 // to write several APIC entries with the same description.
695 rstrip_spaces(apic->description);
696
697 return;
698
699fail:
700 if (apic)
701 free_apic(apic);
702 av_freep(&new_extra);
703 avio_seek(pb, end, SEEK_SET);
704}
705
706static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34)
707{
708 AVRational time_base = {1, 1000};
709 uint32_t start, end;
710 AVChapter *chapter;
711 uint8_t *dst = NULL;
712 int taglen;
713 char tag[5];
714
715 if (!s) {
716 /* We should probably just put the chapter data to extra_meta here
717 * and do the AVFormatContext-needing part in a separate
718 * ff_id3v2_parse_apic()-like function. */
719 av_log(NULL, AV_LOG_DEBUG, "No AVFormatContext, skipped ID3 chapter data\n");
720 return;
721 }
722
723 if (decode_str(s, pb, 0, &dst, &len) < 0)
724 return;
725 if (len < 16)
726 return;
727
728 start = avio_rb32(pb);
729 end = avio_rb32(pb);
730 avio_skip(pb, 8);
731
732 chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
733 if (!chapter) {
734 av_free(dst);
735 return;
736 }
737
738 len -= 16;
739 while (len > 10) {
740 if (avio_read(pb, tag, 4) < 4)
741 goto end;
742 tag[4] = 0;
743 taglen = avio_rb32(pb);
744 avio_skip(pb, 2);
745 len -= 10;
746 if (taglen < 0 || taglen > len)
747 goto end;
748 if (tag[0] == 'T')
749 read_ttag(s, pb, taglen, &chapter->metadata, tag);
750 else
751 avio_skip(pb, taglen);
752 len -= taglen;
753 }
754
755 ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv);
756 ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv);
757end:
758 av_free(dst);
759}
760
761static void free_priv(void *obj)
762{
763 ID3v2ExtraMetaPRIV *priv = obj;
764 av_freep(&priv->owner);
765 av_freep(&priv->data);
766 av_freep(&priv);
767}
768
769static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
770 const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
771{
772 ID3v2ExtraMeta *meta;
773 ID3v2ExtraMetaPRIV *priv;
774
775 meta = av_mallocz(sizeof(*meta));
776 priv = av_mallocz(sizeof(*priv));
777
778 if (!meta || !priv)
779 goto fail;
780
781 if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &priv->owner, &taglen) < 0)
782 goto fail;
783
784 priv->data = av_malloc(taglen);
785 if (!priv->data)
786 goto fail;
787
788 priv->datasize = taglen;
789
790 if (avio_read(pb, priv->data, priv->datasize) != priv->datasize)
791 goto fail;
792
793 meta->tag = "PRIV";
794 meta->data = priv;
795 meta->next = *extra_meta;
796 *extra_meta = meta;
797
798 return;
799
800fail:
801 if (priv)
802 free_priv(priv);
803 av_freep(&meta);
804}
805
806typedef struct ID3v2EMFunc {
807 const char *tag3;
808 const char *tag4;
809 void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen,
810 const char *tag, ID3v2ExtraMeta **extra_meta,
811 int isv34);
812 void (*free)(void *obj);
813} ID3v2EMFunc;
814
815static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
816 { "GEO", "GEOB", read_geobtag, free_geobtag },
817 { "PIC", "APIC", read_apic, free_apic },
818 { "CHAP","CHAP", read_chapter, NULL },
819 { "PRIV","PRIV", read_priv, free_priv },
820 { NULL }
821};
822
823/**
824 * Get the corresponding ID3v2EMFunc struct for a tag.
825 * @param isv34 Determines if v2.2 or v2.3/4 strings are used
826 * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
827 */
828static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
829{
830 int i = 0;
831 while (id3v2_extra_meta_funcs[i].tag3) {
832 if (tag && !memcmp(tag,
833 (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
834 id3v2_extra_meta_funcs[i].tag3),
835 (isv34 ? 4 : 3)))
836 return &id3v2_extra_meta_funcs[i];
837 i++;
838 }
839 return NULL;
840}
841
842static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
843 AVFormatContext *s, int len, uint8_t version,
844 uint8_t flags, ID3v2ExtraMeta **extra_meta)
845{
846 int isv34, unsync;
847 unsigned tlen;
848 char tag[5];
849 int64_t next, end = avio_tell(pb) + len;
850 int taghdrlen;
851 const char *reason = NULL;
852 AVIOContext pb_local;
853 AVIOContext *pbx;
854 unsigned char *buffer = NULL;
855 int buffer_size = 0;
856 const ID3v2EMFunc *extra_func = NULL;
857 unsigned char *uncompressed_buffer = NULL;
858 av_unused int uncompressed_buffer_size = 0;
859 const char *comm_frame;
860
861 av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len);
862
863 switch (version) {
864 case 2:
865 if (flags & 0x40) {
866 reason = "compression";
867 goto error;
868 }
869 isv34 = 0;
870 taghdrlen = 6;
871 comm_frame = "COM";
872 break;
873
874 case 3:
875 case 4:
876 isv34 = 1;
877 taghdrlen = 10;
878 comm_frame = "COMM";
879 break;
880
881 default:
882 reason = "version";
883 goto error;
884 }
885
886 unsync = flags & 0x80;
887
888 if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
889 int extlen = get_size(pb, 4);
890 if (version == 4)
891 /* In v2.4 the length includes the length field we just read. */
892 extlen -= 4;
893
894 if (extlen < 0) {
895 reason = "invalid extended header length";
896 goto error;
897 }
898 avio_skip(pb, extlen);
899 len -= extlen + 4;
900 if (len < 0) {
901 reason = "extended header too long.";
902 goto error;
903 }
904 }
905
906 while (len >= taghdrlen) {
907 unsigned int tflags = 0;
908 int tunsync = 0;
909 int tcomp = 0;
910 int tencr = 0;
911 unsigned long av_unused dlen;
912
913 if (isv34) {
914 if (avio_read(pb, tag, 4) < 4)
915 break;
916 tag[4] = 0;
917 if (version == 3) {
918 tlen = avio_rb32(pb);
919 } else {
920 /* some encoders incorrectly uses v3 sizes instead of syncsafe ones
921 * so check the next tag to see which one to use */
922 tlen = avio_rb32(pb);
923 if (tlen > 0x7f) {
924 if (tlen < len) {
925 int64_t cur = avio_tell(pb);
926
927 if (ffio_ensure_seekback(pb, 2 /* tflags */ + tlen + 4 /* next tag */))
928 break;
929
930 if (check_tag(pb, cur + 2 + size_to_syncsafe(tlen), 4) == 1)
931 tlen = size_to_syncsafe(tlen);
932 else if (check_tag(pb, cur + 2 + tlen, 4) != 1)
933 break;
934 avio_seek(pb, cur, SEEK_SET);
935 } else
936 tlen = size_to_syncsafe(tlen);
937 }
938 }
939 tflags = avio_rb16(pb);
940 tunsync = tflags & ID3v2_FLAG_UNSYNCH;
941 } else {
942 if (avio_read(pb, tag, 3) < 3)
943 break;
944 tag[3] = 0;
945 tlen = avio_rb24(pb);
946 }
947 if (tlen > (1<<28))
948 break;
949 len -= taghdrlen + tlen;
950
951 if (len < 0)
952 break;
953
954 next = avio_tell(pb) + tlen;
955
956 if (!tlen) {
957 if (tag[0])
958 av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
959 tag);
960 continue;
961 }
962
963 if (tflags & ID3v2_FLAG_DATALEN) {
964 if (tlen < 4)
965 break;
966 dlen = avio_rb32(pb);
967 tlen -= 4;
968 } else
969 dlen = tlen;
970
971 tcomp = tflags & ID3v2_FLAG_COMPRESSION;
972 tencr = tflags & ID3v2_FLAG_ENCRYPTION;
973
974 /* skip encrypted tags and, if no zlib, compressed tags */
975 if (tencr || (!CONFIG_ZLIB && tcomp)) {
976 const char *type;
977 if (!tcomp)
978 type = "encrypted";
979 else if (!tencr)
980 type = "compressed";
981 else
982 type = "encrypted and compressed";
983
984 av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
985 avio_skip(pb, tlen);
986 /* check for text tag or supported special meta tag */
987 } else if (tag[0] == 'T' ||
988 !memcmp(tag, "USLT", 4) ||
989 !strcmp(tag, comm_frame) ||
990 (extra_meta &&
991 (extra_func = get_extra_meta_func(tag, isv34)))) {
992 pbx = pb;
993
994 if (unsync || tunsync || tcomp) {
995 av_fast_malloc(&buffer, &buffer_size, tlen);
996 if (!buffer) {
997 av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
998 goto seek;
999 }
1000 }
1001 if (unsync || tunsync) {
1002 int64_t end = avio_tell(pb) + tlen;
1003 uint8_t *b;
1004
1005 b = buffer;
1006 while (avio_tell(pb) < end && b - buffer < tlen && !pb->eof_reached) {
1007 *b++ = avio_r8(pb);
1008 if (*(b - 1) == 0xff && avio_tell(pb) < end - 1 &&
1009 b - buffer < tlen &&
1010 !pb->eof_reached ) {
1011 uint8_t val = avio_r8(pb);
1012 *b++ = val ? val : avio_r8(pb);
1013 }
1014 }
1015 ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL,
1016 NULL);
1017 tlen = b - buffer;
1018 pbx = &pb_local; // read from sync buffer
1019 }
1020
1021#if CONFIG_ZLIB
1022 if (tcomp) {
1023 int err;
1024
1025 av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);
1026
1027 av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);
1028 if (!uncompressed_buffer) {
1029 av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);
1030 goto seek;
1031 }
1032
1033 if (!(unsync || tunsync)) {
1034 err = avio_read(pb, buffer, tlen);
1035 if (err < 0) {
1036 av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");
1037 goto seek;
1038 }
1039 tlen = err;
1040 }
1041
1042 err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);
1043 if (err != Z_OK) {
1044 av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);
1045 goto seek;
1046 }
1047 ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL);
1048 tlen = dlen;
1049 pbx = &pb_local; // read from sync buffer
1050 }
1051#endif
1052 if (tag[0] == 'T')
1053 /* parse text tag */
1054 read_ttag(s, pbx, tlen, metadata, tag);
1055 else if (!memcmp(tag, "USLT", 4))
1056 read_uslt(s, pbx, tlen, metadata);
1057 else if (!strcmp(tag, comm_frame))
1058 read_comment(s, pbx, tlen, metadata);
1059 else
1060 /* parse special meta tag */
1061 extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
1062 } else if (!tag[0]) {
1063 if (tag[1])
1064 av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
1065 avio_skip(pb, tlen);
1066 break;
1067 }
1068 /* Skip to end of tag */
1069seek:
1070 avio_seek(pb, next, SEEK_SET);
1071 }
1072
1073 /* Footer preset, always 10 bytes, skip over it */
1074 if (version == 4 && flags & 0x10)
1075 end += 10;
1076
1077error:
1078 if (reason)
1079 av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
1080 version, reason);
1081 avio_seek(pb, end, SEEK_SET);
1082 av_free(buffer);
1083 av_free(uncompressed_buffer);
1084 return;
1085}
1086
1087static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
1088 AVFormatContext *s, const char *magic,
1089 ID3v2ExtraMeta **extra_meta, int64_t max_search_size)
1090{
1091 int len, ret;
1092 uint8_t buf[ID3v2_HEADER_SIZE];
1093 int found_header;
1094 int64_t start, off;
1095
1096 if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
1097 return;
1098
1099 start = avio_tell(pb);
1100 do {
1101 /* save the current offset in case there's nothing to read/skip */
1102 off = avio_tell(pb);
1103 if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) {
1104 avio_seek(pb, off, SEEK_SET);
1105 break;
1106 }
1107
1108 ret = avio_read(pb, buf, ID3v2_HEADER_SIZE);
1109 if (ret != ID3v2_HEADER_SIZE) {
1110 avio_seek(pb, off, SEEK_SET);
1111 break;
1112 }
1113 found_header = ff_id3v2_match(buf, magic);
1114 if (found_header) {
1115 /* parse ID3v2 header */
1116 len = ((buf[6] & 0x7f) << 21) |
1117 ((buf[7] & 0x7f) << 14) |
1118 ((buf[8] & 0x7f) << 7) |
1119 (buf[9] & 0x7f);
1120 id3v2_parse(pb, metadata, s, len, buf[3], buf[5], extra_meta);
1121 } else {
1122 avio_seek(pb, off, SEEK_SET);
1123 }
1124 } while (found_header);
1125 ff_metadata_conv(metadata, NULL, ff_id3v2_34_metadata_conv);
1126 ff_metadata_conv(metadata, NULL, id3v2_2_metadata_conv);
1127 ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv);
1128 merge_date(metadata);
1129}
1130
1131void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata,
1132 const char *magic, ID3v2ExtraMeta **extra_meta)
1133{
1134 id3v2_read_internal(pb, metadata, NULL, magic, extra_meta, 0);
1135}
1136
1137void ff_id3v2_read(AVFormatContext *s, const char *magic,
1138 ID3v2ExtraMeta **extra_meta, unsigned int max_search_size)
1139{
1140 id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta, max_search_size);
1141}
1142
1143void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
1144{
1145 ID3v2ExtraMeta *current = *extra_meta, *next;
1146 const ID3v2EMFunc *extra_func;
1147
1148 while (current) {
1149 if ((extra_func = get_extra_meta_func(current->tag, 1)))
1150 extra_func->free(current->data);
1151 next = current->next;
1152 av_freep(&current);
1153 current = next;
1154 }
1155
1156 *extra_meta = NULL;
1157}
1158
1159int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
1160{
1161 ID3v2ExtraMeta *cur;
1162
1163 for (cur = *extra_meta; cur; cur = cur->next) {
1164 ID3v2ExtraMetaAPIC *apic;
1165 AVStream *st;
1166
1167 if (strcmp(cur->tag, "APIC"))
1168 continue;
1169 apic = cur->data;
1170
1171 if (!(st = avformat_new_stream(s, NULL)))
1172 return AVERROR(ENOMEM);
1173
1174 st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
1175 st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
1176 st->codecpar->codec_id = apic->id;
1177
1178 if (AV_RB64(apic->buf->data) == 0x89504e470d0a1a0a)
1179 st->codecpar->codec_id = AV_CODEC_ID_PNG;
1180
1181 if (apic->description[0])
1182 av_dict_set(&st->metadata, "title", apic->description, 0);
1183
1184 av_dict_set(&st->metadata, "comment", apic->type, 0);
1185
1186 av_init_packet(&st->attached_pic);
1187 st->attached_pic.buf = apic->buf;
1188 st->attached_pic.data = apic->buf->data;
1189 st->attached_pic.size = apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE;
1190 st->attached_pic.stream_index = st->index;
1191 st->attached_pic.flags |= AV_PKT_FLAG_KEY;
1192
1193 apic->buf = NULL;
1194 }
1195
1196 return 0;
1197}
1198