Exemplo n.º 1
0
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
Exemplo n.º 2
0
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