//--------------------------------------------------------------------------- void File_Flac::PICTURE() { //Parsing int32u PictureType, MimeType_Size, Description_Size, Data_Size; Ztring MimeType, Description; Get_B4 (PictureType, "Picture type"); Element_Info1(Id3v2_PictureType((int8u)PictureType)); Get_B4 (MimeType_Size, "MIME type size"); Get_Local(MimeType_Size, MimeType, "MIME type"); Get_B4 (Description_Size, "Description size"); Get_UTF8(Description_Size, Description, "Description"); Skip_B4( "Width"); Skip_B4( "Height"); Skip_B4( "Color depth"); Skip_B4( "Number of colors used"); Get_B4 (Data_Size, "Data size"); if (Element_Offset+Data_Size>Element_Size) return; //There is a problem std::string Data_Raw((const char*)(Buffer+(size_t)(Buffer_Offset+Element_Offset)), Data_Size); std::string Data_Base64(Base64::encode(Data_Raw)); Skip_XX(Element_Size-Element_Offset, "Data"); //Filling Fill(Stream_General, 0, General_Cover, "Yes"); Fill(Stream_General, 0, General_Cover_Description, Description); Fill(Stream_General, 0, General_Cover_Type, Id3v2_PictureType((int8u)PictureType)); Fill(Stream_General, 0, General_Cover_Mime, MimeType); Fill(Stream_General, 0, General_Cover_Data, Data_Base64); }
//--------------------------------------------------------------------------- void File_Kate::Identification() { Element_Name("Identification"); //Parsing Ztring Language, Category; int16u Width, Height; int8u VersionMajor, VersionMinor, NumHeaders, TextEncoding; Skip_B1 ( "Signature"); Skip_Local(7, "Signature"); Skip_L1( "Reserved"); Get_L1 (VersionMajor, "version major"); Get_L1 (VersionMinor, "version minor"); Get_L1 (NumHeaders, "num headers"); Get_L1 (TextEncoding, "text encoding"); Skip_L1( "directionality"); Skip_L1( "Reserved"); Skip_L1( "granule shift"); Skip_L4( "Reserved"); Get_L2 (Width, "cw sh + canvas width"); Get_L2 (Height, "ch sh + canvas height"); /* BS_Begin(); Skip_BS( 4, "cw sh"); Get_BS (12, Width, "canvas width"); Skip_BS( 4, "ch sh"); Get_BS (12, Height, "canvas height"); BS_End(); */ Skip_L4( "granule rate numerator"); Skip_L4( "granule rate denominator"); Get_UTF8(16, Language, "Language"); Get_UTF8(16, Category, "Category"); FILLING_BEGIN(); Accept("Kate"); Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, Text_Format, "Kate"); Fill(Stream_Text, 0, Text_Codec, "Kate"); Fill(Stream_Text, 0, Text_Language, Language); Fill(Stream_Text, 0, Text_Language_More, Kate_Category(Category)); Finish("Kate"); FILLING_END(); }
//--------------------------------------------------------------------------- void File_Exr::comments () { //Parsing Ztring value; Get_UTF8(Element_Size, value, "value"); //Filling if (Frame_Count==1) Fill(StreamKind_Last, 0, General_Comment, value); }
//--------------------------------------------------------------------------- void File_Caf::info() { if (Element_Size<4) return; //Parsing int32u NumEntries; Get_B4 (NumEntries, "NumEntries"); ZtringList List; std::map<Ztring, Ztring> ListList; const int8u* Buffer_Max = Buffer+(size_t)(Buffer_Offset+Element_Size); while (Element_Offset<Element_Size) { const int8u* Buffer_Begin = Buffer+(size_t)(Buffer_Offset+Element_Offset); const int8u* Buffer_Middle = Buffer_Begin; while (Buffer_Middle<Buffer_Max && *Buffer_Middle) ++Buffer_Middle; const int8u* Buffer_End = Buffer_Middle + 1; while (Buffer_End<Buffer_Max && *Buffer_End) ++Buffer_End; Ztring Key, Value; Get_UTF8(Buffer_Middle-Buffer_Begin, Key, "Key"); Skip_B1 ( "Zero"); Get_UTF8(Buffer_End-(Buffer_Middle+1), Value, "Value"); if (Buffer_End!=Buffer_Max) Skip_B1 ( "Zero"); ListList[Key]=Value; } if (ListList.size()!=NumEntries) return; for (std::map<Ztring, Ztring>::iterator Item=ListList.begin(); Item!=ListList.end(); ++Item) Fill(Stream_General, 0, Item->first.To_UTF8().c_str(), Item->second); }
//--------------------------------------------------------------------------- void File_TimedText::Data_Parse() { //Parsing Ztring Value; Get_UTF8 (Element_Size, Value, "Value"); FILLING_BEGIN(); if (!Status[IsAccepted]) { Accept(); #ifdef MEDIAINFO_MPEG4_YES if (IsChapter) { Stream_Prepare(Stream_Menu); } else #endif //MEDIAINFO_MPEG4_YES { Stream_Prepare(Stream_Text); } Fill(StreamKind_Last, StreamPos_Last, Fill_Parameter(StreamKind_Last, Generic_Format), "Timed Text"); #ifdef MEDIAINFO_MPEG4_YES if (IsChapter) Fill(StreamKind_Last, StreamPos_Last, Menu_Chapters_Pos_Begin, Count_Get(StreamKind_Last, StreamPos_Last), 10, true); #endif //MEDIAINFO_MPEG4_YES } #ifdef MEDIAINFO_MPEG4_YES if (IsChapter) { } else #endif //MEDIAINFO_MPEG4_YES { Finish(); } #ifdef MEDIAINFO_MPEG4_YES if (IsChapter && FrameInfo.DTS!=(int64u)-1 && Buffer_Offset==2) { Fill(Stream_Menu, StreamPos_Last, Ztring().Duration_From_Milliseconds(FrameInfo.DTS/1000000).To_UTF8().c_str(), Value); Fill(Stream_Menu, StreamPos_Last, Menu_Chapters_Pos_End, Count_Get(Stream_Menu, StreamPos_Last), 10, true); } #endif //MEDIAINFO_MPEG4_YES FILLING_END(); Element_Offset=Buffer_Size-Buffer_Offset; //Buffer can also contain atoms after the text, ignoring them }
//--------------------------------------------------------------------------- void File_Ibi::InformData() { Element_Name("InformData"); //Parsing Ztring InformData_FromFile; Get_UTF8 (Element_Size, InformData_FromFile, "Data"); //Filling #if MEDIAINFO_IBIUSAGE if (Config->Ibi_UseIbiInfoIfAvailable_Get()) { ZtringListList Fields(InformData_FromFile); for (size_t Pos=0; Pos<Fields.size(); Pos++) { if (Pos==0 || Fields[Pos].size()<2) { if (Pos) Pos++; if (Pos>Fields.size() || Fields[Pos].size()<1) break; //End or problem if (Fields[Pos][0]==__T("General")) ; //Nothing to do else if (Fields[Pos][0]==__T("Video")) Stream_Prepare(Stream_Video); else if (Fields[Pos][0]==__T("Audio")) Stream_Prepare(Stream_Audio); else if (Fields[Pos][0]==__T("Text")) Stream_Prepare(Stream_Text); else if (Fields[Pos][0]==__T("Other")) Stream_Prepare(Stream_Other); else if (Fields[Pos][0]==__T("Image")) Stream_Prepare(Stream_Image); else if (Fields[Pos][0]==__T("Menu")) Stream_Prepare(Stream_Menu); else break; //Problem Pos++; } Fill(StreamKind_Last, StreamPos_Last, Fields[Pos][0].To_UTF8().c_str(), Fields[Pos][1], true); if (Info_Options<Fields[Pos].size()) (*Stream_More)[StreamKind_Last][StreamPos_Last](Fields[Pos][0].To_UTF8().c_str(), Info_Options)=Fields[Pos][Info_Options]; } } #endif //MEDIAINFO_IBIUSAGE }
//--------------------------------------------------------------------------- void File_Cmml::Configuration() { Element_Name("Configuration"); //Parsing Ztring Data; Get_UTF8(Element_Size, Data, "Data"); FILLING_BEGIN(); Ztring Value; Value=Data.SubString(_T("<head>"), _T("</head>")); if (!Value.empty()) Fill(Stream_Text, 0, Text_Title, Value.SubString(_T("<title>"), _T("</title>"))); if (Data.find(_T("<clip"))!=string::npos) Finish("CMML"); FILLING_END(); }
//--------------------------------------------------------------------------- void File_Ptx::Read_Buffer_Continue() { if (File_Offset || Buffer_Offset) { if (Buffer_Size) Reject(); //Problem return; } //Parsing ZtringList Names; Ztring LibraryName, LibraryVersion, Format, Directory; int32u LibraryName_Length, LibraryVersion_Length, LibraryRelease_Length, Format_Length, Platform_Length, Info_Count, Names_Count, Info_Length, Name_Length, FileName_Count, Directory_Length; int32u Unknown_Length; int16u Audio_Count; Element_Begin1("Header"); Skip_B1( "Magic"); Skip_Local(16, "Magic"); Skip_L2( "0x0500"); Skip_L1( "Unknown"); Skip_L1( "0x5A"); Skip_L2( "0x0001"); Skip_L2( "0x0004"); Skip_L2( "0x0000"); Skip_L4( "Unknown"); Skip_L2( "0x035A"); Skip_L2( "0x6400"); Skip_L2( "0x0000"); Skip_L2( "0x0300"); Skip_L2( "0x0000"); Get_L4 (LibraryName_Length, "WritingLibrary name length"); Get_UTF8(LibraryName_Length, LibraryName, "Library name"); Skip_L4( "0x00000003"); Skip_L4( "Library version, major"); Skip_L4( "Library version, minor"); Skip_L4( "Library version, revision"); Get_L4 (LibraryVersion_Length, "Library version length"); Get_UTF8(LibraryVersion_Length, LibraryVersion, "Library version"); Skip_L1( "0x01"); Get_L4 (LibraryRelease_Length, "Library release length"); Skip_UTF8(LibraryRelease_Length, "Library release"); Skip_L1( "0x00"); Get_L4 (Format_Length, "Format length"); Get_UTF8(Format_Length, Format, "Format"); if (Format!=__T("Pro Tools Session File")) { Element_End(); Reject("Ptx"); return; } Skip_L2( "0x0006"); Get_L4 (Platform_Length, "Platform length"); Skip_UTF8(Platform_Length, "Platform"); Skip_L4( "0x00000000"); Skip_L4( "0x00085A05"); Skip_L4( "Unknown"); Skip_L4( "0x00002067"); Skip_L4( "0x002A0000"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Element_End(); Element_Begin1("Info list"); Get_L4 (Info_Count, "Info count"); if (4*Info_Count>Element_Size) { Element_End(); Reject(); return; } for (int32u Pos=0; Pos<Info_Count; Pos++) { Element_Begin1("Info"); Get_L4 (Info_Length, "Info length"); if (Info_Length) { Info_UTF8(Info_Length, Info, "Name"); Element_Info1(Info); } Element_End(); } Element_End(); Element_Begin1("Unknown"); Skip_L4( "0x00000000"); Element_Begin1("Names list 1"); Get_L4 (Names_Count, "Names count minus 1"); if (4*Names_Count>Element_Size) { Element_End(); Reject(); return; } for (int16u Pos=0; Pos<1+Names_Count; Pos++) { Element_Begin1("Name"); Get_L4 (Name_Length, "Name length"); if (Name_Length) { Info_UTF8(Name_Length, Name, "Name"); Element_Name(Name); } Element_End(); } Element_End(); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Element_Begin1("Names list 2"); Get_L4 (Names_Count, "Names count"); if (4*Names_Count>Element_Size) { Element_End(); Reject(); return; } for (int16u Pos=0; Pos<Names_Count; Pos++) { Element_Begin1("Name"); Get_L4 (Name_Length, "Name length"); if (Name_Length) { Info_UTF8(Name_Length, Name, "Name"); Element_Name(Name); } Element_End(); } Element_End(); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Skip_L4( "0x00000000"); Skip_L4( "Unknown"); Skip_L4( "0x00000101"); Skip_L4( "0x00055A00"); Skip_L4( "Unknown"); Skip_L4( "0x00012519"); Skip_L4( "0x00000000"); Skip_L4( "0x00000000"); Skip_L4( "0x00000001"); Skip_L2( "0x0003"); Element_End(); Get_L2 (Audio_Count, "Audio count"); if (111*Audio_Count>Element_Size) { Reject(); return; } Element_Begin1("Audio tracks list 1"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); Skip_L4( "0x00000000"); Get_L4 (Unknown_Length, "Name length"); Info_UTF8(Unknown_Length, Name, "Name"); Skip_L2( "0x0000"); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A"); Skip_L4( "Unknown (same 1/2/3)"); Skip_L4( "Unknown (same 1/2/3)"); Info_L1(Number, "Ordered number"); Element_Info1(Number); Element_Info1(Name); Element_End(); Names.push_back(Name); } Element_End(); Skip_L2( "0x0000"); Element_Begin1("Audio tracks list 2"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); int32u Size; Skip_L3( "0x00025A"); Get_L4 (Size, "Size"); Skip_L4( "0x0000251A"); Get_L4 (Unknown_Length, "Name length"); Info_UTF8(Unknown_Length, Name, "Name"); Skip_L2( "0x0000"); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A"); Skip_L4( "Unknown (same 1/2/3)"); Skip_L4( "Unknown (same 1/2/3)"); Info_L1(Number, "Ordered number"); Element_Info1(Number); Skip_L4( "0x00000000"); Element_Info1(Name); if (Unknown_Length+31!=Size) { Reject(); return; } Element_End(); } Element_End(); Get_L2 (Audio_Count, "Audio count"); if (4*Audio_Count>Element_Size) { Reject(); return; } Skip_L2( "0x00"); Element_Begin1("Audio tracks list 3"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); int32u Size; Skip_L3( "0x00025A"); Get_L4 (Size, "Size"); Skip_L4( "0x0000251A"); Get_L4 (Unknown_Length, "Name length"); Info_UTF8(Unknown_Length, Name, "Name"); Skip_L2( "0x0000"); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A"); Skip_L4( "Unknown (same 1/2/3)"); Skip_L4( "Unknown (same 1/2/3)"); Info_L1(Number, "Ordered number"); Element_Info1(Number); Skip_L4( "0x00000000"); Element_Info1(Name); if (Unknown_Length+31!=Size) { Reject(); return; } Element_End(); } Element_End(); Skip_L2( "0x0000"); Skip_L2( "0x0018"); Skip_L4( "0x00000001"); Skip_L2( "0x0018"); Skip_L4( "0x00000001"); Skip_L2( "0x0001"); Skip_L3( "0x00095A"); Get_L4 (Unknown_Length, "Opaque length"); Skip_XX(Unknown_Length, "Opaque"); Skip_L3( "0x00045A"); Skip_L4( "0x00000016"); Skip_L4( "0x06002026"); Skip_L4( "0x00000000"); Skip_L2( "0x0000"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Skip_L4( "0x00000000"); Skip_L3( "0x00025A"); Skip_L4( "0x00000015"); Skip_L4( "0x075A2032"); Skip_L4( "0x00000C00"); Skip_L4( "0x01204200"); Skip_L4( "0x01000000"); Skip_L4( "Unknown"); Skip_L4( "0x00025A00"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Skip_L4( "0x015A0000"); Skip_L4( "Unknown"); Skip_L4( "Unknown"); Skip_L4( "0x01000000"); Get_L4 (FileName_Count, "File name count"); if (13*FileName_Count>Element_Size) { Reject(); return; } Get_L4 (Directory_Length, "Directory length"); Get_UTF8(Directory_Length, Directory, "Directory"); Skip_L4( "0x00000000"); Element_Begin1("File names"); size_t Pos_Offset=0; for (int32u Pos=0; Pos<FileName_Count; Pos++) { Ztring Name; int32u Name_Length, Purpose; Element_Begin1("File names"); Skip_L1( "0x0002"); Skip_L4( "Ordered number except WAV files and -1"); Get_L4 (Name_Length, "Name length"); Get_UTF8(Name_Length, Name, "Name"); Element_Name(Name); Get_C4 (Purpose, "Purpose (e.g. EVAW for .wav files)"); Element_End(); switch (Purpose) { case 0x45564157: if (Pos-Pos_Offset<Names.size() && (Name.find(Names[Pos-Pos_Offset])==0 || Name.find(Names[Pos-Pos_Offset]+__T(".wav"))+5==Name.size())) { File__ReferenceFilesHelper::reference ReferenceFile; ReferenceFile.StreamKind=Stream_Audio; ReferenceFile.FileNames.push_back(Directory+PathSeparator+Name); ReferenceFiles->References.push_back(ReferenceFile); } else if (ReferenceFiles->References.empty()) Pos_Offset++; default: ; } } Element_End(); Skip_XX(Element_Size-Element_Offset, "Unknown"); FILLING_BEGIN(); Accept("Ptx"); //Could be Ptf (former formatn but not supported, so we don't care currently Fill("Ptx"); Fill(Stream_General, 0, General_Format, "Pro Tools Session"); Fill(Stream_General, 0, General_Format_Version, "Version 10"); Fill(Stream_General, 0, General_Encoded_Library_Name, LibraryName); Fill(Stream_General, 0, General_Encoded_Library_Version, LibraryVersion); FILLING_END(); }
//--------------------------------------------------------------------------- void File_Dpx::GenericSectionHeader_Cineon() { Element_Name("Generic section header"); //Parsing Element_Begin1("File information"); Ztring CreationDate, CreationTime; string Version; int32u Size_Header, Size_Total, Size_Generic, Size_Industry, Size_User; Skip_B4( "Magic number"); Get_X4 (Size_Header, "Offset to image data"); Get_X4 (Size_Generic, "Generic section header length"); Get_X4 (Size_Industry, "Industry specific header length"); Get_X4 (Size_User, "User-defined header length"); Get_X4 (Size_Total, "Total image file size"); Get_String(8, Version, "Version number of header format"); Skip_UTF8 (100, "FileName"); Get_UTF8 (12, CreationDate, "Creation Date"); Get_UTF8 (12, CreationTime, "Creation Time"); Skip_XX(36, "Reserved for future use"); Element_End0(); Element_Begin1("Image information"); int8u ImageElements; Info_B1(ImageOrientation, "Image orientation"); Param_Info1(DPX_Orientation[ImageOrientation>8?8:ImageOrientation]); Get_B1 (ImageElements, "Number of image elements"); Skip_B2( "Unused"); if (ImageElements>8) ImageElements=8; for(int8u ImageElement=0; ImageElement<ImageElements; ImageElement++) GenericSectionHeader_Cineon_ImageElement(); if (ImageElements!=8) Skip_XX((8-ImageElements)*28, "Padding"); Skip_BF4( "White point - x"); Skip_BF4( "White point - y"); Skip_BF4( "Red primary chromaticity - x"); Skip_BF4( "Red primary chromaticity - u"); Skip_BF4( "Green primary chromaticity - x"); Skip_BF4( "Green primary chromaticity - y"); Skip_BF4( "Blue primary chromaticity - x"); Skip_BF4( "Blue primary chromaticity - y"); Skip_UTF8(200, "Label text"); Skip_XX(28, "Reserved for future use"); Element_End0(); Element_Begin1("Image Data Format Information"); Skip_B1( "Data interleave"); Skip_B1( "Packing"); Skip_B1( "Data signed or unsigned"); Skip_B1( "Image sense"); Skip_B4( "End of line padding"); Skip_B4( "End of channel padding"); Skip_XX(20, "Reserved for future use"); Element_Begin1("Image Origination Information"); Skip_B4( "X offset"); Skip_B4( "Y offset"); Skip_UTF8 (100, "FileName"); Get_UTF8 (12, CreationDate, "Creation Date"); Get_UTF8 (12, CreationTime, "Creation Time"); Skip_UTF8(64, "Input device"); Skip_UTF8(32, "Input device model number"); Skip_UTF8(32, "Input device serial number"); Skip_BF4( "X input device pitch"); Skip_BF4( "Y input device pitch"); Skip_BF4( "Image gamma of capture device"); Skip_XX(40, "Reserved for future use"); Element_End0(); FILLING_BEGIN(); //Coherency tests if (File_Offset+Buffer_Offset+Size_Total>=Config->File_Current_Size) Size_Total=(int32u)(Config->File_Current_Size-(File_Offset+Buffer_Offset)); //The total size is bigger than the real size if (Size_Generic+Size_Industry+Size_User>Size_Header || Size_Header>Size_Total) { Reject(); return; } //Filling sizes Sizes.push_back(Size_Header); Sizes.push_back(Size_Industry); Sizes.push_back(Size_User); Sizes.push_back(Size_Header-(Size_Generic+Size_Industry+Size_User)); //Size of padding Sizes.push_back(Size_Total-Size_Header); //Size of image //Filling meta if (Frame_Count==0) { Fill(Stream_General, 0, General_Encoded_Date, CreationDate+__T(' ')+CreationTime); //ToDo: transform it in UTC Fill(StreamKind_Last, StreamPos_Last, "Encoded_Date", CreationDate+__T(' ')+CreationTime); //ToDo: transform it in UTC Fill(StreamKind_Last, StreamPos_Last, "Format", "Cineom"); if (Version.size()>2 && Version[0]=='V' && Version[1]>='0' && Version[2]<='9') Version.insert(1, "ersion "); Fill(StreamKind_Last, StreamPos_Last, "Format_Version", Version); Fill(Stream_General, 0, General_Format_Version, Version); } FILLING_END(); }
//--------------------------------------------------------------------------- void File_Ptx::Read_Buffer_Continue() { if (File_Offset || Buffer_Offset) { if (Buffer_Size) Reject(); //Problem return; } //Parsing ZtringList Names; Ztring LibraryName, LibraryVersion, Format, Directory; int32u LibraryName_Length, LibraryVersion_Length, LibraryRelease_Length, Format_Length, Platform_Length, Info_Count, Names_Count, Info_Length, Name_Length, FileName_Count, Directory_Length; int32u Opaque2_Length, Audio_Count; int16u Opaque1_Length; Element_Begin1("Header"); Skip_B1( "Magic"); Skip_Local(16, "Magic"); Skip_L2( "0x0500"); Skip_L1( "Unknown [1]"); Skip_L1( "0x5A [1]"); Skip_L2( "0x0001"); Skip_L2( "0x0004"); Skip_L2( "0x0000 [1]"); Skip_L4( "Unknown [2]"); Skip_L2( "0x035A"); Skip_L2( "0x6400"); Skip_L2( "0x0000 [1]"); Skip_L2( "0x0300"); Skip_L2( "0x0000 [1]"); Get_L4 (LibraryName_Length, "WritingLibrary name length"); Get_UTF8(LibraryName_Length, LibraryName, "Library name"); Skip_L4( "0x00000003"); Skip_L4( "Library version, major"); Skip_L4( "Library version, minor"); Skip_L4( "Library version, revision"); Get_L4 (LibraryVersion_Length, "Library version length"); Get_UTF8(LibraryVersion_Length, LibraryVersion, "Library version"); Skip_L1( "0x01"); Get_L4 (LibraryRelease_Length, "Library release length"); Skip_UTF8(LibraryRelease_Length, "Library release"); Skip_L1( "0x00 [1]"); Get_L4 (Format_Length, "Format length"); Get_UTF8(Format_Length, Format, "Format"); if (Format!=__T("Pro Tools Session File")) { Element_End(); Reject(); return; } Skip_L2( "0x0006"); Get_L4 (Platform_Length, "Platform length"); Skip_UTF8(Platform_Length, "Platform"); Skip_L4( "0x00000000"); Skip_L2( "0x5A05"); Get_L2 (Opaque1_Length, "Info list, Opaque length"); //0x0006 (10.2-) or 0x0008 (10.3+) Skip_L4( "Unknown [3]"); Skip_L4( "0x00002067"); Skip_L2( "0x0000 [1]"); Skip_L2( "0x0000 (once) or 0x002A"); Skip_L2( "0x0000 [1]"); Skip_L2( "Unknown [4]"); Skip_L4( "Unknown [5]"); Skip_L4( "Unknown [6]"); Element_End(); Element_Begin1("Info list"); Get_L4 (Info_Count, "Info count"); if (4*Info_Count>Element_Size) { Element_End(); Reject(); return; } for (int32u Pos=0; Pos<Info_Count; Pos++) { Element_Begin1("Info"); Get_L4 (Info_Length, "Info length"); if (Info_Length) { Info_UTF8(Info_Length, Info, "Name"); Element_Info1(Info); } Element_End(); } Element_End(); Element_Begin1("Unknown"); Skip_L4( "0x00000000"); Element_Begin1("Names list 1"); Get_L4 (Names_Count, "Names count minus 1"); if (4*Names_Count>Element_Size) { Element_End(); Reject(); return; } for (int16u Pos=0; Pos<1+Names_Count; Pos++) { Element_Begin1("Name"); Get_L4 (Name_Length, "Name length"); if (Name_Length) { Info_UTF8(Name_Length, Name, "Name"); Element_Name(Name); } Element_End(); } Element_End(); Skip_L4( "0x00000000"); Skip_L4( "0x00000000 or 0x0000002A"); Skip_L4( "Unknown [7]"); Skip_L4( "Unknown [8]"); Element_Begin1("Names list 2"); Get_L4 (Names_Count, "Names count"); if (4*Names_Count>Element_Size) { Element_End(); Reject(); return; } for (int16u Pos=0; Pos<Names_Count; Pos++) { Element_Begin1("Name"); Get_L4 (Name_Length, "Name length"); if (Name_Length) { Info_UTF8(Name_Length, Name, "Name"); Element_Name(Name); } Element_End(); } Element_End(); Skip_L4( "0x00000000"); Skip_L4( "0x0000002A [1]"); Skip_L4( "Unknown [9]"); Skip_L4( "Unknown [10]"); Skip_L4( "0x00000000"); Skip_L1( "0x00 or 0x01 [2]"); Skip_L1( "0x01"); Skip_L1( "0x00 or 0x01 or 0x02"); Skip_L1( "0x00 [2]"); Skip_L1( "0x01"); Skip_L1( "0x00 (once) or 0x01"); Skip_L1( "0x00 or 0x01 (once)"); Skip_L1( "0x00 or 0x01 (once) or 0x5A"); if (Opaque1_Length<6) { if (Opaque1_Length) Skip_XX(Opaque1_Length, "Opaque1"); } else { Skip_L4( "Opaque1 - Unknown [1]"); Skip_L2( "Opaque1 - Unknown [2]"); if (Opaque1_Length<8) { if (Opaque1_Length-6) Skip_XX(Opaque1_Length-6, "Opaque1 - Unknown [3]"); } else { Skip_L2( "Opaque1 - 0x0000"); if (Opaque1_Length>8) Skip_XX(Opaque1_Length-8, "Opaque1 - Unknown [3]"); } } Skip_L2( "0x2519"); Skip_L2( "0x0001"); Skip_L4( "0x00000000 or B5112287"); Skip_L4( "0x00000000 or 4037F9DC"); Skip_L4( "0x00000001 [1]"); Skip_L2( "0x0003"); Element_End(); Get_L4 (Audio_Count, "Audio count"); if (111*Audio_Count>Element_Size) { Reject(); return; } Element_Begin1("Audio tracks list 1"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); Skip_L2( "0x0000 [New]"); Get_L4 (Name_Length, "(Same 1/2/3) Name length"); Info_UTF8(Name_Length, Name, "(Same 1/2/3) Name"); Skip_L2( "(Same 1/2/3) 0x0000 "); Skip_L4( "(Same 1/2/3) 0x00000000"); Skip_L4( "(Same 1/2/3) 0x0000002A"); Skip_L4( "(Same 1/2/3) Unknown"); Skip_L4( "(Same 1/2/3) Unknown"); Info_L3(Number, "(Same 1/2/3) Ordered number"); Element_Info1(Number); Element_Info1(Name); Element_End(); if (Name==__T("Lf")) //Exception? Typo? Name=__T("Lfe"); Name.MakeLowerCase(); Names.push_back(Name); } Element_End(); Element_Begin1("Audio tracks list 2"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); int32u Size; Skip_L3( "(Same 2/3) 0x00025A [1]"); Get_L4 (Size, "(Same 2/3) Size"); Skip_L4( "(Same 2/3) 0x0000251A"); Get_L4 (Name_Length, "(Same 1/2/3) Name length"); Info_UTF8(Name_Length, Name, "(Same 1/2/3) Name"); Skip_L2( "(Same 1/2/3) 0x0000 "); Skip_L4( "(Same 1/2/3) 0x00000000"); Skip_L4( "(Same 1/2/3) 0x0000002A"); Skip_L4( "(Same 1/2/3) Unknown"); Skip_L4( "(Same 1/2/3) Unknown"); Info_L3(Number, "(Same 1/2/3) Ordered number"); Element_Info1(Number); Skip_L2( "(Same 2/3) 0x0000"); Element_Info1(Name); if (Name_Length+31!=Size) { Element_End(); Element_End(); Reject(); return; } Element_End(); } Element_End(); Get_L4 (Audio_Count, "Audio count"); if (4*Audio_Count>Element_Size) { Reject(); return; } Element_Begin1("Audio tracks list 3"); for (int16u Pos=0; Pos<Audio_Count; Pos++) { Element_Begin1("Name"); int32u Size; Skip_L3( "(Same 2/3) 0x00025A [2]"); Get_L4 (Size, "(Same 2/3) Size"); if (Size>0x10000) { Element_End(); Element_End(); Reject(); return; } Skip_L4( "(Same 2/3) 0x0000251A"); Get_L4 (Name_Length, "(Same 1/2/3) Name length"); Info_UTF8(Name_Length, Name, "(Same 1/2/3) Name"); Skip_L2( "(Same 1/2/3) 0x0000 "); Skip_L4( "(Same 1/2/3) 0x00000000"); Skip_L4( "(Same 1/2/3) 0x0000002A"); Skip_L4( "(Same 1/2/3) Unknown"); Skip_L4( "(Same 1/2/3) Unknown"); Info_L3(Number, "(Same 1/2/3) Ordered number"); Element_Info1(Number); Skip_L2( "(Same 2/3) 0x0000"); Element_Info1(Name); if (Name_Length+31!=Size) { Element_End(); Element_End(); Reject(); return; } Element_End(); } Element_End(); Skip_L2( "0x0000 [4]"); Skip_L2( "0x0018"); Skip_L4( "0x00000001 [2]"); Skip_L2( "0x0018"); Skip_L4( "0x00000001 [2]"); Skip_L2( "0x0001 [3]"); Skip_L3( "0x00095A"); Get_L4 (Opaque2_Length, "Opaque2 length"); Skip_XX(Opaque2_Length, "Opaque2"); Skip_L1( "0x5A [2]"); Skip_L2( "0x0003 (10.0) or 0x0004 (10.2+)"); Get_L4 (Opaque2_Length, "Opaque3 length"); //0x0012 (10.0) or 0x0016 (10.2+) if (Opaque2_Length<0x12) Skip_XX(Opaque2_Length, "Opaque3"); else { Skip_L4( "Opaque3 - 0x06002026"); Skip_L4( "Opaque3 - 0x00000000 [1]"); Skip_L2( "Opaque3 - 0x0000"); Skip_L4( "Opaque3 - Unknown [1]"); Skip_L4( "Opaque3 - Unknown [2]"); if (Opaque2_Length<0x16) { if (Opaque2_Length-0x12) Skip_XX(Opaque2_Length-0x12, "Opaque3 - Unknown [3]"); } else { Skip_L4( "Opaque3 - 0x00000000 [2]"); if (Opaque2_Length>0x16) Skip_XX(Opaque2_Length-0x16, "Opaque3 - Unknown [4]"); } } Skip_L3( "0x00025A [3]"); Get_L4 (Opaque2_Length, "0x00000015 (Opaque4 length?) or something else"); if (Opaque2_Length==0x00000015) { Skip_L4( "0x075A2032"); Skip_L4( "0x00000C00"); Skip_L4( "0x01204200"); Skip_L4( "0x00000000 or 0x01000000"); Skip_L4( "Unknown [13]"); Skip_L1( "0x00 [3]"); Skip_L3( "0x00025A [4]"); Skip_L4( "Unknown [14]"); } Skip_L4( "Unknown [15]"); Skip_L4( "0x015A0000"); Skip_L4( "Unknown [16]"); Skip_L4( "Unknown [17]"); Skip_L4( "0x01000000"); Get_L4 (FileName_Count, "File name count"); if (13*FileName_Count>Element_Size) { Reject(); return; } Get_L4 (Directory_Length, "Directory length"); Get_UTF8(Directory_Length, Directory, "Directory"); Skip_L4( "0x00000000 [11]"); Element_Begin1("File names"); vector<int8u> Roles; vector<Ztring> FileNames; vector<Ztring> FileNamesLowerCase; vector<int32u> Purposes; for (int32u Pos=0; Pos<FileName_Count; Pos++) { Ztring FileName; int32u FileName_Length, Purpose; int8u Role; // Element_Begin1("File names"); Get_L1 (Role, "role? (0x02 for WAV files)"); Skip_L4( "Ordered number except WAV files and -1"); Get_L4 (FileName_Length, "File Name length"); Get_UTF8(FileName_Length, FileName, "File Name"); Element_Name(FileName); Get_C4 (Purpose, "Purpose (e.g. EVAW for .wav files)"); //Found 1 .wav file without "EWAV". Element_End(); Roles.push_back(Role); FileNames.push_back(FileName); FileName.MakeLowerCase(); FileNamesLowerCase.push_back(FileName); Purposes.push_back(Purpose); } Element_End(); Skip_XX(Element_Size-Element_Offset, "Unknown"); FILLING_BEGIN(); Accept("Ptx"); //Could be Ptf (former format but not supported, so we don't care currently) Fill("Ptx"); Fill(Stream_General, 0, General_Format, "Pro Tools Session"); Fill(Stream_General, 0, General_Format_Version, "Version 10"); Fill(Stream_General, 0, General_Encoded_Library_Name, LibraryName); Fill(Stream_General, 0, General_Encoded_Library_Version, LibraryVersion); // Role==2 + Purpose==EWAV + listed if (Names.size()>1 || FileNames.size()==1) { size_t Pos_Offset=0; for (int32u Pos=0; Pos<FileName_Count; Pos++) { if (Roles[Pos]==0x02 && Purposes[Pos]==0x45564157 //"EWAV" && Pos-Pos_Offset<Names.size() && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception? && FileNames[Pos].find(__T("_1KTONE_"))==string::npos //Exception? && FileNamesLowerCase[Pos].find(Names[Pos-Pos_Offset]+__T(".wav"))!=string::npos && FileNamesLowerCase[Pos].find(Names[Pos-Pos_Offset]+__T(".wav"))+Names[Pos-Pos_Offset].size()+4==FileNames[Pos].size()) { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Audio; Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]); ReferenceFiles->AddSequence(Sequence); } else if (!ReferenceFiles->Sequences_Size()) Pos_Offset++; } if (Names.size()!=ReferenceFiles->Sequences_Size()) ReferenceFiles->Clear(); //Failed to detect correctly } // Role==2 + listed if (!ReferenceFiles->Sequences_Size() && (Names.size()>1 || FileNames.size()==1)) { size_t Pos_Offset=0; for (int32u Pos=0; Pos<FileName_Count; Pos++) { if (Roles[Pos]==0x02 && Pos-Pos_Offset<Names.size() && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception? && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception? { Ztring FileName=FileNames[Pos]; Ztring Name=Names[Pos-Pos_Offset]; FileName.MakeLowerCase(); Name.MakeLowerCase(); if (FileName.find(Name)==0 || FileName.find(Name+__T(".wav"))+5==Name.size()) { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Audio; Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]); ReferenceFiles->AddSequence(Sequence); } else if (!ReferenceFiles->Sequences_Size()) Pos_Offset++; } else if (!ReferenceFiles->Sequences_Size()) Pos_Offset++; } if (Names.size()!=ReferenceFiles->Sequences_Size()) ReferenceFiles->Clear(); //Failed to detect correctly } // Role==2 + Purpose==EWAV + listed, special case with specific file names if (!ReferenceFiles->Sequences_Size() && (Names.size()>1 || FileNames.size()==1)) { for (int32u Pos=0; Pos<FileName_Count; Pos++) { if (Roles[Pos]==0x02 && Purposes[Pos]==0x45564157 //"EWAV" && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception? && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception? { for (int32u Pos2=0; Pos2<Names.size(); Pos2++) if (FileNamesLowerCase[Pos].find(Names[Pos2])==0) { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Audio; Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]); ReferenceFiles->AddSequence(Sequence); break; } } } } // Role==2 + Purpose==EWAV if (!ReferenceFiles->Sequences_Size()) { for (int32u Pos=0; Pos<FileName_Count; Pos++) { if (Roles[Pos]==0x02 && Purposes[Pos]==0x45564157 //"EWAV" && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception? && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception? { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Audio; Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]); ReferenceFiles->AddSequence(Sequence); } } } // Role==2 if (!ReferenceFiles->Sequences_Size()) { for (int32u Pos=0; Pos<FileName_Count; Pos++) { if (Roles[Pos]==0x02 && FileNames[Pos]!=__T("1 kHz @ -20dB.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos]!=__T("1k@0vu -20.wav") //Exception? && FileNames[Pos]!=__T("*****@*****.**") //Exception? && FileNames[Pos].find(__T(".1Khz.wav"))==string::npos //Exception? && FileNames[Pos].find(__T("_1KTONE_"))==string::npos) //Exception? { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Audio; Sequence->AddFileName(Directory+PathSeparator+FileNames[Pos]); ReferenceFiles->AddSequence(Sequence); } } } FILLING_END(); }
//--------------------------------------------------------------------------- void File_ApeTag::Data_Parse() { //If footer if (Element_Code==(int64u)-1) { HeaderFooter(); Finish("ApeTag"); return; } //Parsing Ztring Value; Get_UTF8(Element_Size, Value, "Value"); Element_Info(Value); //Filling transform(Key.begin(), Key.end(), Key.begin(), (int(*)(int))toupper); //(int(*)(int)) is a patch for unix if (Key=="ALBUM") Fill(Stream_General, 0, General_Album, Value); else if (Key=="ARTIST") Fill(Stream_General, 0, General_Performer, Value); else if (Key=="AUTHOR") Fill(Stream_General, 0, General_WrittenBy, Value); else if (Key=="BAND") Fill(Stream_General, 0, General_Performer, Value); else if (Key=="COMMENT") Fill(Stream_General, 0, General_Comment, Value); else if (Key=="COMMENTS") Fill(Stream_General, 0, General_Comment, Value); else if (Key=="COMPOSER") Fill(Stream_General, 0, General_Composer, Value); else if (Key=="CONTENTGROUP") Fill(Stream_General, 0, General_Genre, Value); else if (Key=="COPYRIGHT") Fill(Stream_General, 0, General_Copyright, Value); else if (Key=="DISK") { if (Value.find(_T("/"))!=Error) { Fill(Stream_General, 0, General_Part_Position_Total, Value.SubString(_T("/"), _T(""))); Fill(Stream_General, 0, General_Part_Position, Value.SubString(_T(""), _T("/"))); } else Fill(Stream_General, 0, General_Track_Position, Value); } else if (Key=="ENCODEDBY") Fill(Stream_General, 0, General_EncodedBy, Value); else if (Key=="GENRE") Fill(Stream_General, 0, General_Genre, Value); else if (Key=="ORIGARTIST") Fill(Stream_General, 0, General_Original_Performer, Value); else if (Key=="TITLE") Fill(Stream_General, 0, General_Title, Value); else if (Key=="TRACK") { if (Value.find(_T("/"))!=Error) { Fill(Stream_General, 0, General_Track_Position_Total, Value.SubString(_T("/"), _T(""))); Fill(Stream_General, 0, General_Track_Position, Value.SubString(_T(""), _T("/"))); } else Fill(Stream_General, 0, General_Track_Position, Value); } else if (Key=="UNSYNCEDLYRICS") Fill(Stream_General, 0, General_Lyrics, Value); else if (Key=="WWW") Fill(Stream_General, 0, General_Title_Url, Value); else if (Key=="YEAR") Fill(Stream_General, 0, General_Recorded_Date, Value); else if (Key=="CONTENT GROUP DESCRIPTION") Fill(Stream_General, 0, General_Title, Value); else if (Key=="ORIGINAL ALBUM/MOVIE/SHOW TITLE") Fill(Stream_General, 0, General_Original_Album, Value); else if (Key=="ORIGINAL ARTIST(S)/PERFORMER(S)") Fill(Stream_General, 0, General_Original_Performer, Value); else if (Key=="MP3GAIN_MINMAX") Fill(Stream_Audio, 0, "MP3Gain, Min/Max", Value); else if (Key=="MP3GAIN_UNDO") Fill(Stream_Audio, 0, "MP3Gain, Undo", Value); else if (Key=="REPLAYGAIN_TRACK_GAIN") Fill(Stream_Audio, 0, Audio_ReplayGain_Gain, Value.To_float64(), 2, true); else if (Key=="REPLAYGAIN_TRACK_PEAK") Fill(Stream_Audio, 0, Audio_ReplayGain_Peak, Value.To_float64(), 6, true); else Fill(Stream_General, 0, Key.c_str(), Value); }