summaryrefslogtreecommitdiff
path: root/apps/metadata/metadata_common.c
diff options
context:
space:
mode:
authorSean Bartell <wingedtachikoma@gmail.com>2011-06-24 01:25:21 -0400
committerNils Wallménius <nils@rockbox.org>2012-03-18 12:00:39 +0100
commitb5716df4cb2837bbbc42195cf1aefcf03e21d6a6 (patch)
tree130cd712e2e00893b6df9959a375a8d9523a1aca /apps/metadata/metadata_common.c
parent24bd9d5393dbe39a5c6194877bc00ede669b1d5d (diff)
downloadrockbox-b5716df4cb2837bbbc42195cf1aefcf03e21d6a6.tar.gz
rockbox-b5716df4cb2837bbbc42195cf1aefcf03e21d6a6.zip
Build librbcodec with DSP and metadata.
All associated files are moved to /lib/rbcodec. Change-Id: I572ddd2b8a996aae1e98c081d06b1ed356dce222
Diffstat (limited to 'apps/metadata/metadata_common.c')
-rw-r--r--apps/metadata/metadata_common.c374
1 files changed, 0 insertions, 374 deletions
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
deleted file mode 100644
index e861644025..0000000000
--- a/apps/metadata/metadata_common.c
+++ /dev/null
@@ -1,374 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include "string-extra.h"
23#include <stdlib.h>
24#include <ctype.h>
25#include <inttypes.h>
26
27#include "system.h"
28#include "metadata.h"
29#include "metadata_common.h"
30#include "metadata_parsers.h"
31#include "replaygain.h"
32
33/* Read a string from the file. Read up to size bytes, or, if eos != -1,
34 * until the eos character is found (eos is not stored in buf, unless it is
35 * nil). Writes up to buf_size chars to buf, always terminating with a nil.
36 * Returns number of chars read or -1 on read error.
37 */
38long read_string(int fd, char* buf, long buf_size, int eos, long size)
39{
40 long read_bytes = 0;
41 char c;
42
43 while (size != 0)
44 {
45 if (read(fd, &c, 1) != 1)
46 {
47 read_bytes = -1;
48 break;
49 }
50
51 read_bytes++;
52 size--;
53
54 if ((eos != -1) && (eos == (unsigned char) c))
55 {
56 break;
57 }
58
59 if (buf_size > 1)
60 {
61 *buf++ = c;
62 buf_size--;
63 }
64 }
65
66 *buf = 0;
67 return read_bytes;
68}
69/* Read an unsigned 8-bit integer from a file. */
70int read_uint8(int fd, uint8_t* buf)
71{
72 size_t n;
73
74 n = read(fd, (char*) buf, 1);
75 return n;
76}
77
78#ifdef ROCKBOX_LITTLE_ENDIAN
79/* Read an unsigned 16-bit integer from a big-endian file. */
80int read_uint16be(int fd, uint16_t* buf)
81{
82 size_t n;
83
84 n = read(fd, (char*) buf, 2);
85 *buf = betoh16(*buf);
86 return n;
87}
88/* Read an unsigned 32-bit integer from a big-endian file. */
89int read_uint32be(int fd, uint32_t* buf)
90{
91 size_t n;
92
93 n = read(fd, (char*) buf, 4);
94 *buf = betoh32(*buf);
95 return n;
96}
97/* Read an unsigned 64-bit integer from a big-endian file. */
98int read_uint64be(int fd, uint64_t* buf)
99{
100 size_t n;
101 uint8_t data[8];
102 int i;
103
104 n = read(fd, data, 8);
105
106 for (i=0, *buf=0; i<=7; i++) {
107 *buf <<= 8;
108 *buf |= data[i];
109 }
110 return n;
111}
112#else
113/* Read unsigned integers from a little-endian file. */
114int read_uint16le(int fd, uint16_t* buf)
115{
116 size_t n;
117
118 n = read(fd, (char*) buf, 2);
119 *buf = letoh16(*buf);
120 return n;
121}
122int read_uint32le(int fd, uint32_t* buf)
123{
124 size_t n;
125
126 n = read(fd, (char*) buf, 4);
127 *buf = letoh32(*buf);
128 return n;
129}
130int read_uint64le(int fd, uint64_t* buf)
131{
132 size_t n;
133 uint8_t data[8];
134 int i;
135
136 n = read(fd, data, 8);
137
138 for (i=7, *buf=0; i>=0; i--) {
139 *buf <<= 8;
140 *buf |= data[i];
141 }
142
143 return n;
144}
145#endif
146
147/* Read an unaligned 64-bit little endian unsigned integer from buffer. */
148uint64_t get_uint64_le(void* buf)
149{
150 unsigned char* p = (unsigned char*) buf;
151
152 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24) | ((uint64_t)p[4] << 32) |
153 ((uint64_t)p[5] << 40) | ((uint64_t)p[6] << 48) | ((uint64_t)p[7] << 56);
154}
155
156/* Read an unaligned 32-bit little endian long from buffer. */
157uint32_t get_long_le(void* buf)
158{
159 unsigned char* p = (unsigned char*) buf;
160
161 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
162}
163
164/* Read an unaligned 16-bit little endian short from buffer. */
165uint16_t get_short_le(void* buf)
166{
167 unsigned char* p = (unsigned char*) buf;
168
169 return p[0] | (p[1] << 8);
170}
171
172/* Read an unaligned 32-bit big endian long from buffer. */
173uint32_t get_long_be(void* buf)
174{
175 unsigned char* p = (unsigned char*) buf;
176
177 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
178}
179
180/* Read an unaligned 16-bit little endian short from buffer. */
181uint16_t get_short_be(void* buf)
182{
183 unsigned char* p = (unsigned char*) buf;
184
185 return (p[0] << 8) | p[1];
186}
187
188/* Read an unaligned 32-bit little endian long from buffer. */
189int32_t get_slong(void* buf)
190{
191 unsigned char* p = (unsigned char*) buf;
192
193 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
194}
195
196uint32_t get_itunes_int32(char* value, int count)
197{
198 static const char hexdigits[] = "0123456789ABCDEF";
199 const char* c;
200 int r = 0;
201
202 while (count-- > 0)
203 {
204 while (isspace(*value))
205 {
206 value++;
207 }
208
209 while (*value && !isspace(*value))
210 {
211 value++;
212 }
213 }
214
215 while (isspace(*value))
216 {
217 value++;
218 }
219
220 while (*value && ((c = strchr(hexdigits, toupper(*value))) != NULL))
221 {
222 r = (r << 4) | (c - hexdigits);
223 value++;
224 }
225
226 return r;
227}
228
229/* Skip an ID3v2 tag if it can be found. We assume the tag is located at the
230 * start of the file, which should be true in all cases where we need to skip it.
231 * Returns true if successfully skipped or not skipped, and false if
232 * something went wrong while skipping.
233 */
234bool skip_id3v2(int fd, struct mp3entry *id3)
235{
236 char buf[4];
237
238 read(fd, buf, 4);
239 if (memcmp(buf, "ID3", 3) == 0)
240 {
241 /* We have found an ID3v2 tag at the start of the file - find its
242 length and then skip it. */
243 if ((id3->first_frame_offset = getid3v2len(fd)) == 0)
244 return false;
245
246 if ((lseek(fd, id3->first_frame_offset, SEEK_SET) < 0))
247 return false;
248
249 return true;
250 } else {
251 lseek(fd, 0, SEEK_SET);
252 id3->first_frame_offset = 0;
253 return true;
254 }
255}
256
257/* Parse the tag (the name-value pair) and fill id3 and buffer accordingly.
258 * String values to keep are written to buf. Returns number of bytes written
259 * to buf (including end nil).
260 */
261long parse_tag(const char* name, char* value, struct mp3entry* id3,
262 char* buf, long buf_remaining, enum tagtype type)
263{
264 long len = 0;
265 char** p;
266
267 if ((((strcasecmp(name, "track") == 0) && (type == TAGTYPE_APE)))
268 || ((strcasecmp(name, "tracknumber") == 0) && (type == TAGTYPE_VORBIS)))
269 {
270 id3->tracknum = atoi(value);
271 p = &(id3->track_string);
272 }
273 else if (strcasecmp(name, "discnumber") == 0 || strcasecmp(name, "disc") == 0)
274 {
275 id3->discnum = atoi(value);
276 p = &(id3->disc_string);
277 }
278 else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
279 || ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
280 {
281 /* Date's can be in any format in Vorbis. However most of them
282 * are in ISO8601 format so if we try and parse the first part
283 * of the tag as a number, we should get the year. If we get crap,
284 * then act like we never parsed it.
285 */
286 id3->year = atoi(value);
287 if (id3->year < 1900)
288 { /* yeah, not likely */
289 id3->year = 0;
290 }
291 p = &(id3->year_string);
292 }
293 else if (strcasecmp(name, "title") == 0)
294 {
295 p = &(id3->title);
296 }
297 else if (strcasecmp(name, "artist") == 0)
298 {
299 p = &(id3->artist);
300 }
301 else if (strcasecmp(name, "album") == 0)
302 {
303 p = &(id3->album);
304 }
305 else if (strcasecmp(name, "genre") == 0)
306 {
307 p = &(id3->genre_string);
308 }
309 else if (strcasecmp(name, "composer") == 0)
310 {
311 p = &(id3->composer);
312 }
313 else if (strcasecmp(name, "comment") == 0)
314 {
315 p = &(id3->comment);
316 }
317 else if (strcasecmp(name, "albumartist") == 0)
318 {
319 p = &(id3->albumartist);
320 }
321 else if (strcasecmp(name, "album artist") == 0)
322 {
323 p = &(id3->albumartist);
324 }
325 else if (strcasecmp(name, "ensemble") == 0)
326 {
327 p = &(id3->albumartist);
328 }
329 else if (strcasecmp(name, "grouping") == 0)
330 {
331 p = &(id3->grouping);
332 }
333 else if (strcasecmp(name, "content group") == 0)
334 {
335 p = &(id3->grouping);
336 }
337 else if (strcasecmp(name, "contentgroup") == 0)
338 {
339 p = &(id3->grouping);
340 }
341 else if (strcasecmp(name, "musicbrainz_trackid") == 0
342 || strcasecmp(name, "http://musicbrainz.org") == 0 )
343 {
344 p = &(id3->mb_track_id);
345 }
346 else
347 {
348 parse_replaygain(name, value, id3);
349 p = NULL;
350 }
351
352 /* Do not overwrite already available metadata. Especially when reading
353 * tags with e.g. multiple genres / artists. This way only the first
354 * of multiple entries is used, all following are dropped. */
355 if (p!=NULL && *p==NULL)
356 {
357 len = strlen(value);
358 len = MIN(len, buf_remaining - 1);
359 len = MIN(len, ID3V2_MAX_ITEM_SIZE); /* Limit max. item size. */
360
361 if (len > 0)
362 {
363 len++;
364 strlcpy(buf, value, len);
365 *p = buf;
366 }
367 else
368 {
369 len = 0;
370 }
371 }
372
373 return len;
374}