bool CreatorAtom::Update ( SXMPMeta& xmpObj, LFA_FileRef fileRef, long riffType, RIFF_Support::RiffState& riffState ) { // Creator Atom related values. bool found = false; std::string posixPathString, uncPathString; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "posixProjectPath", &posixPathString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "uncProjectPath", &uncPathString, 0 ) ) found = true; std::string applicationCodeString, invocationAppleEventString, extensionString, invocationFlagsString, creatorToolString; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "applicationCode", &applicationCodeString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "invocationAppleEvent", &invocationAppleEventString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "extension", &extensionString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "invocationFlags", &invocationFlagsString, 0 ) ) found = true; if ( xmpObj.GetProperty ( kXMP_NS_XMP, "CreatorTool", &creatorToolString, 0 ) ) found = true; // No Creator Atom information present. if ( ! found ) return true; // Read Legacy Creator Atom. unsigned long creatorAtomSize = 0; CR8R_CreatorAtom creatorAtomLegacy; CreatorAtom_Initialize ( creatorAtomLegacy ); bool ok = RIFF_Support::GetRIFFChunk ( fileRef, riffState, myCreatorAtom, 0, 0, 0, &creatorAtomSize ); if ( ok ) { XMP_Assert ( creatorAtomSize == sizeof(CR8R_CreatorAtom) ); ok = RIFF_Support::GetRIFFChunk ( fileRef, riffState, myCreatorAtom, 0, 0, (char*) &creatorAtomLegacy, &creatorAtomSize ); CreatorAtom_MakeValid ( &creatorAtomLegacy ); } // Generate new Creator Atom from XMP. CR8R_CreatorAtom creatorAtomViaXMP; CreatorAtom_Initialize ( creatorAtomViaXMP ); if ( ! applicationCodeString.empty() ) { creatorAtomViaXMP.creator_codeLu = strtoul ( applicationCodeString.c_str(), 0, 0 ); } if ( ! invocationAppleEventString.empty() ) { creatorAtomViaXMP.creator_eventLu = strtoul ( invocationAppleEventString.c_str(), 0, 0 ); } if ( ! extensionString.empty() ) { strncpy ( creatorAtomViaXMP.creator_extAC, extensionString.c_str(), sizeof(creatorAtomViaXMP.creator_extAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_extAC ); } if ( ! invocationFlagsString.empty() ) { strncpy ( creatorAtomViaXMP.creator_flagAC, invocationFlagsString.c_str(), sizeof(creatorAtomViaXMP.creator_flagAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_flagAC ); } if ( ! creatorToolString.empty() ) { strncpy ( creatorAtomViaXMP.creator_nameAC, creatorToolString.c_str(), sizeof(creatorAtomViaXMP.creator_nameAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_nameAC ); } // Write new Creator Atom, if necessary. if ( memcmp ( &creatorAtomViaXMP, &creatorAtomLegacy, sizeof(CR8R_CreatorAtom) ) != 0 ) { CreatorAtom_ToBE ( &creatorAtomViaXMP ); ok = RIFF_Support::PutChunk ( fileRef, riffState, riffType, myCreatorAtom, (char*)&creatorAtomViaXMP, sizeof(CR8R_CreatorAtom) ); } return ok; }
static bool CreatorAtom_Update ( SXMPMeta& xmpObj, UserData& movieUserData ) { // Get Creator Atom XMP values. bool found = false; std::string posixPathString, uncPathString; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "posixProjectPath", &posixPathString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "uncProjectPath", &uncPathString, 0 ) ) found = true; std::string applicationCodeString, invocationAppleEventString, extensionString, invocationFlagsString, creatorToolString; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "applicationCode", &applicationCodeString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "macAtom", kXMP_NS_CreatorAtom, "invocationAppleEvent", &invocationAppleEventString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "extension", &extensionString, 0 ) ) found = true; if ( xmpObj.GetStructField ( kXMP_NS_CreatorAtom, "windowsAtom", kXMP_NS_CreatorAtom, "invocationFlags", &invocationFlagsString, 0 ) ) found = true; if ( xmpObj.GetProperty ( kXMP_NS_XMP, "CreatorTool", &creatorToolString, 0 ) ) found = true; // If no Creator Atom information found, don't write anything. if ( ! found ) return false; // Read Legacy Creator Atom. unsigned long creatorAtomSize = 0; CR8R_CreatorAtom creatorAtomLegacy; CreatorAtom_Initialize ( creatorAtomLegacy ); bool ok = Mov_ReadCreatorAtom ( movieUserData, &creatorAtomLegacy ); // Generate new Creator Atom from XMP. CR8R_CreatorAtom creatorAtomViaXMP; CreatorAtom_Initialize ( creatorAtomViaXMP ); if ( ! applicationCodeString.empty() ) { creatorAtomViaXMP.creator_codeLu = strtoul ( applicationCodeString.c_str(), 0, 0 ); } if ( ! invocationAppleEventString.empty() ) { creatorAtomViaXMP.creator_eventLu = strtoul ( invocationAppleEventString.c_str(), 0, 0 ); } if ( ! extensionString.empty() ) { strncpy ( creatorAtomViaXMP.creator_extAC, extensionString.c_str(), sizeof(creatorAtomViaXMP.creator_extAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_extAC ); } if ( ! invocationFlagsString.empty() ) { strncpy ( creatorAtomViaXMP.creator_flagAC, invocationFlagsString.c_str(), sizeof(creatorAtomViaXMP.creator_flagAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_flagAC ); } if ( ! creatorToolString.empty() ) { strncpy ( creatorAtomViaXMP.creator_nameAC, creatorToolString.c_str(), sizeof(creatorAtomViaXMP.creator_nameAC) ); EnsureFinalNul ( creatorAtomViaXMP.creator_nameAC ); } // Write Creator Atom. if ( ok ) { // If there's legacy, update if atom generated from XMP doesn't match legacy. if ( memcmp ( &creatorAtomViaXMP, &creatorAtomLegacy, sizeof(CR8R_CreatorAtom) ) != 0 ) { ok = Mov_WriteCreatorAtom ( movieUserData, creatorAtomViaXMP, true ); } } else { // Write completely new atom from XMP. ok = Mov_WriteCreatorAtom ( movieUserData, creatorAtomViaXMP, false ); } return ok; }
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 } }