diff options
-rw-r--r-- | apps/metadata.c | 90 | ||||
-rw-r--r-- | apps/talk.c | 15 | ||||
-rw-r--r-- | firmware/common/structec.c | 12 |
3 files changed, 27 insertions, 90 deletions
diff --git a/apps/metadata.c b/apps/metadata.c index ae2a8ecda8..fef8111127 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -31,12 +31,19 @@ | |||
31 | #include "debug.h" | 31 | #include "debug.h" |
32 | #include "system.h" | 32 | #include "system.h" |
33 | #include "cuesheet.h" | 33 | #include "cuesheet.h" |
34 | #include "structec.h" | ||
34 | 35 | ||
35 | enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS }; | 36 | enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS }; |
36 | 37 | ||
38 | #ifdef ROCKBOX_BIG_ENDIAN | ||
39 | #define IS_BIG_ENDIAN 1 | ||
40 | #else | ||
41 | #define IS_BIG_ENDIAN 0 | ||
42 | #endif | ||
43 | |||
37 | #define APETAG_HEADER_LENGTH 32 | 44 | #define APETAG_HEADER_LENGTH 32 |
38 | #define APETAG_HEADER_FORMAT "8LLLL" | 45 | #define APETAG_HEADER_FORMAT "8llll" |
39 | #define APETAG_ITEM_HEADER_FORMAT "LL" | 46 | #define APETAG_ITEM_HEADER_FORMAT "ll" |
40 | #define APETAG_ITEM_TYPE_MASK 3 | 47 | #define APETAG_ITEM_TYPE_MASK 3 |
41 | 48 | ||
42 | #define TAG_NAME_LENGTH 32 | 49 | #define TAG_NAME_LENGTH 32 |
@@ -153,69 +160,6 @@ static long read_string(int fd, char* buf, long buf_size, int eos, long size) | |||
153 | return read_bytes; | 160 | return read_bytes; |
154 | } | 161 | } |
155 | 162 | ||
156 | /* Convert a little-endian structure to native format using a format string. | ||
157 | * Does nothing on a little-endian machine. | ||
158 | */ | ||
159 | static void convert_endian(void *data, const char *format) | ||
160 | { | ||
161 | #ifdef ROCKBOX_BIG_ENDIAN | ||
162 | while (*format) | ||
163 | { | ||
164 | switch (*format) | ||
165 | { | ||
166 | case 'L': | ||
167 | { | ||
168 | long* d = (long*) data; | ||
169 | |||
170 | *d = letoh32(*d); | ||
171 | data = d + 1; | ||
172 | } | ||
173 | |||
174 | break; | ||
175 | |||
176 | case 'S': | ||
177 | { | ||
178 | short* d = (short*) data; | ||
179 | |||
180 | *d = letoh16(*d); | ||
181 | data = d + 1; | ||
182 | } | ||
183 | |||
184 | break; | ||
185 | |||
186 | default: | ||
187 | if (isdigit(*format)) | ||
188 | { | ||
189 | data = ((char*) data) + *format - '0'; | ||
190 | } | ||
191 | |||
192 | break; | ||
193 | } | ||
194 | |||
195 | format++; | ||
196 | } | ||
197 | #else | ||
198 | (void) data; | ||
199 | (void) format; | ||
200 | #endif | ||
201 | } | ||
202 | |||
203 | #if 0 /* not needed atm */ | ||
204 | /* Read an unsigned 16-bit integer from a big-endian file. */ | ||
205 | #ifdef ROCKBOX_BIG_ENDIAN | ||
206 | #define read_uint16be(fd, buf) read((fd), (buf), 2) | ||
207 | #else | ||
208 | static int read_uint16be(int fd, unsigned short* buf) | ||
209 | { | ||
210 | size_t n; | ||
211 | |||
212 | n = read(fd, (char*) buf, 2); | ||
213 | *buf = betoh16(*buf); | ||
214 | return n; | ||
215 | } | ||
216 | #endif | ||
217 | #endif /* if 0 */ | ||
218 | |||
219 | /* Read an unsigned 32-bit integer from a big-endian file. */ | 163 | /* Read an unsigned 32-bit integer from a big-endian file. */ |
220 | #ifdef ROCKBOX_BIG_ENDIAN | 164 | #ifdef ROCKBOX_BIG_ENDIAN |
221 | #define read_uint32be(fd,buf) read((fd), (buf), 4) | 165 | #define read_uint32be(fd,buf) read((fd), (buf), 4) |
@@ -354,13 +298,12 @@ static bool read_ape_tags(int fd, struct mp3entry* id3) | |||
354 | struct apetag_header header; | 298 | struct apetag_header header; |
355 | 299 | ||
356 | if ((lseek(fd, -APETAG_HEADER_LENGTH, SEEK_END) < 0) | 300 | if ((lseek(fd, -APETAG_HEADER_LENGTH, SEEK_END) < 0) |
357 | || (read(fd, &header, APETAG_HEADER_LENGTH) != APETAG_HEADER_LENGTH) | 301 | || (ecread(fd, &header, 1, APETAG_HEADER_FORMAT, IS_BIG_ENDIAN) != APETAG_HEADER_LENGTH) |
358 | || (memcmp(header.id, "APETAGEX", sizeof(header.id)))) | 302 | || (memcmp(header.id, "APETAGEX", sizeof(header.id)))) |
359 | { | 303 | { |
360 | return false; | 304 | return false; |
361 | } | 305 | } |
362 | 306 | ||
363 | convert_endian(&header, APETAG_HEADER_FORMAT); | ||
364 | id3->genre = 0xff; | 307 | id3->genre = 0xff; |
365 | 308 | ||
366 | if ((header.version == 2000) && (header.item_count > 0) | 309 | if ((header.version == 2000) && (header.item_count > 0) |
@@ -389,12 +332,11 @@ static bool read_ape_tags(int fd, struct mp3entry* id3) | |||
389 | break; | 332 | break; |
390 | } | 333 | } |
391 | 334 | ||
392 | if (read(fd, &item, sizeof(item)) < (long) sizeof(item)) | 335 | if (ecread(fd, &item, 1, APETAG_ITEM_HEADER_FORMAT, IS_BIG_ENDIAN) < (long) sizeof(item)) |
393 | { | 336 | { |
394 | return false; | 337 | return false; |
395 | } | 338 | } |
396 | 339 | ||
397 | convert_endian(&item, APETAG_ITEM_HEADER_FORMAT); | ||
398 | tag_remaining -= sizeof(item); | 340 | tag_remaining -= sizeof(item); |
399 | r = read_string(fd, name, sizeof(name), 0, tag_remaining); | 341 | r = read_string(fd, name, sizeof(name), 0, tag_remaining); |
400 | 342 | ||
@@ -447,21 +389,18 @@ static bool read_vorbis_tags(int fd, struct mp3entry *id3, | |||
447 | 389 | ||
448 | id3->genre = 255; | 390 | id3->genre = 255; |
449 | 391 | ||
450 | if (read(fd, &len, sizeof(len)) < (long) sizeof(len)) | 392 | if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len)) |
451 | { | 393 | { |
452 | return false; | 394 | return false; |
453 | } | 395 | } |
454 | 396 | ||
455 | convert_endian(&len, "L"); | ||
456 | |||
457 | if ((lseek(fd, len, SEEK_CUR) < 0) | 397 | if ((lseek(fd, len, SEEK_CUR) < 0) |
458 | || (read(fd, &comment_count, sizeof(comment_count)) | 398 | || (ecread(fd, &comment_count, 1, "l", IS_BIG_ENDIAN) |
459 | < (long) sizeof(comment_count))) | 399 | < (long) sizeof(comment_count))) |
460 | { | 400 | { |
461 | return false; | 401 | return false; |
462 | } | 402 | } |
463 | 403 | ||
464 | convert_endian(&comment_count, "L"); | ||
465 | tag_remaining -= len + sizeof(len) + sizeof(comment_count); | 404 | tag_remaining -= len + sizeof(len) + sizeof(comment_count); |
466 | 405 | ||
467 | if (tag_remaining <= 0) | 406 | if (tag_remaining <= 0) |
@@ -480,12 +419,11 @@ static bool read_vorbis_tags(int fd, struct mp3entry *id3, | |||
480 | break; | 419 | break; |
481 | } | 420 | } |
482 | 421 | ||
483 | if (read(fd, &len, sizeof(len)) < (long) sizeof(len)) | 422 | if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len)) |
484 | { | 423 | { |
485 | return false; | 424 | return false; |
486 | } | 425 | } |
487 | 426 | ||
488 | convert_endian(&len, "L"); | ||
489 | tag_remaining -= 4; | 427 | tag_remaining -= 4; |
490 | 428 | ||
491 | /* Quit if we've passed the end of the page */ | 429 | /* Quit if we've passed the end of the page */ |
diff --git a/apps/talk.c b/apps/talk.c index c22b70066e..6629bbb2e5 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include "id3.h" | 35 | #include "id3.h" |
36 | #include "logf.h" | 36 | #include "logf.h" |
37 | #include "bitswap.h" | 37 | #include "bitswap.h" |
38 | #include "structec.h" | ||
38 | #if CONFIG_CODEC == SWCODEC | 39 | #if CONFIG_CODEC == SWCODEC |
39 | #include "playback.h" | 40 | #include "playback.h" |
40 | #endif | 41 | #endif |
@@ -183,12 +184,7 @@ static void load_voicefile(void) | |||
183 | 184 | ||
184 | #ifdef ROCKBOX_LITTLE_ENDIAN | 185 | #ifdef ROCKBOX_LITTLE_ENDIAN |
185 | logf("Byte swapping voice file"); | 186 | logf("Byte swapping voice file"); |
186 | p_voicefile = (struct voicefile*)audiobuf; | 187 | structec_convert(audiobuf, "llll", 1, true); |
187 | p_voicefile->version = swap32(p_voicefile->version); | ||
188 | p_voicefile->table = swap32(p_voicefile->table); | ||
189 | p_voicefile->id1_max = swap32(p_voicefile->id1_max); | ||
190 | p_voicefile->id2_max = swap32(p_voicefile->id2_max); | ||
191 | p_voicefile = NULL; | ||
192 | #endif | 188 | #endif |
193 | 189 | ||
194 | if (((struct voicefile*)audiobuf)->table /* format check */ | 190 | if (((struct voicefile*)audiobuf)->table /* format check */ |
@@ -208,12 +204,7 @@ static void load_voicefile(void) | |||
208 | 204 | ||
209 | #ifdef ROCKBOX_LITTLE_ENDIAN | 205 | #ifdef ROCKBOX_LITTLE_ENDIAN |
210 | for (i = 0; i < p_voicefile->id1_max + p_voicefile->id2_max; i++) | 206 | for (i = 0; i < p_voicefile->id1_max + p_voicefile->id2_max; i++) |
211 | { | 207 | structec_convert(&p_voicefile->index[i], "ll", 1, true); |
212 | struct clip_entry *ce; | ||
213 | ce = &p_voicefile->index[i]; | ||
214 | ce->offset = swap32(ce->offset); | ||
215 | ce->size = swap32(ce->size); | ||
216 | } | ||
217 | #endif | 208 | #endif |
218 | 209 | ||
219 | /* Do a bitswap as necessary. */ | 210 | /* Do a bitswap as necessary. */ |
diff --git a/firmware/common/structec.c b/firmware/common/structec.c index 7c76874692..1f4205c67c 100644 --- a/firmware/common/structec.c +++ b/firmware/common/structec.c | |||
@@ -17,6 +17,7 @@ | |||
17 | * | 17 | * |
18 | ****************************************************************************/ | 18 | ****************************************************************************/ |
19 | 19 | ||
20 | #include <ctype.h> | ||
20 | #include <string.h> | 21 | #include <string.h> |
21 | #include <inttypes.h> | 22 | #include <inttypes.h> |
22 | #include "structec.h" | 23 | #include "structec.h" |
@@ -82,9 +83,14 @@ void structec_convert(void *structure, const char *ecinst, | |||
82 | break; | 83 | break; |
83 | } | 84 | } |
84 | 85 | ||
85 | /* This should be never reached. */ | 86 | /* Skip N bytes, idea taken from metadata.c */ |
86 | default: | 87 | default: |
88 | { | ||
89 | if (isdigit(*ecinst_ring)) | ||
90 | buf += (*ecinst_ring - '0'); | ||
91 | |||
87 | break; | 92 | break; |
93 | } | ||
88 | } | 94 | } |
89 | 95 | ||
90 | ecinst_ring++; | 96 | ecinst_ring++; |
@@ -114,7 +120,9 @@ size_t structec_size(const char *ecinst) | |||
114 | case 'c': size += 1; break; | 120 | case 'c': size += 1; break; |
115 | case 's': size += 2; break; | 121 | case 's': size += 2; break; |
116 | case 'l': size += 4; break; | 122 | case 'l': size += 4; break; |
117 | default: break; | 123 | default: |
124 | if (isdigit(*ecinst)) | ||
125 | size += (*ecinst - '0'); | ||
118 | } | 126 | } |
119 | } while (*(++ecinst) != '\0'); | 127 | } while (*(++ecinst) != '\0'); |
120 | 128 | ||