1 /*
2  * libid3tag - ID3 tag manipulation library
3  * Copyright (C) 2000-2004 Underbit Technologies, Inc.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * If you would like to negotiate alternate licensing terms, you may do
20  * so by contacting: Underbit Technologies, Inc. <info@underbit.com>
21  *
22  * $Id: id3tag.h,v 1.17 2004/01/23 23:22:46 rob Exp $
23  */
24 
25 # ifndef LIBID3TAG_ID3TAG_H
26 # define LIBID3TAG_ID3TAG_H
27 
28 # ifdef __cplusplus
29 extern "C" {
30 # endif
31 
32 # define ID3_TAG_VERSION		0x0400
33 # define ID3_TAG_VERSION_MAJOR(x)	(((x) >> 8) & 0xff)
34 # define ID3_TAG_VERSION_MINOR(x)	(((x) >> 0) & 0xff)
35 
36 typedef unsigned char id3_byte_t;
37 typedef unsigned long id3_length_t;
38 
39 typedef unsigned long id3_ucs4_t;
40 
41 typedef unsigned char id3_latin1_t;
42 typedef unsigned short id3_utf16_t;
43 typedef signed char id3_utf8_t;
44 
45 struct id3_tag {
46   unsigned int refcount;
47   unsigned int version;
48   int flags;
49   int extendedflags;
50   int restrictions;
51   int options;
52   unsigned int nframes;
53   struct id3_frame **frames;
54   id3_length_t paddedsize;
55 };
56 
57 # define ID3_TAG_QUERYSIZE	10
58 
59 /* ID3v1 field frames */
60 
61 # define ID3_FRAME_TITLE	"TIT2"
62 # define ID3_FRAME_ARTIST	"TPE1"
63 # define ID3_FRAME_ALBUM	"TALB"
64 # define ID3_FRAME_TRACK	"TRCK"
65 # define ID3_FRAME_YEAR		"TDRC"
66 # define ID3_FRAME_GENRE	"TCON"
67 # define ID3_FRAME_COMMENT	"COMM"
68 
69 /* special frames */
70 
71 # define ID3_FRAME_OBSOLETE	"ZOBS"	/* with apologies to the French */
72 
73 /* tag flags */
74 
75 enum {
76   ID3_TAG_FLAG_UNSYNCHRONISATION     = 0x80,
77   ID3_TAG_FLAG_EXTENDEDHEADER        = 0x40,
78   ID3_TAG_FLAG_EXPERIMENTALINDICATOR = 0x20,
79   ID3_TAG_FLAG_FOOTERPRESENT         = 0x10,
80 
81   ID3_TAG_FLAG_KNOWNFLAGS            = 0xf0
82 };
83 
84 /* tag extended flags */
85 
86 enum {
87   ID3_TAG_EXTENDEDFLAG_TAGISANUPDATE   = 0x40,
88   ID3_TAG_EXTENDEDFLAG_CRCDATAPRESENT  = 0x20,
89   ID3_TAG_EXTENDEDFLAG_TAGRESTRICTIONS = 0x10,
90 
91   ID3_TAG_EXTENDEDFLAG_KNOWNFLAGS      = 0x70
92 };
93 
94 /* tag restrictions */
95 
96 enum {
97   ID3_TAG_RESTRICTION_TAGSIZE_MASK             = 0xc0,
98   ID3_TAG_RESTRICTION_TAGSIZE_128_FRAMES_1_MB  = 0x00,
99   ID3_TAG_RESTRICTION_TAGSIZE_64_FRAMES_128_KB = 0x40,
100   ID3_TAG_RESTRICTION_TAGSIZE_32_FRAMES_40_KB  = 0x80,
101   ID3_TAG_RESTRICTION_TAGSIZE_32_FRAMES_4_KB   = 0xc0
102 };
103 
104 enum {
105   ID3_TAG_RESTRICTION_TEXTENCODING_MASK        = 0x20,
106   ID3_TAG_RESTRICTION_TEXTENCODING_NONE        = 0x00,
107   ID3_TAG_RESTRICTION_TEXTENCODING_LATIN1_UTF8 = 0x20
108 };
109 
110 enum {
111   ID3_TAG_RESTRICTION_TEXTSIZE_MASK            = 0x18,
112   ID3_TAG_RESTRICTION_TEXTSIZE_NONE            = 0x00,
113   ID3_TAG_RESTRICTION_TEXTSIZE_1024_CHARS      = 0x08,
114   ID3_TAG_RESTRICTION_TEXTSIZE_128_CHARS       = 0x10,
115   ID3_TAG_RESTRICTION_TEXTSIZE_30_CHARS        = 0x18
116 };
117 
118 enum {
119   ID3_TAG_RESTRICTION_IMAGEENCODING_MASK       = 0x04,
120   ID3_TAG_RESTRICTION_IMAGEENCODING_NONE       = 0x00,
121   ID3_TAG_RESTRICTION_IMAGEENCODING_PNG_JPEG   = 0x04
122 };
123 
124 enum {
125   ID3_TAG_RESTRICTION_IMAGESIZE_MASK           = 0x03,
126   ID3_TAG_RESTRICTION_IMAGESIZE_NONE           = 0x00,
127   ID3_TAG_RESTRICTION_IMAGESIZE_256_256        = 0x01,
128   ID3_TAG_RESTRICTION_IMAGESIZE_64_64          = 0x02,
129   ID3_TAG_RESTRICTION_IMAGESIZE_64_64_EXACT    = 0x03
130 };
131 
132 /* library options */
133 
134 enum {
135   ID3_TAG_OPTION_UNSYNCHRONISATION = 0x0001,	/* use unsynchronisation */
136   ID3_TAG_OPTION_COMPRESSION       = 0x0002,	/* use compression */
137   ID3_TAG_OPTION_CRC               = 0x0004,	/* use CRC */
138 
139   ID3_TAG_OPTION_APPENDEDTAG       = 0x0010,	/* tag will be appended */
140   ID3_TAG_OPTION_FILEALTERED       = 0x0020,	/* audio data was altered */
141 
142   ID3_TAG_OPTION_ID3V1             = 0x0100	/* render ID3v1/ID3v1.1 tag */
143 };
144 
145 struct id3_frame {
146   char id[5];
147   char const *description;
148   unsigned int refcount;
149   int flags;
150   int group_id;
151   int encryption_method;
152   id3_byte_t *encoded;
153   id3_length_t encoded_length;
154   id3_length_t decoded_length;
155   unsigned int nfields;
156   union id3_field *fields;
157 };
158 
159 enum {
160   /* frame status flags */
161   ID3_FRAME_FLAG_TAGALTERPRESERVATION	= 0x4000,
162   ID3_FRAME_FLAG_FILEALTERPRESERVATION	= 0x2000,
163   ID3_FRAME_FLAG_READONLY		= 0x1000,
164 
165   ID3_FRAME_FLAG_STATUSFLAGS            = 0xff00,
166 
167   /* frame format flags */
168   ID3_FRAME_FLAG_GROUPINGIDENTITY	= 0x0040,
169   ID3_FRAME_FLAG_COMPRESSION		= 0x0008,
170   ID3_FRAME_FLAG_ENCRYPTION		= 0x0004,
171   ID3_FRAME_FLAG_UNSYNCHRONISATION	= 0x0002,
172   ID3_FRAME_FLAG_DATALENGTHINDICATOR	= 0x0001,
173 
174   ID3_FRAME_FLAG_FORMATFLAGS            = 0x00ff,
175 
176   ID3_FRAME_FLAG_KNOWNFLAGS             = 0x704f
177 };
178 
179 enum id3_field_type {
180   ID3_FIELD_TYPE_TEXTENCODING,
181   ID3_FIELD_TYPE_LATIN1,
182   ID3_FIELD_TYPE_LATIN1FULL,
183   ID3_FIELD_TYPE_LATIN1LIST,
184   ID3_FIELD_TYPE_STRING,
185   ID3_FIELD_TYPE_STRINGFULL,
186   ID3_FIELD_TYPE_STRINGLIST,
187   ID3_FIELD_TYPE_LANGUAGE,
188   ID3_FIELD_TYPE_FRAMEID,
189   ID3_FIELD_TYPE_DATE,
190   ID3_FIELD_TYPE_INT8,
191   ID3_FIELD_TYPE_INT16,
192   ID3_FIELD_TYPE_INT24,
193   ID3_FIELD_TYPE_INT32,
194   ID3_FIELD_TYPE_INT32PLUS,
195   ID3_FIELD_TYPE_BINARYDATA
196 };
197 
198 enum id3_field_textencoding {
199   ID3_FIELD_TEXTENCODING_ISO_8859_1 = 0x00,
200   ID3_FIELD_TEXTENCODING_UTF_16     = 0x01,
201   ID3_FIELD_TEXTENCODING_UTF_16BE   = 0x02,
202   ID3_FIELD_TEXTENCODING_UTF_8      = 0x03
203 };
204 
205 union id3_field {
206   enum id3_field_type type;
207   struct {
208     enum id3_field_type type;
209     signed long value;
210   } number;
211   struct {
212     enum id3_field_type type;
213     id3_latin1_t *ptr;
214   } latin1;
215   struct {
216     enum id3_field_type type;
217     unsigned int nstrings;
218     id3_latin1_t **strings;
219   } latin1list;
220   struct {
221     enum id3_field_type type;
222     id3_ucs4_t *ptr;
223   } string;
224   struct {
225     enum id3_field_type type;
226     unsigned int nstrings;
227     id3_ucs4_t **strings;
228   } stringlist;
229   struct {
230     enum id3_field_type type;
231     char value[9];
232   } immediate;
233   struct {
234     enum id3_field_type type;
235     id3_byte_t *data;
236     id3_length_t length;
237   } binary;
238 };
239 
240 /* file interface */
241 
242 enum id3_file_mode {
243   ID3_FILE_MODE_READONLY = 0,
244   ID3_FILE_MODE_READWRITE
245 };
246 
247 struct id3_file *id3_file_open(char const *, enum id3_file_mode);
248 struct id3_file *id3_file_fdopen(int, enum id3_file_mode);
249 int id3_file_close(struct id3_file *);
250 
251 struct id3_tag *id3_file_tag(struct id3_file const *);
252 
253 int id3_file_update(struct id3_file *);
254 
255 /* tag interface */
256 
257 struct id3_tag *id3_tag_new(void);
258 void id3_tag_delete(struct id3_tag *);
259 
260 unsigned int id3_tag_version(struct id3_tag const *);
261 
262 int id3_tag_options(struct id3_tag *, int, int);
263 void id3_tag_setlength(struct id3_tag *, id3_length_t);
264 
265 void id3_tag_clearframes(struct id3_tag *);
266 
267 int id3_tag_attachframe(struct id3_tag *, struct id3_frame *);
268 int id3_tag_detachframe(struct id3_tag *, struct id3_frame *);
269 
270 struct id3_frame *id3_tag_findframe(struct id3_tag const *,
271 				    char const *, unsigned int);
272 
273 signed long id3_tag_query(id3_byte_t const *, id3_length_t);
274 
275 struct id3_tag *id3_tag_parse(id3_byte_t const *, id3_length_t);
276 id3_length_t id3_tag_render(struct id3_tag const *, id3_byte_t *);
277 
278 /* frame interface */
279 
280 struct id3_frame *id3_frame_new(char const *);
281 void id3_frame_delete(struct id3_frame *);
282 
283 union id3_field *id3_frame_field(struct id3_frame const *, unsigned int);
284 
285 /* field interface */
286 
287 enum id3_field_type id3_field_type(union id3_field const *);
288 
289 int id3_field_setint(union id3_field *, signed long);
290 int id3_field_settextencoding(union id3_field *, enum id3_field_textencoding);
291 int id3_field_setstrings(union id3_field *, unsigned int, id3_ucs4_t **);
292 int id3_field_addstring(union id3_field *, id3_ucs4_t const *);
293 int id3_field_setlanguage(union id3_field *, char const *);
294 int id3_field_setlatin1(union id3_field *, id3_latin1_t const *);
295 int id3_field_setfulllatin1(union id3_field *, id3_latin1_t const *);
296 int id3_field_setstring(union id3_field *, id3_ucs4_t const *);
297 int id3_field_setfullstring(union id3_field *, id3_ucs4_t const *);
298 int id3_field_setframeid(union id3_field *, char const *);
299 int id3_field_setbinarydata(union id3_field *,
300 			    id3_byte_t const *, id3_length_t);
301 
302 signed long id3_field_getint(union id3_field const *);
303 enum id3_field_textencoding id3_field_gettextencoding(union id3_field const *);
304 id3_latin1_t const *id3_field_getlatin1(union id3_field const *);
305 id3_latin1_t const *id3_field_getfulllatin1(union id3_field const *);
306 id3_ucs4_t const *id3_field_getstring(union id3_field const *);
307 id3_ucs4_t const *id3_field_getfullstring(union id3_field const *);
308 unsigned int id3_field_getnstrings(union id3_field const *);
309 id3_ucs4_t const *id3_field_getstrings(union id3_field const *,
310 				       unsigned int);
311 char const *id3_field_getframeid(union id3_field const *);
312 id3_byte_t const *id3_field_getbinarydata(union id3_field const *,
313 					  id3_length_t *);
314 
315 /* genre interface */
316 
317 id3_ucs4_t const *id3_genre_index(unsigned int);
318 id3_ucs4_t const *id3_genre_name(id3_ucs4_t const *);
319 int id3_genre_number(id3_ucs4_t const *);
320 
321 /* ucs4 interface */
322 
323 id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *);
324 id3_utf16_t *id3_ucs4_utf16duplicate(id3_ucs4_t const *);
325 id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *);
326 
327 void id3_ucs4_putnumber(id3_ucs4_t *, unsigned long);
328 unsigned long id3_ucs4_getnumber(id3_ucs4_t const *);
329 
330 /* latin1/utf16/utf8 interfaces */
331 
332 id3_ucs4_t *id3_latin1_ucs4duplicate(id3_latin1_t const *);
333 id3_ucs4_t *id3_utf16_ucs4duplicate(id3_utf16_t const *);
334 id3_ucs4_t *id3_utf8_ucs4duplicate(id3_utf8_t const *);
335 
336 /* version interface */
337 
338 # define ID3_VERSION_MAJOR	0
339 # define ID3_VERSION_MINOR	15
340 # define ID3_VERSION_PATCH	1
341 # define ID3_VERSION_EXTRA	" (beta)"
342 
343 # define ID3_VERSION_STRINGIZE(str)	#str
344 # define ID3_VERSION_STRING(num)	ID3_VERSION_STRINGIZE(num)
345 
346 # define ID3_VERSION	ID3_VERSION_STRING(ID3_VERSION_MAJOR) "."  \
347 			ID3_VERSION_STRING(ID3_VERSION_MINOR) "."  \
348 			ID3_VERSION_STRING(ID3_VERSION_PATCH)  \
349 			ID3_VERSION_EXTRA
350 
351 # define ID3_PUBLISHYEAR	"2000-2004"
352 # define ID3_AUTHOR		"Underbit Technologies, Inc."
353 # define ID3_EMAIL		"info@underbit.com"
354 
355 extern char const id3_version[];
356 extern char const id3_copyright[];
357 extern char const id3_author[];
358 extern char const id3_build[];
359 
360 # ifdef __cplusplus
361 }
362 # endif
363 
364 # endif
365