Exemple #1
0
bool xmp_files_close(XmpFilePtr xf, XmpCloseFileOptions options)
{
	CHECK_PTR(xf, false);
	RESET_ERROR;
	try {
		SXMPFiles *txf = (SXMPFiles*)xf;
		txf->CloseFile(options);
	}
	catch(const XMP_Error & e) {
		set_error(e);
		return false;
	}
	return true;
}
Exemple #2
0
static void
ProcessFile ( const char * fileName  )
{
    bool ok;
    char buffer [1000];

    SXMPMeta  xmpMeta;
    SXMPFiles xmpFile;
    XMP_FileFormat format;
    XMP_OptionBits openFlags, handlerFlags;
    XMP_PacketInfo xmpPacket;

    sprintf ( buffer, "Dumping main XMP for %s", fileName );
    WriteMinorLabel ( sLogFile, buffer );

    xmpFile.OpenFile ( fileName, kXMP_UnknownFile, kXMPFiles_OpenForRead );
    ok = xmpFile.GetFileInfo ( 0, &openFlags, &format, &handlerFlags );
    if ( ! ok ) return;

    fprintf ( sLogFile, "File info : format = \"%.4s\", handler flags = %.8X\n", &format, handlerFlags );
    fflush ( sLogFile );

    ok = xmpFile.GetXMP ( &xmpMeta, 0, &xmpPacket );
    if ( ! ok ) return;

    XMP_Int32 offset = (XMP_Int32)xmpPacket.offset;
    XMP_Int32 length = xmpPacket.length;
    fprintf ( sLogFile, "Packet info : offset = %d, length = %d\n", offset, length );
    fflush ( sLogFile );

    fprintf ( sLogFile, "\nInitial XMP from %s\n", fileName );
    xmpMeta.DumpObject ( DumpCallback, sLogFile );

    xmpFile.CloseFile();

}	// ProcessFile
Exemple #3
0
/**
* Initializes the toolkit and attempts to open a file for updating its metadata. Initially
* an attempt to open the file is done with a handler, if this fails then the file is opened with
* packet scanning. Once the file is open several properties are read and displayed in the console.
*
* Several properties are then modified, first by checking for their existence and then, if they 
* exist, by updating their values. The updated properties are then displayed again in the console. 
*
* Next a new XMP object is created from an RDF stream, the properties from the new XMP object are
* appended to the original XMP object and the updated properties are displayed in the console for
* last time.
*
* The updated XMP object is then serialized in different formats and written to text files.  Lastly,
* the modified XMP is written back to the resource file.
*/
int main ( int argc, const char * argv[] )
{
	if ( argc != 2 ) // 2 := command and 1 parameter
	{
		cout << "usage: ModifyingXMP (filename)" << endl;
		return 0;
	}

	string filename = string( argv[1] );

	if(!SXMPMeta::Initialize())
	{
		cout << "Could not initialize toolkit!";
		return -1;
	}
	
	XMP_OptionBits options = 0;
	#if UNIX_ENV
		options |= kXMPFiles_ServerMode;
	#endif
		
	// Must initialize SXMPFiles before we use it
	if(SXMPFiles::Initialize(options))
	{
		try
		{
			// Options to open the file with - open for editing and use a smart handler
			XMP_OptionBits opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUseSmartHandler;

			bool ok;
			SXMPFiles myFile;
			std::string status = "";

			// First we try and open the file
			ok = myFile.OpenFile(filename, kXMP_UnknownFile, opts);
			if( ! ok )
			{
				status += "No smart handler available for " + filename + "\n";
				status += "Trying packet scanning.\n";

				// Now try using packet scanning
				opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUsePacketScanning;
				ok = myFile.OpenFile(filename, kXMP_UnknownFile, opts);
			}

			// If the file is open then read get the XMP data
			if(ok)
			{
				cout << status << endl;
				cout << filename << " is opened successfully" << endl;
				// Create the XMP object and get the XMP data
				SXMPMeta meta;
				myFile.GetXMP(&meta);

				// Display some properties in the console
				displayPropertyValues(&meta);
				
				///////////////////////////////////////////////////
				// Now modify the XMP
				if(meta.DoesPropertyExist(kXMP_NS_XMP, "CreatorTool"))
				{
					// Update xap:CreatorTool - we don't need to set any option bits
					meta.SetProperty(kXMP_NS_XMP, "CreatorTool", "Updated By XMP SDK", 0);
				}

				// Update the Metadata Date
				XMP_DateTime updatedTime;
				// Get the current time.  This is a UTC time automatically 
				// adjusted for the local time
				SXMPUtils::CurrentDateTime(&updatedTime);
				if(meta.DoesPropertyExist(kXMP_NS_XMP, "MetadataDate"))
				{
					meta.SetProperty_Date(kXMP_NS_XMP, "MetadataDate", updatedTime, 0);
				}
				
				// Add an item onto the dc:creator array
				// Note the options used, kXMP_PropArrayIsOrdered, if the array does not exist it will be created
				meta.AppendArrayItem(kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered, "Author Name", 0);
				meta.AppendArrayItem(kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered, "Another Author Name", 0);

				// Now update alt-text properties
				meta.SetLocalizedText(kXMP_NS_DC, "title", "en", "en-US", "An English title");
				meta.SetLocalizedText(kXMP_NS_DC, "title", "fr", "fr-FR", "Un titre Francais");
				
				// Display the properties again to show changes
				cout << "After update:" << endl;
				displayPropertyValues(&meta);

				// Create a new XMP object from an RDF string
				SXMPMeta rdfMeta = createXMPFromRDF();

				// Append the newly created properties onto the original XMP object
				// This will:
				// a) Add ANY new TOP LEVEL properties in the source (rdfMeta) to the destination (meta)
				// b) Replace any top level properties in the source with the matching properties from the destination
				SXMPUtils::ApplyTemplate(&meta, rdfMeta, kXMPTemplate_AddNewProperties | kXMPTemplate_ReplaceExistingProperties | kXMPTemplate_IncludeInternalProperties);

				// Display the properties again to show changes
				cout << "After Appending Properties:" << endl;
				displayPropertyValues(&meta);

				// Serialize the packet and write the buffer to a file
				// Let the padding be computed and use the default linefeed and indents without limits
				string metaBuffer;
				meta.SerializeToBuffer(&metaBuffer, 0, 0, "", "", 0);

				// Write the packet to a file as RDF
				writeRDFToFile(&metaBuffer, filename+"_XMP_RDF.txt");
								
				// Write the packet to a file but this time as compact RDF
				XMP_OptionBits outOpts = kXMP_OmitPacketWrapper | kXMP_UseCompactFormat;
				meta.SerializeToBuffer(&metaBuffer, outOpts);
				writeRDFToFile(&metaBuffer, filename+"_XMP_RDF_Compact.txt");

				// Check we can put the XMP packet back into the file
				if(myFile.CanPutXMP(meta))
				{
					// If so then update the file with the modified XMP
					myFile.PutXMP(meta);
				}
			
				// Close the SXMPFile.  This *must* be called.  The XMP is not
				// actually written and the disk file is not closed until this call is made.
				myFile.CloseFile();
			}
			else
			{
				cout << "Unable to open " << filename << endl;
			}
		}
		catch(XMP_Error & e)
		{
			cout << "ERROR: " << e.GetErrMsg() << endl;
		}

		// Terminate the toolkit
		SXMPFiles::Terminate();
		SXMPMeta::Terminate();

	}
	else
	{
		cout << "Could not initialize SXMPFiles.";
		return -1;
	}
	
	return 0;
}
Exemple #4
0
/**
*	Initializes the toolkit and attempts to open a file for reading metadata.  Initially
* an attempt to open the file is done with a handler, if this fails then the file is opened with
* packet scanning. Once the file is open several properties are read and displayed in the console.  
* The XMP object is then dumped to a text file and the resource file is closed.
*/
int main ( int argc, const char * argv[] )
{
	if ( argc != 2 ) // 2 := command and 1 parameter
	{
		cout << "usage: ReadingXMP (filename)" << endl;
		return 0;
	}
	
	string filename = string( argv[1] );

	if(!SXMPMeta::Initialize())
	{
		cout << "Could not initialize toolkit!";
		return -1;
	}
	
	// Must initialize SXMPFiles before we use it
	if ( ! SXMPFiles::Initialize() )
	{
		cout << "Could not initialize SXMPFiles.";
		return -1;
	}
	
	try
	{
		// Options to open the file with - read only and use a file handler
		XMP_OptionBits opts = kXMPFiles_OpenForRead | kXMPFiles_OpenUseSmartHandler;

		bool ok;
		SXMPFiles myFile;			
		std::string status = "";

		// First we try and open the file
		ok = myFile.OpenFile(filename, kXMP_UnknownFile, opts);
		if( ! ok )
		{
			status += "No smart handler available for " + filename + "\n";
			status += "Trying packet scanning.\n";

			// Now try using packet scanning
			opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUsePacketScanning;
			ok = myFile.OpenFile(filename, kXMP_UnknownFile, opts);
		}


		// If the file is open then read the metadata
		if(ok)
		{
			cout << status << endl;
			cout << filename << " is opened successfully" << endl;
			// Create the xmp object and get the xmp data
			SXMPMeta meta;
			myFile.GetXMP(&meta);

			bool exists;

			// Read a simple property
			string simpleValue;  //Stores the value for the property
			exists = meta.GetProperty(kXMP_NS_XMP, "CreatorTool", &simpleValue, NULL);
			if(exists)
				cout << "CreatorTool = " << simpleValue << endl;
			else
				simpleValue.clear();

			// Get the first element in the dc:creator array
			string elementValue;
			exists = meta.GetArrayItem(kXMP_NS_DC, "creator", 1, &elementValue, NULL);
			if(exists)
				cout << "dc:creator = " << elementValue << endl;
			else
				elementValue.clear();

			// Get the the entire dc:subject array 
			string propValue;
			int arrSize = meta.CountArrayItems(kXMP_NS_DC, "subject");
			for(int i = 1; i <= arrSize;i++)
			{
				meta.GetArrayItem(kXMP_NS_DC, "subject", i, &propValue, 0);
				cout << "dc:subject[" << i << "] = " << propValue << endl;
			}

			// Get the dc:title for English and French
			string itemValue;
			string actualLang;
			meta.GetLocalizedText(kXMP_NS_DC, "title", "en", "en-US", NULL, &itemValue, NULL);
			cout << "dc:title in English = " << itemValue << endl;

			meta.GetLocalizedText(kXMP_NS_DC, "title", "fr", "fr-FR", NULL, &itemValue, NULL);
			cout << "dc:title in French = " << itemValue << endl;

			// Get dc:MetadataDate
			XMP_DateTime myDate;
			if(meta.GetProperty_Date(kXMP_NS_XMP, "MetadataDate", &myDate, NULL))
			{
				// Convert the date struct into a convenient string and display it
				string myDateStr;
				SXMPUtils::ConvertFromDate(myDate, &myDateStr);
				cout << "meta:MetadataDate = " << myDateStr << endl;						 
			}

			// See if the flash struct exists and see if it was used
			string path, value;
			exists = meta.DoesStructFieldExist(kXMP_NS_EXIF, "Flash", kXMP_NS_EXIF,"Fired");
			if(exists)
			{
				bool flashFired;
				SXMPUtils::ComposeStructFieldPath(kXMP_NS_EXIF, "Flash", kXMP_NS_EXIF, "Fired", &path);
				meta.GetProperty_Bool(kXMP_NS_EXIF, path.c_str(), &flashFired, NULL);
				string flash = (flashFired) ? "True" : "False";

				cout << "Flash Used = " << flash << endl;
			}

			// Dump the current xmp object to a file
			ofstream dumpFile;
			dumpFile.open("XMPDump.txt", ios::out);
			meta.DumpObject(DumpXMPToFile, &dumpFile);
			dumpFile.close();
			cout << endl << "XMP dumped to XMPDump.txt" << endl;

			// Close the SXMPFile.  The resource file is already closed if it was
			// opened as read only but this call must still be made.
			myFile.CloseFile();
		}
		else
		{
			cout << "Unable to open " << filename << endl;
		}
	}
	catch(XMP_Error & e)
	{
		cout << "ERROR: " << e.GetErrMsg() << endl;
	}

	// Terminate the toolkit
	SXMPFiles::Terminate();
	SXMPMeta::Terminate();

	return 0;
}