Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
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
 
43
const 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
    { 0 }
59
};
60
 
61
const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
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
 
71
static const AVMetadataConv id3v2_2_metadata_conv[] = {
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
 
83
const char ff_id3v2_tags[][4] = {
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
 
91
const char ff_id3v2_4_tags[][4] = {
92
    "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
93
    "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
94
    { 0 },
95
};
96
 
97
const char ff_id3v2_3_tags[][4] = {
98
    "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
99
    { 0 },
100
};
101
 
102
const char *ff_id3v2_picture_types[21] = {
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
 
126
const CodecMime ff_id3v2_mime_tags[] = {
127
    { "image/gif",  AV_CODEC_ID_GIF   },
128
    { "image/jpeg", AV_CODEC_ID_MJPEG },
129
    { "image/jpg",  AV_CODEC_ID_MJPEG },
130
    { "image/png",  AV_CODEC_ID_PNG   },
131
    { "image/tiff", AV_CODEC_ID_TIFF  },
132
    { "image/bmp",  AV_CODEC_ID_BMP   },
133
    { "JPG",        AV_CODEC_ID_MJPEG }, /* ID3v2.2  */
134
    { "PNG",        AV_CODEC_ID_PNG   }, /* ID3v2.2  */
135
    { "",           AV_CODEC_ID_NONE  },
136
};
137
 
138
int ff_id3v2_match(const uint8_t *buf, const char *magic)
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
 
151
int ff_id3v2_tag_len(const uint8_t *buf)
152
{
153
    int len = ((buf[6] & 0x7f) << 21) +
154
              ((buf[7] & 0x7f) << 14) +
155
              ((buf[8] & 0x7f) << 7) +
156
              (buf[9] & 0x7f) +
157
              ID3v2_HEADER_SIZE;
158
    if (buf[5] & 0x10)
159
        len += ID3v2_HEADER_SIZE;
160
    return len;
161
}
162
 
163
static unsigned int get_size(AVIOContext *s, int len)
164
{
165
    int v = 0;
166
    while (len--)
167
        v = (v << 7) + (avio_r8(s) & 0x7F);
168
    return v;
169
}
170
 
171
/**
172
 * Free GEOB type extra metadata.
173
 */
174
static void free_geobtag(void *obj)
175
{
176
    ID3v2ExtraMetaGEOB *geob = obj;
177
    av_free(geob->mime_type);
178
    av_free(geob->file_name);
179
    av_free(geob->description);
180
    av_free(geob->data);
181
    av_free(geob);
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
 */
196
static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
197
                      uint8_t **dst, int *maxread)
198
{
199
    int ret;
200
    uint8_t tmp;
201
    uint32_t ch = 1;
202
    int left = *maxread;
203
    unsigned int (*get)(AVIOContext*) = avio_rb16;
204
    AVIOContext *dynbuf;
205
 
206
    if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
207
        av_log(s, AV_LOG_ERROR, "Error opening memory stream\n");
208
        return ret;
209
    }
210
 
211
    switch (encoding) {
212
    case ID3v2_ENCODING_ISO8859:
213
        while (left && ch) {
214
            ch = avio_r8(pb);
215
            PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
216
            left--;
217
        }
218
        break;
219
 
220
    case ID3v2_ENCODING_UTF16BOM:
221
        if ((left -= 2) < 0) {
222
            av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n");
223
            avio_close_dyn_buf(dynbuf, dst);
224
            av_freep(dst);
225
            return AVERROR_INVALIDDATA;
226
        }
227
        switch (avio_rb16(pb)) {
228
        case 0xfffe:
229
            get = avio_rl16;
230
        case 0xfeff:
231
            break;
232
        default:
233
            av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n");
234
            avio_close_dyn_buf(dynbuf, dst);
235
            av_freep(dst);
236
            *maxread = left;
237
            return AVERROR_INVALIDDATA;
238
        }
239
        // fall-through
240
 
241
    case ID3v2_ENCODING_UTF16BE:
242
        while ((left > 1) && ch) {
243
            GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;)
244
            PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
245
        }
246
        if (left < 0)
247
            left += 2;  /* did not read last char from pb */
248
        break;
249
 
250
    case ID3v2_ENCODING_UTF8:
251
        while (left && ch) {
252
            ch = avio_r8(pb);
253
            avio_w8(dynbuf, ch);
254
            left--;
255
        }
256
        break;
257
    default:
258
        av_log(s, AV_LOG_WARNING, "Unknown encoding\n");
259
    }
260
 
261
    if (ch)
262
        avio_w8(dynbuf, 0);
263
 
264
    avio_close_dyn_buf(dynbuf, dst);
265
    *maxread = left;
266
 
267
    return 0;
268
}
269
 
270
/**
271
 * Parse a text tag.
272
 */
273
static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
274
                      AVDictionary **metadata, const char *key)
275
{
276
    uint8_t *dst;
277
    int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
278
    unsigned genre;
279
 
280
    if (taglen < 1)
281
        return;
282
 
283
    encoding = avio_r8(pb);
284
    taglen--; /* account for encoding type byte */
285
 
286
    if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
287
        av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
288
        return;
289
    }
290
 
291
    if (!(strcmp(key, "TCON") && strcmp(key, "TCO"))                         &&
292
        (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
293
        genre <= ID3v1_GENRE_MAX) {
294
        av_freep(&dst);
295
        dst = av_strdup(ff_id3v1_genre_str[genre]);
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) {
300
            av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
301
            av_freep(&key);
302
            return;
303
        }
304
        dict_flags |= AV_DICT_DONT_STRDUP_KEY;
305
    } else if (!*dst)
306
        av_freep(&dst);
307
 
308
    if (dst)
309
        av_dict_set(metadata, key, dst, dict_flags);
310
}
311
 
312
/**
313
 * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
314
 */
315
static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
316
                         char *tag, ID3v2ExtraMeta **extra_meta)
317
{
318
    ID3v2ExtraMetaGEOB *geob_data = NULL;
319
    ID3v2ExtraMeta *new_extra     = NULL;
320
    char encoding;
321
    unsigned int len;
322
 
323
    if (taglen < 1)
324
        return;
325
 
326
    geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
327
    if (!geob_data) {
328
        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
329
               sizeof(ID3v2ExtraMetaGEOB));
330
        return;
331
    }
332
 
333
    new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
334
    if (!new_extra) {
335
        av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n",
336
               sizeof(ID3v2ExtraMeta));
337
        goto fail;
338
    }
339
 
340
    /* read encoding type byte */
341
    encoding = avio_r8(pb);
342
    taglen--;
343
 
344
    /* read MIME type (always ISO-8859) */
345
    if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
346
                   &taglen) < 0 ||
347
        taglen <= 0)
348
        goto fail;
349
 
350
    /* read file name */
351
    if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
352
        taglen <= 0)
353
        goto fail;
354
 
355
    /* read content description */
356
    if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
357
        taglen < 0)
358
        goto fail;
359
 
360
    if (taglen) {
361
        /* save encapsulated binary data */
362
        geob_data->data = av_malloc(taglen);
363
        if (!geob_data->data) {
364
            av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
365
            goto fail;
366
        }
367
        if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
368
            av_log(s, AV_LOG_WARNING,
369
                   "Error reading GEOB frame, data truncated.\n");
370
        geob_data->datasize = len;
371
    } else {
372
        geob_data->data     = NULL;
373
        geob_data->datasize = 0;
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:
385
    av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
386
    free_geobtag(geob_data);
387
    av_free(new_extra);
388
    return;
389
}
390
 
391
static int is_number(const char *str)
392
{
393
    while (*str >= '0' && *str <= '9')
394
        str++;
395
    return !*str;
396
}
397
 
398
static AVDictionaryEntry *get_date_tag(AVDictionary *m, const char *tag)
399
{
400
    AVDictionaryEntry *t;
401
    if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
402
        strlen(t->value) == 4 && is_number(t->value))
403
        return t;
404
    return NULL;
405
}
406
 
407
static void merge_date(AVDictionary **m)
408
{
409
    AVDictionaryEntry *t;
410
    char date[17] = { 0 };      // YYYY-MM-DD hh:mm
411
 
412
    if (!(t = get_date_tag(*m, "TYER")) &&
413
        !(t = get_date_tag(*m, "TYE")))
414
        return;
415
    av_strlcpy(date, t->value, 5);
416
    av_dict_set(m, "TYER", NULL, 0);
417
    av_dict_set(m, "TYE", NULL, 0);
418
 
419
    if (!(t = get_date_tag(*m, "TDAT")) &&
420
        !(t = get_date_tag(*m, "TDA")))
421
        goto finish;
422
    snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
423
    av_dict_set(m, "TDAT", NULL, 0);
424
    av_dict_set(m, "TDA", NULL, 0);
425
 
426
    if (!(t = get_date_tag(*m, "TIME")) &&
427
        !(t = get_date_tag(*m, "TIM")))
428
        goto finish;
429
    snprintf(date + 10, sizeof(date) - 10,
430
             " %.2s:%.2s", t->value, t->value + 2);
431
    av_dict_set(m, "TIME", NULL, 0);
432
    av_dict_set(m, "TIM", NULL, 0);
433
 
434
finish:
435
    if (date[0])
436
        av_dict_set(m, "date", date, 0);
437
}
438
 
439
static void free_apic(void *obj)
440
{
441
    ID3v2ExtraMetaAPIC *apic = obj;
442
    av_buffer_unref(&apic->buf);
443
    av_freep(&apic->description);
444
    av_freep(&apic);
445
}
446
 
447
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
448
                      char *tag, ID3v2ExtraMeta **extra_meta)
449
{
450
    int enc, pic_type;
451
    char mimetype[64];
452
    const CodecMime *mime     = ff_id3v2_mime_tags;
453
    enum AVCodecID id         = AV_CODEC_ID_NONE;
454
    ID3v2ExtraMetaAPIC *apic  = NULL;
455
    ID3v2ExtraMeta *new_extra = NULL;
456
    int64_t end               = avio_tell(pb) + taglen;
457
 
458
    if (taglen <= 4)
459
        goto fail;
460
 
461
    new_extra = av_mallocz(sizeof(*new_extra));
462
    apic      = av_mallocz(sizeof(*apic));
463
    if (!new_extra || !apic)
464
        goto fail;
465
 
466
    enc = avio_r8(pb);
467
    taglen--;
468
 
469
    /* mimetype */
470
    taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype));
471
    while (mime->id != AV_CODEC_ID_NONE) {
472
        if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) {
473
            id = mime->id;
474
            break;
475
        }
476
        mime++;
477
    }
478
    if (id == AV_CODEC_ID_NONE) {
479
        av_log(s, AV_LOG_WARNING,
480
               "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
481
        goto fail;
482
    }
483
    apic->id = id;
484
 
485
    /* picture type */
486
    pic_type = avio_r8(pb);
487
    taglen--;
488
    if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
489
        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
490
               pic_type);
491
        pic_type = 0;
492
    }
493
    apic->type = ff_id3v2_picture_types[pic_type];
494
 
495
    /* description and picture data */
496
    if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
497
        av_log(s, AV_LOG_ERROR,
498
               "Error decoding attached picture description.\n");
499
        goto fail;
500
    }
501
 
502
    apic->buf = av_buffer_alloc(taglen + FF_INPUT_BUFFER_PADDING_SIZE);
503
    if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)
504
        goto fail;
505
    memset(apic->buf->data + taglen, 0, FF_INPUT_BUFFER_PADDING_SIZE);
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)
516
        free_apic(apic);
517
    av_freep(&new_extra);
518
    avio_seek(pb, end, SEEK_SET);
519
}
520
 
521
static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta)
522
{
523
    AVRational time_base = {1, 1000};
524
    uint32_t start, end;
525
    AVChapter *chapter;
526
    uint8_t *dst = NULL;
527
    int taglen;
528
    char tag[5];
529
 
530
    if (decode_str(s, pb, 0, &dst, &len) < 0)
531
        return;
532
    if (len < 16)
533
        return;
534
 
535
    start = avio_rb32(pb);
536
    end   = avio_rb32(pb);
537
    avio_skip(pb, 8);
538
 
539
    chapter = avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, dst);
540
    if (!chapter) {
541
        av_free(dst);
542
        return;
543
    }
544
 
545
    len -= 16;
546
    while (len > 10) {
547
        avio_read(pb, tag, 4);
548
        tag[4] = 0;
549
        taglen = avio_rb32(pb);
550
        avio_skip(pb, 2);
551
        len -= 10;
552
        if (taglen < 0 || taglen > len) {
553
            av_free(dst);
554
            return;
555
        }
556
        if (tag[0] == 'T')
557
            read_ttag(s, pb, taglen, &chapter->metadata, tag);
558
        else
559
            avio_skip(pb, taglen);
560
        len -= taglen;
561
    }
562
 
563
    ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv);
564
    ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv);
565
    av_free(dst);
566
}
567
 
568
typedef struct ID3v2EMFunc {
569
    const char *tag3;
570
    const char *tag4;
571
    void (*read)(AVFormatContext *, AVIOContext *, int, char *,
572
                 ID3v2ExtraMeta **);
573
    void (*free)(void *obj);
574
} ID3v2EMFunc;
575
 
576
static const ID3v2EMFunc id3v2_extra_meta_funcs[] = {
577
    { "GEO", "GEOB", read_geobtag, free_geobtag },
578
    { "PIC", "APIC", read_apic,    free_apic    },
579
    { "CHAP","CHAP", read_chapter, NULL         },
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
 */
588
static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
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
 
602
static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,
603
                        uint8_t flags, ID3v2ExtraMeta **extra_meta)
604
{
605
    int isv34, unsync;
606
    unsigned tlen;
607
    char tag[5];
608
    int64_t next, end = avio_tell(s->pb) + len;
609
    int taghdrlen;
610
    const char *reason = NULL;
611
    AVIOContext pb;
612
    AVIOContext *pbx;
613
    unsigned char *buffer = NULL;
614
    int buffer_size       = 0;
615
    const ID3v2EMFunc *extra_func = NULL;
616
    unsigned char *uncompressed_buffer = NULL;
617
    int uncompressed_buffer_size = 0;
618
 
619
    av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len);
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 */
645
        int extlen = get_size(s->pb, 4);
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
        }
654
        avio_skip(s->pb, extlen);
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) {
670
            avio_read(s->pb, tag, 4);
671
            tag[4] = 0;
672
            if (version == 3) {
673
                tlen = avio_rb32(s->pb);
674
            } else
675
                tlen = get_size(s->pb, 4);
676
            tflags  = avio_rb16(s->pb);
677
            tunsync = tflags & ID3v2_FLAG_UNSYNCH;
678
        } else {
679
            avio_read(s->pb, tag, 3);
680
            tag[3] = 0;
681
            tlen   = avio_rb24(s->pb);
682
        }
683
        if (tlen > (1<<28))
684
            break;
685
        len -= taghdrlen + tlen;
686
 
687
        if (len < 0)
688
            break;
689
 
690
        next = avio_tell(s->pb) + tlen;
691
 
692
        if (!tlen) {
693
            if (tag[0])
694
                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
695
                       tag);
696
            continue;
697
        }
698
 
699
        if (tflags & ID3v2_FLAG_DATALEN) {
700
            if (tlen < 4)
701
                break;
702
            dlen = avio_rb32(s->pb);
703
            tlen -= 4;
704
        } else
705
            dlen = tlen;
706
 
707
        tcomp = tflags & ID3v2_FLAG_COMPRESSION;
708
        tencr = tflags & ID3v2_FLAG_ENCRYPTION;
709
 
710
        /* skip encrypted tags and, if no zlib, compressed tags */
711
        if (tencr || (!CONFIG_ZLIB && tcomp)) {
712
            const char *type;
713
            if (!tcomp)
714
                type = "encrypted";
715
            else if (!tencr)
716
                type = "compressed";
717
            else
718
                type = "encrypted and compressed";
719
 
720
            av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
721
            avio_skip(s->pb, tlen);
722
        /* check for text tag or supported special meta tag */
723
        } else if (tag[0] == 'T' ||
724
                   (extra_meta &&
725
                    (extra_func = get_extra_meta_func(tag, isv34)))) {
726
            pbx = s->pb;
727
 
728
            if (unsync || tunsync || tcomp) {
729
                av_fast_malloc(&buffer, &buffer_size, tlen);
730
                if (!buffer) {
731
                    av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
732
                    goto seek;
733
                }
734
            }
735
            if (unsync || tunsync) {
736
                int64_t end = avio_tell(s->pb) + tlen;
737
                uint8_t *b;
738
 
739
                b = buffer;
740
                while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) {
741
                    *b++ = avio_r8(s->pb);
742
                    if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 &&
743
                        b - buffer < tlen &&
744
                        !s->pb->eof_reached ) {
745
                        uint8_t val = avio_r8(s->pb);
746
                        *b++ = val ? val : avio_r8(s->pb);
747
                    }
748
                }
749
                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL,
750
                                  NULL);
751
                tlen = b - buffer;
752
                pbx  = &pb; // read from sync buffer
753
            }
754
 
755
#if CONFIG_ZLIB
756
                if (tcomp) {
757
                    int err;
758
 
759
                    av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);
760
 
761
                    av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);
762
                    if (!uncompressed_buffer) {
763
                        av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);
764
                        goto seek;
765
                    }
766
 
767
                    if (!(unsync || tunsync)) {
768
                        err = avio_read(s->pb, buffer, tlen);
769
                        if (err < 0) {
770
                            av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");
771
                            goto seek;
772
                        }
773
                        tlen = err;
774
                    }
775
 
776
                    err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);
777
                    if (err != Z_OK) {
778
                        av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);
779
                        goto seek;
780
                    }
781
                    ffio_init_context(&pb, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL);
782
                    tlen = dlen;
783
                    pbx = &pb; // read from sync buffer
784
                }
785
#endif
786
            if (tag[0] == 'T')
787
                /* parse text tag */
788
                read_ttag(s, pbx, tlen, &s->metadata, 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])
794
                av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
795
            avio_skip(s->pb, tlen);
796
            break;
797
        }
798
        /* Skip to end of tag */
799
seek:
800
        avio_seek(s->pb, next, SEEK_SET);
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)
809
        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
810
               version, reason);
811
    avio_seek(s->pb, end, SEEK_SET);
812
    av_free(buffer);
813
    av_free(uncompressed_buffer);
814
    return;
815
}
816
 
817
void ff_id3v2_read(AVFormatContext *s, const char *magic,
818
                   ID3v2ExtraMeta **extra_meta)
819
{
820
    int len, ret;
821
    uint8_t buf[ID3v2_HEADER_SIZE];
822
    int found_header;
823
    int64_t off;
824
 
825
    do {
826
        /* save the current offset in case there's nothing to read/skip */
827
        off = avio_tell(s->pb);
828
        ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE);
829
        if (ret != ID3v2_HEADER_SIZE) {
830
            avio_seek(s->pb, off, SEEK_SET);
831
            break;
832
        }
833
        found_header = ff_id3v2_match(buf, magic);
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);
840
            id3v2_parse(s, len, buf[3], buf[5], extra_meta);
841
        } else {
842
            avio_seek(s->pb, off, SEEK_SET);
843
        }
844
    } while (found_header);
845
    ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv);
846
    ff_metadata_conv(&s->metadata, NULL, id3v2_2_metadata_conv);
847
    ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv);
848
    merge_date(&s->metadata);
849
}
850
 
851
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
852
{
853
    ID3v2ExtraMeta *current = *extra_meta, *next;
854
    const ID3v2EMFunc *extra_func;
855
 
856
    while (current) {
857
        if ((extra_func = get_extra_meta_func(current->tag, 1)))
858
            extra_func->free(current->data);
859
        next = current->next;
860
        av_freep(¤t);
861
        current = next;
862
    }
863
}
864
 
865
int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
866
{
867
    ID3v2ExtraMeta *cur;
868
 
869
    for (cur = *extra_meta; cur; cur = cur->next) {
870
        ID3v2ExtraMetaAPIC *apic;
871
        AVStream *st;
872
 
873
        if (strcmp(cur->tag, "APIC"))
874
            continue;
875
        apic = cur->data;
876
 
877
        if (!(st = avformat_new_stream(s, NULL)))
878
            return AVERROR(ENOMEM);
879
 
880
        st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;
881
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
882
        st->codec->codec_id   = apic->id;
883
        av_dict_set(&st->metadata, "title",   apic->description, 0);
884
        av_dict_set(&st->metadata, "comment", apic->type, 0);
885
 
886
        av_init_packet(&st->attached_pic);
887
        st->attached_pic.buf          = apic->buf;
888
        st->attached_pic.data         = apic->buf->data;
889
        st->attached_pic.size         = apic->buf->size - FF_INPUT_BUFFER_PADDING_SIZE;
890
        st->attached_pic.stream_index = st->index;
891
        st->attached_pic.flags       |= AV_PKT_FLAG_KEY;
892
 
893
        apic->buf = NULL;
894
    }
895
 
896
    return 0;
897
}