//--------------------------------------------------------------------------- void Riff_AVI__idx1::Read_Internal () { if (Global->AVI__idx1_Pointer) throw exception_read_chunk("2 idx1 chunks, not supported"); Global->AVI__idx1_Pointer=this; //Reading Read_Internal_ReadAllInBuffer(); if (Chunk.Content.Size<16) return; if (Global->AVI__movi_FirstDataChunkSize==(int64u)-1) throw exception_read_chunk("idx1 is before movi chunk, or movi chunk has no frame, not supported"); //Parsing for (Chunk.Content.Buffer_Offset=0; Chunk.Content.Buffer_Offset+16<=Chunk.Content.Size; Chunk.Content.Buffer_Offset+=16) { int32u ChunkId=BigEndian2int32u(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset); bool IsOk; switch (ChunkId&0x0000FFFF) { case Elements::AVI__movi___db : case Elements::AVI__movi___dc : case Elements::AVI__movi___pc : case Elements::AVI__movi___wb : IsOk=true; break; default : IsOk=false; } if (IsOk) break; } if (Chunk.Content.Buffer_Offset+16>Chunk.Content.Size) throw exception_read_chunk("index data has no frame reference?"); int32u Offset=LittleEndian2int32u(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset+8); int32u Size=LittleEndian2int32u(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset+12); if (Size!=Global->AVI__movi_FirstDataChunkSize) throw exception_read_chunk("index data (size) not coherent"); int64u movi_Position=(int64u)-1; for (std::set<void*>::iterator movi=Global->AVI__movi_Pointers.begin(); movi!=Global->AVI__movi_Pointers.end(); movi++) { if (((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position<movi_Position) movi_Position=((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position; } if (Offset==4+Global->AVI__movi_FirstDataChunkMoviOffset) Global->AVI__idx1_IsAbsolute=false; else if (Offset==Global->AVI__movi_FirstDataChunkPosition) Global->AVI__idx1_IsAbsolute=true; else throw exception_read_chunk("index data (position) is not coherent"); }
//--------------------------------------------------------------------------- bool File_Wvpk::Synchronize() { //Specific case if (FromMKV) return true; //Tags bool Tag_Found; if (!File__Tags_Helper::Synchronize(Tag_Found)) return false; if (Tag_Found) return true; //Synchronizing while (Buffer_Offset+8<=Buffer_Size) { while (Buffer_Offset+8<=Buffer_Size && CC4(Buffer+Buffer_Offset)!=CC4("wvpk")) { Buffer_Offset++; } if (Buffer_Offset+8<=Buffer_Size)//Testing if size is coherant { //Testing next start, to be sure size_t Size=LittleEndian2int32u(Buffer+Buffer_Offset+4)+8; if (Buffer_Offset+Size+8>Buffer_Size) return false; //Need more data //Testing if (CC4(Buffer+Buffer_Offset+Size)!=CC4("wvpk")) Buffer_Offset++; else break; //while() } } //Parsing last bytes if needed if (Buffer_Offset+8>Buffer_Size) { if (Buffer_Offset+7==Buffer_Size && CC4(Buffer+Buffer_Offset)!=0x7776706B) //"wvpk" Buffer_Offset++; if (Buffer_Offset+6==Buffer_Size && CC4(Buffer+Buffer_Offset)!=0x7776706B) //"wvpk" Buffer_Offset++; if (Buffer_Offset+5==Buffer_Size && CC4(Buffer+Buffer_Offset)!=0x7776706B) //"wvpk" Buffer_Offset++; if (Buffer_Offset+4==Buffer_Size && CC4(Buffer+Buffer_Offset)!=0x7776706B) //"wvpk" Buffer_Offset++; if (Buffer_Offset+3==Buffer_Size && CC3(Buffer+Buffer_Offset)!=0x777670) //"wv" Buffer_Offset++; if (Buffer_Offset+2==Buffer_Size && CC2(Buffer+Buffer_Offset)!=0x7776) //"wv" Buffer_Offset++; if (Buffer_Offset+1==Buffer_Size && CC1(Buffer+Buffer_Offset)!=0x77) //"w" Buffer_Offset++; return false; } //Synched is OK return true; }
//--------------------------------------------------------------------------- void Riff_AVI__idx1::Modify_Internal () { //Integrity if (Global->AVI__movi_Pointers.empty()) throw exception_valid("indx: movi chunk is not found"); std::set<void*>::iterator movi=Global->AVI__movi_Pointers.begin(); if (((Riff_AVI__movi*)(*movi))->Chunk.Content.IsModified || ((Riff_AVI__movi*)(*movi))->Chunk.Content.Size_IsModified) throw exception_valid("indx: modified movi chunk is not supported"); if (!Global->AVI__idx1_IsAbsolute) return; int64u movi_Position=((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position; int64s Difference=((Riff_AVI__movi*)(*movi))->Chunk.File_Out_Position-((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position; Difference-=Global->AVI__idx1_Difference; if (Difference==0) return; for (Chunk.Content.Buffer_Offset=0; Chunk.Content.Buffer_Offset+16<=Chunk.Content.Size; Chunk.Content.Buffer_Offset+=16) { int32u Offset=LittleEndian2int32u(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset+8); Offset+=Difference; int32u2LittleEndian(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset+8, Offset); } Global->AVI__idx1_Difference+=Difference; Chunk.Content.IsModified=true; }
//--------------------------------------------------------------------------- void File_Dpx::Header_Parse() { //Filling Header_Fill_Code(Sizes_Pos); //We use Sizes_Pos as the unique key if (Sizes.empty()) { if (Element_Size<28) { Element_WaitForMoreData(); return; } int32u Size=LittleEndian?LittleEndian2int32u(Buffer+Buffer_Offset+24):BigEndian2int32u(Buffer+Buffer_Offset+24); if (Size==(int32u)-1) Size=LittleEndian?LittleEndian2int32u(Buffer+Buffer_Offset+4):BigEndian2int32u(Buffer+Buffer_Offset+4); Header_Fill_Size(Size); } else Header_Fill_Size(Sizes[Sizes_Pos]); }
//--------------------------------------------------------------------------- bool File_Cdxa::FileHeader_Begin() { //Element_Size if (Buffer_Size<0x28) return false; //Must wait for more data if ( CC4(Buffer+0x00)!=0x52494646 //"RIFF" || LittleEndian2int32u(Buffer+0x04)!=LittleEndian2int32u(Buffer+0x28)+0x24 //Sizes of chunks || CC4(Buffer+0x08)!=0x43445841 //"CDXA" || CC4(Buffer+0x0C)!=0x666D7420 //"fmt " || LittleEndian2int32u(Buffer+0x10)!=0x10 || CC2(Buffer+0x1A)!=0x5841 //"XA" || CC4(Buffer+0x24)!=0x64617461) //"data" { Reject("CDXA"); return false; } //All should be OK... return true; }
//--------------------------------------------------------------------------- // RIFF Header, 44 bytes // RIFF header 4 bytes, Pos=0 // RIFF data size 4 bytes, Pos=4 // Format (CDXA) 4 bytes, Pos=8 // Format Header 4 bytes, Pos=12 // Format Size 4 bytes, Pos=16 // Format user_id 2 bytes, Pos=20 // Format group_id 2 bytes, Pos=22 // Format attributes 2 bytes, Pos=24 // Format xa_signature 2 bytes, Pos=26 ("XA") // Format xa_track_number 4 bytes, Pos=28 // Format Reserved 4 bytes, Pos=32 // Data Header 4 bytes, Pos=36 // Data Size 4 bytes, Pos=40 // // Attributes (big endian): // 15 Directory // 14 CDDA // 13 Interleaved // 12 Mode2Form2 --> 2324 bytes/block // 11 Mode2Form1 --> 2048 bytes/block // 10 Exec_Other // 09 Reserved // 08 Read_Other // 07 Reserved // 06 Exec_Group // 05 Reserved // 04 Read_Group // 03 Reserved // 02 Exec_User // 01 Reserved // 00 Read_User // void File_Cdxa::FileHeader_Parse() { //Parsing if ( CC4(Buffer+Buffer_Offset+0x00)!=CC4("RIFF") || LittleEndian2int32u(Buffer+Buffer_Offset+0x04)!=LittleEndian2int32u(Buffer+Buffer_Offset+0x28)+0x24 //Sizes of chunks || CC4(Buffer+Buffer_Offset+0x08)!=CC4("CDXA") || CC4(Buffer+Buffer_Offset+0x0C)!=CC4("fmt ") || LittleEndian2int32u(Buffer+Buffer_Offset+0x10)!=0x10 || CC4(Buffer+Buffer_Offset+0x24)!=CC4("data") ) { Finnished(); return; } //Parsing Element_Begin("CDXA header"); Skip_C4( "RIFF header"); Skip_L4( "RIFF data size"); Skip_C4( "CDXA"); Skip_C4( "fmt header"); Skip_L4( "fmt size"); Skip_L2( "user_id"); Skip_L2( "group_id"); Skip_L2( "attributes"); Skip_C2( "xa_signature"); Skip_L4( "xa_track_number"); Skip_L4( "reserved"); Skip_C4( "data header"); Skip_L4( "data size"); Element_End(); FILLING_BEGIN(); if (MI==NULL) MI=new MediaInfo; Stream_Prepare(Stream_General); FILLING_END(); }
//--------------------------------------------------------------------------- bool File_Dpg::FileHeader_Begin() { //Element_Size if (Buffer_Size<0x14) return false; //Must wait for more data if ( CC4(Buffer )!=0x44504730 //"DPG0" || LittleEndian2int32u(Buffer+0x10)!=0) //Zero { Reject("DPG"); return false; } //All should be OK... return true; }
//--------------------------------------------------------------------------- void Riff_AVI__hdrl_strl_indx::Modify_Internal () { //EntryCount int32u Entry_Count=LittleEndian2int32u(Chunk.Content.Buffer+4); bool IsChanged=false; Chunk.Content.Buffer_Offset=24; for (int32u Pos=0; Pos<Entry_Count; Pos++) { int64u Value=LittleEndian2int64u(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset); /* for (std::set<void*>::iterator movi=Global->AVI__movi_Pointers.begin(); movi!=Global->AVI__movi_Pointers.end(); movi++) if (Value>=((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position && Value<((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position+((Riff_AVI__movi*)(*movi))->Chunk.Content.Size) { if (((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position!=((Riff_AVI__movi*)(*movi))->Chunk.File_Out_Position) { Value-=((Riff_AVI__movi*)(*movi))->Chunk.File_In_Position; Value+=((Riff_AVI__movi*)(*movi))->Chunk.File_Out_Position; int64u2LittleEndian(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset, Value); IsChanged=true; } break; } */ for (std::set<void*>::iterator ix=Global->AVI__movi___ix_Pointers.begin(); ix!=Global->AVI__movi___ix_Pointers.end(); ix++) if (Value==((Riff_AVI__movi___ix*)(*ix))->Chunk.File_In_Position) { if (((Riff_AVI__movi___ix*)(*ix))->Chunk.File_Out_Position!=((Riff_AVI__movi___ix*)(*ix))->Chunk.File_In_Position) { int64u2LittleEndian(Chunk.Content.Buffer+Chunk.Content.Buffer_Offset, ((Riff_AVI__movi___ix*)(*ix))->Chunk.File_Out_Position); IsChanged=true; } break; } Chunk.Content.Buffer_Offset+=16; } if (IsChanged) Chunk.Content.IsModified=true; //Chunk.Content.Size_IsModified=true; }
//--------------------------------------------------------------------------- // Little Endian - float 32 bits float32 LittleEndian2float32(const char* Liste) { //sign 1 bit //exponent 8 bit //significand 23 bit //Retrieving data int32u Integer=LittleEndian2int32u(Liste); //Retrieving elements bool Sign =(Integer&0x80000000)?true:false; int32u Exponent=(Integer>>23)&0xFF; int32u Mantissa= Integer&0x007FFFFF; //Some computing if (Exponent==0 || Exponent==0xFF) return 0; //These are denormalised numbers, NANs, and other horrible things Exponent-=0x7F; //Bias float64 Answer=(((float64)Mantissa)/8388608+1.0)*std::pow((float64)2, (int)Exponent); //(1+Mantissa) * 2^Exponent if (Sign) Answer=-Answer; return (float32)Answer; }
//--------------------------------------------------------------------------- void File_Tiff::GetValueOffsetu(ifditem &IfdItem) { ZtringList &Info=Infos[IfdItem.Tag]; Info.clear(); Info.Separator_Set(0, __T(" / ")); const char* Name=Tiff_Tag_Name(IfdItem.Tag); if (IfdItem.Count>=10) { //Too many data, we don't currently need it and we skip it Skip_XX(Element_Size-(Element_Offset+4), Name); Info.clear(); return; } switch (IfdItem.Type) { case 1: /* 8-bit unsigned integer. */ for (int16u Pos=0; Pos<IfdItem.Count; Pos++) { int8u Ret8; #if MEDIAINFO_TRACE if (LittleEndian) Get_L1 (Ret8, Name); else Get_B1 (Ret8, Name); Element_Info1(Ztring::ToZtring(Ret8)); #else //MEDIAINFO_TRACE if (Element_Offset+1>Element_Size) { Trusted_IsNot(); break; } if (LittleEndian) Ret8=LittleEndian2int8u(Buffer+Buffer_Offset+(size_t)Element_Offset); else Ret8=BigEndian2int8u(Buffer+Buffer_Offset+(size_t)Element_Offset); Element_Offset++; #endif //MEDIAINFO_TRACE Info.push_back(Ztring::ToZtring(Ret8)); } break; case 3: /* 16-bit (2-byte) unsigned integer. */ for (int16u Pos=0; Pos<IfdItem.Count; Pos++) { int16u Ret16; #if MEDIAINFO_TRACE if (LittleEndian) Get_L2 (Ret16, Name); else Get_B2 (Ret16, Name); switch (IfdItem.Tag) { case Tiff_Tag::Compression : Element_Info1(Tiff_Compression(Ret16)); break; case Tiff_Tag::PhotometricInterpretation : Element_Info1(Tiff_PhotometricInterpretation(Ret16)); break; default : Element_Info1(Ztring::ToZtring(Ret16)); } #else //MEDIAINFO_TRACE if (Element_Offset+2>Element_Size) { Trusted_IsNot(); break; } if (LittleEndian) Ret16=LittleEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Offset); else Ret16=BigEndian2int16u(Buffer+Buffer_Offset+(size_t)Element_Offset); Element_Offset+=2; #endif //MEDIAINFO_TRACE Info.push_back(Ztring::ToZtring(Ret16)); } break; case 4: /* 32-bit (4-byte) unsigned integer */ for (int16u Pos=0; Pos<IfdItem.Count; Pos++) { int32u Ret32; #if MEDIAINFO_TRACE if (LittleEndian) Get_L4 (Ret32, Name); else Get_B4 (Ret32, Name); Element_Info1(Ztring::ToZtring(Ret32)); #else //MEDIAINFO_TRACE if (Element_Offset+4>Element_Size) { Trusted_IsNot(); break; } if (LittleEndian) Ret32=LittleEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset); else Ret32=BigEndian2int32u(Buffer+Buffer_Offset+(size_t)Element_Offset); Element_Offset+=4; #endif //MEDIAINFO_TRACE Info.push_back(Ztring::ToZtring(Ret32)); } break; default: //Unknown { if (LittleEndian) Skip_L4( Name); else Skip_B4( Name); Info.clear(); //We actually do not know the type } } }