//--------------------------------------------------------------------------- void File_Rm::RJMD_property(std::string Name) { //Element_Name("Property"); //Parsing Ztring value; std::string name; int32u type, flags, num_subproperties, name_length, value_length; Element_Begin1("MetadataProperty"); Skip_B4( "size"); Get_B4 (type, "type"); Get_B4 (flags, "flags"); Skip_Flags(flags, 0, "readonly"); //Read only, cannot be modified. Skip_Flags(flags, 1, "private"); //Private, do not expose to users. Skip_Flags(flags, 2, "type_dexcriptor"); //Type descriptor used to further define type of value. Skip_B4( "value_offset"); //The offset to the value_length , relative to the beginning of the MetadataProperty structure. Skip_B4( "subproperties_offset"); //The offset to the subproperties_list , relative to the beginning of the MetadataProperty structure. Get_B4 (num_subproperties, "num_subproperties"); //The number of subproperties for this MetadataProperty structure. Get_B4 (name_length, "name_length"); //The length of the name data, including the null-terminator. Get_String(name_length, name, "name"); //The name of the property (string data). Get_B4 (value_length, "value_length"); //The length of the value data. switch(type) { case 0x00 : //Nothing Skip_XX(value_length, "Junk"); break; case 0x01 : //String (text). Get_Local(value_length, value, "value"); //String. break; case 0x02 : //Separated list of strings, separator specified as sub-property/type descriptor. Get_Local(value_length, value, "value"); //String. break; case 0x03 : //Boolean flag—either 1 byte or 4 bytes, check size value. switch(value_length) { case 1 : { int8u valueI; Get_L1(valueI, "value"); //1-byte boolean. value.From_Number(valueI); } break; case 4 : { int32u valueI; Get_L4(valueI, "value"); //4-byte boolean. value.From_Number(valueI); } break; default: Skip_XX(value_length, "Unknown"); } break; case 0x04 : //Four-byte integer. { int32u valueI; Get_L4(valueI, "value"); value.From_Number(valueI); } break; case 0x05 : //Byte stream. Skip_XX(value_length, "Byte stream"); break; case 0x06 : //String (URL). Get_Local(value_length, value, "value"); //String. break; case 0x07 : //String representation of the date in the form: YYYYmmDDHHMMSS (m = month, M = minutes). Get_Local(value_length, value, "value"); //String. break; case 0x08 : //String (file name) Get_Local(value_length, value, "value"); //String. break; case 0x09 : //This property has subproperties, but its own value is empty. Skip_XX(value_length, "junk"); break; case 0x0A : //Large buffer of data, use sub-properties/type descriptors to identify mime-type. Skip_XX(value_length, "data"); break; default : //Unknown Skip_XX(value_length, "unknown"); break; } //Filling if (!Name.empty()) Name+='/'; Name+=name; if (Name!="Track/Comments/DataSize" && Name!="Track/Comments/MimeType" ) Fill(Stream_General, 0, Name.c_str(), value); //Parsing for (int32u Pos=0; Pos<num_subproperties; Pos++) { Element_Begin1("PropListEntry"); Skip_B4( "offset"); //The offset for this indexed sub-property, relative to the beginning of the containing MetadataProperty. Skip_B4( "num_props_for_name"); //The number of sub-properties that share the same name. For example, a lyrics property could have multiple versions as differentiated by the language sub-property type descriptor. Element_End0(); } for (int32u Pos=0; Pos<num_subproperties; Pos++) { RJMD_property(Name); } Element_End0(); }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=__T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles_Accept(this, Config); #if defined(MEDIAINFO_REFERENCES_YES) XMLElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { sequence* Sequence=new sequence; Attribute=Track->Attribute("file"); if (Attribute) { Sequence->AddFileName(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } Attribute=Track->Attribute("source"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("main")) Sequence->IsMain=true; } Attribute=Track->Attribute("default_timecode"); if (Attribute) { Sequence->Config["File_DefaultTimeCode"].From_UTF8(Attribute); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { Sequence->FrameRate_Set(Ztring().From_UTF8(Attribute).To_float64()); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==__T("video")) Sequence->StreamKind=Stream_Video; if (StreamKind==__T("audio")) Sequence->StreamKind=Stream_Audio; if (StreamKind==__T("data")) Sequence->StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } XMLElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) Sequence->AddFileName(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } Track=Track->NextSiblingElement(); } #endif //MEDIAINFO_REFERENCES_YES } else { Reject("DXW"); return false; } } Element_Offset=File_Size; //All should be OK... return true; }
namespace ZenLib { //*************************************************************************** // OS info //*************************************************************************** //--------------------------------------------------------------------------- bool IsWin9X () { #ifdef ZENLIB_USEWX return true; #else //ZENLIB_USEWX #ifdef WINDOWS if (GetVersion()<0x80000000) return false; else return true; #else //WINDOWS return true; #endif #endif //ZENLIB_USEWX } //*************************************************************************** // Shell //*************************************************************************** void Shell_Execute(const Ztring &ToExecute) { #ifdef ZENLIB_USEWX #else //ZENLIB_USEWX #ifdef WINDOWS #ifdef UNICODE if (IsWin9X()) ShellExecuteA(NULL, "open", ToExecute.To_Local().c_str(), NULL, NULL, 0); else ShellExecute (NULL, _T("open"), ToExecute.c_str(), NULL, NULL, 0); #else ShellExecute(NULL, _T("open"), ToExecute.c_str(), NULL, NULL, 0); #endif #else //Not supported #endif #endif //ZENLIB_USEWX } //*************************************************************************** // Directories //*************************************************************************** //--------------------------------------------------------------------------- // Select directory code // Extracted from TBffolder by Torsten Johann ([email protected]) Ztring Directory_Select_Caption; #ifdef WINDOWS #ifdef UNICODE char InitDirA[MAX_PATH]; wchar_t InitDir [MAX_PATH]; int __stdcall ShowOpenFolder_CallbackProc (HWND hwnd, UINT uMsg, LPARAM, LPARAM) { if (uMsg==BFFM_INITIALIZED) { if (IsWin9X()) { SetWindowTextA (hwnd, Directory_Select_Caption.To_Local().c_str()); // Caption SendMessageA (hwnd, BFFM_ENABLEOK, 0, TRUE); SendMessageA (hwnd, BFFM_SETSELECTION, true, (LPARAM)&InitDirA); } else { SetWindowText (hwnd, Directory_Select_Caption.c_str()); // Caption SendMessage (hwnd, BFFM_ENABLEOK, 0, TRUE); SendMessage (hwnd, BFFM_SETSELECTION, true, (LPARAM)&InitDir); } } return 0; } Ztring OpenFolder_Show(void* Handle, const Ztring &Title, const Ztring &Caption) { //Caption Directory_Select_Caption=Caption; if (IsWin9X()) { return Ztring(); //Not supported in Win9X } else { //Values LPMALLOC Malloc; LPSHELLFOLDER ShellFolder; BROWSEINFO BrowseInfo; LPITEMIDLIST ItemIdList; //Initializing the SHBrowseForFolder function if (SHGetMalloc(&Malloc)!=NOERROR) return Ztring(); if (SHGetDesktopFolder(&ShellFolder)!=NOERROR) return Ztring(); ZeroMemory(&BrowseInfo, sizeof(BROWSEINFOW)); BrowseInfo.ulFlags+=BIF_RETURNONLYFSDIRS; BrowseInfo.hwndOwner=(HWND)Handle; BrowseInfo.pszDisplayName=InitDir; BrowseInfo.lpszTitle=Title.c_str(); BrowseInfo.lpfn=ShowOpenFolder_CallbackProc; //Displaying ItemIdList=SHBrowseForFolder(&BrowseInfo); //Releasing ShellFolder->Release(); if (ItemIdList!=NULL) { SHGetPathFromIDList(ItemIdList, InitDir); Malloc->Free(ItemIdList); Malloc->Release(); //The value return InitDir; } else return Ztring(); } } #else char InitDirA[MAX_PATH]; int __stdcall ShowOpenFolder_CallbackProc (HWND hwnd, UINT uMsg, LPARAM, LPARAM) { if (uMsg==BFFM_INITIALIZED) { SetWindowText (hwnd, Directory_Select_Caption.c_str()); // Caption SendMessage (hwnd, BFFM_ENABLEOK, 0, TRUE); SendMessage (hwnd, BFFM_SETSELECTION, true, (LPARAM)&InitDirA); } return 0; } Ztring OpenFolder_Show(void* Handle, const Ztring &Title, const Ztring &Caption) { //Caption Directory_Select_Caption=Caption; //Values LPMALLOC Malloc; LPSHELLFOLDER ShellFolder; BROWSEINFO BrowseInfo; LPITEMIDLIST ItemIdList; //Initializing the SHBrowseForFolder function if (SHGetMalloc(&Malloc)!=NOERROR) return Ztring(); if (SHGetDesktopFolder(&ShellFolder)!=NOERROR) return Ztring(); ZeroMemory(&BrowseInfo, sizeof(BROWSEINFO)); BrowseInfo.ulFlags+=BIF_RETURNONLYFSDIRS; BrowseInfo.hwndOwner=(HWND)Handle; BrowseInfo.pszDisplayName=InitDirA; BrowseInfo.lpszTitle=Title.c_str(); BrowseInfo.lpfn=ShowOpenFolder_CallbackProc; //Displaying ItemIdList=SHBrowseForFolder(&BrowseInfo); //Releasing ShellFolder->Release(); if (ItemIdList!=NULL) { SHGetPathFromIDList(ItemIdList, InitDirA); Malloc->Free(ItemIdList); Malloc->Release(); //The value return InitDirA; } else return Ztring(); } #endif //UNICODE #endif //WINDOWS } //namespace ZenLib
//--------------------------------------------------------------------------- bool File_Hls::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024 || File_Size<10) { Reject("HLS"); return false; //HLS files are not big } if (Buffer_Size<File_Size) return false; //Wait for complete file Ztring Document; Document.From_UTF8((char*)Buffer, Buffer_Size); ZtringList Lines; size_t LinesSeparator_Pos=Document.find_first_of(__T("\r\n")); if (LinesSeparator_Pos>File_Size-1) { Reject("HLS"); return false; } Ztring LinesSeparator; if (Document[LinesSeparator_Pos]==__T('\r') && LinesSeparator_Pos+1<Document.size() && Document[LinesSeparator_Pos+1]==__T('\n')) LinesSeparator=__T("\r\n"); else if (Document[LinesSeparator_Pos]==__T('\r')) LinesSeparator=__T("\r"); else if (Document[LinesSeparator_Pos]==__T('\n')) LinesSeparator=__T("\n"); else { Reject("HLS"); return false; } Lines.Separator_Set(0, LinesSeparator); Lines.Write(Document); if (Lines(0)!=__T("#EXTM3U")) { Reject("HLS"); return false; } Accept("HLS"); Fill(Stream_General, 0, General_Format, "HLS"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); if (!IsSub) ReferenceFiles->ContainerHasNoId=true; File__ReferenceFilesHelper::reference ReferenceFile; bool IsGroup=false; for (size_t Line=0; Line<Lines.size(); Line++) { if (!Lines[Line].empty()) { if (Lines[Line].find(__T("#EXT-X-KEY:"))==0) { ZtringListList List; List.Separator_Set(0, __T(",")); List.Separator_Set(1, __T("=")); List.Write(Lines[Line].substr(11, string::npos)); for (size_t Pos=0; Pos<List.size(); ++Pos) { if (List[Pos](0)==__T("METHOD")) { if (List[Pos](1).find(__T("AES-128"))==0) { Fill(Stream_General, 0, General_Encryption_Format, "AES"); Fill(Stream_General, 0, General_Encryption_Length, "128"); Fill(Stream_General, 0, General_Encryption_Method, "Segment"); Fill(Stream_General, 0, General_Encryption_Mode, "CBC"); Fill(Stream_General, 0, General_Encryption_Padding, "PKCS7"); Fill(Stream_General, 0, General_Encryption_InitializationVector, "Sequence number"); #if MEDIAINFO_AES //Trying to get the key from FileName.FileExt.key if (Config->Encryption_Key_Get().empty()) { File KeyFile; if (KeyFile.Open(File_Name+__T(".key"))) { if (KeyFile.Size_Get()==16) { int8u Key[16]; if (KeyFile.Read(Key, 16)==16) Config->Encryption_Key_Set(Key, 16); } else Fill(Stream_General, 0, "Encryption_Key_Problem", KeyFile.Size_Get()); } } #endif } Fill(Stream_General, 0, General_Encryption, List[Pos](1)); } } } else if (Lines[Line].find(__T("#EXT-X-STREAM-INF:"))==0) { IsGroup=true; } else if (Lines[Line][0]==__T('#')) ; else { if (IsGroup) { ReferenceFile.FileNames.push_back(Lines[Line]); ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); IsGroup=false; ReferenceFile=File__ReferenceFilesHelper::reference(); #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_HlsIndex; StreamIDs_Width[0]=sizeof(size_t); #endif //MEDIAINFO_EVENTS } else ReferenceFile.FileNames.push_back(Lines[Line]); } } } if (!ReferenceFile.FileNames.empty()) { ReferenceFiles->References.push_back(ReferenceFile); Fill(Stream_General, 0, General_Format_Profile, "Media"); } else { Fill(Stream_General, 0, General_Format_Profile, "Master"); } Element_Offset=File_Size; //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Id3::Read_Buffer_Continue() { //Buffer size if (Buffer_Size<128) return; int32u Magic; Peek_B4(Magic); Ztring TitleAddition; Ztring ArtistAddition; Ztring AlbumAddition; Ztring GenreAddition; if (Magic==0x5441472B) { if (Buffer_Size<227+128) return; Skip_C4 ( "ID"); Get_Local (60, TitleAddition, "Title"); Get_Local (60, ArtistAddition, "Artist"); Get_Local (60, AlbumAddition, "Album"); Skip_B1 ( "Speed"); Get_Local (30, GenreAddition, "Genre"); Skip_Local(6, "Start time"); //mmm:ss Skip_Local(6, "End time"); //mmm:ss TitleAddition.TrimRight(); ArtistAddition.TrimRight(); AlbumAddition.TrimRight(); GenreAddition.TrimRight(); } //Parsing Ztring Title, Artist, Album, Year, Comment; int8u Track=0, Genre; Skip_C3 ( "ID"); Get_Local (30, Title, "Title"); Get_Local (30, Artist, "Artist"); Get_Local (30, Album, "Album"); Get_Local ( 4, Year, "Year"); Get_Local (30, Comment, "Comment"); if (Comment.size()<29) //Id3v1.1 specifications : Track number addition { Element_Offset-=2; int8u Zero; Peek_B1(Zero); if (Zero==0) { Skip_B1( "Zero"); Get_B1 (Track, "Track"); } else Element_Offset+=2; } Get_B1 (Genre, "Genre"); FILLING_BEGIN(); if (TitleAddition.empty()) Title.TrimRight(); if (ArtistAddition.empty()) Artist.TrimRight(); if (AlbumAddition.empty()) Album.TrimRight(); Year.TrimRight(); Comment.TrimRight(); Accept("Id3"); Stream_Prepare(Stream_General); Fill(Stream_General, 0, General_Album, Album+AlbumAddition); Fill(Stream_General, 0, General_Track, Title+TitleAddition); Fill(Stream_General, 0, General_Performer, Artist+ArtistAddition); Fill(Stream_General, 0, General_Comment, Comment); Fill(Stream_General, 0, General_Recorded_Date, Year); if (GenreAddition.empty()) Fill(Stream_General, 0, General_Genre, GenreAddition); if (Genre && Genre!=(int8u)-1) Fill(Stream_General, 0, General_Genre, Genre); if (Track) Fill(Stream_General, 0, General_Track_Position, Track); Finish("Id3"); FILLING_END(); }
//--------------------------------------------------------------------------- Ztring Export_PBCore::Transform(MediaInfo_Internal &MI) { //Current date/time is ISO format time_t Time=time(NULL); Ztring TimeS; TimeS.Date_From_Seconds_1970((int32u)Time); TimeS.FindAndReplace(__T("UTC "), __T("")); TimeS.FindAndReplace(__T(" "), __T("T")); TimeS+=__T('Z'); Ztring ToReturn; ToReturn+=__T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); ToReturn+=__T("<PBCoreDescriptionDocument xsi:schemaLocation=\"http://www.pbcore.org/PBCore/PBCoreNamespace.html http://www.pbcore.org/PBCore/PBCoreXSD_Ver_1-2-1.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.pbcore.org/PBCore/PBCoreNamespace.html\">\n"); ToReturn+=__T("\t<!-- Generated at ")+TimeS+__T(" by ")+MediaInfoLib::Config.Info_Version_Get()+__T(" -->\n"); ToReturn+=__T("\t<!-- Warning: MediaInfo outputs only pbcoreInstantiation, other mandatory PBCore data is junk -->\n"); ToReturn+=__T("\t<pbcoreIdentifier>\n"); ToReturn+=__T("\t\t<identifier>***</identifier>\n"); ToReturn+=__T("\t\t<identifierSource>***</identifierSource>\n"); ToReturn+=__T("\t</pbcoreIdentifier>\n"); ToReturn+=__T("\t<pbcoreTitle>\n"); ToReturn+=__T("\t\t<title>***</title>\n"); ToReturn+=__T("\t</pbcoreTitle>\n"); ToReturn+=__T("\t<pbcoreDescription>\n"); ToReturn+=__T("\t\t<description>***</description>\n"); ToReturn+=__T("\t\t<descriptionType>***</descriptionType>\n"); ToReturn+=__T("\t</pbcoreDescription>\n"); ToReturn+=__T("\t<pbcoreInstantiation>\n"); //pbcoreFormatID ToReturn+=__T("\t\t<pbcoreFormatID>\n"); //formatIdentifier ToReturn+=__T("\t\t\t<formatIdentifier>")+MI.Get(Stream_General, 0, General_FileName)+__T("</formatIdentifier>\n"); //formatIdentifierSource ToReturn+=__T("\t\t\t<formatIdentifierSource version=\"PBCoreXSD_Ver_1.2_D1\">File Name</formatIdentifierSource>\n"); ToReturn+=__T("\t\t</pbcoreFormatID>\n"); //formatDigital if (!MI.Get(Stream_General, 0, General_InternetMediaType).empty()) { ToReturn+=__T("\t\t<formatDigital>"); ToReturn+=MI.Get(Stream_General, 0, General_InternetMediaType); ToReturn+=__T("</formatDigital>\n"); } else { //TODO: how to implement formats without Media Type? ToReturn+=__T("\t\t<formatDigital>"); if (MI.Count_Get(Stream_Video)) ToReturn+=__T("video/x-"); else if (MI.Count_Get(Stream_Image)) ToReturn+=__T("image/x-"); else if (MI.Count_Get(Stream_Audio)) ToReturn+=__T("audio/x-"); else ToReturn+=__T("application/x-"); ToReturn+=Ztring(MI.Get(Stream_General, 0, __T("Format"))).MakeLowerCase(); ToReturn+=__T("</formatDigital>\n"); } //formatLocation ToReturn+=__T("\t\t<formatLocation>")+MI.Get(Stream_General, 0, General_CompleteName)+__T("</formatLocation>\n"); //dateCreated if (!MI.Get(Stream_General, 0, General_Encoded_Date).empty()) { Ztring dateCreated=MI.Get(Stream_General, 0, General_Recorded_Date); dateCreated.FindAndReplace(__T("UTC"), __T("-")); dateCreated.FindAndReplace(__T(" "), __T("T")); dateCreated+=__T('Z'); ToReturn+=__T("\t\t<dateCreated>")+dateCreated+__T("</dateCreated>\n"); } //dateIssued if (!MI.Get(Stream_General, 0, General_Recorded_Date).empty()) { Ztring dateIssued=MI.Get(Stream_General, 0, General_Recorded_Date); dateIssued.FindAndReplace(__T("UTC"), __T("-")); dateIssued.FindAndReplace(__T(" "), __T("T")); dateIssued+=__T('Z'); ToReturn+=__T("\t\t<dateIssued>")+dateIssued+__T("</dateIssued>\n"); } //formatMediaType if (!PBCore_MediaType(MI).empty()) ToReturn+=__T("\t\t<formatMediaType version=\"PBCoreXSD_Ver_1.2_D1\">")+PBCore_MediaType(MI)+__T("</formatMediaType>\n"); else ToReturn+=__T("\t\t<formatMediaType version=\"PBCoreXSD_Ver_1.2_D1\">application/octet-stream</formatMediaType>\n"); //formatGenerations ToReturn+=__T("\t\t<formatGenerations version=\"PBCoreXSD_Ver_1.2_D1\" />\n"); //formatFileSize if (!MI.Get(Stream_General, 0, General_FileSize).empty()) ToReturn+=__T("\t\t<formatFileSize>")+MI.Get(Stream_General, 0, General_FileSize)+__T("</formatFileSize>\n"); //formatTimeStart if (!MI.Get(Stream_Video, 0, Video_Delay_Original_String3).empty()) ToReturn+=__T("\t\t<formatTimeStart>")+MI.Get(Stream_Video, 0, Video_Delay_Original_String3)+__T("</formatTimeStart>\n"); else if (!MI.Get(Stream_Video, 0, Video_Delay_String3).empty()) ToReturn+=__T("\t\t<formatTimeStart>")+MI.Get(Stream_Video, 0, Video_Delay_String3)+__T("</formatTimeStart>\n"); //formatDuration if (!MI.Get(Stream_General, 0, General_Duration_String3).empty()) ToReturn+=__T("\t\t<formatDuration>")+MI.Get(Stream_General, 0, General_Duration_String3)+__T("</formatDuration>\n"); //formatDataRate if (!MI.Get(Stream_General, 0, General_OverallBitRate).empty()) { ToReturn+=__T("\t\t<formatDataRate>"); ToReturn+=MI.Get(Stream_General, 0, General_OverallBitRate); if (!MI.Get(Stream_General, 0, General_OverallBitRate_Mode).empty()) ToReturn+=__T(' ')+MI.Get(Stream_General, 0, General_OverallBitRate_Mode); ToReturn+=__T("</formatDataRate>\n"); } //formatTracks ToReturn+=__T("\t\t<formatTracks>")+Ztring::ToZtring(MI.Count_Get(Stream_Video)+MI.Count_Get(Stream_Audio)+MI.Count_Get(Stream_Image)+MI.Count_Get(Stream_Text))+__T("</formatTracks>\n"); //Video streams for (size_t StreamPos=0; StreamPos<MI.Count_Get(Stream_Video); StreamPos++) PBCore_Transform_Video(ToReturn, MI, StreamPos); //Audio streams for (size_t StreamPos=0; StreamPos<MI.Count_Get(Stream_Audio); StreamPos++) PBCore_Transform_Audio(ToReturn, MI, StreamPos); //Text streams for (size_t StreamPos=0; StreamPos<MI.Count_Get(Stream_Text); StreamPos++) PBCore_Transform_Text(ToReturn, MI, StreamPos); //Menu streams for (size_t StreamPos=0; StreamPos<MI.Count_Get(Stream_Menu); StreamPos++) PBCore_Transform_Menu(ToReturn, MI, StreamPos); ToReturn+=__T("\t</pbcoreInstantiation>\n"); ToReturn+=__T("</PBCoreDescriptionDocument>\n"); //Carriage return ToReturn.FindAndReplace(__T("\n"), EOL, 0, Ztring_Recursive); return ToReturn; }
//--------------------------------------------------------------------------- bool File_DcpCpl::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; XMLElement* Root=document.FirstChildElement(); const char *NameSpace; if (!Root || strcmp(LocalName(Root, NameSpace), "CompositionPlaylist")) { Reject("DcpCpl"); return false; } bool IsDcp=false, IsImf=false; if (!strcmp(NameSpace, "http://www.digicine.com/PROTO-ASDCP-CPL-20040511#") || !strcmp(NameSpace, "http://www.smpte-ra.org/schemas/429-7/2006/CPL")) { IsDcp=true; } else if (IsSmpteSt2067_3(NameSpace)) { IsImf=true; } else { Reject("DcpCpl"); return false; } Accept("DcpCpl"); Fill(Stream_General, 0, General_Format, IsDcp?"DCP CPL":"IMF CPL"); Config->File_ID_OnlyRoot_Set(false); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); //Parsing main elements for (XMLElement* CompositionPlaylist_Item=Root->FirstChildElement(); CompositionPlaylist_Item; CompositionPlaylist_Item=CompositionPlaylist_Item->NextSiblingElement()) { const char* CompositionPlaylist_Item_Value=CompositionPlaylist_Item->Value(); if (!CompositionPlaylist_Item_Value) continue; //CompositionTimecode if (IsImf && MatchQName(CompositionPlaylist_Item, "CompositionTimecode", NameSpace)) { sequence* Sequence=new sequence; Sequence->StreamKind=Stream_Other; Sequence->Infos["Type"]=__T("Time code"); Sequence->Infos["Format"]=__T("CPL TC"); Sequence->Infos["TimeCode_Striped"]=__T("Yes"); bool IsDropFrame=false; for (XMLElement* CompositionTimecode_Item=CompositionPlaylist_Item->FirstChildElement(); CompositionTimecode_Item; CompositionTimecode_Item=CompositionTimecode_Item->NextSiblingElement()) { const char* Text=CompositionTimecode_Item->GetText(); if (!Text) continue; const char *CtItemNs, *CtItemName = LocalName(CompositionTimecode_Item, CtItemNs); if (!CtItemNs || strcmp(CtItemNs, NameSpace)) continue; // item has wrong namespace //TimecodeDropFrame if (!strcmp(CtItemName, "TimecodeDropFrame")) { if (strcmp(Text, "") && strcmp(Text, "0")) IsDropFrame=true; } //TimecodeRate if (!strcmp(CtItemName, "TimecodeRate")) Sequence->Infos["FrameRate"].From_UTF8(Text); //TimecodeStartAddress if (!strcmp(CtItemName, "TimecodeStartAddress")) Sequence->Infos["TimeCode_FirstFrame"].From_UTF8(Text); } //Adaptation if (IsDropFrame) { std::map<string, Ztring>::iterator Info=Sequence->Infos.find("TimeCode_FirstFrame"); if (Info!=Sequence->Infos.end() && Info->second.size()>=11 && Info->second[8]!=__T(';')) Info->second[8]=__T(';'); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); Stream_Prepare(Stream_Other); Fill(Stream_Other, StreamPos_Last, Other_ID, Sequence->StreamID); for (std::map<string, Ztring>::iterator Info=Sequence->Infos.begin(); Info!=Sequence->Infos.end(); ++Info) Fill(Stream_Other, StreamPos_Last, Info->first.c_str(), Info->second); } #if MEDIAINFO_ADVANCED //EssenceDescriptorList if (IsImf && !strcmp(CompositionPlaylist_Item_Value, "EssenceDescriptorList")) { for (XMLElement* EssenceDescriptorList_Item=CompositionPlaylist_Item->FirstChildElement(); EssenceDescriptorList_Item; EssenceDescriptorList_Item=EssenceDescriptorList_Item->NextSiblingElement()) { const char* EssenceDescriptorList_Item_Value=EssenceDescriptorList_Item->Value(); if (!EssenceDescriptorList_Item_Value) continue; //TimecodeDropFrame if (!strcmp(EssenceDescriptorList_Item_Value, "EssenceDescriptor")) { string Id; descriptor* Descriptor=new descriptor; for (XMLElement* EssenceDescriptor_Item=EssenceDescriptorList_Item->FirstChildElement(); EssenceDescriptor_Item; EssenceDescriptor_Item=EssenceDescriptor_Item->NextSiblingElement()) { const char* EssenceDescriptor_Item_Value=EssenceDescriptor_Item->Value(); const char* EssenceDescriptor_Item_Text=EssenceDescriptor_Item->GetText(); if (!EssenceDescriptor_Item_Value) continue; //Id if (EssenceDescriptor_Item_Text && !strcmp(EssenceDescriptor_Item_Value, "Id")) Id=EssenceDescriptor_Item_Text; //CDCIDescriptor if (!strcmp(EssenceDescriptor_Item_Value, "m:RGBADescriptor") || !strcmp(EssenceDescriptor_Item_Value, "m:CDCIDescriptor")) { for (XMLElement* Descriptor_Item=EssenceDescriptor_Item->FirstChildElement(); Descriptor_Item; Descriptor_Item=Descriptor_Item->NextSiblingElement()) { const char* Descriptor_Item_Value=Descriptor_Item->Value(); if (!Descriptor_Item_Value) continue; //SubDescriptors if (!strcmp(Descriptor_Item_Value, "m:SubDescriptors")) { for (XMLElement* SubDescriptors_Item=Descriptor_Item->FirstChildElement(); SubDescriptors_Item; SubDescriptors_Item=SubDescriptors_Item->NextSiblingElement()) { const char* SubDescriptors_Item_Value=SubDescriptors_Item->Value(); if (!SubDescriptors_Item_Value) continue; descriptor* SubDescriptor=new descriptor; //JPEG2000PictureSubDescriptor if (!strcmp(SubDescriptors_Item_Value, "m:JPEG2000PictureSubDescriptor")) { for (XMLElement* JPEG2000PictureSubDescriptor_Item=SubDescriptors_Item->FirstChildElement(); JPEG2000PictureSubDescriptor_Item; JPEG2000PictureSubDescriptor_Item=JPEG2000PictureSubDescriptor_Item->NextSiblingElement()) { const char* JPEG2000PictureSubDescriptor_Item_Value=JPEG2000PictureSubDescriptor_Item->Value(); const char* JPEG2000PictureSubDescriptor_Item_Text=JPEG2000PictureSubDescriptor_Item->GetText(); if (!JPEG2000PictureSubDescriptor_Item_Value || !JPEG2000PictureSubDescriptor_Item_Text) continue; //Xsiz if (!strcmp(JPEG2000PictureSubDescriptor_Item_Value, "m:Rsiz")) { SubDescriptor->Jpeg2000_Rsiz=(int16u)atoi(JPEG2000PictureSubDescriptor_Item_Text); } } } Descriptor->SubDescriptors.push_back(SubDescriptor); } } } } } if (!Id.empty()) EssenceDescriptorList[Id]=Descriptor; else delete Descriptor; // Can not be associated } } } #endif //MEDIAINFO_ADVANCED //ReelList / SegmentList if (MatchQName(CompositionPlaylist_Item, IsDcp?"ReelList":"SegmentList", NameSpace)) { for (XMLElement* ReelList_Item=CompositionPlaylist_Item->FirstChildElement(); ReelList_Item; ReelList_Item=ReelList_Item->NextSiblingElement()) { //Reel if (MatchQName(ReelList_Item, IsDcp?"Reel":"Segment", NameSpace)) { for (XMLElement* Reel_Item=ReelList_Item->FirstChildElement(); Reel_Item; Reel_Item=Reel_Item->NextSiblingElement()) { //AssetList if (MatchQName(Reel_Item, IsDcp?"AssetList":"SequenceList", NameSpace)) { for (XMLElement* AssetList_Item=Reel_Item->FirstChildElement(); AssetList_Item; AssetList_Item=AssetList_Item->NextSiblingElement()) { const char *AlItemNs, *AlItemName = LocalName(AssetList_Item, AlItemNs); if (!AlItemNs) continue; //File //if ((IsDcp && (!strcmp(AssetList_Item->Value(), "MainPicture") || !strcmp(AssetList_Item->Value(), "MainSound"))) // || (IsImf && (!strcmp(AssetList_Item->Value(), "cc:MainImageSequence") || !strcmp(AssetList_Item->Value(), "cc:MainImage")))) if (strcmp(AlItemName, "MarkerSequence")) //Ignoring MarkerSequence for the moment. TODO: check what to do with MarkerSequence { sequence* Sequence=new sequence; Ztring Asset_Id; if (IsDcp && !strcmp(NameSpace, AlItemNs)) { if (!strcmp(AlItemName, "MainPicture")) Sequence->StreamKind=Stream_Video; else if (!strcmp(AlItemName, "MainSound")) Sequence->StreamKind=Stream_Audio; } else if (IsImf && IsSmpteSt2067_2(AlItemNs)) { if (!strcmp(AlItemName, "MainImageSequence")) Sequence->StreamKind=Stream_Video; else if (!strcmp(AlItemName, "MainAudioSequence")) Sequence->StreamKind=Stream_Audio; } for (XMLElement* File_Item=AssetList_Item->FirstChildElement(); File_Item; File_Item=File_Item->NextSiblingElement()) { //Id if (MatchQName(File_Item, "Id", NameSpace) && Asset_Id.empty()) Asset_Id.From_UTF8(File_Item->GetText()); //ResourceList if (IsImf && MatchQName(File_Item, "ResourceList", NameSpace)) { for (XMLElement* ResourceList_Item=File_Item->FirstChildElement(); ResourceList_Item; ResourceList_Item=ResourceList_Item->NextSiblingElement()) { //Resource if (MatchQName(ResourceList_Item, "Resource", NameSpace)) { Ztring Resource_Id; resource* Resource=new resource; for (XMLElement* Resource_Item=ResourceList_Item->FirstChildElement(); Resource_Item; Resource_Item=Resource_Item->NextSiblingElement()) { const char* ResText=Resource_Item->GetText(); if (!ResText) continue; const char *ResItemNs, *ResItemName = LocalName(Resource_Item, ResItemNs); if (!ResItemNs || strcmp(ResItemNs, NameSpace)) continue; // item has wrong namespace //EditRate if (!strcmp(ResItemName, "EditRate")) { Resource->EditRate=atof(ResText); const char* EditRate2=strchr(ResText, ' '); if (EditRate2!=NULL) { float64 EditRate2f=atof(EditRate2); if (EditRate2f) Resource->EditRate/=EditRate2f; } } //EntryPoint if (!strcmp(ResItemName, "EntryPoint")) { Resource->IgnoreEditsBefore=atoi(ResText); if (Resource->IgnoreEditsAfter!=(int64u)-1) Resource->IgnoreEditsAfter+=Resource->IgnoreEditsBefore; } //Id if (!strcmp(ResItemName, "Id") && Resource_Id.empty()) Resource_Id.From_UTF8(ResText); //SourceDuration if (!strcmp(ResItemName, "SourceDuration")) Resource->IgnoreEditsAfter=Resource->IgnoreEditsBefore+atoi(ResText); #if MEDIAINFO_ADVANCED //SourceEncoding if (!strcmp(ResItemName, "SourceEncoding")) Resource->SourceEncodings.push_back(ResText); #endif //MEDIAINFO_ADVANCED //TrackFileId if (!strcmp(ResItemName, "TrackFileId")) Resource->FileNames.push_back(Ztring().From_UTF8(ResText)); } if (Resource->FileNames.empty()) Resource->FileNames.push_back(Resource_Id); Sequence->AddResource(Resource); } } } } if (Sequence->Resources.empty()) { resource* Resource=new resource; Resource->FileNames.push_back(Asset_Id); Sequence->AddResource(Resource); } Sequence->StreamID=ReferenceFiles->Sequences_Size()+1; ReferenceFiles->AddSequence(Sequence); } } } } } } } } Element_Offset=File_Size; //Getting files names FileName Directory(File_Name); Ztring DirPath = Directory.Path_Get(); if (!DirPath.empty()) DirPath += PathSeparator; Ztring Assetmap_FileName=DirPath+__T("ASSETMAP.xml"); bool IsOk=false; if (File::Exists(Assetmap_FileName)) IsOk=true; else { Assetmap_FileName.resize(Assetmap_FileName.size()-4); //Old fashion, without ".xml" if (File::Exists(Assetmap_FileName)) IsOk=true; } if (IsOk) { MediaInfo_Internal MI; MI.Option(__T("File_KeepInfo"), __T("1")); Ztring ParseSpeed_Save=MI.Option(__T("ParseSpeed_Get"), __T("")); Ztring Demux_Save=MI.Option(__T("Demux_Get"), __T("")); MI.Option(__T("ParseSpeed"), __T("0")); MI.Option(__T("Demux"), Ztring()); MI.Option(__T("File_IsReferenced"), __T("1")); size_t MiOpenResult=MI.Open(Assetmap_FileName); MI.Option(__T("ParseSpeed"), ParseSpeed_Save); //This is a global value, need to reset it. TODO: local value MI.Option(__T("Demux"), Demux_Save); //This is a global value, need to reset it. TODO: local value if (MiOpenResult && (MI.Get(Stream_General, 0, General_Format)==__T("DCP AM") || MI.Get(Stream_General, 0, General_Format)==__T("IMF AM"))) { MergeFromAm(((File_DcpAm*)MI.Info)->Streams); } } ReferenceFiles->FilesForStorage=true; #if MEDIAINFO_ADVANCED for (std::map<string, descriptor*>::iterator EssenceDescriptor = EssenceDescriptorList.begin(); EssenceDescriptor != EssenceDescriptorList.end(); ++EssenceDescriptor) for (std::vector<descriptor*>::iterator SubDescriptor = EssenceDescriptor->second->SubDescriptors.begin(); SubDescriptor != EssenceDescriptor->second->SubDescriptors.end(); ++SubDescriptor) ReferenceFiles->UpdateMetaDataFromSourceEncoding(EssenceDescriptor->first, "Format_Profile", Jpeg2000_Rsiz((*SubDescriptor)->Jpeg2000_Rsiz)); #endif //MEDIAINFO_ADVANCED //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_SubRip::FileHeader_Begin() { if (!IsSub && (Buffer_Size<File_Size && Buffer_Size<65536)) { Element_WaitForMoreData(); return false; } ZtringListList List; List.Separator_Set(0, __T("\n\n")); List.Separator_Set(1, __T("\n")); if (Buffer[0]==0xEF && Buffer[1]==0xBB && Buffer[2]==0xBF) HasBOM=true; bool IsLocal=false; Ztring Temp; Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); if (Temp.empty()) { Temp.From_Local((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); // Trying from local code page IsLocal=true; } Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); if (List(0, 0)==__T("WEBVTT FILE") || List(0, 0)==__T("WEBVTT")) IsVTT=true; if (!IsVTT) { size_t IsOk=0; size_t IsNok=0; for (size_t Pos=0; Pos<List.size(); Pos++) { if (List(Pos, 0).To_int64u()==Pos+1) IsOk++; else IsNok++; if (List(Pos, 1).size()>22 && List(Pos, 1)[2]==__T(':') && List(Pos, 1)[5]==__T(':') && List(Pos, 1).find(__T(" --> "))!=string::npos) IsOk++; else IsNok++; } if (!IsOk || IsNok>IsOk/2) { Reject(); return true; } } if (!IsSub && File_Size!=(int64u)-1 && Buffer_Size!=File_Size) { Element_WaitForMoreData(); return false; } if (!Status[IsAccepted]) { Accept(); Fill(Stream_General, 0, General_Format, IsVTT?"WebVTT":"SubRip"); Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, "Format", IsVTT?"WebVTT":"SubRip"); Fill(Stream_Text, 0, "Codec", IsVTT?"WebVTT":"SubRip"); } if (IsLocal) Temp.From_Local((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); else Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); #if MEDIAINFO_DEMUX size_t Pos=0; for (;;) { if (Pos>=List.size()) break; if (List[Pos].size()>=3 || (IsVTT && List[Pos].size()>=2)) { Ztring PTS_Begin_String=List[Pos][IsVTT?0:1].SubString(Ztring(), __T(" --> ")); Ztring PTS_End_String=List[Pos][IsVTT?0:1].SubString(__T(" --> "), Ztring()); if (IsVTT) { size_t Extra_Pos=PTS_End_String.find(__T(' ')); if (Extra_Pos!=string::npos) PTS_End_String.resize(Extra_Pos); //Discarding positioning } item Item; Item.PTS_Begin=SubRip_str2timecode(PTS_Begin_String.To_UTF8().c_str()); Item.PTS_End=SubRip_str2timecode(PTS_End_String.To_UTF8().c_str()); for (size_t Pos2=IsVTT?1:2; Pos2<List[Pos].size(); Pos2++) { List[Pos][Pos2].Trim(); Item.Content+=List[Pos][Pos2]; if (Pos2+1<List[Pos].size()) Item.Content+=EOL; } Items.push_back(Item); } Pos++; } #endif //MEDIAINFO_DEMUX return true; }
//--------------------------------------------------------------------------- bool File_SequenceInfo::FileHeader_Begin() { XMLDocument document; if (!FileHeader_Begin_XML(document)) return false; { XMLElement* Root=document.FirstChildElement("SEQUENCEINFO"); if (Root) { Accept("SequenceInfo"); Fill(Stream_General, 0, General_Format, "SequenceInfo"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); File__ReferenceFilesHelper::reference ReferenceFile; ReferenceFile.StreamKind=Stream_Video; FileName FN(File_Name); Ztring Base=FN.Path_Get(); size_t Pos=Base.rfind(PathSeparator); if (Pos!=string::npos) { Ztring ToAdd=Base.substr(Pos, string::npos); Ztring DirectoryBase=Base; DirectoryBase+=ToAdd; DirectoryBase+=__T('_'); size_t DirNumberCount=1; Ztring Directory=DirectoryBase; for (; DirNumberCount<9; DirNumberCount++) { Directory+=__T('0'); if (Dir::Exists(Directory)) break; } if (DirNumberCount<9) { int32u DirNumber=0; do { Ztring Number=Ztring::ToZtring(DirNumber); if (Number.size()<DirNumberCount) Number.insert(0, DirNumberCount-Number.size(), __T('0')); Directory=DirectoryBase; Directory+=Number; if (!Dir::Exists(Directory)) break; Ztring FileBase=Directory; FileBase+=ToAdd; FileBase+=__T('_'); FileBase+=__T('.'); size_t FileNumberCount=1; Ztring FullFile=FileBase; Ztring Extension; for (; FileNumberCount<10; FileNumberCount++) { FullFile.insert(FullFile.begin()+FullFile.size()-Extension.size()-1, __T('0')); if (Extension.empty()) { ZtringList List=Dir::GetAllFileNames(FullFile+__T('*')); if (List.size()>=2) { FileNumberCount=(size_t)-1; //Problem, which one to choose? break; } else if (List.size()==1) { FileName Temp(List[0]); Extension=Temp.Extension_Get(); FileBase+=Extension; FullFile=FileBase; break; } } else if (File::Exists(FullFile)) break; } bool FromZero=true; if (FileNumberCount>=9) { //Trying with consecutive file numbers betweens dirs Number=Ztring::ToZtring(ReferenceFile.FileNames.size()); FullFile=FileBase; FullFile.insert(FullFile.size()-Extension.size()-1, Number); FileNumberCount=Number.size(); if (!File::Exists(FullFile)) { FileNumberCount++; for (; FileNumberCount<10; FileNumberCount++) { FullFile.insert(FullFile.begin()+FullFile.size()-Extension.size()-Number.size()-1, __T('0')); if (File::Exists(FullFile)) { FromZero=false; break; } } } else FromZero=false; } if (FileNumberCount<9) { size_t FileNumber=FromZero?0:ReferenceFile.FileNames.size(); do { Number=Ztring::ToZtring(FileNumber); if (Number.size()<FileNumberCount) Number.insert(0, FileNumberCount-Number.size(), __T('0')); FullFile=FileBase; FullFile.insert(FullFile.size()-Extension.size()-1, Number); if (!File::Exists(FullFile)) break; ReferenceFile.FileNames.push_back(FullFile); FileNumber++; } while (FileNumber<1000000000); } DirNumber++; } while (DirNumber<1000000000); if (!ReferenceFile.FileNames.empty()) ReferenceFiles->References.push_back(ReferenceFile); } } } else { Reject("SequenceInfo"); return false; } } //All should be OK... return true; }
//--------------------------------------------------------------------------- void File_Flac::Read_File() { //Init FLAC::Metadata::SimpleIterator SI; if (!SI.is_valid()) return; if (!SI.init(CompleteFileName.To_Local().c_str(), true, true)) return; //Filling Stream_Prepare(Stream_General); Fill("Format", "FLAC"); Stream_Prepare(Stream_Audio); Fill("Codec", "FLAC"); do { switch(SI.get_block_type()) { case FLAC__METADATA_TYPE_STREAMINFO: { FLAC::Metadata::StreamInfo* StreamInfo=(FLAC::Metadata::StreamInfo*)SI.get_block(); if (StreamInfo) { if (StreamInfo->get_min_framesize()==StreamInfo->get_max_framesize() && StreamInfo->get_min_framesize()!=0 ) // 0 means it is unknown Fill("BitRate_Mode", "CBR"); else Fill("BitRate_Mode", "VBR"); Fill("SamplingRate", StreamInfo->get_sample_rate()); Fill("Channel(s)", StreamInfo->get_channels()); Fill("Resolution", StreamInfo->get_bits_per_sample()); Fill(Stream_General, 0, "PlayTime", (int32u)(int64u_float64(StreamInfo->get_total_samples())*1000/StreamInfo->get_sample_rate())); } } break; case FLAC__METADATA_TYPE_PADDING: break; case FLAC__METADATA_TYPE_APPLICATION: break; case FLAC__METADATA_TYPE_SEEKTABLE: break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: { FLAC::Metadata::VorbisComment* vorbiscomment =(FLAC::Metadata::VorbisComment*)SI.get_block(); if (vorbiscomment) { Fill("Encoded_Library", vorbiscomment->get_vendor_string()); for(size_t t=0; t<vorbiscomment->get_num_comments(); t++) { std::string Key(vorbiscomment->get_comment(t).get_field_name(), vorbiscomment->get_comment(t).get_field_name_length()); Ztring Value; Value.From_UTF8(vorbiscomment->get_comment(t).get_field_value(), vorbiscomment->get_comment(t).get_field_value_length()); //Parsing if (Key=="ALBUM") Fill(Stream_General, 0, "Album", Value); else if (Key=="ARTIST") Fill(Stream_General, 0, "Performer", Value); else if (Key=="COPYRIGHT") Fill(Stream_General, 0, "Copyright", Value); else if (Key=="DATE") Fill(Stream_General, 0, "Recorded_Date", Value); else if (Key=="DESCRIPTION") Fill(Stream_General, 0, "Comment", Value); else if (Key=="LOCATION") Fill(Stream_General, 0, "RecordingLocation", Value); else if (Key=="PERFORMER") Fill(Stream_General, 0, "Performer", Value); else if (Key=="TITLE") Fill(Stream_General, 0, "Title", Value); else if (Key=="TRACKNUMBER") Fill(Stream_General, 0, "Track", Value); else Fill(Stream_General, 0, Key.c_str(), Value); } } } break; case FLAC__METADATA_TYPE_CUESHEET: break; }; } while(SI.next()); }
//--------------------------------------------------------------------------- // Main ZenLib::Ztring Enums_Create() { Ztring Out; Ztring Result; Ztring Contents; //Load header Result=Enums_Create_Load(L"../Source/Resource/Text/Enums_.1.txt", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Generic", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"General", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Video", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Audio", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Text", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Other", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Image", Contents); if (!Result.empty()) return Result; Out+=Contents; Result=Enums_Create_Item(L"Stream", L"Menu", Contents); if (!Result.empty()) return Result; Out+=Contents; //Load footer Result=Enums_Create_Load(L"../Source/Resource/Text/Enums_.9.txt", Contents); if (!Result.empty()) return Result; Out+=Contents; //Write file Result=Enums_Create_Save(L"../Source/MediaInfo/File__Analyse_Automatic.h", Out); if (!Result.empty()) return Result; return Out; }
//--------------------------------------------------------------------------- bool File_Dxw::FileHeader_Begin() { //Element_Size if (File_Size>1024*1024) { Reject("DXW"); return false; //DXW files are not big } TiXmlDocument document(File_Name.To_Local().c_str()); if (document.LoadFile()) { TiXmlElement* Root=document.FirstChildElement("indexFile"); if (Root) { const char* Attribute=Root->Attribute("xmlns"); if (Attribute==NULL || Ztring().From_UTF8(Attribute)!=_T("urn:digimetrics-xml-wrapper")) { Reject("DXW"); return false; } Accept("DXW"); Fill(Stream_General, 0, General_Format, "DXW"); ReferenceFiles=new File__ReferenceFilesHelper(this, Config); TiXmlElement* Track=Root->FirstChildElement(); while (Track) { if (string(Track->Value())=="clip") { File__ReferenceFilesHelper::reference ReferenceFile; Attribute=Track->Attribute("file"); if (Attribute) { ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==_T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==_T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==_T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; } Attribute=Track->Attribute("framerate"); if (Attribute) { ReferenceFile.FrameRate=Ztring().From_UTF8(Attribute).To_float64(); Attribute=Track->Attribute("type"); if (Attribute) { Ztring StreamKind; StreamKind.From_UTF8(Attribute); if (StreamKind==_T("video")) ReferenceFile.StreamKind=Stream_Video; if (StreamKind==_T("audio")) ReferenceFile.StreamKind=Stream_Audio; if (StreamKind==_T("data")) ReferenceFile.StreamKind=Stream_Text; //Not sure this is a right mapping, but this is only used when file is missing } TiXmlElement* Frame=Track->FirstChildElement(); while (Frame) { if (string(Frame->Value())=="frame") { Attribute=Frame->Attribute("file"); if (Attribute) ReferenceFile.FileNames.push_back(Ztring().From_UTF8(Attribute)); } Frame=Frame->NextSiblingElement(); } } ReferenceFile.StreamID=ReferenceFiles->References.size()+1; ReferenceFiles->References.push_back(ReferenceFile); } Track=Track->NextSiblingElement(); } } else { Reject("DXW"); return false; } } else { Reject("DXW"); return false; } //All should be OK... return true; }
//--------------------------------------------------------------------------- bool File_SubRip::FileHeader_Begin() { if (!IsSub && (Buffer_Size<File_Size && Buffer_Size<65536)) { Element_WaitForMoreData(); return false; } ZtringListList List; List.Separator_Set(0, __T("\n\n")); List.Separator_Set(1, __T("\n")); if (Buffer_Size>=3 && Buffer[0]==0xEF && Buffer[1]==0xBB && Buffer[2]==0xBF) HasBOM=true; bool IsLocal=false; Ztring Temp; Temp.From_UTF8((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); if (Temp.empty()) { #ifdef WINDOWS Temp.From_Local((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); // Trying from local code page #else //WINDOWS Temp.From_ISO_8859_1((const char*)Buffer+(HasBOM?3:0), (Buffer_Size>65536?65536:Buffer_Size)-(HasBOM?3:0)); #endif //WINDOWS IsLocal=true; } Temp.FindAndReplace(__T("\r\n"), __T("\n"), 0, Ztring_Recursive); Temp.FindAndReplace(__T("\r"), __T("\n"), 0, Ztring_Recursive); List.Write(Temp); if (List(0, 0)==__T("WEBVTT FILE") || List(0, 0)==__T("WEBVTT")) IsVTT=true; if (!IsVTT) { size_t IsOk=0; size_t IsNok=0; for (size_t Pos=0; Pos<List.size(); Pos++) { if (List(Pos, 0).To_int64u()==Pos+1) IsOk++; else IsNok++; if (List(Pos, 1).size()>22 && List(Pos, 1)[2]==__T(':') && List(Pos, 1)[5]==__T(':') && List(Pos, 1).find(__T(" --> "))!=string::npos) IsOk++; else IsNok++; } if (!IsOk || IsNok>IsOk/2) { Reject(); return true; } } if (!IsSub && File_Size!=(int64u)-1 && Buffer_Size!=File_Size) { Element_WaitForMoreData(); return false; } if (!Status[IsAccepted]) { Accept(); Fill(Stream_General, 0, General_Format, IsVTT?"WebVTT":"SubRip"); Stream_Prepare(Stream_Text); Fill(Stream_Text, 0, "Format", IsVTT?"WebVTT":"SubRip"); Fill(Stream_Text, 0, "Codec", IsVTT?"WebVTT":"SubRip"); } if (IsLocal) #ifdef WINDOWS Temp.From_Local((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); #else //WINDOWS Temp.From_ISO_8859_1((const char*)Buffer+(HasBOM?3:0), Buffer_Size-(HasBOM?3:0)); #endif //WINDOWS else
//--------------------------------------------------------------------------- bool File_Pdf::Get_Next(string &Key, Ztring &Value) { Key.clear(); Value.clear(); string Line; //Removig end of lines while (Element_Offset<Element_Size && (Buffer[Buffer_Offset+(size_t)Element_Offset]=='\r' || Buffer[Buffer_Offset+(size_t)Element_Offset]=='\n' || Buffer[Buffer_Offset+(size_t)Element_Offset]==' ')) Element_Offset++; //End if (Element_Offset>=Element_Size) return true; //Testing Catalog Peek_String (2, Line); if (Line=="<<") { Element_Offset+=2; Catalog_Level++; return true; } else if (Line==">>") { Element_Offset+=2; Catalog_Level--; return true; } //Getting a complete line Peek_String (SizeOfLine(), Line); //Testing Catalog size_t Catalog_End=Line.find(">>"); if (Catalog_End!=String::npos) Line.resize(Catalog_End); //Testing stream if (Line=="stream") { Skip_String(Line.size(), "Stream, Header"); Key=Line; return false; } if (Line=="endstream") { Skip_String(Line.size(), "Stream, Footer"); Key=Line; return false; } //Testing object if (Line=="endobj") { Skip_String(Line.size(), "Footer"); Key=Line; return false; } //Base int64u Line_Base=Element_Offset; //Testing next key size_t Line_End=0; size_t Line_Begin=Line_End; // Key-Value if (Line_Begin<Line.size() && Line[Line_Begin]=='/') { Line_End= Line_Begin+1; size_t HasParenthesis=0; size_t HasBracket=0; size_t HasSpace=0; size_t HasValue=0; for (;;) { if (Line_End==Line.size()) break; if (!HasParenthesis && !HasBracket && HasValue && Line[Line_End]=='<' && Line_End+1<Line.size() && Line[Line_End+1]=='<') break; if (!HasParenthesis && !HasBracket && HasValue && Line[Line_End]=='/') break; else if (!HasValue && Line[Line_End]=='/') ++HasValue; else if (!HasValue && HasSpace) ++HasValue; if (Line[Line_End]==' ') ++HasSpace; if (Line[Line_End]=='(') ++HasParenthesis; if (HasParenthesis && Line[Line_End]==')') --HasParenthesis; if (Line[Line_End]=='[') ++HasBracket; if (HasBracket && Line[Line_End]==']') --HasBracket; ++Line_End; } while(Line_End && Line[Line_End-1]==' ') Line_End--; //Removing trailing spaces Element_Offset=Line_Base+Line_Begin; string KeyValue; Get_String(Line_End-Line_Begin, KeyValue, "Key-Value"); size_t Key_Max=KeyValue.find_first_of(" ("); if (Key_Max==string::npos) Key_Max=KeyValue.size(); Key=KeyValue.substr(1, Key_Max-1); size_t Value_Min=Key_Max; while (Value_Min<KeyValue.size() && KeyValue[Value_Min]==' ') ++Value_Min; if (Value_Min<KeyValue.size() && KeyValue[Value_Min]=='(') { ++Value_Min; size_t Value_Max=KeyValue.find(')', Value_Min); if (Value_Max!=string::npos) { //TODO Value.From_UTF8(KeyValue.c_str()+Value_Min, Value_Max-Value_Min); } else Value.From_UTF8(KeyValue.c_str()+Value_Min); } else Value.From_UTF8(KeyValue.c_str()+Value_Min); return false; } return false; }
//--------------------------------------------------------------------------- void File_Pdf::trailer() { Element_Begin1("Trailer"); //Parsing int32u Prev=(int32u)-1; string Key; Ztring Value; Skip_String(SizeOfLine(), "Object name"); while (Element_Offset<Element_Size) { if (Get_Next(Key, Value)) { for (;;) { Get_Next(Key, Value); if (Key.empty()) break; else if (Key=="Root") { int32u ObjectNumber=Value.To_int32u(); Objects[ObjectNumber].Type=Type_Root; Objects[ObjectNumber].TopObject=(int32u)-1; Objects[(int32u)-1].Bottoms.push_back(ObjectNumber); Param_Info1(__T("Document Catalog is at offset 0x"+Ztring().From_Number(Objects[ObjectNumber].Offset, 16))); } else if (Key=="Info") { int32u ObjectNumber=Value.To_int32u(); Objects[ObjectNumber].Type=Type_Info; Objects[ObjectNumber].TopObject=(int32u)-1; Objects[(int32u)-1].Bottoms.push_back(ObjectNumber); Param_Info1(__T("Info is at offset 0x"+Ztring().From_Number(Objects[ObjectNumber].Offset, 16))); } else if (Key=="Prev") { Prev=Value.To_int32u(); Param_Info1(__T("Previous Cross-Reference Table is at offset 0x"+Ztring().From_Number(Prev, 16))); } } continue; } if (Key.empty()) break; } Element_End0(); //Previous Cross-Reference Table if (Prev!=(int32u)-1) { GoTo(Prev); return; } objects::iterator Object_Top=Objects.find((int32u)-1); if (Offsets.empty() || Object_Top==Objects.end()) { ForceFinish(); return; } sort(Offsets.begin(), Offsets.end()); //Offsets_Current=Offsets.end(); //No more used for the moment Objects[(int32u)-1].BottomPos=0; Objects_Current=Objects.find(Object_Top->second.Bottoms[0]); GoTo(Objects_Current->second.Offset); State=State_Parsing_object; }
//--------------------------------------------------------------------------- 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); }