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

📄 aud_id3_parser.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (size > 4)   /* size should never exceed 5 */
    {
        num = *data++;
        size--;
    }
    for (; size > 0; size--)
    {
        num = (num << 7) | (*data++);
    }
    return num;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_get_uint32
 * DESCRIPTION
 *  
 * PARAMETERS
 *  data        [?]         
 *  size        [IN]        
 * RETURNS
 *  kal_uint32
 *****************************************************************************/
kal_uint32 id3_tag_get_uint32(kal_uint8 *data, kal_uint8 size)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint32 num;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    for (num = 0; size > 0; size--) /* size should never exceed 4 */
    {
        num = (num << 8) | (*data++);
    }
    return num;
}


/*****************************************************************************
 * FUNCTION
 *  id3_text_pool_init
 * DESCRIPTION
 *  
 * PARAMETERS
 *  id3_text_pool       [?]     
 * RETURNS
 *  void
 *****************************************************************************/
void id3_text_pool_init(id3_tag_text_pool_struct *id3_text_pool)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    id3_text_pool->next_p = id3_text_pool->text;
    id3_text_pool->available_words = ID3_TAG_POOL_SIZE/2;
}


/*****************************************************************************
 * FUNCTION
 *  id3_text_pool_consume
 * DESCRIPTION
 *  
 * PARAMETERS
 *  id3_text_pool       [?]         
 *  num_of_words        [IN]        
 * RETURNS
 *  void
 *****************************************************************************/
void id3_text_pool_consume(id3_tag_text_pool_struct *id3_text_pool, kal_uint32 num_of_words)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    id3_text_pool->next_p += num_of_words;
    id3_text_pool->available_words -= num_of_words;
}


/*****************************************************************************
 * FUNCTION
 *  id3_frame_init
 * DESCRIPTION
 *  
 * PARAMETERS
 *  id3_frame       [?]     
 * RETURNS
 *  void
 *****************************************************************************/
void id3_frame_init(id3_tag_frame_struct *id3_frame)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    id3_frame->text = NULL;
    id3_frame->size = 0;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_init
 * DESCRIPTION
 *  
 * PARAMETERS
 *  id3_tag     [?]     
 * RETURNS
 *  void
 *****************************************************************************/
void id3_tag_init(id3_tag_struct *id3_tag)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 i;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* init frames */
    for (i = 0; i < NUM_OF_ID3_FRAME; i++)
    {
        id3_frame_init(&id3_tag->frames[i]);
    }

    /* init text_pool */
    id3_text_pool_init(&id3_tag->text_pool);
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse_v2_tag_header
 * DESCRIPTION
 *  
 * PARAMETERS
 *  data        [?]     
 *  id3_tag     [?]     
 * RETURNS
 *  kal_bool
 *****************************************************************************/
kal_bool id3_tag_parse_v2_tag_header(kal_uint8 *data, id3_tag_struct *id3_tag)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint8 flags, version;

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

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

    /* init flags */
    id3_tag->v2_major_ver = version;
    id3_tag->v2_unsync = KAL_FALSE;
    id3_tag->v2_exthdr = KAL_FALSE;
    id3_tag->v2_footer = KAL_FALSE;

    switch (version)
    {
        case 4:
            if (flags & 0x0F)
            {
                return KAL_FALSE;
            }
            if (flags & 0x10)   /* check footer flag */
            {
                id3_tag->v2_footer = KAL_TRUE;
            }
        case 3:
            if (flags & 0x1F)
            {
                return KAL_FALSE;
            }
            if (flags & 0x20)   /* check extended header flag */
            {
                id3_tag->v2_exthdr = KAL_TRUE;
            }
            break;
        case 2:
            if (flags & 0x3F)
            {
                return KAL_FALSE;
            }
            if (flags & 0x40)   /* check compression flag, if it is set, ignore this tag */
            {
                return KAL_FALSE;
            }
            break;
        default:
            return KAL_FALSE;
    }
    if (flags & 0x80)   /* check unsynchronisation flag */
    {
        id3_tag->v2_unsync = KAL_TRUE;
    }

    /* get tag size */
    id3_tag->v2_size = id3_tag_get_unsync_uint32(data + 6, 4);  /* 6, 7, 8, 9 */

    return KAL_TRUE;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_reverse_unsync_process
 * DESCRIPTION
 *  
 * PARAMETERS
 *  data        [?]         
 *  size        [IN]        
 * RETURNS
 *  kal_uint32
 *****************************************************************************/
kal_uint32 id3_tag_reverse_unsync_process(kal_uint8 *data, kal_uint32 size)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint8 *output = data + 1;
    kal_uint8 *ptr = data;
    kal_uint8 prev_value;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (size == 0)
    {
        return 0;
    }
    for (prev_value = *ptr++, size--; size != 0; size--)
    {
        if (!(prev_value == 0xFF && *ptr == 0x00))
        {
            *output++ = *ptr;
        }
        prev_value = *ptr++;
    }

    return (kal_uint32) output - (kal_uint32) data;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse_v2_tag_extended_header
 * DESCRIPTION
 *  
 * IMPACT
 *  we assume id3 tag read buffer >= 14 bytes
 * PARAMETERS
 *  data                [?]         
 *  id3_tag             [?]         Kal_bool data_full_load;
 *  data_full_load      [IN]        
 * RETURNS
 *  kal_bool
 *****************************************************************************/
kal_bool id3_tag_parse_v2_tag_extended_header(kal_uint8 *data, id3_tag_struct *id3_tag, kal_bool data_full_load)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint32 extended_header_size;
    kal_uint32 tag_size;
    kal_uint32 padding_size;
    kal_uint32 crc_data_size;
    kal_uint32 crc_data;
    kal_uint8 *crc_data_start;
    kal_uint8 flags;
    kal_bool crc_data_present;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (id3_tag->v2_unsync)
    {
        tag_size = id3_tag->v2_reverse_unsync_size;
    }
    else
    {
        tag_size = id3_tag->v2_size;
    }
    switch (id3_tag->v2_major_ver)
    {
        case 4:
            extended_header_size = id3_tag_get_unsync_uint32(data, 4);  /* 0, 1, 2, 3 */
            /* check size */
            if (extended_header_size >= tag_size)
            {
                return KAL_FALSE;
            }
            if (data[4] != 0x01)    /* flag bytes must be 1 */
            {
                return KAL_FALSE;
            }
            flags = data[5];
            if (flags & 0x8F)   /* check unset flags */
            {
                return KAL_FALSE;
            }
            if (flags & 0x20)   /* check CRC data present flag */
            {
                crc_data_present = KAL_TRUE;
                if (data[6] != 0x05)    /* flag data length must be 5 */
                {
                    return KAL_FALSE;
                }
                crc_data = id3_tag_get_unsync_uint32(data + 7, 5);      /* 7, 8, 9, 10, 11 */
                crc_data_start = data + 12;
                crc_data_size = tag_size - extended_header_size;
            }
            else
            {
                crc_data_present = KAL_FALSE;
            }
            break;
        case 3:
            extended_header_size = id3_tag_get_uint32(data, 4); /* 0, 1, 2, 3 */
            if (data[5] != 0)   /* 2nd flag must be all unset */
            {
                return KAL_FALSE;
            }
            padding_size = id3_tag_get_uint32(data + 6, 4); /* 6, 7, 8, 9 */
            /* check size */
            if (extended_header_size + padding_size >= tag_size)
            {
                return KAL_FALSE;
            }
            flags = data[4];
            if (flags & 0x80)   /* check CRC data present flag */
            {
                crc_data_present = KAL_TRUE;
                crc_data = id3_tag_get_uint32(data + 10, 4);    /* 10, 11, 12, 13 */
                crc_data_start = data + 14;
                crc_data_size = tag_size - extended_header_size - padding_size;
            }
            else
            {
                crc_data_present = KAL_FALSE;
            }
            break;
        default:
            return KAL_FALSE;
    }

    if (crc_data_present && data_full_load) /* if tag is larger than our buffer size, we skip CRC check process */
    {
        if (med_crc_calculate((kal_uint8 const*)crc_data_start, crc_data_size) != crc_data)
        {
            return KAL_FALSE;
        }
    }

    /* get extended header size */
    id3_tag->v2_exthdr_size = extended_header_size;
    id3_tag->v2_crc = crc_data_present;

    return KAL_TRUE;
}


/*****************************************************************************
 * FUNCTION
 *  id3_tag_parse_v2_frame_header

⌨️ 快捷键说明

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