void GIF_MetaHandler::UpdateFile ( bool doSafeUpdate ) { IgnoreParam(doSafeUpdate); XMP_Assert( !doSafeUpdate ); // This should only be called for "unsafe" updates. if ( ! this->needsUpdate ) return; XMP_IO * fileRef = this->parent->ioRef; /*XMP_StringPtr packetStr = xmpPacket.c_str();*/ XMP_StringLen newPacketLength = (XMP_StringLen)xmpPacket.size(); if ( newPacketLength == XMPPacketLength ) { this->SeekFile( fileRef, this->packetInfo.offset, kXMP_SeekFromStart ); fileRef->Write( this->xmpPacket.c_str(), newPacketLength ); } else { XMP_IO* tempFile = fileRef->DeriveTemp(); if ( tempFile == 0 ) XMP_Throw( "Failure creating GIF temp file", kXMPErr_InternalFailure ); this->WriteTempFile( tempFile ); fileRef->AbsorbTemp(); } this->needsUpdate = false; } // GIF_MetaHandler::UpdateFile
bool ASF_MetaHandler::SafeWriteFile() { XMP_IO* originalFile = this->parent->ioRef; XMP_IO* tempFile = originalFile->DeriveTemp(); if ( tempFile == 0 ) XMP_Throw ( "Failure creating ASF temp file", kXMPErr_InternalFailure ); this->WriteTempFile ( tempFile ); originalFile->AbsorbTemp(); return true; } // ASF_MetaHandler::SafeWriteFile
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
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
void PSD_MetaHandler::UpdateFile ( bool doSafeUpdate ) { XMP_Assert ( ! doSafeUpdate ); // This should only be called for "unsafe" updates. 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_PhotoshopFile, &this->xmpObj, this->exifMgr, 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 image resources. (The IPTC and EXIF are in the PSIR.) // - The new XMP can fit in the old space. bool doInPlace = (fileHadXMP && (this->xmpPacket.size() <= (size_t)oldPacketLength)); if ( this->psirMgr.IsLegacyChanged() ) doInPlace = false; XMP_ProgressTracker* progressTracker = this->parent->progressTracker; if ( doInPlace ) { #if GatherPerformanceData sAPIPerf->back().extraInfo += ", PSD 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 ) progressTracker->BeginWork ( this->xmpPacket.size() ); liveFile->Seek ( oldPacketOffset, kXMP_SeekFromStart ); liveFile->Write ( this->xmpPacket.c_str(), (XMP_StringLen)this->xmpPacket.size() ); if ( progressTracker != 0 ) progressTracker->WorkComplete(); } else { #if GatherPerformanceData sAPIPerf->back().extraInfo += ", PSD copy update"; #endif XMP_IO* origRef = this->parent->ioRef; XMP_IO* tempRef = origRef->DeriveTemp(); try { XMP_Assert ( ! this->skipReconcile ); this->skipReconcile = true; this->WriteTempFile ( tempRef ); this->skipReconcile = false; } catch ( ... ) { this->skipReconcile = false; origRef->DeleteTemp(); throw; } origRef->AbsorbTemp(); } this->needsUpdate = false; } // PSD_MetaHandler::UpdateFile