1 /* 2 3 No-bullshit ID3v2 support 4 5 copyright (c) 2003-2006, 2015 squell <squell@alumina.nl> 6 7 use, modification, copying and distribution of this software is permitted 8 under the conditions described in the file 'COPYING'. 9 10 Usage (brief?): 11 12 void *ID3_readf(const char *fname, size_t *tagsize) 13 14 reads ID3v2 tag from fname to memory, storing the tag size (w/o padding) in 15 *tagsize (if != NULL). returns pointer on success, NULL on failure 16 stores zero in *tagsize on failure, or non-zero value if a malformed ID3v2 17 tag caused failure. 18 19 int ID3_writef(const char *fname, const void *buf, size_t reqsize); 20 21 writes in-memory tag pointed to by buf to fname. returns true / false on 22 success / failure. in-memory tag needs to be zero-terminated. 23 if reqsize != 0, tries to write id3v2 tag of that size. 24 if buf is NULL or points to an empty tag, deletes tag. 25 [doesnt check consistency of fname (use ID3_readf first)!] 26 27 void ID3_free(const void *buf) 28 29 frees pointer obtained by ID3_readf() 30 31 ID3VER ID3_start(ID3FRAME f, const void *buf) 32 33 initializes frame-iterator for stepping through tag pointed to by buf 34 35 int ID3_frame(ID3FRAME f) 36 37 steps through a tag using iterator f. returns 0 if no more frames. 38 39 void *ID3_put(void *dest, ID3VER version, const char ID[4], const void *src, size_t len) 40 41 writes a frame of type ID with contents *src (size len) to the in-memory tag 42 location pointed to by dest. returns the next memory location to write the 43 next frame to. first call with ID null to perform initialization. version 44 must be 2 or 3 (for ID3v2.2 or ID3v2.3). A mixed version tag will result in 45 undefined behaviour by ID3_writef. returns dest to indicate error (no-op). 46 47 void (*ID3_wfail)(const char *dest, const char *src) 48 49 this function pointer gets called if the mvfile() in ID3_writef fails. 50 by default, this points to an abort. 51 52 Example (reading a tag): 53 54 void *buf = ID3_readf("filename",0); 55 ID3FRAME f; 56 57 if(buf) { 58 ID3_start(frame, buf); 59 while( ID3_frame(f) ) 60 ... do stuff with f->XXXX ... 61 } 62 63 Example (writing a tag): 64 65 char buf[10000], *out; 66 int i; 67 68 out = ID3_put(buf, ID3_v2_3, 0, 0, 0); 69 for( .. frames to write .. ) 70 out = ID3_put(out, ID3_v2_3, ..id, ..&data, ..sizeof data); 71 72 ID3_writef("filename", buf, 0); 73 74 Notes: 75 76 ID3_writef() is very conservative by default: it will only rewrite the 77 MP3 file if it absolutely has to, i.e., if a tag has to be removed, 78 added, or is too small. It will not automatically rewrite MP3 files 79 to downsize ID3v2 tags (that would be silly). 80 81 */ 82 #ifndef __ZF_ID3V2_H 83 #define __ZF_ID3V2_H 84 85 #include <stddef.h> 86 87 #ifdef __cplusplus 88 extern "C" { /* whole heaps of errors otherwise */ 89 #endif 90 91 typedef struct _ID3FRAME { 92 const char *data; /* pointer to contents of frame */ 93 unsigned long size; /* length of frame contents */ 94 char ID[5]; /* ID of frame */ 95 unsigned tag_volit : 1; 96 unsigned file_volit : 1; 97 unsigned readonly : 1; 98 unsigned packed : 1; 99 unsigned encrypted : 1; 100 unsigned grouped : 1; 101 unsigned _rev : 2; 102 } ID3FRAME[1]; 103 104 typedef enum { 105 ID3_v2_2 = 2, 106 ID3_v2_3 = 3 107 } ID3VER; 108 109 extern void *ID3_readf(const char *fname, size_t *tagsize); 110 extern int ID3_writef(const char *fname, const void *buf, size_t reqsize); 111 extern void ID3_free(const void *buf); 112 113 extern ID3VER ID3_start(ID3FRAME f, const void *buf); 114 extern int ID3_frame(ID3FRAME f); 115 116 extern void *ID3_put(void *dest, ID3VER version, const char ID[4], const void *src, size_t len); 117 118 extern void (*ID3_wfail)(const char *srcname, const char *dstname); 119 120 #ifdef __cplusplus 121 } 122 #endif 123 #endif 124 125