1 /* OpenCP Module Player
2 * copyright (c) 2020 Stian Skjelstad <stian.skjelstad@gmail.com>
3 *
4 * Utility: Dumping the ID3 tags from MP3 files
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22 #define _GNU_SOURCE
23 #include <fcntl.h>
24 #include <inttypes.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <zlib.h>
33
34 /**** Most common file-layuts:
35 *
36 * [----------MPEG DATA-------------][ID3v1.0] # 128 bytes at the end
37 *
38 * [----------MPEG DATA-------------][ID3v1.1] # 128 bytes at the end
39 *
40 *
41 * [ID3v2.2][----------MPEG DATA-------------] # ID3V2.2 at the start
42 * [ID3v2.3][----------MPEG DATA-------------] # ID3V2.3 at the start
43 * [ID3v2.4][----------MPEG DATA-------------] # ID3V2.4 at the start
44 *
45 * [ID3v2.2][------MPEG DATA--------][ID3v1.0] # ID3V1.x tag at the end of legacy software, ID3v2.x at the start
46 *
47 * [----------MPEG DATA----------][ID3v2.4][F] # ID3V2.4 with footer at the end
48 *
49 * [MPEG DATA][ID3v2.x][MPEG DATA][ID3v2.x].. # Streaming service, music changes while playing
50 *
51 *
52 * This never got popular:
53 *
54 * [------MPEG DATA--------][ID3v1.2][ID3v1.1] # 256 bytes at the end - The two tags combined gives longer strings
55 *
56 *
57 * "Broken" software generates these:
58 *
59 *[ID3v2.2][ID3v2.3][-------MPEG DATA--------] # not common, but perfectly OK. Tag with unknown versions should be ignored, so old software reads v2.2, new read v2.3 and replaces the information
60 */
61
62 static int indent = 0;
63 static int _newline = 1;
print(const char * format,...)64 static void print(const char *format, ...)
65 {
66 va_list ap;
67
68 if (_newline)
69 {
70 int i;
71 _newline = 0;
72 for (i=0; i < indent; i++)
73 {
74 fputc(' ', stdout);
75 }
76 }
77
78 va_start(ap, format);
79 vprintf(format, ap);
80 va_end(ap);
81 }
82 enum stack_message_type
83 {
84 STACK_INFO = 0,
85 STACK_WARNING = 1,
86 STACK_ERROR = 2
87 };
88 static int stacked_count;
89 static char *stacked_messages[1024];
90 static int stacked_indent[1024];
91 static enum stack_message_type stacked_smt[1024];
stack_message(enum stack_message_type smt,int extraindent,const char * format,...)92 static void stack_message(enum stack_message_type smt, int extraindent, const char *format, ...)
93 {
94 va_list ap;
95
96 char *buffer;
97 buffer = malloc(1024);
98 va_start(ap, format);
99 vsnprintf(buffer, 1024, format, ap);
100 va_end(ap);
101 stacked_indent[stacked_count] = extraindent + indent;
102 stacked_messages[stacked_count] = buffer;
103 stacked_smt[stacked_count++] = smt;
104 }
flush()105 static void flush()
106 {
107 int i;
108 int oldindent = indent;
109 if (!_newline)
110 {
111 fputc('\n', stdout);
112 _newline=1;
113 }
114 for (i=0; i < stacked_count; i++)
115 {
116 indent = stacked_indent[i];
117 switch (stacked_smt[i])
118 {
119 case STACK_WARNING: print ("*-* WARNING: "); break;
120 case STACK_ERROR: print ("*-* ERROR: "); break;
121 case STACK_INFO: print ("*-* INFO: "); break;
122 }
123 print(stacked_messages[i]);
124 free(stacked_messages[i]);
125 switch (stacked_smt[i])
126 {
127 case STACK_WARNING:
128 case STACK_ERROR:
129 case STACK_INFO: print (" *-*"); break;
130 }
131 fputc('\n', stdout);
132 _newline=1;
133 }
134 indent = oldindent;
135 stacked_count = 0;
136 }
newline()137 static void newline()
138 {
139 if (stacked_count)
140 {
141 flush();
142 } else {
143 fputc('\n', stdout);
144 _newline=1;
145 }
146 }
unsync(uint8_t * data,uint32_t * len)147 static void unsync(uint8_t *data, uint32_t *len)
148 {
149 uint32_t i;
150 /* Unescape all 0xff 0x00 combinations with 0xff */
151 for (i = 0; (i+1) < (*len); i++)
152 {
153 if ((data[i]==0xff) && (data[i+1]==0x00))
154 {
155 memmove (data + i + 1, data + i + 2, (*len) - i - 1);
156 (*len)--;
157 }
158 }
159 }
160
decode_print_UTF8(uint8_t ** data,uint32_t * len,const int must_include_null_term)161 static int decode_print_UTF8(uint8_t **data, uint32_t *len, const int must_include_null_term)
162 {
163 int ilen = 1;
164 #warning TODO, sanitize UTF-8
165 print("\"");
166 while (*len)
167 {
168 if ((*data)[0] == 0x00)
169 {
170 (*data)++;
171 (*len)--;
172 print("\"");
173 return 0;
174 } else if ((*data[0]) == 0x0a)
175 {
176 ilen += 6;
177 print("\" NL \"");
178 } else if ((*data)[0] == 0x0d)
179 {
180 ilen += 6;
181 print("\" CR \""); /* not always present */
182 } else {
183 if ((*data)[0] & 0x80)
184 {
185 if (((*data)[0] & 0xC0) != 0x80)
186 {
187 ilen++;
188 }
189 } else {
190 ilen++;
191 }
192 print("%c", (*data)[0]);
193 }
194 (*data)++;
195 (*len)--;
196 }
197 print("\"");
198 if (must_include_null_term)
199 {
200 stack_message(ilen, STACK_ERROR, "no NULL termination");
201 return -1;
202 }
203 return 0;
204 }
205
decode_print_iso8859_1(uint8_t ** data,uint32_t * len,const int must_include_null_term)206 static int decode_print_iso8859_1(uint8_t **data, uint32_t *len, const int must_include_null_term)
207 {
208 int ilen = 1;
209 int valid_utf8_chars = 0;
210 int invalid_utf8_chars = 0;
211 /* first we prescan to detect if UTF-8 has been dumped into latin1.. this happens often in ID3.
212 *(we only probe for (2 and 3 characters wide)
213 */
214 {
215 uint8_t *d2 = *data;
216 uint32_t l2 = *len;
217 while (l2)
218 {
219 if (!*d2)
220 {
221 break;
222 }
223 if (d2[0] & 0x80)
224 {
225 if ((l2 >= 2) && ((d2[0] & 0xe0) == 0xc0) && ((d2[1] & 0xc0) == 0x80))
226 {
227 valid_utf8_chars++;
228 d2+=2;
229 l2-=2;
230 } else if ((l2 >= 3) && ((d2[0] & 0xf0) == 0xe0) && ((d2[1] & 0xc0) == 0x80) && ((d2[2] & 0xc0) == 0x80))
231 {
232 valid_utf8_chars++;
233 d2+=3;
234 l2-=3;
235 } else {
236 invalid_utf8_chars++;
237 break;
238 }
239 } else {
240 d2++;
241 l2--;
242 }
243 }
244 }
245
246 if ((!invalid_utf8_chars) && valid_utf8_chars)
247 {
248 print("=> UTF8_detected ");
249 return decode_print_UTF8(data, len, must_include_null_term);
250 }
251 print("\"");
252 while (*len)
253 {
254 if ((*data)[0] == 0x00)
255 {
256 (*data)++;
257 (*len)--;
258 print("\"");
259 return 0;
260 } else if ((*data)[0] == 0x0a)
261 {
262 ilen += 6;
263 print("\" NL \"");
264 } else if ((*data)[0] == 0x0d)
265 {
266 ilen += 6;
267 print("\" CR \""); /* not always present */
268 } else if (((*data)[0] <= 0x1f) || (((*data)[0] >= 0x8f) && ((*data)[0] <= 0x9f)))
269 {
270 stack_message(STACK_WARNING, ilen, "byte with invalid value: 0x%02"PRIx8, (*data)[0]);
271 } else {
272 ilen++;
273 if ((*data)[0] < 0x80)
274 {
275 print("%c", (*data)[0]);
276 } else {
277 print("%c%c", ((*data)[0] >> 6) | 0xc0, ((*data)[0] & 0x3f) | 0x80);
278 }
279 }
280 (*data)++;
281 (*len)--;
282 }
283 print("\"");
284 if (must_include_null_term)
285 {
286 stack_message(STACK_ERROR, ilen, "no NULL termination");
287 return -1;
288 }
289 return 0;
290 }
291
decode_print_UCS2(uint8_t ** data,uint32_t * len,const int must_include_null_term,int firststring)292 static int decode_print_UCS2(uint8_t **data, uint32_t *len, const int must_include_null_term, int firststring)
293 {
294 int ilen = 1;
295 static int be = 1;
296
297 if (*len < 2)
298 {
299 stack_message(STACK_WARNING, ilen, "BOM can not fit");
300 return -1;
301 }
302 if (((*data)[0] == 0xfe) && ((*data)[1] == 0xff))
303 { // big endian
304 be = 1;
305 (*data)+=2;
306 (*len)-=2;
307 } else if (((*data)[0] == 0xff) && ((*data)[1] == 0xfe))
308 { // little endian
309 be = 0;
310 (*data)+=2;
311 (*len)-=2;
312 } else {
313 if (firststring)
314 {
315 stack_message(STACK_WARNING, ilen, "Invalid BOM: 0x%02x 0x%02x", (*data)[0], (*data)[1]);
316 return -1;
317 }
318 }
319
320 print("\"");
321 while (*len)
322 {
323 uint16_t codepoint;
324 if (*len == 1)
325 {
326 stack_message(STACK_WARNING, ilen, "len==1");
327 print("\"");
328 return -1;
329 }
330 if (be)
331 {
332 codepoint = ((*data)[0]<<8) | (*data)[1];
333 } else {
334 codepoint = ((*data)[1]<<8) | (*data)[0];
335 }
336 (*data)+=2;
337 (*len)-=2;
338
339 if (codepoint == 0x0000)
340 {
341 (*data)+=2;
342 (*len)-=2;
343 print("\"");
344 return 0;
345 } else if (codepoint == 0x000a)
346 {
347 ilen += 6;
348 print("\" NL \"");
349 } else if (codepoint == 0x000d)
350 {
351 ilen += 6;
352 print("\" CR \""); /* not always present */
353 } else if (codepoint < 127)
354 {
355 ilen++;
356 print("%c", codepoint);
357 } else if (codepoint < 0x800)
358 {
359 ilen++;
360 print("%c%c", (codepoint >> 6) | 0xc0, (codepoint & 0x3f) | 0x80);
361 } else {
362 ilen++;
363 print("%c%c%c", (codepoint >> 12) | 0xe0, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
364 }
365 }
366 print("\"");
367 if (must_include_null_term)
368 {
369 stack_message(STACK_ERROR, ilen, "no NULL termination");
370 return -1;
371 }
372 return 0;
373 }
374
decode_print_UTF16(uint8_t ** data,uint32_t * len,const int must_include_null_term)375 static int decode_print_UTF16(uint8_t **data, uint32_t *len, const int must_include_null_term)
376 {
377 int ilen = 1;
378 int be = 1;
379
380 print("\"");
381 while (*len)
382 {
383 uint32_t codepoint;
384 if ((*len) == 1)
385 {
386 if (must_include_null_term)
387 {
388 (*data)+=2;
389 (*len)-=2;
390 }
391 stack_message(STACK_ERROR, ilen, "len==1");
392 return -1;
393 }
394 if (be)
395 {
396 codepoint = ((*data)[0]<<8) | (*data)[1];
397 } else {
398 codepoint = ((*data)[1]<<8) | (*data)[0];
399 }
400
401 (*data)+=2;
402 (*len)-=2;
403
404 if ((codepoint >= 0xd800) && (codepoint <= 0xdbff))
405 {
406 uint16_t second;
407 if ((*len) < 2)
408 {
409 stack_message(STACK_ERROR, ilen, "Second surrogate does not fit");
410 print("\"");
411 return 1;
412 }
413 if (be)
414 {
415 second = ((*data)[0]<<8) | (*data)[1];
416 } else {
417 second = ((*data)[1]<<8) | (*data)[0];
418 }
419 (*data)+=2;
420 (*len)-=2;
421
422 if ((second < 0xdc00) || (second > 0xdfff))
423 {
424 stack_message(STACK_ERROR, ilen, "Second surrogate out og range");
425 print("\"");
426 return -1;
427 }
428
429 codepoint = ((codepoint & 0x03ff) << 10) | (second & 0x03ff);
430 codepoint += 0x10000;
431
432 } else if ((codepoint >= 0xdc00) && (codepoint <= 0xdfff))
433 {
434 stack_message(STACK_ERROR, ilen, "Surrogates in the wrong order");
435 print("\"");
436 return -1;
437 }
438 if (codepoint == 0xfeff)
439 {
440 /* NO-OP */
441 } if (codepoint == 0xfffe)
442 {
443 be = !be;
444 } else if (codepoint == 0x0000)
445 {
446 (*data)+=2;
447 (*len)-=2;
448 print("\"");
449 return 0;
450 } else if (codepoint == 0x000a)
451 {
452 ilen += 6;
453 print("\" NL \"");
454 } else if (codepoint == 0x000d)
455 {
456 ilen += 6;
457 print("\" CR \""); /* not always present */
458 } else if (codepoint < 127)
459 {
460 ilen++;
461 print("%c", codepoint);
462 } else if (codepoint < 0x800)
463 {
464 ilen++;
465 print("%c%c", (codepoint >> 6) | 0xc0, (codepoint & 0x3f) | 0x80);
466 } else if (codepoint < 0x10000)
467 {
468 ilen++;
469 print("%c%c%c", (codepoint >> 12) | 0xe0, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
470 } else {
471 ilen++;
472 print("%c%c%c%c", (codepoint >> 18) | 0xf0, ((codepoint >> 12) & 0x3f) | 0x80, ((codepoint >> 6) & 0x3f) | 0x80, (codepoint & 0x3f) | 0x80);
473 }
474 }
475 print("\"");
476 if (must_include_null_term)
477 {
478 stack_message(STACK_ERROR, ilen, "no NULL termination");
479 return -1;
480 }
481 return 0;
482 }
483
decode_UFID(uint8_t * data,uint32_t len)484 static void decode_UFID(uint8_t *data, uint32_t len)
485 { /* ID3v220 used UFI only */
486 uint8_t *nameeof = memchr (data, len, 0x00);
487
488 print("Unique file identifier");
489
490 if (!nameeof)
491 {
492 stack_message(STACK_WARNING, 0, "no DB");
493 } else {
494 print(" \"%s\"", (char *)data);
495 len -= nameeof-data;
496 data=nameeof;
497
498 len--;
499 data++;
500 }
501
502 if (len > 64)
503 {
504 stack_message(STACK_WARNING, 0, "More than 64 bytes in ID");
505 }
506
507 print(" ID=0x");
508 while (len)
509 {
510 print("%02" PRIx8, *data);
511 data++;
512 len--;
513 }
514 newline();
515 }
516
decode_MCDI(uint8_t * data,uint32_t len)517 static void decode_MCDI(uint8_t *data, uint32_t len)
518 { /* ID3v220 used MCI only */
519 print("Music CD identifier");
520
521 if (len > 804)
522 {
523 stack_message(STACK_WARNING, 0, "More than 804 bytes in ID");
524 }
525
526 print(" - CD-TOC=0x");
527 while (len)
528 {
529 print("%02" PRIx8, *data);
530 data++;
531 len--;
532 }
533 newline();
534 }
535
decode_ETCO(uint8_t * data,uint32_t len,uint8_t version)536 static void decode_ETCO(uint8_t *data, uint32_t len, uint8_t version)
537 { /* ID3v220 used ETC only */
538 uint8_t format;
539
540 print("Event timing codes");
541
542 if (len < 1)
543 {
544 stack_message(STACK_WARNING, 0, "Frame contains no format");
545 newline();
546 return;
547 }
548 format = *data;
549 data++;
550 len--;
551
552 if ((format == 0) || (format > 2))
553 {
554 stack_message(STACK_WARNING, 0, "Invalid format");
555 newline();
556 return;
557 }
558
559 newline();
560 while (len >= 5)
561 {
562 if (data[0] != 0xff)
563 {
564 uint32_t timecode;
565 timecode = (data[1]<<24)|(data[2]<<16)|(data[3]<<8)|data[4];
566
567 if (timecode == 0)
568 {
569 print(" %s", (format==1)?" ":" ");
570 } else {
571 print("%10" PRId32 " %s ", timecode, (format==1)?"ms":"mpeg-frames");
572 }
573
574 if (data[0] == 0x00) print("padding (has no meaning)");
575 else if (data[0] == 0x01) print("end of initial silence");
576 else if (data[0] == 0x02) print("intro start");
577 else if (data[0] == 0x03) print("main part start");
578 else if (data[0] == 0x04) print("outro start");
579 else if (data[0] == 0x05) print("outro end");
580 else if (data[0] == 0x06) print("verse start");
581 else if (data[0] == 0x07) print("refrain start");
582 else if (data[0] == 0x08) print("interlude start");
583 else if (data[0] == 0x09) print("theme start");
584 else if (data[0] == 0x0a) print("variation start");
585 else if (data[0] == 0x0b) print("key change");
586 else if (data[0] == 0x0c) print("time change");
587 else if (data[0] == 0x0d) print("momentary unwanted noise (Snap, Crackle & Pop)");
588 else if ((data[0] == 0x0e) && (version >= 3)) print("sustained noise"); /* new in ID3v230 */
589 else if ((data[0] == 0x0f) && (version >= 3)) print("sustained noise end"); /* new in ID3v230 */
590 else if ((data[0] == 0x10) && (version >= 3)) print("intro end"); /* new in ID3v230 */
591 else if ((data[0] == 0x11) && (version >= 3)) print("main part end"); /* new in ID3v230 */
592 else if ((data[0] == 0x12) && (version >= 3)) print("verse end"); /* new in ID3v230 */
593 else if ((data[0] == 0x13) && (version >= 3)) print("refrain end"); /* new in ID3v230 */
594 else if ((data[0] == 0x14) && (version >= 3)) print("theme end"); /* new in ID3v230 */
595 else if ((data[0] == 0x15) && (version >= 4)) print("profanity"); /* new in ID3v240 */
596 else if ((data[0] == 0x16) && (version >= 4)) print("profanity end"); /* new in ID3v240 */
597 else if (data[0] == 0xfd) print("audio end (start of silence)");
598 else if (data[0] == 0xfe) print("audio file ends");
599 else if ((data[0] & 0xf0) == 0xe0) print("not predefined sync: %c", "0123456789ABCDEF"[data[0]&0x0f]);
600 else print("(%02x) - reserved for future use", data[0]);
601
602 newline();
603
604 data+=5;
605 len-=5;
606 } else {
607 int i, j;
608 uint32_t timecode;
609
610 for (i=0; data[i]==0xff; i++)
611 {
612 if (len < (i*2+4))
613 {
614 stack_message(STACK_ERROR, 0, "Ran out of data while reading ETCO user event");
615 return;
616 }
617 }
618
619 timecode = (data[i*2+0]<<24)|(data[i*2+1]<<16)|(data[i*2+2]<<8)|data[i*2+3];
620 indent += 2;
621 for (j=0; j < i; j++)
622 {
623 if ((timecode == 0) || j)
624 {
625 print(" %s", (format==1)?" ":" ");
626 } else {
627 print("%10" PRId32 " %s ", timecode, (format==1)?"ms":"mpeg-frames");
628 }
629 print ("User event %d", data[i+j]);
630 newline();
631 }
632 indent -= 2;
633
634 data += i*2+4;
635 len -= i*2+4;
636 }
637 }
638
639 if (len)
640 {
641 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
642 }
643 }
644
decode_POSS(uint8_t * data,uint32_t len)645 static void decode_POSS(uint8_t *data, uint32_t len)
646 {
647 uint32_t timecode = 0;
648 uint8_t format;
649
650 print("Position synchronisation frame");
651
652 if (len < 1)
653 {
654 stack_message(STACK_ERROR, 0, "Frame contains no format");
655 newline();
656 return;
657 }
658 format = *data;
659 data++;
660 len--;
661
662 if ((format == 0) || (format > 2))
663 {
664 stack_message(STACK_ERROR, 0, "Invalid format");
665 newline();
666 return;
667 }
668
669 while (len)
670 {
671 timecode <<= 8;
672 timecode |= data[0];
673 }
674 print(" - Position: %" PRId32 " %s", timecode, (format==1)?"ms":"mpeg-frames");
675 newline();
676 }
677
decode_GEOB(uint8_t * data,uint32_t len,int version)678 static void decode_GEOB(uint8_t *data, uint32_t len, int version)
679 { /* ID3v220 used GEO only */
680 uint8_t text_encoding;
681 int error;
682
683 print("General encapsulated object");
684
685 if (len < 1)
686 {
687 stack_message(STACK_ERROR, 0, "No space for text_encoding");
688 newline();
689 return;
690 }
691 text_encoding = *data;
692 data++;
693 len--;
694
695 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
696 {
697 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
698 newline();
699 return;
700 }
701
702 if (!len)
703 {
704 stack_message(STACK_ERROR, 0, "No space for MIME-Type");
705 newline();
706 return;
707 }
708 newline();
709 print("MIME-Type: ");
710 error=decode_print_iso8859_1(&data, &len, 1);
711 newline();
712
713 if (error)
714 {
715 return;
716 }
717
718 if (!len)
719 {
720 stack_message(STACK_ERROR, 0, "No space for Filename");
721 return;
722 }
723
724 print("Filename: ");
725 switch (text_encoding)
726 {
727 case 0x00:
728 print("LATIN1 ");
729 error = decode_print_iso8859_1(&data, &len, 1);
730 break;
731 case 0x01:
732 print("UCS-2 ");
733 error = decode_print_UCS2(&data, &len, 1, 1);
734 break;
735 case 0x02:
736 print("UTF-16 ");
737 error = decode_print_UTF16(&data, &len, 1);
738 break;
739 case 0x03:
740 print("UTF-8 ");
741 error = decode_print_UTF8(&data, &len, 1);
742 break;
743 }
744 newline();
745 if (error)
746 {
747 return;
748 }
749
750 if (!len)
751 {
752 stack_message(STACK_ERROR, 0, "Ran out of data");
753 return;
754 }
755
756 print("Content description: ");
757 switch (text_encoding)
758 {
759 case 0x00:
760 print("LATIN1 ");
761 error = decode_print_iso8859_1(&data, &len, 1);
762 break;
763 case 0x01:
764 print("UCS-2 ");
765 error = decode_print_UCS2(&data, &len, 1, 0);
766 break;
767 case 0x02:
768 print("UTF-16 ");
769 error = decode_print_UTF16(&data, &len, 1);
770 break;
771 case 0x03:
772 print("UTF-8 ");
773 error = decode_print_UTF8(&data, &len, 1);
774 break;
775 }
776 newline();
777 if (error)
778 {
779 return;
780 }
781
782 print("Encapsulated object: 0x");
783 while (len)
784 {
785 print("%02" PRIx8, *data);
786 data++;
787 len--;
788 }
789 newline();
790 }
791
decode_EQUA(uint8_t * data,uint32_t len)792 static void decode_EQUA(uint8_t *data, uint32_t len)
793 {
794 uint8_t bits;
795 print("Equalisation"); newline();
796
797 if (len < 1)
798 {
799 stack_message(STACK_ERROR, 0, "No space for Adjustment bits");
800 return;
801 }
802 bits = data[0];
803 if (bits==0||bits>16)
804 {
805 stack_message(STACK_ERROR, 0, "Adjustment bits out of range");
806 return;
807 }
808 data++;
809 len--;
810
811 while (len > 3)
812 {
813 uint16_t frequency = (data[0]<<8) | data[1];
814 uint16_t adjustment = (data[2]);
815
816 data+=3;
817 len-=3;
818 if (bits>8)
819 {
820 if (!len)
821 {
822 stack_message(STACK_ERROR, 0, "Ran out of data");
823 return;
824 }
825 adjustment<<=8;
826 adjustment|=data[0];
827 data++;
828 len--;
829 }
830
831 print("Frequency: %"PRId16" Hz, Volume adjustment: %c%"PRId16, frequency & 0x7fff, (frequency & 0x8000)?'+':'-', adjustment); newline();
832 }
833 if (len)
834 {
835 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
836 }
837 }
838
decode_EQU2(uint8_t * data,uint32_t len)839 static void decode_EQU2(uint8_t *data, uint32_t len)
840 {
841 int error;
842 print("Equalisation (2)"); newline();
843
844 if (len < 1)
845 {
846 stack_message(STACK_ERROR, 0, "No space for Interpolation method");
847 return;
848 }
849 switch (data[0])
850 {
851 case 0x00: print("Interpolation method: Band"); newline(); break;
852 case 0x01: print("Interpolation method: Linear"); newline(); break;
853 default: stack_message(STACK_ERROR, 0, "Unknown interpolation method"); return;
854 }
855 data++;
856 len--;
857
858 print("Identification: ");
859 error = decode_print_iso8859_1(&data, &len, 1);
860 newline();
861 if (error)
862 {
863 return;
864 }
865
866 while (len > 4)
867 {
868 uint16_t frequency = (data[0]<<8) | data[1];
869 uint16_t adjustment = (data[2]<<8) | data[3];
870
871 print("Frequency: %"PRId16" Hz, Volume adjustment: %"PRId16, frequency, adjustment); newline();
872 data+=4;
873 len-=4;
874 }
875 if (len)
876 {
877 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
878 }
879 }
880
decode_RBUF(uint8_t * data,uint32_t len)881 static void decode_RBUF(uint8_t *data, uint32_t len)
882 { /* ID3v220 used BUF*/
883 uint32_t buffersize;
884 print("Recommended buffer size"); newline();
885
886 if (len < 4)
887 {
888 stack_message(STACK_ERROR, 0, "Frame too small");
889 return;
890 }
891 buffersize = (data[0]<<16) | (data[1]<<8) | data[2];
892 data+=3;
893 len-=3;
894
895 print("Buffer size: %" PRId32, buffersize); newline();
896 if (data[0] & 0x01)
897 {
898 print("ID3 tag larger than Recommended buffer size can appear!"); newline();
899 } else {
900 print("Oversized ID3 tag shall not appear!"); newline();
901 }
902 data++;
903 len--;
904
905 if (len < 4)
906 {
907 print("(Offset to next tag omitted)"); newline();
908 } else {
909 buffersize = (data[0] << 24) | (data[1]<<16) | (data[2]<<8) | data[3];
910 print("Offset to next tag: %" PRId32, buffersize); newline();
911 data+=4;
912 len-=4;
913 }
914
915 if (len)
916 {
917 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
918 }
919 }
920
decode_MLLT(uint8_t * data,uint32_t len)921 static void decode_MLLT(uint8_t *data, uint32_t len)
922 { /* ID3v220 used MLL */
923 print("MPEG location lookup table"); newline();
924
925 if (len < 10)
926 {
927 stack_message(STACK_ERROR, 0, "Frame too small");
928 return;
929 }
930
931 print("MPEG frames between reference: %d", (data[0]<<8) | data[1]); newline();
932 print("Bytes between reference: %d", (data[2]<<24) | (data[3]<<8) | data[4]); newline();
933 print("Milliseconds between reference: %d", (data[5]<<24) | (data[6]<<8) | data[7]); newline();
934 print("Bits for bytes deviation: %d", data[8]); newline();
935 print("Bits for milliseconds deviation: %d", data[9]); newline();
936 data+=10;
937 len-=10;
938 print("DATA: 0x");
939 #warning TODO, decode this raw data...
940 while (len)
941 {
942 print("%02x", *data);
943 data++;
944 len--;
945 }
946 newline();
947 }
948
decode_SEEK(uint8_t * data,uint32_t len)949 static void decode_SEEK(uint8_t *data, uint32_t len)
950 {
951 uint32_t min;
952 print("Seek"); newline();
953
954 if (len < 4)
955 {
956 stack_message(STACK_ERROR, 0, "Frame too small");
957 return;
958 }
959 min = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
960 print("Minimum offset to next tag: %" PRId32, min); newline();
961 data+=4;
962 len-=4;
963
964 if (len)
965 {
966 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
967 }
968 }
969
decode_ASPI(uint8_t * data,uint32_t len)970 static void decode_ASPI(uint8_t *data, uint32_t len)
971 {
972 uint32_t S, L;
973 uint16_t N;
974 uint8_t b;
975 print("Audio seek point index"); newline();
976
977 if (len < 11)
978 {
979 stack_message(STACK_ERROR, 0, "Frame too small");
980 return;
981 }
982
983 S = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[3];
984 L = (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7];
985 N = (data[8]<<8)|data[9];
986 b = data[10];
987 print("Indexed data start (S): %" PRId32, S); newline();
988 print("Indexed data length (L): %" PRId32, L); newline();
989 print("Number of index points (N): %" PRId16, N); newline();
990 print("Bits per index point (b): %" PRId8, b); newline();
991 data+=11;
992 len-=11;
993 print("DATA: 0x");
994 #warning TODO, decode this raw data...
995 while (len)
996 {
997 print("%02x", *data);
998 data++;
999 len--;
1000 }
1001 newline();
1002 }
1003
decode_SYTC(uint8_t * data,uint32_t len)1004 static void decode_SYTC(uint8_t *data, uint32_t len)
1005 { /* ID3v220 used STC */
1006 uint8_t format;
1007 print("Synchronised tempo codes"); newline();
1008
1009 if (len < 1)
1010 {
1011 stack_message(STACK_ERROR, 0, "Frame too small");
1012 return;
1013 }
1014 format = *data;
1015 data++;
1016 len--;
1017 if ((format < 1) || (format > 2))
1018 {
1019 stack_message(STACK_ERROR, 0, "Format out of range");
1020 return;
1021 }
1022
1023 while (len)
1024 {
1025 uint16_t value = *data;
1026 uint32_t timestamp;
1027 data++;
1028 len--;
1029 if (value == 255)
1030 {
1031 if (len < 1)
1032 {
1033 stack_message(STACK_ERROR, 0, "Out of data reading second byte of value");
1034 return;
1035 }
1036 value += *data;
1037 data++;
1038 len--;
1039 }
1040 if (len < 4)
1041 {
1042 stack_message(STACK_ERROR, 0, "Out of data reading timestamp");
1043 break;
1044 }
1045 timestamp = (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | data[3];
1046 data+=4;
1047 len-=4;
1048 print("%" PRId32 "%s -- ", timestamp, (format==1)?"mpeg frames":"ms");
1049 if (value == 0)
1050 {
1051 print("beat-free");
1052 } else if (value == 1)
1053 {
1054 print("single beat");
1055 } else {
1056 print("%d BPM", (int)value);
1057 }
1058 newline();
1059 }
1060
1061 if (len)
1062 {
1063 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1064 }
1065 }
1066
decode_SYLT(uint8_t * data,uint32_t len,int version)1067 static void decode_SYLT(uint8_t *data, uint32_t len, int version)
1068 { /* ID3v220 used SLT */
1069 int error;
1070 uint8_t text_encoding, format;
1071 int first = 1;
1072 print("Synchronised lyrics/text");
1073 newline();
1074
1075 if (len < 6)
1076 {
1077 stack_message(STACK_ERROR, 0, "Frame too small");
1078 return;
1079 }
1080
1081 text_encoding = data[0];
1082 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1083 {
1084 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1085 return;
1086 }
1087
1088 if ((data[1]<0x20)||(data[1]>=0x80)||
1089 (data[2]<0x20)||(data[2]>=0x80)||
1090 (data[3]<0x20)||(data[3]>=0x80))
1091 {
1092 print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1093 } else {
1094 print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1095 }
1096 newline();
1097
1098 format = data[4];
1099 if ((format < 0) || (format > 2))
1100 {
1101 stack_message(STACK_ERROR, 0, "Time stamp format out of range");
1102 return;
1103 }
1104 switch (data[5])
1105 {
1106 case 0x00: print("Content type: other"); newline(); break;
1107 case 0x01: print("Content type: lyrics"); newline(); break;
1108 case 0x02: print("Content type: text transcription"); newline(); break;
1109 case 0x03: print("Content type: movement/part name (e.g. \"Adagio\")"); newline(); break;
1110 case 0x04: print("Content type: events (e.g. \"Don Quijote enters the stage\")"); newline(); break;
1111 case 0x05: print("Content type: chord (e.g. \"Bb F Fsus\")"); newline(); break;
1112 case 0x06: print("Content type: trivia/'pop up' information"); newline(); break;
1113 case 0x07: print("Content type: URLs to webpages"); newline(); break;
1114 case 0x08: print("Content type: URLs to images"); newline(); break;
1115 default: stack_message(STACK_WARNING, 0, "Content type out of range"); break;
1116 }
1117 data+= 6;
1118 len-=6;
1119
1120 while (len)
1121 {
1122 uint32_t timecode;
1123 switch (text_encoding)
1124 {
1125 case 0x00:
1126 print("LATIN1 ");
1127 error = decode_print_iso8859_1 (&data, &len, 1);
1128 break;
1129 case 0x01:
1130 print("UCS2 ");
1131 error = decode_print_UCS2 (&data, &len, 1, first);
1132 first = 0;
1133 break;
1134 case 0x02:
1135 print("UTF-16 ");
1136 error=decode_print_UTF16 (&data, &len, 1);
1137 break;
1138 case 0x03:
1139 print("UTF-8 ");
1140 error=decode_print_UTF8 (&data, &len, 1);
1141 break;
1142 }
1143 if (error)
1144 {
1145 newline();
1146 return;
1147 }
1148 if (len < 4)
1149 {
1150 newline();
1151 stack_message(STACK_ERROR, 0, "Ran out of data");
1152 break;
1153 }
1154 timecode = (data[0]<<24)|(data[1]<<16)|(data[2]<<8)|data[1];
1155 data+=4;
1156 len-=4;
1157 print(" %" PRId32 " %s", timecode, (format==1)?"mpeg frames":"ms"); newline();
1158 }
1159
1160 if (len)
1161 {
1162 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1163 }
1164 }
1165
decode_USLT(uint8_t * data,uint32_t len,int version)1166 static void decode_USLT(uint8_t *data, uint32_t len, int version)
1167 { /* ID3v220 used ULT */
1168 int error;
1169 uint8_t text_encoding;
1170 print("Unsynchronised lyrics/text transcription"); newline();
1171
1172 if (len < 4)
1173 {
1174 stack_message(STACK_ERROR, 0, "Frame too small");
1175 return;
1176 }
1177
1178 text_encoding = data[0];
1179 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1180 {
1181 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1182 return;
1183 }
1184
1185 if ((data[1]<0x20)||(data[1]>=0x80)||
1186 (data[2]<0x20)||(data[2]>=0x80)||
1187 (data[3]<0x20)||(data[3]>=0x80))
1188 {
1189 print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1190 } else {
1191 print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1192 }
1193 newline();
1194
1195 print("Content-Descriptor: ");
1196 switch (text_encoding)
1197 {
1198 case 0x00:
1199 print("LATIN1 ");
1200 error = decode_print_iso8859_1 (&data, &len, 1);
1201 break;
1202 case 0x01:
1203 print("UCS2 ");
1204 error = decode_print_UCS2 (&data, &len, 1, 1);
1205 break;
1206 case 0x02:
1207 print("UTF-16 ");
1208 error = decode_print_UTF16 (&data, &len, 1);
1209 break;
1210 case 0x03:
1211 print("UTF-8 ");
1212 error = decode_print_UTF8 (&data, &len, 1);
1213 break;
1214 }
1215 newline();
1216 if (error)
1217 {
1218 return;
1219 }
1220 print("Lyrics/text: ");
1221 switch (text_encoding)
1222 {
1223 case 0x00:
1224 print("LATIN1 "); /* we are laxed on require NULL here */
1225 error = decode_print_iso8859_1 (&data, &len, 0);
1226 break;
1227 case 0x01:
1228 print("UCS2 ");
1229 error = decode_print_UCS2 (&data, &len, 0, 0);
1230 break;
1231 case 0x02:
1232 print("UTF-16 ");
1233 error = decode_print_UTF16 (&data, &len, 0);
1234 break;
1235 case 0x03:
1236 print("UTF-8 ");
1237 error = decode_print_UTF8 (&data, &len, 0);
1238 break;
1239 }
1240 newline();
1241 if (error)
1242 {
1243 return;
1244 }
1245 if (len)
1246 {
1247 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1248 }
1249 }
1250
decode_RVAD(uint8_t * data,uint32_t len,int version)1251 static void decode_RVAD(uint8_t *data, uint32_t len, int version)
1252 { /* ID3v220 used RVA, replaced with RVA2 in ID3v240 */
1253 uint8_t flags;
1254 uint8_t bits;
1255 uint8_t bytesperchannel;
1256 int i;
1257 print("Relative volume adjustment"); newline();
1258
1259 if (len < 2)
1260 {
1261 stack_message(STACK_ERROR, 0, "Frame too small");
1262 return;
1263 }
1264
1265 flags = data[0];
1266 bits = data[1];
1267 data+=2;
1268 len-=2;
1269
1270 if ((bits==0) || (bits > 64))
1271 {
1272 stack_message(STACK_ERROR, 0, "\"Bits used for volume descr.\" is out of range");
1273 return;
1274 }
1275 bytesperchannel = (bits + 7)>>3;
1276
1277 if (flags & 0x03)
1278 {
1279 if (len < (bytesperchannel * 2 * ( (!!(flags & 0x01)) + (!!(flags & 0x02)) ) ) )
1280 {
1281 stack_message(STACK_ERROR, 0, "Ran out of data");
1282 return;
1283 }
1284 if (flags & 0x01)
1285 {
1286 print(" Relative volume change, right: 0x");
1287 for (i=0; i < bytesperchannel; i++)
1288 {
1289 print("%02x", data[0]);
1290 data++;
1291 len--;
1292 }
1293 newline();
1294 }
1295 if (flags & 0x02)
1296 {
1297 print("Relative volume change, left: 0x");
1298 for (i=0; i < bytesperchannel; i++)
1299 {
1300 print("%02x", data[0]);
1301 data++;
1302 len--;
1303 }
1304 newline();
1305 }
1306 if (flags & 0x01)
1307 {
1308 print("Peak volume right: 0x");
1309 for (i=0; i < bytesperchannel; i++)
1310 {
1311 print("%02x", data[0]);
1312 data++;
1313 len--;
1314 }
1315 newline();
1316 }
1317 if (flags & 0x02)
1318 {
1319 print("Peak volume left: 0x");
1320 for (i=0; i < bytesperchannel; i++)
1321 {
1322 print("%02x", data[0]);
1323 data++;
1324 len--;
1325 }
1326 newline();
1327 }
1328 }
1329
1330 if (version < 3)
1331 {
1332 if (len)
1333 {
1334 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1335 }
1336 return;
1337 }
1338
1339 if (flags & 0x0c)
1340 {
1341 if (len < (bytesperchannel * 2 * ( (!!(flags & 0x08)) + (!!(flags & 0x04)) ) ) )
1342 {
1343 stack_message(STACK_ERROR, 0, "Ran out of data");
1344 return;
1345 }
1346 if (flags & 0x04)
1347 {
1348 print("Relative volume change, right back: 0x");
1349 for (i=0; i < bytesperchannel; i++)
1350 {
1351 print("%02x", data[0]);
1352 data++;
1353 len--;
1354 }
1355 newline();
1356 }
1357 if (flags & 0x08)
1358 {
1359 print("Relative volume change, left back: 0x");
1360 for (i=0; i < bytesperchannel; i++)
1361 {
1362 print("%02x", data[0]);
1363 data++;
1364 len--;
1365 }
1366 newline();
1367 }
1368 if (flags & 0x04)
1369 {
1370 print("Peak volume right back: 0x");
1371 for (i=0; i < bytesperchannel; i++)
1372 {
1373 print("%02x", data[0]);
1374 data++;
1375 len--;
1376 }
1377 newline();
1378 }
1379 if (flags & 0x08)
1380 {
1381 print("Peak volume left back: 0x");
1382 for (i=0; i < bytesperchannel; i++)
1383 {
1384 print("%02x", data[0]);
1385 data++;
1386 len--;
1387 }
1388 newline();
1389 }
1390 }
1391
1392 if (flags & 0x10)
1393 {
1394 if (len < (bytesperchannel * 2) )
1395 {
1396 stack_message(STACK_ERROR, 0, "Ran out of data");
1397 return;
1398 }
1399 print("Relative volume change, center: 0x");
1400 for (i=0; i < bytesperchannel; i++)
1401 {
1402 print("%02x", data[0]);
1403 data++;
1404 len--;
1405 }
1406 newline();
1407 print("Peak volume center: 0x");
1408 for (i=0; i < bytesperchannel; i++)
1409 {
1410 print("%02x", data[0]);
1411 data++;
1412 len--;
1413 }
1414 newline();
1415 }
1416
1417 if (flags & 0x20)
1418 {
1419 if (len < (bytesperchannel * 2) )
1420 {
1421 stack_message(STACK_ERROR, 0, "Ran out of data");
1422 return;
1423 }
1424 print("Relative volume change, bass: 0x");
1425 for (i=0; i < bytesperchannel; i++)
1426 {
1427 print("%02x", data[0]);
1428 data++;
1429 len--;
1430 }
1431 newline();
1432 print("Peak volume bass: 0x");
1433 for (i=0; i < bytesperchannel; i++)
1434 {
1435 print("%02x", data[0]);
1436 data++;
1437 len--;
1438 }
1439 newline();
1440 }
1441
1442 if (len)
1443 {
1444 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1445 }
1446 }
1447
decode_RVRB(uint8_t * data,uint32_t len)1448 static void decode_RVRB(uint8_t *data, uint32_t len)
1449 { /* ID3v220 used REV */
1450 print("Reverb"); newline();
1451
1452 if (len < 12)
1453 {
1454 stack_message(STACK_ERROR, 0, "Frame too small");
1455 return;
1456 }
1457
1458 print("Reverb left (ms) %d ms", (data[0]<<8)|data[1]); newline();
1459 print("Reverb right (ms) %d ms", (data[2]<<8)|data[3]); newline();
1460 print("Reverb bounces, left %d/255", data[4]); newline();
1461 print("Reverb bounces, right %d/255", data[5]); newline();
1462 print("Reverb feedback, left to left %d/255", data[6]); newline();
1463 print("Reverb feedback, left to right %d/255", data[7]); newline();
1464 print("Reverb feedback, right to right %d/255", data[8]); newline();
1465 print("Reverb feedback, right to left %d/255", data[9]); newline();
1466 print("Premix left to right %d/255", data[10]); newline();
1467 print("Premix right to left %d/255", data[11]); newline();
1468
1469 data+=12;
1470 len-=12;
1471
1472 if (len)
1473 {
1474 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1475 }
1476 }
1477
decode_RVA2(uint8_t * data,uint32_t len)1478 static void decode_RVA2(uint8_t *data, uint32_t len)
1479 {
1480 int error;
1481 print("Relative volume adjustment (2)"); newline();
1482
1483 print("Identification: ");
1484 error=decode_print_iso8859_1(&data, &len, 1);
1485 newline();
1486 if (error)
1487 {
1488 return;
1489 }
1490
1491 while (len > 4)
1492 {
1493 uint16_t peakvolume = 0;
1494 switch (data[0])
1495 {
1496 case 0x00: print("Type of channel: Other"); break;
1497 case 0x01: print("Type of channel: Master volume"); break;
1498 case 0x02: print("Type of channel: Front right"); break;
1499 case 0x03: print("Type of channel: Front left"); break;
1500 case 0x04: print("Type of channel: Back right"); break;
1501 case 0x05: print("Type of channel: Back left"); break;
1502 case 0x06: print("Type of channel: Front centre"); break;
1503 case 0x07: print("Type of channel: Back centre"); break;
1504 case 0x08: print("Type of channel: Subwooder"); break;
1505 default: print("Type of channel: (%d) Unknown", data[0]); break;
1506 }
1507 newline();
1508
1509 print("Volume adjustment: %d", (data[1]<<8)|data[2]); newline();
1510 print("Bits representing peak: %d", data[3]); newline();
1511 data+=4;
1512 len-=4;
1513 while (data[0] == 0xff)
1514 {
1515 if (!len)
1516 {
1517 stack_message(STACK_ERROR, 0, "Ran out of data");
1518 return;
1519 }
1520 peakvolume+=data[0];
1521 data++;
1522 len--;
1523 }
1524 if (!len)
1525 {
1526 stack_message(STACK_ERROR, 0, "Ran out of data");
1527 return;
1528 }
1529 peakvolume+=data[0];
1530 data++;
1531 len--;
1532 print("Peak volume: %" PRId16, peakvolume); newline();
1533 }
1534
1535 if (len)
1536 {
1537 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1538 }
1539 }
1540
decode_POPM(uint8_t * data,uint32_t len)1541 static void decode_POPM(uint8_t *data, uint32_t len)
1542 { /* ID3v220 used POP */
1543 int error;
1544 print("Popularimeter");
1545
1546 if (!len)
1547 {
1548 stack_message(STACK_ERROR, 0, "Frame too small");
1549 newline();
1550 return;
1551 }
1552
1553 print("Email to user: ");
1554 error=decode_print_iso8859_1 (&data, &len, 1);
1555 newline();
1556 if (error)
1557 {
1558 return;
1559 }
1560
1561 if (!len)
1562 {
1563 stack_message(STACK_ERROR, 0, "No space for rating");
1564 return;
1565 }
1566 if (*data)
1567 {
1568 print("Rating: %d", *data);
1569 } else {
1570 print("Rating: unknown");
1571 }
1572 newline();
1573 data++;
1574 len--;
1575
1576 if (!len)
1577 {
1578 print("Counter: omitted");
1579 } else {
1580 uint64_t counter = 0;
1581 while (len)
1582 {
1583 counter<<=8;
1584 counter |= *data;
1585 data++;
1586 len--;
1587 }
1588 print("Counter: %"PRId64, counter);
1589 }
1590 newline();
1591 }
1592
decode_LINK(uint8_t * data,uint32_t len)1593 static void decode_LINK(uint8_t *data, uint32_t len)
1594 { /* ID3v220 used LEN */
1595 int error;
1596 print("Link"); newline();
1597
1598 if (!len)
1599 {
1600 stack_message(STACK_ERROR, 0, "Frame too small");
1601 return;
1602 }
1603
1604 print("URL: ");
1605 error = decode_print_iso8859_1 (&data, &len, 1);
1606 newline();
1607 if (error)
1608 {
1609 return;
1610 }
1611
1612 print(" ID and additional data: "); /* we are laxed on the last zero here */
1613 error=decode_print_iso8859_1 (&data, &len, 0);
1614 newline();
1615 if (error)
1616 {
1617 return;
1618 }
1619
1620 if (len)
1621 {
1622 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1623 }
1624 }
1625
decode_PCNT(uint8_t * data,uint32_t len)1626 static void decode_PCNT(uint8_t *data, uint32_t len)
1627 { /* ID3v220 used CNT */
1628 uint64_t counter = 0;
1629 print("Play Counter");
1630
1631 while (len)
1632 {
1633 counter<<=8;
1634 counter |= *data;
1635 data++;
1636 len--;
1637 }
1638 print(" - Counter: %"PRId64, counter);
1639 newline();
1640 }
1641
decode_AENC(uint8_t * data,uint32_t len)1642 static void decode_AENC(uint8_t *data, uint32_t len)
1643 { /* ID3v220 used CRA */
1644 int error;
1645 print("Audio encryption"); newline();
1646
1647 print("Owner identifier: ");
1648 error = decode_print_iso8859_1 (&data, &len, 1);
1649 newline();
1650 if (error)
1651 {
1652 return;
1653 }
1654 if (len < 4)
1655 {
1656 stack_message(STACK_ERROR, 0, "Ran out of data");
1657 return;
1658 }
1659 print("Preview start: %d MPEG frames", (data[0]<<8)|data[1]); newline();
1660 print("Preview length: %d MPEG frames", (data[2]<<8)|data[3]); newline();
1661 print("Encryption info: 0x");
1662 data+=4;
1663 len-=4;
1664 while (len)
1665 {
1666 print("%02x", data[0]);
1667 data++;
1668 len--;
1669 }
1670 newline();
1671 }
1672
decode_COMM(uint8_t * data,uint32_t len,int version)1673 static void decode_COMM(uint8_t *data, uint32_t len, int version)
1674 { /* ID3v220 used COM */
1675 uint8_t text_encoding;
1676 int error;
1677 print("Comments"); newline();
1678
1679 if (len < 4)
1680 {
1681 stack_message(STACK_ERROR, 0, "Frame too small");
1682 return;
1683 }
1684
1685 text_encoding = data[0];
1686 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1687 {
1688 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1689 return;
1690 }
1691 if ((data[1]<0x20)||(data[1]>=0x80)||
1692 (data[2]<0x20)||(data[2]>=0x80)||
1693 (data[3]<0x20)||(data[3]>=0x80))
1694 {
1695 print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1696 } else {
1697 print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1698 }
1699 newline();
1700
1701 data+=4;
1702 len-=4;
1703
1704 print("Content-Descriptor: ");
1705 switch (text_encoding)
1706 {
1707 case 0x00:
1708 print("LATIN1 ");
1709 error=decode_print_iso8859_1 (&data, &len, 1);
1710 break;
1711 case 0x01:
1712 print("UCS2 ");
1713 error=decode_print_UCS2 (&data, &len, 1, 1);
1714 break;
1715 case 0x02:
1716 print("UTF-16 ");
1717 error=decode_print_UTF16 (&data, &len, 1);
1718 break;
1719 case 0x03:
1720 print("UTF-8 ");
1721 error=decode_print_UTF8 (&data, &len, 1);
1722 break;
1723 }
1724 newline();
1725 if (error)
1726 {
1727 return;
1728 }
1729 print("Comment/text: ");
1730 switch (text_encoding)
1731 {
1732 case 0x00:
1733 print("LATIN1 "); /* we are laxed on require NL here */
1734 error=decode_print_iso8859_1 (&data, &len, 0);
1735 break;
1736 case 0x01:
1737 print("UCS2 ");
1738 error=decode_print_UCS2 (&data, &len, 0, 0);
1739 break;
1740 case 0x02:
1741 print("UTF-16 ");
1742 error=decode_print_UTF16 (&data, &len, 0);
1743 break;
1744 case 0x03:
1745 print("UTF-8 ");
1746 error=decode_print_UTF8 (&data, &len, 0);
1747 break;
1748 }
1749 newline();
1750 if (error)
1751 {
1752 return;
1753 }
1754
1755 if (len)
1756 {
1757 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1758 }
1759 }
1760
decode_PRIV(uint8_t * data,uint32_t len)1761 static void decode_PRIV(uint8_t *data, uint32_t len)
1762 { /* ID3v220 used COM */
1763 int error;
1764 print("Private"); newline();
1765
1766 print("Owner identifier:");
1767 error=decode_print_iso8859_1 (&data, &len, 1);
1768 newline();
1769 if (error)
1770 {
1771 return;
1772 }
1773
1774 print("The private data: 0x");
1775 while (len)
1776 {
1777 print("%02x", data[0]);
1778 data++;
1779 len--;
1780 }
1781 newline();
1782 }
1783
1784
decode_USER(uint8_t * data,uint32_t len,int version)1785 static void decode_USER(uint8_t *data, uint32_t len, int version)
1786 {
1787 int error;
1788 uint8_t text_encoding;
1789 print("Terms of use"); newline();
1790
1791 if (len < 4)
1792 {
1793 stack_message(STACK_ERROR, 0, "Frame too small");
1794 return;
1795 }
1796
1797 text_encoding = data[0];
1798 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1799 {
1800 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1801 return;
1802 }
1803 if ((data[1]<0x20)||(data[1]>=0x80)||
1804 (data[2]<0x20)||(data[2]>=0x80)||
1805 (data[3]<0x20)||(data[3]>=0x80))
1806 {
1807 print("language is invalid 0x%02x 0x%02x 0x%02x", data[1], data[2], data[3]);
1808 } else {
1809 print("language: \"%c%c%c\"", data[1], data[2], data[3]);
1810 }
1811 newline();
1812 data+=4;
1813 len-=4;
1814
1815 print("text: ");
1816 switch (text_encoding)
1817 {
1818 case 0x00:
1819 print("LATIN1 "); /* we are laxed on require NL here */
1820 error = decode_print_iso8859_1 (&data, &len, 0);
1821 break;
1822 case 0x01:
1823 print("UCS2 ");
1824 error = decode_print_UCS2 (&data, &len, 0, 1);
1825 break;
1826 case 0x02:
1827 print("UTF-16 ");
1828 error=decode_print_UTF16 (&data, &len, 0);
1829 break;
1830 case 0x03:
1831 print("UTF-8 ");
1832 error=decode_print_UTF8 (&data, &len, 0);
1833 break;
1834 }
1835 newline();
1836 if (error)
1837 {
1838 return;
1839 }
1840
1841 if (len)
1842 {
1843 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
1844 }
1845 }
1846
decode_COMR(uint8_t * data,uint32_t len,int version)1847 static void decode_COMR(uint8_t *data, uint32_t len, int version)
1848 {
1849 int error;
1850 uint8_t text_encoding;
1851 print("Commercial frame"); newline();
1852
1853 if (len < 4)
1854 {
1855 stack_message(STACK_ERROR, 0, "Frame too small");
1856 return;
1857 }
1858
1859 text_encoding = data[0];
1860 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
1861 {
1862 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
1863 return;
1864 }
1865
1866 print("Price string: ");
1867 error = decode_print_iso8859_1 (&data, &len, 1);
1868 newline();
1869 if (error)
1870 {
1871 return;
1872 }
1873
1874 if (len < 8)
1875 {
1876 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Valid until\"");
1877 return;
1878 }
1879 print("Valid Until: \"%c%c%c%c%c%c%c%c\"", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); newline();
1880 data+=8;
1881 len-=8;
1882
1883 print("Contact URL: ");
1884 error = decode_print_iso8859_1 (&data, &len, 1);
1885 newline();
1886 if (error)
1887 {
1888 return;
1889 }
1890
1891 if (len < 1)
1892 {
1893 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Received as\"");
1894 return;
1895 }
1896 switch (data[0])
1897 {
1898 case 0x00: print("Received as: Other"); break;
1899 case 0x01: print("Received as: Standard CD album with other songs"); break;
1900 case 0x02: print("Received as: Compressed audio on CD"); break;
1901 case 0x03: print("Received as: File over the Internet"); break;
1902 case 0x04: print("Received as: Stream over the Internet"); break;
1903 case 0x05: print("Received as: As note sheets"); break;
1904 case 0x06: print("Received as: As note sheets in a book with other sheets"); break;
1905 case 0x07: print("Received as: Music on other media"); break;
1906 case 0x08: print("Received as: Non-musical merchandise"); break;
1907 default: print("Received as: (%d)Unknown", data[0]); break;
1908 }
1909 newline();
1910 data++;
1911 len--;
1912
1913
1914 print("name of seller: ");
1915 switch (text_encoding)
1916 {
1917 case 0x00:
1918 print("LATIN1 ");
1919 error = decode_print_iso8859_1 (&data, &len, 1);
1920 break;
1921 case 0x01:
1922 print("UCS2 ");
1923 error = decode_print_UCS2 (&data, &len, 1, 1);
1924 break;
1925 case 0x02:
1926 print("UTF-16 ");
1927 error = decode_print_UTF16 (&data, &len, 1);
1928 break;
1929 case 0x03:
1930 print("UTF-8 ");
1931 error = decode_print_UTF8 (&data, &len, 1);
1932 break;
1933 }
1934 newline();
1935 if (error)
1936 {
1937 return;
1938 }
1939
1940 print("Description: ");
1941 switch (text_encoding)
1942 {
1943 case 0x00:
1944 print("LATIN1 "); /* we are laxed on require NL here */
1945 error = decode_print_iso8859_1 (&data, &len, 0);
1946 break;
1947 case 0x01:
1948 print("UCS2 ");
1949 error = decode_print_UCS2 (&data, &len, 0, 0);
1950 break;
1951 case 0x02:
1952 print("UTF-16 ");
1953 error = decode_print_UTF16 (&data, &len, 0);
1954 break;
1955 case 0x03:
1956 print("UTF-8 ");
1957 error = decode_print_UTF8 (&data, &len, 0);
1958 break;
1959 }
1960 newline();
1961 if (error)
1962 {
1963 return;
1964 }
1965
1966 if (!len)
1967 {
1968 print("(Picture data omitted)"); newline();
1969 return;
1970 }
1971
1972 print("Picture MIME type: ");
1973 error = decode_print_iso8859_1 (&data, &len, 1);
1974 newline();
1975 if (error)
1976 {
1977 return;
1978 }
1979 print("Seller logo: 0x");
1980 while (len)
1981 {
1982 print("%02x", data[0]);
1983 data++;
1984 len--;
1985 }
1986 newline();
1987 }
1988
decode_OWNE(uint8_t * data,uint32_t len,int version)1989 static void decode_OWNE(uint8_t *data, uint32_t len, int version)
1990 {
1991 int error;
1992 uint8_t text_encoding;
1993 print("Ownership"); newline();
1994
1995 if (len < 4)
1996 {
1997 stack_message(STACK_ERROR, 0, "Frame too small");
1998 return;
1999 }
2000
2001 text_encoding = data[0];
2002 if (((text_encoding >= 2) && (version < 4)) || (text_encoding >= 4))
2003 {
2004 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2005 return;
2006 }
2007
2008 print("Price Payed: ");
2009 error = decode_print_iso8859_1 (&data, &len, 1);
2010 newline();
2011 if (error)
2012 {
2013 return;
2014 }
2015
2016 if (len < 8)
2017 {
2018 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Date of purchase\"");
2019 return;
2020 }
2021 print("Date of purchase: \"%c%c%c%c%c%c%c%c\"", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); newline();
2022 data+=8;
2023 len-=8;
2024
2025 print("Seller: ");
2026 switch (text_encoding)
2027 {
2028 case 0x00:
2029 print(" LATIN1 "); /* we are laxed on require NL here */
2030 error = decode_print_iso8859_1 (&data, &len, 0);
2031 break;
2032 case 0x01:
2033 print(" UCS2 ");
2034 error = decode_print_UCS2 (&data, &len, 0, 1);
2035 break;
2036 case 0x02:
2037 print(" UTF-16 ");
2038 error = decode_print_UTF16 (&data, &len, 0);
2039 break;
2040 case 0x03:
2041 print(" UTF-8 ");
2042 error = decode_print_UTF8 (&data, &len, 0);
2043 break;
2044 }
2045 newline();
2046 if (error)
2047 {
2048 return;
2049 }
2050
2051 if (len)
2052 {
2053 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2054 }
2055 }
2056
decode_GRID(uint8_t * data,uint32_t len)2057 static void decode_GRID(uint8_t *data, uint32_t len)
2058 {
2059 int error;
2060
2061 print("Group ID registration"); newline();
2062
2063 print("Owner identifier: ");
2064 error = decode_print_iso8859_1 (&data, &len, 1);
2065 newline();
2066 if (error)
2067 {
2068 return;
2069 }
2070
2071 if (!len)
2072 {
2073 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2074 return;
2075 }
2076 print("Group symbol: 0x%02x", data[0]); newline();
2077 data++;
2078 len--;
2079 print("Group dependent data: 0x");
2080 while (len)
2081 {
2082 print("%02x", data[0]);
2083 data++;
2084 len--;
2085 }
2086 newline();
2087 }
2088
decode_ENCR(uint8_t * data,uint32_t len)2089 static void decode_ENCR(uint8_t *data, uint32_t len)
2090 {
2091 int error;
2092 print("Encryption method registration"); newline();
2093
2094 print("Owner identifier: ");
2095 error = decode_print_iso8859_1 (&data, &len, 1);
2096 newline();
2097 if (error)
2098 {
2099 return;
2100 }
2101
2102 if (!len)
2103 {
2104 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2105 return;
2106 }
2107 print("Method symbol: 0x%02x", data[0]); newline();
2108 data++;
2109 len--;
2110
2111 print("Encryption data: 0x");
2112 while (len)
2113 {
2114 print("%02x", data[0]);
2115 data++;
2116 len--;
2117 }
2118 newline();
2119 }
2120
decode_SIGN(uint8_t * data,uint32_t len)2121 static void decode_SIGN(uint8_t *data, uint32_t len)
2122 {
2123 print("Signature"); newline();
2124 if (!len)
2125 {
2126 stack_message(STACK_ERROR, 0, "Frame too small to contain field \"Group symbol\"");
2127 return;
2128 }
2129
2130 print("Group symbol: 0x%02x", data[0]); newline();
2131 data++;
2132 len--;
2133
2134 print("Signature data: 0x");
2135 while (len)
2136 {
2137 print("%02x", data[0]);
2138 data++;
2139 len--;
2140 }
2141 newline();
2142 }
2143
decode_CRM(uint8_t * data,uint32_t len)2144 static void decode_CRM(uint8_t *data, uint32_t len)
2145 { /* ID3v220 only */
2146 int error;
2147 print("Encrypted meta frame"); newline();
2148
2149 print(" Owner identifier: ");
2150 error = decode_print_iso8859_1 (&data, &len, 1);
2151 newline();
2152
2153 if (error)
2154 {
2155 return;
2156 }
2157
2158 print("Content/explanation: ");
2159 error = decode_print_iso8859_1 (&data, &len, 1);
2160 newline();
2161
2162 if (error)
2163 {
2164 return;
2165 }
2166
2167 print("Content: 0x");
2168 while (len)
2169 {
2170 print("%02x", data[0]);
2171 data++;
2172 len--;
2173 }
2174 newline();
2175 }
2176
decode_APIC(uint8_t * data,uint32_t len,int version)2177 static void decode_APIC(uint8_t *data, uint32_t len, int version)
2178 { /* ID3v220 used PIC */
2179 uint8_t text_encoding;
2180 int error;
2181
2182 print("Attached picture"); newline();
2183
2184 if (len < 1)
2185 {
2186 stack_message(STACK_ERROR, 0, "No space for \"text_encoding\"");
2187 return;
2188 }
2189
2190 text_encoding = data[0];
2191 data++;
2192 len--;
2193
2194 if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2195 {
2196 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2197 return;
2198 }
2199
2200 if (version <= 2)
2201 {
2202 if (len<3)
2203 {
2204 stack_message(STACK_ERROR, 0, "No space for \"Image format\"");
2205 return;
2206 }
2207 print("Image format: \"%c%c%c\"", data[0], data[1], data[2]);newline();
2208 len+=3;
2209 } else {
2210 int error;
2211 print("MIME/type: ");
2212 error = decode_print_iso8859_1(&data, &len, 1); newline();
2213 if (error)
2214 {
2215 return;
2216 }
2217 }
2218
2219 if (len < 1)
2220 {
2221 stack_message(STACK_ERROR, 0, "No space for \"Picture Type\"");
2222 return;
2223 }
2224 switch (data[0])
2225 {
2226 case 0x00: print("Picture type: Other"); break;
2227 case 0x01: print("Picture type: 32x32 pixels 'file icon' (PNG only)"); break;
2228 case 0x02: print("Picture type: Other file icon"); break;
2229 case 0x03: print("Picture type: Cover (front)"); break;
2230 case 0x04: print("Picture type: Cover (back)"); break;
2231 case 0x05: print("Picture type: Leaflet page"); break;
2232 case 0x06: print("Picture type: Media (e.g. lable side of CD)"); break;
2233 case 0x07: print("Picture type: Lead artist/lead performer/soloist"); break;
2234 case 0x08: print("Picture type: Artist/performer"); break;
2235 case 0x09: print("Picture type: Conductor"); break;
2236 case 0x0A: print("Picture type: Band/Orchestra"); break;
2237 case 0x0B: print("Picture type: Composer"); break;
2238 case 0x0C: print("Picture type: Lyricist/text writer"); break;
2239 case 0x0D: print("Picture type: Recording Location"); break;
2240 case 0x0E: print("Picture type: During recording"); break;
2241 case 0x0F: print("Picture type: During performance"); break;
2242 case 0x10: print("Picture type: Movie/video screen capture"); break;
2243 case 0x11: print("Picture type: A bright coloured fish"); break;
2244 case 0x12: print("Picture type: Illustration"); break;
2245 case 0x13: print("Picture type: Band/artist logotype"); break;
2246 case 0x14: print("Picture type: Publisher/Studio logotype"); break;
2247 default: print("Picture type: (%d)unknown", data[0]); break;
2248 }
2249 newline();
2250 data++;
2251 len--;
2252
2253 print("Description: ");
2254 switch (text_encoding)
2255 {
2256 case 0x00:
2257 print("LATIN1 ");
2258 error = decode_print_iso8859_1(&data, &len, 1);
2259 break;
2260 case 0x01:
2261 print("UCS-2 ");
2262 error = decode_print_UCS2(&data, &len, 1, 1);
2263 break;
2264 case 0x02:
2265 print("UTF-16 ");
2266 error = decode_print_UTF16(&data, &len, 1);
2267 break;
2268 case 0x03:
2269 print("UTF-8 ");
2270 error = decode_print_UTF8(&data, &len, 1);
2271 break;
2272 }
2273 newline();
2274 if (error)
2275 {
2276 return;
2277 }
2278 print("Picture data: 0x");
2279 while (len)
2280 {
2281 print("%02x", data[0]);
2282 data++;
2283 len--;
2284 }
2285 newline();
2286 }
2287
decode_T(const char * description,uint8_t * data,uint32_t len,int version)2288 static void decode_T(const char *description, uint8_t *data, uint32_t len, int version)
2289 {
2290 int added = 0;
2291 int first = 1;
2292 uint8_t text_encoding;
2293
2294 print("\"%-60s\" ", description);
2295
2296 if (len < 1)
2297 {
2298 stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2299 return;
2300 }
2301
2302 text_encoding = data[0];
2303 data++;
2304 len--;
2305
2306 if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2307 {
2308 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2309 newline();
2310 }
2311
2312 while (1)
2313 {
2314 int error = 1;
2315 switch (text_encoding)
2316 {
2317 case 0x00:
2318 print("LATIN1 ");
2319 error = decode_print_iso8859_1(&data, &len, 0);
2320 break;
2321 case 0x01:
2322 print("UCS-2 ");
2323 error = decode_print_UCS2(&data, &len, 0, first);
2324 break;
2325 case 0x02:
2326 print("UTF-16 ");
2327 error = decode_print_UTF16(&data, &len, 0);
2328 break;
2329 case 0x03:
2330 print("UTF-8 ");
2331 error = decode_print_UTF8(&data, &len, 0);
2332 break;
2333 }
2334 newline();
2335 if (error || (!len))
2336 {
2337 indent -= added;
2338 return;
2339 }
2340 if (version < 4)
2341 {
2342 if (len)
2343 {
2344 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2345 }
2346 indent -= added;
2347 return;
2348 }
2349 if (first)
2350 {
2351 first=0;
2352 added=10;
2353 indent+=added;
2354 }
2355 }
2356 }
2357
decode_TXXX(uint8_t * data,uint32_t len,int version)2358 static void decode_TXXX(uint8_t *data, uint32_t len, int version)
2359 {
2360 int error;
2361 uint8_t text_encoding;
2362 print("Private text");
2363
2364 if (len < 1)
2365 {
2366 stack_message(STACK_ERROR, 0 , "No space for \"Text encoding\"");
2367 return;
2368 }
2369
2370 text_encoding = data[0];
2371 data++;
2372 len--;
2373
2374 if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2375 {
2376 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2377 return;
2378 }
2379
2380 switch (text_encoding)
2381 {
2382 case 0x00:
2383 print("LATIN1 ");
2384 error=decode_print_iso8859_1(&data, &len, 1);
2385 break;
2386 case 0x01:
2387 print("UCS-2 ");
2388 error=decode_print_UCS2(&data, &len, 1, 1);
2389 break;
2390 case 0x02:
2391 print("UTF-16 ");
2392 error=decode_print_UTF16(&data, &len, 1);
2393 break;
2394 case 0x03:
2395 print("UTF-8 ");
2396 error=decode_print_UTF8(&data, &len, 1);
2397 break;
2398 }
2399 if (error)
2400 {
2401 newline();
2402 return;
2403 }
2404 print(" = ");
2405 switch (text_encoding)
2406 {
2407 case 0x00:
2408 print("LATIN1 ");
2409 error = decode_print_iso8859_1(&data, &len, 0);
2410 break;
2411 case 0x01:
2412 print("UCS-2 ");
2413 error = decode_print_UCS2(&data, &len, 0, 0);
2414 break;
2415 case 0x02:
2416 print("UTF-16 ");
2417 error = decode_print_UTF16(&data, &len, 0);
2418 break;
2419 case 0x03:
2420 print("UTF-8 ");
2421 error = decode_print_UTF8(&data, &len, 0);
2422 break;
2423 }
2424 newline();
2425 if (error)
2426 {
2427 return;
2428 }
2429 if (len)
2430 {
2431 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2432 }
2433 }
2434
decode_W(const char * description,uint8_t * data,uint32_t len)2435 static void decode_W(const char *description, uint8_t *data, uint32_t len)
2436 {
2437 print("\"%s\" ", description);
2438
2439 decode_print_iso8859_1(&data, &len, 0);
2440 newline();
2441
2442 if (len)
2443 {
2444 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2445 }
2446 }
2447
decode_WXXX(uint8_t * data,uint32_t len,int version)2448 static void decode_WXXX(uint8_t *data, uint32_t len, int version)
2449 {
2450 int error;
2451 uint8_t text_encoding;
2452 print("Private URL");
2453 newline();
2454
2455 if (len < 1)
2456 {
2457 stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2458 return;
2459 }
2460
2461 text_encoding = data[0];
2462 data++;
2463 len--;
2464
2465 if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2466 {
2467 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2468 return;
2469 }
2470
2471 switch (text_encoding)
2472 {
2473 case 0x00:
2474 print("LATIN1 ");
2475 error=decode_print_iso8859_1(&data, &len, 1);
2476 break;
2477 case 0x01:
2478 print("UCS-2 ");
2479 error=decode_print_UCS2(&data, &len, 1, 1);
2480 return;
2481 case 0x02:
2482 print("UTF-16 ");
2483 error=decode_print_UTF16(&data, &len, 1);
2484 break;
2485 case 0x03:
2486 print("UTF-8 ");
2487 error=decode_print_UTF8(&data, &len, 1);
2488 break;
2489 }
2490 if (error)
2491 {
2492 newline();
2493 return;
2494 }
2495 print(" = ");
2496 error = decode_print_iso8859_1(&data, &len, 0);
2497 newline();
2498 if (error)
2499 {
2500 return;
2501 }
2502
2503 if (len)
2504 {
2505 stack_message(STACK_WARNING, 0, "Some extra padding in the frame");
2506 }
2507 }
2508
decode_Tn(const char * description,uint8_t * data,uint32_t len,int version)2509 static void decode_Tn(const char *description, uint8_t *data, uint32_t len, int version)
2510 {
2511 uint8_t text_encoding;
2512 int first = 1;
2513 print("%s", description);
2514
2515 if (len < 1)
2516 {
2517 stack_message(STACK_ERROR, 0, "No space for \"Text encoding\"");
2518 newline();
2519 return;
2520 }
2521
2522 text_encoding = data[0];
2523 data++;
2524 len--;
2525
2526 if ((text_encoding >= 2 && version < 4) || (text_encoding >= 4))
2527 {
2528 stack_message(STACK_ERROR, 0, "Text_encoding out of range");
2529 newline();
2530 }
2531
2532 switch (text_encoding)
2533 {
2534 case 0x00:
2535 print(" LATIN1");
2536 newline();
2537 while (len)
2538 {
2539 int error = decode_print_iso8859_1(&data, &len, 0);
2540 newline();
2541 if (error)
2542 {
2543 return;
2544 }
2545 }
2546 return;
2547 case 0x01:
2548 print(" UCS-2");
2549 newline();
2550 while (len)
2551 {
2552 int error=decode_print_UCS2(&data, &len, 0, first);
2553 newline();
2554 if (error)
2555 {
2556 return;
2557 }
2558 first=0;
2559 }
2560 return;
2561 case 0x02:
2562 print(" UTF-16");
2563 newline();
2564 while (len)
2565 {
2566 int error = decode_print_UTF16(&data, &len, 0);
2567 newline();
2568 if (error)
2569 {
2570 return;
2571 }
2572 }
2573 return;
2574 case 0x03:
2575 print(" UTF-8");
2576 newline();
2577 while (len)
2578 {
2579 int error = decode_print_UTF8(&data, &len, 0);
2580 newline();
2581 if (error)
2582 {
2583 return;
2584 }
2585 }
2586 return;
2587 }
2588 }
2589
zalloc(void * q,unsigned int n,unsigned m)2590 static void *zalloc(void *q, unsigned int n, unsigned m)
2591 {
2592 (void)q;
2593 return calloc(n, m);
2594 }
2595
zfree(void * q,void * p)2596 static void zfree(void *q, void *p)
2597 {
2598 (void)q;
2599 free(p);
2600 }
2601
decode_id3v240_frame(uint8_t * ptr,uint32_t len)2602 static int32_t decode_id3v240_frame(uint8_t *ptr, uint32_t len)
2603 {
2604 uint8_t FrameId[4];
2605 uint32_t inputsize;
2606 uint8_t *frameptr, *zlibptr=0;
2607 uint32_t framelen;
2608 uint32_t zlib_new_framelen=0xffffff;
2609 uint16_t flags;
2610
2611 if (len < 11)
2612 {
2613 print("*-*-* ERROR, Minimum frame length is 11 bytes"); newline();
2614 return -1;
2615 }
2616
2617 FrameId[0] = ptr[0];
2618 FrameId[1] = ptr[1];
2619 FrameId[2] = ptr[2];
2620 FrameId[3] = ptr[3];
2621
2622 if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
2623 (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
2624 (FrameId[2] < 0x20) || (FrameId[2] >= 0x80) ||
2625 (FrameId[3] < 0x20) || (FrameId[3] >= 0x80))
2626 {
2627 print("Invalid frame ID %02x %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2], FrameId[3]); newline();
2628 return -1;
2629 }
2630
2631 flags = (ptr[8]<<8)|(ptr[9]);
2632
2633 if ((ptr[4] & 0x80) |
2634 (ptr[5] & 0x80) |
2635 (ptr[6] & 0x80) |
2636 (ptr[7] & 0x80))
2637 {
2638 stack_message(STACK_WARNING, 0, "Framelength not valid not valid %02x %02x %02x %02x, trying to use 2.3.0 syntax", ptr[4], ptr[5], ptr[6], ptr[7]);
2639 framelen = inputsize = (ptr[4]<<24)|(ptr[5]<<16)|(ptr[6]<<8)|ptr[7]; /* attempt to ressurect broken FRAME, iTunes of some version*/
2640 } else {
2641 framelen = inputsize = (ptr[4]<<21)|(ptr[5]<<14)|(ptr[6]<<7)|ptr[7];
2642 }
2643 frameptr = ptr + 10;
2644 len-=10;
2645
2646 print("Frame %c%c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], FrameId[3], inputsize);
2647 indent++;
2648
2649 if (inputsize > len)
2650 {
2651 stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", inputsize - len);
2652 newline();
2653 indent--;
2654 return -1;
2655 }
2656
2657 print("FLAGS=0x%04"PRIx16" ", flags);
2658
2659 /* part-1, parse header */
2660 #if 0
2661 /* these are very noisy to see */
2662 if (flags & 0x4000) printf (" Tag alter preservation: Frame should be discarded.\n"); else printf (" Tag alter preservation: Frame should be preserved.\n");
2663 if (flags & 0x2000) printf (" File alter preservation: Frame should be discarded.\n"); else printf (" File alter preservation: Frame should be preserved.\n");
2664 if (flags & 0x1000) printf (" Frame is Read only\n"); else printf (" Frame is Read/Write\n");
2665 #endif
2666
2667 if (flags & 0x0008)
2668 {
2669 if (!(flags & 0x0001))
2670 {
2671 stack_message(STACK_ERROR, 0, "Compression flag set, without data length indicicator");
2672 newline();
2673 goto ignoreframe;
2674 }
2675 }
2676 if (flags & 0x0004)
2677 {
2678 uint8_t method;
2679 if (framelen < 1)
2680 {
2681 stack_message(STACK_ERROR, 0, "*-*-* ERROR, Encryption set, but no space for method field");
2682 } else {
2683 method = frameptr[0];
2684 frameptr++;
2685 framelen--;
2686 stack_message(STACK_INFO, 0, "Frame is encrypted (method %d), ignoring it", method);
2687 }
2688 newline();
2689 goto ignoreframe;
2690 }
2691 if (flags & 0x0040)
2692 {
2693 if (framelen < 1)
2694 {
2695 stack_message(STACK_WARNING, 0, "Grouping set, but no space for Frame grouping information");
2696 } else {
2697 stack_message(STACK_INFO, 0, "Frame is grouped with ID=%d", frameptr[0]);
2698 frameptr++;
2699 framelen--;
2700 }
2701 }
2702 if (flags & 0x0002)
2703 {
2704 stack_message(STACK_INFO, 0, "Frame is unsynced");
2705 unsync (frameptr, &framelen);
2706 }
2707
2708 if (framelen == 0)
2709 {
2710 stack_message(STACK_ERROR, 0, "Frame with zero-length");
2711 flush();
2712 indent--;
2713 return -1;
2714 }
2715
2716 if (flags & 0x0001)
2717 {
2718 uint32_t temp;
2719
2720 if (framelen < 4)
2721 {
2722 stack_message(STACK_ERROR, 0, "Data-Length-Indicator set, but no space for outputsize field (skipping to next frame)");
2723 newline();
2724 goto ignoreframe;
2725 }
2726
2727 temp = (frameptr[0]<<21)|(frameptr[1]<<14)|(frameptr[2]<<7)|frameptr[3];
2728 frameptr+=4;
2729 framelen-=4;
2730
2731 if (flags & 0x0008)
2732 {
2733 if (temp > 32*1024*1024)
2734 {
2735 stack_message(STACK_WARNING, 0, "Decompression bigger than 32MB, blocking it");
2736 newline();
2737 goto ignoreframe;
2738 }
2739 zlib_new_framelen = temp;
2740 if (!zlib_new_framelen)
2741 {
2742 stack_message(STACK_ERROR, 0, "Decompression size of zero bytes");
2743 newline();
2744 goto ignoreframe;
2745 }
2746 } else {
2747 if (temp > framelen)
2748 {
2749 stack_message(STACK_WARNING, 0, "Data-Length-Indicator overshots the original framelen");
2750 } else {
2751 stack_message(STACK_INFO, 0, "framelen forcefully set from % " PRId32 " to %" PRId32 " bytes", framelen, temp);
2752 framelen = temp;
2753 }
2754 }
2755 }
2756 /* part-2 fix the data*/
2757 if (flags & 0x0008)
2758 {
2759 int result;
2760
2761 z_stream strm;
2762 zlibptr = malloc (zlib_new_framelen);
2763
2764 strm.zalloc = zalloc;
2765 strm.zfree = zfree;
2766 strm.opaque = (voidpf)0;
2767 strm.avail_in = framelen;
2768 strm.next_in = frameptr;
2769 strm.avail_out = zlib_new_framelen;
2770 strm.next_out = zlibptr;
2771 stack_message(STACK_INFO, 0, "Frame is compressed (inputsize=%" PRId32 ", outputsize=%" PRId32 ")", framelen, zlib_new_framelen);
2772
2773 if (inflateInit(&strm))
2774 {
2775 stack_message(STACK_ERROR, 0, "Zlib failed to init");
2776 newline();
2777 goto ignoreframe;
2778 }
2779 result = inflate(&strm, Z_FINISH);
2780 if (result == Z_STREAM_ERROR ||
2781 result == Z_NEED_DICT ||
2782 result == Z_DATA_ERROR ||
2783 result == Z_MEM_ERROR)
2784 {
2785 stack_message(STACK_ERROR, 0, "Zlib failed to decompress");
2786 if (result != Z_STREAM_ERROR)
2787 {
2788 inflateEnd (&strm);
2789 }
2790 newline();
2791 goto ignoreframe;
2792 }
2793 if (strm.avail_in != 0)
2794 {
2795 stack_message(STACK_WARNING, 0, "Zlib did not consume the entire input, %d bytes left", (int)strm.avail_in);
2796 }
2797 if (strm.avail_out != 0)
2798 {
2799 stack_message(STACK_WARNING, 0, "Zlib did not fill the entire output, %d bytes left", (int)strm.avail_out);
2800 memset (strm.next_out, 0, strm.avail_out);
2801 }
2802 inflateEnd (&strm);
2803 frameptr = zlibptr;
2804 framelen = zlib_new_framelen;
2805 }
2806
2807 indent++;
2808
2809 if (!memcmp(FrameId, "AENC", 4)) decode_AENC( frameptr, framelen);
2810 else if (!memcmp(FrameId, "APIC", 4)) decode_APIC( frameptr, framelen, 4);
2811 else if (!memcmp(FrameId, "ASPI", 4)) decode_ASPI( frameptr, framelen);
2812 else if (!memcmp(FrameId, "COMM", 4)) decode_COMM( frameptr, framelen, 4);
2813 else if (!memcmp(FrameId, "COMR", 4)) decode_COMR( frameptr, framelen, 4);
2814 else if (!memcmp(FrameId, "ENCR", 4)) decode_ENCR( frameptr, framelen);
2815 else if (!memcmp(FrameId, "EQU2", 4)) decode_EQU2( frameptr, framelen);
2816 /* NOT SUPPORTED ANY MORE
2817 else if (!memcmp(FrameId, "EQUA", 4)) decode_EQUA( frameptr, framelen);
2818 */
2819 else if (!memcmp(FrameId, "ETCO", 4)) decode_ETCO( frameptr, framelen, 4);
2820 else if (!memcmp(FrameId, "GEOB", 4)) decode_GEOB( frameptr, framelen, 4);
2821 else if (!memcmp(FrameId, "GRID", 4)) decode_GRID( frameptr, framelen);
2822 /* NOT SUPPORTED ANY MORE
2823 else if (!memcmp(FrameId, "IPLS", 4)) decode_Tn ("Involved people list", frameptr, framelen, 4);
2824 */
2825 else if (!memcmp(FrameId, "LINK", 4)) decode_LINK( frameptr, framelen);
2826 else if (!memcmp(FrameId, "MCDI", 4)) decode_MCDI( frameptr, framelen);
2827 else if (!memcmp(FrameId, "MLLT", 4)) decode_MLLT( frameptr, framelen);
2828 else if (!memcmp(FrameId, "OWNE", 4)) decode_OWNE( frameptr, framelen, 4);
2829 else if (!memcmp(FrameId, "PRIV", 4)) decode_PRIV( frameptr, framelen);
2830 else if (!memcmp(FrameId, "PCNT", 4)) decode_PCNT( frameptr, framelen);
2831 else if (!memcmp(FrameId, "POPM", 4)) decode_POPM( frameptr, framelen);
2832 else if (!memcmp(FrameId, "POSS", 4)) decode_POSS( frameptr, framelen);
2833 else if (!memcmp(FrameId, "RBUF", 4)) decode_RBUF( frameptr, framelen);
2834 else if (!memcmp(FrameId, "RVA2", 4)) decode_RVA2( frameptr, framelen);
2835 /* NOT SUPPORTED ANY MORE
2836 else if (!memcmp(FrameId, "RVAD", 4)) decode_RVAD( frameptr, framelen, 4);
2837 */
2838 else if (!memcmp(FrameId, "RVRB", 4)) decode_RVRB( frameptr, framelen);
2839 else if (!memcmp(FrameId, "SEEK", 4)) decode_SEEK( frameptr, framelen);
2840 else if (!memcmp(FrameId, "SIGN", 4)) decode_SIGN( frameptr, framelen);
2841 else if (!memcmp(FrameId, "SYLT", 4)) decode_SYLT( frameptr, framelen, 4);
2842 else if (!memcmp(FrameId, "SYTC", 3)) decode_SYTC( frameptr, framelen);
2843 else if (!memcmp(FrameId, "TALB", 4)) decode_T ("Album/Movie/Show title", frameptr, framelen, 4);
2844 else if (!memcmp(FrameId, "TBPM", 4)) decode_T ("BPM", frameptr, framelen, 4);
2845 else if (!memcmp(FrameId, "TCOM", 4)) decode_T ("Composer(s)", frameptr, framelen, 4);
2846 else if (!memcmp(FrameId, "TCON", 4)) decode_T ("Content (ID3v1 (n)String encoded)", frameptr, framelen, 4);
2847 else if (!memcmp(FrameId, "TCOP", 4)) decode_T ("Copyright message", frameptr, framelen, 4);
2848 /* NOT SUPPORTED ANY MORE
2849 else if (!memcmp(FrameId, "TDAT", 4)) decode_T ("Date (DDMM encoded)", frameptr, framelen, 4);
2850 */
2851 else if (!memcmp(FrameId, "TDEN", 4)) decode_T ("Encoding time", frameptr, framelen, 4);
2852 else if (!memcmp(FrameId, "TDLY", 4)) decode_T ("Playlist delay", frameptr, framelen, 4);
2853 else if (!memcmp(FrameId, "TDOR", 4)) decode_T ("Original release time", frameptr, framelen, 4);
2854 else if (!memcmp(FrameId, "TDRC", 4)) decode_T ("Recording time", frameptr, framelen, 4);
2855 else if (!memcmp(FrameId, "TDRL", 4)) decode_T ("Release time", frameptr, framelen, 4);
2856 else if (!memcmp(FrameId, "TDTG", 4)) decode_T ("Tagging time", frameptr, framelen, 4);
2857 else if (!memcmp(FrameId, "TENC", 4)) decode_T ("Encoded by", frameptr, framelen, 4);
2858 else if (!memcmp(FrameId, "TEXT", 4)) decode_T ("Lyricist(s)/text writer(s)", frameptr, framelen, 4);
2859 else if (!memcmp(FrameId, "TFLT", 4)) decode_T ("File type", frameptr, framelen, 4);
2860 /* NOT SUPPORTED ANY MORE
2861 else if (!memcmp(FrameId, "TIME", 4)) decode_T ("Time (HHMM encoded)", frameptr, framelen, 4);
2862 */
2863 else if (!memcmp(FrameId, "TIPL", 4)) decode_T ("Involved people list", frameptr, framelen, 4);
2864 else if (!memcmp(FrameId, "TIT1", 4)) decode_T ("Content group description", frameptr, framelen, 4);
2865 else if (!memcmp(FrameId, "TIT2", 4)) decode_T ("Title/Songname/Content description", frameptr, framelen, 4);
2866 else if (!memcmp(FrameId, "TIT3", 4)) decode_T ("Subtitle/Description refinement", frameptr, framelen, 4);
2867 else if (!memcmp(FrameId, "TKEY", 4)) decode_T ("Initial key", frameptr, framelen, 4);
2868 else if (!memcmp(FrameId, "TLAN", 4)) decode_T ("Language(s) (ISO-639-2)", frameptr, framelen, 4);
2869 else if (!memcmp(FrameId, "TLEN", 4)) decode_T ("Length (in milliseconds)", frameptr, framelen, 4);
2870 else if (!memcmp(FrameId, "TMCL", 4)) decode_T ("Musician credits list",/*New*/ frameptr, framelen, 4);
2871 else if (!memcmp(FrameId, "TMED", 4)) decode_T ("Media type", frameptr, framelen, 4);
2872 else if (!memcmp(FrameId, "TMOO", 4)) decode_T ("Mood", frameptr, framelen, 4);
2873 else if (!memcmp(FrameId, "TOAL", 4)) decode_T ("Original album/Movie/Show title", frameptr, framelen, 4);
2874 else if (!memcmp(FrameId, "TOFN", 4)) decode_T ("Original filename", frameptr, framelen, 4);
2875 else if (!memcmp(FrameId, "TOLY", 4)) decode_T ("Original Lyricist(s)/text writer(s)", frameptr, framelen, 4);
2876 else if (!memcmp(FrameId, "TOPE", 4)) decode_T ("Original artist(s)/performer(s)", frameptr, framelen, 4);
2877 /* NOT SUPPORTED ANY MORE
2878 else if (!memcmp(FrameId, "TORY", 4)) decode_T ("Original release year", frameptr, framelen, 4);
2879 */
2880 else if (!memcmp(FrameId, "TOWN", 4)) decode_T ("File Owner/License",/*New*/ frameptr, framelen, 4);
2881 else if (!memcmp(FrameId, "TPE1", 4)) decode_T ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", frameptr, framelen, 4);
2882 else if (!memcmp(FrameId, "TPE2", 4)) decode_T ("Band/Orchestra/Accompaniment", frameptr, framelen, 4);
2883 else if (!memcmp(FrameId, "TPE3", 4)) decode_T ("Conductor", frameptr, framelen, 4);
2884 else if (!memcmp(FrameId, "TPE4", 4)) decode_T ("Interpreted, remixed, or otherwise modified by", frameptr, framelen, 4);
2885 else if (!memcmp(FrameId, "TPOS", 4)) decode_T ("Part of a set", frameptr, framelen, 4);
2886 else if (!memcmp(FrameId, "TPRO", 4)) decode_T ("Produced notice", frameptr, framelen, 4);
2887 else if (!memcmp(FrameId, "TPUB", 4)) decode_T ("Publisher", frameptr, framelen, 4);
2888 else if (!memcmp(FrameId, "TRCK", 4)) decode_T ("Track number/Position in set (#/total encoded)", frameptr, framelen, 4);
2889 /* NOT SUPPORTED ANY MORE
2890 else if (!memcmp(FrameId, "TRDA", 4)) decode_T ("Recording dates", frameptr, framelen, 4);
2891 */
2892 else if (!memcmp(FrameId, "TRSN", 4)) decode_T ("Internet radio station name",/*New*/ frameptr, framelen, 4);
2893 else if (!memcmp(FrameId, "TRSO", 4)) decode_T ("Internet radio station Owner",/*New*/ frameptr, framelen, 4);
2894 /* NOT SUPPORTED ANY MORE
2895 else if (!memcmp(FrameId, "TSIZ", 4)) decode_T ("Size (file in bytes)", frameptr, framelen, 4);
2896 */
2897 else if (!memcmp(FrameId, "TSOA", 4)) decode_T ("Album sort order", frameptr, framelen, 4);
2898 else if (!memcmp(FrameId, "TSOP", 4)) decode_T ("Performer sort order", frameptr, framelen, 4);
2899 else if (!memcmp(FrameId, "TSOT", 4)) decode_T ("Title sort order", frameptr, framelen, 4);
2900 else if (!memcmp(FrameId, "TSRC", 4)) decode_T ("International Standard Recording Code (ISO 3901:1986)", frameptr, framelen, 4);
2901 else if (!memcmp(FrameId, "TSSE", 4)) decode_T ("Software/hardware and settings used for encoding", frameptr, framelen, 4);
2902 else if (!memcmp(FrameId, "TSST", 4)) decode_T ("Set subtitle" , frameptr, framelen, 4);
2903 /* NOT SUPPORTED ANY MORE
2904 else if (!memcmp(FrameId, "TYER", 4)) decode_T ("Year (YYYY encoded)", frameptr, framelen, 4);
2905 */
2906 else if (!memcmp(FrameId, "TXXX", 4)) decode_TXXX( frameptr, framelen, 4);
2907 else if (!memcmp(FrameId, "UFID", 4)) decode_UFID( frameptr, framelen);
2908 else if (!memcmp(FrameId, "USER", 4)) decode_USER( frameptr, framelen, 4);
2909 else if (!memcmp(FrameId, "USLT", 3)) decode_USLT( frameptr, framelen, 4);
2910 else if (!memcmp(FrameId, "WCOM", 4)) decode_W ("Commercial information", frameptr, framelen);
2911 else if (!memcmp(FrameId, "WCOP", 4)) decode_W ("Copyright/Legal information", frameptr, framelen);
2912 else if (!memcmp(FrameId, "WOAF", 4)) decode_W ("Official audio file webpage", frameptr, framelen);
2913 else if (!memcmp(FrameId, "WOAR", 4)) decode_W ("Official artist/performer webpage", frameptr, framelen);
2914 else if (!memcmp(FrameId, "WOAS", 4)) decode_W ("Official audio source webpage", frameptr, framelen);
2915 else if (!memcmp(FrameId, "WORS", 4)) decode_W ("Official internet radio station homepage",/*New*/ frameptr, framelen);
2916 else if (!memcmp(FrameId, "WPAY", 4)) decode_W ("Payment",/*New*/ frameptr, framelen);
2917 else if (!memcmp(FrameId, "WPUB", 4)) decode_W ("Publishers official webpage", frameptr, framelen);
2918 else if (!memcmp(FrameId, "WXXX", 4)) decode_WXXX( frameptr, framelen,4);
2919 else if ((FrameId[0]=='T')&&
2920 (((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
2921 (((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
2922 (((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
2923 {
2924 decode_T("Unknown Text", frameptr, framelen, 4);
2925 }
2926 else if ((FrameId[0]=='W')&&
2927 (((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
2928 (((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
2929 (((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
2930 {
2931 decode_W("Unknown URL", frameptr, framelen);
2932 } else {
2933 print("Unknown frame"); newline();
2934 }
2935 flush();
2936 indent--;
2937 ignoreframe:
2938 indent--;
2939 if (zlibptr)
2940 {
2941 free (zlibptr);
2942 zlibptr = 0;
2943 }
2944 return (int32_t)(inputsize + 10);
2945 }
2946
decode_id3v240(uint8_t * data,uint32_t _length,int fd)2947 static void decode_id3v240(uint8_t *data, uint32_t _length, int fd)
2948 {
2949 uint8_t *ptr = data;
2950 uint32_t len = _length;
2951 uint8_t flags = data[5];
2952
2953 ptr = data;
2954 len = _length;
2955
2956 if (flags & 0x80)
2957 {
2958 print(" UNSYNC");
2959 unsync(ptr, &len);
2960 }
2961 if (flags & 0x20)
2962 {
2963 print(" EXPERIMENTAL");
2964 }
2965 if (flags & 0x10)
2966 {
2967 print(" FOOTER");
2968 }
2969
2970 ptr+=10;
2971 len-=10;
2972
2973 indent++;
2974
2975 if (flags & 0x40)
2976 { /* extended header */
2977 uint32_t _elength, elen;
2978 uint8_t *eptr = ptr;
2979 uint8_t eflags;
2980
2981 print(" EXTENDED HEADER");newline();
2982
2983 if ((eptr[0] & 0x80) ||
2984 (eptr[1] & 0x80) ||
2985 (eptr[2] & 0x80) ||
2986 (eptr[3] & 0x80))
2987 {
2988 stack_message(STACK_ERROR, 0, "Extended header length has a MSB set 0x%02x 0x%02x 0x%02x 0x%02x", eptr[0], eptr[1], eptr[2], eptr[3]);
2989 flush();
2990 indent--;
2991 return;
2992 }
2993 _elength = (eptr[0] << 21) |
2994 (eptr[1] << 14) |
2995 (eptr[2] << 7) |
2996 (eptr[3]);
2997 if (_elength < 6)
2998 {
2999 stack_message(STACK_ERROR, 0, "Extended header length too small: %"PRId32, _elength);
3000 flush();
3001 indent--;
3002 return;
3003 }
3004 if (_elength >= len)
3005 {
3006 stack_message(STACK_ERROR, 0, "Extended header length too big: %"PRId32" > %"PRId32, _elength, len);
3007 flush();
3008 indent--;
3009 return;
3010 }
3011 elen = _elength;
3012 if (eptr[4] != 0x01)
3013 {
3014 stack_message(STACK_WARNING, 0, "Non-standard number of flag bytes: %"PRId32" != 0", eptr[4]);
3015 flush();
3016 goto skip_eheader_v240;
3017 }
3018 eflags = eptr[5];
3019
3020 eptr += 6;
3021 elen -= 6;
3022
3023 if (eflags & 0x40)
3024 {
3025 if (elen < 1)
3026 {
3027 stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3028 flush();
3029 goto skip_eheader_v240;
3030 }
3031 if (eptr[0] != 0x00)
3032 {
3033 stack_message(STACK_WARNING, 0, "\"update_flags\" should not have data");
3034 flush();
3035 goto skip_eheader_v240;
3036 }
3037 print("ID3 TAG IS AN UPDATE OF EARLIER DATA"); newline();
3038 } else {
3039 print("ID3 TAG IS A REPLACEMENT OF EARLIER DATA"); newline();
3040 }
3041
3042 if (eflags & 0x20)
3043 {
3044 if (elen < 6)
3045 {
3046 stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3047 flush();
3048 goto skip_eheader_v240;
3049 }
3050 if (eptr[0] != 0x05)
3051 {
3052 stack_message(STACK_WARNING, 0, "CRC should have 5 bytes of data: %d", eptr[0]);
3053 flush();
3054 goto skip_eheader_v240;
3055 }
3056 if ((eptr[1] & 0xf0) ||
3057 (eptr[2] & 0x80) ||
3058 (eptr[3] & 0x80) ||
3059 (eptr[4] & 0x80) ||
3060 (eptr[5] & 0x80))
3061 {
3062 stack_message(STACK_WARNING, 0, "CRC data stream not valid, MSB set: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", eptr[1], eptr[2], eptr[3], eptr[4], eptr[5]);
3063 flush();
3064 goto skip_eheader_v240;
3065 }
3066 uint32_t crc = (eptr[1] << 28) |
3067 (eptr[2] << 21) |
3068 (eptr[3] << 14) |
3069 (eptr[4] << 7) |
3070 (eptr[5]);
3071 print("CRC = 0x%08" PRIx32, crc); newline();
3072 eptr += 6;
3073 elen -= 6;
3074 }
3075 if (eflags & 0x10)
3076 {
3077 if (elen < 2)
3078 {
3079 stack_message(STACK_WARNING, 0, "Extended header ran out of space");
3080 flush();
3081 goto skip_eheader_v240;
3082 }
3083 if (eptr[0] != 0x01)
3084 {
3085 stack_message(STACK_WARNING, 0, "\"Restrictions\" should have 1 bytes of data: %d", eptr[0]);
3086 flush();
3087 goto skip_eheader_v240;
3088 }
3089 print("RESTRICTIONS IN TAG"); newline();
3090 switch (eptr[1] & 0xc0)
3091 {
3092 case 0x00: print("No more than 128 frames and 1 MB total tag size."); break;
3093 case 0x40: print("No more than 64 frames and 128 KB total tag size."); break;
3094 case 0x80: print("No more than 32 frames and 40 KB total tag size."); break;
3095 case 0xc0: print("No more than 32 frames and 4 KB total tag size."); break;
3096 }
3097 newline();
3098 switch (eptr[1] & 0x40)
3099 {
3100 case 0x00: print("Text encoding not restricted."); break;
3101 case 0x40: print("Strings are only encoded with ISO-8859-1 [ISO-8859-1] or UTF-8 [UTF-8]."); break;
3102 }
3103 newline();
3104 switch (eptr[1] & 0x0c)
3105 {
3106 case 0x00: print("Text lengths not restricted."); break;
3107 case 0x04: print("No string is longer than 1024 characters."); break;
3108 case 0x08: print("No string is longer than 128 characters."); break;
3109 case 0x0c: print("No string is longer than 30 characters."); break;
3110 }
3111 newline();
3112 switch (eptr[1] & 0x04)
3113 {
3114 case 0x00: print("Image encoding not restricted."); break;
3115 case 0x04: print("Images are encoded only with PNG [PNG] or JPEG [JFIF]."); break;
3116 }
3117 newline();
3118 switch (eptr[1] & 0x03)
3119 {
3120 case 0x00: print("Image resolution not restricted."); break;
3121 case 0x01: print("All images are 256x256 pixels or smaller."); break;
3122 case 0x02: print("All images are 64x64 pixels or smaller."); break;
3123 case 0x03: print("All images are exactly 64x64 pixels, unless required otherwise."); break;
3124 }
3125 newline();
3126
3127 eptr += 2;
3128 elen -= 2;
3129 }
3130 if (elen != 0)
3131 {
3132 stack_message(STACK_WARNING, 0, "Unused data in extended header: %" PRId32 "bytes left", elen);
3133 flush();
3134 }
3135 skip_eheader_v240:
3136 ptr += _elength;
3137 len -= _elength;
3138 }
3139
3140 while (len > 10)
3141 {
3142 int32_t framelen;
3143
3144 if (ptr[0] == 0)
3145 {
3146 break;
3147 }
3148
3149 indent++;
3150 framelen = decode_id3v240_frame (ptr, len);
3151 indent--;
3152 if (framelen < 0)
3153 {
3154 indent--;
3155 return;
3156 }
3157
3158 ptr += framelen;
3159 len -= framelen;
3160 }
3161
3162 if (len)
3163 {
3164 if (flags & 0x10)
3165 {
3166 stack_message(STACK_WARNING, 0, "PADDING + FOOTER %d bytes", (int) len);
3167 } else {
3168 stack_message(STACK_INFO, 0, "%d bytes of PADDING to inspect", (int)len);
3169 }
3170 }
3171 while (len)
3172 {
3173 if (ptr[0])
3174 {
3175 stack_message(STACK_WARNING, 0, "Non-zero data in padding: 0x%02x", ptr[0]);
3176 }
3177 ptr++;
3178 len--;
3179 }
3180
3181 {
3182 uint8_t fdata[10];
3183 if (read (fd, fdata, 10) != 10)
3184 {
3185 if (flags & 0x10)
3186 {
3187 stack_message(STACK_ERROR, 0, "Unable to read FOOTER"); flush();
3188 }
3189 indent--;
3190 return;
3191 }
3192 if ((fdata[0] == '3') &&
3193 (fdata[1] == 'D') &&
3194 (fdata[2] == 'I'))
3195 {
3196 print("%08lx FOOTER v2.%d.%d 10 bytes", (long) lseek (fd, 0, SEEK_CUR)-10, fdata[3], fdata[4]); newline();
3197 if (fdata[5] != data[5]) {stack_message(STACK_WARNING, 0, "Flags does not match the copy from the header"); flush(); }
3198 if ((fdata[6] != data[6]) ||
3199 (fdata[7] != data[7]) ||
3200 (fdata[8] != data[8]) ||
3201 (fdata[9] != data[9])) {stack_message(STACK_WARNING, 0, "Size does not match the copy from the header"); flush(); }
3202 }
3203 }
3204 indent--;
3205 }
3206
decode_id3v230_frame(uint8_t * ptr,uint32_t len)3207 static int32_t decode_id3v230_frame(uint8_t *ptr, uint32_t len)
3208 {
3209 uint8_t FrameId[4];
3210 uint32_t inputsize;
3211 uint8_t *frameptr, *zlibptr=0;
3212 uint32_t framelen;
3213 uint32_t zlib_new_framelen = 0xffffff;
3214 uint16_t flags;
3215
3216 if (len < 11)
3217 {
3218 stack_message(STACK_ERROR, 0, "Minimum frame length is 11 bytes");
3219 newline();
3220 return -1;
3221 }
3222
3223 FrameId[0] = ptr[0];
3224 FrameId[1] = ptr[1];
3225 FrameId[2] = ptr[2];
3226 FrameId[3] = ptr[3];
3227
3228 if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
3229 (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
3230 (FrameId[2] < 0x20) || (FrameId[2] >= 0x80) ||
3231 (FrameId[3] < 0x20) || (FrameId[3] >= 0x80))
3232 {
3233 stack_message(STACK_ERROR, 0, "Invalid frame ID %02x %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2], FrameId[3]);
3234 newline();
3235 return -1;
3236 }
3237
3238 flags = (ptr[8]<<8)|(ptr[9]);
3239
3240 framelen = inputsize = (ptr[4]<<24)|(ptr[5]<<16)|(ptr[6]<<8)|ptr[7];
3241
3242 frameptr = ptr + 10;
3243 len-=10;
3244
3245 print("Frame %c%c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], FrameId[3], inputsize);
3246 indent++;
3247
3248 if (inputsize > len)
3249 {
3250 stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", inputsize - len);
3251 newline();
3252 indent--;
3253 return -1;
3254 }
3255
3256 print("FLAGS=0x%04"PRIx16" ", flags);
3257
3258 /* part-1, parse header */
3259 #if 0
3260 print("flags=0x%04", flags);
3261 #endif
3262 #if 0
3263 /* these are very noisy to see */
3264 if (flags & 0x8000) stack_message("Tag alter preservation: Frame should be discarded."); else stack_message("Tag alter preservation: Frame should be preserved.");
3265 if (flags & 0x4000) stack_message("File alter preservation: Frame should be discarded."); else stack_message("File alter preservation: Frame should be preserved.");
3266 if (flags & 0x2000) stack_message("Frame is Read only"); else stack_message(" Frame is Read/Write");
3267 #endif
3268
3269 if (flags & 0x0080)
3270 {
3271 if (framelen < 4)
3272 {
3273 stack_message(STACK_ERROR, 0, "Compression set, but no space for outputsize field");
3274 newline();
3275 goto ignoreframe;
3276 }
3277 zlib_new_framelen = (frameptr[0]<<24)|(frameptr[1]<<16)|(frameptr[2]<<8)|frameptr[3];
3278 if (zlib_new_framelen > 32*1024*1024)
3279 {
3280 stack_message(STACK_WARNING, 0, "Decompression bigger than 32MB, blocking it");
3281 newline();
3282 goto ignoreframe;
3283 }
3284 if (!zlib_new_framelen)
3285 {
3286 stack_message(STACK_WARNING, 0, "Decompression size of zero bytes");
3287 newline();
3288 goto ignoreframe;
3289 }
3290 frameptr+=4;
3291 framelen-=4;
3292 }
3293 if (flags & 0x0040)
3294 {
3295 uint8_t method;
3296 if (framelen < 1)
3297 {
3298 stack_message(STACK_WARNING, 0, "Encryption set, but not space for method field");
3299 }
3300 method = frameptr[0];
3301 frameptr++;
3302 framelen--;
3303 stack_message(STACK_INFO, 0, "Frame is encrypted (method %d), ignoring it", method);
3304 newline();
3305 goto ignoreframe;
3306 }
3307 if (flags & 0x0020)
3308 {
3309 if (framelen < 1)
3310 {
3311 stack_message(STACK_WARNING, 0, "Grouping set, but no space for Frame grouping information");
3312 }
3313 stack_message(STACK_INFO, 0, "Frame is grouped with ID=%d", frameptr[0]);
3314 frameptr++;
3315 framelen--;
3316 }
3317 /* part-2 fix the data*/
3318
3319 if (framelen == 0)
3320 {
3321 stack_message(STACK_ERROR, 0, "Frame with zero-length");
3322 indent--;
3323 flush();
3324 return -1;
3325 }
3326
3327 if (flags & 0x0080)
3328 {
3329 int result;
3330
3331 z_stream strm;
3332 zlibptr = malloc (zlib_new_framelen);
3333
3334 strm.zalloc = zalloc;
3335 strm.zfree = zfree;
3336 strm.opaque = (voidpf)0;
3337 strm.avail_in = framelen;
3338 strm.next_in = frameptr;
3339 strm.avail_out = zlib_new_framelen;
3340 strm.next_out = zlibptr;
3341
3342 stack_message(STACK_INFO, 0, "Frame is compressed (inputsize=%" PRId32 ", outputsize=%" PRId32 ")", framelen, zlib_new_framelen);
3343
3344 if (inflateInit(&strm))
3345 {
3346 stack_message(STACK_ERROR, 0, "Zlib failed to init");
3347 newline();
3348 goto ignoreframe;
3349 }
3350 result = inflate(&strm, Z_FINISH);
3351 if (result == Z_STREAM_ERROR ||
3352 result == Z_NEED_DICT ||
3353 result == Z_DATA_ERROR ||
3354 result == Z_MEM_ERROR)
3355 {
3356 stack_message(STACK_ERROR, 0, "Zlib failed to decompress");
3357 if (result != Z_STREAM_ERROR)
3358 {
3359 inflateEnd (&strm);
3360 }
3361 newline();
3362 goto ignoreframe;
3363 }
3364 if (strm.avail_in != 0)
3365 {
3366 stack_message(STACK_WARNING, 0, "Zlib did not consume the entire input, %d bytes left", (int)strm.avail_in);
3367 }
3368 if (strm.avail_out != 0)
3369 {
3370 stack_message(STACK_WARNING, 0, "Zlib did not fill the entire output, %d bytes left", (int)strm.avail_out);
3371 memset (strm.next_out, 0, strm.avail_out);
3372 }
3373 inflateEnd (&strm);
3374 frameptr = zlibptr;
3375 framelen = zlib_new_framelen;
3376 }
3377
3378 indent++;
3379
3380 if (!memcmp(FrameId, "AENC", 4)) decode_AENC( frameptr, framelen);
3381 else if (!memcmp(FrameId, "APIC", 4)) decode_APIC( frameptr, framelen, 3);
3382 else if (!memcmp(FrameId, "COMM", 4)) decode_COMM( frameptr, framelen, 3);
3383 else if (!memcmp(FrameId, "COMR", 4)) decode_COMR( frameptr, framelen, 3);
3384 else if (!memcmp(FrameId, "ENCR", 4)) decode_ENCR( frameptr, framelen);
3385 else if (!memcmp(FrameId, "EQUA", 4)) decode_EQUA( frameptr, framelen);
3386 else if (!memcmp(FrameId, "ETCO", 4)) decode_ETCO( frameptr, framelen, 3);
3387 else if (!memcmp(FrameId, "GEOB", 4)) decode_GEOB( frameptr, framelen, 3);
3388 else if (!memcmp(FrameId, "GRID", 4)) decode_GRID( frameptr, framelen);
3389 else if (!memcmp(FrameId, "IPLS", 4)) decode_Tn ("Involved people list", frameptr, framelen, 3);
3390 else if (!memcmp(FrameId, "LINK", 4)) decode_LINK( frameptr, framelen);
3391 else if (!memcmp(FrameId, "MCDI", 4)) decode_MCDI( frameptr, framelen);
3392 else if (!memcmp(FrameId, "MLLT", 4)) decode_MLLT( frameptr, framelen);
3393 else if (!memcmp(FrameId, "OWNE", 4)) decode_OWNE( frameptr, framelen, 3);
3394 else if (!memcmp(FrameId, "PRIV", 4)) decode_PRIV( frameptr, framelen);
3395 else if (!memcmp(FrameId, "PCNT", 4)) decode_PCNT( frameptr, framelen);
3396 else if (!memcmp(FrameId, "POPM", 4)) decode_POPM( frameptr, framelen);
3397 else if (!memcmp(FrameId, "POSS", 4)) decode_POSS( frameptr, framelen);
3398 else if (!memcmp(FrameId, "RBUF", 4)) decode_RBUF( frameptr, framelen);
3399 else if (!memcmp(FrameId, "RVAD", 4)) decode_RVAD( frameptr, framelen, 3);
3400 else if (!memcmp(FrameId, "RVRB", 4)) decode_RVRB( frameptr, framelen);
3401 else if (!memcmp(FrameId, "SYLT", 4)) decode_SYLT( frameptr, framelen, 3);
3402 else if (!memcmp(FrameId, "SYTC", 3)) decode_SYTC( frameptr, framelen);
3403 else if (!memcmp(FrameId, "TALB", 4)) decode_T ("Album/Movie/Show title", frameptr, framelen, 3);
3404 else if (!memcmp(FrameId, "TBPM", 4)) decode_T ("BPM", frameptr, framelen, 3);
3405 else if (!memcmp(FrameId, "TCOM", 4)) decode_T ("Composer(s)", frameptr, framelen, 3);
3406 else if (!memcmp(FrameId, "TCON", 4)) decode_T ("Content (ID3v1 (n)String encoded)", frameptr, framelen, 3);
3407 else if (!memcmp(FrameId, "TCOP", 4)) decode_T ("Copyright message", frameptr, framelen, 3);
3408 else if (!memcmp(FrameId, "TDAT", 4)) decode_T ("Date (DDMM encoded)", frameptr, framelen, 3);
3409 else if (!memcmp(FrameId, "TDLY", 4)) decode_T ("Playlist delay", frameptr, framelen, 3);
3410 else if (!memcmp(FrameId, "TENC", 4)) decode_T ("Encoded by", frameptr, framelen, 3);
3411 else if (!memcmp(FrameId, "TEXT", 4)) decode_T ("Lyricist(s)/text writer(s)", frameptr, framelen, 3);
3412 else if (!memcmp(FrameId, "TFLT", 4)) decode_T ("File type", frameptr, framelen, 3);
3413 else if (!memcmp(FrameId, "TIME", 4)) decode_T ("Time (HHMM encoded)", frameptr, framelen, 2);
3414 else if (!memcmp(FrameId, "TIT1", 4)) decode_T ("Content group description", frameptr, framelen, 3);
3415 else if (!memcmp(FrameId, "TIT2", 4)) decode_T ("Title/Songname/Content description", frameptr, framelen, 3);
3416 else if (!memcmp(FrameId, "TIT3", 4)) decode_T ("Subtitle/Description refinement", frameptr, framelen, 3);
3417 else if (!memcmp(FrameId, "TKEY", 4)) decode_T ("Initial key", frameptr, framelen, 3);
3418 else if (!memcmp(FrameId, "TLAN", 4)) decode_T ("Language(s) (ISO-639-2)", frameptr, framelen, 3);
3419 else if (!memcmp(FrameId, "TLEN", 4)) decode_T ("Length (in milliseconds)", frameptr, framelen, 3);
3420 else if (!memcmp(FrameId, "TMED", 4)) decode_T ("Media type", frameptr, framelen, 3);
3421 else if (!memcmp(FrameId, "TOAL", 4)) decode_T ("Original album/Movie/Show title", frameptr, framelen, 3);
3422 else if (!memcmp(FrameId, "TOFN", 4)) decode_T ("Original filename", frameptr, framelen, 3);
3423 else if (!memcmp(FrameId, "TOLY", 4)) decode_T ("Original Lyricist(s)/text writer(s)", frameptr, framelen, 3);
3424 else if (!memcmp(FrameId, "TOPE", 4)) decode_T ("Original artist(s)/performer(s)", frameptr, framelen, 3);
3425 else if (!memcmp(FrameId, "TORY", 4)) decode_T ("Original release year", frameptr, framelen, 3);
3426 else if (!memcmp(FrameId, "TOWN", 4)) decode_T ("File Owner/License",/*New*/ frameptr, framelen, 3);
3427 else if (!memcmp(FrameId, "TPE1", 4)) decode_T ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", frameptr, framelen, 3);
3428 else if (!memcmp(FrameId, "TPE2", 4)) decode_T ("Band/Orchestra/Accompaniment", frameptr, framelen, 3);
3429 else if (!memcmp(FrameId, "TPE3", 4)) decode_T ("Conductor", frameptr, framelen, 3);
3430 else if (!memcmp(FrameId, "TPE4", 4)) decode_T ("Interpreted, remixed, or otherwise modified by", frameptr, framelen, 3);
3431 else if (!memcmp(FrameId, "TPOS", 4)) decode_T ("Part of a set", frameptr, framelen, 3);
3432 else if (!memcmp(FrameId, "TPUB", 4)) decode_T ("Publisher", frameptr, framelen, 3);
3433 else if (!memcmp(FrameId, "TRCK", 4)) decode_T ("Track number/Position in set (#/total encoded)", frameptr, framelen, 3);
3434 else if (!memcmp(FrameId, "TRDA", 4)) decode_T ("Recording dates", frameptr, framelen, 3);
3435 else if (!memcmp(FrameId, "TRSN", 4)) decode_T ("Internet radio station name",/*New*/ frameptr, framelen, 3);
3436 else if (!memcmp(FrameId, "TRSO", 4)) decode_T ("Internet radio station Owner",/*New*/ frameptr, framelen, 3);
3437 else if (!memcmp(FrameId, "TSIZ", 4)) decode_T ("Size (file in bytes)", frameptr, framelen, 3);
3438 else if (!memcmp(FrameId, "TSRC", 4)) decode_T ("International Standard Recording Code (ISO 3901:1986)", frameptr, framelen, 3);
3439 else if (!memcmp(FrameId, "TSSE", 4)) decode_T ("Software/hardware and settings used for encoding", frameptr, framelen, 3);
3440 else if (!memcmp(FrameId, "TYER", 4)) decode_T ("Year (YYYY encoded)", frameptr, framelen, 3);
3441 else if (!memcmp(FrameId, "TXXX", 4)) decode_TXXX( frameptr, framelen, 3);
3442 else if (!memcmp(FrameId, "UFID", 4)) decode_UFID( frameptr, framelen);
3443 else if (!memcmp(FrameId, "USER", 4)) decode_USER( frameptr, framelen, 3);
3444 else if (!memcmp(FrameId, "USLT", 3)) decode_USLT( frameptr, framelen, 3);
3445 else if (!memcmp(FrameId, "WCOM", 4)) decode_W ("Commercial information", frameptr, framelen);
3446 else if (!memcmp(FrameId, "WCOP", 4)) decode_W ("Copyright/Legal information", frameptr, framelen);
3447 else if (!memcmp(FrameId, "WOAF", 4)) decode_W ("Official audio file webpage", frameptr, framelen);
3448 else if (!memcmp(FrameId, "WOAR", 4)) decode_W ("Official artist/performer webpage", frameptr, framelen);
3449 else if (!memcmp(FrameId, "WOAS", 4)) decode_W ("Official audio source webpage", frameptr, framelen);
3450 else if (!memcmp(FrameId, "WORS", 4)) decode_W ("Official internet radio station homepage",/*New*/ frameptr, framelen);
3451 else if (!memcmp(FrameId, "WPAY", 4)) decode_W ("Payment",/*New*/ frameptr, framelen);
3452 else if (!memcmp(FrameId, "WPUB", 4)) decode_W ("Publishers official webpage", frameptr, framelen);
3453 else if (!memcmp(FrameId, "WXXX", 4)) decode_WXXX( frameptr, framelen,3);
3454 else if ((FrameId[0]=='T')&&
3455 (((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
3456 (((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
3457 (((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
3458 {
3459 decode_T("Unknown Text", frameptr, framelen, 3);
3460 }
3461 else if ((FrameId[0]=='W')&&
3462 (((FrameId[1]>='0')&&(FrameId[1]<='9'))||((FrameId[1]>='a')&&(FrameId[1]<='z'))||((FrameId[1]>='A')&&(FrameId[1]<='Z')))&&
3463 (((FrameId[2]>='0')&&(FrameId[2]<='9'))||((FrameId[2]>='a')&&(FrameId[2]<='z'))||((FrameId[2]>='A')&&(FrameId[2]<='Z')))&&
3464 (((FrameId[3]>='0')&&(FrameId[3]<='9'))||((FrameId[3]>='a')&&(FrameId[3]<='z'))||((FrameId[3]>='A')&&(FrameId[3]<='Z'))))
3465 {
3466 decode_W("Unknown URL", frameptr, framelen);
3467 } else {
3468 print("Unknown frame"); newline();
3469 }
3470 flush();
3471 indent--;
3472 ignoreframe:
3473 indent--;
3474 if (zlibptr)
3475 {
3476 free (zlibptr);
3477 zlibptr = 0;
3478 }
3479 ptr += inputsize;
3480 len -= inputsize;
3481
3482 return (int32_t)(inputsize + 10);
3483 }
3484
decode_id3v230(uint8_t * data,uint32_t _length)3485 static void decode_id3v230(uint8_t *data, uint32_t _length)
3486 {
3487 uint8_t *ptr;
3488 uint32_t len;
3489 uint8_t flags = data[5];
3490 uint32_t v3_paddinglength=0;
3491
3492 ptr = data;
3493 len = _length;
3494
3495 if (flags & 0x80)
3496 {
3497 print(" UNSYNC");
3498 unsync(ptr, &len);
3499 }
3500 if (flags & 0x20)
3501 {
3502 print(" EXPERIMENTAL");
3503 }
3504 if (flags & 0x1f)
3505 {
3506 print(" UNKNOWN_FLAGS(This will probably fail to parse)");
3507 }
3508 newline();
3509
3510 ptr+=10;
3511 len-=10;
3512
3513 indent++;
3514 if (flags & 0x40)
3515 {
3516 uint32_t _elength;
3517 uint8_t *eptr = ptr;
3518
3519 print(" EXTENDED HEADER");newline();
3520
3521 _elength = (eptr[0] << 24) |
3522 (eptr[1] << 16) |
3523 (eptr[2] << 8) |
3524 (eptr[3]);
3525
3526 if ((_elength != 6) && (_elength != 10))
3527 {
3528 stack_message(STACK_ERROR, 0, "Extended header length should be 6 or 10");
3529 indent--;
3530 return;
3531 }
3532
3533 if ((_elength + 4) > len)
3534 {
3535 stack_message(STACK_ERROR, 0, "Extended header length too big");
3536 indent--;
3537 return;
3538 }
3539 if (eptr[4] == 0x00)
3540 {
3541 if (_elength != 6)
3542 {
3543 stack_message(STACK_WARNING, 0, "CRC disabled and length = 6");
3544 goto skip_eheader_v230;
3545 }
3546 v3_paddinglength = (eptr[6] << 24) |
3547 (eptr[7] << 16) |
3548 (eptr[8] << 8) |
3549 eptr[9] ;
3550 len -= v3_paddinglength;
3551 print("PADDING=%" PRId32 " BYTES", v3_paddinglength);
3552 } else if (eptr[4] == 0x80)
3553 {
3554 uint32_t crc;
3555 if (_elength != 10)
3556 {
3557 stack_message(STACK_WARNING, 0, "CRC enabled and length != 10");
3558 goto skip_eheader_v230;
3559 }
3560 v3_paddinglength = (eptr[6] << 24) |
3561 (eptr[7] << 16) |
3562 (eptr[8] << 8) |
3563 (eptr[9]);
3564 crc = (eptr[10]<<24) |
3565 (eptr[11]<<16) |
3566 (eptr[12]<<8) |
3567 eptr[13];
3568
3569 print("CRC=0x%08"PRIx32, crc);
3570 } else {
3571 stack_message(STACK_WARNING, 0, "FLAGS[0] is out of range");
3572 goto skip_eheader_v230;
3573 }
3574 if (eptr[5] != 0x00)
3575 {
3576 stack_message(STACK_WARNING, 0, "FLAGS[0] is out of range");
3577 goto skip_eheader_v230;
3578 }
3579 skip_eheader_v230:
3580 ptr += _elength+4;
3581 len -= _elength+4;
3582 }
3583
3584 while (len > 10)
3585 {
3586 int32_t framelen;
3587
3588 if (ptr[0] == 0)
3589 {
3590 stack_message(STACK_WARNING, 0, "Hit zero data, should have been marked as padding");
3591 break;
3592 }
3593
3594 indent++;
3595 framelen = decode_id3v230_frame (ptr, len);
3596 indent--;
3597 if (framelen < 0)
3598 {
3599 indent--;
3600 return;
3601 }
3602
3603 ptr += framelen;
3604 len -= framelen;
3605 }
3606
3607 len += v3_paddinglength;
3608 if (len)
3609 {
3610 stack_message(STACK_INFO, 0, "%d bytes of PADDING to inspect", (int)len);
3611 }
3612 while (len)
3613 {
3614 if (ptr[0])
3615 {
3616 stack_message(STACK_WARNING, 0, "Non-zero data in padding: 0x%02x", ptr[0]);
3617 }
3618 ptr++;
3619 len--;
3620 }
3621 }
3622
decode_id3v220_frame(uint8_t * ptr,uint32_t len)3623 static int32_t decode_id3v220_frame(uint8_t *ptr, uint32_t len)
3624 {
3625 uint8_t FrameId[3];
3626 uint32_t framelen;
3627
3628 if (len < 7)
3629 {
3630 print("*-*-* ERROR, Minimum frame length is 7 bytes"); newline();
3631 return -1;
3632 }
3633
3634 FrameId[0] = ptr[0];
3635 FrameId[1] = ptr[1];
3636 FrameId[2] = ptr[2];
3637
3638 if ((FrameId[0] < 0x20) || (FrameId[0] >= 0x80) ||
3639 (FrameId[1] < 0x20) || (FrameId[1] >= 0x80) ||
3640 (FrameId[2] < 0x20) || (FrameId[2] >= 0x80))
3641 {
3642 stack_message(STACK_ERROR, 0, "Invalid frame ID %02x %02x %02x", FrameId[0], FrameId[1], FrameId[2]);
3643 newline();
3644 return -1;
3645 }
3646
3647 framelen = (ptr[3]<<16) | (ptr[4]<<8) | ptr[5];
3648
3649 if (framelen == 0)
3650 {
3651 stack_message(STACK_ERROR, 1, "Frame with zero-length");
3652 newline();
3653 return -1;
3654 }
3655
3656 ptr += 6;
3657 len -= 6;
3658
3659 print("Frame %c%c%c (%5"PRId32" bytes) - ", FrameId[0], FrameId[1], FrameId[2], framelen);
3660 indent++;
3661
3662 if (framelen > len)
3663 {
3664 stack_message(STACK_ERROR, 0, "We are missing %d of data in this frame", framelen - len);
3665 newline();
3666 indent--;
3667 return -1;
3668 }
3669 indent++;
3670
3671 if (!memcmp(FrameId, "UFI", 3)) decode_UFID( ptr, framelen);
3672 else if (!memcmp(FrameId, "TT1", 3)) decode_T ("Content group description", ptr, framelen, 2);
3673 else if (!memcmp(FrameId, "TT2", 3)) decode_T ("Title/Songname/Content description", ptr, framelen, 2);
3674 else if (!memcmp(FrameId, "TT3", 3)) decode_T ("Subtitle/Description refinement", ptr, framelen, 2);
3675 else if (!memcmp(FrameId, "TP1", 3)) decode_T ("Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group", ptr, framelen, 2);
3676 else if (!memcmp(FrameId, "TP2", 3)) decode_T ("Band/Orchestra/Accompaniment", ptr, framelen, 2);
3677 else if (!memcmp(FrameId, "TP3", 3)) decode_T ("Conductor", ptr, framelen, 2);
3678 else if (!memcmp(FrameId, "TP4", 3)) decode_T ("Interpreted, remixed, or otherwise modified by", ptr, framelen, 2);
3679 else if (!memcmp(FrameId, "TCM", 3)) decode_T ("Composer(s)", ptr, framelen, 2);
3680 else if (!memcmp(FrameId, "TXT", 3)) decode_T ("Lyricist(s)/text writer(s)", ptr, framelen, 2);
3681 else if (!memcmp(FrameId, "TLA", 3)) decode_T ("Language(s) (ISO-639-2)", ptr, framelen, 2);
3682 else if (!memcmp(FrameId, "TCO", 3)) decode_T ("Content (ID3v1 (n)String encoded)", ptr, framelen, 2);
3683 else if (!memcmp(FrameId, "TAL", 3)) decode_T ("Album/Movie/Show title", ptr, framelen, 2);
3684 else if (!memcmp(FrameId, "TPA", 3)) decode_T ("Part of a set", ptr, framelen, 2);
3685 else if (!memcmp(FrameId, "TRK", 3)) decode_T ("Track number/Position in set (#/total encoded)", ptr, framelen, 2);
3686 else if (!memcmp(FrameId, "TRC", 3)) decode_T ("International Standard Recording Code (ISO 3901:1986)", ptr, framelen, 2);
3687 else if (!memcmp(FrameId, "TYE", 3)) decode_T ("Year (YYYY encoded)", ptr, framelen, 2);
3688 else if (!memcmp(FrameId, "TDA", 3)) decode_T ("Date (DDMM encoded)", ptr, framelen, 2);
3689 else if (!memcmp(FrameId, "TIM", 3)) decode_T ("Time (HHMM encoded)", ptr, framelen, 2);
3690 else if (!memcmp(FrameId, "TRD", 3)) decode_T ("Recording dates", ptr, framelen, 2);
3691 else if (!memcmp(FrameId, "TMT", 3)) decode_T ("Media type", ptr, framelen, 2);
3692 else if (!memcmp(FrameId, "TFT", 3)) decode_T ("File type", ptr, framelen, 2);
3693 else if (!memcmp(FrameId, "TBP", 3)) decode_T ("BPM", ptr, framelen, 2);
3694 else if (!memcmp(FrameId, "TCR", 3)) decode_T ("Copyright message", ptr, framelen, 2);
3695 else if (!memcmp(FrameId, "TPB", 3)) decode_T ("Publisher", ptr, framelen, 2);
3696 else if (!memcmp(FrameId, "TEN", 3)) decode_T ("Encoded by", ptr, framelen, 2);
3697 else if (!memcmp(FrameId, "TSS", 3)) decode_T ("Software/hardware and settings used for encoding", ptr, framelen, 2);
3698 else if (!memcmp(FrameId, "TOF", 3)) decode_T ("Original filename", ptr, framelen, 2);
3699 else if (!memcmp(FrameId, "TLE", 3)) decode_T ("Length (in milliseconds)", ptr, framelen, 2);
3700 else if (!memcmp(FrameId, "TSI", 3)) decode_T ("Size (file in bytes)", ptr, framelen, 2);
3701 else if (!memcmp(FrameId, "TDY", 3)) decode_T ("Playlist delay", ptr, framelen, 2);
3702 else if (!memcmp(FrameId, "TKE", 3)) decode_T ("Initial key", ptr, framelen, 2);
3703 else if (!memcmp(FrameId, "TOT", 3)) decode_T ("Original album/Movie/Show title", ptr, framelen, 2);
3704 else if (!memcmp(FrameId, "TOA", 3)) decode_T ("Original artist(s)/performer(s)", ptr, framelen, 2);
3705 else if (!memcmp(FrameId, "TOL", 3)) decode_T ("Original Lyricist(s)/text writer(s)", ptr, framelen, 2);
3706 else if (!memcmp(FrameId, "TOR", 3)) decode_T ("Original release year", ptr, framelen, 2);
3707 else if (!memcmp(FrameId, "TXX", 3)) decode_TXXX( ptr, framelen, 2);
3708 else if (!memcmp(FrameId, "WAF", 3)) decode_W ("Official audio file webpage", ptr, framelen);
3709 else if (!memcmp(FrameId, "WAR", 3)) decode_W ("Official artist/performer webpage", ptr, framelen);
3710 else if (!memcmp(FrameId, "WAS", 3)) decode_W ("Official audio source webpage", ptr, framelen);
3711 else if (!memcmp(FrameId, "WCM", 3)) decode_W ("Commercial information", ptr, framelen);
3712 else if (!memcmp(FrameId, "WCP", 3)) decode_W ("Copyright/Legal information", ptr, framelen);
3713 else if (!memcmp(FrameId, "WPB", 3)) decode_W ("Publishers official webpage", ptr, framelen);
3714 else if (!memcmp(FrameId, "WXX", 3)) decode_WXXX( ptr, framelen, 2);
3715 else if (!memcmp(FrameId, "IPL", 3)) decode_Tn ("Involved people list", ptr, framelen, 2);
3716 else if (!memcmp(FrameId, "MCI", 3)) decode_MCDI( ptr, framelen);
3717 else if (!memcmp(FrameId, "ETC", 3)) decode_ETCO( ptr, framelen, 2);
3718 else if (!memcmp(FrameId, "MLL", 3)) decode_MLLT( ptr, framelen);
3719 else if (!memcmp(FrameId, "STC", 3)) decode_SYTC( ptr, framelen);
3720 else if (!memcmp(FrameId, "ULT", 3)) decode_USLT( ptr, framelen, 2);
3721 else if (!memcmp(FrameId, "SLT", 3)) decode_SYLT( ptr, framelen, 2);
3722 else if (!memcmp(FrameId, "COM", 3)) decode_COMM( ptr, framelen, 2);
3723 else if (!memcmp(FrameId, "RVA", 3)) decode_RVAD( ptr, framelen, 2);
3724 else if (!memcmp(FrameId, "EQU", 3)) decode_EQUA( ptr, framelen);
3725 else if (!memcmp(FrameId, "REV", 3)) decode_RVRB( ptr, framelen);
3726 else if (!memcmp(FrameId, "PIC", 3)) decode_APIC( ptr, framelen, 2);
3727 else if (!memcmp(FrameId, "GEO", 3)) decode_GEOB( ptr, framelen, 2);
3728 else if (!memcmp(FrameId, "CNT", 3)) decode_PCNT( ptr, framelen);
3729 else if (!memcmp(FrameId, "POP", 3)) decode_POPM( ptr, framelen);
3730 else if (!memcmp(FrameId, "BUF", 3)) decode_RBUF( ptr, framelen);
3731 else if (!memcmp(FrameId, "CRM", 3)) decode_CRM ( ptr, framelen); /* ID3v2.3.0 changed layout */
3732 else if (!memcmp(FrameId, "CRA", 3)) decode_AENC( ptr, framelen);
3733 else if (!memcmp(FrameId, "LNK", 3)) decode_LINK( ptr, framelen);
3734 else if ((ptr[0]=='T')&&
3735 (((ptr[1]>='0')&&(ptr[1]<='9'))||((ptr[1]>='a')&&(ptr[1]<='z'))||((ptr[1]>='A')&&(ptr[1]<='Z')))&&
3736 (((ptr[2]>='0')&&(ptr[2]<='9'))||((ptr[2]>='a')&&(ptr[2]<='z'))||((ptr[2]>='A')&&(ptr[1]<='Z'))) )
3737 {
3738 decode_T("Unknown Text", ptr+6, framelen, 2);
3739 }
3740 else if ((ptr[0]=='W')&&
3741 (((ptr[1]>='0')&&(ptr[1]<='9'))||((ptr[1]>='a')&&(ptr[1]<='z'))||((ptr[1]>='A')&&(ptr[1]<='Z')))&&
3742 (((ptr[2]>='0')&&(ptr[2]<='9'))||((ptr[2]>='a')&&(ptr[2]<='z'))||((ptr[2]>='A')&&(ptr[1]<='Z'))))
3743 {
3744 decode_W("Unknown URL", ptr+6, framelen);
3745 } else {
3746 print("Unknown frame"); newline();
3747 }
3748 flush();
3749 indent-=2;
3750
3751 return 6 + framelen;
3752 }
3753
decode_id3v220(uint8_t * data,uint32_t _length)3754 static void decode_id3v220(uint8_t *data, uint32_t _length)
3755 {
3756 uint8_t *ptr;
3757 uint32_t len;
3758 uint8_t flags = data[5];
3759
3760 ptr = data;
3761 len = _length;
3762
3763 if (flags & 0x80)
3764 {
3765 print(" UNSYNC");
3766 unsync(ptr, &len);
3767 }
3768 if (flags & 0x40)
3769 {
3770 print(" COMPRESSION?(This is not defined yet)");
3771 }
3772 if (flags & 0x3f)
3773 {
3774 print(" UNKNOWN_FLAGS(This will probably fail to parse)");
3775 }
3776 newline();
3777
3778 ptr+=10;
3779 len-=10;
3780
3781 while (len > 6)
3782 {
3783 int32_t framelen;
3784
3785 if (ptr[0] == 0)
3786 {
3787 break;
3788 }
3789
3790 indent++;
3791 framelen = decode_id3v220_frame (ptr, len);
3792 indent--;
3793 if (framelen < 0)
3794 {
3795 indent--;
3796 return;
3797 }
3798
3799 ptr += framelen;
3800 len -= framelen;
3801 }
3802
3803 if (len)
3804 {
3805 stack_message(STACK_INFO, 0, "(%d bytes of PADDING to inspect)", (int)len);
3806 }
3807 while (len)
3808 {
3809 if (ptr[0])
3810 {
3811 stack_message(STACK_WARNING,0, "Non-zero data in padding: 0x%02x", ptr[0]);
3812 }
3813 ptr++;
3814 len--;
3815 }
3816 }
3817
decode_id3v2x(int fd,uint8_t data[10],off_t offset)3818 static off_t decode_id3v2x(int fd, uint8_t data[10], off_t offset)
3819 {
3820 unsigned char *ndata;
3821 uint32_t length;
3822 uint32_t hlength = 10;
3823 off_t p;
3824
3825 if (!(((data[3] == 2) && (data[4]==0)) ||
3826 ((data[3] == 3) && (data[4]==0)) ||
3827 ((data[3] == 4) && (data[4]==0)) ) )
3828 { /* False positive or unknown version */
3829 return 0;
3830 }
3831
3832 if (data[5] & 0x0f)
3833 {
3834 /* The lower nibble will never be set - also why FLAGS byte is never unsyncronized */
3835 return 0;
3836 }
3837
3838 if ((data[6] & 0x80) ||
3839 (data[7] & 0x80) ||
3840 (data[8] & 0x80) ||
3841 (data[9] & 0x80))
3842 {
3843 /* size is stored as 'syncsafe integer'. MSB will never be set */
3844 return 0;
3845 }
3846
3847 length = (((unsigned char *)data)[6]<<21) |
3848 (((unsigned char *)data)[7]<<14) |
3849 (((unsigned char *)data)[8]<<7) |
3850 (((unsigned char *)data)[9]);
3851
3852 if (length < (10 + ((data[5] & 0x40)?6:0)))
3853 {
3854 /* must fit atleast the header */
3855 return 0;
3856 }
3857
3858 print("0x%08lx ID3v2.%d.%d %ld bytes", (long) offset, ((unsigned char *)data)[3], ((unsigned char *)data)[4], (long)length);
3859
3860 ndata = malloc (length + hlength);
3861 p = lseek(fd, 0, SEEK_CUR);
3862 lseek(fd, offset, SEEK_SET);
3863 {
3864 int result = read (fd, ndata, (length+hlength));
3865 if (result != (length + hlength))
3866 {
3867 stack_message(STACK_WARNING, 0, "Unable to read entire tag from disk");
3868 if (result < 0) result = 0;
3869 memset (ndata + result, 0, (length+hlength)-result);
3870 }
3871
3872 /* Different versions have different rules for extended header, and sync-safe integers */
3873 if (data[3] == 2)
3874 {
3875 indent++;
3876 decode_id3v220(ndata, length+hlength);
3877 indent--;
3878 } else if(data[3] == 3)
3879 {
3880 indent++;
3881 decode_id3v230(ndata, length+hlength);
3882 indent--;
3883 } else if (data[3] == 4)
3884 {
3885 indent++;
3886 decode_id3v240(ndata, length+hlength, fd); /* FD, to probe for footer */
3887 indent--;
3888 }
3889 flush();
3890 }
3891
3892 free (ndata);
3893 lseek (fd, p, SEEK_SET);
3894 return length + hlength;
3895 }
3896
decode_id3v12(uint8_t data[128],off_t offset)3897 static void decode_id3v12(uint8_t data[128], off_t offset)
3898 {
3899 uint8_t *d;
3900 uint32_t l;
3901
3902 print("%08lx ID3v1.2 (extends more text onto ID3v1.0/ID3v1.1 128 bytes", (long) offset); newline();
3903 indent++;
3904 print("..SongName: "); d=data+ 3; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3905 print("..Artist: "); d=data+ 33; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3906 print("..Album: "); d=data+ 63; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
3907 print("..Comment: "); d=data+ 93; l=15; decode_print_iso8859_1(&d, &l, 0); newline();
3908 print("SubGenre: "); d=data+108; l=20; decode_print_iso8859_1(&d, &l, 0); newline();
3909 indent--;
3910 }
3911
decode_id3v1x(uint8_t data[128],off_t offset)3912 static void decode_id3v1x(uint8_t data[128], off_t offset)
3913 {
3914 uint8_t *d;
3915 uint32_t l;
3916 const char *genre[] =
3917 {
3918 "Blues",
3919 "Classic Rock",
3920 "Country",
3921 "Dance",
3922 "Disco",
3923 "Funk",
3924 "Grunge",
3925 "Hip-Hop",
3926 "Jazz",
3927 "Metal",
3928 "New Age",
3929 "Oldies",
3930 "Other",
3931 "Pop",
3932 "R&B",
3933 "Rap",
3934 "Reggae",
3935 "Rock",
3936 "Techno",
3937 "Industrial",
3938 "Alternative",
3939 "Ska",
3940 "Death Metal",
3941 "Pranks",
3942 "Soundtrack",
3943 "Euro-Techno",
3944 "Ambient",
3945 "Trip-Hop",
3946 "Vocal",
3947 "Jazz+Funk",
3948 "Fusion",
3949 "Trance",
3950 "Classical",
3951 "Instrumental",
3952 "Acid",
3953 "House",
3954 "Game",
3955 "Sound Clip",
3956 "Gospel",
3957 "Noise",
3958 "AlternRock",
3959 "Bass",
3960 "Soul",
3961 "Punk",
3962 "Space",
3963 "Meditative",
3964 "Instrumental Pop",
3965 "Instrumental Rock",
3966 "Ethnic",
3967 "Gothic",
3968 "Darkwave",
3969 "Techno-Industrial",
3970 "Electronic",
3971 "Pop-Folk",
3972 "Eurodance",
3973 "Dream",
3974 "Southern Rock",
3975 "Comedy",
3976 "Cult",
3977 "Gangsta",
3978 "Top 40",
3979 "Christian Rap",
3980 "Pop/Funk",
3981 "Jungle",
3982 "Native American",
3983 "Cabaret",
3984 "New Wave",
3985 "Psychadelic",
3986 "Rave",
3987 "Showtunes",
3988 "Trailer",
3989 "Lo-Fi",
3990 "Tribal",
3991 "Acid Punk",
3992 "Acid Jazz",
3993 "Polka",
3994 "Retro",
3995 "Musical",
3996 "Rock & Roll",
3997 "Hard Rock",
3998 "Folk (Winamp extension)",
3999 "Folk-Rock (Winamp extension)",
4000 "National Folk (Winamp extension)",
4001 "Swing (Winamp extension)",
4002 "Fast Fusion (Winamp extension)",
4003 "Bebob (Winamp extension)",
4004 "Latin (Winamp extension)",
4005 "Revival (Winamp extension)",
4006 "Celtic (Winamp extension)",
4007 "Bluegrass (Winamp extension)",
4008 "Avantgarde (Winamp extension)",
4009 "Gothic Rock (Winamp extension)",
4010 "Progressive Rock (Winamp extension)",
4011 "Psychedelic Rock (Winamp extension)",
4012 "Symphonic Rock (Winamp extension)",
4013 "Slow Rock (Winamp extension)",
4014 "Big Band (Winamp extension)",
4015 "Chorus (Winamp extension)",
4016 "Easy Listening (Winamp extension)",
4017 "Acoustic (Winamp extension)",
4018 "Humour (Winamp extension)",
4019 "Speech (Winamp extension)",
4020 "Chanson (Winamp extension)",
4021 "Opera (Winamp extension)",
4022 "Chamber Music (Winamp extension)",
4023 "Sonata (Winamp extension)",
4024 "Symphony (Winamp extension)",
4025 "Booty Bass (Winamp extension)",
4026 "Primus (Winamp extension)",
4027 "Porn Groove (Winamp extension)",
4028 "Satire (Winamp extension)",
4029 "Slow Jam (Winamp extension)",
4030 "Club (Winamp extension)",
4031 "Tango (Winamp extension)",
4032 "Samba (Winamp extension)",
4033 "Folklore (Winamp extension)",
4034 "Ballad (Winamp extension)",
4035 "Power Ballad (Winamp extension)",
4036 "Rhythmic Soul (Winamp extension)",
4037 "Freestyle (Winamp extension)",
4038 "Duet (Winamp extension)",
4039 "Punk Rock (Winamp extension)",
4040 "Drum Solo (Winamp extension)",
4041 "A capella (Winamp extension)",
4042 "Euro-House (Winamp extension)",
4043 "Dance Hall (Winamp extension"
4044 };
4045
4046 if ((!data[125]) && data[126])
4047 {
4048 print("%08lx ID3v1.1 128 bytes", (long) offset); newline();
4049 } else {
4050 print("%08lx ID3v1 128 bytes", (long) offset); newline();
4051 }
4052 indent++;
4053
4054 print("SongName: "); d=data+ 3; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4055 print("Artist: "); d=data+ 33; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4056 print("Album: "); d=data+ 63; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4057 print("Year: "); d=data+ 93; l= 4; decode_print_iso8859_1(&d, &l, 0); newline();
4058
4059 if ((!data[125]) && data[126])
4060 {
4061 print("Comment: "); d=data+ 97; l=27; decode_print_iso8859_1(&d, &l, 0); newline();
4062 print("Track number: %d", data[126]); newline();
4063 } else {
4064
4065 print("Comment: "); d=data+ 97; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4066 }
4067 print("Genre: %d \"%s\"", data[127], (data[127]>=(sizeof(genre)/sizeof(genre[0])))?"Unknown":genre[data[127]]); newline();
4068
4069 indent--;
4070 }
4071
decode_etag(uint8_t data[227],off_t offset)4072 static void decode_etag(uint8_t data[227], off_t offset)
4073 {
4074 uint8_t *d;
4075 uint32_t l;
4076
4077 print("%08lx ETAG 227 bytes", (long) offset);newline();
4078 indent++;
4079
4080 print("Title: "); d=data+ 4; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4081 print("Artist: "); d=data+ 64; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4082 print("Album: "); d=data+124; l=60; decode_print_iso8859_1(&d, &l, 0); newline();
4083 switch (data[184])
4084 {
4085 case 0x00: print("Speed: (unset)"); newline(); break;
4086 case 0x01: print("Speed: slow"); newline(); break;
4087 case 0x02: print("Speed: medium"); newline(); break;
4088 case 0x03: print("Speed: fast"); newline(); break;
4089 case 0x04: print("Speed: hardcore"); newline(); break;
4090 default: print("Speed: (%d) Unknown", data[184]); newline(); break;
4091 }
4092 print("Genre: "); d=data+185; l=30; decode_print_iso8859_1(&d, &l, 0); newline();
4093 print("Start-Time: "); d=data+215; l=6; decode_print_iso8859_1(&d, &l, 0); newline();
4094 print("Stop-Time: "); d=data+221; l=6; decode_print_iso8859_1(&d, &l, 0); newline();
4095
4096 indent--;
4097 }
4098
scanfile(const char * filename)4099 static void scanfile(const char *filename)
4100 {
4101 int fd;
4102 uint8_t prehead[65536];
4103 int fill;
4104 int need_sync = 1;
4105
4106 printf ("FILE: %s\n", filename);
4107 fd = open (filename, O_RDONLY);
4108 if (fd < 0)
4109 {
4110 fprintf (stderr, "Failed to open %s\n", filename);
4111 return;
4112 }
4113
4114 if (read (fd, prehead, 3) != 3)
4115 {
4116 fprintf (stderr, "Failed to read offset 0, count 3\n");
4117 close (fd);
4118 return;
4119 }
4120
4121 if (!memcmp (prehead, "TAG", 3))
4122 {
4123 if (read (fd, prehead + 3, 128-3) != (128-3))
4124 {
4125 fprintf (stderr, "Failed to read offset 3, count 125\n");
4126 close (fd);
4127 return;
4128 }
4129 fprintf (stderr, "NON STANDARD ID3v1 tag at the start of the file!!!\n");
4130 decode_id3v1x (prehead, 0);
4131 }
4132
4133 if (lseek (fd, -128, SEEK_END) != (off_t)-1)
4134 {
4135 read (fd, prehead, 3);
4136 if (!memcmp (prehead, "TAG", 3))
4137 {
4138 if (read (fd, prehead + 3, 128-3) != (128-3))
4139 {
4140 fprintf (stderr, "Failed to read offset -125, count 125\n");
4141 close (fd);
4142 return;
4143 }
4144 decode_id3v1x (prehead, lseek(fd, 0, SEEK_CUR)-128);
4145
4146 lseek (fd, -256, SEEK_END);
4147 read (fd, prehead, 3);
4148 if (!memcmp (prehead, "EXT", 3))
4149 {
4150 if (read (fd, prehead + 3, 125) != (125))
4151 {
4152 fprintf (stderr, "Failed to read offset -351, count 223\n");
4153 close (fd);
4154 return;
4155 }
4156 decode_id3v12 (prehead, lseek(fd, 0, SEEK_CUR)-256);
4157 }
4158
4159 lseek (fd, -355, SEEK_END);
4160 read (fd, prehead, 4);
4161 if (!memcmp (prehead, "TAG+", 4))
4162 {
4163 if (read (fd, prehead + 4, 227-4) != (227-4))
4164 {
4165 fprintf (stderr, "Failed to read offset -351, count 223\n");
4166 close (fd);
4167 return;
4168 }
4169 decode_etag (prehead, lseek(fd, 0, SEEK_CUR)-355);
4170 }
4171 }
4172 }
4173 lseek (fd, 0, SEEK_SET);
4174 fill=0;
4175 while (1)
4176 {
4177 read_more:
4178 fill += read (fd, prehead + fill, sizeof(prehead) - fill);
4179 if (fill < 10)
4180 {
4181 break;
4182 }
4183 while (fill >= 10)
4184 {
4185 uint8_t *loc;
4186
4187 if (need_sync)
4188 {
4189 if (memcmp(prehead, "ID3", 3))
4190 {
4191 if (prehead[0] != 0xff)
4192 {
4193 printf ("offset=0x%08lx not sync yet: %02x\n", lseek(fd, 0, SEEK_CUR)-fill, prehead[0]);
4194 fill -= 1;
4195 memmove (prehead, prehead+1, fill);
4196 continue;
4197 } else {
4198 need_sync = 0;
4199 }
4200 }
4201 }
4202
4203
4204 if ((loc = memmem (prehead, fill - 6, "ID3", 3)))
4205 {
4206 off_t decode_length;
4207 //printf ("fill=%d offset=0x%08lx loc-prehead=%d realoffset=0x%08lx\n", fill, (long int) lseek(fd, 0, SEEK_CUR), loc-prehead, lseek(fd, 0, SEEK_CUR)-fill+(loc-prehead));
4208 decode_length = decode_id3v2x(fd, loc, lseek(fd, 0, SEEK_CUR)-fill+(loc-prehead));
4209 if (decode_length)
4210 {
4211 lseek (fd, - fill + (loc-prehead) + decode_length, SEEK_CUR);
4212 fill = 0;
4213 need_sync = 1;
4214 goto read_more;
4215 } else {
4216 fill -= (loc-prehead)+10;
4217 memmove (prehead, loc+10, fill);
4218 }
4219 } else {
4220 break;
4221 }
4222 }
4223 memmove (prehead, prehead + fill - 9, 9);
4224 fill = 9;
4225 }
4226
4227 close (fd);
4228 fflush(stdout);
4229 }
4230
main(int argc,char * argv[])4231 int main(int argc, char *argv[])
4232 {
4233 int i;
4234
4235 if (argc < 2)
4236 {
4237 fprintf (stderr, "Usage: %s file\n", argv[0]);
4238 return -1;
4239 }
4240 if (!strcmp (argv[1], "-2"))
4241 {
4242 uint8_t buffer[65536];
4243 uint32_t fill;
4244 int32_t result;
4245 int fd;
4246 for (i=2; i < argc; i++)
4247 {
4248 fd = open (argv[i], O_RDONLY);
4249 if (fd < 0)
4250 {
4251 continue;
4252 }
4253 fill = read (fd, buffer, sizeof (buffer));
4254 close (fd);
4255 print("ID3v2.2.0 frame file: %s", argv[i]);newline();
4256 result = decode_id3v220_frame (buffer, fill);
4257 if (result < 0)
4258 {
4259 } else if (result != fill)
4260 {
4261 print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4262 }
4263 flush();
4264 }
4265 } else if (!strcmp (argv[1], "-3"))
4266 {
4267 uint8_t buffer[65536];
4268 uint32_t fill;
4269 int32_t result;
4270 int fd;
4271 for (i=2; i < argc; i++)
4272 {
4273 fd = open (argv[i], O_RDONLY);
4274 if (fd < 0)
4275 {
4276 continue;
4277 }
4278 fill = read (fd, buffer, sizeof (buffer));
4279 close (fd);
4280 print("ID3v2.3.0 frame file: %s", argv[i]);newline();
4281 result = decode_id3v230_frame (buffer, fill);
4282 if (result < 0)
4283 {
4284 } else if (result != fill)
4285 {
4286 print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4287 }
4288 flush();
4289 }
4290 } else if (!strcmp (argv[1], "-4"))
4291 {
4292 uint8_t buffer[65536];
4293 uint32_t fill;
4294 int32_t result;
4295 int fd;
4296 for (i=2; i < argc; i++)
4297 {
4298 fd = open (argv[i], O_RDONLY);
4299 if (fd < 0)
4300 {
4301 continue;
4302 }
4303 fill = read (fd, buffer, sizeof (buffer));
4304 close (fd);
4305 print("ID3v2.4.0 frame file: %s", argv[i]);newline();
4306 result = decode_id3v240_frame (buffer, fill);
4307 if (result < 0)
4308 {
4309 } else if (result != fill)
4310 {
4311 print("(EXTRA DATA AFTER FRAME: %d bytes", fill - result); newline();
4312 }
4313 flush();
4314 }
4315 } else {
4316 for (i=1; i < argc; i++)
4317 {
4318 scanfile(argv[i]);
4319 flush();
4320 }
4321 }
4322 return 0;
4323 }
4324