Beispiel #1
0
	bool WriteChunk ( LFA_FileRef inFileRef, long tagID, const char * data, UInt32 len )
	{
		atag ck;
		ck.id = MakeUns32LE ( tagID );
		ck.len = MakeUns32LE ( len );
	
		try {
			LFA_Write ( inFileRef, &ck, 8 );
			LFA_Write ( inFileRef, data, len );
		} catch ( ... ) {
			return false;
		}
	
		return true;
	}
Beispiel #2
0
	bool MarkChunkAsPadding ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, long tagID, long subtypeID )
	{
		UInt32 len;
		UInt64 pos;
		atag tag;
	
		try {
	
			bool found = FindChunk ( inOutRiffState, tagID, riffType, subtypeID, NULL, &len, &pos );
			if ( ! found ) return false;
	
			if ( subtypeID != 0 ) {
				pos -= 12;
			} else {
				pos -= 8;
			}

			tag.id = MakeUns32LE ( ckidPremierePadding );
			LFA_Seek ( inFileRef, pos, SEEK_SET );
			LFA_Write ( inFileRef, &tag, 4 );
	
			pos += 8;
			AddTag ( inOutRiffState, ckidPremierePadding, len, pos, 0, 0, 0 );
	
		} catch(...) {
	
			return false;	// If a write fails, it throws, so we return false.
	
		}
	
		return true;
	}
Beispiel #3
0
	bool WriteFileAttrFlags ( LFA_FileRef fileRef, const TagData& fileAttrTag, XMP_Uns32  flags )
	{

		try {
			XMP_Uns32 bitMask = MakeUns32LE ( flags );
			LFA_Seek ( fileRef, fileAttrTag.pos + fileAttrTag.offset, SEEK_SET );
			LFA_Write ( fileRef, &bitMask, 4 );
			return true;
		} catch ( ... ) {}

		return false;

	}	// WriteFileAttrFlags
Beispiel #4
0
bool ASF_Support::WriteHeaderExtensionObject ( const std::string& buffer, std::string* header, const ASF_ObjectBase& _objectBase, const int /*reservePadding*/ )
{
	if ( ! IsEqualGUID ( ASF_Header_Extension_Object, _objectBase.guid ) || (! header) || (buffer.size() < 46) ) return false;

	const XMP_Uns64 offset = 46;
	int startPos = header->size();

	// copy header base
	header->append ( buffer, 0, offset );

	// read extended header-object structure beginning at the data part (offset = 46)
	XMP_Uns64 read = 0;
	XMP_Uns64 data = (_objectBase.size - offset);
	XMP_Uns64 pos = offset;

	ASF_ObjectBase objectBase;

	while ( read < data ) {

		memcpy ( &objectBase, &buffer[int(pos)], kASF_ObjectBaseLen );
		objectBase.size = GetUns64LE ( &objectBase.size );

		if ( IsEqualGUID ( ASF_Padding_Object, objectBase.guid ) ) {
			// eliminate
		} else {
			// copy other objects
			header->append ( buffer, XMP_Uns32(pos), XMP_Uns32(objectBase.size) );
		}

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

	}

	// update header extension data size
	XMP_Uns32 valueUns32LE = MakeUns32LE ( header->size() - startPos - offset );
	std::string newDataSize ( (const char*)&valueUns32LE, 4 );
	ReplaceString ( *header, newDataSize, (startPos + 42), 4 );

	// update new object size
	XMP_Uns64 valueUns64LE = MakeUns64LE ( header->size() - startPos );
	std::string newObjectSize ( (const char*)&valueUns64LE, 8 );
	ReplaceString ( *header, newObjectSize, (startPos + 16), 8 );

	return true;

}
Beispiel #5
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
Beispiel #6
0
	bool PutChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, long tagID, const char * inBuffer, UInt32 inBufferSize )
	{
		UInt32 len;
		UInt64 pos;
		atag tag;
	
		// Make sure we're writting an even number of bytes. Required by the RIFF specification.
		XMP_Assert ( (inBufferSize & 1) == 0 );
	
		try {

			bool found = FindChunk ( inOutRiffState, tagID, 0, 0, NULL, &len, &pos );
			if ( found ) {

				if ( len == inBufferSize ) {
					LFA_Seek ( inFileRef, pos, SEEK_SET );
					LFA_Write ( inFileRef, inBuffer, inBufferSize );
					return true;
				}
	
				pos -= 8;
				tag.id = MakeUns32LE ( ckidPremierePadding );
				LFA_Seek ( inFileRef, pos, SEEK_SET );
				LFA_Write ( inFileRef, &tag, 4 );
	
				if ( len > inBufferSize ) {
					pos += 8;
					AddTag ( inOutRiffState, ckidPremierePadding, len, pos, 0, 0, 0 );
				}

			}

		} catch ( ... ) {

			// If a write fails, it throws, so we return false
			return false;

		}
	
		bool ok = MakeChunk ( inFileRef, inOutRiffState, riffType, (inBufferSize + 8) );
		if ( ! ok ) return false;
	
		return WriteChunk ( inFileRef, tagID, inBuffer, inBufferSize );
	
	}
Beispiel #7
0
	bool UpdateHeader ( LFA_FileRef fileRef )
	{

		try {

			XMP_Int64 length64 = LFA_Measure ( fileRef );
			if ( (length64 < 8) || (length64 > (XMP_Int64)0xFFFFFFFFULL) ) return false;

			XMP_Uns32 length32 = MakeUns32LE ( (XMP_Uns32)length64 );

			LFA_Seek ( fileRef, 4, SEEK_SET );
			LFA_Write ( fileRef, &length32, 4 );
			
			return true;

		} catch ( ... ) {}
	
		return false;

	}	// UpdateHeader
Beispiel #8
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
Beispiel #9
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;

}
Beispiel #10
0
	bool MakeChunk ( LFA_FileRef inFileRef, RiffState & inOutRiffState, long riffType, UInt32 len )
	{
		long starttag;
		UInt32 taglen;
		UInt32 rifflen, avail;
		UInt64 pos;
	
		/* look for top level Premiere padding chunk */
		starttag = 0;
		while ( FindChunk ( inOutRiffState, ckidPremierePadding, riffType, 0, &starttag, &taglen, &pos ) ) {
	
			pos -= 8;
			taglen += 8;
			long extra = taglen - len;
			if ( extra < 0 ) continue;
	
			RiffIterator iter = inOutRiffState.tags.begin();
			iter += (starttag - 1);
	
			if ( extra == 0 ) {

				iter->len = 0;

			} else {

				atag pad;
				UInt64 padpos;
	
				/*  need 8 bytes extra to be able to split it */
				extra -= 8;
				if ( extra < 0 ) continue;
	
				try{
					padpos = pos + len;
					LFA_Seek ( inFileRef, padpos, SEEK_SET );
					pad.id = MakeUns32LE ( ckidPremierePadding );
					pad.len = MakeUns32LE ( extra );
					LFA_Write ( inFileRef, &pad, sizeof(pad) );
				} catch ( ... ) {
					return false;
				}

				iter->pos = padpos + 8;
				iter->len = extra;

			}
	
			/* seek back to start of original padding chunk */
			LFA_Seek ( inFileRef, pos, SEEK_SET );
	
			return true;

		}
	
		/* can't take padding chunk, so append new chunk to end of file */
	
		rifflen = inOutRiffState.rifflen + 8;
		avail = AVIMAXCHUNKSIZE - rifflen;
	
		LFA_Seek ( inFileRef, 0, SEEK_END );
		pos = GetFilePosition ( inFileRef );

		if ( (pos & 1) == 1 ) {
			// The file length is odd, need a pad byte.
			XMP_Uns8 pad = 0;
			LFA_Write ( inFileRef, &pad, 1 );
			++pos;
		}
	
		if ( avail < len ) {

			/* if needed, create new AVIX chunk */
			ltag avix;
	
			avix.id = MakeUns32LE ( FOURCC_RIFF );
			avix.len = MakeUns32LE ( 4 + len );
			avix.subid = MakeUns32LE ( formtypeAVIX );
			LFA_Write(inFileRef, &avix, sizeof(avix));
	
			pos += 12;
			AddTag ( inOutRiffState, avix.id, len, pos, 0, 0, 0 );

		} else {

			/* otherwise, rewrite length of last RIFF chunk in file */
			pos = inOutRiffState.riffpos + 4;
			rifflen = inOutRiffState.rifflen + len;
			XMP_Uns32 fileLen = MakeUns32LE ( rifflen );
			LFA_Seek ( inFileRef, pos, SEEK_SET );
			LFA_Write ( inFileRef, &fileLen, 4 );
			inOutRiffState.rifflen = rifflen;
	
			/* prepare to write data */
			LFA_Seek ( inFileRef, 0, SEEK_END );

		}
	
		return true;

	}
Beispiel #11
0
	static inline XMP_Uns32 ReadUns32_LE ( XMP_IO* file )
	{
		XMP_Uns32 value;
		file->ReadAll ( &value, 4 );
		return MakeUns32LE ( value );
	}
Beispiel #12
0
	static inline void WriteUns32_LE ( XMP_IO* file, XMP_Uns32 value )
	{
		XMP_Uns32 v = MakeUns32LE ( value );
		file->Write ( &v, 4 );
	}