⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aud_id3_parser.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
            if (audio_input_stream_read(input_stream, buf_size) != buf_size)
            {
                return KAL_FALSE;
            }
        }
        else
        {
            data_full_load = KAL_TRUE;
            /* read the whole tag header to read buffer (not include footer) */
            if (audio_input_stream_read(input_stream, v2_tag_size) != v2_tag_size)
            {
                return KAL_FALSE;
            }
        }

        /* reverse unsynchronisation process */
        if (id3_tag->v2_unsync)
        {
            if (!data_full_load)    /* if the tag is larger than our buffer size, we can't do reverse unsync process */
            {
                return KAL_TRUE;    /* but we still return TRUE */
            }
            v2_tag_size = id3_tag->v2_reverse_unsync_size =
                (kal_int32) id3_tag_reverse_unsync_process(ptr, v2_tag_size);
        }

        /* target size (v2_tag_size) not including 10 bytes v2 tag header */
        target_size = v2_tag_size;
        if (id3_tag->v2_exthdr)
        {
            /*
             * parse extended header and set the following 2 fields in id3_tag:
             * (1) v2_exthdr_size
             * (2) v2_crc
             */
            if (!id3_tag_parse_v2_tag_extended_header(ptr, id3_tag, data_full_load))
            {
                return KAL_FALSE;
            }

            /* point to frame start position */
            offset += id3_tag->v2_exthdr_size;
            ptr += id3_tag->v2_exthdr_size;
            target_size -= id3_tag->v2_exthdr_size;
        }

        /* parse frames */
        for (frame_size = 0; target_size > 0 && ptr + 15 <= input_stream->tail &&       /* 15 is the maximal frame header size */
             (parse_result = id3_tag_parse_v2_frame_header(ptr, target_size, &frame_header, id3_tag)) != PARSE_ID3_FRAME_NO_SPACE;
             ptr += frame_size, target_size -= frame_size)
        {
            /* check if frame id is invalid or frame size too large */
            if (frame_header.id[0] == 0 || frame_header.size > (kal_uint32) target_size)
            {
                break;
            }
            offset += frame_size;   /* offset always point to frame start position */
            frame_size = frame_header.size;
            if (parse_result != PARSE_ID3_FRAME_ABORT)
            {
                // we need to check if the frame boundary is within buffer
                // otherwise, we need to skip processing the frame data & move to next frame
                if (ptr + frame_size <= input_stream->tail)
                {
                    frame_data_ptr = ptr + frame_header.data_offset;

                    /* check unsync flag & reverse unsynchronisation process in a frame */
                    if (!id3_tag->v2_unsync && frame_header.unsync)
                    {
                        frame_header.data_size = id3_tag_reverse_unsync_process(frame_data_ptr, frame_header.data_size);
                    }

                    /* parse frame data */
                    if (frame_header.data_size > 1)
                    {
                        id3_tag_parse_v2_frame_data(frame_data_ptr, &frame_header, id3_tag);
                    }
                }
            }
        }

        // when data_full_load is FALSE, we can't finish parsing it in buffer in last step
        // so we keep loading data & parse frames
        if (!data_full_load)
        {
            target_size += frame_size;
            ptr = input_stream->buf;
            do
            {
                /* seek to the frame header start position */
                audio_input_stream_seek(input_stream, offset);

                /* we assume buf is >= 15 bytes, and read 15 bytes for parsing header */
                if (audio_input_stream_read(input_stream, 15) != 15)    /* 15 is the maximal frame header size */
                {
                    break;
                }

                parse_result = id3_tag_parse_v2_frame_header(ptr, target_size, &frame_header, id3_tag);
                if (parse_result == PARSE_ID3_FRAME_NO_SPACE)
                {
                    break;
                }
                /* check if frame id is invalid or frame size too large */
                if (frame_header.id[0] == 0 || frame_header.size > (kal_uint32) target_size)
                {
                    break;
                }

                frame_data_size = frame_header.data_size;

                // if it's our wanted frame, we need to check if the frame data size <= buf_size
                // otherwise, we need to skip processing the frame data & seek to next frame
                if (parse_result != PARSE_ID3_FRAME_ABORT && (kal_int32) frame_data_size <= buf_size)
                {
                    /* seek to the frame data start position */
                    audio_input_stream_seek(input_stream, offset + frame_header.data_offset);

                    /* read data bytes */
                    if ((kal_uint32) audio_input_stream_read(input_stream, frame_data_size) != frame_data_size)
                    {
                        break;
                    }

                    /* check unsync flag & reverse unsynchronisation process in a frame */
                    if (!id3_tag->v2_unsync && frame_header.unsync)
                    {
                        frame_data_size = frame_header.data_size = id3_tag_reverse_unsync_process(ptr, frame_data_size);
                    }

                    /* parse frame data */
                    if (frame_header.data_size > 1)
                    {
                        id3_tag_parse_v2_frame_data(ptr, &frame_header, id3_tag);
                    }
                }

                frame_size = frame_header.size;
                target_size -= frame_size;
                offset += frame_size;
            } while (target_size > 0);
        }

        return KAL_TRUE;
    }

    return KAL_FALSE;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse_v1_tag
 * DESCRIPTION
 *  
 * PARAMETERS
 *  input_stream        [?]     
 *  id3_tag             [?]     
 * RETURNS
 *  kal_bool
 *****************************************************************************/
kal_bool id3_tag_parse_v1_tag(audio_input_stream_struct *input_stream, id3_tag_struct *id3_tag)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_bool need_alloc_pool;
    kal_uint8 i;
    kal_uint8 *data, *ptr;
    id3_tag_frame_struct *frame_p;
    kal_uint32 len, j, size;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (audio_input_stream_read(input_stream, 128) != 128)
    {
        return KAL_FALSE;
    }
    data = input_stream->buf;

    /*
     * check id3v1 magic word -- "TAG"
     * and parse header and set the following 5 frames in id3_tag:
     * (1) title
     * (2) artist
     * (3) album
     * (4) year
     * (5) genre
     */
    if (!(data[0] == 'T' && data[1] == 'A' && data[2] == 'G'))
    {
        return KAL_FALSE;
    }

    for (i = 0; i < NUM_OF_ID3_FRAME; i++)
    {
        frame_p = &id3_tag->frames[i];
        if (frame_p->text != NULL)  /* check if the same frame in v2 exist */
        {
            continue;
        }

        ptr = data + id3_tag_v1_field_list[i].offset;
        size = (kal_uint32) id3_tag_v1_field_list[i].size;
        if (i == ID3_FRAME_GENRE)
        {
            if (*ptr < ID3_TAG_GENRE_NUM)
            {
                ptr = (kal_uint8*) id3_tag_genres[*ptr];
                size = 0xFFFF;  /* we know none string length in id3_tag_genres exceed this number */
            }
            else
            {
                continue;
            }
        }
        /* measure the string len with limited size boundary */
        len = 2;    /* UCS2 null terminator */
        for (j = 0; ptr[j] && j < size; j++)
        {
            if (ptr[j] > 0x7F)
            {
                j++;
                if (j == size)  /* if it's not ASCII and it's the last char, we discard it */
                {
                    break;
                }
            }
            len += 2;
        }

        /* check previous frame data from pool. we would like to reuse memory in pool as many as possible */
        if (frame_p->text == NULL || frame_p->size < len)
        {
            /* check available space in pool */
            if (id3_tag->text_pool.available_words << 1 >= len)
            {
                /* alloc space from pool */
                frame_p->text = id3_tag->text_pool.next_p;
                need_alloc_pool = KAL_TRUE;
            }
            else
            {
                continue;
            }
        }
        else
        {
            need_alloc_pool = KAL_FALSE;
        }

        /* transalte text to UCS2 and copy to dest space */
        len = (kal_uint32) mmi_chset_text_to_ucs2((kal_uint8*) frame_p->text, len, ptr);
        frame_p->size = len;
        if (need_alloc_pool)
        {
            id3_text_pool_consume(&id3_tag->text_pool, (len + 1) >> 1);
        }
    }
    return KAL_TRUE;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse
 * DESCRIPTION
 *  
 * PARAMETERS
 *  input_stream        [?]     
 *  id3_tag             [?]     
 * RETURNS
 *  kal_bool
 *****************************************************************************/
kal_bool id3_tag_parse(audio_input_stream_struct *input_stream, id3_tag_struct *id3_tag)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 data_size;
    kal_bool v2_result = KAL_FALSE;
    kal_bool v1_result = KAL_FALSE;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* init id3 tag data structure */
    id3_tag_init(id3_tag);

    audio_input_stream_seek(input_stream, 0);
    /*
     * check id3v2 magic word -- "ID3"
     * and parse & save data to frames
     */
    v2_result = id3_tag_parse_v2_tag(input_stream, id3_tag);

    if ((data_size = audio_input_stream_get_data_size(input_stream)) >= 128)
    {
        /* move to last 128 bytes before file end for checking id3v1 tag */
        audio_input_stream_seek(input_stream, data_size - 128);

        /*
         * check id3v1 magic word -- "TAG"
         * and parse & save data to frames
         */
        v1_result = id3_tag_parse_v1_tag(input_stream, id3_tag);
    }
    else
    {
        v1_result = KAL_FALSE;
    }

    return v1_result || v2_result;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse_v2_tag_size
 * DESCRIPTION
 *  
 * PARAMETERS
 *  data        [?]     
 * RETURNS
 *  kal_int32
 *****************************************************************************/
kal_int32 id3_tag_parse_v2_tag_size(kal_uint8 *data)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint8 flags, version;
    kal_bool footer = KAL_FALSE;
    kal_int32 tag_size;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* check id3v2 magic word -- "ID3" */
    if (!(data[0] == 'I' && data[1] == 'D' && data[2] == '3'))
    {
        return -1;
    }

    version = data[3];
    if (data[4] != 0)
    {
        return -1;
    }
    flags = data[5];

    switch (version)
    {
        case 4:
            if (flags & 0x0F)   /* check unset bits */
            {
                return -1;
            }
            if (flags & 0x10)   /* check footer flag */
            {
                footer = KAL_TRUE;
            }
        case 3:
            if (flags & 0x1F)   /* check unset bits */
            {
                return -1;
            }
            break;
        case 2:
            if (flags & 0x3F)   /* check unset bits */
            {
                return -1;
            }
            break;
        default:
            return -1;
    }

    /* get tag size */
    tag_size = (kal_int32) id3_tag_get_unsync_uint32(data + 6, 4) + 10; /* 6, 7, 8, 9 */
    if (footer)
    {
        tag_size += 10;
    }

    return tag_size;
}

#endif /* __RICH_AUDIO_PROFILE__ */ 

#endif /* MED_NOT_PRESENT */ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -