0
|
1 /*********************************************************************
|
|
2 *
|
|
3 * Copyright (C) 1999-2000, Espen Skoglund
|
|
4 * Department of Computer Science, University of Tromsų
|
|
5 *
|
|
6 * Filename: id3_tag.c
|
|
7 * Description: Code for handling ID3 tags.
|
|
8 * Author: Espen Skoglund <espensk@stud.cs.uit.no>
|
|
9 * Created at: Tue Feb 9 21:13:19 1999
|
|
10 *
|
|
11 * $Id: id3_tag.c,v 1.6 2004/07/20 21:47:22 descender Exp $
|
|
12 *
|
|
13 * This program is free software; you can redistribute it and/or
|
|
14 * modify it under the terms of the GNU General Public License
|
|
15 * as published by the Free Software Foundation; either version 2
|
|
16 * of the License, or (at your option) any later version.
|
|
17 *
|
|
18 * This program is distributed in the hope that it will be useful,
|
|
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
21 * GNU General Public License for more details.
|
|
22 *
|
|
23 * You should have received a copy of the GNU General Public License
|
|
24 * along with this program; if not, write to the Free Software
|
|
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
26 *
|
|
27 ********************************************************************/
|
|
28 #include <glib.h>
|
|
29
|
|
30 #include "xmms-id3.h"
|
|
31 #include "id3_header.h"
|
|
32
|
|
33
|
|
34 /*
|
|
35 * Function id3_init_tag (id3)
|
|
36 *
|
|
37 * Initialize an empty ID3 tag.
|
|
38 *
|
|
39 */
|
|
40 void
|
|
41 id3_init_tag(struct id3_tag *id3)
|
|
42 {
|
|
43 /*
|
|
44 * Initialize header.
|
|
45 */
|
|
46 id3->id3_version = 3;
|
|
47 id3->id3_revision = 0;
|
|
48 id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP;
|
|
49 id3->id3_tagsize = 0;
|
|
50
|
|
51 id3->id3_altered = 1;
|
|
52 id3->id3_newtag = 1;
|
|
53 id3->id3_pos = 0;
|
|
54
|
|
55 /*
|
|
56 * Initialize frames.
|
|
57 */
|
|
58 id3->id3_frame = NULL;
|
|
59 }
|
|
60
|
|
61
|
|
62 /*
|
|
63 * Function id3_read_tag (id3)
|
|
64 *
|
|
65 * Read the ID3 tag from the input stream. The start of the tag
|
|
66 * must be positioned in the next tag in the stream. Return 0 upon
|
|
67 * success, or -1 if an error occured.
|
|
68 *
|
|
69 */
|
|
70 int
|
|
71 id3_read_tag(struct id3_tag *id3)
|
|
72 {
|
|
73 char *buf;
|
|
74
|
|
75 /*
|
|
76 * We know that the tag will be at least this big.
|
|
77 *
|
|
78 * tag header + "ID3"
|
|
79 */
|
|
80 id3->id3_tagsize = ID3_TAGHDR_SIZE + 3;
|
|
81
|
|
82 if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) {
|
|
83 /*
|
|
84 * Check if we have a valid ID3 tag.
|
|
85 */
|
|
86 char *id = id3->id3_read(id3, NULL, 3);
|
|
87 if (id == NULL)
|
|
88 return -1;
|
|
89
|
|
90 if (id[0] != 'I' || id[1] != 'D' || id[2] != '3') {
|
|
91 /*
|
|
92 * ID3 tag was not detected.
|
|
93 */
|
|
94 id3->id3_seek(id3, -3);
|
|
95 return -1;
|
|
96 }
|
|
97 }
|
|
98
|
|
99 /*
|
|
100 * Read ID3 tag-header.
|
|
101 */
|
|
102 buf = id3->id3_read(id3, NULL, ID3_TAGHDR_SIZE);
|
|
103 if (buf == NULL)
|
|
104 return -1;
|
|
105
|
|
106 id3->id3_version = buf[0];
|
|
107 id3->id3_revision = buf[1];
|
|
108 id3->id3_flags = buf[2];
|
|
109 id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]);
|
|
110 id3->id3_newtag = 0;
|
|
111 id3->id3_pos = 0;
|
|
112
|
|
113 if (id3->id3_version < 2 || id3->id3_version > 4)
|
|
114 return -1;
|
|
115
|
|
116 /*
|
|
117 * Parse extended header.
|
|
118 */
|
|
119 if (id3->id3_flags & ID3_THFLAG_EXT) {
|
|
120 buf = id3->id3_read(id3, NULL, ID3_EXTHDR_SIZE);
|
|
121 if (buf == NULL)
|
|
122 return -1;
|
|
123 }
|
|
124
|
|
125 /*
|
|
126 * Parse frames.
|
|
127 */
|
|
128 while (id3->id3_pos < id3->id3_tagsize) {
|
|
129 if (id3_read_frame(id3) == -1)
|
|
130 return -1;
|
|
131 }
|
|
132
|
|
133 return 0;
|
|
134 }
|