annotate decoders/libmpg123/id3.c @ 576:8d62447b75f2

Added new Core Audio backend.
author Eric Wing <ewing . public |-at-| gmail . com>
date Sun, 10 Oct 2010 21:30:17 -0700
parents 7e08477b0fc1
children
rev   line source
562
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 id3: ID3v2.3 and ID3v2.4 parsing (a relevant subset)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 copyright 2006-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 initially written by Thomas Orgis
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 #include "mpg123lib_intern.h"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 #include "id3.h"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11 #include "debug.h"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 /* UTF support definitions */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 typedef void (*text_converter)(mpg123_string *sb, unsigned char* source, size_t len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17 static void convert_latin1 (mpg123_string *sb, unsigned char* source, size_t len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 static void convert_utf16 (mpg123_string *sb, unsigned char* source, size_t len, int str_be);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19 static void convert_utf16bom(mpg123_string *sb, unsigned char* source, size_t len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 static void convert_utf16be (mpg123_string *sb, unsigned char* source, size_t len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 static void convert_utf8 (mpg123_string *sb, unsigned char* source, size_t len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 static const text_converter text_converters[4] =
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 convert_latin1,
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 convert_utf16bom,
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27 convert_utf16be,
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 convert_utf8
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 };
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31 const int encoding_widths[4] = { 1, 2, 2, 1 };
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33 /* the code starts here... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 static void null_id3_links(mpg123_handle *fr)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 fr->id3v2.title = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 fr->id3v2.artist = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39 fr->id3v2.album = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 fr->id3v2.year = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 fr->id3v2.genre = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 fr->id3v2.comment = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 void init_id3(mpg123_handle *fr)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 fr->id3v2.version = 0; /* nothing there */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 null_id3_links(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 fr->id3v2.comments = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50 fr->id3v2.comment_list = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51 fr->id3v2.texts = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52 fr->id3v2.text = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53 fr->id3v2.extras = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54 fr->id3v2.extra = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 /* Managing of the text, comment and extra lists. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59 /* Initialize one element. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60 static void init_mpg123_text(mpg123_text *txt)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 mpg123_init_string(&txt->text);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 mpg123_init_string(&txt->description);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64 txt->id[0] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 txt->id[1] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 txt->id[2] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67 txt->id[3] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 txt->lang[0] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 txt->lang[1] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 txt->lang[2] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 /* Free memory of one element. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74 static void free_mpg123_text(mpg123_text *txt)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76 mpg123_free_string(&txt->text);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77 mpg123_free_string(&txt->description);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 /* Free memory of whole list. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 #define free_comment(mh) free_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82 #define free_text(mh) free_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 #define free_extra(mh) free_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 static void free_id3_text(mpg123_text **list, size_t *size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86 size_t i;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87 for(i=0; i<*size; ++i) free_mpg123_text(&((*list)[i]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 free(*list);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 *list = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91 *size = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 /* Add items to the list. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95 #define add_comment(mh) add_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 #define add_text(mh) add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 #define add_extra(mh) add_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 static mpg123_text *add_id3_text(mpg123_text **list, size_t *size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100 mpg123_text *x = safe_realloc(*list, sizeof(mpg123_text)*(*size+1));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 if(x == NULL) return NULL; /* bad */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 *list = x;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 *size += 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 init_mpg123_text(&((*list)[*size-1]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107 return &((*list)[*size-1]); /* Return pointer to the added text. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 /* Remove the last item. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 #define pop_comment(mh) pop_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 #define pop_text(mh) pop_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 #define pop_extra(mh) pop_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114 static void pop_id3_text(mpg123_text **list, size_t *size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
115 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
116 mpg123_text *x;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
117 if(*size < 1) return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
118
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
119 free_mpg123_text(&((*list)[*size-1]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
120 if(*size > 1)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
121 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
122 x = safe_realloc(*list, sizeof(mpg123_text)*(*size-1));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
123 if(x != NULL){ *list = x; *size -= 1; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
124 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
125 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
126 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
127 free(*list);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
128 *list = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
129 *size = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
130 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
131 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
132
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
133 /* OK, back t the higher level functions. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
134
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
135 void exit_id3(mpg123_handle *fr)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
136 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
137 free_comment(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
138 free_extra(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
139 free_text(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
140 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
141
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
142 void reset_id3(mpg123_handle *fr)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
143 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
144 exit_id3(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
145 init_id3(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
146 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
147
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
148 /* Set the id3v2.artist id3v2.title ... links to elements of the array. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
149 void id3_link(mpg123_handle *fr)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
150 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
151 size_t i;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
152 mpg123_id3v2 *v2 = &fr->id3v2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
153 debug("linking ID3v2");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
154 null_id3_links(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
155 for(i=0; i<v2->texts; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
156 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
157 mpg123_text *entry = &v2->text[i];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
158 if (!strncmp("TIT2", entry->id, 4)) v2->title = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
159 else if(!strncmp("TALB", entry->id, 4)) v2->album = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
160 else if(!strncmp("TPE1", entry->id, 4)) v2->artist = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
161 else if(!strncmp("TYER", entry->id, 4)) v2->year = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
162 else if(!strncmp("TCON", entry->id, 4)) v2->genre = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
163 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
164 for(i=0; i<v2->comments; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
165 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
166 mpg123_text *entry = &v2->comment_list[i];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
167 if(entry->description.fill == 0 || entry->description.p[0] == 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
168 v2->comment = &entry->text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
169 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
170 /* When no generic comment found, use the last non-generic one. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
171 if(v2->comment == NULL && v2->comments > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
172 v2->comment = &v2->comment_list[v2->comments-1].text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
173 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
174
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
175 /*
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
176 Store any text in UTF8 encoding; preserve the zero string separator (I don't need strlen for the total size).
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
177 ID3v2 standard says that there should be one text frame of specific type per tag, and subsequent tags overwrite old values.
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
178 So, I always replace the text that may be stored already (perhaps with a list of zero-separated strings, though).
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
179 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
180 void store_id3_text(mpg123_string *sb, char *source, size_t source_size, const int noquiet)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
181 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
182 int encoding;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
183 int bwidth;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
184 if(!source_size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
185 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
186 debug("Empty id3 data!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
187 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
188 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
189 encoding = source[0];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
190 ++source;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
191 --source_size;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
192 debug1("encoding: %i", encoding);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
193 /* A note: ID3v2.3 uses UCS-2 non-variable 16bit encoding, v2.4 uses UTF16.
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
194 UTF-16 uses a reserved/private range in UCS-2 to add the magic, so we just always treat it as UTF. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
195 if(encoding > 3)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
196 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
197 if(noquiet) warning1("Unknown text encoding %d, assuming ISO8859-1 - I will probably screw a bit up!", encoding);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
198 encoding = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
199 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
200 bwidth = encoding_widths[encoding];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
201 /* Hack! I've seen a stray zero byte before BOM. Is that supposed to happen? */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
202 while(source_size > bwidth && source[0] == 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
203 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
204 --source_size;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
205 ++source;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
206 debug("skipped leading zero");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
207 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
208 if(source_size % bwidth)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
209 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
210 /* When we need two bytes for a character, it's strange to have an uneven bytestream length. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
211 if(noquiet) warning2("Weird tag size %d for encoding %d - I will probably trim too early or something but I think the MP3 is broken.", (int)source_size, encoding);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
212 source_size -= source_size % bwidth;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
213 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
214 text_converters[encoding](sb, (unsigned char*)source, source_size);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
215 if(sb->size) debug1("UTF-8 string (the first one): %s", sb->p);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
216 else if(noquiet) error("unable to convert string to UTF-8 (out of memory, junk input?)!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
217 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
218
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
219 char *next_text(char* prev, int encoding, size_t limit)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
220 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
221 char *text = prev;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
222 unsigned long neednull = encoding_widths[encoding];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
223 /* So I go lengths to find zero or double zero... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
224 while(text-prev < limit)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
225 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
226 if(text[0] == 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
227 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
228 if(neednull <= limit-(text-prev))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
229 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
230 unsigned long i = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
231 for(; i<neednull; ++i) if(text[i] != 0) break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
232
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
233 if(i == neednull) /* found a null wide enough! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
234 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
235 text += neednull;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
236 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
237 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
238 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
239 else{ text = NULL; break; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
240 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
241 ++text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
242 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
243 if(text-prev == limit) text = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
244
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
245 return text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
246 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
247
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
248 static const char *enc_name(int enc)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
249 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
250 switch(enc)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
251 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
252 case 0: return "Latin 1";
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
253 case 1: return "UTF-16 BOM";
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
254 case 2: return "UTF-16 BE";
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
255 case 3: return "UTF-8";
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
256 default: return "unknown!";
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
257 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
258 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
259
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
260 static void process_text(mpg123_handle *fr, char *realdata, size_t realsize, char *id)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
261 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
262 /* Text encoding $xx */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
263 /* The text (encoded) ... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
264 mpg123_text *t = add_text(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
265 if(VERBOSE4) fprintf(stderr, "Note: Storing text from %s encoding\n", enc_name(realdata[0]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
266 if(t == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
267 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
268 if(NOQUIET) error("Unable to attach new text!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
269 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
270 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
271 memcpy(t->id, id, 4);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
272 store_id3_text(&t->text, realdata, realsize, NOQUIET);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
273 if(VERBOSE4) fprintf(stderr, "Note: ID3v2 %c%c%c%c text frame: %s\n", id[0], id[1], id[2], id[3], t->text.p);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
274 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
275
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
276 /* Store a new comment that perhaps is a RVA / RVA_ALBUM/AUDIOPHILE / RVA_MIX/RADIO one */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
277 static void process_comment(mpg123_handle *fr, char *realdata, size_t realsize, int rva_level, char *id)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
278 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
279 /* Text encoding $xx */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
280 /* Language $xx xx xx */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
281 /* Short description (encoded!) <text> $00 (00) */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
282 /* Then the comment text (encoded) ... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
283 char encoding = realdata[0];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
284 char *lang = realdata+1; /* I'll only use the 3 bytes! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
285 char *descr = realdata+4;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
286 char *text = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
287 mpg123_text *xcom = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
288 if(realsize < descr-realdata)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
289 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
290 if(NOQUIET) error1("Invalid frame size of %lu (too small for anything).", (unsigned long)realsize);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
291 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
292 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
293 xcom = add_comment(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
294 if(VERBOSE4) fprintf(stderr, "Note: Storing comment from %s encoding\n", enc_name(realdata[0]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
295 if(xcom == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
296 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
297 if(NOQUIET) error("Unable to attach new comment!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
298 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
299 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
300 memcpy(xcom->lang, lang, 3);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
301 memcpy(xcom->id, id, 4);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
302 /* Now I can abuse a byte from lang for the encoding. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
303 descr[-1] = encoding;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
304 /* Be careful with finding the end of description, I have to honor encoding here. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
305 text = next_text(descr, encoding, realsize-(descr-realdata));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
306 if(text == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
307 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
308 if(NOQUIET) error("No comment text / valid description?");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
309 pop_comment(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
310 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
311 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
312 store_id3_text(&xcom->description, descr-1, text-descr+1, NOQUIET);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
313 text[-1] = encoding;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
314 store_id3_text(&xcom->text, text-1, realsize+1-(text-realdata), NOQUIET);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
315
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
316 if(VERBOSE4)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
317 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
318 fprintf(stderr, "Note: ID3 comment desc: %s\n", xcom->description.fill > 0 ? xcom->description.p : "");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
319 fprintf(stderr, "Note: ID3 comment text: %s\n", xcom->text.fill > 0 ? xcom->text.p : "");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
320 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
321 if(xcom->description.fill > 0 && xcom->text.fill > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
322 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
323 int rva_mode = -1; /* mix / album */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
324 if( !strcasecmp(xcom->description.p, "rva")
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
325 || !strcasecmp(xcom->description.p, "rva_mix")
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
326 || !strcasecmp(xcom->description.p, "rva_track")
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
327 || !strcasecmp(xcom->description.p, "rva_radio"))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
328 rva_mode = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
329 else if( !strcasecmp(xcom->description.p, "rva_album")
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
330 || !strcasecmp(xcom->description.p, "rva_audiophile")
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
331 || !strcasecmp(xcom->description.p, "rva_user"))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
332 rva_mode = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
333 if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
334 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
335 fr->rva.gain[rva_mode] = atof(xcom->text.p);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
336 if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
337 fr->rva.peak[rva_mode] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
338 fr->rva.level[rva_mode] = rva_level;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
339 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
340 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
341 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
342
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
343 void process_extra(mpg123_handle *fr, char* realdata, size_t realsize, int rva_level, char *id)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
344 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
345 /* Text encoding $xx */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
346 /* Description ... $00 (00) */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
347 /* Text ... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
348 char encoding = realdata[0];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
349 char *descr = realdata+1; /* remember, the encoding is descr[-1] */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
350 char *text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
351 mpg123_text *xex;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
352 if(realsize < descr-realdata)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
353 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
354 if(NOQUIET) error1("Invalid frame size of %lu (too small for anything).", (unsigned long)realsize);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
355 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
356 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
357 text = next_text(descr, encoding, realsize-(descr-realdata));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
358 if(VERBOSE4) fprintf(stderr, "Note: Storing extra from %s encoding\n", enc_name(realdata[0]));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
359 if(text == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
360 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
361 if(NOQUIET) error("No extra frame text / valid description?");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
362 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
363 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
364 xex = add_extra(fr);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
365 if(xex == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
366 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
367 if(NOQUIET) error("Unable to attach new extra text!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
368 return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
369 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
370 memcpy(xex->id, id, 4);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
371 store_id3_text(&xex->description, descr-1, text-descr+1, NOQUIET);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
372 text[-1] = encoding;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
373 store_id3_text(&xex->text, text-1, realsize-(text-realdata)+1, NOQUIET);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
374 if(xex->description.fill > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
375 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
376 int is_peak = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
377 int rva_mode = -1; /* mix / album */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
378
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
379 if(!strncasecmp(xex->description.p, "replaygain_track_",17))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
380 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
381 if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain track gain/peak\n");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
382
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
383 rva_mode = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
384 if(!strcasecmp(xex->description.p, "replaygain_track_peak")) is_peak = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
385 else if(strcasecmp(xex->description.p, "replaygain_track_gain")) rva_mode = -1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
386 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
387 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
388 if(!strncasecmp(xex->description.p, "replaygain_album_",17))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
389 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
390 if(VERBOSE3) fprintf(stderr, "Note: RVA ReplayGain album gain/peak\n");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
391
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
392 rva_mode = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
393 if(!strcasecmp(xex->description.p, "replaygain_album_peak")) is_peak = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
394 else if(strcasecmp(xex->description.p, "replaygain_album_gain")) rva_mode = -1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
395 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
396 if((rva_mode > -1) && (fr->rva.level[rva_mode] <= rva_level))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
397 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
398 if(xex->text.fill > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
399 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
400 if(is_peak)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
401 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
402 fr->rva.peak[rva_mode] = atof(xex->text.p);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
403 if(VERBOSE3) fprintf(stderr, "Note: RVA peak %f\n", fr->rva.peak[rva_mode]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
404 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
405 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
406 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
407 fr->rva.gain[rva_mode] = atof(xex->text.p);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
408 if(VERBOSE3) fprintf(stderr, "Note: RVA gain %fdB\n", fr->rva.gain[rva_mode]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
409 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
410 fr->rva.level[rva_mode] = rva_level;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
411 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
412 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
413 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
414 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
415
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
416 /* Make a ID3v2.3+ 4-byte ID from a ID3v2.2 3-byte ID
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
417 Note that not all frames survived to 2.4; the mapping goes to 2.3 .
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
418 A notable miss is the old RVA frame, which is very unspecific anyway.
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
419 This function returns -1 when a not known 3 char ID was encountered, 0 otherwise. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
420 int promote_framename(mpg123_handle *fr, char *id) /* fr because of VERBOSE macros */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
421 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
422 size_t i;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
423 char *old[] =
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
424 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
425 "COM", "TAL", "TBP", "TCM", "TCO", "TCR", "TDA", "TDY", "TEN", "TFT",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
426 "TIM", "TKE", "TLA", "TLE", "TMT", "TOA", "TOF", "TOL", "TOR", "TOT",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
427 "TP1", "TP2", "TP3", "TP4", "TPA", "TPB", "TRC", "TDA", "TRK", "TSI",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
428 "TSS", "TT1", "TT2", "TT3", "TXT", "TXX", "TYE"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
429 };
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
430 char *new[] =
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
431 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
432 "COMM", "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDAT", "TDLY", "TENC", "TFLT",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
433 "TIME", "TKEY", "TLAN", "TLEN", "TMED", "TOPE", "TOFN", "TOLY", "TORY", "TOAL",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
434 "TPE1", "TPE2", "TPE3", "TPE4", "TPOS", "TPUB", "TSRC", "TRDA", "TRCK", "TSIZ",
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
435 "TSSE", "TIT1", "TIT2", "TIT3", "TEXT", "TXXX", "TYER"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
436 };
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
437 for(i=0; i<sizeof(old)/sizeof(char*); ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
438 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
439 if(!strncmp(id, old[i], 3))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
440 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
441 memcpy(id, new[i], 4);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
442 if(VERBOSE3) fprintf(stderr, "Translated ID3v2.2 frame %s to %s\n", old[i], new[i]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
443 return 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
444 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
445 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
446 if(VERBOSE3) fprintf(stderr, "Ignoring untranslated ID3v2.2 frame %c%c%c\n", id[0], id[1], id[2]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
447 return -1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
448 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
449
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
450 /*
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
451 trying to parse ID3v2.3 and ID3v2.4 tags...
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
452
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
453 returns: 0: bad or just unparseable tag
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
454 1: good, (possibly) new tag info
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
455 <0: reader error (may need more data feed, try again)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
456 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
457 int parse_new_id3(mpg123_handle *fr, unsigned long first4bytes)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
458 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
459 #define UNSYNC_FLAG 128
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
460 #define EXTHEAD_FLAG 64
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
461 #define EXP_FLAG 32
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
462 #define FOOTER_FLAG 16
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
463 #define UNKNOWN_FLAGS 15 /* 00001111*/
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
464 unsigned char buf[6];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
465 unsigned long length=0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
466 unsigned char flags = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
467 int ret = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
468 int ret2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
469 unsigned char* tagdata = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
470 unsigned char major = first4bytes & 0xff;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
471 debug1("ID3v2: major tag version: %i", major);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
472 if(major == 0xff) return 0; /* Invalid... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
473 if((ret2 = fr->rd->read_frame_body(fr, buf, 6)) < 0) /* read more header information */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
474 return ret2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
475
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
476 if(buf[0] == 0xff) return 0; /* Revision, will never be 0xff. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
477
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
478 /* second new byte are some nice flags, if these are invalid skip the whole thing */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
479 flags = buf[1];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
480 debug1("ID3v2: flags 0x%08x", flags);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
481 /* use 4 bytes from buf to construct 28bit uint value and return 1; return 0 if bytes are not synchsafe */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
482 #define synchsafe_to_long(buf,res) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
483 ( \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
484 (((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
485 (res = (((unsigned long) (buf)[0]) << 21) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
486 | (((unsigned long) (buf)[1]) << 14) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
487 | (((unsigned long) (buf)[2]) << 7) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
488 | ((unsigned long) (buf)[3]) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
489 ,1) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
490 )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
491 /* id3v2.3 does not store synchsafe frame sizes, but synchsafe tag size - doh! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
492 #define bytes_to_long(buf,res) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
493 ( \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
494 major == 3 ? \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
495 (res = (((unsigned long) (buf)[0]) << 24) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
496 | (((unsigned long) (buf)[1]) << 16) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
497 | (((unsigned long) (buf)[2]) << 8) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
498 | ((unsigned long) (buf)[3]) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
499 ,1) : synchsafe_to_long(buf,res) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
500 )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
501 /* for id3v2.2 only */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
502 #define threebytes_to_long(buf,res) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
503 ( \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
504 res = (((unsigned long) (buf)[0]) << 16) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
505 | (((unsigned long) (buf)[1]) << 8) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
506 | ((unsigned long) (buf)[2]) \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
507 ,1 \
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
508 )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
509
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
510 /* length-10 or length-20 (footer present); 4 synchsafe integers == 28 bit number */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
511 /* we have already read 10 bytes, so left are length or length+10 bytes belonging to tag */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
512 if(!synchsafe_to_long(buf+2,length))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
513 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
514 if(NOQUIET) error4("Bad tag length (not synchsafe): 0x%02x%02x%02x%02x; You got a bad ID3 tag here.", buf[2],buf[3],buf[4],buf[5]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
515 return 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
516 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
517 debug1("ID3v2: tag data length %lu", length);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
518 if(VERBOSE2) fprintf(stderr,"Note: ID3v2.%i rev %i tag of %lu bytes\n", major, buf[0], length);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
519 /* skip if unknown version/scary flags, parse otherwise */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
520 if((flags & UNKNOWN_FLAGS) || (major > 4) || (major < 2))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
521 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
522 /* going to skip because there are unknown flags set */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
523 if(NOQUIET) warning2("ID3v2: Won't parse the ID3v2 tag with major version %u and flags 0x%xu - some extra code may be needed", major, flags);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
524 if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) /* will not store data in backbuff! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
525 ret = ret2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
526 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
527 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
528 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
529 fr->id3v2.version = major;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
530 /* try to interpret that beast */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
531 if((tagdata = (unsigned char*) malloc(length+1)) != NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
532 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
533 debug("ID3v2: analysing frames...");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
534 if((ret2 = fr->rd->read_frame_body(fr,tagdata,length)) > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
535 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
536 unsigned long tagpos = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
537 debug1("ID3v2: have read at all %lu bytes for the tag now", (unsigned long)length+6);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
538 /* going to apply strlen for strings inside frames, make sure that it doesn't overflow! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
539 tagdata[length] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
540 if(flags & EXTHEAD_FLAG)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
541 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
542 debug("ID3v2: skipping extended header");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
543 if(!bytes_to_long(tagdata, tagpos))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
544 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
545 ret = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
546 if(NOQUIET) error4("Bad (non-synchsafe) tag offset: 0x%02x%02x%02x%02x", tagdata[0], tagdata[1], tagdata[2], tagdata[3]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
547 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
548 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
549 if(ret > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
550 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
551 char id[5];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
552 unsigned long framesize;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
553 unsigned long fflags; /* need 16 bits, actually */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
554 id[4] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
555 /* pos now advanced after ext head, now a frame has to follow */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
556 while(tagpos < length-10) /* I want to read at least a full header */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
557 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
558 int i = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
559 unsigned long pos = tagpos;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
560 int head_part = fr->id3v2.version == 2 ? 3 : 4; /* bytes of frame title and of framesize value */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
561 /* level 1,2,3 - 0 is info from lame/info tag! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
562 /* rva tags with ascending significance, then general frames */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
563 #define KNOWN_FRAMES 3
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
564 const char frame_type[KNOWN_FRAMES][5] = { "COMM", "TXXX", "RVA2" }; /* plus all text frames... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
565 enum { unknown = -2, text = -1, comment, extra, rva2 } tt = unknown;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
566 /* we may have entered the padding zone or any other strangeness: check if we have valid frame id characters */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
567 for(i=0; i< head_part; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
568 if( !( ((tagdata[tagpos+i] > 47) && (tagdata[tagpos+i] < 58))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
569 || ((tagdata[tagpos+i] > 64) && (tagdata[tagpos+i] < 91)) ) )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
570 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
571 debug5("ID3v2: real tag data apparently ended after %lu bytes with 0x%02x%02x%02x%02x", tagpos, tagdata[tagpos], tagdata[tagpos+1], tagdata[tagpos+2], tagdata[tagpos+3]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
572 /* This is no hard error... let's just hope that we got something meaningful already (ret==1 in that case). */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
573 goto tagparse_cleanup; /* Need to escape two loops here. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
574 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
575 if(ret > 0)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
576 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
577 /* 4 or 3 bytes id */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
578 strncpy(id, (char*) tagdata+pos, head_part);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
579 pos += head_part;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
580 tagpos += head_part;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
581 /* size as 32 bits or 28 bits */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
582 if(fr->id3v2.version == 2) threebytes_to_long(tagdata+pos, framesize);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
583 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
584 if(!bytes_to_long(tagdata+pos, framesize))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
585 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
586 /* Just assume that up to now there was some good data. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
587 if(NOQUIET) error1("ID3v2: non-syncsafe size of %s frame, skipping the remainder of tag", id);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
588 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
589 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
590 if(VERBOSE3) fprintf(stderr, "Note: ID3v2 %s frame of size %lu\n", id, framesize);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
591 tagpos += head_part + framesize; /* the important advancement in whole tag */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
592 if(tagpos > length)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
593 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
594 if(NOQUIET) error("Whoa! ID3v2 frame claims to be larger than the whole rest of the tag.");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
595 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
596 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
597 pos += head_part;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
598 if(fr->id3v2.version > 2)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
599 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
600 fflags = (((unsigned long) tagdata[pos]) << 8) | ((unsigned long) tagdata[pos+1]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
601 pos += 2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
602 tagpos += 2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
603 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
604 else fflags = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
605 /* for sanity, after full parsing tagpos should be == pos */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
606 /* debug4("ID3v2: found %s frame, size %lu (as bytes: 0x%08lx), flags 0x%016lx", id, framesize, framesize, fflags); */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
607 /* %0abc0000 %0h00kmnp */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
608 #define BAD_FFLAGS (unsigned long) 36784
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
609 #define PRES_TAG_FFLAG 16384
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
610 #define PRES_FILE_FFLAG 8192
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
611 #define READ_ONLY_FFLAG 4096
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
612 #define GROUP_FFLAG 64
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
613 #define COMPR_FFLAG 8
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
614 #define ENCR_FFLAG 4
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
615 #define UNSYNC_FFLAG 2
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
616 #define DATLEN_FFLAG 1
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
617 if(head_part < 4 && promote_framename(fr, id) != 0) continue;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
618
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
619 /* shall not or want not handle these */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
620 if(fflags & (BAD_FFLAGS | COMPR_FFLAG | ENCR_FFLAG))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
621 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
622 if(NOQUIET) warning("ID3v2: skipping invalid/unsupported frame");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
623 continue;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
624 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
625
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
626 for(i = 0; i < KNOWN_FRAMES; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
627 if(!strncmp(frame_type[i], id, 4)){ tt = i; break; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
628
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
629 if(id[0] == 'T' && tt != extra) tt = text;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
630
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
631 if(tt != unknown)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
632 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
633 int rva_mode = -1; /* mix / album */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
634 unsigned long realsize = framesize;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
635 unsigned char* realdata = tagdata+pos;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
636 if((flags & UNSYNC_FLAG) || (fflags & UNSYNC_FFLAG))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
637 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
638 unsigned long ipos = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
639 unsigned long opos = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
640 debug("Id3v2: going to de-unsync the frame data");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
641 /* de-unsync: FF00 -> FF; real FF00 is simply represented as FF0000 ... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
642 /* damn, that means I have to delete bytes from withing the data block... thus need temporal storage */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
643 /* standard mandates that de-unsync should always be safe if flag is set */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
644 realdata = (unsigned char*) malloc(framesize); /* will need <= bytes */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
645 if(realdata == NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
646 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
647 if(NOQUIET) error("ID3v2: unable to allocate working buffer for de-unsync");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
648 continue;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
649 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
650 /* now going byte per byte through the data... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
651 realdata[0] = tagdata[pos];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
652 opos = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
653 for(ipos = pos+1; ipos < pos+framesize; ++ipos)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
654 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
655 if(!((tagdata[ipos] == 0) && (tagdata[ipos-1] == 0xff)))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
656 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
657 realdata[opos++] = tagdata[ipos];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
658 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
659 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
660 realsize = opos;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
661 debug2("ID3v2: de-unsync made %lu out of %lu bytes", realsize, framesize);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
662 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
663 pos = 0; /* now at the beginning again... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
664 switch(tt)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
665 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
666 case comment:
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
667 process_comment(fr, (char*)realdata, realsize, comment+1, id);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
668 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
669 case extra: /* perhaps foobar2000's work */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
670 process_extra(fr, (char*)realdata, realsize, extra+1, id);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
671 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
672 case rva2: /* "the" RVA tag */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
673 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
674 #ifdef HAVE_INTTYPES_H
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
675 /* starts with null-terminated identification */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
676 if(VERBOSE3) fprintf(stderr, "Note: RVA2 identification \"%s\"\n", realdata);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
677 /* default: some individual value, mix mode */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
678 rva_mode = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
679 if( !strncasecmp((char*)realdata, "album", 5)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
680 || !strncasecmp((char*)realdata, "audiophile", 10)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
681 || !strncasecmp((char*)realdata, "user", 4))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
682 rva_mode = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
683 if(fr->rva.level[rva_mode] <= rva2+1)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
684 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
685 pos += strlen((char*) realdata) + 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
686 if(realdata[pos] == 1)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
687 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
688 ++pos;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
689 /* only handle master channel */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
690 debug("ID3v2: it is for the master channel");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
691 /* two bytes adjustment, one byte for bits representing peak - n bytes for peak */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
692 /* 16 bit signed integer = dB * 512 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
693 /* we already assume short being 16 bit */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
694 fr->rva.gain[rva_mode] = (float) ((((short) realdata[pos]) << 8) | ((short) realdata[pos+1])) / 512;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
695 pos += 2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
696 if(VERBOSE3) fprintf(stderr, "Note: RVA value %fdB\n", fr->rva.gain[rva_mode]);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
697 /* heh, the peak value is represented by a number of bits - but in what manner? Skipping that part */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
698 fr->rva.peak[rva_mode] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
699 fr->rva.level[rva_mode] = rva2+1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
700 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
701 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
702 #else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
703 if(NOQUIET) warning("ID3v2: Cannot parse RVA2 value because I don't have a guaranteed 16 bit signed integer type");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
704 #endif
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
705 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
706 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
707 /* non-rva metainfo, simply store... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
708 case text:
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
709 process_text(fr, (char*)realdata, realsize, id);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
710 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
711 default: if(NOQUIET) error1("ID3v2: unknown frame type %i", tt);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
712 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
713 if((flags & UNSYNC_FLAG) || (fflags & UNSYNC_FFLAG)) free(realdata);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
714 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
715 #undef BAD_FFLAGS
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
716 #undef PRES_TAG_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
717 #undef PRES_FILE_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
718 #undef READ_ONLY_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
719 #undef GROUP_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
720 #undef COMPR_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
721 #undef ENCR_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
722 #undef UNSYNC_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
723 #undef DATLEN_FFLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
724 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
725 else break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
726 #undef KNOWN_FRAMES
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
727 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
728 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
729 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
730 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
731 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
732 if(NOQUIET) error("ID3v2: Duh, not able to read ID3v2 tag data.");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
733 ret = ret2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
734 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
735 tagparse_cleanup:
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
736 free(tagdata);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
737 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
738 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
739 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
740 if(NOQUIET) error1("ID3v2: Arrg! Unable to allocate %lu bytes for interpreting ID3v2 data - trying to skip instead.", length);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
741 if((ret2 = fr->rd->skip_bytes(fr,length)) < 0) ret = ret2; /* will not store data in backbuff! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
742 else ret = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
743 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
744 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
745 /* skip footer if present */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
746 if((ret > 0) && (flags & FOOTER_FLAG) && ((ret2 = fr->rd->skip_bytes(fr,length)) < 0)) ret = ret2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
747
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
748 return ret;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
749 #undef UNSYNC_FLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
750 #undef EXTHEAD_FLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
751 #undef EXP_FLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
752 #undef FOOTER_FLAG
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
753 #undef UNKOWN_FLAGS
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
754 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
755
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
756 static void convert_latin1(mpg123_string *sb, unsigned char* s, size_t l)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
757 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
758 size_t length = l;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
759 size_t i;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
760 unsigned char *p;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
761 /* determine real length, a latin1 character can at most take 2 in UTF8 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
762 for(i=0; i<l; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
763 if(s[i] >= 0x80) ++length;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
764
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
765 debug1("UTF-8 length: %lu", (unsigned long)length);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
766 /* one extra zero byte for paranoia */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
767 if(!mpg123_resize_string(sb, length+1)){ mpg123_free_string(sb); return ; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
768
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
769 p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
770 for(i=0; i<l; ++i)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
771 if(s[i] < 0x80){ *p = s[i]; ++p; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
772 else /* two-byte encoding */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
773 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
774 *p = 0xc0 | (s[i]>>6);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
775 *(p+1) = 0x80 | (s[i] & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
776 p+=2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
777 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
778
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
779 sb->p[length] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
780 sb->fill = length+1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
781 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
782
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
783 #define FULLPOINT(f,s) ( (((f)&0x3ff)<<10) + ((s)&0x3ff) + 0x10000 )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
784 /* Remember: There's a limit at 0x1ffff. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
785 #define UTF8LEN(x) ( (x)<0x80 ? 1 : ((x)<0x800 ? 2 : ((x)<0x10000 ? 3 : 4)))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
786 static void convert_utf16(mpg123_string *sb, unsigned char* s, size_t l, int str_be)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
787 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
788 size_t i;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
789 unsigned char *p;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
790 size_t length = 0; /* the resulting UTF-8 length */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
791 /* Determine real length... extreme case can be more than utf-16 length. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
792 size_t high = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
793 size_t low = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
794 debug1("convert_utf16 with length %lu", (unsigned long)l);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
795 if(!str_be) /* little-endian */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
796 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
797 high = 1; /* The second byte is the high byte. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
798 low = 0; /* The first byte is the low byte. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
799 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
800 /* first: get length, check for errors -- stop at first one */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
801 for(i=0; i < l-1; i+=2)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
802 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
803 unsigned long point = ((unsigned long) s[i+high]<<8) + s[i+low];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
804 if((point & 0xd800) == 0xd800) /* lead surrogate */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
805 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
806 unsigned short second = (i+3 < l) ? (s[i+2+high]<<8) + s[i+2+low] : 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
807 if((second & 0xdc00) == 0xdc00) /* good... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
808 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
809 point = FULLPOINT(point,second);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
810 length += UTF8LEN(point); /* possibly 4 bytes */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
811 i+=2; /* We overstepped one word. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
812 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
813 else /* if no valid pair, break here */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
814 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
815 debug1("Invalid UTF16 surrogate pair at %li.", (unsigned long)i);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
816 l = i; /* Forget the half pair, END! */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
817 break;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
818 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
819 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
820 else length += UTF8LEN(point); /* 1,2 or 3 bytes */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
821 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
822
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
823 if(l < 1){ mpg123_set_string(sb, ""); return; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
824
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
825 if(!mpg123_resize_string(sb, length+1)){ mpg123_free_string(sb); return ; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
826
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
827 /* Now really convert, skip checks as these have been done just before. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
828 p = (unsigned char*) sb->p; /* Signedness doesn't matter but it shows I thought about the non-issue */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
829 for(i=0; i < l-1; i+=2)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
830 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
831 unsigned long codepoint = ((unsigned long) s[i+high]<<8) + s[i+low];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
832 if((codepoint & 0xd800) == 0xd800) /* lead surrogate */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
833 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
834 unsigned short second = (s[i+2+high]<<8) + s[i+2+low];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
835 codepoint = FULLPOINT(codepoint,second);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
836 i+=2; /* We overstepped one word. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
837 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
838 if(codepoint < 0x80) *p++ = (unsigned char) codepoint;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
839 else if(codepoint < 0x800)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
840 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
841 *p++ = 0xc0 | (codepoint>>6);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
842 *p++ = 0x80 | (codepoint & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
843 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
844 else if(codepoint < 0x10000)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
845 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
846 *p++ = 0xe0 | (codepoint>>12);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
847 *p++ = 0x80 | ((codepoint>>6) & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
848 *p++ = 0x80 | (codepoint & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
849 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
850 else if (codepoint < 0x200000)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
851 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
852 *p++ = 0xf0 | codepoint>>18;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
853 *p++ = 0x80 | ((codepoint>>12) & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
854 *p++ = 0x80 | ((codepoint>>6) & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
855 *p++ = 0x80 | (codepoint & 0x3f);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
856 } /* ignore bigger ones (that are not possible here anyway) */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
857 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
858 sb->p[sb->size-1] = 0; /* paranoia... */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
859 sb->fill = sb->size;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
860 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
861 #undef UTF8LEN
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
862 #undef FULLPOINT
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
863
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
864 static void convert_utf16be(mpg123_string *sb, unsigned char* source, size_t len)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
865 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
866 convert_utf16(sb, source, len, 1);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
867 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
868
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
869 static void convert_utf16bom(mpg123_string *sb, unsigned char* source, size_t len)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
870 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
871 if(len < 2){ mpg123_free_string(sb); return; }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
872
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
873 if(source[0] == 0xff && source[1] == 0xfe) /* Little-endian */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
874 convert_utf16(sb, source + 2, len - 2, 0);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
875 else /* Big-endian */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
876 convert_utf16(sb, source + 2, len - 2, 1);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
877 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
878
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
879 static void convert_utf8(mpg123_string *sb, unsigned char* source, size_t len)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
880 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
881 if(mpg123_resize_string(sb, len+1))
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
882 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
883 memcpy(sb->p, source, len);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
884 sb->p[len] = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
885 sb->fill = len+1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
886 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
887 else mpg123_free_string(sb);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
888 }