Beispiel #1
0
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;
}
Beispiel #2
0
static void ExportIPTC_Array ( 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_PropIsArray ( xmpFlags ) ) return;	// ? Complain? Delete the DataSet?

	XMP_Index xmpCount  = xmp.CountArrayItems ( xmpNS, xmpProp );
	XMP_Index iptcCount = (XMP_Index) iptc->GetDataSet ( id, 0 );

	if ( xmpCount != iptcCount ) iptc->DeleteDataSet ( id );

	for ( XMP_Index ds = 0; ds < xmpCount; ++ds ) {	// ! XMP arrays are indexed from 1, IPTC from 0.

		(void) xmp.GetArrayItem ( xmpNS, xmpProp, ds+1, &value, &xmpFlags );
		if ( ! XMP_PropIsSimple ( xmpFlags ) ) continue;	// ? Complain?

		NormalizeToCR ( &value );

		iptc->SetDataSet_UTF8 ( id, value.c_str(), (XMP_Uns32)value.size(), ds );	// ! Appends if necessary.

	}

}	// ExportIPTC_Array
Beispiel #3
0
static void ExportIPTC_SubjectCode ( const SXMPMeta & xmp, IPTC_Manager * iptc )
{
	std::string    xmpValue, iimValue;
	XMP_OptionBits xmpFlags;

	bool found = xmp.GetProperty ( kXMP_NS_IPTCCore, "SubjectCode", 0, &xmpFlags );
	if ( ! found ) {
		iptc->DeleteDataSet ( kIPTC_SubjectCode );
		return;
	}

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

	XMP_Index xmpCount  = xmp.CountArrayItems ( kXMP_NS_IPTCCore, "SubjectCode" );
	XMP_Index iptcCount = (XMP_Index) iptc->GetDataSet ( kIPTC_SubjectCode, 0 );

	if ( xmpCount != iptcCount ) iptc->DeleteDataSet ( kIPTC_SubjectCode );

	for ( XMP_Index ds = 0; ds < xmpCount; ++ds ) {	// ! XMP arrays are indexed from 1, IPTC from 0.

		(void) xmp.GetArrayItem ( kXMP_NS_IPTCCore, "SubjectCode", ds+1, &xmpValue, &xmpFlags );
		if ( ! XMP_PropIsSimple ( xmpFlags ) ) continue;	// ? Complain?
		if ( xmpValue.size() != 8 ) continue;	// ? Complain?

		iimValue = "IPTC:";
		iimValue += xmpValue;
		iimValue += ":::";	// Add the separating colons for the empty name portions.

		iptc->SetDataSet_UTF8 ( kIPTC_SubjectCode, iimValue.c_str(), (XMP_Uns32)iimValue.size(), ds );	// ! Appends if necessary.

	}

}	// ExportIPTC_SubjectCode
Beispiel #4
0
static void FullUnicodeParse ( FILE * log, const char * encoding, size_t bufferSize,
                               const std::string & packet, const std::string & fullUnicode )
{
	if ( bufferSize > sizeof(sU32) ) {
		fprintf ( log, "#ERROR: FullUnicodeParse buffer overrun for %s, %d byte buffers\n", encoding, bufferSize );
		return;
	}

	SXMPMeta meta;
	try {
		memset ( sU32, -1, sizeof(sU32) );
		for ( size_t i = 0; i < packet.size(); i += bufferSize ) {
			size_t count = bufferSize;
			if ( count > (packet.size() - i) ) count = packet.size() - i;
			memcpy ( sU32, &packet[i], count );
			meta.ParseFromBuffer ( XMP_StringPtr(sU32), count, kXMP_ParseMoreBuffers );
		}
		meta.ParseFromBuffer ( XMP_StringPtr(sU32), 0 );
	} catch ( XMP_Error& excep ) {
		char message [200];
		sprintf ( message, "#ERROR: Full Unicode parsing error for %s, %d byte buffers", encoding, bufferSize );
		PrintXMPErrorInfo ( excep, message );
		return;
	}
	
	std::string value;
	bool found = meta.GetProperty ( kNS1, "FullUnicode", &value, 0 );
	if ( (! found) || (value != fullUnicode) ) fprintf ( log, "#ERROR: Failed to get full Unicode value for %s, %d byte buffers\n", encoding, bufferSize );
	
}	// FullUnicodeParse
Beispiel #5
0
/**
* Creates an XMP object from an RDF string.  The string is used to
* to simulate creating and XMP object from multiple input buffers.
* The last call to ParseFromBuffer has no kXMP_ParseMoreBuffers options,
* thereby indicating this is the last input buffer.
*/
SXMPMeta createXMPFromRDF()
{
	const char * rdf = 
		"<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
			"<rdf:Description rdf:about='' xmlns:dc='http://purl.org/dc/elements/1.1/'>"
				"<dc:subject>"
					"<rdf:Bag>"
						"<rdf:li>XMP</rdf:li>"
						"<rdf:li>SDK</rdf:li>"
						"<rdf:li>Sample</rdf:li>"
					"</rdf:Bag>"
				"</dc:subject>"
				"<dc:format>image/tiff</dc:format>"
			"</rdf:Description>"
		"</rdf:RDF>";

	SXMPMeta meta;
	// Loop over the rdf string and create the XMP object
	// 10 characters at a time 
	int i;
	for (i = 0; i < (long)strlen(rdf) - 10; i += 10 )
	{
		meta.ParseFromBuffer ( &rdf[i], 10, kXMP_ParseMoreBuffers );
	}
	
	// The last call has no kXMP_ParseMoreBuffers options, signifying 
	// this is the last input buffer
	meta.ParseFromBuffer ( &rdf[i], (XMP_StringLen) strlen(rdf) - i );
	return meta;

}
Beispiel #6
0
bool xmp_set_property(XmpPtr xmp, const char *schema, 
											const char *name, const char *value,
											uint32_t optionBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	// see bug #16030
	// when it is a struct or an array, get prop return an empty string
	// but it fail if passed an empty string
	if ((optionBits & (XMP_PROP_VALUE_IS_STRUCT | XMP_PROP_VALUE_IS_ARRAY)) 
			&& (*value == 0)) {
		value = NULL;
	}
	try {
		txmp->SetProperty(schema, name, value, optionBits);
		ret = true;
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	catch(...) {
	}
	return ret;
}
Beispiel #7
0
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
Beispiel #8
0
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 );

}
Beispiel #9
0
bool xmp_parse(XmpPtr xmp, const char *buffer, size_t len)
{
	CHECK_PTR(xmp, false);
	CHECK_PTR(buffer, false);

	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->ParseFromBuffer(buffer, len, kXMP_RequireXMPMeta );
	}
	catch(const XMP_Error & e)
	{
		set_error(e);
		return false;
	}
	return true;
}
Beispiel #10
0
static void ExportIPTC_IntellectualGenre ( const SXMPMeta & xmp, IPTC_Manager * iptc )
{
	std::string    xmpValue;
	XMP_OptionBits xmpFlags;

	bool found = xmp.GetProperty ( kXMP_NS_IPTCCore, "IntellectualGenre", &xmpValue, &xmpFlags );
	if ( ! found ) {
		iptc->DeleteDataSet ( kIPTC_IntellectualGenre );
		return;
	}

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

	NormalizeToCR ( &xmpValue );

	int i;
	XMP_StringPtr namePtr = xmpValue.c_str();
	for ( i = 0; kIntellectualGenreMappings[i].name != 0; ++i ) {
		if ( strcmp ( namePtr, kIntellectualGenreMappings[i].name ) == 0 ) break;
	}
	if ( kIntellectualGenreMappings[i].name == 0 ) return;	// Not a known genre, don't export it.

	std::string iimValue = kIntellectualGenreMappings[i].refNum;
	iimValue += ':';
	iimValue += xmpValue;

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

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

}	// ExportIPTC_IntellectualGenre
Beispiel #11
0
bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = true;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		ret = txmp->DoesPropertyExist(schema, name);
	}
	catch(const XMP_Error & e) {
		set_error(e);
		ret = false;
	}
	catch(...) {
		ret = false;
	}
	return ret;
}
Beispiel #12
0
bool xmp_set_array_item(XmpPtr xmp, const char *schema, 
											 const char *name, int32_t index, const char *value,
											 uint32_t optionBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->SetArrayItem(schema, name, index, value, optionBits);
		ret = true;
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	catch(...) {
	}
	return ret;
}
Beispiel #13
0
bool xmp_set_property_int64(XmpPtr xmp, const char *schema, 
							const char *name, int64_t value,
							uint32_t optionBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->SetProperty_Int64(schema, name, value, optionBits);
		ret = true;
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	catch(...) {
	}
	return ret;
}
Beispiel #14
0
bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer, 
							  uint32_t options, 
							  uint32_t padding, const char *newline, 
							  const char *tab, int32_t indent)
{
	CHECK_PTR(xmp, false);
	CHECK_PTR(buffer, false);
	RESET_ERROR;

	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->SerializeToBuffer(STRING(buffer), options, padding,
														newline, tab, indent);
	}
	catch(const XMP_Error & e)
	{
		set_error(e);
		return false;
	}
	return true;
}
Beispiel #15
0
bool xmp_get_property_int64(XmpPtr xmp, const char *schema, 
							const char *name, int64_t * property,
							uint32_t *propsBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	try {
		SXMPMeta *txmp = (SXMPMeta *)xmp;
		XMP_OptionBits optionBits;
		ret = txmp->GetProperty_Int64(schema, name, property, &optionBits);
		if(propsBits) {
			*propsBits = optionBits;
		}
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	return ret;
}
Beispiel #16
0
static void
ProcessPacket ( const char * fileName,
				FILE *       inFile,
			    size_t		 offset,
			    size_t       length )
{
	std::string xmlString;
	xmlString.append ( length, ' ' );
	fseek ( inFile, offset, SEEK_SET );
	fread ( (void*)xmlString.data(), 1, length, inFile );
	
	char title [1000];
	
	sprintf ( title, "// Dumping raw input for \"%s\" (%d..%d)", fileName, offset, (offset + length - 1) );
	printf ( "// " );
	for ( size_t i = 3; i < strlen(title); ++i ) printf ( "=" );
	printf ( "\n\n%s\n\n%.*s\n\n", title, length, xmlString.c_str() );
	fflush ( stdout );
	
	SXMPMeta xmpObj;
	try {
		xmpObj.ParseFromBuffer ( xmlString.c_str(), length );
	} catch ( ... ) {
		printf ( "## Parse failed\n\n" );
		return;
	}
	
	xmpObj.DumpObject ( DumpCallback, stdout );
	fflush ( stdout );
	
	string xmpString;
	xmpObj.SerializeToBuffer ( &xmpString, kXMP_OmitPacketWrapper );
	printf ( "\nPretty serialization, %d bytes :\n\n%s\n", xmpString.size(), xmpString.c_str() );
	fflush ( stdout );

	xmpObj.SerializeToBuffer ( &xmpString, (kXMP_OmitPacketWrapper | kXMP_UseCompactFormat) );
	printf ( "Compact serialization, %d bytes :\n\n%s\n", xmpString.size(), xmpString.c_str() );
	fflush ( stdout );

}	// ProcessPacket
Beispiel #17
0
bool xmp_set_property_date(XmpPtr xmp, const char *schema, 
						   const char *name, const XmpDateTime *value,
						   uint32_t optionBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		XMP_DateTime dt;
		ASSIGN(dt, (*value));
		txmp->SetProperty_Date(schema, name, dt, optionBits);
		ret = true;
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	catch(...) {
	}
	return ret;
}
Beispiel #18
0
bool xmp_delete_localized_text(XmpPtr xmp, const char *schema,
							   const char *name, const char *genericLang,
							   const char *specificLang)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = true;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->DeleteLocalizedText(schema, name, genericLang,
															specificLang);
	}
	catch(const XMP_Error & e) {
		set_error(e);
		ret = false;
	}
	catch(...) {
		ret = false;
	}
	return ret;
}
Beispiel #19
0
bool xmp_get_property_int32(XmpPtr xmp, const char *schema, 
							const char *name, int32_t * property,
							uint32_t *propsBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	try {
		SXMPMeta *txmp = (SXMPMeta *)xmp;
		XMP_OptionBits optionBits;
		// the long converstion is needed until XMPCore is fixed it use proper types.
		ret = txmp->GetProperty_Int(schema, name, property, &optionBits);
		if(propsBits) {
			*propsBits = optionBits;
		}
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	return ret;
}
Beispiel #20
0
bool xmp_get_array_item(XmpPtr xmp, const char *schema, 
												const char *name, int32_t index, XmpStringPtr property,
												uint32_t *propsBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	try {
		SXMPMeta *txmp = (SXMPMeta *)xmp;
		XMP_OptionBits optionBits;
		ret = txmp->GetArrayItem(schema, name, index, STRING(property), 
														 &optionBits);
		if(propsBits) {
			*propsBits = optionBits;
		}
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	return ret;
}
Beispiel #21
0
bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name,
			    const char *genericLang, const char *specificLang,
			    const char *value, uint32_t optionBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = true;
	SXMPMeta *txmp = (SXMPMeta *)xmp;
	try {
		txmp->SetLocalizedText(schema, name, genericLang, specificLang,
				       value, optionBits);
	}
	catch(const XMP_Error & e) {
		set_error(e);
		ret = false;
	}
	catch(...) {
		ret = false;		
	}
	return ret;
}
AssetMediaInfoPtr AssetMediaInfo::Create(
		AssetMediaType		inType,
		ASL::Guid	const&	inGuid,
		ASL::String	const&	inMediaPath,
		XMPText				inXMP,
		ASL::String const&  inFileContent,
		ASL::String	const&	inCustomMetadata,
		ASL::String const&  inCreateTime,
		ASL::String const&  inLastModifyTime,
		ASL::String const&  inTimeBase,
		ASL::String const&  inNtsc,
		ASL::String const&  inAliasName,
		bool inNeedSavePreCheck)
{
	XMPText xmp = inXMP;
	if (inXMP == NULL || inXMP->empty() || !TestValidXMPString(inXMP))
	{
		SXMPMeta metadata;
		XMPText fileXMPBuffer(new ASL::StdString);
		metadata.SerializeToBuffer(fileXMPBuffer.get(), kXMP_OmitPacketWrapper);
		xmp = fileXMPBuffer;
	}

	return AssetMediaInfoPtr(new AssetMediaInfo(
								inType,
								inGuid,
								inMediaPath,
								xmp,
								inFileContent,
								inCustomMetadata,
								inCreateTime,
								inLastModifyTime,
								inTimeBase,
								inNtsc,
								inAliasName,
								inNeedSavePreCheck));
}
Beispiel #23
0
void PhotoDataUtils::ExportPSIR ( const SXMPMeta & xmp, PSIR_Manager * psir )
{
	bool found;
	std::string utf8Value;

	try {	// Don't let errors with one stop the others.
		found = xmp.GetProperty ( kXMP_NS_XMP_Rights, "Marked", &utf8Value, 0 );
		if ( ! found ) {
			psir->DeleteImgRsrc ( kPSIR_CopyrightFlag );
		} else {
			bool copyrighted = SXMPUtils::ConvertToBool ( utf8Value );
			psir->SetImgRsrc ( kPSIR_CopyrightFlag, &copyrighted, 1 );
		}
	} catch ( ... ) {
		// Do nothing, let other exports proceed.
		// ? Notify client?
	}

	try {	// Don't let errors with one stop the others.
		found = xmp.GetProperty ( kXMP_NS_XMP_Rights, "WebStatement", &utf8Value, 0 );
		if ( ! found ) {
			psir->DeleteImgRsrc ( kPSIR_CopyrightURL );
		} else if ( ! ignoreLocalText ) {
			std::string localValue;
			ReconcileUtils::UTF8ToLocal ( utf8Value.c_str(), utf8Value.size(), &localValue );
			psir->SetImgRsrc ( kPSIR_CopyrightURL, localValue.c_str(), (XMP_Uns32)localValue.size() );
		} else if ( ReconcileUtils::IsASCII ( utf8Value.c_str(), utf8Value.size() ) ) {
			psir->SetImgRsrc ( kPSIR_CopyrightURL, utf8Value.c_str(), (XMP_Uns32)utf8Value.size() );
		} else {
			psir->DeleteImgRsrc ( kPSIR_CopyrightURL );
		}
	} catch ( ... ) {
		// Do nothing, let other exports proceed.
		// ? Notify client?
	}

}	// PhotoDataUtils::ExportPSIR;
Beispiel #24
0
static void ExportIPTC_Date ( XMP_Uns8 dateID, const SXMPMeta & xmp, IPTC_Manager * iptc )
{
	XMP_Uns8 timeID;
	XMP_StringPtr xmpNS, xmpProp;
	
	if ( dateID == kIPTC_DateCreated ) {
		timeID  = kIPTC_TimeCreated;
		xmpNS   = kXMP_NS_Photoshop;
		xmpProp = "DateCreated";
	} else if ( dateID == kIPTC_DigitalCreateDate ) {
		timeID  = kIPTC_DigitalCreateTime;
		xmpNS   = kXMP_NS_XMP;
		xmpProp = "CreateDate";
	} else {
		XMP_Throw ( "Unrecognized dateID", kXMPErr_BadParam );
	}

	iptc->DeleteDataSet ( dateID );	// ! Either the XMP does not exist and we want to 
	iptc->DeleteDataSet ( timeID );	// ! delete the IPTC, or we're replacing the IPTC.

	XMP_DateTime xmpValue;
	bool found = xmp.GetProperty_Date ( xmpNS, xmpProp, &xmpValue, 0 );
	if ( ! found ) return;

	char iimValue[16];	// AUDIT: Big enough for "YYYYMMDD" (8) and "HHMMSS+HHMM" (11).

	// Set the IIM date portion as YYYYMMDD with zeroes for unknown parts.
	
	snprintf ( iimValue, sizeof(iimValue), "%04d%02d%02d",	// AUDIT: Use of sizeof(iimValue) is safe.
			   xmpValue.year, xmpValue.month, xmpValue.day );

	iptc->SetDataSet_UTF8 ( dateID, iimValue, 8 );

	// Set the IIM time portion as HHMMSS+HHMM (or -HHMM). Allow a missing time zone.

	if ( xmpValue.hasTimeZone )  {
		snprintf ( iimValue, sizeof(iimValue), "%02d%02d%02d%c%02d%02d",	// AUDIT: Use of sizeof(iimValue) is safe.
				   xmpValue.hour, xmpValue.minute, xmpValue.second,
				   ((xmpValue.tzSign == kXMP_TimeWestOfUTC) ? '-' : '+'), xmpValue.tzHour, xmpValue.tzMinute );
		iptc->SetDataSet_UTF8 ( timeID, iimValue, 11 );
	} else if ( xmpValue.hasTime ) {
		snprintf ( iimValue, sizeof(iimValue), "%02d%02d%02d",	// AUDIT: Use of sizeof(iimValue) is safe.
				   xmpValue.hour, xmpValue.minute, xmpValue.second );
		iptc->SetDataSet_UTF8 ( timeID, iimValue, 6 );
	} else {
		iptc->DeleteDataSet ( timeID );
	}

}	// ExportIPTC_Date
Beispiel #25
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
Beispiel #26
0
bool xmp_get_property_date(XmpPtr xmp, const char *schema, 
					  const char *name, XmpDateTime *property,
					  uint32_t *propsBits)
{
	CHECK_PTR(xmp, false);
	RESET_ERROR;

	bool ret = false;
	try {
		SXMPMeta *txmp = (SXMPMeta *)xmp;
		XMP_OptionBits optionBits;
		XMP_DateTime dt;
//		memset((void*)&dt, 1, sizeof(XMP_DateTime)); 
		ret = txmp->GetProperty_Date(schema, name, &dt, &optionBits);
		ASSIGN((*property), dt);
		if(propsBits) {
			*propsBits = optionBits;
		}
	}
	catch(const XMP_Error & e) {
		set_error(e);
	}
	return ret;
}
Beispiel #27
0
bool ASF_LegacyManager::CheckDigest ( const SXMPMeta& xmp )
{
	bool ret = false;

	if ( ! digestComputed ) this->ComputeDigest();

	std::string oldDigest;

	if ( xmp.GetProperty ( kXMP_NS_ASF, "NativeDigest", &oldDigest, 0 ) ) {
		ret = (digestStr == oldDigest);
	}

	return ret;

}
Beispiel #28
0
static bool CreatorAtom_SetProperties ( SXMPMeta& xmpObj, 
									    const MOV_MetaHandler::CreatorAtomStrings& creatorAtomStrings )
{
	if ( ! creatorAtomStrings.posixProjectPath.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "macAtom",
								kXMP_NS_CreatorAtom, "posixProjectPath", creatorAtomStrings.posixProjectPath, 0 );
	}

	if ( ! creatorAtomStrings.uncProjectPath.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "windowsAtom",
								kXMP_NS_CreatorAtom, "uncProjectPath", creatorAtomStrings.uncProjectPath, 0 );
	}

	if ( ! creatorAtomStrings.projectRefType.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_DM, "projectRef", kXMP_NS_DM, "type", creatorAtomStrings.projectRefType.c_str());
	}

	if ( ! creatorAtomStrings.applicationCode.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "macAtom",
								kXMP_NS_CreatorAtom, "applicationCode", creatorAtomStrings.applicationCode, 0 );
	}

	if ( ! creatorAtomStrings.invocationAppleEvent.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "macAtom",
								kXMP_NS_CreatorAtom, "invocationAppleEvent", creatorAtomStrings.invocationAppleEvent, 0 );
	}

	if ( ! creatorAtomStrings.extension.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "windowsAtom",
								kXMP_NS_CreatorAtom, "extension", creatorAtomStrings.extension, 0 );
	}

	if ( ! creatorAtomStrings.invocationFlags.empty() ) {
		xmpObj.SetStructField ( kXMP_NS_CreatorAtom, "windowsAtom",
								kXMP_NS_CreatorAtom, "invocationFlags", creatorAtomStrings.invocationFlags, 0 );
	}

	if ( ! creatorAtomStrings.creatorTool.empty() ) {
		xmpObj.SetProperty ( kXMP_NS_XMP, "CreatorTool", creatorAtomStrings.creatorTool, 0 );
	}

	return ok;

}
Beispiel #29
0
    int XmpParser::encode(      std::string& xmpPacket,
                          const XmpData&     xmpData,
                                uint16_t     formatFlags,
                                uint32_t     padding)
    { try {
        if (xmpData.empty()) {
            xmpPacket.clear();
            return 0;
        }

        if (!initialize()) {
#ifndef SUPPRESS_WARNINGS
            std::cerr << "XMP Toolkit initialization failed.\n";
#endif
            return 2;
        }

        SXMPMeta meta;
        for (XmpData::const_iterator i = xmpData.begin(); i != xmpData.end(); ++i) {
            const std::string ns = XmpProperties::ns(i->groupName());
            XMP_OptionBits options = 0;

            if (i->typeId() == langAlt) {
                // Encode Lang Alt property
                const LangAltValue* la = dynamic_cast<const LangAltValue*>(&i->value());
                if (la == 0) throw Error(43, i->key());
                int idx = 1;
                // write the default first
                LangAltValue::ValueType::const_iterator k = la->value_.find("x-default");
                if (k != la->value_.end()) {
#ifdef DEBUG
                    printNode(ns, i->tagName(), k->second, 0);
#endif
                    meta.AppendArrayItem(ns.c_str(), i->tagName().c_str(), kXMP_PropArrayIsAlternate, k->second.c_str());
                    const std::string item = i->tagName() + "[" + toString(idx++) + "]";
                    meta.SetQualifier(ns.c_str(), item.c_str(), kXMP_NS_XML, "lang", k->first.c_str());
                }
                for (k = la->value_.begin(); k != la->value_.end(); ++k) {
                    if (k->first == "x-default") continue;
#ifdef DEBUG
                    printNode(ns, i->tagName(), k->second, 0);
#endif
                    meta.AppendArrayItem(ns.c_str(), i->tagName().c_str(), kXMP_PropArrayIsAlternate, k->second.c_str());
                    const std::string item = i->tagName() + "[" + toString(idx++) + "]";
                    meta.SetQualifier(ns.c_str(), item.c_str(), kXMP_NS_XML, "lang", k->first.c_str());
                }
                continue;
            }
            // Todo: Xmpdatum should have an XmpValue, not a Value
            const XmpValue* val = dynamic_cast<const XmpValue*>(&i->value());
            assert(val);
            options =   xmpArrayOptionBits(val->xmpArrayType())
                      | xmpArrayOptionBits(val->xmpStruct());
            if (   i->typeId() == xmpBag
                || i->typeId() == xmpSeq
                || i->typeId() == xmpAlt) {
#ifdef DEBUG
                printNode(ns, i->tagName(), "", options);
#endif
                meta.SetProperty(ns.c_str(), i->tagName().c_str(), 0, options);
                for (int idx = 0; idx < i->count(); ++idx) {
                    const std::string item = i->tagName() + "[" + toString(idx + 1) + "]";
#ifdef DEBUG
                    printNode(ns, item, i->toString(idx), 0);
#endif
                    meta.SetProperty(ns.c_str(), item.c_str(), i->toString(idx).c_str());
                }
                continue;
            }
            if (i->typeId() == xmpText) {
                if (i->count() == 0) {
#ifdef DEBUG
                    printNode(ns, i->tagName(), "", options);
#endif
                    meta.SetProperty(ns.c_str(), i->tagName().c_str(), 0, options);
                }
                else {
#ifdef DEBUG
                    printNode(ns, i->tagName(), i->toString(0), options);
#endif
                    meta.SetProperty(ns.c_str(), i->tagName().c_str(), i->toString(0).c_str(), options);
                }
                continue;
            }
            // Don't let any Xmpdatum go by unnoticed
            throw Error(38, i->tagName(), TypeInfo::typeName(i->typeId()));
        }
        std::string tmpPacket;
        meta.SerializeToBuffer(&tmpPacket, xmpFormatOptionBits(static_cast<XmpFormatFlags>(formatFlags)), padding); // throws
        xmpPacket = tmpPacket;

        return 0;
    }
    catch (const XMP_Error& e) {
#ifndef SUPPRESS_WARNINGS
        std::cerr << Error(40, e.GetID(), e.GetErrMsg()) << "\n";
#endif
        return 3;
    }} // XmpParser::decode
Beispiel #30
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;
}