1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
/*
* mplib - a library that enables you to edit ID3 tags
* Copyright (C) 2001,2002 Stefan Podkowinski
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1.
*
* This library 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
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __MPLIB_H
#define __MPLIB_H
/* __BEGIN_DECLS should be used at the beginning of your declarations,
so that C++ compilers don't mangle their names. Use __END_DECLS at
the end of C declarations. */
#undef __BEGIN_DECLS
#undef __END_DECLS
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS /* empty */
# define __END_DECLS /* empty */
#endif
/* __P is a macro used to wrap function prototypes, so that compilers
that don't understand ANSI C prototypes still work, and ANSI C
compilers can issue warnings about type mismatches. */
#undef __P
#if defined (__STDC__) || defined (_AIX) \
|| (defined (__mips) && defined (_SYSTYPE_SVR4)) \
|| defined(WIN32) || defined(__cplusplus)
# define __P(protos) protos
#else
# define __P(protos) ()
#endif
__BEGIN_DECLS
/*************************************/
/* Defines */
/*************************************/
#define MP_ARTIST 1
#define MP_TITLE 2
#define MP_ALBUM 3
#define MP_GENRE 4
#define MP_COMMENT 5
#define MP_YEAR 6
#define MP_TRACK 7
#define ISO_8859_1 0
#define UTF16 1
#define UTF16BE 2
#define UTF8 3
/*************************************/
/* errno values */
/*************************************/
#define MP_EERROR 1
#define MP_EFNF 2
#define MP_EFCOMPR 3
#define MP_EFENCR 4
/*define MP_EUNICODE 5*/
#define MP_EVERSION 6
/*************************************/
/* Structs and company */
/*************************************/
/* Header structure with 4 segments containing 32 bit header information */
typedef struct _mpeg_header
{
unsigned int syncword; /* Sync Word */
unsigned int version; /* Version number */
unsigned int layer; /* Layer number */
unsigned int protbit; /* Protection Bit */
unsigned int bitrate; /* kbit/sec */
unsigned int samplingfreq; /* hz */
unsigned int padbit; /* Padding bit */
unsigned int privbit; /* Private Bit */
unsigned int mode; /* Stereo, Joint-Stereo, Dual-Channel, Mono */
unsigned int mode_ext; /* Mode extension */
unsigned int copyright; /* Copyright yes/no */
unsigned int originalhome; /* Original datastream yes/no */
unsigned int emphasis; /* Emphasis bits */
} mpeg_header;
/* Generic tag structure */
typedef struct _id3_tag
{
int version; /* tags version, either 1 or 2 or -1 if not supported */
void *tag; /* pointer to specific struct */
} id3_tag;
/* list of tags found in file */
typedef struct _id3_tag_list
{
id3_tag *tag;
struct _id3_tag_list *next;
struct _id3_tag_list *first;
} id3_tag_list;
/*
* The following structures are ment as low-level data holders. I strongly
* suggest you to use the appropriate generic functions below to access them.
*/
/* V 1 */
/* ID3v1 tag structure */
typedef struct _id3v1_tag
{
char *title;
char *artist;
char *album;
char *year;
char *comment;
unsigned char track; /* track binary encoded */
unsigned char genre; /* index on genre list - 0xFF for null */
} id3v1_tag;
/* V 2 */
/* ID3v2 Frame structure */
typedef struct _id3v2_frame
{
char* frame_id; /* The frame id e.g. TALB */
unsigned char status_flag;
unsigned char format_flag;
char *data;
unsigned int data_size; /* frame size excluding header, incl. enc.,lang.,etc.
(total frame size - 10) */
} id3v2_frame;
/* single linked list referencing a number of frames */
typedef struct _id3v2_frame_list
{
struct _id3v2_frame *data;
struct _id3v2_frame_list *next;
struct _id3v2_frame_list *start;
} id3v2_frame_list;
/* ID3v2 Extended Header structure */
typedef struct _id3v2_extended_header
{
unsigned long size;
char *flag_bytes;
unsigned int no_flag_bytes;
unsigned int is_update;
unsigned int crc_data_present;
unsigned char crc_data_length;
unsigned char* crc_data;
unsigned int restrictions;
unsigned char restrictions_data_length;
unsigned char* restrictions_data;
} id3v2_extended_header;
/* ID3v2 Header structure */
typedef struct _id3v2_header
{
/* Version 2.minor.revision */
unsigned int version_minor;
unsigned int version_revision;
char flags; /* Flags - should only be set by mplib and does only contain
the following infos */
unsigned int unsyncronization;
unsigned int has_extended_header;
unsigned int is_experimental;
unsigned int has_footer;
unsigned long total_tag_size; /* is size of all tag elements including
header and footer (each 10 bytes) */
id3v2_extended_header *extended_header; /* Extended header */
} id3v2_header;
/* ID3v2 tag structure */
typedef struct _id3v2_tag
{
id3v2_header *header;
id3v2_frame_list *frame_list;
} id3v2_tag;
/* A fields content unparsed */
typedef struct _id3_content
{
unsigned int compressed;
unsigned int encrypted;
char *data;
unsigned int length;
} id3_content;
typedef enum _id3_encoding
{
iso_8859_1 = ISO_8859_1,
utf16 = UTF16,
utf16be = UTF16BE,
utf8 = UTF8
} id3_encoding;
typedef struct _id3_text_content
{
id3_encoding encoding;
char *text; /* Null terminated text */
} id3_text_content;
typedef struct _id3_comment_content
{
id3_encoding encoding;
char *language; /* ISO Language code */
char *short_descr; /* Null term. content short description */
char *text; /* Null terminated text */
} id3_comment_content;
/***************************************/
/* Functions */
/***************************************/
/* Allocates a MPEG header structure from a file
* Arg 1 - The filename
* Returns - A pointer to a new initialized header structure - NULL on IO Error
*/
extern mpeg_header *mp_get_mpeg_header_from_file __P((const char*));
/* Gets the header structure from a file descriptor
* Arg 1 - The file descriptor
* Returns - A pointer to a new initialized header structure - NULL on IO Error
*/
extern mpeg_header *mp_get_mpeg_header_from_fd __P((int));
/* Frees a mpeg header structure
* Arg 1 - The allocated mpeg header
*/
#define mp_free_mpeg_header(str) xfree(str)
/* Allocates a label with the appropriate header field value as a string */
extern char *mp_get_str_version __P((const mpeg_header*));
extern char *mp_get_str_layer __P((const mpeg_header*));
extern char *mp_get_str_bitrate __P((const mpeg_header*));
extern char *mp_get_str_samplingfreq __P((const mpeg_header*));
extern char *mp_get_str_mode __P((const mpeg_header*));
/* Allocates and fills a list of tags found in the given file. This list
* will contain at least one and at most two tags or is NULL if no tags
* have been found.
* Arg 1 - The files name/file descriptor to search for tags
* Returns - A pointer to a initialized list struct or null if no tags have
* been found
*/
extern id3_tag_list* mp_get_tag_list_from_file __P((const char*));
extern id3_tag_list* mp_get_tag_list_from_fd __P((int));
/* Frees a tag list beginning with the given element XXX */
extern void mp_free_list __P((id3_tag_list*));
/* Gets the first content found of a specified field in the given tag and
* allocates a struct.
* Arg 1 - The tag
* Arg 2 - The fields identifier
*
* Returns The new allocated content for the specified field or NULL
* On NULL: errno set to the following values
* MP_EERROR - General failure: may occure on wrong usage, but should never happen
* MP_EFNF - Field does not exists in tag /invalid identifier
* MP_EVERSION - Tag has a version set that is not supported by the library
*/
extern id3_content* mp_get_content __P((const id3_tag*, int));
/* It's posible that a tag has multiple ocurances of a field.
* Use this function to get a specified field by position. The first
* ocurance of the field in the tag is 0.
* e.g.: To get the third comment in an id3v2 tag use
* mp_get_content_at_pos(tag, MP_COMMENT, 2);
* Arg 1 - The tag
* Arg 2 - The fields identifier
* Arg 3 - The content position in the tag
* Returns - see mp_get_content
*/
extern id3_content* mp_get_content_at_pos __P((const id3_tag*, int, int));
/* Gets a custom fields content and allocates a struct. This function can
* only be applied to ID3v2 tags. It will lookup a by the given identifier
* and return its content.
* Arg 1 - The tag
* Arg 2 - The field names identifier e.g. ENCR
* Returns - see mp_get_content
*/
extern id3_content* mp_get_content_custom __P((const id3_tag*, const char*));
/* See mp_get_content_at_pos() and mp_get_content_custom()
* Arg 1 - The tag
* Arg 2 - The field names identifier e.g. ENCR
* Arg 3 - The content position in the tag
* Returns - see mp_get_content
*/
extern id3_content* mp_get_content_custom_at_pos __P((const id3_tag*, const char*, int));
/* Frees a content struct */
extern void mp_free_content __P((id3_content*));
extern void mp_free_text_content __P((id3_text_content*));
extern void mp_free_comment_content __P((id3_comment_content*));
/* Copys the value of a specified field into the given tag. The content
* argument may be freed after using this function. The way a content
* is represented in a tag depends from the tags version and kind of field.
* I.e. it may be nessecary to represent a track number as a binary value in a v1
* tag or to embeded it into a frame for a v2 tag. The caller just needs to
* give the correct identifier with the value as a id3_content and to take
* care of freeing the id3_content value afterwards.
* Arg 1 - The tag to edit
* Arg 2 - The fields identifier
* Arg 3 - The fields new content
* Returns - 0 success or one of the following errors
* MP_EERROR - General failure: may occure on wrong usage, but should never happen
* MP_EFNF - Field does not exists in tag /invalid identifier
* MP_EVERSION - Function isn't able to handle a tag of this version
*/
extern int mp_set_content __P((id3_tag*, int, id3_content*));
extern int mp_set_content_at_pos __P((id3_tag*, int, id3_content*, int));
/* Sets up a new custom field with the given value
* Arg 1 - The tag to edit
* Arg 2 - The new fields name - A four chars upper case identifier e.g. ENCR
* Arg 3 - The fields new content
* Returns - See mp_set_content
*/
extern int mp_set_custom_content __P((id3_tag*, char*, id3_content*));
extern int mp_set_custom_content_at_pos __P((id3_tag*, char*, id3_content*, int));
/* Writes the tag to the specified file
* Arg 1 - The tag list to be added to file - may be NULL for deleting all tags
* Arg 2 - The files name/file descriptor
* Returns - 0 on success or one of the following errors
* MP_EERROR - General failure: may occure on wrong usage, but should never happen
* MP_EVERSION - Function isn't able to handle a tag of this version
*/
extern int mp_write_to_file __P((const id3_tag_list*, const char*));
extern int mp_write_to_fd __P((const id3_tag_list*, int));
/* Deletes all tags in file
* Arg 1 - The filename of fd
* Return - 0 on success
*/
extern int mp_del_tags_from_file __P((const char*));
extern int mp_del_tags_from_fd __P((int));
/* Deletes all tags in file with the specified version
* Arg 1 - The filename or fd
* Arg 2 - The version
*/
extern int mp_del_tags_by_ver_from_file __P((const char*, int));
extern int mp_del_tags_by_ver_from_fd __P((int, int));
/* Converts a tag to id3v1 or id3v2 tag format
* Arg 1 - The tag to be converted
* Returns - 0 on success or one of the following errors
* MP_EVERSION - Function isn't able to handle a tag of this version
*/
extern int mp_convert_to_v1 __P((id3_tag*));
extern int mp_convert_to_v2 __P((id3_tag*));
/* Checks wether the given value would be a valid v1 field
* Arg 1 - The field
* Arg 2 - The value
* Returns - 0 if test failed
*/
extern int mp_is_valid_v1_value __P((int, char*));
/* Parses a content field
* Arg 1 - the content to parse
* Returns - A pointer to a new initialized structure suitable for the content
* or NULL
* On NULL: errno set to the following values
* MP_EERROR - General failure: may occure on wrong usage, but should never happen
* MP_EFENCR - The value for this field has been encrypted and can thus not be retrieved
* MP_EFCOMPR - The value for this field has been compressed and can thus not be retrieved
*/
extern id3_text_content *mp_parse_artist __P((const id3_content*));
extern id3_text_content *mp_parse_title __P((const id3_content*));
extern id3_text_content *mp_parse_album __P((const id3_content*));
extern id3_text_content *mp_parse_year __P((const id3_content*));
extern id3_text_content *mp_parse_genre __P((const id3_content*));
extern id3_text_content *mp_parse_track __P((const id3_content*));
extern id3_text_content *mp_parse_text __P((const id3_content*));
extern id3_comment_content *mp_parse_comment __P((const id3_content*));
/* Assembles content from a comont text content
* Arg 1 - the text
* Arg 2 - the texts encoding (NULL)
* Returns - A pointer to a new initialized content structure
*/
extern id3_content *mp_assemble_text_content __P((const char*, id3_encoding));
/* Assembles content from a comment
* Arg 1 - the text
* Arg 2 - a short describtion to the text (NULL)
* Arg 3 - the texts encoding
* Arg 4 - the comments language (NULL)
* Returns - A pointer to a new initialized content structure
*/
extern id3_content *mp_assemble_comment_content __P((const char*, const char*, id3_encoding, const char*));
/* Gets a new allocated tag */
extern id3_tag* mp_alloc_tag __P((void));
extern id3_tag* mp_alloc_tag_with_version __P((int));
/* Frees tag struct */
extern void mp_free_tag __P((id3_tag *));
__END_DECLS
#endif /* __MPLIB_H */
|