FFmpeg
id3v1.c
Go to the documentation of this file.
1 /*
2  * ID3v1 header parser
3  * Copyright (c) 2003 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "id3v1.h"
23 #include "libavcodec/avcodec.h"
24 #include "libavutil/dict.h"
25 
26 /* See Genre List at http://id3.org/id3v2.3.0 */
27 const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
28  [0] = "Blues",
29  [1] = "Classic Rock",
30  [2] = "Country",
31  [3] = "Dance",
32  [4] = "Disco",
33  [5] = "Funk",
34  [6] = "Grunge",
35  [7] = "Hip-Hop",
36  [8] = "Jazz",
37  [9] = "Metal",
38  [10] = "New Age",
39  [11] = "Oldies",
40  [12] = "Other",
41  [13] = "Pop",
42  [14] = "R&B",
43  [15] = "Rap",
44  [16] = "Reggae",
45  [17] = "Rock",
46  [18] = "Techno",
47  [19] = "Industrial",
48  [20] = "Alternative",
49  [21] = "Ska",
50  [22] = "Death Metal",
51  [23] = "Pranks",
52  [24] = "Soundtrack",
53  [25] = "Euro-Techno",
54  [26] = "Ambient",
55  [27] = "Trip-Hop",
56  [28] = "Vocal",
57  [29] = "Jazz+Funk",
58  [30] = "Fusion",
59  [31] = "Trance",
60  [32] = "Classical",
61  [33] = "Instrumental",
62  [34] = "Acid",
63  [35] = "House",
64  [36] = "Game",
65  [37] = "Sound Clip",
66  [38] = "Gospel",
67  [39] = "Noise",
68  [40] = "AlternRock",
69  [41] = "Bass",
70  [42] = "Soul",
71  [43] = "Punk",
72  [44] = "Space",
73  [45] = "Meditative",
74  [46] = "Instrumental Pop",
75  [47] = "Instrumental Rock",
76  [48] = "Ethnic",
77  [49] = "Gothic",
78  [50] = "Darkwave",
79  [51] = "Techno-Industrial",
80  [52] = "Electronic",
81  [53] = "Pop-Folk",
82  [54] = "Eurodance",
83  [55] = "Dream",
84  [56] = "Southern Rock",
85  [57] = "Comedy",
86  [58] = "Cult",
87  [59] = "Gangsta",
88  [60] = "Top 40",
89  [61] = "Christian Rap",
90  [62] = "Pop/Funk",
91  [63] = "Jungle",
92  [64] = "Native American",
93  [65] = "Cabaret",
94  [66] = "New Wave",
95  [67] = "Psychadelic", /* sic, the misspelling is used in the specification */
96  [68] = "Rave",
97  [69] = "Showtunes",
98  [70] = "Trailer",
99  [71] = "Lo-Fi",
100  [72] = "Tribal",
101  [73] = "Acid Punk",
102  [74] = "Acid Jazz",
103  [75] = "Polka",
104  [76] = "Retro",
105  [77] = "Musical",
106  [78] = "Rock & Roll",
107  [79] = "Hard Rock",
108  [80] = "Folk",
109  [81] = "Folk-Rock",
110  [82] = "National Folk",
111  [83] = "Swing",
112  [84] = "Fast Fusion",
113  [85] = "Bebob",
114  [86] = "Latin",
115  [87] = "Revival",
116  [88] = "Celtic",
117  [89] = "Bluegrass",
118  [90] = "Avantgarde",
119  [91] = "Gothic Rock",
120  [92] = "Progressive Rock",
121  [93] = "Psychedelic Rock",
122  [94] = "Symphonic Rock",
123  [95] = "Slow Rock",
124  [96] = "Big Band",
125  [97] = "Chorus",
126  [98] = "Easy Listening",
127  [99] = "Acoustic",
128  [100] = "Humour",
129  [101] = "Speech",
130  [102] = "Chanson",
131  [103] = "Opera",
132  [104] = "Chamber Music",
133  [105] = "Sonata",
134  [106] = "Symphony",
135  [107] = "Booty Bass",
136  [108] = "Primus",
137  [109] = "Porn Groove",
138  [110] = "Satire",
139  [111] = "Slow Jam",
140  [112] = "Club",
141  [113] = "Tango",
142  [114] = "Samba",
143  [115] = "Folklore",
144  [116] = "Ballad",
145  [117] = "Power Ballad",
146  [118] = "Rhythmic Soul",
147  [119] = "Freestyle",
148  [120] = "Duet",
149  [121] = "Punk Rock",
150  [122] = "Drum Solo",
151  [123] = "A capella",
152  [124] = "Euro-House",
153  [125] = "Dance Hall",
154  [126] = "Goa",
155  [127] = "Drum & Bass",
156  [128] = "Club-House",
157  [129] = "Hardcore",
158  [130] = "Terror",
159  [131] = "Indie",
160  [132] = "BritPop",
161  [133] = "Negerpunk",
162  [134] = "Polsk Punk",
163  [135] = "Beat",
164  [136] = "Christian Gangsta",
165  [137] = "Heavy Metal",
166  [138] = "Black Metal",
167  [139] = "Crossover",
168  [140] = "Contemporary Christian",
169  [141] = "Christian Rock",
170  [142] = "Merengue",
171  [143] = "Salsa",
172  [144] = "Thrash Metal",
173  [145] = "Anime",
174  [146] = "JPop",
175  [147] = "SynthPop",
176 };
177 
178 static void get_string(AVFormatContext *s, const char *key,
179  const uint8_t *buf, int buf_size)
180 {
181  int i, c;
182  char *q, str[512], *first_free_space = NULL;
183 
184  q = str;
185  for(i = 0; i < buf_size; i++) {
186  c = buf[i];
187  if (c == '\0')
188  break;
189  if ((q - str) >= sizeof(str) - 1)
190  break;
191  if (c == ' ') {
192  if (!first_free_space)
193  first_free_space = q;
194  } else {
195  first_free_space = NULL;
196  }
197  *q++ = c;
198  }
199  *q = '\0';
200 
201  if (first_free_space)
202  *first_free_space = '\0';
203 
204  if (*str)
205  av_dict_set(&s->metadata, key, str, 0);
206 }
207 
208 /**
209  * Parse an ID3v1 tag
210  *
211  * @param buf ID3v1_TAG_SIZE long buffer containing the tag
212  */
213 static int parse_tag(AVFormatContext *s, const uint8_t *buf)
214 {
215  int genre;
216 
217  if (!(buf[0] == 'T' &&
218  buf[1] == 'A' &&
219  buf[2] == 'G'))
220  return -1;
221  get_string(s, "title", buf + 3, 30);
222  get_string(s, "artist", buf + 33, 30);
223  get_string(s, "album", buf + 63, 30);
224  get_string(s, "date", buf + 93, 4);
225  get_string(s, "comment", buf + 97, 30);
226  if (buf[125] == 0 && buf[126] != 0) {
227  av_dict_set_int(&s->metadata, "track", buf[126], 0);
228  }
229  genre = buf[127];
230  if (genre <= ID3v1_GENRE_MAX)
231  av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
232  return 0;
233 }
234 
236 {
237  int ret;
239  int64_t filesize, position = avio_tell(s->pb);
240 
241  if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
242  /* XXX: change that */
243  filesize = avio_size(s->pb);
244  if (filesize > 128) {
245  avio_seek(s->pb, filesize - 128, SEEK_SET);
246  ret = avio_read(s->pb, buf, ID3v1_TAG_SIZE);
247  if (ret == ID3v1_TAG_SIZE) {
248  parse_tag(s, buf);
249  }
250  avio_seek(s->pb, position, SEEK_SET);
251  }
252  }
253 }
#define NULL
Definition: coverity.c:32
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:336
void ff_id3v1_read(AVFormatContext *s)
Read an ID3v1 tag.
Definition: id3v1.c:235
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
const char * key
Format I/O context.
Definition: avformat.h:1358
Public dictionary API.
uint8_t
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:647
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVDictionary * metadata
Metadata that applies to the whole file.
Definition: avformat.h:1598
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
#define s(width, name)
Definition: cbs_vp9.c:257
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
static void get_string(AVFormatContext *s, const char *key, const uint8_t *buf, int buf_size)
Definition: id3v1.c:178
Libavcodec external API header.
AVIOContext * pb
I/O context.
Definition: avformat.h:1400
void * buf
Definition: avisynth_c.h:766
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
static int parse_tag(AVFormatContext *s, const uint8_t *buf)
Parse an ID3v1 tag.
Definition: id3v1.c:213
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set that converts the value to a string and stores it...
Definition: dict.c:147
#define ID3v1_TAG_SIZE
Definition: id3v1.h:27
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:27