summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/id3.c133
1 files changed, 58 insertions, 75 deletions
diff --git a/firmware/id3.c b/firmware/id3.c
index e0e3ca1abf..e59618e234 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -232,38 +232,28 @@ static void setid3v2title(int fd, struct mp3entry *entry)
232{ 232{
233 int minframesize; 233 int minframesize;
234 int size; 234 int size;
235 int readsize = 0, headerlen; 235 int bufferpos = 0, totframelen, framelen;
236 char *title = NULL;
237 char *artist = NULL;
238 char *album = NULL;
239 char *tracknum = NULL;
240 char header[10]; 236 char header[10];
241 unsigned short int version; 237 unsigned short int version;
242 int titlen=0, artistn=0, albumn=0, tracknumn=0;
243 char *buffer = entry->id3v2buf; 238 char *buffer = entry->id3v2buf;
239 char *tracknum = NULL;
240 int bytesread = 0;
241 int buffersize = sizeof(entry->id3v2buf);
244 242
245 /* 10 = headerlength */ 243 /* Bail out if the tag is shorter than 10 bytes */
246 if(entry->id3v2len < 10) 244 if(entry->id3v2len < 10)
247 return; 245 return;
248 246
249 /* Check version */ 247 /* Read the ID3 tag version from the header */
250 lseek(fd, 0, SEEK_SET); 248 lseek(fd, 0, SEEK_SET);
251 if(10 != read(fd, header, 10)) 249 if(10 != read(fd, header, 10))
252 return; 250 return;
253 251
254 version = (unsigned short int)header[3]; 252 version = (unsigned short int)header[3];
255 253
256 /* Read all frames in the tag */ 254 /* Get the total ID3 tag size */
257 size = entry->id3v2len - 10; 255 size = entry->id3v2len - 10;
258 256
259 if(size >= (int)sizeof(entry->id3v2buf))
260 size = sizeof(entry->id3v2buf)-1;
261
262 if(size != read(fd, buffer, size))
263 return;
264
265 *(buffer + size) = '\0';
266
267 /* Set minimum frame size according to ID3v2 version */ 257 /* Set minimum frame size according to ID3v2 version */
268 if(version > 2) 258 if(version > 2)
269 minframesize = 12; 259 minframesize = 12;
@@ -274,86 +264,79 @@ static void setid3v2title(int fd, struct mp3entry *entry)
274 * We must have at least minframesize bytes left for the 264 * We must have at least minframesize bytes left for the
275 * remaining frames to be interesting 265 * remaining frames to be interesting
276 */ 266 */
277 while(size - readsize > minframesize) { 267 while(size > minframesize) {
278
279 /* Read frame header and check length */ 268 /* Read frame header and check length */
280 if(version > 2) { 269 if(version > 2) {
281 memcpy(header, (buffer + readsize), 10); 270 if(10 != read(fd, header, 10))
282 readsize += 10; 271 return;
272 /* Adjust for the 10 bytes we read */
273 size -= 10;
274
283 if (version > 3) { 275 if (version > 3) {
284 headerlen = UNSYNC(header[4], header[5], 276 framelen = UNSYNC(header[4], header[5],
285 header[6], header[7]); 277 header[6], header[7]);
286 } else { 278 } else {
287 /* version .3 files don't use synchsafe ints for 279 /* version .3 files don't use synchsafe ints for
288 * size */ 280 * size */
289 headerlen = BYTES2INT(header[4], header[5], 281 framelen = BYTES2INT(header[4], header[5],
290 header[6], header[7]); 282 header[6], header[7]);
291 } 283 }
292 } else { 284 } else {
293 memcpy(header, (buffer + readsize), 6); 285 if(6 != read(fd, header, 6))
294 readsize += 6; 286 return;
295 headerlen = (header[3] << 16) + 287 /* Adjust for the 6 bytes we read */
296 (header[4] << 8) + 288 size -= 6;
297 (header[5]); 289
290 framelen = BYTES2INT(0, header[3], header[4], header[5]);
298 } 291 }
299 292
300 /* Get only the part of the header that is within our buffer */ 293 /* Keep track of the total size */
301 if(headerlen > (size-readsize)) 294 totframelen += framelen;
302 headerlen = (size - readsize); 295
296 if(framelen == 0)
297 return;
298
299 /* If the frame is larger than the remaining buffer space we try
300 to read as much as would fit in the buffer */
301 if(framelen >= buffersize - bufferpos)
302 framelen = buffersize - bufferpos - 1;
303 303
304 /* Check for certain frame headers */ 304 /* Check for certain frame headers */
305 if(!strncmp(header, "TPE1", strlen("TPE1")) || 305 if(!strncmp(header, "TPE1", strlen("TPE1")) ||
306 !strncmp(header, "TP1", strlen("TP1"))) { 306 !strncmp(header, "TP1", strlen("TP1"))) {
307 readsize++; 307 bytesread = read(fd, buffer + bufferpos, framelen);
308 headerlen--; 308 entry->artist = buffer + bufferpos;
309 artist = buffer + readsize; 309 unicode_munge(&entry->artist, &bytesread);
310 artistn = headerlen; 310 entry->artist[bytesread + 1] = '\0';
311 unicode_munge(&artist, &artistn); 311 bufferpos += bytesread + 2;
312 size -= bytesread;
312 } 313 }
313 else if(!strncmp(header, "TIT2", strlen("TIT2")) || 314 else if(!strncmp(header, "TIT2", strlen("TIT2")) ||
314 !strncmp(header, "TT2", strlen("TT2"))) { 315 !strncmp(header, "TT2", strlen("TT2"))) {
315 readsize++; 316 bytesread = read(fd, buffer + bufferpos, framelen);
316 headerlen--; 317 entry->title = buffer + bufferpos;
317 title = buffer + readsize; 318 unicode_munge(&entry->title, &bytesread);
318 titlen = headerlen; 319 entry->title[bytesread + 1] = '\0';
319 unicode_munge(&title, &titlen); 320 bufferpos += bytesread + 2;
321 size -= bytesread;
320 } 322 }
321 else if(!strncmp(header, "TALB", strlen("TALB"))) { 323 else if(!strncmp(header, "TALB", strlen("TALB"))) {
322 readsize++; 324 bytesread = read(fd, buffer + bufferpos, framelen);
323 headerlen--; 325 entry->album = buffer + bufferpos;
324 album = buffer + readsize; 326 unicode_munge(&entry->album, &bytesread);
325 albumn = headerlen; 327 entry->album[bytesread + 1] = '\0';
326 unicode_munge(&album, &albumn); 328 bufferpos += bytesread + 2;
329 size -= bytesread;
327 } 330 }
328 else if(!strncmp(header, "TRCK", strlen("TRCK"))) { 331 else if(!strncmp(header, "TRCK", strlen("TRCK"))) {
329 readsize++; 332 bytesread = read(fd, buffer + bufferpos, framelen);
330 headerlen--; 333 tracknum = buffer + bufferpos;
331 tracknum = buffer + readsize; 334 unicode_munge(&tracknum, &bytesread);
332 tracknumn = headerlen; 335 tracknum[bytesread + 1] = '\0';
333 unicode_munge(&tracknum, &tracknumn); 336 entry->tracknum = atoi(tracknum);
337 bufferpos += bytesread + 1;
338 size -= bytesread;
334 } 339 }
335
336 readsize += headerlen;
337 }
338
339 if(artist) {
340 entry->artist = artist;
341 artist[artistn]=0;
342 }
343
344 if(title) {
345 entry->title = title;
346 title[titlen]=0;
347 }
348
349 if(album) {
350 entry->album = album;
351 album[albumn]=0;
352 }
353
354 if(tracknum) {
355 tracknum[tracknumn] = 0;
356 entry->tracknum = atoi(tracknum);
357 } 340 }
358} 341}
359 342