FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/id3v1.c
Date: 2024-04-19 17:50:32
Exec Total Coverage
Lines: 45 47 95.7%
Functions: 3 3 100.0%
Branches: 23 32 71.9%

Line Branch Exec Source
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 "libavutil/dict.h"
24
25 /* See Genre List at http://id3.org/id3v2.3.0 */
26 const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = {
27 [0] = "Blues",
28 [1] = "Classic Rock",
29 [2] = "Country",
30 [3] = "Dance",
31 [4] = "Disco",
32 [5] = "Funk",
33 [6] = "Grunge",
34 [7] = "Hip-Hop",
35 [8] = "Jazz",
36 [9] = "Metal",
37 [10] = "New Age",
38 [11] = "Oldies",
39 [12] = "Other",
40 [13] = "Pop",
41 [14] = "R&B",
42 [15] = "Rap",
43 [16] = "Reggae",
44 [17] = "Rock",
45 [18] = "Techno",
46 [19] = "Industrial",
47 [20] = "Alternative",
48 [21] = "Ska",
49 [22] = "Death Metal",
50 [23] = "Pranks",
51 [24] = "Soundtrack",
52 [25] = "Euro-Techno",
53 [26] = "Ambient",
54 [27] = "Trip-Hop",
55 [28] = "Vocal",
56 [29] = "Jazz+Funk",
57 [30] = "Fusion",
58 [31] = "Trance",
59 [32] = "Classical",
60 [33] = "Instrumental",
61 [34] = "Acid",
62 [35] = "House",
63 [36] = "Game",
64 [37] = "Sound Clip",
65 [38] = "Gospel",
66 [39] = "Noise",
67 [40] = "AlternRock",
68 [41] = "Bass",
69 [42] = "Soul",
70 [43] = "Punk",
71 [44] = "Space",
72 [45] = "Meditative",
73 [46] = "Instrumental Pop",
74 [47] = "Instrumental Rock",
75 [48] = "Ethnic",
76 [49] = "Gothic",
77 [50] = "Darkwave",
78 [51] = "Techno-Industrial",
79 [52] = "Electronic",
80 [53] = "Pop-Folk",
81 [54] = "Eurodance",
82 [55] = "Dream",
83 [56] = "Southern Rock",
84 [57] = "Comedy",
85 [58] = "Cult",
86 [59] = "Gangsta",
87 [60] = "Top 40",
88 [61] = "Christian Rap",
89 [62] = "Pop/Funk",
90 [63] = "Jungle",
91 [64] = "Native American",
92 [65] = "Cabaret",
93 [66] = "New Wave",
94 [67] = "Psychedelic",
95 [68] = "Rave",
96 [69] = "Showtunes",
97 [70] = "Trailer",
98 [71] = "Lo-Fi",
99 [72] = "Tribal",
100 [73] = "Acid Punk",
101 [74] = "Acid Jazz",
102 [75] = "Polka",
103 [76] = "Retro",
104 [77] = "Musical",
105 [78] = "Rock & Roll",
106 [79] = "Hard Rock",
107 [80] = "Folk",
108 [81] = "Folk-Rock",
109 [82] = "National Folk",
110 [83] = "Swing",
111 [84] = "Fast Fusion",
112 [85] = "Bebop",
113 [86] = "Latin",
114 [87] = "Revival",
115 [88] = "Celtic",
116 [89] = "Bluegrass",
117 [90] = "Avantgarde",
118 [91] = "Gothic Rock",
119 [92] = "Progressive Rock",
120 [93] = "Psychedelic Rock",
121 [94] = "Symphonic Rock",
122 [95] = "Slow Rock",
123 [96] = "Big Band",
124 [97] = "Chorus",
125 [98] = "Easy Listening",
126 [99] = "Acoustic",
127 [100] = "Humour",
128 [101] = "Speech",
129 [102] = "Chanson",
130 [103] = "Opera",
131 [104] = "Chamber Music",
132 [105] = "Sonata",
133 [106] = "Symphony",
134 [107] = "Booty Bass",
135 [108] = "Primus",
136 [109] = "Porn Groove",
137 [110] = "Satire",
138 [111] = "Slow Jam",
139 [112] = "Club",
140 [113] = "Tango",
141 [114] = "Samba",
142 [115] = "Folklore",
143 [116] = "Ballad",
144 [117] = "Power Ballad",
145 [118] = "Rhythmic Soul",
146 [119] = "Freestyle",
147 [120] = "Duet",
148 [121] = "Punk Rock",
149 [122] = "Drum Solo",
150 [123] = "A Cappella",
151 [124] = "Euro-House",
152 [125] = "Dance Hall",
153 [126] = "Goa",
154 [127] = "Drum & Bass",
155 [128] = "Club-House",
156 [129] = "Hardcore Techno",
157 [130] = "Terror",
158 [131] = "Indie",
159 [132] = "BritPop",
160 [133] = "Negerpunk",
161 [134] = "Polsk Punk",
162 [135] = "Beat",
163 [136] = "Christian Gangsta Rap",
164 [137] = "Heavy Metal",
165 [138] = "Black Metal",
166 [139] = "Crossover",
167 [140] = "Contemporary Christian",
168 [141] = "Christian Rock",
169 [142] = "Merengue",
170 [143] = "Salsa",
171 [144] = "Thrash Metal",
172 [145] = "Anime",
173 [146] = "Jpop",
174 [147] = "Synthpop",
175 [148] = "Abstract",
176 [149] = "Art Rock",
177 [150] = "Baroque",
178 [151] = "Bhangra",
179 [152] = "Big Beat",
180 [153] = "Breakbeat",
181 [154] = "Chillout",
182 [155] = "Downtempo",
183 [156] = "Dub",
184 [157] = "EBM",
185 [158] = "Eclectic",
186 [159] = "Electro",
187 [160] = "Electroclash",
188 [161] = "Emo",
189 [162] = "Experimental",
190 [163] = "Garage",
191 [164] = "Global",
192 [165] = "IDM",
193 [166] = "Illbient",
194 [167] = "Industro-Goth",
195 [168] = "Jam Band",
196 [169] = "Krautrock",
197 [170] = "Leftfield",
198 [171] = "Lounge",
199 [172] = "Math Rock",
200 [173] = "New Romantic",
201 [174] = "Nu-Breakz",
202 [175] = "Post-Punk",
203 [176] = "Post-Rock",
204 [177] = "Psytrance",
205 [178] = "Shoegaze",
206 [179] = "Space Rock",
207 [180] = "Trop Rock",
208 [181] = "World Music",
209 [182] = "Neoclassical",
210 [183] = "Audiobook",
211 [184] = "Audio Theatre",
212 [185] = "Neue Deutsche Welle",
213 [186] = "Podcast",
214 [187] = "Indie Rock",
215 [188] = "G-Funk",
216 [189] = "Dubstep",
217 [190] = "Garage Rock",
218 [191] = "Psybient"
219 };
220
221 5 static void get_string(AVFormatContext *s, const char *key,
222 const uint8_t *buf, int buf_size)
223 {
224 int i, c;
225 5 char *q, str[512], *first_free_space = NULL;
226
227 5 q = str;
228
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 4 times.
99 for(i = 0; i < buf_size; i++) {
229 95 c = buf[i];
230
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 94 times.
95 if (c == '\0')
231 1 break;
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 94 times.
94 if ((q - str) >= sizeof(str) - 1)
233 break;
234
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 11 times.
94 if (c == ' ') {
235
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 79 times.
83 if (!first_free_space)
236 4 first_free_space = q;
237 } else {
238 11 first_free_space = NULL;
239 }
240 94 *q++ = c;
241 }
242 5 *q = '\0';
243
244
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (first_free_space)
245 4 *first_free_space = '\0';
246
247
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (*str)
248 2 av_dict_set(&s->metadata, key, str, 0);
249 5 }
250
251 /**
252 * Parse an ID3v1 tag
253 *
254 * @param buf ID3v1_TAG_SIZE long buffer containing the tag
255 */
256 79 static int parse_tag(AVFormatContext *s, const uint8_t *buf)
257 {
258 int genre;
259
260
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 78 times.
79 if (!(buf[0] == 'T' &&
261
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 buf[1] == 'A' &&
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 buf[2] == 'G'))
263 78 return -1;
264 1 get_string(s, "title", buf + 3, 30);
265 1 get_string(s, "artist", buf + 33, 30);
266 1 get_string(s, "album", buf + 63, 30);
267 1 get_string(s, "date", buf + 93, 4);
268 1 get_string(s, "comment", buf + 97, 30);
269
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (buf[125] == 0 && buf[126] != 0) {
270 av_dict_set_int(&s->metadata, "track", buf[126], 0);
271 }
272 1 genre = buf[127];
273
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (genre <= ID3v1_GENRE_MAX)
274 1 av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0);
275 1 return 0;
276 }
277
278 79 void ff_id3v1_read(AVFormatContext *s)
279 {
280 int ret;
281 uint8_t buf[ID3v1_TAG_SIZE];
282 79 int64_t filesize, position = avio_tell(s->pb);
283
284
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 if (s->pb->seekable & AVIO_SEEKABLE_NORMAL) {
285 /* XXX: change that */
286 79 filesize = avio_size(s->pb);
287
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 if (filesize > 128) {
288 79 avio_seek(s->pb, filesize - 128, SEEK_SET);
289 79 ret = avio_read(s->pb, buf, ID3v1_TAG_SIZE);
290
1/2
✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
79 if (ret == ID3v1_TAG_SIZE) {
291 79 parse_tag(s, buf);
292 }
293 79 avio_seek(s->pb, position, SEEK_SET);
294 }
295 }
296 79 }
297