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
42
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 { 0 }
59 };
60
62 { "TDRL", "date" },
63 { "TDRC", "date" },
64 { "TDEN", "creation_time" },
65 { "TSOA", "album-sort" },
66 { "TSOP", "artist-sort" },
67 { "TSOT", "title-sort" },
68 { 0 }
69 };
70
72 { "TAL", "album" },
73 { "TCO", "genre" },
74 { "TT2", "title" },
75 { "TEN", "encoded_by" },
76 { "TP1", "artist" },
77 { "TP2", "album_artist" },
78 { "TP3", "performer" },
79 { "TRK", "track" },
80 { 0 }
81 };
82
84 "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
85 "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
86 "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
87 "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
88 { 0 },
89 };
90
92 "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
93 "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
94 { 0 },
95 };
96
98 "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
99 { 0 },
100 };
101
103 "Other",
104 "32x32 pixels 'file icon'",
105 "Other file icon",
106 "Cover (front)",
107 "Cover (back)",
108 "Leaflet page",
109 "Media (e.g. label side of CD)",
110 "Lead artist/lead performer/soloist",
111 "Artist/performer",
112 "Conductor",
113 "Band/Orchestra",
114 "Composer",
115 "Lyricist/text writer",
116 "Recording Location",
117 "During recording",
118 "During performance",
119 "Movie/video screen capture",
120 "A bright coloured fish",
121 "Illustration",
122 "Band/artist logotype",
123 "Publisher/Studio logotype",
124 };
125
136 };
137
139 {
140 return buf[0] == magic[0] &&
141 buf[1] == magic[1] &&
142 buf[2] == magic[2] &&
143 buf[3] != 0xff &&
144 buf[4] != 0xff &&
145 (buf[6] & 0x80) == 0 &&
146 (buf[7] & 0x80) == 0 &&
147 (buf[8] & 0x80) == 0 &&
148 (buf[9] & 0x80) == 0;
149 }
150
152 {
153 int len = ((buf[6] & 0x7f) << 21) +
154 ((buf[7] & 0x7f) << 14) +
155 ((buf[8] & 0x7f) << 7) +
156 (buf[9] & 0x7f) +
158 if (buf[5] & 0x10)
161 }
162
164 {
166 while (len--)
167 v = (v << 7) + (
avio_r8(s) & 0x7F);
169 }
170
171 /**
172 * Free GEOB type extra metadata.
173 */
175 {
182 }
183
184 /**
185 * Decode characters to UTF-8 according to encoding type. The decoded buffer is
186 * always null terminated. Stop reading when either *maxread bytes are read from
187 * pb or U+0000 character is found.
188 *
189 * @param dst Pointer where the address of the buffer with the decoded bytes is
190 * stored. Buffer must be freed by caller.
191 * @param maxread Pointer to maximum number of characters to read from the
192 * AVIOContext. After execution the value is decremented by the number of bytes
193 * actually read.
194 * @returns 0 if no error occurred, dst is uninitialized on error
195 */
198 {
201 uint32_t ch = 1;
202 int left = *maxread;
205
209 }
210
211 switch (encoding) {
213 while (left && ch) {
216 left--;
217 }
218 break;
219
221 if ((left -= 2) < 0) {
226 }
228 case 0xfffe:
230 case 0xfeff:
231 break;
232 default:
236 *maxread = left;
238 }
239 // fall-through
240
242 while ((left > 1) && ch) {
243 GET_UTF16(ch, ((left -= 2) >= 0 ?
get(pb) : 0),
break;)
245 }
246 if (left < 0)
247 left += 2; /* did not read last char from pb */
248 break;
249
251 while (left && ch) {
254 left--;
255 }
256 break;
257 default:
259 }
260
261 if (ch)
263
265 *maxread = left;
266
267 return 0;
268 }
269
270 /**
271 * Parse a text tag.
272 */
275 {
278 unsigned genre;
279
280 if (taglen < 1)
281 return;
282
284 taglen--; /* account for encoding type byte */
285
286 if (
decode_str(s, pb, encoding, &dst, &taglen) < 0) {
288 return;
289 }
290
291 if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) &&
292 (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
296 } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
297 /* dst now contains the key, need to get value */
298 key = dst;
299 if (
decode_str(s, pb, encoding, &dst, &taglen) < 0) {
302 return;
303 }
305 } else if (!*dst)
307
308 if (dst)
310 }
311
312 /**
313 * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
314 */
317 {
320 char encoding;
322
323 if (taglen < 1)
324 return;
325
327 if (!geob_data) {
330 return;
331 }
332
334 if (!new_extra) {
337 goto fail;
338 }
339
340 /* read encoding type byte */
342 taglen--;
343
344 /* read MIME type (always ISO-8859) */
346 &taglen) < 0 ||
347 taglen <= 0)
348 goto fail;
349
350 /* read file name */
352 taglen <= 0)
353 goto fail;
354
355 /* read content description */
357 taglen < 0)
358 goto fail;
359
360 if (taglen) {
361 /* save encapsulated binary data */
363 if (!geob_data->
data) {
365 goto fail;
366 }
369 "Error reading GEOB frame, data truncated.\n");
371 } else {
372 geob_data->
data = NULL;
374 }
375
376 /* add data to the list */
377 new_extra->
tag =
"GEOB";
378 new_extra->
data = geob_data;
379 new_extra->
next = *extra_meta;
380 *extra_meta = new_extra;
381
382 return;
383
384 fail:
388 return;
389 }
390
392 {
393 while (*str >= '0' && *str <= '9')
394 str++;
395 return !*str;
396 }
397
399 {
404 return NULL;
405 }
406
408 {
410 char date[17] = { 0 }; // YYYY-MM-DD hh:mm
411
414 return;
418
425
429 snprintf(date + 10,
sizeof(date) - 10,
433
435 if (date[0])
437 }
438
440 {
445 }
446
449 {
450 int enc, pic_type;
451 char mimetype[64];
457
458 if (taglen <= 4)
459 goto fail;
460
463 if (!new_extra || !apic)
464 goto fail;
465
467 taglen--;
468
469 /* mimetype */
470 taglen -=
avio_get_str(pb, taglen, mimetype,
sizeof(mimetype));
474 break;
475 }
476 mime++;
477 }
480 "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
481 goto fail;
482 }
484
485 /* picture type */
487 taglen--;
490 pic_type);
491 pic_type = 0;
492 }
494
495 /* description and picture data */
498 "Error decoding attached picture description.\n");
499 goto fail;
500 }
501
504 goto fail;
506
507 new_extra->
tag =
"APIC";
508 new_extra->
data = apic;
509 new_extra->
next = *extra_meta;
510 *extra_meta = new_extra;
511
512 return;
513
514 fail:
515 if (apic)
519 }
520
522 {
527 int taglen;
529
531 return;
532 if (len < 16)
533 return;
534
538
540 if (!chapter) {
542 return;
543 }
544
545 len -= 16;
546 while (len > 10) {
548 tag[4] = 0;
551 len -= 10;
552 if (taglen < 0 || taglen > len) {
554 return;
555 }
556 if (tag[0] == 'T')
558 else
560 len -= taglen;
561 }
562
566 }
567
575
580 { NULL }
581 };
582
583 /**
584 * Get the corresponding ID3v2EMFunc struct for a tag.
585 * @param isv34 Determines if v2.2 or v2.3/4 strings are used
586 * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
587 */
589 {
590 int i = 0;
591 while (id3v2_extra_meta_funcs[i].tag3) {
592 if (tag && !memcmp(tag,
593 (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
594 id3v2_extra_meta_funcs[i].tag3),
595 (isv34 ? 4 : 3)))
596 return &id3v2_extra_meta_funcs[i];
597 i++;
598 }
599 return NULL;
600 }
601
604 {
605 int isv34, unsync;
606 unsigned tlen;
609 int taghdrlen;
610 const char *reason = NULL;
613 unsigned char *
buffer = NULL;
614 int buffer_size = 0;
616 unsigned char *uncompressed_buffer = NULL;
617 int uncompressed_buffer_size = 0;
618
620
621 switch (version) {
622 case 2:
623 if (flags & 0x40) {
624 reason = "compression";
625 goto error;
626 }
627 isv34 = 0;
628 taghdrlen = 6;
629 break;
630
631 case 3:
632 case 4:
633 isv34 = 1;
634 taghdrlen = 10;
635 break;
636
637 default:
638 reason = "version";
639 goto error;
640 }
641
642 unsync = flags & 0x80;
643
644 if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
646 if (version == 4)
647 /* In v2.4 the length includes the length field we just read. */
648 extlen -= 4;
649
650 if (extlen < 0) {
651 reason = "invalid extended header length";
652 goto error;
653 }
655 len -= extlen + 4;
656 if (len < 0) {
657 reason = "extended header too long.";
658 goto error;
659 }
660 }
661
662 while (len >= taghdrlen) {
663 unsigned int tflags = 0;
664 int tunsync = 0;
665 int tcomp = 0;
666 int tencr = 0;
667 unsigned long dlen;
668
669 if (isv34) {
671 tag[4] = 0;
672 if (version == 3) {
674 } else
678 } else {
680 tag[3] = 0;
682 }
683 if (tlen > (1<<28))
684 break;
685 len -= taghdrlen + tlen;
686
687 if (len < 0)
688 break;
689
691
692 if (!tlen) {
693 if (tag[0])
695 tag);
696 continue;
697 }
698
700 if (tlen < 4)
701 break;
703 tlen -= 4;
704 } else
705 dlen = tlen;
706
709
710 /* skip encrypted tags and, if no zlib, compressed tags */
711 if (tencr || (!CONFIG_ZLIB && tcomp)) {
713 if (!tcomp)
714 type = "encrypted";
715 else if (!tencr)
716 type = "compressed";
717 else
718 type = "encrypted and compressed";
719
722 /* check for text tag or supported special meta tag */
723 } else if (tag[0] == 'T' ||
724 (extra_meta &&
727
728 if (unsync || tunsync || tcomp) {
730 if (!buffer) {
732 goto seek;
733 }
734 }
735 if (unsync || tunsync) {
738
742 if (*(b - 1) == 0xff &&
avio_tell(s->
pb) < end - 1 &&
743 b - buffer < tlen &&
747 }
748 }
750 NULL);
752 pbx = &pb; // read from sync buffer
753 }
754
755 #if CONFIG_ZLIB
756 if (tcomp) {
757 int err;
758
760
761 av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);
762 if (!uncompressed_buffer) {
764 goto seek;
765 }
766
767 if (!(unsync || tunsync)) {
769 if (err < 0) {
771 goto seek;
772 }
773 tlen = err;
774 }
775
776 err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);
777 if (err != Z_OK) {
779 goto seek;
780 }
782 tlen = dlen;
783 pbx = &pb; // read from sync buffer
784 }
785 #endif
786 if (tag[0] == 'T')
787 /* parse text tag */
789 else
790 /* parse special meta tag */
791 extra_func->
read(s, pbx, tlen, tag, extra_meta);
792 } else if (!tag[0]) {
793 if (tag[1])
796 break;
797 }
798 /* Skip to end of tag */
799 seek:
801 }
802
803 /* Footer preset, always 10 bytes, skip over it */
804 if (version == 4 && flags & 0x10)
805 end += 10;
806
807 error:
808 if (reason)
810 version, reason);
814 return;
815 }
816
819 {
822 int found_header;
824
825 do {
826 /* save the current offset in case there's nothing to read/skip */
831 break;
832 }
834 if (found_header) {
835 /* parse ID3v2 header */
836 len = ((buf[6] & 0x7f) << 21) |
837 ((buf[7] & 0x7f) << 14) |
838 ((buf[8] & 0x7f) << 7) |
839 (buf[9] & 0x7f);
841 } else {
843 }
844 } while (found_header);
849 }
850
852 {
855
856 while (current) {
859 next = current->
next;
861 current = next;
862 }
863 }
864
866 {
868
869 for (cur = *extra_meta; cur; cur = cur->
next) {
872
873 if (strcmp(cur->
tag,
"APIC"))
874 continue;
876
879
885
892
894 }
895
896 return 0;
897 }