/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license that can
* be found in the License.html file in the root of the source tree.
*/
//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#if defined(MEDIAINFO_CDXA_YES)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Multiple/File_Cdxa.h"
#include "ZenLib/Utils.h"
#include "MediaInfo/MediaInfo_Internal.h"
#if MEDIAINFO_EVENTS
#include "MediaInfo/MediaInfo_Events.h"
#endif //MEDIAINFO_EVENTS
using namespace ZenLib;
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Format
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// CDXA = RIFF header + Raw sectors
// Riff header size = 44
// Raw sector size = 2352
//
// Raw sector :
// Sync 12 bytes (00 FF .. FF 00)
// Header 4 bytes
// SubHeader 8 bytes
// Datas 2324 bytes
// EDC (CRC) 4 bytes
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//***************************************************************************
// Constructor/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
File_Cdxa::File_Cdxa()
:File__Analyze()
{
//Configuration
ParserName="CDXA";
#if MEDIAINFO_EVENTS
ParserIDs[0]=MediaInfo_Parser_Cdxa;
StreamIDs_Width[0]=0;
#endif //MEDIAINFO_EVENTS
MustSynchronize=true;
//Temp
MI=NULL;
}
//---------------------------------------------------------------------------
File_Cdxa::~File_Cdxa()
{
delete MI; //MI=NULL;
}
//***************************************************************************
// Buffer - File header
//***************************************************************************
// 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
//---------------------------------------------------------------------------
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;
}
//---------------------------------------------------------------------------
void File_Cdxa::FileHeader_Parse()
{
//Parsing
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");
FILLING_BEGIN();
Accept("CDXA");
MI=new MediaInfo_Internal;
MI->Option(__T("FormatDetection_MaximumOffset"), __T("1048576"));
MI->Option(__T("File_IsReferenced"), __T("1"));
//MI->Option(__T("File_IsSub"), __T("1"));
MI->Open_Buffer_Init(File_Size, File_Offset+Buffer_Offset);
FILLING_END();
}
//***************************************************************************
// Buffer - Synchro
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Cdxa::Synchronize()
{
//Synchronizing
while ( Buffer_Offset+2352*3+12<=Buffer_Size
&& !(CC8(Buffer+Buffer_Offset+2352*0)==0x00FFFFFFFFFFFFFFLL && CC4(Buffer+Buffer_Offset+2352*0+8)==0xFFFFFF00
&& CC8(Buffer+Buffer_Offset+2352*1)==0x00FFFFFFFFFFFFFFLL && CC4(Buffer+Buffer_Offset+2352*1+8)==0xFFFFFF00
&& CC8(Buffer+Buffer_Offset+2352*2)==0x00FFFFFFFFFFFFFFLL && CC4(Buffer+Buffer_Offset+2352*2+8)==0xFFFFFF00
&& CC8(Buffer+Buffer_Offset+2352*3)==0x00FFFFFFFFFFFFFFLL && CC4(Buffer+Buffer_Offset+2352*3+8)==0xFFFFFF00))
Buffer_Offset++;
if (Buffer_Offset+2352*3+12>Buffer_Size)
return false;
//Synched is OK
return true;
}
//---------------------------------------------------------------------------
bool File_Cdxa::Synched_Test()
{
//Must have enough buffer for having header
if (Buffer_Offset+12>Buffer_Size)
return false;
//Quick test of synchro
if (!(CC8(Buffer+Buffer_Offset)==0x00FFFFFFFFFFFFFFLL && CC4(Buffer+Buffer_Offset+8)==0xFFFFFF00))
Synched=false;
//We continue
return true;
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Cdxa::Streams_Finish ()
{
if (!MI)
return;
//If nothing
if (MI->Info==NULL || !MI->Info->Status[IsAccepted])
{
Fill(Stream_General, 0, General_Format, "CDXA");
}
else
{
//General
MI->Info->Open_Buffer_Finalize();
Merge(*(MI->Info));
Merge(*(MI->Info), Stream_General, 0, 0);
const Ztring &Format=Retrieve(Stream_General, 0, General_Format);
Fill(Stream_General, 0, General_Format, (Ztring(__T("CDXA/"))+Format).c_str(), Unlimited, true);
Clear(Stream_General, 0, General_Duration);
Clear(Stream_Video, 0, Video_Duration);
}
//Purge what is not needed anymore
if (!File_Name.empty()) //Only if this is not a buffer, with buffer we can have more data
{
delete MI; MI=NULL;
}
}
//***************************************************************************
// Buffer - Per element
//***************************************************************************
//---------------------------------------------------------------------------
void File_Cdxa::Header_Parse()
{
//Parsing
Skip_B4( "Sync1");
Skip_B4( "Sync2");
Skip_B4( "Sync3");
Skip_B4( "Header");
Skip_B8( "SubHeader");
//Filling
Header_Fill_Size(2352);
Header_Fill_Code(0, "Chunk");
}
//---------------------------------------------------------------------------
void File_Cdxa::Data_Parse()
{
if (MI==NULL)
{
//Where is the header? --> Problem
Reject("CDXA");
return;
}
//CRC or not?
int64u CRC_Size=4;
if (Element_Size!=2328)
CRC_Size=0;
//Parsing
Skip_XX(Element_Size-CRC_Size, "Data");
if (CRC_Size>0)
Skip_B4( "CRC");
//Preparing to fill MediaInfo with a buffer
MI->Open_Buffer_Position_Set(File_Offset+Buffer_Offset);
//Sending the buffer to MediaInfo
MI->Open_Buffer_Continue(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size));
//Testing if filled
if (MI->Info->Status[IsFilled]) {
}
//Testing if MediaInfo always need data
File_GoTo=MI->Open_Buffer_Continue_GoTo_Get();
if (File_GoTo==(int64u)-1 && MI->Info->Status[IsFilled] && File_Size!=(int64u)-1 && File_Offset+Buffer_Size<File_Size/2)
GoToFromEnd(File_Offset+Buffer_Size);
if (File_GoTo!=(int64u)-1)
Info("CDXA, Jumping to end of file");
//Details
#if MEDIAINFO_TRACE
if (Config_Trace_Level)
{
if (!MI->Inform().empty())
Element_Show_Add(MI->Info);
}
#endif //MEDIAINFO_TRACE
//Demux
Demux(Buffer+Buffer_Offset, (size_t)(Element_Size-CRC_Size), ContentType_MainStream);
}
} //NameSpace
#endif //MEDIAINFO_CDXA_YES
↑ V525 The code contains the collection of similar blocks. Check items '4', '2', '2', '2' in lines 145, 146, 147, 148.