1 /*****************************************************************************
2 * ID3Tag.h : ID3v2 Parsing Helper
3 *****************************************************************************
4 * Copyright (C) 2016 VLC authors and VideoLAN
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
23 static uint32_t ID3TAG_ReadSize( const uint8_t *p_buffer
, bool b_syncsafe
)
26 return GetDWBE( p_buffer
);
27 return ( (uint32_t)p_buffer
[3] & 0x7F ) |
28 (( (uint32_t)p_buffer
[2] & 0x7F ) << 7) |
29 (( (uint32_t)p_buffer
[1] & 0x7F ) << 14) |
30 (( (uint32_t)p_buffer
[0] & 0x7F ) << 21);
33 static bool ID3TAG_IsTag( const uint8_t *p_buffer
, bool b_footer
)
35 return( memcmp(p_buffer
, (b_footer
) ? "3DI" : "ID3", 3) == 0 &&
38 ((GetDWBE(&p_buffer
[6]) & 0x80808080) == 0) );
41 static size_t ID3TAG_Parse( const uint8_t *p_peek
, size_t i_peek
,
42 int (*pf_callback
)(uint32_t, const uint8_t *, size_t, void *), void *p_priv
)
44 size_t i_total_size
= 0;
45 uint32_t i_ID3size
= 0;
46 if( i_peek
> 10 && ID3TAG_IsTag( p_peek
, false ) )
48 const bool b_syncsafe
= p_peek
[5] & 0x80;
49 i_ID3size
= ID3TAG_ReadSize( &p_peek
[6], true );
50 if( i_ID3size
> i_peek
- 10 )
52 i_total_size
= i_ID3size
+ 10;
53 const uint8_t *p_frame
= &p_peek
[10];
54 while( i_ID3size
> 10 )
56 uint32_t i_tagname
= VLC_FOURCC( p_frame
[0], p_frame
[1], p_frame
[2], p_frame
[3] );
57 uint32_t i_framesize
= ID3TAG_ReadSize( &p_frame
[4], b_syncsafe
) + 10;
58 if( i_framesize
> i_ID3size
)
61 if( i_framesize
> 10 &&
62 pf_callback( i_tagname
, &p_frame
[10], i_framesize
- 10, p_priv
) != VLC_SUCCESS
)
65 p_frame
+= i_framesize
;
66 i_ID3size
-= i_framesize
;
70 /* Count footer if any */
71 if( i_total_size
&& i_peek
- i_total_size
>= 10 &&
72 ID3TAG_IsTag( &p_peek
[i_total_size
], true ) )