コード例 #1
0
ファイル: ReconcileIPTC.cpp プロジェクト: hfiguiere/exempi
static void ExportIPTC_LangAlt ( const SXMPMeta & xmp, IPTC_Manager * iptc,
								 const char * xmpNS, const char * xmpProp, XMP_Uns8 id )
{
	std::string    value;
	XMP_OptionBits xmpFlags;

	bool found = xmp.GetProperty ( xmpNS, xmpProp, 0, &xmpFlags );
	if ( ! found ) {
		iptc->DeleteDataSet ( id );
		return;
	}

	if ( ! XMP_ArrayIsAltText ( xmpFlags ) ) return;	// ? Complain? Delete the DataSet?

	found = xmp.GetLocalizedText ( xmpNS, xmpProp, "", "x-default", 0, &value, 0 );
	if ( ! found ) {
		iptc->DeleteDataSet ( id );
		return;
	}

	NormalizeToCR ( &value );

	size_t iptcCount = iptc->GetDataSet ( id, 0 );
	if ( iptcCount > 1 ) iptc->DeleteDataSet ( id );

	iptc->SetDataSet_UTF8 ( id, value.c_str(), (XMP_Uns32)value.size(), 0 );	// ! Don't append a 2nd DataSet!

}	// ExportIPTC_LangAlt
コード例 #2
0
ファイル: exempi.cpp プロジェクト: JanX2/exempi
bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name,
			    const char *genericLang, const char *specificLang,
			    XmpStringPtr actualLang, XmpStringPtr itemValue,
			    uint32_t *propsBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	try {
		SXMPMeta *txmp = (SXMPMeta *)xmp;
		XMP_OptionBits optionBits;
		ret = txmp->GetLocalizedText(schema, name, genericLang,
					     specificLang, STRING(actualLang), 
					     STRING(itemValue), &optionBits);
		if(propsBits) {
			*propsBits = optionBits;
		}
	}
	catch(const XMP_Error & e) {
		set_error(e);
		ret = false;
	}
	return ret;
}
コード例 #3
0
ファイル: RIFF_Support.cpp プロジェクト: JanX2/exempi
void exportAndRemoveProperties ( RIFF_MetaHandler* handler )
{
	SXMPMeta xmpObj = handler->xmpObj;

	exportXMPtoCr8rChunk ( handler, &handler->cr8rChunk );				

	// 1/4 BWF Bext extension chunk -----------------------------------------------
	if ( handler->parent->format == kXMP_WAVFile ) {	// applies only to WAV
		exportXMPtoBextChunk ( handler, &handler->bextChunk );
	}

	// 2/4 DISP chunk
	if ( handler->parent->format == kXMP_WAVFile ) {	// create for WAVE only

		std::string actualLang, xmpValue;
		bool r = xmpObj.GetLocalizedText ( kXMP_NS_DC, "title", "" , "x-default" , &actualLang, &xmpValue, 0 );

		if ( r && ( actualLang == "x-default" ) ) {	// prop exists?

			// the 'right' DISP is lead by a 32 bit low endian 0x0001
			std::string dispValue = std::string( "\x1\0\0\0", 4 );
			dispValue.append ( xmpValue );

			if ( handler->dispChunk == 0 ) {
				handler->dispChunk = new RIFF::ValueChunk ( handler->riffChunks.at(0), std::string(), kChunk_DISP );
			}

			// ! The NUL is optional in WAV to avoid a parsing bug in Audition 3 - can't handle implicit pad byte.
			handler->dispChunk->SetValue ( dispValue, ValueChunk::kNULisOptional );

		} else {	// remove Disp Chunk..

			if ( handler->dispChunk != 0 ) {	// ..if existing
				ContainerChunk* mainChunk = handler->riffChunks.at(0);				
				Chunk* needle = handler->dispChunk;
				chunkVectIter iter = mainChunk->getChild ( needle );
				if ( iter != mainChunk->children.end() ) {
					mainChunk->replaceChildWithJunk ( *iter );
					handler->dispChunk = 0;
					mainChunk->hasChange = true;
				}
			}

		}

	}

	// 3/4 LIST:INFO	
	exportXMPtoListChunk ( kChunk_LIST, kType_INFO, handler, &handler->listInfoChunk, listInfoProps );

	// 4/4 LIST:Tdat
	exportXMPtoListChunk ( kChunk_LIST, kType_Tdat, handler, &handler->listTdatChunk, listTdatProps );

}
コード例 #4
0
ファイル: ReadingXMP.cpp プロジェクト: JJWTimmer/Uforia
/**
*	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;
}
コード例 #5
0
ファイル: ASF_Support.cpp プロジェクト: hfiguiere/exempi
int ASF_LegacyManager::ExportLegacy ( const SXMPMeta& xmp )
{
	int changed = 0;
	objectsToExport = 0;
	legacyDiff = 0;

	std::string utf8;
	std::string utf16;
	XMP_OptionBits flags;

	if ( ! broadcastSet ) {
		if ( xmp.GetProperty ( kXMP_NS_XMP, "CreateDate", &utf8, &flags ) ) {
			std::string date;
			ConvertISODateToMSDate ( utf8, &date );
			if ( fields[fieldCreationDate] != date ) {
				legacyDiff += date.size();
				legacyDiff -= fields[fieldCreationDate].size();
				this->SetField ( fieldCreationDate, date );
				objectsToExport |= objectFileProperties;
				changed ++;
			}
		}
	}

	if ( xmp.GetLocalizedText ( kXMP_NS_DC, "title", "", "x-default", 0, &utf8, &flags ) ) {
		NormalizeStringTrailingNull ( utf8 );
		ToUTF16 ( (const UTF8Unit*)utf8.data(), utf8.size(), &utf16, false );
		if ( fields[fieldTitle] != utf16 ) {
			legacyDiff += utf16.size();
			legacyDiff -= fields[fieldTitle].size();
			this->SetField ( fieldTitle, utf16 );
			objectsToExport |= objectContentDescription;
			changed ++;
		}
	}

	utf8.clear();
	SXMPUtils::CatenateArrayItems ( xmp, kXMP_NS_DC, "creator", 0, 0, kXMPUtil_AllowCommas, &utf8 );
	if ( ! utf8.empty() ) {
		NormalizeStringTrailingNull ( utf8 );
		ToUTF16 ( (const UTF8Unit*)utf8.data(), utf8.size(), &utf16, false );
		if ( fields[fieldAuthor] != utf16 ) {
			legacyDiff += utf16.size();
			legacyDiff -= fields[fieldAuthor].size();
			this->SetField ( fieldAuthor, utf16 );
			objectsToExport |= objectContentDescription;
			changed ++;
		}
	}

	if ( xmp.GetLocalizedText ( kXMP_NS_DC, "rights", "", "x-default", 0, &utf8, &flags ) ) {
		NormalizeStringTrailingNull ( utf8 );
		ToUTF16 ( (const UTF8Unit*)utf8.data(), utf8.size(), &utf16, false );
		if ( fields[fieldCopyright] != utf16 ) {
			legacyDiff += utf16.size();
			legacyDiff -= fields[fieldCopyright].size();
			this->SetField ( fieldCopyright, utf16 );
			objectsToExport |= objectContentDescription;
			changed ++;
		}
	}

	if ( xmp.GetLocalizedText ( kXMP_NS_DC, "description", "", "x-default", 0, &utf8, &flags ) ) {
		NormalizeStringTrailingNull ( utf8 );
		ToUTF16 ( (const UTF8Unit*)utf8.data(), utf8.size(), &utf16, false );
		if ( fields[fieldDescription] != utf16 ) {
			legacyDiff += utf16.size();
			legacyDiff -= fields[fieldDescription].size();
			this->SetField ( fieldDescription, utf16 );
			objectsToExport |= objectContentDescription;
			changed ++;
		}
	}

	if ( xmp.GetProperty ( kXMP_NS_XMP_Rights, "WebStatement", &utf8, &flags ) ) {
		NormalizeStringTrailingNull ( utf8 );
		if ( fields[fieldCopyrightURL] != utf8 ) {
			legacyDiff += utf8.size();
			legacyDiff -= fields[fieldCopyrightURL].size();
			this->SetField ( fieldCopyrightURL, utf8 );
			objectsToExport |= objectContentBranding;
			changed ++;
		}
	}

#if ! Exclude_LicenseURL_Recon
	if ( xmp.GetProperty ( kXMP_NS_XMP_Rights, "Certificate", &utf8, &flags ) ) {
		NormalizeStringTrailingNull ( utf8 );
		if ( fields[fieldLicenseURL] != utf8 ) {
			legacyDiff += utf8.size();
			legacyDiff -= fields[fieldLicenseURL].size();
			this->SetField ( fieldLicenseURL, utf8 );
			objectsToExport |= objectContentEncryption;
			changed ++;
		}
	}
#endif

	// find objects, that would need to be created on legacy export
	int newObjects = (objectsToExport & !objectsExisting);

	// calculate minimum storage for new objects, that might be created on export
	if ( newObjects & objectContentDescription )
		legacyDiff += sizeContentDescription;
	if ( newObjects & objectContentBranding )
		legacyDiff += sizeContentBranding;
	if ( newObjects & objectContentEncryption )
		legacyDiff += sizeContentEncryption;

	ComputeDigest();

	return changed;

}
コード例 #6
0
ファイル: RIFF_Support.cpp プロジェクト: JanX2/exempi
static void exportXMPtoListChunk( XMP_Uns32 id, XMP_Uns32 containerType, 
						   RIFF_MetaHandler* handler, ContainerChunk** listChunk, Mapping mapping[])
{
	// note: ContainerChunk**: adress of pointer to allow changing the pointer itself (i.e. chunk creation)
	SXMPMeta* xmp = &handler->xmpObj;
	bool listChunkIsNeeded = false; // assume for now
	
	// ! The NUL is optional in WAV to avoid a parsing bug in Audition 3 - can't handle implicit pad byte.
	bool optionalNUL = (handler->parent->format == kXMP_WAVFile);

	for ( int p=0; mapping[p].chunkID != 0; ++p ) {	// go through all potential property mappings

		bool propExists = false;
		std::string value, actualLang;

		switch ( mapping[p].propType ) {

			// get property. if existing, remove from XMP (to avoid redundant storage)
			case prop_TIMEVALUE:
				propExists = xmp->GetStructField ( mapping[p].ns, mapping[p].prop, kXMP_NS_DM, "timeValue", &value, 0 );
				break;

			case prop_LOCALIZED_TEXT:
				propExists = xmp->GetLocalizedText ( mapping[p].ns, mapping[p].prop, "", "x-default", &actualLang, &value, 0);
				if ( actualLang != "x-default" ) propExists = false; // no "x-default" => nothing to reconcile !
				break;

			case prop_ARRAYITEM:
				propExists = xmp->GetArrayItem ( mapping[p].ns, mapping[p].prop, 1, &value, 0 );
				break;

			case prop_SIMPLE:
				propExists = xmp->GetProperty ( mapping[p].ns, mapping[p].prop, &value, 0 );
				break;			

			default:
				XMP_Throw ( "internal error", kXMPErr_InternalFailure );

		}

		if ( ! propExists ) {

			if ( *listChunk != 0 ) (*listChunk)->removeValue ( mapping[p].chunkID );

		} else {

			listChunkIsNeeded = true;
			if ( *listChunk == 0 ) *listChunk = new ContainerChunk ( handler->riffChunks[0], id, containerType );

			valueMap* cm = &(*listChunk)->childmap;			
			valueMapIter result = cm->find( mapping[p].chunkID );
			ValueChunk* propChunk = 0;

			if ( result != cm->end() ) {
				propChunk = result->second;
			} else {
				propChunk = new ValueChunk ( *listChunk, std::string(), mapping[p].chunkID );
			}

			propChunk->SetValue ( value.c_str(), optionalNUL );

		}

	} // for each property

	if ( (! listChunkIsNeeded) && (*listChunk != 0) && ((*listChunk)->children.size() == 0) ) {
		(*listChunk)->parent->replaceChildWithJunk ( *listChunk );
		(*listChunk) = 0; // reset direct Chunk pointer
	}

}