Lines Matching defs:tag
2 * libid3tag - ID3 tag manipulation library
19 * $Id: tag.c,v 1.18 2003/04/19 00:14:33 rob Exp $
36 # include "tag.h"
49 * NAME: tag->new()
50 * DESCRIPTION: allocate and return a new, empty tag
54 struct id3_tag *tag;
56 tag = malloc(sizeof(*tag));
57 if (tag) {
58 tag->refcount = 0;
59 tag->version = ID3_TAG_VERSION;
60 tag->flags = 0;
61 tag->extendedflags = 0;
62 tag->restrictions = 0;
63 tag->options = /* ID3_TAG_OPTION_UNSYNCHRONISATION | */
65 tag->nframes = 0;
66 tag->frames = 0;
67 tag->paddedsize = 0;
70 return tag;
74 * NAME: tag->delete()
75 * DESCRIPTION: destroy a tag and deallocate all associated memory
77 void id3_tag_delete(struct id3_tag *tag)
79 assert(tag);
81 if (tag->refcount == 0) {
82 id3_tag_clearframes(tag);
84 if (tag->frames)
85 free(tag->frames);
87 free(tag);
92 * NAME: tag->addref()
93 * DESCRIPTION: add an external reference to a tag
95 void id3_tag_addref(struct id3_tag *tag)
97 assert(tag);
99 ++tag->refcount;
103 * NAME: tag->delref()
104 * DESCRIPTION: remove an external reference to a tag
106 void id3_tag_delref(struct id3_tag *tag)
108 assert(tag && tag->refcount > 0);
110 --tag->refcount;
114 * NAME: tag->version()
115 * DESCRIPTION: return the tag's original ID3 version number
117 unsigned int id3_tag_version(struct id3_tag const *tag)
119 assert(tag);
121 return tag->version;
125 * NAME: tag->options()
126 * DESCRIPTION: get or set tag options
128 int id3_tag_options(struct id3_tag *tag, int mask, int values)
130 assert(tag);
133 tag->options = (tag->options & ~mask) | (values & mask);
135 return tag->options;
139 * NAME: tag->setlength()
140 * DESCRIPTION: set the minimum rendered tag size
142 void id3_tag_setlength(struct id3_tag *tag, id3_length_t length)
144 assert(tag);
146 tag->paddedsize = length;
150 * NAME: tag->clearframes()
151 * DESCRIPTION: detach and delete all frames associated with a tag
153 void id3_tag_clearframes(struct id3_tag *tag)
157 assert(tag);
159 for (i = 0; i < tag->nframes; ++i) {
160 id3_frame_delref(tag->frames[i]);
161 id3_frame_delete(tag->frames[i]);
164 tag->nframes = 0;
168 * NAME: tag->attachframe()
169 * DESCRIPTION: attach a frame to a tag
171 int id3_tag_attachframe(struct id3_tag *tag, struct id3_frame *frame)
175 assert(tag && frame);
177 frames = realloc(tag->frames, (tag->nframes + 1) * sizeof(*frames));
181 tag->frames = frames;
182 tag->frames[tag->nframes++] = frame;
190 * NAME: tag->detachframe()
191 * DESCRIPTION: detach (but don't delete) a frame from a tag
193 int id3_tag_detachframe(struct id3_tag *tag, struct id3_frame *frame)
197 assert(tag && frame);
199 for (i = 0; i < tag->nframes; ++i) {
200 if (tag->frames[i] == frame)
204 if (i == tag->nframes)
207 --tag->nframes;
208 while (i++ < tag->nframes)
209 tag->frames[i - 1] = tag->frames[i];
217 * NAME: tag->findframe()
218 * DESCRIPTION: find in a tag the nth (0-based) frame with the given frame ID
220 struct id3_frame *id3_tag_findframe(struct id3_tag const *tag,
225 assert(tag);
228 return (index < tag->nframes) ? tag->frames[index] : 0;
242 for (i = 0; i < tag->nframes; ++i) {
243 if (strncmp(tag->frames[i]->id, id, len) == 0 && index-- == 0)
244 return tag->frames[i];
286 * NAME: tag->query()
287 * DESCRIPTION: if a tag begins at the given location, return its size
333 int v1_attachstr(struct id3_tag *tag, char const *id,
371 if (id3_tag_attachframe(tag, frame) == -1)
384 struct id3_tag *tag;
386 tag = id3_tag_new();
387 if (tag) {
391 tag->version = 0x0100;
393 tag->options |= ID3_TAG_OPTION_ID3V1;
394 tag->options &= ~ID3_TAG_OPTION_COMPRESSION;
396 tag->restrictions =
413 tag->version = 0x0101;
416 /* populate tag frames */
418 if (v1_attachstr(tag, ID3_FRAME_TITLE, title, 0) == -1 ||
419 v1_attachstr(tag, ID3_FRAME_ARTIST, artist, 0) == -1 ||
420 v1_attachstr(tag, ID3_FRAME_ALBUM, album, 0) == -1 ||
421 v1_attachstr(tag, ID3_FRAME_YEAR, year, 0) == -1 ||
422 (track && v1_attachstr(tag, ID3_FRAME_TRACK, 0, track) == -1) ||
423 (genre < 0xff && v1_attachstr(tag, ID3_FRAME_GENRE, 0, genre) == -1) ||
424 v1_attachstr(tag, ID3_FRAME_COMMENT, comment, 0) == -1) {
425 id3_tag_delete(tag);
426 tag = 0;
430 return tag;
436 struct id3_tag *tag;
439 tag = id3_tag_new();
440 if (tag) {
444 parse_header(&ptr, &tag->version, &tag->flags, &size);
446 tag->paddedsize = 10 + size;
448 if ((tag->flags & ID3_TAG_FLAG_UNSYNCHRONISATION) &&
449 ID3_TAG_VERSION_MAJOR(tag->version) < 4) {
462 if (tag->flags & ID3_TAG_FLAG_EXTENDEDHEADER) {
463 switch (ID3_TAG_VERSION_MAJOR(tag->version)) {
512 tag->extendedflags |= ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT;
563 tag->extendedflags = id3_parse_uint(&ptr, 1);
567 if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE) {
572 if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT) {
586 if (tag->extendedflags & ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS) {
591 tag->restrictions = id3_parse_uint(&ehptr, 1);
607 frame = id3_frame_parse(&ptr, end - ptr, tag->version);
608 if (frame == 0 || id3_tag_attachframe(tag, frame) == -1)
612 if (ID3_TAG_VERSION_MAJOR(tag->version) < 4 &&
613 id3_compat_fixup(tag) == -1)
619 id3_tag_delete(tag);
620 tag = 0;
626 return tag;
630 * NAME: tag->parse()
631 * DESCRIPTION: parse a complete ID3 tag
672 void v1_renderstr(struct id3_tag const *tag, char const *frameid,
678 frame = id3_tag_findframe(tag, frameid, 0);
693 * DESCRIPTION: render an ID3v1 (or ID3v1.1) tag
696 id3_length_t v1_render(struct id3_tag const *tag, id3_byte_t *buffer)
707 v1_renderstr(tag, ID3_FRAME_TITLE, &ptr, 30);
708 v1_renderstr(tag, ID3_FRAME_ARTIST, &ptr, 30);
709 v1_renderstr(tag, ID3_FRAME_ALBUM, &ptr, 30);
710 v1_renderstr(tag, ID3_FRAME_YEAR, &ptr, 4);
711 v1_renderstr(tag, ID3_FRAME_COMMENT, &ptr, 30);
715 frame = id3_tag_findframe(tag, ID3_FRAME_TRACK, 0);
728 frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0);
746 /* make sure the tag is not empty */
765 * NAME: tag->render()
766 * DESCRIPTION: render a complete ID3 tag
768 id3_length_t id3_tag_render(struct id3_tag const *tag, id3_byte_t *buffer)
776 assert(tag);
778 if (tag->options & ID3_TAG_OPTION_ID3V1)
779 return v1_render(tag, buffer);
781 /* a tag must contain at least one (renderable) frame */
783 for (i = 0; i < tag->nframes; ++i) {
784 if (id3_frame_render(tag->frames[i], 0, 0) > 0)
788 if (i == tag->nframes)
795 flags = tag->flags & ID3_TAG_FLAG_KNOWNFLAGS;
796 extendedflags = tag->extendedflags & ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS;
799 if (tag->options & ID3_TAG_OPTION_CRC)
803 if (tag->restrictions)
807 if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION)
815 if (tag->options & ID3_TAG_OPTION_APPENDEDTAG)
859 ehsize += id3_render_int(ptr, tag->restrictions, 1);
873 for (i = 0; i < tag->nframes; ++i)
874 size += id3_frame_render(tag->frames[i], ptr, tag->options);
879 if (size < tag->paddedsize)
880 size += id3_render_padding(ptr, 0, tag->paddedsize - size);
881 else if (tag->options & ID3_TAG_OPTION_UNSYNCHRONISATION) {
891 /* patch tag size and CRC */