1
0
Fork 0
forked from len0rd/rockbox

Added unsynchronization

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3983 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Linus Nielsen Feltzing 2003-10-22 13:06:31 +00:00
parent 9ace15871d
commit 5557fe3259

View file

@ -108,6 +108,35 @@ struct tag_resolver {
int (*ppFunc)(struct mp3entry*, char* tag, int bufferpos); int (*ppFunc)(struct mp3entry*, char* tag, int bufferpos);
}; };
static int unsynchronize(char* tag, int len)
{
int i;
unsigned char c;
unsigned char *rp, *wp;
bool ff_found = false;
wp = rp = tag;
rp = (unsigned char *)tag;
for(i = 0;i < len;i++) {
/* Read the next byte and write it back, but don't increment the
write pointer */
c = *rp++;
*wp = c;
if(ff_found) {
/* Increment the write pointer if it isn't an unsynch pattern */
if(c != 0)
wp++;
ff_found = false;
} else {
if(c == 0xff)
ff_found = true;
wp++;
}
}
return (int)wp - (int)tag;
}
/* parse numeric value from string */ /* parse numeric value from string */
static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos ) static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos )
{ {
@ -326,12 +355,17 @@ static void setid3v2title(int fd, struct mp3entry *entry)
int size; int size;
int bufferpos = 0, totframelen, framelen; int bufferpos = 0, totframelen, framelen;
char header[10]; char header[10];
char tmp[4];
unsigned char version; unsigned char version;
char *buffer = entry->id3v2buf; char *buffer = entry->id3v2buf;
int bytesread = 0; int bytesread = 0;
int buffersize = sizeof(entry->id3v2buf); int buffersize = sizeof(entry->id3v2buf);
unsigned char global_flags;
int flags; int flags;
int skip; int skip;
bool global_unsynch = false;
bool unsynch = false;
int data_length_ind;
int i; int i;
/* Bail out if the tag is shorter than 10 bytes */ /* Bail out if the tag is shorter than 10 bytes */
@ -372,9 +406,11 @@ static void setid3v2title(int fd, struct mp3entry *entry)
entry->genre = 0xff; entry->genre = 0xff;
entry->title = entry->artist = entry->album = NULL; entry->title = entry->artist = entry->album = NULL;
global_flags = header[5];
/* Skip the extended header if it is present */ /* Skip the extended header if it is present */
if(version >= ID3_VER_2_4) { if(version >= ID3_VER_2_4) {
if(header[5] & 0x40) { if(global_flags & 0x40) {
if(4 != read(fd, header, 4)) if(4 != read(fd, header, 4))
return; return;
@ -385,6 +421,11 @@ static void setid3v2title(int fd, struct mp3entry *entry)
} }
} }
/* Is unsynchronization applied? */
if(global_flags & 0x80) {
global_unsynch = true;
}
/* /*
* We must have at least minframesize bytes left for the * We must have at least minframesize bytes left for the
* remaining frames to be interesting * remaining frames to be interesting
@ -425,12 +466,17 @@ static void setid3v2title(int fd, struct mp3entry *entry)
if(framelen == 0) if(framelen == 0)
return; return;
unsynch = false;
data_length_ind = 0;
if(flags) if(flags)
{ {
skip = 0; skip = 0;
if(flags & 0x0040) /* Grouping identity */ if(flags & 0x0040) { /* Grouping identity */
skip++; lseek(fd, 1, SEEK_CUR); /* Skip 1 byte */
framelen--;
}
if(flags & 0x000c) /* Compression or encryption */ if(flags & 0x000c) /* Compression or encryption */
{ {
@ -441,16 +487,15 @@ static void setid3v2title(int fd, struct mp3entry *entry)
continue; continue;
} }
/* The Unsynchronization flag can't be trusted, so we if(flags & 0x0002) /* Unsynchronization */
don't check it for now... */ unsynch = true;
if(flags & 0x0001) /* Data length indicator */ if(flags & 0x0001) { /* Data length indicator */
skip += 4; if(4 != read(fd, tmp, 4))
return;
if(skip) data_length_ind = UNSYNC(tmp[0], tmp[1], tmp[2], tmp[3]);
{ framelen -= 4;
lseek(fd, skip, SEEK_CUR);
framelen -= skip;
} }
} }
@ -494,6 +539,10 @@ static void setid3v2title(int fd, struct mp3entry *entry)
size -= bytesread; size -= bytesread;
*ptag = buffer + bufferpos; *ptag = buffer + bufferpos;
if(global_unsynch || unsynch)
bytesread = unsynchronize(*ptag, bytesread);
unicode_munge( ptag, &bytesread ); unicode_munge( ptag, &bytesread );
tag = *ptag; tag = *ptag;
tag[bytesread + 1] = 0; tag[bytesread + 1] = 0;
@ -508,12 +557,34 @@ static void setid3v2title(int fd, struct mp3entry *entry)
/* no tag in tagList was found, or it was a repeat. /* no tag in tagList was found, or it was a repeat.
skip it using the total size */ skip it using the total size */
/* We may need to compensate for the unsynchronization scheme */
if(global_unsynch && !data_length_ind) {
bool ff_found = false;
for(i = 0;i < totframelen;i++) {
unsigned char c;
bytesread = read(fd, &c, 1);
if(ff_found) {
if(c == 0)
/* Found an unsynch pattern, counting it */
totframelen++;
ff_found = false;
} else {
if(c == 0xff)
ff_found = true;
}
}
} else {
if(data_length_ind)
totframelen = data_length_ind;
size -= totframelen; size -= totframelen;
if( lseek(fd, totframelen, SEEK_CUR) == -1 ) if( lseek(fd, totframelen, SEEK_CUR) == -1 )
return; return;
} }
} }
} }
}
/* /*
* Calculates the size of the ID3v2 tag. * Calculates the size of the ID3v2 tag.