#include #include #include enum { HeaderSize = 10, MagicSize = 3, RecHdrSize = 10, /* 6 for v2.2 */ IdSize = 4, /* 3 for v2.2 */ LangSize = 3, MaxFields = 4, MaxStrings = 4, /* arbitrary */ MinPadding = 128,, /* arbitrary */ PadChunkSize = 1024,, /* arbitrary */ }; typedef struct Header { char magic[MagicSize+1]; u8int version; u8int revision; u8int flags; u32int length; } Header; typedef struct Rechdr { char id[IdSize+1]; u32int length; u16int flags; } Rechdr; typedef struct Comment { char language[LangSize+1]; char *description; /* malloc'd */ char *comment; /* malloc'd with description */ } Comment; typedef struct Text { char **strings; /* nil terminated array of malloc'd utf strings */ } Text; typedef struct Record { Rechdr; int type; union { Comment c; Text t; }; } Record; typedef struct Rectype { char *id; int type; } Rectype; typedef void (*Recpacker)(uchar **, Record *); typedef struct Recfields { int type; Recpacker pack; int fields[MaxFields+1]; } Recfields; typedef struct Enc { char *str; int len; char sep[2]; } Enc; enum { Hunsync = 1<<7, Hext = 1<<6, Hexp = 1<<5, Hfoot = 1<<4, }; enum { Rcomment, Rtext, Runimplemented, }; enum { Fend, Fenc, Flang, Fstring, /* a single string */ Fstrings, /* a group of at least one separated strings */ }; enum { E8859, Eutf16le, Eutf16be, Eutf, Eend, }; Enc enctab[]; /* dat.c */ int rectype(char *); Recpacker recpacker(int); Recfields *recfields(int); int encnum(char *); /* pack.c */ void gstr(uchar **, char *s, int); void pstr(uchar **, char *s, int); u8int g8(uchar **); void p8(uchar **, u8int); u16int g16(uchar **); void p16(uchar **, u16int); u32int g32(uchar **); u32int gss32(uchar **); void pss32(uchar **, u32int); void gheader(uchar **, Header *); void pheader(uchar **, Header *); void grechdr(uchar **, Rechdr *, Header *); void prechdr(uchar **, Rechdr *); void precord(uchar **, Record *); int gcomment(uchar **, Comment *, int); void pcomment(uchar **, Record *); int gtext(uchar **, Text *, int); void ptext(uchar **, Record *r); /* util.c */ void *emalloc(ulong); void readrec(Biobuf *, void *, long, long, char *); /* http://web.archive.org/web/20130114052304/http://id3.org/id3v2.4.0-structure * http://web.archive.org/web/20130114052304/http://id3.org/id3v2.4.0-frames * http://web.archive.org/web/20120831234820/http://www.id3.org/id3v2-00 * http://gabriel.mp3-tech.org/mp3infotag.html */