コード例 #1
0
ファイル: Matroska_Handler.cpp プロジェクト: SSE4/vmf-1
void Matroska_MetaHandler::UpdateFile(bool doSafeUpdate)
{
    if (!needsUpdate) return; // If needsUpdate is set then at least the XMP changed.

    needsUpdate = false;	// Make sure only called once.
    XMP_Assert(!doSafeUpdate);	// This should only be called for "unsafe" updates.
    XMP_Assert(parent && parent->ioRef);

    XMP_AbortProc abortProc = parent->abortProc;
    void *        abortArg = parent->abortArg;
    const bool    checkAbort = (abortProc != 0);

    bool localProgressTracking(false);
    XMP_ProgressTracker* progressTracker = parent->progressTracker;
    if (progressTracker)
    {
        float xmpSize = static_cast<float>(xmpPacket.size());
        if (progressTracker->WorkInProgress())
        {
            progressTracker->AddTotalWork(xmpSize);
        }
        else
        {
            localProgressTracking = true;
            progressTracker->BeginWork(xmpSize);
        }
    }
    UpdateXMP();

    if (localProgressTracking) progressTracker->WorkComplete();
}
コード例 #2
0
ファイル: Matroska_Handler.cpp プロジェクト: SSE4/vmf-1
void Matroska_MetaHandler::WriteTempFile(XMP_IO* tempRef)
{
    XMP_Assert(needsUpdate);

    XMP_IO* originalRef = parent->ioRef;
    
    bool localProgressTracking(false);
    XMP_ProgressTracker* progressTracker = parent->progressTracker;
    if (progressTracker)
    {
        float xmpSize = static_cast<float>(xmpPacket.size());
        if (progressTracker->WorkInProgress())
        {
            progressTracker->AddTotalWork(xmpSize);
        }
        else
        {
            localProgressTracking = true;
            progressTracker->BeginWork(xmpSize);
        }
    }

    XMP_Assert(tempRef);
    XMP_Assert(originalRef);

    tempRef->Rewind();
    originalRef->Rewind();
    XIO::Copy(originalRef, tempRef, originalRef->Length(), parent->abortProc, parent->abortArg);

    try
    {
        parent->ioRef = tempRef;	// ! Fool UpdateFile into using the temp file.
        UpdateFile(false);
        parent->ioRef = originalRef;
    }
    catch (...)
    {
        parent->ioRef = originalRef;
        throw;
    }
    if (localProgressTracking) progressTracker->WorkComplete();
}
コード例 #3
0
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