summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-05-09 07:10:07 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-05-09 07:10:07 +0000
commit20eb5f48e5212d9eeb6c7d2ab531f62bb16380a5 (patch)
tree5b928604887affad38da9b83adfd79240ab6a8f8
parent52a8a540b14313aa83bee0fb9eca4502f86eb9f7 (diff)
downloadrockbox-20eb5f48e5212d9eeb6c7d2ab531f62bb16380a5.tar.gz
rockbox-20eb5f48e5212d9eeb6c7d2ab531f62bb16380a5.zip
wave/wave64 LIST chunk parser
- logic simplify - tag data always ends by the '\0' terminate. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25911 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/metadata/wave.c128
1 files changed, 40 insertions, 88 deletions
diff --git a/apps/metadata/wave.c b/apps/metadata/wave.c
index 564d028140..e34c740aa5 100644
--- a/apps/metadata/wave.c
+++ b/apps/metadata/wave.c
@@ -76,35 +76,29 @@ static const unsigned char *wave64_chunklist
76 "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a" 76 "data\xf3\xac\xd3\x11\x8c\xd1\x00\xc0\x4f\x8e\xdb\x8a"
77 "\xbc\x94\x5f\x92\x5a\x52\xd2\x11\x86\xdc\x00\xc0\x4f\x8e\xdb\x8a"; 77 "\xbc\x94\x5f\x92\x5a\x52\xd2\x11\x86\xdc\x00\xc0\x4f\x8e\xdb\x8a";
78 78
79enum { 79/* list/info chunk */
80 INFO_TITLE = 0, 80
81 INFO_ARTIST, 81struct info_chunk {
82 INFO_ALBUM_ARTIST, 82 const unsigned char* tag;
83 INFO_ALBUM, 83 size_t offset;
84 INFO_COMPOSER,
85 INFO_COMMENT,
86 INFO_GROUPING,
87 INFO_GENRE,
88 INFO_DATE,
89 INFO_TRACK,
90 INFO_DISC,
91}; 84};
92 85
93/* info chunk names are common wave/wave64 */ 86/* info chunk names are common wave/wave64 */
94static const unsigned char infochunk_list[][4] 87static const struct info_chunk info_chunks[] = {
95 = { 88 { "INAM", offsetof(struct mp3entry, title), }, /* title */
96 "INAM", /* title */ 89 { "IART", offsetof(struct mp3entry, artist), }, /* artist */
97 "IART", /* artist */ 90 { "ISBJ", offsetof(struct mp3entry, albumartist), }, /* albumartist */
98 "ISBJ", /* albumartist */ 91 { "IPRD", offsetof(struct mp3entry, album), }, /* album */
99 "IPRD", /* album */ 92 { "IWRI", offsetof(struct mp3entry, composer), }, /* composer */
100 "IWRI", /* composer */ 93 { "ICMT", offsetof(struct mp3entry, comment), }, /* comment */
101 "ICMT", /* comment */ 94 { "ISRF", offsetof(struct mp3entry, grouping), }, /* grouping */
102 "ISRF", /* grouping */ 95 { "IGNR", offsetof(struct mp3entry, genre_string), }, /* genre */
103 "IGNR", /* genre */ 96 { "ICRD", offsetof(struct mp3entry, year_string), }, /* date */
104 "ICRD", /* date */ 97 { "IPRT", offsetof(struct mp3entry, track_string), }, /* track/trackcount */
105 "IPRT", /* track/trackcount */ 98 { "IFRM", offsetof(struct mp3entry, disc_string), }, /* disc/disccount */
106 "IFRM", /* disc/disccount */ 99};
107 }; 100
101#define INFO_CHUNK_COUNT ((int)ARRAYLEN(info_chunks))
108 102
109/* support formats */ 103/* support formats */
110enum 104enum
@@ -135,11 +129,9 @@ struct wave_fmt {
135 uint64_t numbytes; 129 uint64_t numbytes;
136}; 130};
137 131
138static unsigned char *convert_utf8(unsigned char *src, unsigned char *dst, 132static unsigned char *convert_utf8(const unsigned char *src, unsigned char *dst,
139 int datasize, int bufsize, bool is_64) 133 int size, bool is_64)
140{ 134{
141 int size = (datasize > bufsize)? bufsize : datasize;
142
143 if (is_64) 135 if (is_64)
144 { 136 {
145 /* Note: wave64: metadata codepage is UTF-16 only */ 137 /* Note: wave64: metadata codepage is UTF-16 only */
@@ -243,90 +235,50 @@ static void parse_riff_format(unsigned char* buf, int fmtsize, struct wave_fmt *
243 } 235 }
244} 236}
245 237
246static bool parse_list_chunk(int fd, struct mp3entry* id3, int chunksize, bool is_64) 238static void parse_list_chunk(int fd, struct mp3entry* id3, int chunksize, bool is_64)
247{ 239{
248 unsigned char tmpbuf[ID3V2_BUF_SIZE]; 240 unsigned char tmpbuf[ID3V2_BUF_SIZE];
249 unsigned char *bp = tmpbuf; 241 unsigned char *bp = tmpbuf;
250 unsigned char *endp; 242 unsigned char *endp;
251 unsigned char *data_pos; 243 unsigned char *data_pos;
252 unsigned char *curpos = id3->id3v2buf; 244 unsigned char *tag_pos = id3->id3v2buf;
253 int datasize; 245 int datasize;
254 int infosize; 246 int infosize;
255 int remain = ID3V2_BUF_SIZE; 247 int remain;
256 bool convert_string; 248 int i;
257 249
258 if (is_64) 250 if (is_64)
259 lseek(fd, 4, SEEK_CUR); 251 lseek(fd, 4, SEEK_CUR);
260 else if (read(fd, bp, 4) < 4 || memcmp(bp, "INFO", 4)) 252 else if (read(fd, bp, 4) < 4 || memcmp(bp, "INFO", 4))
261 return false; 253 return;
262 254
263 infosize = read(fd, bp, (ID3V2_BUF_SIZE > chunksize)? chunksize : ID3V2_BUF_SIZE); 255 infosize = read(fd, bp, (ID3V2_BUF_SIZE > chunksize)? chunksize : ID3V2_BUF_SIZE);
264 if (infosize <= 8) 256 if (infosize <= 8)
265 return false; 257 return;
266 258
267 endp = bp + infosize; 259 endp = bp + infosize;
268 while (bp < endp) 260 while (bp < endp)
269 { 261 {
270 convert_string = true;
271 datasize = get_long_le(bp + 4); 262 datasize = get_long_le(bp + 4);
272 data_pos = bp + 8; 263 data_pos = bp + 8;
273 remain = ID3V2_BUF_SIZE - (curpos - (unsigned char*)id3->id3v2buf); 264 remain = ID3V2_BUF_SIZE - (tag_pos - (unsigned char*)id3->id3v2buf);
274 if (remain <= 0) 265 if (remain < 1)
275 break; 266 break;
276 267
277 if (memcmp(bp, infochunk_list[INFO_TITLE], 4) == 0) 268 for (i = 0; i < INFO_CHUNK_COUNT; i++)
278 {
279 id3->title = curpos;
280 }
281 else if (memcmp(bp, infochunk_list[INFO_ARTIST], 4) == 0)
282 {
283 id3->artist = curpos;
284 }
285 else if (memcmp(bp, infochunk_list[INFO_ALBUM_ARTIST], 4) == 0)
286 {
287 id3->albumartist = curpos;
288 }
289 else if (memcmp(bp, infochunk_list[INFO_COMPOSER], 4) == 0)
290 {
291 id3->composer = curpos;
292 }
293 else if (memcmp(bp, infochunk_list[INFO_COMMENT], 4) == 0)
294 {
295 id3->comment = curpos;
296 }
297 else if (memcmp(bp, infochunk_list[INFO_GROUPING], 4) == 0)
298 {
299 id3->grouping = curpos;
300 }
301 else if (memcmp(bp, infochunk_list[INFO_GENRE], 4) == 0)
302 {
303 id3->genre_string = curpos;
304 }
305 else if (memcmp(bp, infochunk_list[INFO_DATE], 4) == 0)
306 {
307 id3->year_string = curpos;
308 }
309 else if (memcmp(bp, infochunk_list[INFO_TRACK], 4) == 0)
310 {
311 id3->track_string = curpos;
312 }
313 else if (memcmp(bp, infochunk_list[INFO_DISC], 4) == 0)
314 {
315 id3->disc_string = curpos;
316 }
317 else
318 {
319 convert_string = false;
320 }
321
322 if (convert_string)
323 { 269 {
324 curpos = convert_utf8(data_pos, curpos, datasize, remain, is_64); 270 if (memcmp(bp, info_chunks[i].tag, 4) == 0)
271 {
272 *((char **)(((char*)id3) + info_chunks[i].offset)) = tag_pos;
273 tag_pos = convert_utf8(data_pos, tag_pos,
274 (datasize + 1 >= remain )? remain - 1 : datasize,
275 is_64);
276 *tag_pos++ = 0;
277 break;
278 }
325 } 279 }
326
327 bp = data_pos + datasize + (datasize & 1); 280 bp = data_pos + datasize + (datasize & 1);
328 }; 281 };
329 return true;
330} 282}
331 283
332static bool read_header(int fd, struct mp3entry* id3, const unsigned char *chunknames, 284static bool read_header(int fd, struct mp3entry* id3, const unsigned char *chunknames,