summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-10-01 13:20:23 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-10-01 13:20:23 +0000
commitc09c4afb2330df87bc65edbe00138ca8515673b3 (patch)
treedaa3f0af180f388df7a08216dff2fbabb785ebf9
parent43c9e003d865ff2392086066f9194c6abd7365ed (diff)
Made the Unicode kludge even kludgier, but non-crashing
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2469 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/id3.c112
1 files changed, 70 insertions, 42 deletions
diff --git a/firmware/id3.c b/firmware/id3.c
index 90db840689..30c095cf09 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -38,21 +38,15 @@
#include "id3.h"
-/* Some utility macros used in getsonglength() */
-#define BYTE0(x) ((x >> 24) & 0xFF)
-#define BYTE1(x) ((x >> 16) & 0xFF)
-#define BYTE2(x) ((x >> 8) & 0xFF)
-#define BYTE3(x) ((x >> 0) & 0xFF)
-
-#define UNSYNC(b1,b2,b3,b4) (((b1 & 0x7F) << (3*7)) | \
- ((b2 & 0x7F) << (2*7)) | \
- ((b3 & 0x7F) << (1*7)) | \
- ((b4 & 0x7F) << (0*7)))
-
-#define BYTES_TO_INT(b1,b2,b3,b4) (((b1 & 0xFF) << (3*8)) | \
- ((b2 & 0xFF) << (2*8)) | \
- ((b3 & 0xFF) << (1*8)) | \
- ((b4 & 0xFF) << (0*8)))
+#define UNSYNC(b0,b1,b2,b3) (((b0 & 0x7F) << (3*7)) | \
+ ((b1 & 0x7F) << (2*7)) | \
+ ((b2 & 0x7F) << (1*7)) | \
+ ((b3 & 0x7F) << (0*7)))
+
+#define BYTES2INT(b0,b1,b2,b3) (((b0 & 0xFF) << (3*8)) | \
+ ((b1 & 0xFF) << (2*8)) | \
+ ((b2 & 0xFF) << (1*8)) | \
+ ((b3 & 0xFF) << (0*8)))
/* Table of bitrates for MP3 files, all values in kilo.
* Indexed by version, layer and value of bit 15-12 in header.
@@ -93,19 +87,63 @@ const int freqtab[][4] =
string. If it is, we attempt to convert it to a 8-bit ASCII string
(for valid 8-bit ASCII characters). If it's not unicode, we leave
it alone. At some point we should fully support unicode strings */
+static int unicode_munge(char** string, int *len) {
+ int tmp;
+ bool le = false;
+ int i;
+ char *str = *string;
+ char *outstr = *string;
+
+ if(str[0] > 0x03) {
+ /* Plain old string */
+ return 0;
+ }
+
+ /* Type 0x00 is ordinary ISO 8859-1 */
+ if(str[0] == 0x00) {
+ *len--;
+ *string++; /* Skip the encoding type byte */
+ return 0;
+ }
+
+ /* Unicode with or without BOM */
+ if(str[0] == 0x01 || str[0] == 0x02) {
+ str++;
+ tmp = BYTES2INT(0, 0, str[1], str[2]);
+
+ if(tmp == UNICODE_BOM_2) { /* Little endian? */
+ le = true;
+ str += 2;
+ }
+
+ if(tmp == UNICODE_BOM_1) /* Big endian? */
+ str += 2;
+
+ i = 0;
-static void unicode_munge(char* string) {
- unsigned short* short_string = (unsigned short*)string;
- if (short_string[0] == UNICODE_BOM_1 ||
- short_string[0] == UNICODE_BOM_2) {
- int x = 0;
do {
- x++;
- if (!(short_string[x]&0xff00)) {
- string[x-1]=(short_string[x]&0xff);
+ if(le) {
+ if(str[1])
+ outstr[i++] = '.';
+ else
+ outstr[i++] = str[0];
+ } else {
+ if(str[0])
+ outstr[i++] = '.';
+ else
+ outstr[i++] = str[1];
}
- } while (short_string[x]!=0x0000);
+ } while(str[0] || str[1]);
+
+ *len = i;
+ *string++; /* Skip the encoding type byte */
+ return 0;
}
+
+ /* If we come here, the string was of an unsupported type */
+ *len = 1;
+ outstr[0] = 0;
+ return -1;
}
/*
@@ -248,8 +286,8 @@ static void setid3v2title(int fd, struct mp3entry *entry)
} else {
/* version .3 files don't use synchsafe ints for
* size */
- headerlen = BYTES_TO_INT(header[4], header[5],
- header[6], header[7]);
+ headerlen = BYTES2INT(header[4], header[5],
+ header[6], header[7]);
}
} else {
memcpy(header, (buffer + readsize), 6);
@@ -270,8 +308,7 @@ static void setid3v2title(int fd, struct mp3entry *entry)
headerlen--;
artist = buffer + readsize;
artistn = headerlen;
- readsize += headerlen;
- unicode_munge(artist);
+ unicode_munge(&artist, &artistn);
}
else if(!strncmp(header, "TIT2", strlen("TIT2")) ||
!strncmp(header, "TT2", strlen("TT2"))) {
@@ -279,27 +316,24 @@ static void setid3v2title(int fd, struct mp3entry *entry)
headerlen--;
title = buffer + readsize;
titlen = headerlen;
- readsize += headerlen;
- unicode_munge(title);
+ unicode_munge(&title, &titlen);
}
else if(!strncmp(header, "TALB", strlen("TALB"))) {
readsize++;
headerlen--;
album = buffer + readsize;
albumn = headerlen;
- readsize += headerlen;
- unicode_munge(album);
+ unicode_munge(&album, &albumn);
}
else if(!strncmp(header, "TRCK", strlen("TRCK"))) {
readsize++;
headerlen--;
tracknum = buffer + readsize;
tracknumn = headerlen;
- readsize += headerlen;
- unicode_munge(tracknum);
- } else {
- readsize += headerlen;
+ unicode_munge(&tracknum, &tracknumn);
}
+
+ readsize += headerlen;
}
if(artist) {
@@ -482,12 +516,6 @@ static int getsonglength(int fd, struct mp3entry *entry)
if((header & 0xF000) == 0xF000)
goto restart;
-#ifdef DEBUG_VERBOSE
- fprintf(stderr,
- "We found %x-%x-%x-%x and checksync %i and test %x\n",
- BYTE0(header), BYTE1(header), BYTE2(header), BYTE3(header),
- CHECKSYNC(header), (header & 0xF000) == 0xF000);
-#endif
/* MPEG Audio Version */
switch((header & 0x180000) >> 19) {
case 0: