/*
* libid3tag - ID3 tag manipulation library
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: tag.c,v 1.20 2004/02/17 02:04:10 rob Exp $
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "global.h"
# include <string.h>
# include <stdlib.h>
# ifdef HAVE_ASSERT_H
# include <assert.h>
# endif
# include "id3tag.h"
# include "tag.h"
# include "frame.h"
# include "compat.h"
# include "parse.h"
# include "render.h"
# include "latin1.h"
# include "ucs4.h"
# include "genre.h"
# include "crc.h"
# include "field.h"
# include "util.h"
/*
* NAME: tag->new()
* DESCRIPTION: allocate and return a new, empty tag
*/
struct id3_tag *id3_tag_new(void)
{
struct id3_tag *tag;
tag = malloc(sizeof(*tag));
if (tag) {
tag->refcount = 0;
tag->version = ID3_TAG_VERSION;
tag->flags = 0;
tag->extendedflags = 0;
tag->restrictions = 0;
tag->options = /* ID3_TAG_OPTION_UNSYNCHRONISATION | */
ID3_TAG_OPTION_COMPRESSION | ID3_TAG_OPTION_CRC;
tag->nframes = 0;
tag->frames = 0;
tag->paddedsize = 0;
}
return tag;
}
/*
* NAME: tag->delete()
* DESCRIPTION: destroy a tag and deallocate all associated memory
*/
void id3_tag_delete(struct id3_tag *tag)
{
assert(tag);
if (tag->refcount == 0) {
id3_tag_clearframes(tag);
if (tag->frames)
free(tag->frames);
free(tag);
}
}
/*
* NAME: tag->addref()
* DESCRIPTION: add an external reference to a tag
*/
void id3_tag_addref(struct id3_tag *tag)
{
assert(tag);
++tag->refcount;
}
/*
* NAME: tag->delref()
* DESCRIPTION: remove an external reference to a tag
*/
void id3_tag_delref(struct id3_tag *tag)
{
assert(tag && tag->refcount > 0);
--tag->refcount;
}
/*
* NAME: tag->version()
* DESCRIPTION: return the tag's original ID3 version number
*/
unsigned int id3_tag_version(struct id3_tag const *tag)
{
assert(tag);
return tag->version;
}
/*
* NAME: tag->options()
* DESCRIPTION: get or set tag options
*/
int id3_tag_options(struct id3_tag *tag, int mask, int values)
{
assert(tag);
if (mask)
tag->options = (tag->options & ~mask) | (values & mask);
return tag->options;
}
/*
* NAME: tag->setlength()
* DESCRIPTION: set the minimum rendered tag size
*/
void id3_tag_setlength(struct id3_tag *tag, id3_length_t length)
{
assert(tag);
tag->paddedsize = length;
}
/*
* NAME: tag->clearframes()
* DESCRIPTION: detach and delete all frames associated with a tag
*/
void id3_tag_clearframes(struct id3_tag *tag)
{
unsigned int i;
assert(tag);
for (i = 0; i < tag->nframes; ++i) {
id3_frame_delref(tag->frames[i]);
id3_frame_delete(tag->frames[i]);
}
tag->nframes = 0;
}
/*
* NAME: tag->attachframe()
* DESCRIPTION: attach a frame to a tag
*/
int id3_tag_attachframe(struct id3_tag *tag, struct id3_frame *frame)
{
struct id3_frame **frames;
assert(tag && frame);
frames = realloc(tag->frames, (tag->nframes + 1) * sizeof(*frames));
if (frames == 0)
return -1;
tag->frames = frames;
tag->frames[tag->nframes++] = frame;
id3_frame_addref(frame);
return 0;
}
/*
* NAME: tag->detachframe()
* DESCRIPTION: detach (but don't delete) a frame from a tag
*/
int id3_tag_detachframe(struct id3_tag *tag, struct id3_frame *frame)
{
unsigned int i;
assert(tag && frame);
for (i = 0; i < tag->nframes; ++i) {
if (tag->frames[i] == frame)
break;
}
if (i == tag->nframes)
return -1;
--tag->nframes;
while (i++ < tag->nframes)
tag->frames[i - 1] = tag->frames[i];
id3_frame_delref(frame);
return 0;
}
/*
* NAME: tag->findframe()
* DESCRIPTION: find in a tag the nth (0-based) frame with the given frame ID
*/
struct id3_frame *id3_tag_findframe(struct id3_tag const *tag,
char const *id, unsigned int index)
{
unsigned int len, i;
assert(tag);
if (id == 0 || *id == 0)
return (index < tag->nframes) ? tag->frames[index] : 0;
len = strlen(id);
if (len == 4) {
struct id3_compat const *compat;
compat = id3_compat_lookup(id, len);
if (compat && compat->equiv && !compat->translate) {
id = compat->equiv;
len = strlen(id);
}
}
for (i = 0; i < tag->nframes; ++i) {
if (strncmp(tag->frames[i]->id, id, len) == 0 && index-- == 0)
return tag->frames[i];
}
return 0;
}
enum tagtype {
TAGTYPE_NONE = 0,
TAGTYPE_ID3V1,
TAGTYPE_ID3V2,
TAGTYPE_ID3V2_FOOTER
};
static
enum tagtype tagtype(id3_byte_t const *data, id3_length_t length)
{
if (length >= 3 &&
data[0] == 'T' && data[1] == 'A' && data[2] == 'G')
return TAGTYPE_ID3V1;
if (length >= 10 &&
((data[0] == 'I' && data[1] == 'D' && data[2] == '3') ||
(data[0] == '3' && data[1] == 'D' && data[2] == 'I')) &&
data[3] < 0xff && data[4] < 0xff &&
data[6] < 0x80 && data[7] < 0x80 && data[8] < 0x80 && data[9] < 0x80)
return data[0] == 'I' ? TAGTYPE_ID3V2 : TAGTYPE_ID3V2_FOOTER;
return TAGTYPE_NONE;
}
static
void parse_header(id3_byte_t const **ptr,
unsigned int *version, int *flags, id3_length_t *size)
{
*ptr += 3;
*version = id3_parse_uint(ptr, 2);
*flags = id3_parse_uint(ptr, 1);
*size = id3_parse_syncsafe(ptr, 4);
}
/*
* NAME: tag->query()
* DESCRIPTION: if a tag begins at the given location, return its size
*/
signed long id3_tag_query(id3_byte_t const *data, id3_length_t length)
{
unsigned int version;
int flags;
id3_length_t size;
assert(data);
switch (tagtype(data, length)) {
case TAGTYPE_ID3V1:
return 128;
case TAGTYPE_ID3V2:
parse_header(&data, &version, &flags, &size);
if (flags & ID3_TAG_FLAG_FOOTERPRESENT)
size += 10;
return 10 + size;
case TAGTYPE_ID3V2_FOOTER:
parse_header(&data, &version, &flags, &size);
return -size - 10;
case TAGTYPE_NONE:
break;
}
return 0;
}
static
void trim(char *str)
{
char *ptr;
ptr = str + strlen(str);
while (ptr > str && ptr[-1] == ' ')
--ptr;
*ptr = 0;
}
static
int v1_attachstr(struct id3_tag *tag, char const *id,
char *text, unsigned long number)
{
struct id3_frame *frame;
id3_ucs4_t ucs4[31];
if (text) {
trim(text);
if (*text == 0)
return 0;
}
frame = id3_frame_new(id);
if (frame == 0)
return -1;
if (id3_field_settextencoding(&frame->fields[0],
ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1)
goto fail;
if (text)
id3_latin1_decode(text, ucs4);
else
id3_ucs4_putnumber(ucs4, number);
if (strcmp(id, ID3_FRAME_COMMENT) == 0) {
if (id3_field_setlanguage(&frame->fields[1], "XXX") == -1 ||
id3_field_setstring(&frame->fields[2], id3_ucs4_empty) == -1 ||
id3_field_setfullstring(&frame->fields[3], ucs4) == -1)
goto fail;
}
else {
id3_ucs4_t *ptr = ucs4;
if (id3_field_setstrings(&frame->fields[1], 1, &ptr) == -1)
goto fail;
}
if (id3_tag_attachframe(tag, frame) == -1)
goto fail;
return 0;
fail:
id3_frame_delete(frame);
return -1;
}
static
struct id3_tag *v1_parse(id3_byte_t const *data)
{
struct id3_tag *tag;
tag = id3_tag_new();
if (tag) {
char title[31], artist[31], album[31], year[5], comment[31];
unsigned int genre, track;
tag->version = 0x0100;
tag->option
没有合适的资源?快使用搜索试试~ 我知道了~
libid3tag-0.15.1b.tar.gz
需积分: 50 33 下载量 91 浏览量
2016-04-14
17:35:38
上传
评论
收藏 330KB GZ 举报
温馨提示
共67个文件
h:20个
c:17个
in:5个
Linux中madplay 音乐播放器移植参考这篇文章:http://blog.csdn.net/qq_21792169/article/details/48104267
资源推荐
资源详情
资源评论
收起资源包目录
libid3tag-0.15.1b.tar.gz (67个子文件)
libid3tag-0.15.1b
msvc++
libid3tag.dsp 5KB
Makefile.am 977B
config.h 2KB
Makefile.in 8KB
frame.h 1KB
render.c 4KB
genre.c 3KB
config.guess 42KB
version.c 1KB
mkinstalldirs 2KB
tag.h 1KB
config.sub 30KB
COPYING 18KB
compat.c 16KB
VERSION 85B
field.h 1KB
aclocal.m4 236KB
INSTALL 8KB
frametype.gperf 10KB
crc.c 6KB
utf16.c 6KB
compat.h 1KB
utf16.h 2KB
install-sh 6KB
file.c 13KB
file.h 938B
Makefile.am 4KB
genre.dat 17KB
genre.dat.in 2KB
configure 672KB
CREDITS 765B
util.c 3KB
missing 10KB
tag.c 19KB
field.c 18KB
utf8.h 2KB
COPYRIGHT 923B
CHANGES 3KB
frametype.h 1KB
utf8.c 9KB
depcomp 13KB
config.h.in 2KB
latin1.h 2KB
util.h 1KB
frametype.c 18KB
genre.dat.sed 1KB
configure.ac 4KB
frame.c 13KB
libid3tag.list.in 582B
version.h 947B
render.h 2KB
id3tag.h 10KB
TODO 278B
ucs4.c 5KB
parse.c 4KB
compat.gperf 8KB
Makefile.in 27KB
README 3KB
ltmain.sh 178KB
debug.h 1KB
latin1.c 5KB
crc.h 1023B
genre.h 971B
global.h 2KB
debug.c 4KB
parse.h 1KB
ucs4.h 1KB
共 67 条
- 1
资源评论
HeroKern
- 粉丝: 4766
- 资源: 110
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功