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