larsbs / id3v2lib

id3v2lib is a library written in C to read and edit id3 tags from mp3 files.
BSD 2-Clause "Simplified" License
128 stars 44 forks source link

Question regarding this library #7

Closed hwen3 closed 9 years ago

hwen3 commented 9 years ago

Hi Lars,

Thanks for this amazing and light library. However, I am currently running into problems with parsing some mp3 files. For these files the library spits out garbage strings, any thoughts as to what could be causing this?

Thank you, Jim

antontriola commented 9 years ago

Jim, I'm running into similar issue, I think I can fix it pretty easily (it's a unicode string parsing thing), I'll post back with a fix if I succeed.

antontriola commented 9 years ago

OK, here's the fix. This works whether the content is ascii or unicode.

char* uni2text(unsigned char *binbuf, int len)
{
    unsigned char *b;       //must be unsigned
    char *p;                //scratch ptr
    static char cbuf[4096]; //examp: feel free to malloc instead
    int i;                  //counter

    memset(cbuf,0,sizeof(cbuf)); //zero, required

    for(b=binbuf, p=cbuf, i=0; i<len; i++, b++)
    {
        if(*b==0||*b==1||*b==0xff||*b==0xfe) 
            continue;
        else
            *p++=*b;
    } 
    return cbuf;
}

Now, scroll down to parse_text_frame_content(), add one line as shown:

ID3v2_frame_text_content* parse_text_frame_content(ID3v2_frame* frame)
{
    if(frame == NULL)
    {
        return NULL;
    }

    ID3v2_frame_text_content* content = new_text_content(frame->size);
    content->encoding = frame->data[0];
    content->size = frame->size - ID3_FRAME_ENCODING;
    memcpy(content->data, frame->data + ID3_FRAME_ENCODING, content->size);

    //add this line:
    content->data=uni2text(content->data, content->size);

return content;
}

The parsing function will now read ascii or unicode and insure content->data is ascii. NOTE: you may want to do this to parse_comment_frame_content(), as well, or any other parsing functions that may potentially return unicode text.

Cheers, Tony

hwen3 commented 9 years ago

Oh, sorry, forgot to close the issue. It was like you said an issue with unicode encoding in the id3 metadata. Since I want to minimize changes to the library I use, I simply used ICU library to decode the data if it was utf-16 encoded.

Jonatas4ndrade commented 3 years ago

OK, here's the fix. This works whether the content is ascii or unicode.

  • Open the file: frame.c
  • Copy the following code to frame.c right after the #includes:
char* uni2text(unsigned char *binbuf, int len)
{
    unsigned char *b;       //must be unsigned
    char *p;                //scratch ptr
    static char cbuf[4096]; //examp: feel free to malloc instead
    int i;                  //counter

    memset(cbuf,0,sizeof(cbuf)); //zero, required

    for(b=binbuf, p=cbuf, i=0; i<len; i++, b++)
    {
        if(*b==0||*b==1||*b==0xff||*b==0xfe) 
            continue;
        else
            *p++=*b;
    } 
    return cbuf;
}

Now, scroll down to parse_text_frame_content(), add one line as shown:

ID3v2_frame_text_content* parse_text_frame_content(ID3v2_frame* frame)
{
    if(frame == NULL)
    {
        return NULL;
    }

    ID3v2_frame_text_content* content = new_text_content(frame->size);
    content->encoding = frame->data[0];
    content->size = frame->size - ID3_FRAME_ENCODING;
    memcpy(content->data, frame->data + ID3_FRAME_ENCODING, content->size);

    //add this line:
    content->data=uni2text(content->data, content->size);

return content;
}
  • Re-compile your lib.
  • Re-compile your app.

The parsing function will now read ascii or unicode and insure content->data is ascii. NOTE: you may want to do this to parse_comment_frame_content(), as well, or any other parsing functions that may potentially return unicode text.

Cheers, Tony

Thanks man, solved my problem as well. Maybe open a pull request to incorporate the fix?