|
kmediad 0.5.0a
A cross-platform Web-based audio player
|
Defines an ID3 targ reader and parser. More...
Go to the source code of this file.
Data Structures | |
| struct | Tag |
| Models a single ID3 tag. More... | |
| struct | TagData |
| A linked list of Tag objects. More... | |
Typedefs | |
| typedef struct Tag | Tag |
| Models a single ID3 tag. | |
Enumerations | |
| enum | TagResult { TAG_OK = 0, TAG_READERROR = 1, TAG_NOID3V2 = 2, TAG_TRUNCATED = 3, TAG_OUTOFMEMORY = 4, TAG_UNSUPFORMAT = 5, TAG_NOVORBIS = 6 } |
| Error codes returned by the tag reader. More... | |
| enum | TagType { TAG_TYPE_TEXT = 0, TAG_TYPE_BINARY = 1 } |
| enum | TagCommonID { TAG_COMMON_TITLE, TAG_COMMON_ALBUM, TAG_COMMON_ARTIST, TAG_COMMON_COMPOSER, TAG_COMMON_YEAR, TAG_COMMON_GENRE, TAG_COMMON_TRACK } |
| Common tag names -- see tag_get_common for more information. More... | |
Functions | |
| TagResult | tag_get_id3v2_tags (const char *file, TagData **tag_data_ret) |
| read all ID3 tags from the file, if poissible. | |
| TagResult | tag_get_flac_tags (const char *file, TagData **tag_data_ret) |
| read all ID3 tags from the file, if poissible. | |
| int | tag_get_tag_count (TagData *tag_data) |
| Counts the tags in a TagData struct returned by tag_get_tags. | |
| void | tag_free_tag_data (TagData *tag_data) |
| Free a TagData struct created by tag_get_tags. | |
| Tag * | tag_get_tag (const TagData *tag_data, int index) |
| Get a specific Tag entry from a TagData struct created by tag_get_tags. | |
| const unsigned char * | tag_get_by_id (const TagData *tag_data, const char *id) |
| Get the Tag entry from a TagData struct created by tag_get_tags which has the specific character ID, e.g., 'TCOM'. | |
| const unsigned char * | tag_get_common (const TagData *tag_data, TagCommonID id) |
| Get the Tag entry from a TagData struct created by tag_get_tags which has the specified common ID (e.g., TAG_COMMON_TITLE. | |
| TagResult | tag_get_tags (const char *file, TagData **tag_data_ret) |
| Invoked the tag scanner, trying all the formats that are supported. | |
Defines an ID3 targ reader and parser.
| enum TagCommonID |
Common tag names -- see tag_get_common for more information.
| enum TagResult |
Error codes returned by the tag reader.
| TAG_OK | |
| TAG_READERROR | |
| TAG_NOID3V2 | |
| TAG_TRUNCATED | |
| TAG_OUTOFMEMORY | |
| TAG_UNSUPFORMAT | |
| TAG_NOVORBIS |
{
TAG_OK = 0,
TAG_READERROR = 1, // File read error
TAG_NOID3V2 = 2, // File does not contain an ID3V2 tag
TAG_TRUNCATED = 3, // File runs out in the middle of a frame
TAG_OUTOFMEMORY = 4,
TAG_UNSUPFORMAT = 5, // Tag is a version we don't support
TAG_NOVORBIS = 6, // File does not contain VORBIS comments
} TagResult;
| enum TagType |
{
TAG_TYPE_TEXT = 0,
TAG_TYPE_BINARY = 1
} TagType;
| void tag_free_tag_data | ( | TagData * | tag_data | ) |
| const unsigned char* tag_get_by_id | ( | const TagData * | tag_data, |
| const char * | id | ||
| ) |
Get the Tag entry from a TagData struct created by tag_get_tags which has the specific character ID, e.g., 'TCOM'.
In general, callers should prefer tag_get_common, which handles differences in tag naming between the different formats
| const unsigned char* tag_get_common | ( | const TagData * | tag_data, |
| TagCommonID | id | ||
| ) |
Get the Tag entry from a TagData struct created by tag_get_tags which has the specified common ID (e.g., TAG_COMMON_TITLE.
This method will work across all the supported formats.)
{
const unsigned char *s;
switch (id)
{
case TAG_COMMON_TITLE:
s = tag_get_by_id (tag_data, "TIT2");
if (!s) s = tag_get_by_id (tag_data, "TT2");
if (!s) s = tag_get_by_id (tag_data, "TITLE");
return s;
case TAG_COMMON_ARTIST:
s = tag_get_by_id (tag_data, "TPE1");
if (!s) s = tag_get_by_id (tag_data, "TP1");
if (!s) s = tag_get_by_id (tag_data, "ARTIST");
return s;
case TAG_COMMON_GENRE:
s = tag_get_by_id (tag_data, "TCON");
if (!s) s = tag_get_by_id (tag_data, "TCO");
if (!s) s = tag_get_by_id (tag_data, "GENRE");
return s;
case TAG_COMMON_ALBUM:
s = tag_get_by_id (tag_data, "TALB");
if (!s) s = tag_get_by_id (tag_data, "TAL");
if (!s) s = tag_get_by_id (tag_data, "ALBUM");
return s;
case TAG_COMMON_COMPOSER:
s = tag_get_by_id (tag_data, "TCOM");
if (!s) s = tag_get_by_id (tag_data, "TCM");
if (!s) s = tag_get_by_id (tag_data, "COMPOSER");
return s;
case TAG_COMMON_YEAR:
s = tag_get_by_id (tag_data, "TYER");
if (!s) s = tag_get_by_id (tag_data, "TYE");
if (!s) s = tag_get_by_id (tag_data, "DATE");
return s;
case TAG_COMMON_TRACK:
s = tag_get_by_id (tag_data, "TRCK");
if (!s) s = tag_get_by_id (tag_data, "TRK");
if (!s) s = tag_get_by_id (tag_data, "TRACKNUMBER");
return s;
}
return NULL;
}
read all ID3 tags from the file, if poissible.
The function allocates memory for a TagData struct, which must be freed by the called
{
TagData *tag_data = (TagData*) malloc (sizeof (TagData));
if (!tag_data)
{
*tag_data_ret = NULL;
return TAG_OUTOFMEMORY;
}
*tag_data_ret = tag_data;
memset (tag_data, 0, sizeof (TagData));
int f = open (file, O_RDONLY);
if (f <= 0) return TAG_READERROR;
unsigned char buff[100];
if (read (f, buff, 4) != 4)
{
close (f);
return TAG_UNSUPFORMAT;
};
if (strncmp ((char *)buff, "fLaC", 4))
{
close (f);
return TAG_UNSUPFORMAT;
};
int got_it = 0;
int last_block = 0;
while (!got_it && !last_block)
{
if (read (f, buff, 4) != 4)
{
close (f);
return TAG_UNSUPFORMAT;
}
int block_type = buff[0] & 0x7F;
last_block = buff[0] & 0x80;
int block_size = (256 * 256) * buff[1]
+ 256 * buff[2] + buff[3];
// printf ("size = %d, last = %d type = %d\n", block_size,
// last_block, block_type);
if (block_type == 4)
{
#ifdef TAG_DEBUG
printf ("Found comment block of size %d\n", block_size);
#endif
got_it = 1;
unsigned char *bigbuff = (unsigned char *) malloc (block_size);
if (!bigbuff)
{
close (f);
return TAG_OUTOFMEMORY;
}
if (read (f, bigbuff, block_size) != block_size)
{
close (f);
return TAG_TRUNCATED;
}
Tag **p_current_tag = &(tag_data->tag);
int ret = tag_parse_vorbis_comments (bigbuff, p_current_tag);
free (bigbuff);
close (f);
return ret;
}
else
lseek (f, block_size, SEEK_CUR);
}
close (f);
return TAG_OK;
}
read all ID3 tags from the file, if poissible.
The function allocates memory for a TagData struct, which must be freed by the called
{
TagData *tag_data = (TagData*) malloc (sizeof (TagData));
if (!tag_data)
{
*tag_data_ret = NULL;
return TAG_OUTOFMEMORY;
}
*tag_data_ret = tag_data;
memset (tag_data, 0, sizeof (TagData));
#ifdef WIN32
int f = open (file, O_RDONLY | O_BINARY);
#else
int f = open (file, O_RDONLY);
#endif
char buff[10];
unsigned char b1, b2, b3, b4;
if (f <= 0) return TAG_READERROR;
if (read (f, &buff, 10) != 10)
{
close (f);
return TAG_NOID3V2;
}
if (strncmp (buff, "ID3", 3))
{
close (f);
return TAG_NOID3V2;
}
int id3Major = buff[3];
int id3Minor = buff[4];
#ifdef TAG_DEBUG
printf ("ID3v2 version = %d.%d\n", id3Major, id3Minor);
#endif
if (buff[5] & 0x80)
{
// We don't support extended headers yet
close (f);
return TAG_UNSUPFORMAT;
}
b1 = buff[6];
b2 = buff[7];
b3 = buff[8];
b4 = buff[9];
int id3len = (128 * 128 * 128) * b1 +
(128 * 128) * b2 +
(128) * b3 +
b4;
#ifdef TAG_DEBUG
printf ("ID3V2 Header length = %d\n", id3len);
#endif
TagResult r;
int carry_on = 1;
Tag **p_current_tag = &(tag_data->tag);
int total_bytes = 0;
do
{
char *frameId = NULL;
unsigned char *data = NULL;
r = tag_read_frame (f, id3Major, &carry_on, &frameId, &data, &total_bytes,
tag_data); // We pass tag_data here only for the APIC frame
#ifdef TAG_DEBUG
printf ("Read %d bytes from header\n", total_bytes);
#endif
if (frameId && data)
{
Tag *tag = (Tag *)malloc (sizeof (Tag));
memset (tag, 0, sizeof (Tag));
tag->frameId = frameId;
tag->data = data;
tag->next = NULL;
*p_current_tag = tag;
p_current_tag = &((*p_current_tag)->next);
}
} while (r == TAG_OK && carry_on && total_bytes < id3len);
#ifdef TAG_DEBUG
printf ("Read %d bytes from header\n", total_bytes);
#endif
close (f);
return r;
}
| int tag_get_tag_count | ( | TagData * | tag_data | ) |
Counts the tags in a TagData struct returned by tag_get_tags.
Invoked the tag scanner, trying all the formats that are supported.
{
TagResult ret = tag_get_id3v2_tags (file, tag_data_ret);
if (ret == TAG_NOID3V2)
{
ret = tag_get_flac_tags (file, tag_data_ret);;
}
return ret;
}
1.7.4