//--------------------------------------------------------------------------- void File_Caf::desc() { //Parsing float64 SampleRate; int32u FormatID, FormatFlags, BytesPerPacket, FramesPerPacket, ChannelsPerFrame, BitsPerChannel; Get_BF8(SampleRate, "SampleRate"); Get_C4 (FormatID, "FormatID"); Get_B4 (FormatFlags, "FormatFlags"); Get_B4 (BytesPerPacket, "BytesPerPacket"); Get_B4 (FramesPerPacket, "FramesPerPacket"); Get_B4 (ChannelsPerFrame, "ChannelsPerFrame"); Get_B4 (BitsPerChannel, "BitsPerChannel"); FILLING_BEGIN(); if (SampleRate) Fill(Stream_Audio, 0, Audio_SamplingRate, SampleRate); CodecID_Fill(Ztring().From_CC4(FormatID), Stream_Audio, 0, InfoCodecID_Format_Mpeg4); if (ChannelsPerFrame) Fill(Stream_Audio, 0, Audio_Channel_s_, ChannelsPerFrame); if (BitsPerChannel) Fill(Stream_Audio, 0, Audio_BitDepth, BitsPerChannel); if (BytesPerPacket && SampleRate && FramesPerPacket) Fill(Stream_Audio, 0, Audio_BitRate, SampleRate*BytesPerPacket*8/FramesPerPacket); FILLING_END(); }
//--------------------------------------------------------------------------- void Riff_AVI__hdrl_strl_indx::Read_Internal () { //Filling Global->AVI__hdrl_strl_indx_Pointers.insert(this); //Reading Read_Internal_ReadAllInBuffer(); //Parsing int32u Entry_Count, ChunkId; int16u LongsPerEntry; int8u IndexType, IndexSubType; Get_L2 (LongsPerEntry); Get_L1 (IndexSubType); Get_L1 (IndexType); Get_L4 (Entry_Count); Get_C4 (ChunkId); //Integrity if (LongsPerEntry!=4 || (IndexSubType&0xFE) || IndexType!=0x00 || 24+Entry_Count*16>Chunk.Content.Size) throw exception_valid("hdrl_strl_indx form is not supported"); //Parsing Skip_XX(12); //Reserved for (int32u Pos=0; Pos<Entry_Count; Pos++) { int64u Offset; Get_L8 (Offset); Skip_XX(8); //Size + Duration //Filling Global->AVI__hdrl_strl_indx_In_Position_Indexes_List.push_back(Offset); Global->AVI__movi___ix_WithFields[ChunkId]=(IndexSubType&0x01)?true:false; } }
//--------------------------------------------------------------------------- void File_Flac::FileHeader_Parse() { //Parsing int32u Signature; if (VorbisHeader) { Skip_B1( "Signature"); Skip_Local(4, "Signature"); Skip_B1( "Major version"); Skip_B1( "Minor version"); Skip_B2( "Number of header"); } Get_C4 (Signature, "Signature"); FILLING_BEGIN(); //Integrity if (Signature!=CC4("fLaC")) { Finished(); return; } Stream_Prepare(Stream_General); Fill(Stream_General, 0, General_Format, "FLAC"); FILLING_END(); }
//--------------------------------------------------------------------------- void File_Png::Header_Parse() { //Parsing int32u Length, Chunk_Type; Get_B4 (Length, "Length"); Get_C4 (Chunk_Type, "Chunk Type"); //Filling Header_Fill_Size(12+Length); //+4 for CRC Header_Fill_Code(Chunk_Type, Ztring().From_CC4(Chunk_Type)); }
//--------------------------------------------------------------------------- void File_TwinVQ::Header_Parse() { //Parsing int32u id, size; Get_C4 (id, "id"); Get_B4 (size, "size"); //Filling Header_Fill_Code(id, Ztring().From_CC4(id)); Header_Fill_Size(8+(id==Elements::DATA?0:size)); //DATA chunk indicates the end of the header, with no chunk size }
//--------------------------------------------------------------------------- void File_Jpeg::APP1_EXIF() { //Parsing Element_Begin1("Exif"); int32u Alignment; Get_C4(Alignment, "Alignment"); if (Alignment==0x49492A00) Skip_B4( "First_IFD"); if (Alignment==0x4D4D2A00) Skip_L4( "First_IFD"); Element_End0(); }
//--------------------------------------------------------------------------- void File_Jpeg::APP0() { //Parsing int32u Name; Get_C4(Name, "Name"); if (Name==CC4("AVI1")) APP0_AVI1(); if (Name==CC4("JFIF")) APP0_JFIF(); if (Name==CC4("JFFF")) APP0_JFXX(); }
//--------------------------------------------------------------------------- void File_Jpeg::APP0() { //Parsing int32u Name; Get_C4(Name, "Name"); switch (Name) { case 0x41564931 : APP0_AVI1(); break; //"AVI1" case 0x4A464946 : APP0_JFIF(); break; //"JFIF" case 0x4A464646 : APP0_JFFF(); break; //"JFFF" default : Skip_XX(Element_Size, "Data"); } }
//--------------------------------------------------------------------------- void File_Module::FileHeader_Parse() { //Parsing Ztring ModuleName, SamplesName; int32u Signature; Get_Local(20, ModuleName, "Module name"); for (int8u Pos=0; Pos<31; Pos++) { Element_Begin(); Get_Local(22, SamplesName, "Sample's name"); Element_Name(SamplesName); Skip_B2( "Sample length"); Skip_B1( "Finetune value for the sample"); Skip_B1( "Volume of the sample"); Skip_B2( "Start of sample repeat offset"); Skip_B2( "Length of sample repeat"); Element_End(); } Skip_B1( "Number of song positions"); Skip_B1( "0x8F"); Skip_XX(128, "Pattern table"); Get_C4 (Signature, "Signature"); FILLING_BEGIN(); switch (Signature) { case 0x4D2E4B2E : //M.K. case 0x4D214B21 : //M!K! case 0x664C5434 : //FLT4 case 0x664C5438 : //FLT8 case 0x3663684E : //6CHN case 0x3863684E : //8CHN break; default : Finished(); return; } FILLING_END() FILLING_BEGIN(); Stream_Prepare(Stream_General); Fill(Stream_General, 0, General_Format, "Module"); Stream_Prepare(Stream_Audio); Finished(); FILLING_END(); }
//--------------------------------------------------------------------------- void File_Png::Header_Parse() { if (!Signature_Parsed) { //Filling Header_Fill_Size(8); Header_Fill_Code(0, "File header"); return; } //Parsing int32u Length, Chunk_Type; Get_B4 (Length, "Length"); Get_C4 (Chunk_Type, "Chunk Type"); //Filling Header_Fill_Size(12+Length); //+4 for CRC Header_Fill_Code(Chunk_Type, Ztring().From_CC4(Chunk_Type)); }
//--------------------------------------------------------------------------- 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_ProRes::Read_Buffer_Continue() { //Parsing int32u Name, creatorID; int16u hdrSize, version, frameWidth, frameHeight; int8u chrominance_factor, frame_type, primaries, transf_func, colorMatrix; bool IsOk=true, luma, chroma; Element_Begin1("Header"); Skip_B4( "Size"); Get_C4 (Name, "Name"); Element_End(); Element_Begin1("Frame header"); Get_B2 (hdrSize, "hdrSize"); Get_B2 (version, "version"); Get_C4 (creatorID, "creatorID"); Get_B2 (frameWidth, "frameWidth"); Get_B2 (frameHeight, "frameHeight"); BS_Begin(); Get_S1 (2, chrominance_factor, "chrominance factor"); Param_Info1(ProRes_chrominance_factor(chrominance_factor)); Skip_S1(2, "reserved"); Get_S1 (2, frame_type, "frame type"); Param_Info1(ProRes_frame_type_ScanType(frame_type)); Param_Info1(ProRes_frame_type_ScanOrder(frame_type)); Skip_S1(2, "reserved"); BS_End(); Skip_B1( "reserved"); Get_B1 (primaries, "primaries"); Param_Info1(Mpegv_colour_primaries(primaries)); Get_B1 (transf_func, "transf_func"); Param_Info1(Mpegv_transfer_characteristics(transf_func)); Get_B1 (colorMatrix, "colorMatrix"); Param_Info1(Mpegv_matrix_coefficients(colorMatrix)); BS_Begin(); Skip_S1(4, "src_pix_fmt"); Skip_S1(4, "alpha_info"); BS_End(); Skip_B1( "reserved"); BS_Begin(); Skip_S1(6, "reserved"); Get_SB (luma, "custom luma quant matrix present"); Get_SB (chroma, "custom chroma quant matrix present"); BS_End(); if (luma) Skip_XX(64, "QMatLuma"); if (chroma) Skip_XX(64, "QMatChroma"); Element_End(); if (Element_Offset!=8+(int32u)hdrSize) IsOk=false; for (int8u PictureNumber=0; PictureNumber<(frame_type?2:1); PictureNumber++) { Element_Begin1("Picture layout"); int16u total_slices; vector<int16u> slices_size; Element_Begin1("Picture header"); int64u pic_hdr_End, pic_data_End; int32u pic_data_size; int8u pic_hdr_size; Get_B1 (pic_hdr_size, "pic_hdr_size"); if (pic_hdr_size<64) { Trusted_IsNot("pic_hdr_size"); Element_End(); Element_End(); return; } pic_hdr_End=Element_Offset+pic_hdr_size/8-((pic_hdr_size%8)?0:1); Get_B4 (pic_data_size, "pic_data_size"); if (pic_data_size<8) { Trusted_IsNot("pic_data_size"); Element_End(); Element_End(); return; } pic_data_End=Element_Offset+pic_data_size-5; Get_B2 (total_slices, "total_slices"); BS_Begin(); Skip_S1(4, "slice_width_factor"); Skip_S1(4, "slice_height_factor"); BS_End(); if (Element_Offset<pic_hdr_End) Skip_XX(pic_hdr_End-Element_Offset, "Unknown"); Element_End(); Element_Begin1("Slice index table"); for (int16u Pos=0; Pos<total_slices; Pos++) { int16u slice_size; Get_B2 (slice_size, "slice_size"); slices_size.push_back(slice_size); } Element_End(); for (int16u Pos=0; Pos<slices_size.size(); Pos++) { Skip_XX(slices_size[Pos], "slice data"); } if (Element_Offset<pic_data_End) Skip_XX(pic_data_End-Element_Offset, "Unknown"); Element_End(); } bool IsZeroes=true; for (size_t Pos=(size_t)Element_Offset; Pos<(size_t)Element_Size; Pos++) if (Buffer[Buffer_Offset+Pos]) { IsZeroes=false; break; } Skip_XX(Element_Size-Element_Offset, IsZeroes?"Zeroes":"Unknown"); FILLING_BEGIN(); if (IsOk && Name==0x69637066 && !Status[IsAccepted]) //icpf { Accept(); Fill(); Fill(Stream_Video, 0, Video_Format_Version, __T("Version ")+Ztring::ToZtring(version)); Fill(Stream_Video, 0, Video_Width, frameWidth); Fill(Stream_Video, 0, Video_Height, frameHeight); Fill(Stream_Video, 0, Video_Encoded_Library, ProRes_creatorID(creatorID)); Fill(Stream_Video, 0, Video_ChromaSubsampling, ProRes_chrominance_factor(chrominance_factor)); Fill(Stream_Video, 0, Video_ScanType, ProRes_frame_type_ScanType(frame_type)); Fill(Stream_Video, 0, Video_ScanOrder, ProRes_frame_type_ScanOrder(frame_type)); Fill(Stream_Video, 0, Video_colour_description_present, "Yes"); Fill(Stream_Video, 0, Video_colour_primaries, Mpegv_colour_primaries(primaries)); Fill(Stream_Video, 0, Video_transfer_characteristics, Mpegv_transfer_characteristics(transf_func)); Fill(Stream_Video, 0, Video_matrix_coefficients, Mpegv_matrix_coefficients(colorMatrix)); Finish(); } 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_Ivf::FileHeader_Parse() { //Parsing int32u frame_rate_num, frame_rate_den, frame_count, fourcc; int16u version, header_size, width, height; Skip_C4 ( "Signature"); Get_L2 (version, "Version"); if (version==0) { Get_L2 (header_size, "Header Size"); if (header_size>=32) { Get_C4 (fourcc, "Fourcc"); Get_L2 (width, "Width"); Get_L2 (height, "Height"); Get_L4 (frame_rate_num, "FrameRate Numerator"); Get_L4 (frame_rate_den, "FrameRate Denominator"); Get_L4 (frame_count, "Frame Count"); Skip_L4( "Unused"); if (header_size-32) Skip_XX(header_size-32, "Unknown"); } else { fourcc=0x00000000; width=0; height=0; frame_rate_num=0; frame_rate_den=0; frame_count=0; } } else { header_size=0; fourcc=0x00000000; width=0; height=0; frame_rate_num=0; frame_rate_den=0; frame_count=0; } FILLING_BEGIN(); Accept("IVF"); Fill(Stream_General, 0, General_Format, "IVF"); if (version==0 && header_size>=32) { Stream_Prepare(Stream_Video); CodecID_Fill(Ztring().From_CC4(fourcc), Stream_Video, 0, InfoCodecID_Format_Riff); Fill(Stream_Video, 0, Video_FrameRate, (float)frame_rate_num / frame_rate_den); Fill(Stream_Video, 0, Video_FrameCount, frame_count); Fill(Stream_Video, 0, Video_Width, width); Fill(Stream_Video, 0, Video_Height, height); Fill(Stream_Video, 0, Video_StreamSize, File_Size-header_size-12*frame_count); //Overhead is 12 byte per frame } //No more need data Finish("IVF"); FILLING_END(); }