本文整理汇总了C++中XMP_IO::Seek方法的典型用法代码示例。如果您正苦于以下问题:C++ XMP_IO::Seek方法的具体用法?C++ XMP_IO::Seek怎么用?C++ XMP_IO::Seek使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类XMP_IO
的用法示例。
在下文中一共展示了XMP_IO::Seek方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: UpdateXMP
void Matroska_MetaHandler::UpdateXMP()
{
XMP_IO* fileRef = parent->ioRef;
fileRef->Seek(fileRef->Length(), kXMP_SeekFromStart);
for (auto segment : _dom->_root->getElementsById(kSegment))
{
for (auto tags : segment->getElementsById(kTags))
{
for (auto tag : tags->getElementsById(kTag))
{
for (auto simple_tag : tag->getElementsById(kSimpleTag))
{
auto tag_name = simple_tag->getElementById(kTagName);
if (tag_name->_value.StringValue == "XMP")
{
auto tag_string = simple_tag->getElementById(kTagString);
// we have found valid XMP, and if it's in the very end of file, we can truncate segment
if (tag_string->_offset + tag_string->size() == fileRef->Length())
{
segment->_size._value -= tags->size();
fileRef->Truncate(tags->_offset);
fileRef->Seek(tags->_offset, kXMP_SeekFromStart);
}
// otherwise, make old XMP tag Void and create new one from the scratch
else
{
tags->wipe(fileRef);
}
}
}
}
}
}
auto segments = _dom->_root->getElementsById(kSegment);
auto segment = segments.back();
auto tag_name = std::make_shared<ebml_element_t>(kTagName, ebml_variant_t("XMP"));
auto tag_string = std::make_shared<ebml_element_t>(kTagString, ebml_variant_t(xmpPacket));
auto tag_language = std::make_shared<ebml_element_t>(kTagLanguage, ebml_variant_t("eng"));
auto tag_default = std::make_shared<ebml_element_t>(kTagDefault, ebml_variant_t(1ULL));
auto simple_tag = std::make_shared<ebml_element_t>(kSimpleTag, ebml_element_t::vec{ tag_language, tag_default, tag_name, tag_string });
auto tag = std::make_shared<ebml_element_t>(kTag, simple_tag);
auto tags = std::make_shared<ebml_element_t>(kTags, tag);
tags->write(fileRef);
segment->_size._value += tags->size();
segment->update_header(fileRef);
}
示例2: 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
示例3: 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 )
}
}
}
}
}
示例4: UpdateFile
void FLV_MetaHandler::UpdateFile ( bool doSafeUpdate )
{
if ( ! this->needsUpdate ) return;
XMP_Assert ( ! doSafeUpdate ); // This should only be called for "unsafe" updates.
XMP_AbortProc abortProc = this->parent->abortProc;
void * abortArg = this->parent->abortArg;
const bool checkAbort = (abortProc != 0);
XMP_IO* fileRef = this->parent->ioRef;
XMP_Uns64 fileSize = fileRef->Length();
// Make sure the XMP has a legacy digest if appropriate.
if ( ! this->onMetaData.empty() ) {
std::string newDigest;
this->MakeLegacyDigest ( &newDigest );
this->xmpObj.SetStructField ( kXMP_NS_XMP, "NativeDigests",
kXMP_NS_XMP, "FLV", newDigest.c_str(), kXMP_DeleteExisting );
try {
XMP_StringLen xmpLen = (XMP_StringLen)this->xmpPacket.size();
this->xmpObj.SerializeToBuffer ( &this->xmpPacket, (kXMP_UseCompactFormat | kXMP_ExactPacketLength), xmpLen );
} catch ( ... ) {
this->xmpObj.SerializeToBuffer ( &this->xmpPacket, kXMP_UseCompactFormat );
}
}
// Rewrite the packet in-place if it fits. Otherwise rewrite the whole file.
if ( this->xmpPacket.size() == (size_t)this->packetInfo.length ) {
XMP_ProgressTracker* progressTracker = this->parent->progressTracker;
if ( progressTracker != 0 ) progressTracker->BeginWork ( (float)this->xmpPacket.size() );
fileRef->Seek ( this->packetInfo.offset, kXMP_SeekFromStart );
fileRef->Write ( this->xmpPacket.data(), (XMP_Int32)this->xmpPacket.size() );
if ( progressTracker != 0 ) progressTracker->WorkComplete();
} else {
XMP_IO* tempRef = fileRef->DeriveTemp();
if ( tempRef == 0 ) XMP_Throw ( "Failure creating FLV temp file", kXMPErr_InternalFailure );
this->WriteTempFile ( tempRef );
fileRef->AbsorbTemp();
}
this->needsUpdate = false;
} // FLV_MetaHandler::UpdateFile
示例5: UpdateFile
void Trivial_MetaHandler::UpdateFile ( bool doSafeUpdate )
{
IgnoreParam ( doSafeUpdate );
XMP_Assert ( ! doSafeUpdate ); // Not supported at this level.
if ( ! this->needsUpdate ) return;
XMP_IO* fileRef = this->parent->ioRef;
XMP_PacketInfo & packetInfo = this->packetInfo;
std::string & xmpPacket = this->xmpPacket;
fileRef->Seek ( packetInfo.offset, kXMP_SeekFromStart );
fileRef->Write ( xmpPacket.c_str(), packetInfo.length );
XMP_Assert ( xmpPacket.size() == (size_t)packetInfo.length );
this->needsUpdate = false;
} // Trivial_MetaHandler::UpdateFile
示例6:
// 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 ) );
}
}
示例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: UpdateFile
void SVG_MetaHandler::UpdateFile( bool doSafeUpdate )
{
XMP_Assert( !doSafeUpdate ); // This should only be called for "unsafe" updates.
XMP_IO* sourceRef = this->parent->ioRef;
if ( sourceRef == NULL || svgNode == NULL )
return;
// Checking whether Title updation requires or not
std::string title;
XML_NodePtr titleNode = svgNode->GetNamedElement( svgNode->ns.c_str(), "title" );
(void) this->xmpObj.GetLocalizedText( kXMP_NS_DC, "title", "", "x-default", 0, &title, 0 );
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;
// Checking whether Description updation requires or not
std::string description;
XML_NodePtr descNode = svgNode->GetNamedElement( svgNode->ns.c_str(), "desc" );
( void ) this->xmpObj.GetLocalizedText( kXMP_NS_DC, "description", "", "x-default", 0, &description, 0 );
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;
// If any updation is required then don't do inplace replace
bool isUpdateRequire = isTitleUpdateReq | isDescUpdateReq | (this->packetInfo.offset == kXMPFiles_UnknownOffset);
// Inplace Updation of XMP
if ( !isUpdateRequire && this->xmpPacket.size() == this->packetInfo.length )
{
sourceRef->Seek( this->packetInfo.offset, kXMP_SeekFromStart );
sourceRef->Write( this->xmpPacket.c_str(), static_cast< int >( this->xmpPacket.size() ) );
}
else
{
// Inplace is not possibe, So perform full updation
try
{
XMP_IO* tempRef = sourceRef->DeriveTemp();
this->WriteTempFile( tempRef );
}
catch ( ... )
{
sourceRef->DeleteTemp();
throw;
}
sourceRef->AbsorbTemp();
}
this->needsUpdate = false;
} // SVG_MetaHandler::UpdateFile
示例9: WriteTempFile
//.........这里部分代码省略.........
// Insert/Update Metadata if requires
// Don't insert/update it if case is DTM
bool isMetadataWritten = false;
if ( metadataOffset.startOffset == -1 )
{
if ( descOffset.nextOffset != -1 )
{
XIO::Copy( sourceRef, tempRef, descOffset.nextOffset - currentOffset );
currentOffset = descOffset.nextOffset;
}
else if ( titleOffset.nextOffset != -1 )
{
XIO::Copy( sourceRef, tempRef, titleOffset.nextOffset - currentOffset );
currentOffset = titleOffset.nextOffset;
}
InsertNewMetadata( tempRef, this->xmpPacket );
isMetadataWritten = true;
}
else if ( !( !isTitleWritten && isDescWritten && titleOffset.startOffset < metadataOffset.startOffset ) ) // Not DTM
{
// No XMP packet was present in the file
if ( this->packetInfo.offset == kXMPFiles_UnknownOffset )
{
std::string metadataElement = "<metadata>";
XIO::Copy( sourceRef, tempRef, metadataOffset.startOffset - currentOffset + metadataElement.length() );
currentOffset = sourceRef->Offset();
tempRef->Write( this->xmpPacket.c_str(), static_cast< int >( this->xmpPacket.length() ) );
}
else // Replace XMP Packet
{
XIO::Copy( sourceRef, tempRef, this->packetInfo.offset - currentOffset );
tempRef->Write( this->xmpPacket.c_str(), static_cast< int >( this->xmpPacket.length() ) );
sourceRef->Seek( this->packetInfo.offset + this->packetInfo.length, kXMP_SeekFromStart );
currentOffset = sourceRef->Offset();
}
isMetadataWritten = true;
}
// If simple cases was followed then copy rest file
if ( isTitleWritten && isDescWritten && isMetadataWritten )
{
XIO::Copy( sourceRef, tempRef, ( sourceRef->Length() - currentOffset ) );
return;
}
// If the case is not Simple (TDM) then perform these operations
if ( isDescWritten ) // TDM, DTM, DMT
{
if ( !isTitleWritten ) // DTM, DMT
{
if ( titleOffset.startOffset < metadataOffset.startOffset ) // DTM
{
ProcessTitle( sourceRef, tempRef, title, currentOffset, titleOffset );
isTitleWritten = true;
if ( this->packetInfo.offset == kXMPFiles_UnknownOffset )
{
std::string metadataElement = "<metadata>";
XIO::Copy( sourceRef, tempRef, metadataOffset.startOffset - currentOffset + metadataElement.length() );
currentOffset = sourceRef->Offset();
tempRef->Write( this->xmpPacket.c_str(), static_cast< int >( this->xmpPacket.length() ) );
}
else
{
XIO::Copy( sourceRef, tempRef, this->packetInfo.offset - currentOffset );
示例10: CacheFileData
//.........这里部分代码省略.........
XMP_Int32 ioCount = fileRef->Read( buffer, sizeof( buffer ) );
if ( ioCount == 0 || !svgAdapter->IsParsingRequire() ) break;
svgAdapter->ParseBuffer( buffer, ioCount, false /* not the end */ );
}
svgAdapter->ParseBuffer( 0, 0, true ); // End the parse.
XML_Node & xmlTree = this->svgAdapter->tree;
XML_NodePtr rootElem = 0;
for ( size_t i = 0, limit = xmlTree.content.size(); i < limit; ++i )
{
if ( xmlTree.content[ i ]->kind == kElemNode ) {
rootElem = xmlTree.content[ i ];
}
}
if ( rootElem == 0 )
XMP_Throw( "Not a valid SVG File", kXMPErr_BadFileFormat );
XMP_StringPtr rootLocalName = rootElem->name.c_str() + rootElem->nsPrefixLen;
if ( ! XMP_LitMatch( rootLocalName, "svg" ) )
XMP_Throw( "Not able to parse such SVG File", kXMPErr_BadFileFormat );
// Making SVG node as Root Node
svgNode = rootElem;
bool FoundPI = false;
bool FoundWrapper = false;
XML_NodePtr metadataNode = svgNode->GetNamedElement( rootElem->ns.c_str(), "metadata" );
// We are intersted only in the Metadata tag of outer SVG element
// XMP should be present only in metadata Node of SVG
if ( metadataNode != NULL )
{
XMP_Int64 packetLength = -1;
XMP_Int64 packetOffset = -1;
XMP_Int64 PIOffset = svgAdapter->GetPIOffset( "xpacket", 1 );
OffsetStruct wrapperOffset = svgAdapter->GetElementOffsets( "xmpmeta" );
OffsetStruct rdfOffset = svgAdapter->GetElementOffsets( "RDF" );
// Checking XMP PI's position
if ( PIOffset != -1 )
{
if ( wrapperOffset.startOffset != -1 && wrapperOffset.startOffset < PIOffset )
packetOffset = wrapperOffset.startOffset;
else
{
XMP_Int64 trailerOffset = svgAdapter->GetPIOffset( "xpacket", 2 );
XML_NodePtr trailerNode = metadataNode->GetNamedElement( "", "xpacket", 1 );
if ( trailerOffset != -1 || trailerNode != 0 )
{
packetLength = 2; // "<?" = 2
packetLength += trailerNode->name.length(); // Node's name
packetLength += 1; // Empty Space after Node's name
packetLength += trailerNode->value.length(); // Value
packetLength += 2; // "?>" = 2
packetLength += ( trailerOffset - PIOffset );
packetOffset = PIOffset;
}
}
}
else if ( wrapperOffset.startOffset != -1 ) // XMP Wrapper is present without PI
{
XML_NodePtr wrapperNode = metadataNode->GetNamedElement( "adobe:ns:meta/", "xmpmeta" );
if ( wrapperNode != 0 )
{
std::string trailerWrapper = "</x:xmpmeta>";
packetLength = trailerWrapper.length();
packetLength += ( wrapperOffset.endOffset - wrapperOffset.startOffset );
packetOffset = wrapperOffset.startOffset;
}
}
else // RDF packet is present without PI and wrapper
{
XML_NodePtr rdfNode = metadataNode->GetNamedElement( "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "RDF" );
if ( rdfNode != 0 )
{
std::string rdfTrailer = "</rdf:RDF>";
packetLength = rdfTrailer.length();
packetLength += ( rdfOffset.endOffset - rdfOffset.startOffset );
packetOffset = rdfOffset.startOffset;
}
}
// Fill the necesarry information and packet with XMP data
if ( packetOffset != -1 )
{
this->packetInfo.offset = packetOffset;
this->packetInfo.length = ( XMP_Int32 ) packetLength;
this->xmpPacket.assign( this->packetInfo.length, ' ' );
fileRef->Seek( packetOffset, kXMP_SeekFromStart );
fileRef->ReadAll( ( void* )this->xmpPacket.data(), this->packetInfo.length );
FillPacketInfo( this->xmpPacket, &this->packetInfo );
this->containsXMP = true;
return;
}
}
this->containsXMP = false;
} // SVG_MetaHandler::CacheFileData
示例11: WriteTempFile
void FLV_MetaHandler::WriteTempFile ( XMP_IO* tempRef )
{
if ( ! this->needsUpdate ) return;
XMP_AbortProc abortProc = this->parent->abortProc;
void * abortArg = this->parent->abortArg;
const bool checkAbort = (abortProc != 0);
XMP_IO* originalRef = this->parent->ioRef;
XMP_Uns64 sourceLen = originalRef->Length();
XMP_Uns64 sourcePos = 0;
originalRef->Rewind();
tempRef->Rewind();
tempRef->Truncate ( 0 );
XMP_ProgressTracker* progressTracker = this->parent->progressTracker;
if ( progressTracker != 0 ) {
float fileSize=(float)(this->xmpPacket.size()+48);
if ( this->omdTagPos == 0 ) {
sourcePos=(this->flvHeaderLen+4);
fileSize+=sourcePos;
} else {
if ( this->xmpTagPos < this->omdTagPos ) {
fileSize+=this->xmpTagPos;
}
fileSize+=(this->omdTagPos + this->omdTagLen-
((this->xmpTagPos!=0 && this->xmpTagPos < this->omdTagPos)?
(this->xmpTagPos + this->xmpTagLen):0));
sourcePos =this->omdTagPos + this->omdTagLen;
}
if ( (this->xmpTagPos != 0) && (this->xmpTagPos >= sourcePos) ) {
fileSize+=(this->xmpTagPos - sourcePos);
sourcePos=this->xmpTagPos + this->xmpTagLen;
}
fileSize+=(sourceLen - sourcePos);
sourcePos=0;
progressTracker->BeginWork ( fileSize );
}
// First do whatever is needed to put the new XMP after any existing onMetaData tag, or as the
// first time 0 tag.
if ( this->omdTagPos == 0 ) {
// There is no onMetaData tag. Copy the file header, then write the new XMP as the first tag.
// Allow the degenerate case of a file with just a header, no initial back pointer or tags.
originalRef->Seek ( sourcePos, kXMP_SeekFromStart );
XIO::Copy ( originalRef, tempRef, this->flvHeaderLen, abortProc, abortArg );
XMP_Uns32 zero = 0; // Ensure that the initial back offset really is zero.
tempRef->Write ( &zero, 4 );
sourcePos = this->flvHeaderLen + 4;
WriteOnXMP ( tempRef, this->xmpPacket );
} else {
// There is an onMetaData tag. Copy the front of the file through the onMetaData tag,
// skipping any XMP that happens to be in the way. The XMP should not be before onMetaData,
// but let's be robust. Write the new XMP immediately after onMetaData, at the same time.
XMP_Uns64 omdEnd = this->omdTagPos + this->omdTagLen;
if ( (this->xmpTagPos != 0) && (this->xmpTagPos < this->omdTagPos) ) {
// The XMP tag was in front of the onMetaData tag. Copy up to it, then skip it.
originalRef->Seek ( sourcePos, kXMP_SeekFromStart );
XIO::Copy ( originalRef, tempRef, this->xmpTagPos, abortProc, abortArg );
sourcePos = this->xmpTagPos + this->xmpTagLen; // The tag length includes the trailing size field.
}
// Copy through the onMetaData tag, then write the XMP.
originalRef->Seek ( sourcePos, kXMP_SeekFromStart );
XIO::Copy ( originalRef, tempRef, (omdEnd - sourcePos), abortProc, abortArg );
sourcePos = omdEnd;
WriteOnXMP ( tempRef, this->xmpPacket );
}
// Copy the rest of the file, skipping any XMP that is in the way.
if ( (this->xmpTagPos != 0) && (this->xmpTagPos >= sourcePos) ) {
originalRef->Seek ( sourcePos, kXMP_SeekFromStart );
XIO::Copy ( originalRef, tempRef, (this->xmpTagPos - sourcePos), abortProc, abortArg );
sourcePos = this->xmpTagPos + this->xmpTagLen;
}
originalRef->Seek ( sourcePos, kXMP_SeekFromStart );
XIO::Copy ( originalRef, tempRef, (sourceLen - sourcePos), abortProc, abortArg );
this->needsUpdate = false;
if ( progressTracker != 0 ) progressTracker->WorkComplete();
} // FLV_MetaHandler::WriteTempFile
示例12: CacheFileData
void InDesign_MetaHandler::CacheFileData()
{
XMP_IO* fileRef = this->parent->ioRef;
XMP_PacketInfo & packetInfo = this->packetInfo;
XMP_Assert ( kINDD_PageSize == sizeof(InDesignMasterPage) );
static const size_t kBufferSize = (2 * kINDD_PageSize);
XMP_Uns8 buffer [kBufferSize];
size_t dbPages;
XMP_Uns8 cobjEndian;
XMP_AbortProc abortProc = this->parent->abortProc;
void * abortArg = this->parent->abortArg;
const bool checkAbort = (abortProc != 0);
this->containsXMP = false;
// ---------------------------------------------------------------------------------
// Figure out which master page is active and seek to the contiguous object portion.
{
fileRef->Rewind();
fileRef->ReadAll ( buffer, (2 * kINDD_PageSize) );
InDesignMasterPage * masters = (InDesignMasterPage *) &buffer[0];
XMP_Uns64 seq0 = GetUns64LE ( (XMP_Uns8 *) &masters[0].fSequenceNumber );
XMP_Uns64 seq1 = GetUns64LE ( (XMP_Uns8 *) &masters[1].fSequenceNumber );
dbPages = GetUns32LE ( (XMP_Uns8 *) &masters[0].fFilePages );
cobjEndian = masters[0].fObjectStreamEndian;
if ( seq1 > seq0 ) {
dbPages = GetUns32LE ( (XMP_Uns8 *) &masters[1].fFilePages );
cobjEndian = masters[1].fObjectStreamEndian;
}
}
XMP_Assert ( ! this->streamBigEndian );
if ( cobjEndian == kINDD_BigEndian ) this->streamBigEndian = true;
// ---------------------------------------------------------------------------------------------
// Look for the XMP contiguous object. Each contiguous object has a header and trailer, both of
// the InDesignContigObjMarker structure. The stream size in the header/trailer is the number of
// data bytes between the header and trailer. The XMP stream begins with a 4 byte size of the
// XMP packet. Yes, this is the contiguous object data size minus 4 - silly but true. The XMP
// must have a packet wrapper, the leading xpacket PI is used as the marker of XMP.
XMP_Int64 cobjPos = (XMP_Int64)dbPages * kINDD_PageSize; // ! Use a 64 bit multiply!
cobjPos -= (2 * sizeof(InDesignContigObjMarker)); // ! For the first pass in the loop.
XMP_Uns32 streamLength = 0; // ! For the first pass in the loop.
while ( true ) {
if ( checkAbort && abortProc(abortArg) ) {
XMP_Throw ( "InDesign_MetaHandler::LocateXMP - User abort", kXMPErr_UserAbort );
}
// Fetch the start of the next stream and check the contiguous object header.
// ! The writeable bit of fObjectClassID is ignored, we use the packet trailer flag.
cobjPos += streamLength + (2 * sizeof(InDesignContigObjMarker));
fileRef->Seek ( cobjPos, kXMP_SeekFromStart );
fileRef->ReadAll ( buffer, sizeof(InDesignContigObjMarker) );
const InDesignContigObjMarker * cobjHeader = (const InDesignContigObjMarker *) &buffer[0];
if ( ! CheckBytes ( Uns8Ptr(&cobjHeader->fGUID), kINDDContigObjHeaderGUID, kInDesignGUIDSize ) ) break; // Not a contiguous object header.
this->xmpObjID = cobjHeader->fObjectUID; // Save these now while the buffer is good.
this->xmpClassID = cobjHeader->fObjectClassID;
streamLength = GetUns32LE ( (XMP_Uns8 *) &cobjHeader->fStreamLength );
// See if this is the XMP stream.
if ( streamLength < (4 + kUTF8_PacketHeaderLen + kUTF8_PacketTrailerLen) ) continue; // Too small, can't possibly be XMP.
fileRef->ReadAll ( buffer, (4 + kUTF8_PacketHeaderLen) );
XMP_Uns32 innerLength = GetUns32LE ( &buffer[0] );
if ( this->streamBigEndian ) innerLength = GetUns32BE ( &buffer[0] );
if ( innerLength != (streamLength - 4) ) {
// Be tolerant of a mistake with the endian flag.
innerLength = Flip4 ( innerLength );
if ( innerLength != (streamLength - 4) ) continue; // Not legit XMP.
}
XMP_Uns8 * chPtr = &buffer[4];
size_t startLen = strlen((char*)kUTF8_PacketStart);
size_t idLen = strlen((char*)kUTF8_PacketID);
if ( ! CheckBytes ( chPtr, kUTF8_PacketStart, startLen ) ) continue;
chPtr += startLen;
XMP_Uns8 quote = *chPtr;
if ( (quote != '\'') && (quote != '"') ) continue;
chPtr += 1;
if ( *chPtr != quote ) {
if ( ! CheckBytes ( chPtr, Uns8Ptr("\xEF\xBB\xBF"), 3 ) ) continue;
chPtr += 3;
}
if ( *chPtr != quote ) continue;
chPtr += 1;
//.........这里部分代码省略.........
示例13: UpdateFile
void TIFF_MetaHandler::UpdateFile ( bool doSafeUpdate )
{
XMP_Assert ( ! doSafeUpdate ); // This should only be called for "unsafe" updates.
XMP_IO* destRef = this->parent->ioRef;
XMP_AbortProc abortProc = this->parent->abortProc;
void * abortArg = this->parent->abortArg;
XMP_Int64 oldPacketOffset = this->packetInfo.offset;
XMP_Int32 oldPacketLength = this->packetInfo.length;
if ( oldPacketOffset == kXMPFiles_UnknownOffset ) oldPacketOffset = 0; // ! Simplify checks.
if ( oldPacketLength == kXMPFiles_UnknownLength ) oldPacketLength = 0;
bool fileHadXMP = ((oldPacketOffset != 0) && (oldPacketLength != 0));
// Update the IPTC-IIM and native TIFF/Exif metadata. ExportPhotoData also trips the tiff: and
// exif: copies from the XMP, so reserialize the now final XMP packet.
ExportPhotoData ( kXMP_TIFFFile, &this->xmpObj, &this->tiffMgr, this->iptcMgr, this->psirMgr );
try {
XMP_OptionBits options = kXMP_UseCompactFormat;
if ( fileHadXMP ) options |= kXMP_ExactPacketLength;
this->xmpObj.SerializeToBuffer ( &this->xmpPacket, options, oldPacketLength );
} catch ( ... ) {
this->xmpObj.SerializeToBuffer ( &this->xmpPacket, kXMP_UseCompactFormat );
}
// Decide whether to do an in-place update. This can only happen if all of the following are true:
// - There is an XMP packet in the file.
// - The are no changes to the legacy tags. (The IPTC and PSIR are in the TIFF tags.)
// - The new XMP can fit in the old space.
bool doInPlace = (fileHadXMP && (this->xmpPacket.size() <= (size_t)oldPacketLength));
if ( this->tiffMgr.IsLegacyChanged() ) doInPlace = false;
bool localProgressTracking = false;
XMP_ProgressTracker* progressTracker = this->parent->progressTracker;
if ( ! doInPlace ) {
#if GatherPerformanceData
sAPIPerf->back().extraInfo += ", TIFF append update";
#endif
if ( (progressTracker != 0) && (! progressTracker->WorkInProgress()) ) {
localProgressTracking = true;
progressTracker->BeginWork();
}
this->tiffMgr.SetTag ( kTIFF_PrimaryIFD, kTIFF_XMP, kTIFF_UndefinedType, (XMP_Uns32)this->xmpPacket.size(), this->xmpPacket.c_str() );
this->tiffMgr.UpdateFileStream ( destRef, progressTracker );
} else {
#if GatherPerformanceData
sAPIPerf->back().extraInfo += ", TIFF in-place update";
#endif
if ( this->xmpPacket.size() < (size_t)this->packetInfo.length ) {
// They ought to match, cheap to be sure.
size_t extraSpace = (size_t)this->packetInfo.length - this->xmpPacket.size();
this->xmpPacket.append ( extraSpace, ' ' );
}
XMP_IO* liveFile = this->parent->ioRef;
XMP_Assert ( this->xmpPacket.size() == (size_t)oldPacketLength ); // ! Done by common PutXMP logic.
if ( progressTracker != 0 ) {
if ( progressTracker->WorkInProgress() ) {
progressTracker->AddTotalWork ( this->xmpPacket.size() );
} else {
localProgressTracking = true;
progressTracker->BeginWork ( this->xmpPacket.size() );
}
}
liveFile->Seek ( oldPacketOffset, kXMP_SeekFromStart );
liveFile->Write ( this->xmpPacket.c_str(), (XMP_Int32)this->xmpPacket.size() );
}
if ( localProgressTracking ) progressTracker->WorkComplete();
this->needsUpdate = false;
} // TIFF_MetaHandler::UpdateFile
示例14: 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...
//.........这里部分代码省略.........
示例15: frame
//.........这里部分代码省略.........
// 2/4) value before, now gone:
if ( value.empty() && (frame!=0)) {
frame->active = false; //mark for non-use
continue;
}
// 3/4) no old value, create new value
bool needUTF16 = false;
if ( needEncodingByte ) needUTF16 = (! ReconcileUtils::IsASCII ( value.c_str(), value.size() ) );
if ( frame != 0 ) {
frame->setFrameValue( value, needDescriptor, needUTF16, false, needEncodingByte );
} else {
ID3v2Frame* newFrame=new ID3v2Frame( storedID );
newFrame->setFrameValue( value, needDescriptor, needUTF16, false, needEncodingByte ); //always write as utf16-le incl. BOM
framesVector.push_back( newFrame );
framesMap[ storedID ] = newFrame;
continue;
}
} // RECON LOOP END
/////////////////////////////////////////////////////////////////////////////////
// (Re)Build XMP frame:
XMP_Uns32 xmpID = XMP_V23_ID;
if ( this->majorVersion == 2 ) xmpID = XMP_V22_ID;
ID3v2Frame* frame = framesMap[ xmpID ];
if ( frame != 0 ) {
frame->setFrameValue( this->xmpPacket, false, false, true );
} else {
ID3v2Frame* newFrame=new ID3v2Frame( xmpID );
newFrame->setFrameValue ( this->xmpPacket, false, false, true );
framesVector.push_back ( newFrame );
framesMap[ xmpID ] = newFrame;
}
////////////////////////////////////////////////////////////////////////////////
// Decision making
XMP_Int32 frameHeaderSize = ID3v2Frame::kV23_FrameHeaderSize;
if ( this->majorVersion == 2 ) frameHeaderSize = ID3v2Frame::kV22_FrameHeaderSize;
newFramesSize = 0;
for ( XMP_Uns32 i = 0; i < framesVector.size(); i++ ) {
if ( framesVector[i]->active ) newFramesSize += (frameHeaderSize + framesVector[i]->contentSize);
}
mustShift = (newFramesSize > (XMP_Int64)(oldTagSize - ID3Header::kID3_TagHeaderSize)) ||
//optimization: If more than 8K can be saved by rewriting the MP3, go do it:
((newFramesSize + 8*1024) < oldTagSize );
if ( ! mustShift ) { // fill what we got
newTagSize = oldTagSize;
} else { // if need to shift anyway, get some nice 2K padding
newTagSize = newFramesSize + 2048 + ID3Header::kID3_TagHeaderSize;
}
newPadding = newTagSize - ID3Header::kID3_TagHeaderSize - newFramesSize;
// shifting needed? -> shift
if ( mustShift ) {
XMP_Int64 filesize = file ->Length();
if ( this->hasID3Tag ) {
XIO::Move ( file, oldTagSize, file, newTagSize, filesize - oldTagSize ); //fix [2338569]
} else {
XIO::Move ( file, 0, file, newTagSize, filesize ); // move entire file up.
}
}
// correct size stuff, write out header
file ->Rewind();
id3Header.write ( file, newTagSize );
// write out tags
for ( XMP_Uns32 i = 0; i < framesVector.size(); i++ ) {
if ( framesVector[i]->active ) framesVector[i]->write ( file, majorVersion );
}
// write out padding:
for ( XMP_Int64 i = newPadding; i > 0; ) {
const XMP_Uns64 zero = 0;
if ( i >= 8 ) {
file->Write ( &zero, 8 );
i -= 8;
continue;
}
file->Write ( &zero, 1 );
i--;
}
// check end of file for ID3v1 tag
XMP_Int64 possibleTruncationPoint = file->Seek ( -128, kXMP_SeekFromEnd );
bool alreadyHasID3v1 = (XIO::ReadInt32_BE( file ) & 0xFFFFFF00) == 0x54414700; // "TAG"
if ( ! alreadyHasID3v1 ) file->Seek ( 128, kXMP_SeekFromEnd ); // Seek will extend the file.
id3v1Tag.write( file, &this->xmpObj );
this->needsUpdate = false; //do last for safety reasons
} // MP3_MetaHandler::UpdateFile