846{
847 #define UNSYNC_FLAG 128
848 #define EXTHEAD_FLAG 64
849 #define COMPRESS_FLAG 64
850 #define EXP_FLAG 32
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;
859 int storetag = 0;
860 unsigned int footlen = 0;
861#ifndef NO_ID3V2
862 int skiptag = 0;
863#endif
864 unsigned char major = first4bytes & 0xff;
866
867 if(
major == 0xff)
return 0;
868 if((ret2 = fr->
rd->read_frame_body(fr,
buf, 6)) < 0)
869 return ret2;
870
871 if(
buf[0] == 0xff)
return 0;
872
874 storetag = 1;
875
878
879 #define synchsafe_to_long(buf,res) \
880 ( \
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]) \
886 ,1) \
887 )
888
889
890 #define bytes_to_long(buf,res) \
891 ( \
892 major == 3 ? \
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) \
898 )
899
900 #define threebytes_to_long(buf,res) \
901 ( \
902 res = (((unsigned long) (buf)[0]) << 16) \
903 | (((unsigned long) (buf)[1]) << 8) \
904 | ((unsigned long) (buf)[2]) \
905 )
906
907
908
909
910
912 {
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]);
914 return 0;
915 }
917 footlen = 10;
919#ifndef NO_ID3V2
921
923 {
925 fprintf(
stderr,
"Note: Skipping ID3v2 tag per user request.\n");
926 skiptag = 1;
927 }
929 {
931 warning2(
"ID3v2: Won't parse the ID3v2 tag with major version"
932 " %u and flags 0x%xu - some extra code may be needed"
934 skiptag = 1;
935 }
936
937
939 {
941 warning(
"ID3v2: ignoring compressed ID3v2.2 tag");
942 skiptag = 1;
943 }
945 {
947 warning1(
"ID3v2: unrealistic small tag lengh %lu, skipping",
length);
948 skiptag = 1;
949 }
950 if(!skiptag)
951 storetag = 1;
952#endif
953 if(storetag)
954 {
955
957 return ret2;
958 }
959#ifndef NO_ID3V2
960 if(skiptag)
961 {
963 fprintf(
stderr,
"Note: skipped tag clearing possibly existing ID3v2 data");
965#endif
966 if(!storetag && (ret2=fr->
rd->skip_bytes(fr,
length+footlen))<0)
968#ifndef NO_ID3V2
969 }
970 else
971 {
972 unsigned char* tagdata = fr->
id3v2_raw+10;
973
974 debug(
"ID3v2: analysing frames...");
976 {
977 unsigned char extflags = 0;
978 unsigned long tagpos = 0;
979
980 unsigned int head_part =
major > 2 ? 4 : 3;
981 unsigned int flag_part =
major > 2 ? 2 : 0;
982
983
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);
987 {
988 debug(
"ID3v2: extended header");
990 {
993 error4(
"Bad (non-synchsafe/too large) tag offset from extended header:"
994 "0x%02x%02x%02x%02x"
995 , tagdata[0], tagdata[1], tagdata[2], tagdata[3] );
996 } else if(tagpos < 6)
997 {
1000 merror(
"Extended header too small (%lu).", tagpos);
1001 }
1003 {
1004 tagpos += 4;
1006 {
1009 error(
"Too much extended v2.3 header.");
1010 }
1012 {
1013
1014
1015
1017 {
1021 }
1022 }
1023 }
1025 {
1027 fprintf(
stderr,
"Note: non-update tag replacing existing ID3v2 data\n");
1029 }
1031 {
1032 char id[5];
1033 unsigned long framesize;
1034 unsigned long fflags;
1035 id[4] = 0;
1037
1038
1039
1040
1041 while(
length >= tagpos+framebegin)
1042 {
1044 unsigned long pos = tagpos;
1045
1046
1048
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)) ) )
1052 {
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]);
1054
1055 goto tagparse_cleanup;
1056 }
1058 {
1059
1061 id[head_part] = 0;
1063 tagpos += head_part;
1064
1066 else
1068 {
1069
1070 if(
NOQUIET)
error1(
"ID3v2: non-syncsafe size of %s frame, skipping the remainder of tag",
id);
1071 break;
1072 }
1074 tagpos += head_part;
1077 {
1078 fflags = (((
unsigned long) tagdata[
pos]) << 8) | ((
unsigned long) tagdata[
pos+1]);
1080 tagpos += 2;
1081 }
1082 else fflags = 0;
1083
1084 if(
length - tagpos < framesize)
1085 {
1086 if(
NOQUIET)
error(
"Whoa! ID3v2 frame claims to be larger than the whole rest of the tag.");
1087 break;
1088 }
1089 tagpos += framesize;
1090
1091
1092
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
1103
1104
1106 {
1107 if(
NOQUIET)
warning(
"ID3v2: skipping invalid/unsupported frame");
1108 continue;
1109 }
1110
1113
1114 if(
id[0] ==
'T' && tt !=
extra) tt =
text;
1115
1117 {
1118 int rva_mode = -1;
1119 unsigned long realsize = framesize;
1120 unsigned char* realdata = tagdata+
pos;
1121 unsigned char* unsyncbuffer =
NULL;
1123 {
1124 unsigned long ipos = 0;
1125 unsigned long opos = 0;
1126 debug(
"Id3v2: going to de-unsync the frame data");
1127
1128
1129
1130 realdata = unsyncbuffer =
malloc(framesize+1);
1131 if(realdata ==
NULL)
1132 {
1133 if(
NOQUIET)
error(
"ID3v2: unable to allocate working buffer for de-unsync");
1134 continue;
1135 }
1136
1137 realdata[0] = tagdata[
pos];
1138 opos = 1;
1139 for(ipos =
pos+1; ipos <
pos+framesize; ++ipos)
1140 {
1141 if(!((tagdata[ipos] == 0) && (tagdata[ipos-1] == 0xff)))
1142 {
1143 realdata[opos++] = tagdata[ipos];
1144 }
1145 }
1146 realsize = opos;
1147
1148 realdata[realsize] = 0;
1149 debug2(
"ID3v2: de-unsync made %lu out of %lu bytes", realsize, framesize);
1150 }
1152
1153
1154 if(realsize) switch(tt)
1155 {
1159 break;
1162 break;
1164 {
1165
1167
1168 rva_mode = 0;
1170 || !
strncasecmp((
char*)realdata,
"audiophile", 10)
1172 rva_mode = 1;
1173 if(fr->
rva.level[rva_mode] <=
rva2+1)
1174 {
1176 debug2(
"got my pos: %zu - %zu", realsize,
pos);
1177
1178
1179 if(
pos > realsize || realsize-
pos < 3)
1180 {
1182 error(
"bad RVA2 tag (truncated?)");
1183 }
1184 else if(realdata[
pos] == 1)
1185 {
1187
1188 debug(
"ID3v2: it is for the master channel");
1189
1190
1191
1192
1194 ((
short)((
signed char*)realdata)[
pos]) * 256 + (
short)realdata[
pos+1] ) / 512;
1197
1198 fr->
rva.peak[rva_mode] = 0;
1199 fr->
rva.level[rva_mode] =
rva2+1;
1200 }
1201 }
1202 }
1203 break;
1204
1207 break;
1211
1212 break;
1213 default:
if(
NOQUIET)
error1(
"ID3v2: unknown frame type %i", tt);
1214 }
1215 if(unsyncbuffer)
1217 }
1218 #undef BAD_FFLAGS
1219 #undef PRES_TAG_FFLAG
1220 #undef PRES_FILE_FFLAG
1221 #undef READ_ONLY_FFLAG
1222 #undef GROUP_FFLAG
1223 #undef COMPR_FFLAG
1224 #undef ENCR_FFLAG
1225 #undef UNSYNC_FFLAG
1226 #undef DATLEN_FFLAG
1227 }
1228 else break;
1229 #undef KNOWN_FRAMES
1230 }
1231 } else
1232 {
1234 fprintf(
stderr,
"Note: faulty ID3v2 tag still clearing old data\n");
1236 }
1237 } else
1238 {
1242 }
1243tagparse_cleanup:
1244
1246 {
1250 }
1251 }
1252#endif
1254 #undef UNSYNC_FLAG
1255 #undef EXTHEAD_FLAG
1256 #undef COMPRESS_FLAG
1257 #undef EXP_FLAG
1258 #undef FOOTER_FLAG
1259 #undef EXT_UPDATE_FLAG
1260 #undef UNKOWN_FLAGS
1261}
ACPI_SIZE strlen(const char *String)
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
static void process_text(mpg123_handle *fr, unsigned char *realdata, size_t realsize, char *id)
static void process_extra(mpg123_handle *fr, unsigned char *realdata, size_t realsize, int rva_level, char *id)
#define threebytes_to_long(buf, res)
static void process_picture(mpg123_handle *fr, unsigned char *realdata, size_t realsize)
static const char frame_type[KNOWN_FRAMES][5]
#define bytes_to_long(buf, res)
static int promote_framename(mpg123_handle *fr, char *id)
static void process_comment(mpg123_handle *fr, enum frame_types tt, unsigned char *realdata, size_t realsize, int rva_level, char *id)
int store_id3v2(mpg123_handle *fr, unsigned long first4bytes, unsigned char buf[6], unsigned long length)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
static float(__cdecl *square_half_float)(float x
#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::@3459 rva