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:
parent
9ace15871d
commit
5557fe3259
1 changed files with 88 additions and 17 deletions
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue