1 /*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
2  *
3  *  Use of this source code is governed by a BSD-style license that can
4  *  be found in the License.html file in the root of the source tree.
5  */
6 
7 //---------------------------------------------------------------------------
8 // Pre-compilation
9 #include "MediaInfo/PreComp.h"
10 #ifdef __BORLANDC__
11     #pragma hdrstop
12 #endif
13 //---------------------------------------------------------------------------
14 
15 //---------------------------------------------------------------------------
16 #include "MediaInfo/Setup.h"
17 //---------------------------------------------------------------------------
18 
19 //***************************************************************************
20 // Infos (Common)
21 //***************************************************************************
22 
23 //---------------------------------------------------------------------------
24 #if defined(MEDIAINFO_ID3V2_YES) || defined(MEDIAINFO_FLAC_YES) || defined(MEDIAINFO_VORBISCOM_YES) || defined(MEDIAINFO_OGG_YES)
25 //---------------------------------------------------------------------------
26 
27 #include "ZenLib/Conf.h"
28 using namespace ZenLib;
29 
30 namespace MediaInfoLib
31 {
32 
33 //---------------------------------------------------------------------------
Id3v2_PictureType(int8u Type)34 extern const char* Id3v2_PictureType(int8u Type)
35 {
36     switch (Type)
37     {
38         case 0x01 :
39         case 0x02 : return "File icon";
40         case 0x03 : return "Cover (front)";
41         case 0x04 : return "Cover (back)";
42         case 0x05 : return "Leaflet page";
43         case 0x06 : return "Media";
44         case 0x07 :
45         case 0x08 : return "Performer";
46         case 0x09 : return "Conductor";
47         case 0x0A : return "Performer";
48         case 0x0B : return "Composer";
49         case 0x0C : return "Lyricist";
50         case 0x0D : return "Recording Location";
51         case 0x0E : return "During recording";
52         case 0x0F : return "During performance";
53         case 0x10 : return "Screen capture";
54         case 0x12 : return "Illustration";
55         case 0x13 : return "Performer logo";
56         case 0x14 : return "Publisher logo";
57         default   : return "";
58     }
59 }
60 
61 } //NameSpace
62 
63 //---------------------------------------------------------------------------
64 #endif //...
65 //---------------------------------------------------------------------------
66 
67 //***************************************************************************
68 //
69 //***************************************************************************
70 
71 //---------------------------------------------------------------------------
72 #if defined(MEDIAINFO_ID3V2_YES)
73 //---------------------------------------------------------------------------
74 
75 //---------------------------------------------------------------------------
76 #include "MediaInfo/Tag/File_Id3v2.h"
77 #include "ZenLib/ZtringListList.h"
78 #include "ZenLib/Utils.h"
79 #include "ThirdParty/base64/base64.h"
80 #include <cstring>
81 using namespace ZenLib;
82 //---------------------------------------------------------------------------
83 
84 namespace MediaInfoLib
85 {
86 
87 //***************************************************************************
88 // Infos
89 //***************************************************************************
90 
91 //---------------------------------------------------------------------------
92 const char* Id3v2_TextEnc[]=
93 {
94     "ISO 8859-1",
95     "UTF-16",
96     "UTF-16BE",
97     "UTF-8",
98 };
99 
100 //---------------------------------------------------------------------------
101 const char* Id3v2_RGAD_Name_code[]=
102 {
103     "",
104     "Radio Gain Adjustment",
105     "Audiophile Gain Adjustment",
106     "",
107     "",
108     "",
109     "",
110     "",
111 };
112 
113 //---------------------------------------------------------------------------
114 const char* Id3v2_RGAD_Originator_code[]=
115 {
116     "",
117     "Pre-set by artist/producer/mastering engineer",
118     "Set by user",
119     "Determined automatically",
120     "",
121     "",
122     "",
123     "",
124 };
125 
126 //***************************************************************************
127 // Constants
128 //***************************************************************************
129 
130 namespace Elements
131 {
132     const int32u AENC=0x41454E47;
133     const int32u APIC=0x41504943;
134     const int32u ASPI=0x41535049;
135     const int32u COMM=0x434F4D4D;
136     const int32u COMR=0x434F4D52;
137     const int32u ENCR=0x454E4352;
138     const int32u EQU2=0x45515532;
139     const int32u EQUA=0x45515541;
140     const int32u ETCO=0x4554434F;
141     const int32u GEOB=0x47454F42;
142     const int32u GRID=0x47524944;
143     const int32u IPLS=0x49504C53;
144     const int32u LINK=0x4C494E4B;
145     const int32u MCDI=0x4D434449;
146     const int32u MLLT=0x4D4C4C54;
147     const int32u OWNE=0x4F574E45;
148     const int32u PCNT=0x50434E58;
149     const int32u POPM=0x504F504D;
150     const int32u POSS=0x504F5353;
151     const int32u PRIV=0x50524956;
152     const int32u RBUF=0x52425546;
153     const int32u RGAD=0x52474144;
154     const int32u RVA2=0x52564132;
155     const int32u RVRB=0x52565242;
156     const int32u SEEK=0x5345454B;
157     const int32u SIGN=0x5349474E;
158     const int32u SYLT=0x53594C54;
159     const int32u SYTC=0x53595443;
160     const int32u TALB=0x54414C42;
161     const int32u TBPM=0x5442504D;
162     const int32u TCAT=0x54434154;
163     const int32u TCMP=0x54434D50;
164     const int32u TCOM=0x54434F4D;
165     const int32u TCON=0x54434F4E;
166     const int32u TCOP=0x54434F50;
167     const int32u TDAT=0x54444154;
168     const int32u TDEN=0x5444454E;
169     const int32u TDLY=0x54444C59;
170     const int32u TDOR=0x54444F52;
171     const int32u TDRC=0x54445243;
172     const int32u TDRL=0x5444524C;
173     const int32u TDTG=0x54445447;
174     const int32u TENC=0x54454E43;
175     const int32u TEXT=0x54455854;
176     const int32u TFLT=0x54464C54;
177     const int32u TIME=0x54494D45;
178     const int32u TIPL=0x5449504C;
179     const int32u TIT1=0x54495431;
180     const int32u TIT2=0x54495432;
181     const int32u TIT3=0x54495433;
182     const int32u TKEY=0x544B4559;
183     const int32u TLAN=0x544C414E;
184     const int32u TLEN=0x544C454E;
185     const int32u TMCL=0x544D434C;
186     const int32u TMED=0x544D4544;
187     const int32u TMOO=0x544D4F4F;
188     const int32u TOAL=0x544F414C;
189     const int32u TOFN=0x544F464E;
190     const int32u TOLY=0x544F4C59;
191     const int32u TOPE=0x544F5045;
192     const int32u TORY=0x544F5259;
193     const int32u TOWN=0x544F574E;
194     const int32u TPE1=0x54504531;
195     const int32u TPE2=0x54504532;
196     const int32u TPE3=0x54504533;
197     const int32u TPE4=0x54504534;
198     const int32u TPOS=0x54504F53;
199     const int32u TPRO=0x5450524F;
200     const int32u TPUB=0x54505542;
201     const int32u TRCK=0x5452434B;
202     const int32u TRDA=0x54524441;
203     const int32u TRSN=0x5452534E;
204     const int32u TRSO=0x5452534F;
205     const int32u TSIZ=0x5453495A;
206     const int32u TSO2=0x54534F32;
207     const int32u TSOA=0x54534F41;
208     const int32u TSOC=0x54534F43;
209     const int32u TSOP=0x54534F50;
210     const int32u TSOT=0x54534F54;
211     const int32u TSRC=0x54535243;
212     const int32u TSSE=0x54535345;
213     const int32u TSST=0x54535354;
214     const int32u TXXX=0x54585858;
215     const int32u TYER=0x54594552;
216     const int32u UFID=0x55464944;
217     const int32u USER=0x55534552;
218     const int32u USLT=0x55534C54;
219     const int32u WCOM=0x57434F4D;
220     const int32u WCOP=0x57434F50;
221     const int32u WOAF=0x574F4146;
222     const int32u WOAR=0x574F4152;
223     const int32u WOAS=0x574F4153;
224     const int32u WORS=0x574F5253;
225     const int32u WPAY=0x57504159;
226     const int32u WPUB=0x57505542;
227     const int32u WXXX=0x57585858;
228     const int32u XRVA=0x58525641;
229     const int32u BUF=0x425546;
230     const int32u CNT=0x434E56;
231     const int32u COM=0x434F4D;
232     const int32u CRA=0x435241;
233     const int32u CRM=0x43524D;
234     const int32u EQU=0x455155;
235     const int32u ETC=0x455443;
236     const int32u GEO=0x47454F;
237     const int32u IPL=0x49504C;
238     const int32u LNK=0x4C4E4B;
239     const int32u MCI=0x4D4349;
240     const int32u MLL=0x4D4C4C;
241     const int32u PIC_=0x504943; //PIC is used by shared libs in GCC
242     const int32u POP=0x504F50;
243     const int32u REV=0x524556;
244     const int32u RVA=0x525641;
245     const int32u SLT=0x534C54;
246     const int32u STC=0x535443;
247     const int32u TAL=0x54414C;
248     const int32u TBP=0x544250;
249     const int32u TCM=0x54434D;
250     const int32u TCO=0x54434F;
251     const int32u TCP=0x544350;
252     const int32u TCR=0x544352;
253     const int32u TDA=0x544441;
254     const int32u TDY=0x544459;
255     const int32u TEN=0x54454E;
256     const int32u TFT=0x544654;
257     const int32u TIM=0x54494D;
258     const int32u TKE=0x544B45;
259     const int32u TLA=0x544C41;
260     const int32u TLE=0x544C45;
261     const int32u TMT=0x544D54;
262     const int32u TOA=0x544F41;
263     const int32u TOF=0x544F46;
264     const int32u TOL=0x544F4C;
265     const int32u TOR=0x544F52;
266     const int32u TOT=0x544F54;
267     const int32u TP1=0x545031;
268     const int32u TP2=0x545032;
269     const int32u TP3=0x545033;
270     const int32u TP4=0x545034;
271     const int32u TPA=0x545041;
272     const int32u TPB=0x545042;
273     const int32u TRC=0x545243;
274     const int32u TRD=0x545244;
275     const int32u TRK=0x54524B;
276     const int32u TSI=0x545349;
277     const int32u TSS=0x545353;
278     const int32u TT1=0x545431;
279     const int32u TT2=0x545432;
280     const int32u TT3=0x545433;
281     const int32u TXT=0x545854;
282     const int32u TXX=0x545858;
283     const int32u TYE=0x545945;
284     const int32u UFI=0x554649;
285     const int32u ULT=0x554C54;
286     const int32u WAF=0x574146;
287     const int32u WAR=0x574152;
288     const int32u WAS=0x574153;
289     const int32u WCM=0x57434D;
290     const int32u WCP=0x574350;
291     const int32u WPB=0x575042;
292     const int32u WXX=0x575858;
293 }
294 
295 //***************************************************************************
296 // Constructor/Destructor
297 //***************************************************************************
298 
299 //---------------------------------------------------------------------------
File_Id3v2()300 File_Id3v2::File_Id3v2()
301 :File__Analyze()
302 {
303     //Temp
304     Id3v2_Size=0;
305 }
306 
307 //***************************************************************************
308 // Static stuff
309 //***************************************************************************
310 
311 //---------------------------------------------------------------------------
Static_Synchronize_Tags(const int8u * Buffer,size_t Buffer_Offset,size_t Buffer_Size,bool & Tag_Found)312 bool File_Id3v2::Static_Synchronize_Tags(const int8u* Buffer, size_t Buffer_Offset, size_t Buffer_Size, bool &Tag_Found)
313 {
314     //Buffer size
315     if (Buffer_Offset+3>Buffer_Size)
316         return false;
317 
318     //ID
319     if ((Buffer[Buffer_Offset  ]==0x49 // "ID3"
320       && Buffer[Buffer_Offset+1]==0x44
321       && Buffer[Buffer_Offset+2]==0x33)
322      || (Buffer[Buffer_Offset  ]==0x65 // "ea3", found in OpenMG
323       && Buffer[Buffer_Offset+1]==0x61
324       && Buffer[Buffer_Offset+2]==0x33))
325         Tag_Found=true;
326     else
327         Tag_Found=false;
328 
329     //Continue
330     return true;
331 }
332 
333 //***************************************************************************
334 // Streams management
335 //***************************************************************************
336 
337 //---------------------------------------------------------------------------
Streams_Fill()338 void File_Id3v2::Streams_Fill()
339 {
340     if (Count_Get(Stream_General)==0)
341         return;
342 
343     //Specific formats (multiple Id3v2 tags for one MI tag)
344     if (Retrieve(Stream_General, 0, General_Recorded_Date).empty() && !Year.empty())
345     {
346         Ztring Recorded_Date=Year;
347         if (!Month.empty())
348         {
349             Recorded_Date+=__T('-');
350             Recorded_Date+=Month;
351             if (!Day.empty())
352             {
353                 Recorded_Date+=__T('-');
354                 Recorded_Date+=Day;
355                 if (!Hour.empty())
356                 {
357                     Recorded_Date+=__T(' ');
358                     Recorded_Date+=Hour;
359                     if (!Minute.empty())
360                     {
361                         Recorded_Date+=__T(':');
362                         Recorded_Date+=Minute;
363                     }
364                 }
365             }
366         }
367         Fill(Stream_General, 0, General_Recorded_Date, Recorded_Date);
368     }
369 }
370 
371 //***************************************************************************
372 // Buffer - File header
373 //***************************************************************************
374 
375 //---------------------------------------------------------------------------
FileHeader_Parse()376 void File_Id3v2::FileHeader_Parse()
377 {
378     //Parsing
379     int32u Size;
380     int8u Flags;
381     bool ExtendedHeader;
382     Skip_C3(                                                    "identifier");
383     Get_B1 (Id3v2_Version,                                      "version_major");
384     Skip_B1(                                                    "version_revision");
385     Get_B1 (Flags,                                              "flags");
386         Get_Flags (Flags, 7, Unsynchronisation_Global,          "Unsynchronisation");
387         Get_Flags (Flags, 6, ExtendedHeader,                    "Extended header");
388         Skip_Flags(Flags, 5,                                    "Experimental indicator");
389     Get_B4 (Size,                                               "Size");
390     Id3v2_Size=((Size>>0)&0x7F)
391              | ((Size>>1)&0x3F80)
392              | ((Size>>2)&0x1FC000)
393              | ((Size>>3)&0x0FE00000);
394     Param_Info1(Id3v2_Size);
395     if (ExtendedHeader)
396     {
397         Element_Begin1("Extended header");
398         int32u Size_Extended;
399         Get_B4 (Size_Extended,                                  "Size");
400         Skip_XX(Size_Extended,                                  "Extended header");
401         Element_End0();
402     }
403 
404     FILLING_BEGIN();
405         //Versions
406         switch (Id3v2_Version)
407         {
408             case 2 : break;
409             case 3 : break;
410             case 4 : break;
411             default :
412                 Skip_XX(Id3v2_Size,                             "Data");
413                 return;
414         }
415 
416         Accept("Id3v2");
417         Stream_Prepare(Stream_General);
418 
419         Stream_Prepare(Stream_Audio);
420     FILLING_END();
421 }
422 
423 //***************************************************************************
424 // Buffer - Per element
425 //***************************************************************************
426 
427 //---------------------------------------------------------------------------
Header_Parse()428 void File_Id3v2::Header_Parse()
429 {
430     Unsynchronisation_Frame=false;
431     DataLengthIndicator=false;
432 
433     if (Id3v2_Size<10) //first 10 is minimum size of a tag, Second 10 is ID3v2 header size
434     {
435         //Not enough place for a tag, must be padding
436         Header_Fill_Code((int64u)-1, "Padding");
437         Header_Fill_Size(Id3v2_Size);
438         return;
439     }
440 
441     if (Buffer_Offset+10>Buffer_Size)
442     {
443         Element_WaitForMoreData();
444         return; //Not enough buffer
445     }
446 
447     //Testing padding
448     int32u Frame_ID, Size;
449     Frame_ID=CC1(Buffer+Buffer_Offset);
450     if (Frame_ID==0x00)
451     {
452         //This is the padding
453         Header_Fill_Code(0xFFFFFFFF, "Padding");
454         Header_Fill_Size(Id3v2_Size);
455         return;
456     }
457 
458     //Parsing
459     if (Id3v2_Version==2)
460     {
461         Get_C3 (Frame_ID,                                       "Frame ID");
462         Get_B3 (Size,                                           "Size");
463     }
464     else
465     {
466         int16u Flags;
467         Get_C4 (Frame_ID,                                       "Frame ID");
468         if (!(Frame_ID&0xFF))
469             Frame_ID>>=8;
470         Get_B4 (Size,                                           "Size");
471         if (Id3v2_Version!=3)
472         {
473             Size=((Size>>0)&0x7F)
474                | ((Size>>1)&0x3F80)
475                | ((Size>>2)&0x1FC000)
476                | ((Size>>3)&0x0FE00000);
477             Param_Info2(Size, " bytes");
478         }
479         Get_B2 (Flags,                                          "Flags");
480         if (Id3v2_Version==3)
481         {
482             Skip_Flags(Flags, 15,                               "Tag alter preservation");
483             Skip_Flags(Flags, 14,                               "File alter preservation");
484             Skip_Flags(Flags, 13,                               "Read only");
485             Skip_Flags(Flags,  7,                               "Compression");
486             Skip_Flags(Flags,  6,                               "Encryption");
487             Skip_Flags(Flags,  5,                               "Grouping identity");
488         }
489         if (Id3v2_Version==4)
490         {
491             Skip_Flags(Flags, 14,                               "Tag alter preservation");
492             Skip_Flags(Flags, 13,                               "File alter preservation");
493             Skip_Flags(Flags, 12,                               "Read only");
494             Skip_Flags(Flags,  6,                               "Grouping identity");
495             Skip_Flags(Flags,  3,                               "Compression");
496             Skip_Flags(Flags,  2,                               "Encryption");
497             Get_Flags (Flags,  1, Unsynchronisation_Frame,      "Unsynchronisation");
498             Get_Flags (Flags,  0, DataLengthIndicator,          "Data length indicator");
499         }
500     }
501 
502     //Hanlding Unsynchronisation
503     if (Unsynchronisation_Global || Unsynchronisation_Frame)
504     {
505         if (Buffer_Offset+(size_t)Element_Offset+Size>Buffer_Size)
506         {
507             Element_WaitForMoreData();
508             return;
509         }
510         for (size_t Element_Offset_Unsynch=0; Element_Offset_Unsynch+2<Element_Offset+Size; Element_Offset_Unsynch++)
511             if (CC2(Buffer+Buffer_Offset+Element_Offset_Unsynch)==0xFF00)
512             {
513                 Size++;
514                 if (Buffer_Offset+(size_t)Element_Offset+Size>Buffer_Size)
515                 {
516                     Element_WaitForMoreData();
517                     return;
518                 }
519             }
520     }
521 
522     //Filling
523     Ztring ToShow;
524     if (Id3v2_Version==2)
525         ToShow.From_CC3(Frame_ID);
526     else
527         ToShow.From_CC4(Frame_ID);
528     Header_Fill_Code(Frame_ID, ToShow);
529     Header_Fill_Size(Element_Offset+Size);
530 }
531 
532 //---------------------------------------------------------------------------
Data_Parse()533 void File_Id3v2::Data_Parse()
534 {
535     Id3v2_Size-=Header_Size+Element_Size;
536 
537     int32u DataLength=(int32u)-1;
538     if (DataLengthIndicator)
539     {
540         Get_B4 (DataLength,                             "Data length");
541         DataLength=((DataLength>>0)&0x7F)
542                  | ((DataLength>>1)&0x3F80)
543                  | ((DataLength>>2)&0x1FC000)
544                  | ((DataLength>>3)&0x0FE00000);
545         Param_Info2(DataLength, " bytes");
546     }
547 
548     //Unsynchronisation
549     int8u* Buffer_Unsynch=NULL;
550     const int8u* Save_Buffer=Buffer;
551     int64u Save_File_Offset=File_Offset;
552     size_t Save_Buffer_Offset=Buffer_Offset;
553     int64u Save_Element_Size=Element_Size;
554     int64u Element_Offset_Unsynch=Element_Offset;
555     std::vector<size_t> Unsynch_List;
556     if (Unsynchronisation_Global || Unsynchronisation_Frame)
557     {
558         while (Element_Offset_Unsynch+2<Element_Size)
559         {
560             if (CC2(Buffer+Buffer_Offset+(size_t)Element_Offset_Unsynch)==0xFF00)
561                 Unsynch_List.push_back((size_t)(Element_Offset_Unsynch+1));
562             Element_Offset_Unsynch++;
563         }
564         if (DataLength!=(int32u)-1 && 4+DataLength!=Element_Size-Unsynch_List.size())
565         {
566             Skip_XX(Element_Size-Element_Offset,                "Size coherency issue");
567             return;
568         }
569         if (!Unsynch_List.empty())
570         {
571             //We must change the buffer for keeping out
572             File_Offset=Save_File_Offset+Buffer_Offset;
573             Element_Size=Save_Element_Size-Unsynch_List.size();
574             Buffer_Offset=0;
575             Buffer_Unsynch=new int8u[(size_t)Element_Size];
576             for (size_t Pos=0; Pos<=Unsynch_List.size(); Pos++)
577             {
578                 size_t Pos0=(Pos==Unsynch_List.size())?(size_t)Save_Element_Size:(Unsynch_List[Pos]);
579                 size_t Pos1=(Pos==0)?0:(Unsynch_List[Pos-1]+1);
580                 size_t Buffer_Unsynch_Begin=Pos1-Pos;
581                 size_t Save_Buffer_Begin  =Pos1;
582                 size_t Size=               Pos0-Pos1;
583                 std::memcpy(Buffer_Unsynch+Buffer_Unsynch_Begin, Save_Buffer+Save_Buffer_Offset+Save_Buffer_Begin, Size);
584             }
585             Buffer=Buffer_Unsynch;
586         }
587     }
588 
589     #define CASE_INFO(_NAME, _DETAIL) \
590         case Elements::_NAME : Element_Info1(_DETAIL); _NAME(); break;
591 
592     //Parsing
593     Element_Value.clear();
594     Element_Values.clear();
595     switch (Element_Code)
596     {
597         CASE_INFO(AENC,                                         "Audio encryption");
598         CASE_INFO(APIC,                                         "Attached picture");
599         CASE_INFO(ASPI,                                         "Audio seek point index");
600         CASE_INFO(COMM,                                         "Comments");
601         CASE_INFO(COMR,                                         "Commercial frame");
602         CASE_INFO(ENCR,                                         "Encryption method registration");
603         CASE_INFO(EQU2,                                         "Equalisation (2)");
604         CASE_INFO(EQUA,                                         "Equalization");
605         CASE_INFO(ETCO,                                         "Event timing codes");
606         CASE_INFO(GEOB,                                         "General encapsulated object");
607         CASE_INFO(GRID,                                         "Group identification registration");
608         CASE_INFO(IPLS,                                         "Involved people list");
609         CASE_INFO(LINK,                                         "Linked information");
610         CASE_INFO(MCDI,                                         "Music CD identifier");
611         CASE_INFO(MLLT,                                         "MPEG location lookup table");
612         CASE_INFO(OWNE,                                         "Ownership frame");
613         CASE_INFO(PCNT,                                         "Play counter");
614         CASE_INFO(POPM,                                         "Popularimeter");
615         CASE_INFO(POSS,                                         "Position synchronisation frame");
616         CASE_INFO(PRIV,                                         "Private frame");
617         CASE_INFO(RBUF,                                         "Recommended buffer size");
618         CASE_INFO(RGAD,                                         "Replay Gain Adjustment");
619         CASE_INFO(RVA2,                                         "Relative volume adjustment (2)");
620         CASE_INFO(RVRB,                                         "Reverb");
621         CASE_INFO(SEEK,                                         "Seek frame");
622         CASE_INFO(SIGN,                                         "Signature frame");
623         CASE_INFO(SYLT,                                         "Synchronised lyric/text");
624         CASE_INFO(SYTC,                                         "Synchronised tempo codes");
625         CASE_INFO(TALB,                                         "Album/Movie/Show title");
626         CASE_INFO(TBPM,                                         "BPM (beats per minute)");
627         CASE_INFO(TCAT,                                         "iTunes Podcast category");
628         CASE_INFO(TCMP,                                         "iTunes Compilation Flag");
629         CASE_INFO(TCOM,                                         "Composer");
630         CASE_INFO(TCON,                                         "Content type");
631         CASE_INFO(TCOP,                                         "Copyright message");
632         CASE_INFO(TDAT,                                         "Date");
633         CASE_INFO(TDEN,                                         "Encoding time");
634         CASE_INFO(TDLY,                                         "Playlist delay");
635         CASE_INFO(TDOR,                                         "Original release time");
636         CASE_INFO(TDRC,                                         "Recording time");
637         CASE_INFO(TDRL,                                         "Release time");
638         CASE_INFO(TDTG,                                         "Tagging time");
639         CASE_INFO(TENC,                                         "Encoded by");
640         CASE_INFO(TEXT,                                         "Lyricist/Text writer");
641         CASE_INFO(TFLT,                                         "File type");
642         CASE_INFO(TIME,                                         "Time");
643         CASE_INFO(TIPL,                                         "Involved people list");
644         CASE_INFO(TIT1,                                         "Content group description");
645         CASE_INFO(TIT2,                                         "Title/songname/content description");
646         CASE_INFO(TIT3,                                         "Subtitle/Description refinement");
647         CASE_INFO(TKEY,                                         "Initial key");
648         CASE_INFO(TLAN,                                         "Language(s)");
649         CASE_INFO(TLEN,                                         "Length");
650         CASE_INFO(TMCL,                                         "Musician credits list");
651         CASE_INFO(TMED,                                         "Media type");
652         CASE_INFO(TMOO,                                         "Mood");
653         CASE_INFO(TOAL,                                         "Original album/movie/show title");
654         CASE_INFO(TOFN,                                         "Original filename");
655         CASE_INFO(TOLY,                                         "Original lyricist(s)/text writer(s)");
656         CASE_INFO(TOPE,                                         "Original artist(s)/performer(s)");
657         CASE_INFO(TORY,                                         "Original release year");
658         CASE_INFO(TOWN,                                         "File owner/licensee");
659         CASE_INFO(TPE1,                                         "Lead performer(s)/Soloist(s)");
660         CASE_INFO(TPE2,                                         "Band/orchestra/accompaniment");
661         CASE_INFO(TPE3,                                         "Conductor/performer refinement");
662         CASE_INFO(TPE4,                                         "Interpreted, remixed, or otherwise modified by");
663         CASE_INFO(TPOS,                                         "Part of a set");
664         CASE_INFO(TPRO,                                         "Produced notice");
665         CASE_INFO(TPUB,                                         "Publisher");
666         CASE_INFO(TRCK,                                         "Track number/Position in set");
667         CASE_INFO(TRDA,                                         "Recording dates");
668         CASE_INFO(TRSN,                                         "Internet radio station name");
669         CASE_INFO(TRSO,                                         "Internet radio station owner");
670         CASE_INFO(TSIZ,                                         "Size");
671         CASE_INFO(TSO2,                                         "Performer order");
672         CASE_INFO(TSOA,                                         "Album sort order");
673         CASE_INFO(TSOC,                                         "Composer sort order");
674         CASE_INFO(TSOP,                                         "Performer sort order");
675         CASE_INFO(TSOT,                                         "Title sort order");
676         CASE_INFO(TSRC,                                         "ISRC (international standard recording code)");
677         CASE_INFO(TSSE,                                         "Software/Hardware and settings used for encoding");
678         CASE_INFO(TSST,                                         "Set subtitle");
679         CASE_INFO(TXXX,                                         "User defined text information frame");
680         CASE_INFO(TYER,                                         "Year");
681         CASE_INFO(UFID,                                         "Unique file identifier");
682         CASE_INFO(USER,                                         "Terms of use");
683         CASE_INFO(USLT,                                         "Unsynchronised lyric/text transcription");
684         CASE_INFO(WCOM,                                         "Commercial information");
685         CASE_INFO(WCOP,                                         "Copyright/Legal information");
686         CASE_INFO(WOAF,                                         "Official audio file webpage");
687         CASE_INFO(WOAR,                                         "Official artist/performer webpage");
688         CASE_INFO(WOAS,                                         "Official audio source webpage");
689         CASE_INFO(WORS,                                         "Official Internet radio station homepage");
690         CASE_INFO(WPAY,                                         "Payment");
691         CASE_INFO(WPUB,                                         "Publishers official webpage");
692         CASE_INFO(WXXX,                                         "User defined URL link frame");
693         CASE_INFO(XRVA,                                         "Relative volume adjustment (2)");
694         CASE_INFO(BUF,                                          "Recommended buffer size");
695         CASE_INFO(CNT,                                          "Play counter");
696         CASE_INFO(COM,                                          "Comments");
697         CASE_INFO(CRA,                                          "Audio encryption");
698         CASE_INFO(CRM,                                          "Encrypted meta frame");
699         CASE_INFO(EQU,                                          "Equalization");
700         CASE_INFO(ETC,                                          "Event timing codes");
701         CASE_INFO(GEO,                                          "General encapsulated object");
702         CASE_INFO(IPL,                                          "Involved people list");
703         CASE_INFO(LNK,                                          "Linked information");
704         CASE_INFO(MCI,                                          "Music CD Identifier");
705         CASE_INFO(MLL,                                          "MPEG location lookup table");
706         CASE_INFO(PIC_,                                         "Attached picture");
707         CASE_INFO(POP,                                          "Popularimeter");
708         CASE_INFO(REV,                                          "Reverb");
709         CASE_INFO(RVA,                                          "Relative volume adjustment");
710         CASE_INFO(SLT,                                          "Synchronized lyric/text");
711         CASE_INFO(STC,                                          "Synced tempo codes");
712         CASE_INFO(TAL,                                          "Album/Movie/Show title");
713         CASE_INFO(TBP,                                          "BPM (Beats Per Minute)");
714         CASE_INFO(TCM,                                          "Composer");
715         CASE_INFO(TCO,                                          "Content type");
716         CASE_INFO(TCP,                                          "iTunes Compilation Flag");
717         CASE_INFO(TCR,                                          "Copyright message");
718         CASE_INFO(TDA,                                          "Date");
719         CASE_INFO(TDY,                                          "Playlist delay");
720         CASE_INFO(TEN,                                          "Encoded by");
721         CASE_INFO(TFT,                                          "File type");
722         CASE_INFO(TIM,                                          "Time");
723         CASE_INFO(TKE,                                          "Initial key");
724         CASE_INFO(TLA,                                          "Language(s)");
725         CASE_INFO(TLE,                                          "Length");
726         CASE_INFO(TMT,                                          "Media type");
727         CASE_INFO(TOA,                                          "Original artist(s)/performer(s)");
728         CASE_INFO(TOF,                                          "Original filename");
729         CASE_INFO(TOL,                                          "Original Lyricist(s)/text writer(s)");
730         CASE_INFO(TOR,                                          "Original release year");
731         CASE_INFO(TOT,                                          "Original album/Movie/Show title");
732         CASE_INFO(TP1,                                          "Lead artist(s)/Lead performer(s)/Soloist(s)/Performing group");
733         CASE_INFO(TP2,                                          "Band/Orchestra/Accompaniment");
734         CASE_INFO(TP3,                                          "Conductor/Performer refinement");
735         CASE_INFO(TP4,                                          "Interpreted,                                          remixed,                                          or otherwise modified by");
736         CASE_INFO(TPA,                                          "Part of a set");
737         CASE_INFO(TPB,                                          "Publisher");
738         CASE_INFO(TRC,                                          "ISRC (International Standard Recording Code)");
739         CASE_INFO(TRD,                                          "Recording dates");
740         CASE_INFO(TRK,                                          "Track number/Position in set");
741         CASE_INFO(TSI,                                          "Size");
742         CASE_INFO(TSS,                                          "Software/hardware and settings used for encoding");
743         CASE_INFO(TT1,                                          "Content group description");
744         CASE_INFO(TT2,                                          "Title/Songname/Content description");
745         CASE_INFO(TT3,                                          "Subtitle/Description refinement");
746         CASE_INFO(TXT,                                          "Lyricist/text writer");
747         CASE_INFO(TXX,                                          "User defined text information frame");
748         CASE_INFO(TYE,                                          "Year");
749         CASE_INFO(UFI,                                          "Unique file identifier");
750         CASE_INFO(ULT,                                          "Unsychronized lyric/text transcription");
751         CASE_INFO(WAF,                                          "Official audio file webpage");
752         CASE_INFO(WAR,                                          "Official artist/performer webpage");
753         CASE_INFO(WAS,                                          "Official audio source webpage");
754         CASE_INFO(WCM,                                          "Commercial information");
755         CASE_INFO(WCP,                                          "Copyright/Legal information");
756         CASE_INFO(WPB,                                          "Publishers official webpage");
757         CASE_INFO(WXX,                                          "User defined URL link frame");
758         default : Skip_XX(Element_Size,                         "Data");
759     }
760 
761     if (!Unsynch_List.empty())
762     {
763         //We must change the buffer for keeping out
764         File_Offset=Save_File_Offset;
765         Element_Size=Save_Element_Size;
766         Buffer_Offset=Save_Buffer_Offset;
767         delete[] Buffer; Buffer=Save_Buffer;
768         Buffer_Unsynch=NULL; //Same as Buffer...
769         Element_Offset+=Unsynch_List.size();
770     }
771 
772     if (!Id3v2_Size)
773         Finish("Id3v2");
774 }
775 
776 //***************************************************************************
777 // Elements
778 //***************************************************************************
779 
780 //---------------------------------------------------------------------------
781 //
T___()782 void File_Id3v2::T___()
783 {
784     int8u Encoding;
785     Get_B1 (Encoding,                                           "Text_encoding");
786     switch (Encoding)
787     {
788         case 0 : Get_ISO_8859_1 (Element_Size-Element_Offset, Element_Value, "Information"); break;
789         case 1 : Get_UTF16      (Element_Size-Element_Offset, Element_Value, "Information"); break;
790         case 2 : Get_UTF16B     (Element_Size-Element_Offset, Element_Value, "Information"); break;
791         case 3 : Get_UTF8       (Element_Size-Element_Offset, Element_Value, "Information"); break;
792         default : ;
793     }
794 
795     //Exceptions
796     if (Element_Code==Elements::TCMP || Element_Code==Elements::TCP)
797     {
798         if (Element_Value==__T("0")) Element_Value.clear(); //This is usually set to 0 even if the user did not explicitely indicated something (default)
799         if (Element_Value==__T("1")) Element_Value=__T("Yes");
800     }
801 
802     //Filling
803     if (Element_Value.empty())
804         return;
805     Fill_Name();
806 }
807 
808 //---------------------------------------------------------------------------
809 //
T__X()810 void File_Id3v2::T__X()
811 {
812     //Integrity
813     if (Element_Size<(Elements::TXXX?4:1))
814     {
815         Element_Values(1).clear();
816         Element_Values(0).clear();
817         return;
818     }
819 
820     int8u Encoding;
821     Get_B1 (Encoding,                                           "Text_encoding");
822     if (Element_Code!=Elements::TXXX)
823         Skip_C3(                                                "Language");
824     size_t Value0_Size=0;
825     switch (Encoding)
826     {
827         case 0 :
828         case 3 : //1-byte char
829                 while (Element_Offset+Value0_Size<Element_Size && Buffer[Buffer_Offset+(size_t)Element_Offset+Value0_Size]!='\0')
830                     Value0_Size++;
831                 if (Element_Offset+Value0_Size>=Element_Size)
832                     return; //Problem
833                 switch (Encoding)
834                 {
835                     case 0 : Get_ISO_8859_1 (Value0_Size, Element_Values(0), "Short_content_descrip"); break;
836                     case 3 : Get_UTF8       (Value0_Size, Element_Values(0), "Short_content_descrip"); break;
837                     default : ;
838                 }
839                 Skip_B1(                                        "Null");
840                 switch (Encoding)
841                 {
842                     case 0 : Get_ISO_8859_1 (Element_Size-Element_Offset, Element_Values(1), "The_actual_text"); break;
843                     case 3 : Get_UTF8       (Element_Size-Element_Offset, Element_Values(1), "The_actual_text"); break;
844                     default : ;
845                 }
846                 break;
847         case 1 :
848         case 2 : //2-byte char
849                 while (Element_Offset+Value0_Size+1<Element_Size
850                     && !(Buffer[Buffer_Offset+(size_t)Element_Offset+Value0_Size  ]=='\0'
851                       && Buffer[Buffer_Offset+(size_t)Element_Offset+Value0_Size+1]=='\0')) //2-byte zero
852                     Value0_Size+=2;
853                 if (Element_Offset+Value0_Size>=Element_Size)
854                     return; //Problem
855                 switch (Encoding)
856                 {
857                     case 1 : Get_UTF16 (Value0_Size, Element_Values(0), "Short_content_descrip"); break;
858                     case 2 : Get_UTF16B(Value0_Size, Element_Values(0), "Short_content_descrip"); break;
859                     default : ;
860                 }
861                 Skip_B2(                                        "Null");
862                 switch (Encoding)
863                 {
864                     case 1 : Get_UTF16 (Element_Size-Element_Offset, Element_Values(1), "The_actual_text"); break;
865                     case 2 : Get_UTF16B(Element_Size-Element_Offset, Element_Values(1), "The_actual_text"); break;
866                     default : ;
867                 }
868                 break;
869         default: //Unknown
870                 Skip_XX(Element_Size-Element_Offset,            "Unknown");
871         ;
872     }
873 }
874 
875 //---------------------------------------------------------------------------
W___()876 void File_Id3v2::W___()
877 {
878     Get_ISO_8859_1(Element_Size, Element_Value,                 "URL");
879 
880     //Filling
881     Fill_Name();
882 }
883 
884 //---------------------------------------------------------------------------
W__X()885 void File_Id3v2::W__X()
886 {
887     if (Element_Size<1)
888         return; //Problem
889 
890     int8u Encoding;
891     Get_B1 (Encoding,                                           "Text_encoding");
892     switch (Encoding)
893     {
894         case 0 : Get_ISO_8859_1 (Element_Size-1, Element_Values(0),  "Description"); break;
895         case 1 : Get_UTF16      (Element_Size-1, Element_Values(0),  "Description"); break;
896         case 2 : Get_UTF16B     (Element_Size-1, Element_Values(0),  "Description"); break;
897         case 3 : Get_UTF8       (Element_Size-1, Element_Values(0),  "Description"); break;
898         default : ;
899     }
900     Element_Offset=1;
901     switch (Encoding)
902     {
903         case 0 : Element_Offset+=Element_Values(0).size()+1; break; //NULL
904         case 1 : Element_Offset+=Element_Values(0).size()*2+4; break; //UTF-16 BOM + UTF-16 NULL
905         case 2 : Element_Offset+=Element_Values(0).size()*2+2; break; //UTF-16 NULL
906         case 3 : Element_Offset+=Element_Values(0).To_UTF8().size()+1; break; //UTF-8 NULL
907         default : ;
908     }
909     if (Element_Offset<Element_Size)
910         Get_ISO_8859_1(Element_Size-Element_Offset, Element_Values(1), "URL");
911 }
912 
913 //---------------------------------------------------------------------------
APIC()914 void File_Id3v2::APIC()
915 {
916     int8u Encoding, PictureType;
917     Ztring Mime, Description;
918     Get_B1 (Encoding,                                           "Text_encoding");
919     if (Id3v2_Version==2)
920     {
921         int32u Image_format;
922         Get_C3(Image_format,                                    "Image_format");
923         switch (Image_format)
924         {
925             case 0x504E47 : Mime="image/png"; break;
926             case 0x4A5047 : Mime="image/jpeg"; break;
927             default       : ;
928         }
929     }
930     else
931     {
932         int64u Element_Offset_Real=Element_Offset;
933         Get_ISO_8859_1(Element_Size-Element_Offset, Mime,       "MIME_type");
934         Element_Offset=Element_Offset_Real+Mime.size()+1;
935     }
936     Get_B1 (PictureType,                                        "Picture_type"); Element_Info1(Id3v2_PictureType(PictureType));
937     int64u Element_Offset_Real=Element_Offset;
938     switch (Encoding)
939     {
940         case 0 : Get_ISO_8859_1 (Element_Size-Element_Offset, Description, "Description"); break;
941         case 1 : Get_UTF16      (Element_Size-Element_Offset, Description, "Description"); break;
942         case 2 : Get_UTF16B     (Element_Size-Element_Offset, Description, "Description"); break;
943         case 3 : Get_UTF8       (Element_Size-Element_Offset, Description, "Description"); break;
944         default : ;
945     }
946     Element_Offset=Element_Offset_Real;
947     switch (Encoding)
948     {
949         case 0 : Element_Offset+=Description.size()+1; break; //NULL
950         case 1 : Element_Offset+=Description.size()*2+4; break; //UTF-16 BOM + UTF-16 NULL
951         case 2 : Element_Offset+=Description.size()*2+2; break; //UTF-16 NULL
952         case 3 : Element_Offset+=Description.To_UTF8().size()+1; break; //UTF-8 NULL
953         default : ;
954     }
955     if (Element_Offset>Element_Size)
956         return; //There is a problem
957 
958     //Filling
959     Fill_Name();
960     Fill(Stream_General, 0, General_Cover_Description, Description);
961     Fill(Stream_General, 0, General_Cover_Type, Id3v2_PictureType(PictureType));
962     Fill(Stream_General, 0, General_Cover_Mime, Mime);
963     #if MEDIAINFO_ADVANCED
964         if (MediaInfoLib::Config.Flags1_Get(Flags_Cover_Data_base64))
965         {
966             std::string Data_Raw((const char*)(Buffer+(size_t)(Buffer_Offset+Element_Offset)), (size_t)(Element_Size-Element_Offset));
967             std::string Data_Base64(Base64::encode(Data_Raw));
968             Fill(Stream_General, 0, General_Cover_Data, Data_Base64);
969         }
970     #endif //MEDIAINFO_ADVANCED
971 
972     Skip_XX(Element_Size-Element_Offset, "Data");
973 }
974 
975 //---------------------------------------------------------------------------
COMM()976 void File_Id3v2::COMM()
977 {
978     T__X();
979 
980     //Testing
981          if (Element_Values(0)==__T("iTunes_CDDB_IDs")) return;
982     else if (Element_Values(0)==__T("iTunNORM")) return;
983     else if (Element_Values(0)==__T("iTunSMPB")) return;
984     else if (Element_Values(0)==__T("Songs-DB_Tempo")) return;
985     else if (Element_Values(0)==__T("Songs-DB_Preference")) return;
986     else if (Element_Values(0)==__T("MusicMatch_Tempo")) return;
987     else if (Element_Values(0)==__T("MusicMatch_Mood"))
988     {
989         if (Retrieve(Stream_General, 0, General_Mood).empty())
990             Element_Values(0)=__T("Mood");
991         else
992             return;
993     }
994     else if (Element_Values(0)==__T("MusicMatch_Preference")) return;
995 
996     //Filling
997     if (Element_Values(0).empty())
998     {
999         if (Element_Values(1).find(__T("ExactAudioCopy"))==0)
1000         {
1001             Fill(Stream_General, 0, General_Encoded_Application, Element_Values(1));
1002             return;
1003         }
1004 
1005         Element_Values(0)=__T("Comment");
1006     }
1007     Fill_Name();
1008 }
1009 
1010 //---------------------------------------------------------------------------
RGAD()1011 void File_Id3v2::RGAD()
1012 {
1013     //Parsing
1014     float32 Peak_Amplitude;
1015     Get_BF4 (Peak_Amplitude,                                    "Peak Amplitude");
1016     while (Element_Offset+2<=Element_Size)
1017     {
1018         Element_Begin1("Gain Adjustement");
1019         int16u Replay_Gain_Adjustment;
1020         int8u  Name_code;
1021         bool   Sign_bit;
1022         BS_Begin();
1023         Get_S1 (3, Name_code,                                   "Name code"); Param_Info1(Id3v2_RGAD_Name_code[Name_code]);
1024         Info_S1(3, Originator_code,                             "Originator code"); Param_Info1(Id3v2_RGAD_Originator_code[Originator_code]);
1025         Get_SB (Sign_bit,                                       "Sign bit");
1026         Get_S2 (9, Replay_Gain_Adjustment,                      "Replay Gain Adjustment"); Param_Info3 ((Sign_bit?-1:1)*(float)Replay_Gain_Adjustment/10, " dB", 1);
1027         BS_End();
1028         Element_End0();
1029 
1030         FILLING_BEGIN();
1031             switch (Name_code)
1032             {
1033                 case 1 : if (Retrieve(Stream_Audio, 0, Audio_ReplayGain_Gain).empty()) //this tag is not precise, we prefer other RG tags
1034                             Fill(Stream_Audio, 0, Audio_ReplayGain_Gain, (Sign_bit?-1:1)*(float)Replay_Gain_Adjustment/10, 1);
1035                          break;
1036                 case 2 : if (Retrieve(Stream_General, 0, General_Album_ReplayGain_Gain).empty()) //this tag is not precise, we prefer other RG tags
1037                             Fill(Stream_General, 0, General_Album_ReplayGain_Gain, (Sign_bit?-1:1)*(float)Replay_Gain_Adjustment/10, 1);
1038                          break;
1039                 default: ;
1040             }
1041         FILLING_END();
1042     }
1043 
1044     FILLING_BEGIN();
1045         if (Peak_Amplitude && Retrieve(Stream_Audio, 0, Audio_ReplayGain_Peak).empty()) //this tag is not precise, we prefer other RG tags
1046             Fill(Stream_Audio, 0, Audio_ReplayGain_Peak, Peak_Amplitude, 6);
1047     FILLING_END();
1048 }
1049 
1050 //---------------------------------------------------------------------------
PRIV()1051 void File_Id3v2::PRIV()
1052 {
1053     //Parsing
1054     //Ztring Owner;
1055     //Get_ISO_8859_1(Element_Size, Owner,                         "Owner identifier");
1056     string Owner;
1057     size_t Owner_Size=0;
1058     while (Element_Offset+Owner_Size<Element_Size && Buffer[Buffer_Offset+(size_t)Element_Offset+Owner_Size]!='\0')
1059         Owner_Size++;
1060     if (Owner_Size==0 || Element_Offset+Owner_Size>=Element_Size)
1061     {
1062         Skip_XX(Element_Size-Element_Offset,                    "Unknown");
1063         return;
1064     }
1065     Get_String(Owner_Size, Owner,                               "Owner identifier");
1066     Skip_B1(                                                    "Null");
1067     if (Owner=="com.apple.streaming.transportStreamTimestamp")
1068     {
1069         //http://tools.ietf.org/html/draft-pantos-http-live-streaming-13
1070         int64u DTS;
1071         Get_B8 (DTS,                                            "DTS");
1072 
1073         FILLING_BEGIN();
1074             if (DTS>=0x200000000LL) //33 bits
1075             {
1076                 Fill(Stream_Audio, 0, Audio_Delay, DTS/90);
1077                 FrameInfo.DTS=DTS*1000000/90;
1078             }
1079         FILLING_END();
1080     }
1081     else
1082     {
1083         Skip_XX(Element_Size-Element_Offset,                    "Data");
1084     }
1085 }
1086 
1087 //---------------------------------------------------------------------------
USLT()1088 void File_Id3v2::USLT()
1089 {
1090     T__X();
1091 
1092     //Filling
1093     if (!Element_Values(0).empty())
1094         Element_Values(1)=Element_Values(0)+MediaInfoLib::Config.Language_Get(__T(": "))+Element_Values(1);
1095     Element_Values(0)=__T("Lyrics");
1096 
1097     Fill_Name();
1098 }
1099 
1100 //---------------------------------------------------------------------------
TXXX()1101 void File_Id3v2::TXXX()
1102 {
1103     T__X();
1104 
1105     //Filling
1106     if (Element_Values(0).empty())
1107         Element_Values(0)=__T("Comment");
1108     Fill_Name();
1109 }
1110 
1111 //---------------------------------------------------------------------------
SYLT()1112 void File_Id3v2::SYLT()
1113 {
1114     if (Element_Size<6)
1115     {
1116         Skip_XX(Element_Size,                                   "(Problem)");
1117         return;
1118     }
1119 
1120     int8u Encoding;
1121     Get_B1 (Encoding,                                           "Text encoding");
1122     Skip_C3(                                                    "Language");
1123     Skip_B1(                                                    "Time_stamp_format");
1124     Skip_B1(                                                    "Content_type");
1125     switch (Encoding)
1126     {
1127         case 0 : Get_ISO_8859_1 (Element_Size-6, Element_Value, "Short_content_descrip"); break;
1128         case 1 : Get_UTF16      (Element_Size-6, Element_Value, "Short_content_descrip"); break;
1129         case 2 : Get_UTF16B     (Element_Size-6, Element_Value, "Short_content_descrip"); break;
1130         case 3 : Get_UTF8       (Element_Size-6, Element_Value, "Short_content_descrip"); break;
1131         default : ;
1132     }
1133 
1134     //Filling
1135     Fill_Name();
1136 }
1137 
1138 //---------------------------------------------------------------------------
WXXX()1139 void File_Id3v2::WXXX()
1140 {
1141     W__X();
1142 
1143     //Filling
1144     if (Element_Values(1).empty())
1145         return;
1146     if (Element_Values(0).empty())
1147         Element_Values(0)=__T("URL");
1148     Fill_Name();
1149 }
1150 
1151 //***************************************************************************
1152 // Helpers
1153 //***************************************************************************
1154 
1155 //---------------------------------------------------------------------------
Fill_Name()1156 void File_Id3v2::Fill_Name()
1157 {
1158     Ztring Value=Ztring().From_CC4((int32u)Element_Code);
1159     if (MediaInfoLib::Config.CustomMapping_IsPresent(__T("Id3v2"), Value))
1160     {
1161         Fill(Stream_General, 0, MediaInfoLib::Config.CustomMapping_Get(__T("Id3v2"), Value).To_Local().c_str(), Element_Value);
1162         return;
1163     }
1164 
1165     switch (Element_Code)
1166     {
1167         case Elements::AENC : break;
1168         case Elements::APIC : Fill(Stream_General, 0, General_Cover, "Yes"); break;
1169         case Elements::ASPI : break;
1170         case Elements::COMM : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1171         case Elements::COMR : Fill(Stream_General, 0, "Commercial frame", Element_Value); break;
1172         case Elements::ENCR : break;
1173         case Elements::EQU2 : break;
1174         case Elements::EQUA : break;
1175         case Elements::ETCO : break;
1176         case Elements::GEOB : break;
1177         case Elements::GRID : Fill(Stream_General, 0, "Group identification registration", Element_Value); break;
1178         case Elements::IPLS : Fill(Stream_General, 0, "Involved people list", Element_Value); break;
1179         case Elements::LINK : Fill(Stream_General, 0, "Linked information", Element_Value); break;
1180         case Elements::MCDI : Fill(Stream_General, 0, "MCDI", "Yes"); break;
1181         case Elements::MLLT : break;
1182         case Elements::OWNE : Fill(Stream_General, 0, General_Owner, Element_Value); break;
1183         case Elements::PCNT : break;
1184         case Elements::POPM : break;
1185         case Elements::POSS : break;
1186         case Elements::PRIV : break;
1187         case Elements::RBUF : break;
1188         case Elements::RVA2 : break;
1189         case Elements::RVRB : break;
1190         case Elements::SEEK : break;
1191         case Elements::SIGN : break;
1192         case Elements::SYLT : Fill(Stream_General, 0, General_Lyrics, Element_Value); break;
1193         case Elements::SYTC : break;
1194         case Elements::TALB : Fill(Stream_General, 0, General_Album, Element_Value); break;
1195         case Elements::TBPM : Fill(Stream_General, 0, General_BPM, Element_Value); break;
1196         case Elements::TCAT : Fill(Stream_General, 0, General_PodcastCategory, Element_Value); break;
1197         case Elements::TCMP : Fill(Stream_General, 0, General_Compilation, Element_Value); break;
1198         case Elements::TCOM : Fill(Stream_General, 0, General_Composer, Element_Value); break;
1199         case Elements::TCON :
1200                               {
1201                                 if (Element_Value.find(__T('('))==0)
1202                                     Element_Value=Element_Value.SubString(__T("("), __T(")")); //Replace (nn) by nn
1203                                 if (Element_Value==__T("0") || Element_Value==__T("255"))
1204                                     Element_Value.clear();
1205                                 Fill(Stream_General, 0, General_Genre, Element_Value);
1206                               }
1207                               break;
1208         case Elements::TCOP : Fill(Stream_General, 0, General_Copyright, Element_Value); break;
1209         case Elements::TDA  :
1210         case Elements::TDAT : if (Element_Value.size()==4)
1211                          {
1212                             Day.assign  (Element_Value.c_str(), 0, 2);
1213                             Month.assign(Element_Value.c_str(), 2, 2);
1214                          }
1215                          break;
1216         case Elements::TDEN : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Encoded_Date", Element_Value); break;
1217         case Elements::TDLY : break;
1218         case Elements::TDOR : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Original/Released_Date", Element_Value); break;
1219         case Elements::TDRC : Normalize_Date(Element_Value); Fill(Stream_General, 0, General_Recorded_Date, Element_Value); break;
1220         case Elements::TDRL : Normalize_Date(Element_Value); Fill(Stream_General, 0, General_Released_Date, Element_Value); break;
1221         case Elements::TDTG : Normalize_Date(Element_Value); Fill(Stream_General, 0, General_Tagged_Date, Element_Value); break;
1222         case Elements::TENC : Fill(Stream_General, 0, General_EncodedBy, Element_Value); break;
1223         case Elements::TEXT : Fill(Stream_General, 0, General_Lyricist, Element_Value); break;
1224         case Elements::TFLT : Fill(Stream_General, 0, "File type", Element_Value); break;
1225         case Elements::TIM  :
1226         case Elements::TIME : if (Element_Value.size()==4)
1227                          {
1228                             Hour.assign  (Element_Value.c_str(), 0, 2);
1229                             Minute.assign(Element_Value.c_str(), 2, 2);
1230                          }
1231                          break;
1232         case Elements::TIPL : Fill(Stream_General, 0, General_ThanksTo, Element_Value); break;
1233         case Elements::TIT1 : Fill(Stream_General, 0, General_Grouping, Element_Value); break;
1234         case Elements::TIT2 : Fill(Stream_General, 0, General_Track, Element_Value); break;
1235         case Elements::TIT3 : Fill(Stream_General, 0, General_Track_More, Element_Value); break;
1236         case Elements::TKEY : Fill(Stream_General, 0, "Initial key", Element_Value); break;
1237         case Elements::TLAN : Fill(Stream_Audio,   0, Audio_Language, Element_Value); break;
1238         case Elements::TLEN : break; //Fill(Stream_General, 0, "Length", Element_Value); break;
1239         case Elements::TMCL : Fill(Stream_General, 0, "Musician Credit List", Element_Value); break;
1240         case Elements::TMED : Fill(Stream_General, 0, "Media Type", Element_Value); break;
1241         case Elements::TMOO : Fill(Stream_General, 0, "Mood", Element_Value); break;
1242         case Elements::TOAL : Fill(Stream_General, 0, "Original/Album", Element_Value); break;
1243         case Elements::TOFN : Fill(Stream_General, 0, "Original/FileName", Element_Value); break;
1244         case Elements::TOLY : Fill(Stream_General, 0, "Original/Lyricist", Element_Value); break;
1245         case Elements::TOPE : Fill(Stream_General, 0, "Original/Performer", Element_Value); break;
1246         case Elements::TORY : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Original/Released_Date", Element_Value); break;
1247         case Elements::TOWN : Fill(Stream_General, 0, General_Owner, Element_Value); break;
1248         case Elements::TPE1 : Fill(Stream_General, 0, General_Performer, Element_Value); break;
1249         case Elements::TPE2 : Fill(Stream_General, 0, General_Album_Performer, Element_Value); break;
1250         case Elements::TPE3 : Fill(Stream_General, 0, General_Conductor, Element_Value); break;
1251         case Elements::TPE4 : Fill(Stream_General, 0, General_RemixedBy, Element_Value); break;
1252         case Elements::TPOS :
1253                               {
1254                                 ZtringList List; List.Separator_Set(0, __T("/")); List.Write(Element_Value);
1255                                 if (!List(0).empty())
1256                                     Fill(Stream_General, 0, General_Part_Position, List(0));
1257                                 if (!List(1).empty())
1258                                     Fill(Stream_General, 0, General_Part_Position_Total, List(1));
1259                               }
1260                               break;
1261         case Elements::TPRO : Fill(Stream_General, 0, General_Producer_Copyright, Element_Value); break;
1262         case Elements::TPUB : Fill(Stream_General, 0, General_Publisher, Element_Value); break;
1263         case Elements::TRCK :
1264                               {
1265                                 ZtringList List; List.Separator_Set(0, __T("/")); List.Write(Element_Value);
1266                                 if (!List(0).empty())
1267                                     Fill(Stream_General, 0, General_Track_Position, List(0));
1268                                 if (!List(1).empty())
1269                                     Fill(Stream_General, 0, General_Track_Position_Total, List(1));
1270                               }
1271                               break;
1272         case Elements::TRDA : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Recorded_Date", Element_Value); break;
1273         case Elements::TRSN : Fill(Stream_General, 0, General_ServiceName, Element_Value); break;
1274         case Elements::TRSO : Fill(Stream_General, 0, General_ServiceProvider, Element_Value); break;
1275         case Elements::TSIZ : Fill(Stream_General, 0, "Size", Element_Value); break;
1276         case Elements::TSO2 : Fill(Stream_General, 0, General_Album_Performer_Sort, Element_Value); break;
1277         case Elements::TSOA : Fill(Stream_General, 0, General_Album_Sort, Element_Value); break;
1278         case Elements::TSOC : Fill(Stream_General, 0, General_Composer_Sort, Element_Value); break;
1279         case Elements::TSOP : Fill(Stream_General, 0, General_Performer_Sort, Element_Value); break;
1280         case Elements::TSOT : Fill(Stream_General, 0, General_Track_Sort, Element_Value); break;
1281         case Elements::TSRC : Fill(Stream_General, 0, General_ISRC, Element_Value); break;
1282         case Elements::TSSE : Fill(Stream_General, 0, General_Encoded_Library, Element_Value); break;
1283         case Elements::TSST : Fill(Stream_General, 0, "Set subtitle", Element_Value); break;
1284         case Elements::TXXX : if (Element_Values(0)==__T("AccurateRipResult"))      ;
1285                          else if (Element_Values(0)==__T("AccurateRipDiscID"))      ;
1286                          else if (Element_Values(0)==__T("CT_GAPLESS_DATA"))        ;
1287                          else if (Element_Values(0)==__T("DISCNUMBER"))             Fill(Stream_General, 0, General_Part_Position,           Element_Values(1), true);
1288                          else if (Element_Values(0)==__T("DISCTOTAL"))              Fill(Stream_General, 0, General_Part_Position_Total,     Element_Values(1), true);
1289                          else if (Element_Values(0)==__T("first_played_timestamp")) Fill(Stream_General, 0, General_Played_First_Date,       Ztring().Date_From_Milliseconds_1601(Element_Values(1).To_int64u()/10000));
1290                          else if (Element_Values(0)==__T("last_played_timestamp"))  Fill(Stream_General, 0, General_Played_Last_Date,        Ztring().Date_From_Milliseconds_1601(Element_Values(1).To_int64u()/10000));
1291                          else if (Element_Values(0)==__T("play_count"))             Fill(Stream_General, 0, General_Played_Count,            Element_Values(1).To_int64u());
1292                          else if (Element_Values(0)==__T("added_timestamp"))        Fill(Stream_General, 0, General_Added_Date,              Ztring().Date_From_Milliseconds_1601(Element_Values(1).To_int64u()/10000));
1293                          else if (Element_Values(0)==__T("replaygain_album_gain"))  Fill(Stream_General, 0, General_Album_ReplayGain_Gain,   Element_Values(1).To_float64(), 2, true);
1294                          else if (Element_Values(0)==__T("replaygain_album_peak"))  Fill(Stream_General, 0, General_Album_ReplayGain_Peak,   Element_Values(1).To_float64(), 6, true);
1295                          else if (Element_Values(0)==__T("replaygain_track_gain"))  Fill(Stream_Audio,   0, Audio_ReplayGain_Gain,           Element_Values(1).To_float64(), 2, true);
1296                          else if (Element_Values(0)==__T("replaygain_track_peak"))  Fill(Stream_Audio,   0, Audio_ReplayGain_Peak,           Element_Values(1).To_float64(), 6, true);
1297                          else if (Element_Values(0)==__T("TRACKTOTAL"))             Fill(Stream_General, 0, General_Track_Position_Total,    Element_Values(1), true);
1298                          else if (Element_Values(0)==__T("OMG_AGENR"))              ; //Duplicate of Genre
1299                          else if (Element_Values(0)==__T("OMG_ALBMS"))              ; //Duplicate of Album
1300                          else if (Element_Values(0)==__T("OMG_ASGTM"))              ; //?
1301                          else if (Element_Values(0)==__T("OMG_ATPE1"))              ; //Duplicate of Title
1302                          else if (Element_Values(0)==__T("OMG_TIT2S"))              ; //Duplicate of Title
1303                          else if (Element_Values(0)==__T("OMG_TPE1S"))              ; //Duplicate of Artist
1304                          else if (Element_Values(0)==__T("OMG_TRACK"))              Fill(Stream_General, 0, General_Track_Position,          Element_Values(1), true);
1305                          else if (Element_Values(0)==__T("OMG_TRLDA"))              ; //Duplicate of Date
1306                          else
1307                             Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1));
1308                          break;
1309         case Elements::TYER : Year=Element_Value; break;
1310         case Elements::UFID : Fill(Stream_Audio,   0, "UID", Element_Value); break;
1311         case Elements::USER : Fill(Stream_General, 0, General_TermsOfUse, Element_Value); break;
1312         case Elements::USLT : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1313         case Elements::WCOM : Fill(Stream_General, 0, "Commercial information", Element_Value); break;
1314         case Elements::WCOP : Fill(Stream_General, 0, "Copyright/Legal information", Element_Value); break;
1315         case Elements::WOAF : Fill(Stream_General, 0, "Official audio file webpage", Element_Value); break;
1316         case Elements::WOAR : Fill(Stream_General, 0, "Performer/Url", Element_Value); break;
1317         case Elements::WOAS : Fill(Stream_General, 0, "Official audio source webpage", Element_Value); break;
1318         case Elements::WORS : Fill(Stream_General, 0, General_Service_Url, Element_Value); break;
1319         case Elements::WPAY : Fill(Stream_General, 0, "Payment", Element_Value); break;
1320         case Elements::WPUB : Fill(Stream_General, 0, "Publisher/Url", Element_Value); break;
1321         case Elements::WXXX : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1322         case Elements::BUF  : break;
1323         case Elements::CNT  : break;
1324         case Elements::COM  : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1325         case Elements::CRA  : break;
1326         case Elements::CRM  : break;
1327         case Elements::EQU  : break;
1328         case Elements::ETC  : break;
1329         case Elements::GEO  : break;
1330         case Elements::IPL  : Fill(Stream_General, 0, "Involved people list", Element_Value); break;
1331         case Elements::LNK  : Fill(Stream_General, 0, "Linked information,", Element_Value); break;
1332         case Elements::MCI  : Fill(Stream_General, 0, "MCDI", Element_Value); break;
1333         case Elements::MLL  : break;
1334         case Elements::PIC_ : Fill(Stream_General, 0, "Cover", "Yes"); break;
1335         case Elements::POP  : break;
1336         case Elements::REV  : break;
1337         case Elements::RVA  : break;
1338         case Elements::SLT  : break;
1339         case Elements::STC  : break;
1340         case Elements::TAL  : Fill(Stream_General, 0, "Album", Element_Value); break;
1341         case Elements::TBP  : Fill(Stream_General, 0, "BPM", Element_Value); break;
1342         case Elements::TCM  : Fill(Stream_General, 0, "Composer", Element_Value); break;
1343         case Elements::TCO  :
1344                               {
1345                                 if (Element_Value.find(__T('('))==0)
1346                                     Element_Value=Element_Value.SubString(__T("("), __T(")")); //Replace (nn) by nn
1347                                 if (Element_Value==__T("0") || Element_Value==__T("255"))
1348                                     Element_Value.clear();
1349                                 if (!Element_Value.empty())
1350                                     Fill(Stream_General, 0, General_Genre, Element_Value);
1351                               }
1352                               break;
1353         case Elements::TCR  : Fill(Stream_General, 0, "Copyright", Element_Value); break;
1354         case Elements::TDY  : break;
1355         case Elements::TEN  : Fill(Stream_General, 0, "Encoded_Library", Element_Value); break;
1356         case Elements::TFT  : Fill(Stream_General, 0, "File type", Element_Value); break;
1357         case Elements::TKE  : Fill(Stream_General, 0, "Initial key", Element_Value); break;
1358         case Elements::TLA  : Fill(Stream_Audio,   0, Audio_Language, Element_Value); break;
1359         case Elements::TLE  : break;
1360         case Elements::TMT  : Fill(Stream_General, 0, "Media type", Element_Value); break;
1361         case Elements::TOA  : Fill(Stream_General, 0, "Original/Performer", Element_Value); break;
1362         case Elements::TOF  : Fill(Stream_General, 0, "Original/FileName", Element_Value); break;
1363         case Elements::TOL  : Fill(Stream_General, 0, "Original/Lyricist", Element_Value); break;
1364         case Elements::TOR  : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Original/Released_Date", Element_Value); break;
1365         case Elements::TOT  : Fill(Stream_General, 0, "Original/Album", Element_Value); break;
1366         case Elements::TP1  : Fill(Stream_General, 0, "Performer", Element_Value); break;
1367         case Elements::TP2  : Fill(Stream_General, 0, General_Album_Performer, Element_Value); break;
1368         case Elements::TP3  : Fill(Stream_General, 0, "Conductor", Element_Value); break;
1369         case Elements::TP4  : Fill(Stream_General, 0, "RemixedBy", Element_Value); break;
1370         case Elements::TPA  :
1371                               {
1372                                 ZtringList List; List.Separator_Set(0, __T("/")); List.Write(Element_Value);
1373                                 if (!List(0).empty())
1374                                     Fill(Stream_General, 0, General_Part_Position, List(0));
1375                                 if (!List(1).empty())
1376                                     Fill(Stream_General, 0, General_Part_Position_Total, List(1));
1377                               }
1378                               break;
1379         case Elements::TPB  : Fill(Stream_General, 0, "Publisher", Element_Value); break;
1380         case Elements::TRC  : Fill(Stream_General, 0, "ISRC", Element_Value); break;
1381         case Elements::TRD  : Normalize_Date(Element_Value); Fill(Stream_General, 0, "Recorded_Date", Element_Value); break;
1382         case Elements::TRK  :
1383                               {
1384                                 ZtringList List; List.Separator_Set(0, __T("/")); List.Write(Element_Value);
1385                                 if (!List(0).empty())
1386                                     Fill(Stream_General, 0, General_Track_Position, List(0));
1387                                 if (!List(1).empty())
1388                                     Fill(Stream_General, 0, General_Track_Position_Total, List(1));
1389                               }
1390                               break;
1391         case Elements::TSI  : break;
1392         case Elements::TSS  : break;
1393         case Elements::TT1  : Fill(Stream_General, 0, "Grouping", Element_Value); break;
1394         case Elements::TT2  : Fill(Stream_General, 0, "Track", Element_Value); break;
1395         case Elements::TT3  : Fill(Stream_General, 0, "Track_More", Element_Value); break;
1396         case Elements::TXT  : Fill(Stream_General, 0, "Lyricist", Element_Value); break;
1397         case Elements::TXX  : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1398         case Elements::TYE  : Year=Element_Value; break;
1399         case Elements::UFI  : Fill(Stream_Audio,   0, "UID", Element_Value); break;
1400         case Elements::ULT  : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1401         case Elements::WAF  : break;
1402         case Elements::WAR  : Fill(Stream_General, 0, General_Service_Url, Element_Value); break;
1403         case Elements::WAS  : Fill(Stream_General, 0, "Official audio source webpage", Element_Value); break;
1404         case Elements::WCM  : Fill(Stream_General, 0, "Commercial information", Element_Value); break;
1405         case Elements::WCP  : Fill(Stream_General, 0, "Copyright/Legal information", Element_Value); break;
1406         case Elements::WPB  : Fill(Stream_General, 0, "Publisher/Url", Element_Value); break;
1407         case Elements::WXX  : Fill(Stream_General, 0, Element_Values(0).To_UTF8().c_str(), Element_Values(1)); break;
1408         default : ;
1409     }
1410 }
1411 
1412 //---------------------------------------------------------------------------
Normalize_Date(Ztring & Date)1413 void File_Id3v2::Normalize_Date(Ztring& Date)
1414 {
1415     if (Date.size()<=11 || Date[4]!=__T('-') || Date[7]!=__T('-'))
1416         return; //Format unknown or without time
1417     Date[10]=__T(' '); //could be "T"
1418     Date=Ztring(__T("UTC "))+Date; //Id3v2 specify a UTC date
1419 }
1420 
1421 //***************************************************************************
1422 // C++
1423 //***************************************************************************
1424 
1425 } //NameSpace
1426 
1427 #endif //MEDIAINFO_MPEGA_YES
1428 
1429