示例#1
0
	bool WriteXMPTag ( LFA_FileRef fileRef, XMP_Uns32 len, const char* inBuffer )
	{
		bool ret = false;

		XMP_Uns16 code = MakeUns16LE ( (SWF_TAG_ID_METADATA << 6) | 0x3F );
		XMP_Uns32 length = MakeUns32LE ( len );

		try {
			LFA_Write (fileRef, &code, 2 );
			LFA_Write (fileRef, &length, 4 );
			LFA_Write (fileRef, inBuffer, len );
			ret = true;
		} catch ( ... ) {}

		return ret;

	}	// WriteXMPTag
示例#2
0
	typedef struct _GUID
	{
		XMP_Uns32	Data1;
		XMP_Uns16	Data2;
		XMP_Uns16	Data3;
		XMP_Uns8	Data4[8];
	} GUID;

	int IsEqualGUID ( const GUID& guid1, const GUID& guid2 );

	static const GUID GUID_NULL = { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };

#endif

// header object
static const GUID ASF_Header_Object = { MakeUns32LE(0x75b22630), MakeUns16LE(0x668e), MakeUns16LE(0x11cf), { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c } };
// contains ...
static const GUID ASF_File_Properties_Object = { MakeUns32LE(0x8cabdca1), MakeUns16LE(0xa947), MakeUns16LE(0x11cf), { 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 } };
static const GUID ASF_Content_Description_Object = { MakeUns32LE(0x75b22633), MakeUns16LE(0x668e), MakeUns16LE(0x11cf), { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c } };
static const GUID ASF_Content_Branding_Object = { MakeUns32LE(0x2211b3fa), MakeUns16LE(0xbd23), MakeUns16LE(0x11d2), { 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e } };
static const GUID ASF_Content_Encryption_Object = { MakeUns32LE(0x2211b3fb), MakeUns16LE(0xbd23), MakeUns16LE(0x11d2), { 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e } };
// padding
// Remark: regarding to Microsofts spec only the ASF_Header_Object contains a ASF_Padding_Object
// Real world files show, that the ASF_Header_Extension_Object contains a ASF_Padding_Object
static const GUID ASF_Header_Extension_Object = { MakeUns32LE(0x5fbf03b5), MakeUns16LE(0xa92e), MakeUns16LE(0x11cf), { 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 } };
static const GUID ASF_Padding_Object = { MakeUns32LE(0x1806d474), MakeUns16LE(0xcadf), MakeUns16LE(0x4509), { 0xa4, 0xba, 0x9a, 0xab, 0xcb, 0x96, 0xaa, 0xe8 } };

// data object
static const GUID ASF_Data_Object = { MakeUns32LE(0x75b22636), MakeUns16LE(0x668e), MakeUns16LE(0x11cf), { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c } };

// XMP object
示例#3
0
bool ASF_Support::WriteHeaderObject ( XMP_IO* sourceRef, XMP_IO* destRef, const ObjectData& object, ASF_LegacyManager& _legacyManager, bool usePadding )
{
	if ( ! IsEqualGUID ( ASF_Header_Object, object.guid ) ) return false;

	std::string buffer;
	XMP_Uns16 valueUns16LE;
	XMP_Uns32 valueUns32LE;
	XMP_Uns64 valueUns64LE;

	try {

		// read header-object structure
		XMP_Uns64 pos = object.pos;
		XMP_Uns32 bufferSize = kASF_ObjectBaseLen + 6;

		buffer.clear();
		buffer.reserve ( bufferSize );
		buffer.assign ( bufferSize, ' ' );
		sourceRef->Seek ( pos, kXMP_SeekFromStart );
		sourceRef->ReadAll ( const_cast<char*>(buffer.data()), bufferSize );

		XMP_Uns64 read = bufferSize;
		pos += bufferSize;

		// read contained header objects
		/*XMP_Uns32 numberOfHeaders = GetUns32LE ( &buffer[24] );*/
		ASF_ObjectBase objectBase;

		// prepare new header in memory
		std::string header;

		int changedObjects = _legacyManager.changedObjects();
		int exportedObjects = 0;
		int writtenObjects = 0;

		header.append ( buffer.c_str(), bufferSize );

		while ( read < object.len ) {

			sourceRef->Seek ( pos, kXMP_SeekFromStart );
			if ( kASF_ObjectBaseLen != sourceRef->Read ( &objectBase, kASF_ObjectBaseLen, true ) ) break;

			sourceRef->Seek ( pos, kXMP_SeekFromStart );
			objectBase.size = GetUns64LE ( &objectBase.size );

			int headerStartPos = header.size();

			// save position of filesize-information
			if ( IsEqualGUID ( ASF_File_Properties_Object, objectBase.guid ) ) {
				posFileSizeInfo = (headerStartPos + 40);
			}

			// write objects
			if ( IsEqualGUID ( ASF_File_Properties_Object, objectBase.guid ) &&
				(objectBase.size >= 104) && (changedObjects & ASF_LegacyManager::objectFileProperties) ) {

				// copy object and replace creation-date
				buffer.reserve ( XMP_Uns32 ( objectBase.size ) );
				buffer.assign ( XMP_Uns32 ( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );
				header.append ( buffer, 0, XMP_Uns32( objectBase.size ) );

				if ( ! _legacyManager.GetBroadcast() ) {
					buffer = _legacyManager.GetField ( ASF_LegacyManager::fieldCreationDate );
					ReplaceString ( header, buffer, (headerStartPos + 48), 8 );
				}

				exportedObjects |= ASF_LegacyManager::objectFileProperties;

			} else if ( IsEqualGUID ( ASF_Content_Description_Object, objectBase.guid ) &&
						(objectBase.size >= 34) && (changedObjects & ASF_LegacyManager::objectContentDescription) ) {

				// re-create object with xmp-data
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );
				// write header only 
				header.append ( buffer, 0, XMP_Uns32( kASF_ObjectBaseLen ) );

				// write length fields

				XMP_Uns16 titleLen = _legacyManager.GetField ( ASF_LegacyManager::fieldTitle).size( );
				valueUns16LE = MakeUns16LE ( titleLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 authorLen = _legacyManager.GetField ( ASF_LegacyManager::fieldAuthor).size( );
				valueUns16LE = MakeUns16LE ( authorLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 copyrightLen = _legacyManager.GetField ( ASF_LegacyManager::fieldCopyright).size( );
				valueUns16LE = MakeUns16LE ( copyrightLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 descriptionLen = _legacyManager.GetField ( ASF_LegacyManager::fieldDescription).size( );
				valueUns16LE = MakeUns16LE ( descriptionLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				// retrieve existing overall length of preceding fields
				XMP_Uns16 precedingLen = 0;
				precedingLen += GetUns16LE ( &buffer[24] ); // Title
				precedingLen += GetUns16LE ( &buffer[26] ); // Author
				precedingLen += GetUns16LE ( &buffer[28] ); // Copyright
				precedingLen += GetUns16LE ( &buffer[30] ); // Description
				// retrieve existing 'Rating' length
				XMP_Uns16 ratingLen = GetUns16LE ( &buffer[32] ); // Rating
				valueUns16LE = MakeUns16LE ( ratingLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				// write field contents

				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldTitle ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldAuthor ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldCopyright ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldDescription ) );
				header.append ( buffer, (34 + precedingLen), ratingLen );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				exportedObjects |= ASF_LegacyManager::objectContentDescription;

			} else if ( IsEqualGUID ( ASF_Content_Branding_Object, objectBase.guid ) &&
						(changedObjects & ASF_LegacyManager::objectContentBranding) ) {

				// re-create object with xmp-data
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				// calculate size of fields coming before 'Copyright URL'
				XMP_Uns32 length = 28;
				length += (GetUns32LE ( &buffer[length] ) + 4); // Banner Image Data
				length += (GetUns32LE ( &buffer[length] ) + 4); // Banner Image URL

				// write first part of header
				header.append ( buffer, 0, length );

				// copyright URL
				length = _legacyManager.GetField ( ASF_LegacyManager::fieldCopyrightURL).size( );
				valueUns32LE = MakeUns32LE ( length );
				header.append ( (const char*)&valueUns32LE, 4 );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldCopyrightURL ) );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				exportedObjects |= ASF_LegacyManager::objectContentBranding;

#if ! Exclude_LicenseURL_Recon

			} else if ( IsEqualGUID ( ASF_Content_Encryption_Object, objectBase.guid ) &&
						(changedObjects & ASF_LegacyManager::objectContentEncryption) ) {

				// re-create object with xmp-data
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				// calculate size of fields coming before 'License URL'
				XMP_Uns32 length = 24;
				length += (GetUns32LE ( &buffer[length] ) + 4); // Secret Data
				length += (GetUns32LE ( &buffer[length] ) + 4); // Protection Type
				length += (GetUns32LE ( &buffer[length] ) + 4); // Key ID

				// write first part of header
				header.append ( buffer, 0, length );

				// License URL
				length = _legacyManager.GetField ( ASF_LegacyManager::fieldLicenseURL).size( );
				valueUns32LE = MakeUns32LE ( length );
				header.append ( (const char*)&valueUns32LE, 4 );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldLicenseURL ) );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				exportedObjects |= ASF_LegacyManager::objectContentEncryption;

#endif

			} else if ( IsEqualGUID ( ASF_Header_Extension_Object, objectBase.guid ) && usePadding ) {

				// re-create object if padding needs to be used
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				ASF_Support::WriteHeaderExtensionObject ( buffer, &header, objectBase, 0 );

			} else if ( IsEqualGUID ( ASF_Padding_Object, objectBase.guid ) && usePadding ) {

				// eliminate padding (will be created as last object)

			} else {

				// simply copy all other objects
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				sourceRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				header.append ( buffer, 0, XMP_Uns32( objectBase.size ) );

			}

			pos += objectBase.size;
			read += objectBase.size;

			writtenObjects ++;

		}

		// any objects to create ?
		int newObjects = (changedObjects ^ exportedObjects);

		if ( newObjects ) {

			// create new objects with xmp-data
			int headerStartPos;
			ASF_ObjectBase newObjectBase;
			XMP_Uns32 length;

			if ( newObjects & ASF_LegacyManager::objectContentDescription ) {

				headerStartPos = header.size();
				newObjectBase.guid = ASF_Content_Description_Object;
				newObjectBase.size = 0;

				// write object header
				header.append ( (const char*)&newObjectBase, kASF_ObjectBaseLen );

				XMP_Uns16 titleLen = _legacyManager.GetField ( ASF_LegacyManager::fieldTitle).size( );
				valueUns16LE = MakeUns16LE ( titleLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 authorLen = _legacyManager.GetField ( ASF_LegacyManager::fieldAuthor).size( );
				valueUns16LE = MakeUns16LE ( authorLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 copyrightLen = _legacyManager.GetField ( ASF_LegacyManager::fieldCopyright).size( );
				valueUns16LE = MakeUns16LE ( copyrightLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 descriptionLen = _legacyManager.GetField ( ASF_LegacyManager::fieldDescription).size( );
				valueUns16LE = MakeUns16LE ( descriptionLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				XMP_Uns16 ratingLen = 0;
				valueUns16LE = MakeUns16LE ( ratingLen );
				header.append ( (const char*)&valueUns16LE, 2 );

				// write field contents

				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldTitle ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldAuthor ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldCopyright ) );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldDescription ) );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				newObjects &= ~ASF_LegacyManager::objectContentDescription;

				writtenObjects ++;

			}
			
			if ( newObjects & ASF_LegacyManager::objectContentBranding ) {

				headerStartPos = header.size();
				newObjectBase.guid = ASF_Content_Branding_Object;
				newObjectBase.size = 0;

				// write object header
				header.append ( (const char*)&newObjectBase, kASF_ObjectBaseLen );

				// write 'empty' fields
				header.append ( 12, '\0' );

				// copyright URL
				length = _legacyManager.GetField ( ASF_LegacyManager::fieldCopyrightURL).size( );
				valueUns32LE = MakeUns32LE ( length );
				header.append ( (const char*)&valueUns32LE, 4 );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldCopyrightURL ) );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				newObjects &= ~ASF_LegacyManager::objectContentBranding;

				writtenObjects ++;

			}

#if ! Exclude_LicenseURL_Recon

			if ( newObjects & ASF_LegacyManager::objectContentEncryption ) {

				headerStartPos = header.size();
				newObjectBase.guid = ASF_Content_Encryption_Object;
				newObjectBase.size = 0;

				// write object header
				header.append ( (const char*)&newObjectBase, kASF_ObjectBaseLen );

				// write 'empty' fields
				header.append ( 12, '\0' );

				// License URL
				length = _legacyManager.GetField ( ASF_LegacyManager::fieldLicenseURL).size( );
				valueUns32LE = MakeUns32LE ( length );
				header.append ( (const char*)&valueUns32LE, 4 );
				header.append ( _legacyManager.GetField ( ASF_LegacyManager::fieldLicenseURL ) );

				// update new object size
				valueUns64LE = MakeUns64LE ( header.size() - headerStartPos );
				std::string newSize ( (const char*)&valueUns64LE, 8 );
				ReplaceString ( header, newSize, (headerStartPos + 16), 8 );

				newObjects &= ~ASF_LegacyManager::objectContentEncryption;

				writtenObjects ++;

			}

#endif

		}

		// create padding object ?
		if ( usePadding && (header.size ( ) < object.len ) ) {
			ASF_Support::CreatePaddingObject ( &header, (object.len - header.size()) );
			writtenObjects ++;
		}

		// update new header-object size
		valueUns64LE = MakeUns64LE ( header.size() );
		std::string newValue ( (const char*)&valueUns64LE, 8 );
		ReplaceString ( header, newValue, 16, 8 );

		// update new number of Header objects
		valueUns32LE = MakeUns32LE ( writtenObjects );
		newValue = std::string ( (const char*)&valueUns32LE, 4 );
		ReplaceString ( header, newValue, 24, 4 );

		// if we are operating on the same file (in-place update), place pointer before writing
		if ( sourceRef == destRef ) destRef->Seek ( object.pos, kXMP_SeekFromStart );
		if ( this->progressTracker != 0 ) 
		{
			XMP_Assert ( this->progressTracker->WorkInProgress() );
			this->progressTracker->AddTotalWork ( (float)header.size() );
		}
		// write header
		destRef->Write ( header.c_str(), header.size() );

	} catch ( ... ) {

		return false;

	}

	return true;

}
示例#4
0
	static inline XMP_Uns16 ReadUns16_LE ( XMP_IO* file )
	{
		XMP_Uns16 value;
		file->ReadAll ( &value, 2 );
		return MakeUns16LE ( value );
	}
示例#5
0
	static inline void WriteUns16_LE ( XMP_IO* file, XMP_Uns16 value )
	{
		XMP_Uns16 v = MakeUns16LE ( value );
		file->Write ( &v, 2 );
	}