Exemplo n.º 1
0
			// reads entire *FileHeader* structure from file (starting at current position)
			void read(XMP_IO* file)
			{
				this->release();

				file ->ReadAll ( fields , FIXED_SIZE  );

				XMP_Uns32 tmp32 = GetUns32LE( &this->fields[FileHeader::o_sig] );
				XMP_Validate( SIG == tmp32, "invalid header", kXMPErr_BadFileFormat );
				filenameLen   = GetUns16LE( &this->fields[FileHeader::o_fileNameLength] );
				extraFieldLen = GetUns16LE( &this->fields[FileHeader::o_extraFieldLength] );

				// nb unlike the CDFileHeader the FileHeader will in practice never have
				// extra fields. Reasoning: File headers never carry (their own) offsets,
				// (un)compressed size of XMP will hardly ever reach 4 GB

				if (filenameLen) {
					filename = new char[filenameLen];
					file->ReadAll ( filename, filenameLen );
				}
				if (extraFieldLen) {
					extraField = new char[extraFieldLen];
					file->ReadAll ( extraField, extraFieldLen );
					// *** NB: this WOULD need parsing for content files that are
					//   compressed or uncompressed >4GB (VERY unlikely for XMP)
				}
			}
Exemplo n.º 2
0
		void write(XMP_IO* file)
		{
			XMP_Enforce( this->SIG == GetUns32LE( &this->fields[o_Sig] ) );
			commentLen   = GetUns16LE( &this->fields[o_CommentLen] );
			file ->Write ( fields , FIXED_SIZE  );
			if (commentLen)
				file->Write ( comment, commentLen );
		}
Exemplo n.º 3
0
	XMP_Uns32 ReadFileAttrFlags ( IO::InputStream* inputStream )
	{
		XMP_Uns8 buffer[4];
		
		XMP_Uns32 bytes = inputStream->Read ( buffer, 4 );
		XMP_Assert ( bytes == 4 );

		return GetUns32LE ( buffer );

	}	// ReadFileAttrFlags
Exemplo n.º 4
0
			// writes structure to file (starting at current position)
			void write(XMP_IO* file)
			{
				XMP_Validate( SIG == GetUns32LE( &this->fields[FileHeader::o_sig] ), "invalid header on write", kXMPErr_BadFileFormat );

				filenameLen   = GetUns16LE( &this->fields[FileHeader::o_fileNameLength] );
				extraFieldLen = GetUns16LE( &this->fields[FileHeader::o_extraFieldLength] );

				file ->Write ( fields , FIXED_SIZE  );
				if (filenameLen)	file->Write ( filename, filenameLen    );
				if (extraFieldLen)	file->Write ( extraField, extraFieldLen  );
			}
Exemplo n.º 5
0
bool ASF_Support::UpdateFileSize ( XMP_IO* fileRef )
{
	if ( fileRef == 0 ) return false;

	XMP_Uns64 posCurrent = fileRef->Seek ( 0, kXMP_SeekFromCurrent );
	XMP_Uns64 newSizeLE  = MakeUns64LE ( fileRef->Length() );

	if ( this->posFileSizeInfo != 0 ) {

		fileRef->Seek ( this->posFileSizeInfo, kXMP_SeekFromStart );
	
	} else {

		// The position of the file size field is not known, find it.

		ASF_ObjectBase objHeader;
		
		// Read the Header object at the start of the file.

		fileRef->Rewind();
		fileRef->ReadAll ( &objHeader, kASF_ObjectBaseLen );
		if ( ! IsEqualGUID ( ASF_Header_Object, objHeader.guid ) ) return false;
		
		XMP_Uns32 childCount;
		fileRef->ReadAll ( &childCount, 4 );
		childCount = GetUns32LE ( &childCount );
		
		fileRef->Seek ( 2, kXMP_SeekFromCurrent );	// Skip the 2 reserved bytes.
		
		// Look for the File Properties object in the Header's children.

		for ( ; childCount > 0; --childCount ) {
			fileRef->ReadAll ( &objHeader, kASF_ObjectBaseLen );
			if ( IsEqualGUID ( ASF_File_Properties_Object, objHeader.guid ) ) break;
			XMP_Uns64 dataLen = GetUns64LE ( &objHeader.size ) - 24;
			fileRef->Seek ( dataLen, kXMP_SeekFromCurrent );	// Skip this object's data.
		}
		if ( childCount == 0 ) return false;
		
		// Seek to the file size field.

		XMP_Uns64 fpoSize = GetUns64LE ( &objHeader.size );
		if ( fpoSize < (16+8+16+8) ) return false;
		fileRef->Seek ( 16, kXMP_SeekFromCurrent );	// Skip to the file size field.

	}

	fileRef->Write ( &newSizeLE, 8 );	// Write the new file size.

	fileRef->Seek ( posCurrent, kXMP_SeekFromStart );
	return true;

}
Exemplo n.º 6
0
			// writes structure to file (starting at current position)
			void write(XMP_IO* file)
			{
				//// WRITE BACK REAL 64 BIT VALUES, CREATE EXTRA FIELD ///////////////
				//may only wipe extra field after obtaining all Info from it
				if (extraField)	delete extraField;
					extraFieldLen=0;

				if ( ( sizeUncompressed  > 0xffffffff ) ||
					 ( sizeCompressed    > 0xffffffff ) ||
					 ( offsetLocalHeader > 0xffffffff )  )
				{
					extraField = new char[64]; // actual maxlen is 32
					extraFieldLen = 4; //first fields are for ID, size
					if ( sizeUncompressed > 0xffffffff )
					{
						PutUns64LE( sizeUncompressed, &extraField[extraFieldLen] );
						extraFieldLen += 8;
						sizeUncompressed = 0xffffffff;
					}
					if ( sizeCompressed > 0xffffffff )
					{
						PutUns64LE( sizeCompressed, &extraField[extraFieldLen] );
						extraFieldLen += 8;
						sizeCompressed = 0xffffffff;
					}
					if ( offsetLocalHeader > 0xffffffff )
					{
						PutUns64LE( offsetLocalHeader, &extraField[extraFieldLen] );
						extraFieldLen += 8;
						offsetLocalHeader = 0xffffffff;
					}

					//write ID, dataSize
					PutUns16LE( 0x0001, &extraField[0] );
					PutUns16LE( extraFieldLen-4, &extraField[2] );
					//extraFieldSize
					PutUns16LE( extraFieldLen, &this->fields[CDFileHeader::o_extraFieldLength] );
				}

				// write out 32-bit ('ff-stubs' or not)
				PutUns32LE( (XMP_Uns32)sizeUncompressed, &fields[o_sizeUncompressed] );
				PutUns32LE( (XMP_Uns32)sizeCompressed, &fields[o_sizeCompressed] );
				PutUns32LE( (XMP_Uns32)offsetLocalHeader, &fields[o_offsetLocalHeader] );

				/// WRITE /////////////////////////////////////////////////////////////////
				XMP_Enforce( SIG == GetUns32LE( &this->fields[CDFileHeader::o_sig] ) );

				file ->Write ( fields , FIXED_SIZE  );
				if (filenameLen)	file->Write ( filename   , filenameLen    );
				if (extraFieldLen)	file->Write ( extraField , extraFieldLen  );
				if (commentLen)		file->Write ( extraField , extraFieldLen  );
			}
Exemplo n.º 7
0
		void read (XMP_IO* file)
		{
			UCFECD_Free();

			file->ReadAll ( fields, FIXED_SIZE );
			XMP_Validate( this->SIG == GetUns32LE( &this->fields[o_Sig] ), "invalid header", kXMPErr_BadFileFormat );

			commentLen = GetUns16LE( &this->fields[o_CommentLen] );
			if(commentLen)
			{
				comment = new char[commentLen];
				file->ReadAll ( comment, commentLen );
			}
		};
Exemplo n.º 8
0
	void FileInfo::CheckFormat ( LFA_FileRef fileRef )
	{
		IOBuffer ioBuf;
	
		LFA_Seek ( fileRef, 0, SEEK_SET );

		if ( CheckFileSpace ( fileRef, &ioBuf, SWF_SIGNATURE_LEN ) ) {

			if ( CheckBytes ( ioBuf.ptr, SWF_F_SIGNATURE_DATA, SWF_SIGNATURE_LEN ) ) {
				this->compressedFile = false;
			} else if ( CheckBytes ( ioBuf.ptr, SWF_C_SIGNATURE_DATA, SWF_SIGNATURE_LEN ) ) {
				this->compressedFile = true;
			}

			LFA_Seek ( fileRef, 4, SEEK_SET );
			XMP_Uns8 buffer[4];
			LFA_Read ( fileRef, buffer, 4 );
			iSize = GetUns32LE ( buffer );

		}

		LFA_Seek ( fileRef, 0, SEEK_SET );

	}	// FileInfo::CheckFormat
Exemplo n.º 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;

}
Exemplo n.º 10
0
bool ASF_Support::ReadHeaderObject ( XMP_IO* fileRef, ObjectState& inOutObjectState, const ObjectData& newObject )
{
	if ( ! IsEqualGUID ( ASF_Header_Object, newObject.guid) || (! legacyManager ) ) return false;

	std::string buffer;

	legacyManager->SetPadding(0);

	try {

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

		buffer.clear();
		buffer.reserve ( bufferSize );
		buffer.assign ( bufferSize, ' ' );
		fileRef->Seek ( pos, kXMP_SeekFromStart );
		fileRef->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;

		while ( read < newObject.len ) {

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

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

			if ( IsEqualGUID ( ASF_File_Properties_Object, objectBase.guid) && (objectBase.size >= 104 ) ) {

				buffer.clear();
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				fileRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				// save position of filesize-information
				posFileSizeInfo = (pos + 40);

				// creation date
				std::string sub ( buffer.substr ( 48, 8 ) );
				legacyManager->SetField ( ASF_LegacyManager::fieldCreationDate, sub );

				// broadcast flag set ?
				XMP_Uns32 flags = GetUns32LE ( &buffer[88] );
				inOutObjectState.broadcast = (flags & 1);
				legacyManager->SetBroadcast ( inOutObjectState.broadcast );

				legacyManager->SetObjectExists ( ASF_LegacyManager::objectFileProperties );

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

				buffer.clear();
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				fileRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				XMP_Uns16 titleLen = GetUns16LE ( &buffer[24] );
				XMP_Uns16 authorLen = GetUns16LE ( &buffer[26] );
				XMP_Uns16 copyrightLen = GetUns16LE ( &buffer[28] );
				XMP_Uns16 descriptionLen = GetUns16LE ( &buffer[30] );
				/*XMP_Uns16 ratingLen = GetUns16LE ( &buffer[32] );*/

				XMP_Uns16 fieldPos = 34;

				std::string titleStr = buffer.substr ( fieldPos, titleLen );
				fieldPos += titleLen;
				legacyManager->SetField ( ASF_LegacyManager::fieldTitle, titleStr );

				std::string authorStr = buffer.substr ( fieldPos, authorLen );
				fieldPos += authorLen;
				legacyManager->SetField ( ASF_LegacyManager::fieldAuthor, authorStr );

				std::string copyrightStr = buffer.substr ( fieldPos, copyrightLen );
				fieldPos += copyrightLen;
				legacyManager->SetField ( ASF_LegacyManager::fieldCopyright, copyrightStr );

				std::string descriptionStr = buffer.substr ( fieldPos, descriptionLen );
				fieldPos += descriptionLen;
				legacyManager->SetField ( ASF_LegacyManager::fieldDescription, descriptionStr );

				/* rating is currently not part of reconciliation
				std::string ratingStr = buffer.substr ( fieldPos, ratingLen );
				fieldPos += ratingLen;
				legacyData.append ( titleStr );
				*/

				legacyManager->SetObjectExists ( ASF_LegacyManager::objectContentDescription );

			} else if ( IsEqualGUID ( ASF_Content_Branding_Object, objectBase.guid ) ) {

				buffer.clear();
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				fileRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				XMP_Uns32 fieldPos = 28;

				// copyright URL is 3. element with variable size
				for ( int i = 1; i <= 3 ; ++i ) {
					XMP_Uns32 len = GetUns32LE ( &buffer[fieldPos] );
					if ( i == 3 ) {
						std::string copyrightURLStr = buffer.substr ( fieldPos + 4, len );
						legacyManager->SetField ( ASF_LegacyManager::fieldCopyrightURL, copyrightURLStr );
					}
					fieldPos += (len + 4);
				}

				legacyManager->SetObjectExists ( ASF_LegacyManager::objectContentBranding );

#if ! Exclude_LicenseURL_Recon

			} else if ( IsEqualGUID ( ASF_Content_Encryption_Object, objectBase.guid ) ) {

				buffer.clear();
				buffer.reserve ( XMP_Uns32( objectBase.size ) );
				buffer.assign ( XMP_Uns32( objectBase.size ), ' ' );
				fileRef->ReadAll ( const_cast<char*>(buffer.data()), XMP_Int32(objectBase.size) );

				XMP_Uns32 fieldPos = 24;

				// license URL is 4. element with variable size
				for ( int i = 1; i <= 4 ; ++i ) {
					XMP_Uns32 len = GetUns32LE ( &buffer[fieldPos] );
					if ( i == 4 ) {
						std::string licenseURLStr = buffer.substr ( fieldPos + 4, len );
						legacyManager->SetField ( ASF_LegacyManager::fieldLicenseURL, licenseURLStr );
					}
					fieldPos += (len + 4);
				}

				legacyManager->SetObjectExists ( objectContentEncryption );

#endif

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

				legacyManager->SetPadding ( legacyManager->GetPadding() + (objectBase.size - 24) );

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

				this->ReadHeaderExtensionObject ( fileRef, inOutObjectState, pos, objectBase );

			} else if (objectBase.size == 0) {
				break;
			}

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

	} catch ( ... ) {

		return false;

	}

	legacyManager->ComputeDigest();

	return true;
}
Exemplo n.º 11
0
			// reads entire structure from file (starting at current position)
			void read(XMP_IO* file)
			{
				this->release();

				file->ReadAll ( fields, FIXED_SIZE );
				XMP_Validate( SIG == GetUns32LE( &this->fields[CDFileHeader::o_sig] ), "invalid header", kXMPErr_BadFileFormat );

				filenameLen   = GetUns16LE( &this->fields[CDFileHeader::o_fileNameLength] );
				extraFieldLen = GetUns16LE( &this->fields[CDFileHeader::o_extraFieldLength] );
				commentLen    = GetUns16LE( &this->fields[CDFileHeader::o_commentLength] );

				if (filenameLen) {
					filename = new char[filenameLen];
					file->ReadAll ( filename, filenameLen );
				}
				if (extraFieldLen) {
					extraField = new char[extraFieldLen];
					file->ReadAll ( extraField, extraFieldLen );
				}
				if (commentLen) {
					comment = new char[commentLen];
					file->ReadAll ( comment, commentLen );
				}

				////// GET ACTUAL 64 BIT VALUES //////////////////////////////////////////////
				// get 32bit goodies first, correct later
				sizeUncompressed		= GetUns32LE( &fields[o_sizeUncompressed] );
				sizeCompressed			= GetUns32LE( &fields[o_sizeCompressed] );
				offsetLocalHeader		= GetUns32LE( &fields[o_offsetLocalHeader] );

				XMP_Int32 offset = 0;
				while ( offset < extraFieldLen )
				{
					XMP_Validate( (extraFieldLen - offset) >= 4, "need 4 bytes for next header ID+len", kXMPErr_BadFileFormat);
					XMP_Uns16 headerID = GetUns16LE( &extraField[offset] );
					XMP_Uns16 dataSize = GetUns16LE( &extraField[offset+2] );
					offset += 4;

					XMP_Validate( (extraFieldLen - offset) <= dataSize,
									"actual field lenght not given", kXMPErr_BadFileFormat);
					if ( headerID == 0x1 ) //we only care about "Zip64 extended information extra field"
					{
						XMP_Validate( offset < extraFieldLen, "extra field too short", kXMPErr_BadFileFormat);
						if (sizeUncompressed == 0xffffffff)
						{
							sizeUncompressed = GetUns64LE( &extraField[offset] );
							offset += 8;
						}
						if (sizeCompressed == 0xffffffff)
						{
							sizeCompressed = GetUns64LE( &extraField[offset] );
							offset += 8;
						}
						if (offsetLocalHeader == 0xffffffff)
						{
							offsetLocalHeader = GetUns64LE( &extraField[offset] );
							offset += 8;
						}
					}
					else
					{
						offset += dataSize;
					} // if
				} // while
			} // read()
Exemplo n.º 12
0
			XMP_Uns32 sizeTotalCF()
			{
				//*** not zip64 bit safe yet, use only for non-large xmp packet
				return this->sizeHeader() + GetUns32LE( &fields[FileHeader::o_sizeCompressed] );
			}
Exemplo n.º 13
0
		// writes structure to file (starting at current position)
		void write(XMP_IO* file)
		{
			XMP_Validate( ID == GetUns32LE( &this->fields[o_sig] ), "invalid header on write", kXMPErr_BadFileFormat );
			file ->Write ( fields , TOTAL_SIZE  );
		}
Exemplo n.º 14
0
	static bool  ReadTag ( LFA_FileRef inFileRef, long * outTag, UInt32 * outLength, long * subtype, UInt64 & inOutPosition, UInt64 maxOffset )
	{
		UInt32	realLength;
	
		long bytesRead;
		bytesRead = LFA_Read ( inFileRef, outTag, 4 );
		if ( bytesRead != 4 ) return false;
		*outTag = GetUns32LE ( outTag );
		
		bytesRead = LFA_Read ( inFileRef, outLength, 4 );
		if ( bytesRead != 4 ) return false;
		*outLength = GetUns32LE ( outLength );

		realLength = *outLength;
		realLength += (realLength & 1);		// Round up to an even value.

		inOutPosition = GetFilePosition ( inFileRef );	// The file offset of the data portion.
		UInt64 maxLength = maxOffset - inOutPosition;

		if ( (inOutPosition > maxOffset) || ((UInt64)(*outLength) > maxLength) ) {

			bool ignoreLastPad = true;	// Ignore cases where a final pad byte is missing.
			UInt64 fileLen = LFA_Measure ( inFileRef );
			if ( inOutPosition > (maxOffset + 1) ) ignoreLastPad = false;
			if ( (UInt64)(*outLength) > (maxLength + 1) ) ignoreLastPad = false;

			if ( ! ignoreLastPad ) {

				// Workaround for bad files in the field that have a bad size in the outermost RIFF
				// chunk. Do a "runtime repair" of cases where the length is too long (beyond EOF).
				// This handles read-only usage, update usage is repaired (or not) in the handler.

				bool oversizeRIFF = (inOutPosition == 8) &&	// Is this the initial 'RIFF' chunk?
									(fileLen >= 8);			// Is the file at least of the minimal size?
								 
				if ( ! oversizeRIFF ) {
					XMP_Throw ( "RIFF tag exceeds maximum length", kXMPErr_BadValue );
				} else {
					*outLength = (UInt32)(fileLen) - 8;
					realLength = *outLength;
					realLength += (realLength & 1);		// Round up to an even value.
				}

			}

		}
		
		*subtype = 0;

		if ( (*outTag != FOURCC_LIST) && (*outTag != FOURCC_RIFF) ) {

			UInt64 tempPos = inOutPosition + realLength;
			if ( tempPos <= maxOffset ) {
				LFA_Seek ( inFileRef, tempPos, SEEK_SET );
			} else if ( (tempPos == (maxOffset + 1)) && (maxOffset == (UInt64)LFA_Measure(inFileRef)) ) {
				LFA_Seek ( inFileRef, 0, SEEK_END );	// Hack to tolerate a missing final pad byte.
			} else {
				XMP_Throw ( "Bad RIFF offset", kXMPErr_BadValue );
			}

		} else  {

			bytesRead = LFA_Read ( inFileRef, subtype, 4 );
			if ( bytesRead != 4 ) return false;
			*subtype = GetUns32LE ( subtype );

			*outLength -= 4;
			realLength -= 4;

			// Special case:
			// Since the 'movi' chunk can contain billions of subchunks, skip over the 'movi' subchunk.
			//
			// The 'movi' subtype is added to the list as the TAG.
			// The subtype is returned empty so nobody will try to parse the subchunks.

			if ( *subtype == listtypeAVIMOVIE ) {
				inOutPosition = GetFilePosition ( inFileRef );
				UInt64 tempPos = inOutPosition + realLength;
				if ( tempPos <= maxOffset ) {
					LFA_Seek ( inFileRef, tempPos, SEEK_SET );
				} else if ( (tempPos == (maxOffset + 1)) && (maxOffset == (UInt64)LFA_Measure(inFileRef)) ) {
					LFA_Seek ( inFileRef, 0, SEEK_END );	// Hack to tolerate a missing final pad byte.
				} else {
					XMP_Throw ( "Bad RIFF offset", kXMPErr_BadValue );
				}
				*outLength += 4;
				*outTag = *subtype;
				*subtype = 0;
			}

			inOutPosition = GetFilePosition ( inFileRef );

		}
	
		return true;

	}
Exemplo n.º 15
0
	bool  ReadTag ( IO::InputStream* inputStream, TagState & inOutTagState,
					long* tagType, XMP_Uns32* tagLength, XMP_Uns64& inOutPosition )
	{

		try {

			XMP_Uns64 startPosition = inOutPosition;
			long bytesRead;
			XMP_Uns8 buffer[4];
			
			bytesRead = inputStream->Read ( buffer, 2 );
			if ( bytesRead != 2 ) return false;

			inOutPosition += 2;
			XMP_Uns16 code = GetUns16LE ( buffer );
			*tagType = code >> 6;
			*tagLength = code & 0x3f;

			bool longTag = false;

			if ( *tagLength == 0x3f ) {
				longTag = true;
				bytesRead = inputStream->Read ( buffer, 4 );
				if ( bytesRead != 4 ) return false;
				inOutPosition += 4;
				*tagLength = GetUns32LE ( buffer );
			}

			inOutPosition += *tagLength;

			TagData	newTag;
	
			newTag.pos = startPosition;
			newTag.len = *tagLength;
			newTag.id = *tagType;
			newTag.offset = ( (! longTag) ? 2 : 6 );

			// we cannot check valid XMP within the handler
			// provide validating XMP by invoking XMPCore
			// check tag for XMP
			if ( newTag.id == SWF_TAG_ID_METADATA ) {
				newTag.xmp = true;
				inOutTagState.xmpTag = newTag;
				CheckTag ( inputStream, inOutTagState, newTag );
				if ( ! inOutTagState.hasFileAttrTag ) inOutTagState.hasXMP = true;
			}
				
			//store FileAttribute Tag
			if ( newTag.id == SWF_TAG_ID_FILEATTRIBUTES ) {
				inOutTagState.hasFileAttrTag = true;
				inOutTagState.fileAttrTag = newTag;
				inOutTagState.hasXMP = HasMetadata ( inputStream, inOutTagState );
				//decreasing since stream moved on within HasMetadata function
				*tagLength -= 4;
			}
			
			//store tag in vector to process later
			inOutTagState.tags.push_back ( newTag );

			//seek to next tag
			if ( ! newTag.xmp ) inputStream->Skip ( *tagLength );
			if ( inputStream->IsEOF() ) return false;

		} catch ( ... ) {

			return false;

		}
	
		return true;

	}	// ReadTag