diff options
author | Yoshihisa Uchida <uchida@rockbox.org> | 2010-05-09 07:10:07 +0000 |
---|---|---|
committer | Yoshihisa Uchida <uchida@rockbox.org> | 2010-05-09 07:10:07 +0000 |
commit | 20eb5f48e5212d9eeb6c7d2ab531f62bb16380a5 (patch) | |
tree | 5b928604887affad38da9b83adfd79240ab6a8f8 /apps/metadata | |
parent | 52a8a540b14313aa83bee0fb9eca4502f86eb9f7 (diff) | |
download | rockbox-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
Diffstat (limited to 'apps/metadata')
-rw-r--r-- | apps/metadata/wave.c | 128 |
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 | ||
79 | enum { | 79 | /* list/info chunk */ |
80 | INFO_TITLE = 0, | 80 | |
81 | INFO_ARTIST, | 81 | struct 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 */ |
94 | static const unsigned char infochunk_list[][4] | 87 | static 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 */ |
110 | enum | 104 | enum |
@@ -135,11 +129,9 @@ struct wave_fmt { | |||
135 | uint64_t numbytes; | 129 | uint64_t numbytes; |
136 | }; | 130 | }; |
137 | 131 | ||
138 | static unsigned char *convert_utf8(unsigned char *src, unsigned char *dst, | 132 | static 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 | ||
246 | static bool parse_list_chunk(int fd, struct mp3entry* id3, int chunksize, bool is_64) | 238 | static 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 | ||
332 | static bool read_header(int fd, struct mp3entry* id3, const unsigned char *chunknames, | 284 | static bool read_header(int fd, struct mp3entry* id3, const unsigned char *chunknames, |