184#define free_comment(mh) free_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments))
185#define free_text(mh) free_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts))
186#define free_extra(mh) free_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras))
187#define free_picture(mh) free_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures))
209#define add_comment(mh, l, d) add_id3_text(&((mh)->id3v2.comment_list), &((mh)->id3v2.comments), NULL, l, d)
210#define add_text(mh, id) add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, NULL, NULL)
211#define add_uslt(mh, l, d) add_id3_text(&((mh)->id3v2.text), &((mh)->id3v2.texts), id, l, d)
212#define add_extra(mh, d) add_id3_text(&((mh)->id3v2.extra), &((mh)->id3v2.extras), NULL, NULL, d)
213#define add_picture(mh, t, d) add_id3_picture(&((mh)->id3v2.picture), &((mh)->id3v2.pictures), t, d)
217 mdebug(
"add_id3_text id=%s lang=%s, desc=%s"
218 ,
id ? (
char[5]) {
id[0],
id[1],
id[2],
id[3], 0 } :
"(nil)"
239 mdebug(
"add_id3_text: entry %zu was no match",
i);
242 mdebug(
"add_id3_text: append to list of %zu", *
size);
251 return &((*list)[*
size-1]);
279 return &((*list)[*
size-1]);
303 debug(
"linking ID3v2");
305 for(
i=0;
i<
v2->texts; ++
i)
314 for(
i=0;
i<
v2->comments; ++
i)
317 if(
entry->description.fill == 0 ||
entry->description.p[0] == 0)
321 if(
v2->comment ==
NULL &&
v2->comments > 0)
322 v2->comment = &
v2->comment_list[
v2->comments-1].text;
340 debug(
"Empty id3 data!");
350 if(noquiet)
error(
"Cannot resize target string, out of memory?");
354 sb->fill = source_size;
363 error1(
"Unknown text encoding %u, I take no chances, sorry!",
encoding);
368 if(
sb->fill)
debug1(
"UTF-8 string (the first one): %s",
sb->p);
369 else if(noquiet)
error(
"unable to convert string to UTF-8 (out of memory, junk input?)!");
385 while(source_size > bwidth &&
source[0] == 0)
389 debug(
"skipped leading zero");
391 if(source_size % bwidth)
394 if(noquiet)
warning2(
"Weird tag size %d for encoding %u - I will probably trim too early or something but I think the MP3 is broken.", (
int)source_size,
encoding);
395 source_size -= source_size % bwidth;
403 unsigned char *
text = prev;
437 case 0:
return "Latin 1";
438 case 1:
return "UTF-16 BOM";
439 case 2:
return "UTF-16 BE";
440 case 3:
return "UTF-8";
441 default:
return "unknown!";
456 mdebug(
"process_text: (over)writing entry with ID %s",
t->id
457 ? (
char[5]) { t->id[0], t->id[1], t->id[2], t->id[3], 0 }
462 fprintf(
stderr,
"Note: ID3v2 %c%c%c%c text frame stored\n",
id[0],
id[1],
id[2],
id[3]);
469 unsigned char* workpoint =
NULL;
471 unsigned char image_type = 0;
473 unsigned char *image_data =
NULL;
476 debug(
"Empty id3 data!");
480 realdata++; realsize--;
484 error1(
"Unknown text encoding %u, I take no chances, sorry!",
encoding);
490 workpoint =
next_text(realdata, 0, realsize);
494 error(
"Unable to get mime type for picture; skipping picture.");
498 realsize -= workpoint - realdata;
499 realdata = workpoint;
501 image_type = realdata[0];
502 realdata++; realsize--;
508 error(
"Unable to get description for picture; skipping picture.");
513 realsize -= workpoint - realdata;
515 image_data = (
unsigned char*)
malloc(realsize);
516 if(!realsize || !image_data) {
518 error(
"No picture data or malloc failure; skipping picture.");
523 memcpy(image_data, workpoint, realsize);
530 error(
"Unable to attach new picture!");
540 i->type = image_type;
542 i->data = image_data;
546 fprintf(
stderr,
"Note: ID3v2 APIC picture frame of type: %d\n",
i->type);
557 unsigned char encoding = realdata[0];
559 unsigned char *
descr = realdata+4;
565 if(realsize < (
size_t)(
descr-realdata))
573 error1(
"Unknown text encoding %u, I take no chances, sorry!",
encoding);
584 error(
"No comment text / valid description?");
605 error(
"Unable to attach new comment!");
638 if((rva_mode > -1) && (fr->
rva.level[rva_mode] <= rva_level))
646 fr->
rva.peak[rva_mode] = 0;
647 fr->
rva.level[rva_mode] = rva_level;
660 unsigned char encoding = realdata[0];
661 unsigned char *
descr = realdata+1;
666 if((
int)realsize <
descr-realdata)
668 if(
NOQUIET)
error1(
"Invalid frame size of %lu (too small for anything).", (
unsigned long)realsize);
674 error1(
"Unknown text encoding %u, I take no chances, sorry!",
encoding);
681 if(
NOQUIET)
error(
"No extra frame text / valid description?");
734 if((rva_mode > -1) && (fr->
rva.level[rva_mode] <= rva_level))
750 fr->
rva.level[rva_mode] = rva_level;
767 "COM",
"TAL",
"TBP",
"TCM",
"TCO",
"TCR",
"TDA",
"TDY",
"TEN",
"TFT",
768 "TIM",
"TKE",
"TLA",
"TLE",
"TMT",
"TOA",
"TOF",
"TOL",
"TOR",
"TOT",
769 "TP1",
"TP2",
"TP3",
"TP4",
"TPA",
"TPB",
"TRC",
"TDA",
"TRK",
"TSI",
770 "TSS",
"TT1",
"TT2",
"TT3",
"TXT",
"TXX",
"TYE"
774 "COMM",
"TALB",
"TBPM",
"TCOM",
"TCON",
"TCOP",
"TDAT",
"TDLY",
"TENC",
"TFLT",
775 "TIME",
"TKEY",
"TLAN",
"TLEN",
"TMED",
"TOPE",
"TOFN",
"TOLY",
"TORY",
"TOAL",
776 "TPE1",
"TPE2",
"TPE3",
"TPE4",
"TPOS",
"TPUB",
"TSRC",
"TRDA",
"TRCK",
"TSIZ",
777 "TSSE",
"TIT1",
"TIT2",
"TIT3",
"TEXT",
"TXXX",
"TYER"
779 for(
i=0;
i<
sizeof(old)/
sizeof(
char*); ++
i)
795,
unsigned long first4bytes,
unsigned char buf[6],
unsigned long length )
799 unsigned long fullen = 10+
length;
809 error1(
"ID3v2: Arrg! Unable to allocate %lu bytes"
810 " for ID3v2 data - trying to skip instead.",
length+1);
811 if((ret2=fr->
rd->skip_bytes(fr,
length)) < 0)
818 fr->
id3v2_raw[0] = (first4bytes>>24) & 0xff;
819 fr->
id3v2_raw[1] = (first4bytes>>16) & 0xff;
820 fr->
id3v2_raw[2] = (first4bytes>>8) & 0xff;
847 #define UNSYNC_FLAG 128
848 #define EXTHEAD_FLAG 64
849 #define COMPRESS_FLAG 64
851 #define FOOTER_FLAG 16
852 #define EXT_UPDATE_FLAG 64
853 #define UNKNOWN_FLAGS 15
854 unsigned char buf[6];
856 unsigned char flags = 0;
860 unsigned int footlen = 0;
864 unsigned char major = first4bytes & 0xff;
867 if(
major == 0xff)
return 0;
868 if((ret2 = fr->
rd->read_frame_body(fr,
buf, 6)) < 0)
871 if(
buf[0] == 0xff)
return 0;
879 #define synchsafe_to_long(buf,res) \
881 (((buf)[0]|(buf)[1]|(buf)[2]|(buf)[3]) & 0x80) ? 0 : \
882 (res = (((unsigned long) (buf)[0]) << 21) \
883 | (((unsigned long) (buf)[1]) << 14) \
884 | (((unsigned long) (buf)[2]) << 7) \
885 | ((unsigned long) (buf)[3]) \
890 #define bytes_to_long(buf,res) \
893 (res = (((unsigned long) (buf)[0]) << 24) \
894 | (((unsigned long) (buf)[1]) << 16) \
895 | (((unsigned long) (buf)[2]) << 8) \
896 | ((unsigned long) (buf)[3]) \
897 ,1) : synchsafe_to_long(buf,res) \
900 #define threebytes_to_long(buf,res) \
902 res = (((unsigned long) (buf)[0]) << 16) \
903 | (((unsigned long) (buf)[1]) << 8) \
904 | ((unsigned long) (buf)[2]) \
913 if(
NOQUIET)
error4(
"Bad tag length (not synchsafe): 0x%02x%02x%02x%02x; You got a bad ID3 tag here.",
buf[2],
buf[3],
buf[4],
buf[5]);
925 fprintf(
stderr,
"Note: Skipping ID3v2 tag per user request.\n");
931 warning2(
"ID3v2: Won't parse the ID3v2 tag with major version"
932 " %u and flags 0x%xu - some extra code may be needed"
941 warning(
"ID3v2: ignoring compressed ID3v2.2 tag");
947 warning1(
"ID3v2: unrealistic small tag lengh %lu, skipping",
length);
963 fprintf(
stderr,
"Note: skipped tag clearing possibly existing ID3v2 data");
966 if(!storetag && (ret2=fr->
rd->skip_bytes(fr,
length+footlen))<0)
972 unsigned char* tagdata = fr->
id3v2_raw+10;
974 debug(
"ID3v2: analysing frames...");
977 unsigned char extflags = 0;
978 unsigned long tagpos = 0;
980 unsigned int head_part =
major > 2 ? 4 : 3;
981 unsigned int flag_part =
major > 2 ? 2 : 0;
984 unsigned int framebegin = head_part+head_part+flag_part;
985 debug1(
"ID3v2: have read at all %lu bytes for the tag now", (
unsigned long)
length+6);
988 debug(
"ID3v2: extended header");
993 error4(
"Bad (non-synchsafe/too large) tag offset from extended header:"
995 , tagdata[0], tagdata[1], tagdata[2], tagdata[3] );
996 }
else if(tagpos < 6)
1000 merror(
"Extended header too small (%lu).", tagpos);
1009 error(
"Too much extended v2.3 header.");
1027 fprintf(
stderr,
"Note: non-update tag replacing existing ID3v2 data\n");
1033 unsigned long framesize;
1034 unsigned long fflags;
1041 while(
length >= tagpos+framebegin)
1044 unsigned long pos = tagpos;
1049 for(
i=0;
i< head_part; ++
i)
1050 if( !( ((tagdata[tagpos+
i] > 47) && (tagdata[tagpos+
i] < 58))
1051 || ((tagdata[tagpos+
i] > 64) && (tagdata[tagpos+
i] < 91)) ) )
1053 debug5(
"ID3v2: real tag data apparently ended after %lu bytes with 0x%02x%02x%02x%02x", tagpos, tagdata[tagpos], tagdata[tagpos+1], tagdata[tagpos+2], tagdata[tagpos+3]);
1055 goto tagparse_cleanup;
1063 tagpos += head_part;
1070 if(
NOQUIET)
error1(
"ID3v2: non-syncsafe size of %s frame, skipping the remainder of tag",
id);
1074 tagpos += head_part;
1078 fflags = (((
unsigned long) tagdata[
pos]) << 8) | ((
unsigned long) tagdata[
pos+1]);
1084 if(
length - tagpos < framesize)
1086 if(
NOQUIET)
error(
"Whoa! ID3v2 frame claims to be larger than the whole rest of the tag.");
1089 tagpos += framesize;
1093 #define BAD_FFLAGS (unsigned long) 36784
1094 #define PRES_TAG_FFLAG 16384
1095 #define PRES_FILE_FFLAG 8192
1096 #define READ_ONLY_FFLAG 4096
1097 #define GROUP_FFLAG 64
1098 #define COMPR_FFLAG 8
1099 #define ENCR_FFLAG 4
1100 #define UNSYNC_FFLAG 2
1101 #define DATLEN_FFLAG 1
1107 if(
NOQUIET)
warning(
"ID3v2: skipping invalid/unsupported frame");
1114 if(
id[0] ==
'T' && tt !=
extra) tt =
text;
1119 unsigned long realsize = framesize;
1120 unsigned char* realdata = tagdata+
pos;
1121 unsigned char* unsyncbuffer =
NULL;
1124 unsigned long ipos = 0;
1125 unsigned long opos = 0;
1126 debug(
"Id3v2: going to de-unsync the frame data");
1130 realdata = unsyncbuffer =
malloc(framesize+1);
1131 if(realdata ==
NULL)
1133 if(
NOQUIET)
error(
"ID3v2: unable to allocate working buffer for de-unsync");
1137 realdata[0] = tagdata[
pos];
1139 for(ipos =
pos+1; ipos <
pos+framesize; ++ipos)
1141 if(!((tagdata[ipos] == 0) && (tagdata[ipos-1] == 0xff)))
1143 realdata[opos++] = tagdata[ipos];
1148 realdata[realsize] = 0;
1149 debug2(
"ID3v2: de-unsync made %lu out of %lu bytes", realsize, framesize);
1154 if(realsize)
switch(tt)
1170 || !
strncasecmp((
char*)realdata,
"audiophile", 10)
1173 if(fr->
rva.level[rva_mode] <=
rva2+1)
1176 debug2(
"got my pos: %zu - %zu", realsize,
pos);
1179 if(
pos > realsize || realsize-
pos < 3)
1182 error(
"bad RVA2 tag (truncated?)");
1184 else if(realdata[
pos] == 1)
1188 debug(
"ID3v2: it is for the master channel");
1194 ((
short)((
signed char*)realdata)[
pos]) * 256 + (
short)realdata[
pos+1] ) / 512;
1198 fr->
rva.peak[rva_mode] = 0;
1199 fr->
rva.level[rva_mode] =
rva2+1;
1213 default:
if(
NOQUIET)
error1(
"ID3v2: unknown frame type %i", tt);
1219 #undef PRES_TAG_FFLAG
1220 #undef PRES_FILE_FFLAG
1221 #undef READ_ONLY_FFLAG
1234 fprintf(
stderr,
"Note: faulty ID3v2 tag still clearing old data\n");
1256 #undef COMPRESS_FLAG
1259 #undef EXT_UPDATE_FLAG
1279 p = (
unsigned char*)
sb->p;
1281 if(
s[
i] < 0x80){ *
p =
s[
i]; ++
p; }
1284 *
p = 0xc0 | (
s[
i]>>6);
1285 *(
p+1) = 0x80 | (
s[
i] & 0x3f);
1307 int further_bom = 0;
1309 if(*
len < 2)
return 0;
1324 if(further_bom == 0)
return this_bom;
1325 else return further_bom;
1330#define FULLPOINT(f,s) ( (((f)&0x3ff)<<10) + ((s)&0x3ff) + 0x10000 )
1332#define UTF8LEN(x) ( (x)<0x80 ? 1 : ((x)<0x800 ? 2 : ((x)<0x10000 ? 3 : 4)))
1344 debug1(
"convert_utf16 with length %lu", (
unsigned long)
l);
1347 debug1(
"UTF16 endianness check: %i", bom_endian);
1349 if(bom_endian == -1)
1358 for(
i=0;
i <
n;
i+=2)
1360 unsigned long point = ((
unsigned long)
s[
i+high]<<8) +
s[
i+low];
1361 if((
point & 0xfc00) == 0xd800)
1363 unsigned short second = (
i+3 <
l) ? (
s[
i+2+high]<<8) +
s[
i+2+low] : 0;
1364 if((second & 0xfc00) == 0xdc00)
1372 if(noquiet)
error2(
"Invalid UTF16 surrogate pair at %li (0x%04lx).", (
unsigned long)
i,
point);
1384 p = (
unsigned char*)
sb->p;
1385 for(
i=0;
i <
n;
i+=2)
1387 unsigned long codepoint = ((
unsigned long)
s[
i+high]<<8) +
s[
i+low];
1388 if((codepoint & 0xfc00) == 0xd800)
1390 unsigned short second = (
s[
i+2+high]<<8) +
s[
i+2+low];
1391 codepoint =
FULLPOINT(codepoint,second);
1394 if(codepoint < 0x80) *
p++ = (
unsigned char) codepoint;
1395 else if(codepoint < 0x800)
1397 *
p++ = (
unsigned char) (0xc0 | (codepoint>>6));
1398 *
p++ = (
unsigned char) (0x80 | (codepoint & 0x3f));
1400 else if(codepoint < 0x10000)
1402 *
p++ = (
unsigned char) (0xe0 | (codepoint>>12));
1403 *
p++ = 0x80 | ((codepoint>>6) & 0x3f);
1404 *
p++ = 0x80 | (codepoint & 0x3f);
1406 else if (codepoint < 0x200000)
1408 *
p++ = (
unsigned char) (0xf0 | codepoint>>18);
1409 *
p++ = (
unsigned char) (0x80 | ((codepoint>>12) & 0x3f));
1410 *
p++ = (
unsigned char) (0x80 | ((codepoint>>6) & 0x3f));
1411 *
p++ = (
unsigned char) (0x80 | (codepoint & 0x3f));
1414 sb->p[
sb->size-1] = 0;
1415 sb->fill =
sb->size;
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
ACPI_SIZE strlen(const char *String)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei GLenum type
GLint GLint GLsizei width
GLenum GLuint GLenum GLsizei const GLchar * buf
GLuint GLsizei GLsizei * length
GLfloat GLfloat GLfloat v2
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
mpg123_string description
mpg123_text * comment_list
mpg123_string description
static mpg123_text * add_id3_text(mpg123_text **list, size_t *size, char id[4], char lang[3], mpg123_string *description)
static void process_text(mpg123_handle *fr, unsigned char *realdata, size_t realsize, char *id)
#define add_picture(mh, t, d)
static const text_converter text_converters[4]
static void convert_utf8(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
static void init_mpg123_text(mpg123_text *txt)
static void free_id3_picture(mpg123_picture **list, size_t *size)
static void convert_utf16bom(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
static void process_extra(mpg123_handle *fr, unsigned char *realdata, size_t realsize, int rva_level, char *id)
#define add_comment(mh, l, d)
static void init_mpg123_picture(mpg123_picture *pic)
#define synchsafe_to_long(buf, res)
#define threebytes_to_long(buf, res)
static void free_mpg123_picture(mpg123_picture *pic)
static void free_mpg123_text(mpg123_text *txt)
static void process_picture(mpg123_handle *fr, unsigned char *realdata, size_t realsize)
static void null_id3_links(mpg123_handle *fr)
static const char frame_type[KNOWN_FRAMES][5]
void(* text_converter)(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
static const unsigned int encoding_widths[4]
static void free_id3_text(mpg123_text **list, size_t *size)
static const char * enc_name(unsigned char enc)
#define bytes_to_long(buf, res)
static int promote_framename(mpg123_handle *fr, char *id)
#define add_uslt(mh, l, d)
static unsigned char * next_text(unsigned char *prev, unsigned char encoding, size_t limit)
static void process_comment(mpg123_handle *fr, enum frame_types tt, unsigned char *realdata, size_t realsize, int rva_level, char *id)
static int check_bom(const unsigned char **source, size_t *len)
int store_id3v2(mpg123_handle *fr, unsigned long first4bytes, unsigned char buf[6], unsigned long length)
static void convert_latin1(mpg123_string *sb, const unsigned char *source, size_t len, const int noquiet)
static void store_id3_text(mpg123_string *sb, unsigned char *source, size_t source_size, const int noquiet, const int notranslate)
static mpg123_picture * add_id3_picture(mpg123_picture **list, size_t *size, char type, mpg123_string *description)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define memcpy(s1, s2, n)
static float(__cdecl *square_half_float)(float x
#define warning2(s, a, b)
#define debug5(s, a, b, c, d, e)
#define error4(s, a, b, c, d)
struct mpg123_pars_struct p
unsigned char * id3v2_raw
struct mpg123_handle_struct::@3456 rva
static const WCHAR lang[]