本文整理汇总了C++中XMP_IO::Offset方法的典型用法代码示例。如果您正苦于以下问题:C++ XMP_IO::Offset方法的具体用法?C++ XMP_IO::Offset怎么用?C++ XMP_IO::Offset使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类XMP_IO
的用法示例。
在下文中一共展示了XMP_IO::Offset方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: WriteTempFile
void GIF_MetaHandler::WriteTempFile ( XMP_IO* tempRef )
{
XMP_Assert( this->needsUpdate );
XMP_IO* originalRef = this->parent->ioRef;
originalRef->Rewind();
tempRef->Truncate ( 0 );
if ( XMPPacketOffset != 0 )
{
// Copying blocks before XMP Application Block
XIO::Copy( originalRef, tempRef, XMPPacketOffset );
// Writing XMP Packet
tempRef->Write( this->xmpPacket.c_str(), (XMP_Uns32)this->xmpPacket.size() );
// Copying Rest of the file
originalRef->Seek( XMPPacketLength, kXMP_SeekFromCurrent );
XIO::Copy( originalRef, tempRef, originalRef->Length() - originalRef->Offset() );
}
else
{
if ( trailerOffset == 0 )
XMP_Throw( "Not able to write XMP packet in GIF file", kXMPErr_BadFileFormat );
// Copying blocks before XMP Application Block
XIO::Copy( originalRef, tempRef, trailerOffset );
// Writing Extension Introducer
XIO::WriteUns8( tempRef, kXMP_block_Extension );
// Writing Application Extension label
XIO::WriteUns8( tempRef, 0xFF );
// Writing Application Extension label
XIO::WriteUns8( tempRef, APP_ID_LEN );
// Writing Application Extension label
tempRef->Write( XMP_APP_ID_DATA, APP_ID_LEN );
// Writing XMP Packet
tempRef->Write( this->xmpPacket.c_str(), (XMP_Uns32)this->xmpPacket.size() );
// Writing Magic trailer
XMP_Uns8 magicByte = 0x01;
tempRef->Write( &magicByte, 1 );
for ( magicByte = 0xFF; magicByte != 0x00; --magicByte )
tempRef->Write( &magicByte, 1 );
tempRef->Write( &magicByte, 1 );
tempRef->Write( &magicByte, 1 );
// Copying Rest of the file
XIO::Copy( originalRef, tempRef, originalRef->Length() - originalRef->Offset() );
}
} // GIF_MetaHandler::WriteTempFile
示例2: CacheFileData
void RIFF_MetaHandler::CacheFileData()
{
this->containsXMP = false; //assume for now
XMP_IO* file = this->parent->ioRef;
this->oldFileSize = file ->Length();
if ( (this->parent->format == kXMP_WAVFile) && (this->oldFileSize > 0xFFFFFFFF) )
XMP_Throw ( "RIFF_MetaHandler::CacheFileData: WAV Files larger 4GB not supported", kXMPErr_Unimplemented );
file ->Rewind();
this->level = 0;
// parse top-level chunks (most likely just one, except large avi files)
XMP_Int64 filePos = 0;
while ( filePos < this->oldFileSize )
{
this->riffChunks.push_back( (RIFF::ContainerChunk*) RIFF::getChunk( NULL, this ) );
// Tolerate limited forms of trailing garbage in a file. Some apps append private data.
filePos = file->Offset();
XMP_Int64 fileTail = this->oldFileSize - filePos;
if ( fileTail != 0 ) {
if ( fileTail < 12 ) {
this->oldFileSize = filePos; // Pretend the file is smaller.
this->trailingGarbageSize = fileTail;
} else if ( this->parent->format == kXMP_WAVFile ) {
if ( fileTail < 1024*1024 ) {
this->oldFileSize = filePos; // Pretend the file is smaller.
this->trailingGarbageSize = fileTail;
} else {
XMP_Throw ( "Excessive garbage at end of file", kXMPErr_BadFileFormat )
}
} else {
XMP_Int32 chunkInfo [3];
file->ReadAll ( &chunkInfo, 12 );
file->Seek ( -12, kXMP_SeekFromCurrent );
if ( (GetUns32LE ( &chunkInfo[0] ) != RIFF::kChunk_RIFF) || (GetUns32LE ( &chunkInfo[2] ) != RIFF::kType_AVIX) ) {
if ( fileTail < 1024*1024 ) {
this->oldFileSize = filePos; // Pretend the file is smaller.
this->trailingGarbageSize = fileTail;
} else {
XMP_Throw ( "Excessive garbage at end of file", kXMPErr_BadFileFormat )
}
}
}
}
}
示例3:
// parsing creation
Chunk::Chunk( ContainerChunk* parent_, RIFF_MetaHandler* handler, bool skip, ChunkType c )
{
chunkType = c; // base class assumption
this->parent = parent_;
this->oldSize = 0;
this->hasChange = false; // [2414649] valid assumption at creation time
XMP_IO* file = handler->parent->ioRef;
this->oldPos = file->Offset();
this->id = XIO::ReadUns32_LE( file );
this->oldSize = XIO::ReadUns32_LE( file );
this->oldSize += 8;
// Make sure the size is within expected bounds.
XMP_Int64 chunkEnd = this->oldPos + this->oldSize;
XMP_Int64 chunkLimit = handler->oldFileSize;
if ( parent_ != 0 ) chunkLimit = parent_->oldPos + parent_->oldSize;
if ( chunkEnd > chunkLimit ) {
bool isUpdate = XMP_OptionIsSet ( handler->parent->openFlags, kXMPFiles_OpenForUpdate );
bool repairFile = XMP_OptionIsSet ( handler->parent->openFlags, kXMPFiles_OpenRepairFile );
if ( (! isUpdate) || (repairFile && (parent_ == 0)) ) {
this->oldSize = chunkLimit - this->oldPos;
} else {
XMP_Throw ( "Bad RIFF chunk size", kXMPErr_BadFileFormat );
}
}
this->newSize = this->oldSize;
this->needSizeFix = false;
if ( skip ) file->Seek ( (this->oldSize - 8), kXMP_SeekFromCurrent );
// "good parenting", essential for latter destruction.
if ( this->parent != NULL )
{
this->parent->children.push_back( this );
if( this->chunkType == chunk_VALUE )
this->parent->childmap.insert( std::make_pair( this->id, (ValueChunk*) this ) );
}
}
示例4: if
// b) parsing
ContainerChunk::ContainerChunk( ContainerChunk* parent, RIFF_MetaHandler* handler ) : Chunk( parent, handler, false, chunk_CONTAINER )
{
bool repairMode = ( 0 != ( handler->parent->openFlags & kXMPFiles_OpenRepairFile ));
try
{
XMP_IO* file = handler->parent->ioRef;
XMP_Uns8 level = handler->level;
// get type of container chunk
this->containerType = XIO::ReadUns32_LE( file );
// ensure legality of top-level chunks
if ( level == 0 && handler->riffChunks.size() > 0 )
{
XMP_Validate( handler->parent->format == kXMP_AVIFile, "only AVI may have multiple top-level chunks", kXMPErr_BadFileFormat );
XMP_Validate( this->containerType == kType_AVIX, "all chunks beyond main chunk must be type AVIX", kXMPErr_BadFileFormat );
}
// has *relevant* subChunks? (there might be e.g. non-INFO LIST chunks we don't care about)
bool hasSubChunks = ( ( this->id == kChunk_RIFF ) ||
( this->id == kChunk_LIST && this->containerType == kType_INFO ) ||
( this->id == kChunk_LIST && this->containerType == kType_Tdat ) ||
( this->id == kChunk_LIST && this->containerType == kType_hdrl )
);
XMP_Int64 endOfChunk = this->oldPos + this->oldSize;
// this statement catches beyond-EoF-offsets on any level
// exception: level 0, tolerate if in repairMode
if ( (level == 0) && repairMode && (endOfChunk > handler->oldFileSize) )
{
endOfChunk = handler->oldFileSize; // assign actual file size
this->oldSize = endOfChunk - this->oldPos; //reversely calculate correct oldSize
}
XMP_Validate( endOfChunk <= handler->oldFileSize, "offset beyond EoF", kXMPErr_BadFileFormat );
Chunk* curChild = 0;
if ( hasSubChunks )
{
handler->level++;
while ( file->Offset() < endOfChunk )
{
curChild = RIFF::getChunk( this, handler );
// digest pad byte - no value validation (0), since some 3rd party files have non-0-padding.
if ( file->Offset() % 2 == 1 )
{
// [1521093] tolerate missing pad byte at very end of file:
XMP_Uns8 pad;
file->Read ( &pad, 1 ); // Read the pad, tolerate being at EOF.
}
// within relevant LISTs, relentlesly delete junk chunks (create a single one
// at end as part of updateAndChanges()
if ( (containerType== kType_INFO || containerType == kType_Tdat)
&& ( curChild->chunkType == chunk_JUNK ) )
{
this->children.pop_back();
delete curChild;
} // for other chunks: join neighouring Junk chunks into one
else if ( (curChild->chunkType == chunk_JUNK) && ( this->children.size() >= 2 ) )
{
// nb: if there are e.g 2 chunks, then last one is at(1), prev one at(0) ==> '-2'
Chunk* prevChunk = this->children.at( this->children.size() - 2 );
if ( prevChunk->chunkType == chunk_JUNK )
{
// stack up size to prior chunk
prevChunk->oldSize += curChild->oldSize;
prevChunk->newSize += curChild->newSize;
XMP_Enforce( prevChunk->oldSize == prevChunk->newSize );
// destroy current chunk
this->children.pop_back();
delete curChild;
}
}
}
handler->level--;
XMP_Validate( file->Offset() == endOfChunk, "subchunks exceed outer chunk size", kXMPErr_BadFileFormat );
// pointers for later legacy processing
if ( level==1 && this->id==kChunk_LIST && this->containerType == kType_INFO )
handler->listInfoChunk = this;
if ( level==1 && this->id==kChunk_LIST && this->containerType == kType_Tdat )
handler->listTdatChunk = this;
if ( level == 1 && this->id == kChunk_LIST && this->containerType == kType_hdrl )
handler->listHdlrChunk = this;
}
else // skip non-interest container chunk
{
file->Seek ( (this->oldSize - 8 - 4), kXMP_SeekFromCurrent );
} // if - else
} // try
catch (XMP_Error& e) {
this->release(); // free resources
if ( this->parent != 0)
this->parent->children.pop_back(); // hereby taken care of, so removing myself...
//.........这里部分代码省略.........
示例5: WriteTempFile
// =================================================================================================
// SVG_MetaHandler::WriteTempFile
// ==============================
//
void SVG_MetaHandler::WriteTempFile( XMP_IO* tempRef )
{
XMP_Assert( this->needsUpdate );
XMP_IO* sourceRef = this->parent->ioRef;
if ( sourceRef == NULL || svgNode == NULL )
return;
tempRef->Rewind();
sourceRef->Rewind();
XMP_Int64 currentOffset = svgAdapter->firstSVGElementOffset;
XIO::Copy( sourceRef, tempRef, currentOffset );
OffsetStruct titleOffset = svgAdapter->GetElementOffsets( "title" );
OffsetStruct descOffset = svgAdapter->GetElementOffsets( "desc" );
OffsetStruct metadataOffset = svgAdapter->GetElementOffsets( "metadata" );
std::string title;
std::string description;
XML_NodePtr titleNode = svgNode->GetNamedElement( svgNode->ns.c_str(), "title" );
( void ) this->xmpObj.GetLocalizedText( kXMP_NS_DC, "title", "", "x-default", 0, &title, 0 );
XML_NodePtr descNode = svgNode->GetNamedElement( svgNode->ns.c_str(), "desc" );
( void ) this->xmpObj.GetLocalizedText( kXMP_NS_DC, "description", "", "x-default", 0, &description, 0 );
// Need to cover the case of both workflows
// This would have been called after inplace is not possible
// This would have called for safe update
if ( !isTitleUpdateReq )
{
if ( ( titleNode == NULL ) == ( title.empty() ) )
{
if ( titleNode != NULL && titleNode->content.size() == 1 && titleNode->content[ 0 ]->kind == kCDataNode && !XMP_LitMatch( titleNode->content[ 0 ]->value.c_str(), title.c_str() ) )
isTitleUpdateReq = true;
}
else
isTitleUpdateReq = true;
}
if ( !isDescUpdateReq )
{
if ( ( descNode == NULL ) == ( description.empty() ) )
{
if ( descNode != NULL && descNode->content.size() == 1 && descNode->content[ 0 ]->kind == kCDataNode && !XMP_LitMatch( descNode->content[ 0 ]->value.c_str(), description.c_str() ) )
isDescUpdateReq = true;
}
else
isDescUpdateReq = true;
}
// Initial Insertion/Updation
// Insert/Update Title if requires
// Don't insert/update it if Metadata or desc child comes before title child
bool isTitleWritten = !isTitleUpdateReq;
if ( isTitleUpdateReq )
{
// Insertion Case
if ( titleNode == NULL )
{
InsertNewTitle( tempRef, title );
isTitleWritten = true;
}
else if ( ( descOffset.startOffset == -1 || titleOffset.startOffset < descOffset.startOffset ) // Updation/Deletion Case
&& ( metadataOffset.startOffset == -1 || titleOffset.startOffset < metadataOffset.startOffset ) )
{
ProcessTitle( sourceRef, tempRef, title, currentOffset, titleOffset );
isTitleWritten = true;
}
}
// Insert/Update Description if requires
// Don't insert/update it if Metadata child comes before desc child
bool isDescWritten = !isDescUpdateReq;
if ( isDescUpdateReq )
{
if ( descNode == NULL )
{
if ( titleOffset.nextOffset != -1 )
{
XIO::Copy( sourceRef, tempRef, titleOffset.nextOffset - currentOffset );
currentOffset = titleOffset.nextOffset;
}
InsertNewDescription( tempRef, description );
isDescWritten = true;
}
else if ( metadataOffset.startOffset == -1 || descOffset.startOffset < metadataOffset.startOffset )
{
ProcessDescription( sourceRef, tempRef, description, currentOffset, descOffset );
isDescWritten = true;
}
}
// Insert/Update Metadata if requires
// Don't insert/update it if case is DTM
//.........这里部分代码省略.........
示例6: WriteTempFile
//.........这里部分代码省略.........
while ( psirLen > 0 ) {
XMP_Uns32 count = std::min ( psirLen, (XMP_Uns32) kPSIRMaxDataLength );
first4 = MakeUns32BE ( 0xFFED0000 + 2 + kPSIRSignatureLength + count );
tempRef->Write ( &first4, 4 );
tempRef->Write ( kPSIRSignatureString, kPSIRSignatureLength );
tempRef->Write ( psirPtr, count );
psirPtr = (XMP_Uns8 *) psirPtr + count;
psirLen -= count;
}
}
// Copy remaining marker segments, skipping old metadata, to the first SOS marker or to EOI.
origRef->Seek ( -2, kXMP_SeekFromCurrent ); // Back up to the marker from the end of the APP0 copy loop.
while ( true ) {
if ( checkAbort && abortProc(abortArg) ) {
XMP_Throw ( "JPEG_MetaHandler::WriteFile - User abort", kXMPErr_UserAbort );
}
if ( ! XIO::CheckFileSpace ( origRef, 2 ) ) break; // Tolerate a file that ends abruptly.
marker = XIO::ReadUns16_BE ( origRef ); // Read the next marker.
if ( marker == 0xFFFF ) {
// Have a pad byte, skip it. These are almost unheard of, so efficiency isn't critical.
origRef->Seek ( -1, kXMP_SeekFromCurrent ); // Skip the first 0xFF, read the second again.
continue;
}
if ( (marker == 0xFFDA) || (marker == 0xFFD9) ) { // Quit at the first SOS marker or at EOI.
origRef->Seek ( -2, kXMP_SeekFromCurrent ); // The tail copy must include this marker.
break;
}
if ( (marker == 0xFF01) || // Ill-formed file if we encounter a TEM or RSTn marker.
((0xFFD0 <= marker) && (marker <= 0xFFD7)) ) {
XMP_Throw ( "Unexpected TEM or RSTn marker", kXMPErr_BadJPEG );
}
contentLen = XIO::ReadUns16_BE ( origRef ); // Read this segment's length.
if ( contentLen < 2 ) XMP_Throw ( "Invalid JPEG segment length", kXMPErr_BadJPEG );
contentLen -= 2; // Reduce to just the content length.
XMP_Int64 contentOrigin = origRef->Offset();
bool copySegment = true;
size_t signatureLen;
if ( (marker == 0xFFED) && (contentLen >= kPSIRSignatureLength) ) {
// This is an APP13 segment, skip if it is the old PSIR.
signatureLen = origRef->Read ( buffer, kPSIRSignatureLength );
if ( (signatureLen == kPSIRSignatureLength) &&
CheckBytes ( &buffer[0], kPSIRSignatureString, kPSIRSignatureLength ) ) {
copySegment = false;
}
} else if ( (marker == 0xFFE1) && (contentLen >= kExifSignatureLength) ) { // Check for the shortest signature.
// This is an APP1 segment, skip if it is the old Exif or XMP.
XMP_Assert ( (kExifSignatureLength < kMainXMPSignatureLength) &&
(kMainXMPSignatureLength < kExtXMPSignatureLength) );
signatureLen = origRef->Read ( buffer, kExtXMPSignatureLength ); // Read for the longest signature.
if ( (signatureLen >= kExifSignatureLength) &&
(CheckBytes ( &buffer[0], kExifSignatureString, kExifSignatureLength ) ||
CheckBytes ( &buffer[0], kExifSignatureAltStr, kExifSignatureLength )) ) {
copySegment = false;
}
if ( copySegment && (signatureLen >= kMainXMPSignatureLength) &&
CheckBytes ( &buffer[0], kMainXMPSignatureString, kMainXMPSignatureLength ) ) {
copySegment = false;
}
if ( copySegment && (signatureLen == kExtXMPSignatureLength) &&
CheckBytes ( &buffer[0], kExtXMPSignatureString, kExtXMPPrefixLength ) ) {
copySegment = false;
}
}
if ( ! copySegment ) {
origRef->Seek ( (contentOrigin + contentLen), kXMP_SeekFromStart );
} else {
XIO::WriteUns16_BE ( tempRef, marker );
XIO::WriteUns16_BE ( tempRef, (contentLen + 2) );
origRef->Seek ( contentOrigin, kXMP_SeekFromStart );
origRef->ReadAll ( buffer, contentLen );
tempRef->Write ( buffer, contentLen );
}
}
// Copy the remainder of the source file.
XIO::Copy ( origRef, tempRef, (origLength - origRef->Offset()) );
this->needsUpdate = false;
} // JPEG_MetaHandler::WriteTempFile
示例7: CacheFileData
void JPEG_MetaHandler::CacheFileData()
{
XMP_IO* fileRef = this->parent->ioRef;
XMP_PacketInfo & packetInfo = this->packetInfo;
static const size_t kBufferSize = 64*1024; // Enough for maximum segment contents.
XMP_Uns8 buffer [kBufferSize];
psirContents.clear();
exifContents.clear();
XMP_AbortProc abortProc = this->parent->abortProc;
void * abortArg = this->parent->abortArg;
const bool checkAbort = (abortProc != 0);
ExtendedXMPInfo extXMP;
XMP_Assert ( ! this->containsXMP );
// Set containsXMP to true here only if the standard XMP packet is found.
XMP_Assert ( kPSIRSignatureLength == (strlen(kPSIRSignatureString) + 1) );
XMP_Assert ( kMainXMPSignatureLength == (strlen(kMainXMPSignatureString) + 1) );
XMP_Assert ( kExtXMPSignatureLength == (strlen(kExtXMPSignatureString) + 1) );
// -------------------------------------------------------------------------------------------
// Look for any of the Exif, PSIR, main XMP, or extended XMP marker segments. Quit when we hit
// an SOFn, EOI, or invalid/unexpected marker.
fileRef->Seek ( 2, kXMP_SeekFromStart ); // Skip the SOI, CheckFormat made sure it is present.
while ( true ) {
if ( checkAbort && abortProc(abortArg) ) {
XMP_Throw ( "JPEG_MetaHandler::CacheFileData - User abort", kXMPErr_UserAbort );
}
if ( ! XIO::CheckFileSpace ( fileRef, 2 ) ) return; // Quit, don't throw, if the file ends unexpectedly.
XMP_Uns16 marker = XIO::ReadUns16_BE ( fileRef ); // Read the next marker.
if ( marker == 0xFFFF ) {
// Have a pad byte, skip it. These are almost unheard of, so efficiency isn't critical.
fileRef->Seek ( -1, kXMP_SeekFromCurrent ); // Skip the first 0xFF, read the second again.
continue;
}
if ( (marker == 0xFFDA) || (marker == 0xFFD9) ) break; // Quit reading at the first SOS marker or at EOI.
if ( (marker == 0xFF01) || // Ill-formed file if we encounter a TEM or RSTn marker.
((0xFFD0 <= marker) && (marker <= 0xFFD7)) ) return;
XMP_Uns16 contentLen = XIO::ReadUns16_BE ( fileRef ); // Read this segment's length.
if ( contentLen < 2 ) XMP_Throw ( "Invalid JPEG segment length", kXMPErr_BadJPEG );
contentLen -= 2; // Reduce to just the content length.
XMP_Int64 contentOrigin = fileRef->Offset();
size_t signatureLen;
if ( (marker == 0xFFED) && (contentLen >= kPSIRSignatureLength) ) {
// This is an APP13 marker, is it the Photoshop image resources?
signatureLen = fileRef->Read ( buffer, kPSIRSignatureLength );
if ( (signatureLen == kPSIRSignatureLength) &&
CheckBytes ( &buffer[0], kPSIRSignatureString, kPSIRSignatureLength ) ) {
size_t psirLen = contentLen - kPSIRSignatureLength;
fileRef->Seek ( (contentOrigin + kPSIRSignatureLength), kXMP_SeekFromStart );
fileRef->ReadAll ( buffer, psirLen );
this->psirContents.append( (char *) buffer, psirLen );
continue; // Move on to the next marker.
}
} else if ( (marker == 0xFFE1) && (contentLen >= kExifSignatureLength) ) { // Check for the shortest signature.
// This is an APP1 marker, is it the Exif, main XMP, or extended XMP?
// ! Check in that order, which is in increasing signature string length.
XMP_Assert ( (kExifSignatureLength < kMainXMPSignatureLength) &&
(kMainXMPSignatureLength < kExtXMPSignatureLength) );
signatureLen = fileRef->Read ( buffer, kExtXMPSignatureLength ); // Read for the longest signature.
if ( (signatureLen >= kExifSignatureLength) &&
(CheckBytes ( &buffer[0], kExifSignatureString, kExifSignatureLength ) ||
CheckBytes ( &buffer[0], kExifSignatureAltStr, kExifSignatureLength )) ) {
size_t exifLen = contentLen - kExifSignatureLength;
fileRef->Seek ( (contentOrigin + kExifSignatureLength), kXMP_SeekFromStart );
fileRef->ReadAll ( buffer, exifLen );
this->exifContents.append ( (char*)buffer, exifLen );
continue; // Move on to the next marker.
}
if ( (signatureLen >= kMainXMPSignatureLength) &&
CheckBytes ( &buffer[0], kMainXMPSignatureString, kMainXMPSignatureLength ) ) {
this->containsXMP = true; // Found the standard XMP packet.
size_t xmpLen = contentLen - kMainXMPSignatureLength;
fileRef->Seek ( (contentOrigin + kMainXMPSignatureLength), kXMP_SeekFromStart );
//.........这里部分代码省略.........
示例8: while
void MP3_MetaHandler::CacheFileData()
{
//*** abort procedures
this->containsXMP = false; //assume no XMP for now
XMP_IO* file = this->parent->ioRef;
XMP_PacketInfo &packetInfo = this->packetInfo;
file->Rewind();
this->hasID3Tag = this->id3Header.read( file );
this->majorVersion = this->id3Header.fields[ID3Header::o_vMajor];
this->minorVersion = this->id3Header.fields[ID3Header::o_vMinor];
this->hasExtHeader = (0 != ( 0x40 & this->id3Header.fields[ID3Header::o_flags])); //'naturally' false if no ID3Tag
this->hasFooter = ( 0 != ( 0x10 & this->id3Header.fields[ID3Header::o_flags])); //'naturally' false if no ID3Tag
// stored size is w/o initial header (thus adding 10)
// + but extended header (if existing)
// + padding + frames after unsynchronisation (?)
// (if no ID3 tag existing, constructed default correctly sets size to 10.)
this->oldTagSize = ID3Header::kID3_TagHeaderSize + synchToInt32(GetUns32BE( &id3Header.fields[ID3Header::o_size] ));
if ( ! hasExtHeader ) {
this->extHeaderSize = 0; // := there is no such header.
} else {
this->extHeaderSize = synchToInt32( XIO::ReadInt32_BE( file));
XMP_Uns8 extHeaderNumFlagBytes = XIO::ReadUns8( file );
// v2.3 doesn't include the size, while v2.4 does
if ( this->majorVersion < 4 ) this->extHeaderSize += 4;
XMP_Validate( this->extHeaderSize >= 6, "extHeader size too small", kXMPErr_BadFileFormat );
file->Seek ( this->extHeaderSize - 6, kXMP_SeekFromCurrent );
}
this->framesVector.clear(); //mac precaution
ID3v2Frame* curFrame = 0; // reusable
////////////////////////////////////////////////////
// read frames
XMP_Uns32 xmpID = XMP_V23_ID;
if ( this->majorVersion == 2 ) xmpID = XMP_V22_ID;
while ( file->Offset() < this->oldTagSize ) {
curFrame = new ID3v2Frame();
try {
XMP_Int64 frameSize = curFrame->read ( file, this->majorVersion );
if ( frameSize == 0 ) {
delete curFrame; // ..since not becoming part of vector for latter delete.
break; // not a throw. There's nothing wrong with padding.
}
this->containsXMP = true;
} catch ( ... ) {
delete curFrame;
throw;
}
// these are both pointer assignments, no (copy) construction
// (MemLeak Note: for all things pushed, memory cleanup is taken care of in destructor.)
this->framesVector.push_back ( curFrame );
//remember XMP-Frame, if it occurs:
if ( (curFrame->id ==xmpID) &&
(curFrame->contentSize > 8) && CheckBytes ( &curFrame->content[0], "XMP\0", 4 ) ) {
// be sure that this is the first packet (all else would be illegal format)
XMP_Validate ( this->framesMap[xmpID] == 0, "two XMP packets in one file", kXMPErr_BadFileFormat );
//add this to map, needed on reconciliation
this->framesMap[xmpID] = curFrame;
this->packetInfo.length = curFrame->contentSize - 4; // content minus "XMP\0"
this->packetInfo.offset = ( file->Offset() - this->packetInfo.length );
this->xmpPacket.erase(); //safety
this->xmpPacket.assign( &curFrame->content[4], curFrame->contentSize - 4 );
this->containsXMP = true; // do this last, after all possible failure
}
// No space for another frame? => assume into ID3v2.4 padding.
XMP_Int64 newPos = file->Offset();
XMP_Int64 spaceLeft = this->oldTagSize - newPos; // Depends on first check below!
if ( (newPos > this->oldTagSize) || (spaceLeft < (XMP_Int64)ID3Header::kID3_TagHeaderSize) ) break;
}
////////////////////////////////////////////////////
// padding
this->oldPadding = this->oldTagSize - file->Offset();
this->oldFramesSize = this->oldTagSize - ID3Header::kID3_TagHeaderSize - this->oldPadding;
//.........这里部分代码省略.........