diff options
author | Hubert Figuière <hub@figuiere.net> | 2016-12-07 00:25:52 -0500 |
---|---|---|
committer | Hubert Figuière <hub@figuiere.net> | 2016-12-07 00:29:32 -0500 |
commit | 1696cff2133f0eab1fea45c164cb771a6e5e4526 (patch) | |
tree | d526dab08731fd8f6a4978b67df6e788979b567c /XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp | |
parent | 93571bfffb172a92f602de38a615902c52da111a (diff) | |
parent | 6071af09b5e263b63e57b28ab8a78484bc65e3fe (diff) |
Merge branch 'adobe-sdk' into integration
Merge Adobe SDK CC 2016.07
Diffstat (limited to 'XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp')
-rw-r--r-- | XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp | 189 |
1 files changed, 181 insertions, 8 deletions
diff --git a/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp b/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp index d6ea068..a153bc7 100644 --- a/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp +++ b/XMPFiles/source/FormatSupport/WAVE/iXMLMetadata.cpp @@ -21,7 +21,7 @@ namespace IFF_RIFF { static const char * tagNames[ iXMLMetadata::kLastEntry ] = { "TAPE", //kTape, // std::string - "TAKE", //kTake, // XMP_Uns64 + "TAKE", //kTake, // std::string "SCENE", //kScene, // std::string "NOTE", //kNote, // std::string "PROJECT", //kProject, // std::string @@ -44,11 +44,18 @@ namespace IFF_RIFF { "TIMESTAMP_SAMPLE_RATE", //kTimeStampSampleRate, // XMP_Uns64 "TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO", //kTimeStampSampleSinceMidnightLow, // XMP_Uns32 "TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI", //kTimeStampSampleSinceMidnightHi, // XMP_Uns32 + "TRACK_LIST", //kTrackList // std::vector< TrackListInfo > }; static const char * rootTagName = "BWFXML"; static const char * speedTagName = "SPEED"; static const char * bextTagName = "BEXT"; + static const char * trackCountTagName = "TRACK_COUNT"; + static const char * trackTagName = "TRACK"; + static const char * trackChannelIndexTagName = "CHANNEL_INDEX"; + static const char * trackInterleaveIndexTagName = "INTERLEAVE_INDEX"; + static const char * trackNameTagName = "NAME"; + static const char * trackFunctionTagName = "FUNCTION"; iXMLMetadata::iXMLMetadata() : mExpatAdapter( NULL ) @@ -194,6 +201,7 @@ namespace IFF_RIFF { switch( id ) { case kTape: + case kTake: case kScene: case kNote: case kProject: @@ -213,7 +221,6 @@ namespace IFF_RIFF { } break; - case kTake: case kFileSampleRate: case kAudioBitDepth: case kBWFTimeReferenceLow: @@ -230,6 +237,19 @@ namespace IFF_RIFF { ret = false; break; + case kTrackList: + ret = true; + { + TArrayObject< TrackListInfo > * trackListInfoArrayObj = dynamic_cast< TArrayObject< TrackListInfo > *>( &valueObj ); + if ( trackListInfoArrayObj ) { + XMP_Uns32 nElements ( 0 ); + const TrackListInfo * trackListInfoPtr = trackListInfoArrayObj->getArray( nElements ); + if ( nElements > 0 && trackListInfoPtr != NULL ) + ret = false; + } + } + break; + default: ret = true; } @@ -252,6 +272,15 @@ namespace IFF_RIFF { XMPFileHandler::NotifyClient( mErrorCallback, severity, error ); } + static std::string & Trim( std::string & str ) { + static const char * whiteSpaceChars = " \t\n\r\v"; + size_t pos = str.find_last_not_of( whiteSpaceChars ); + if ( pos != std::string::npos ) { + str.erase( pos + 1 ); + } + return str; + } + static XMP_Uns64 ConvertStringToUns64( const std::string & strValue ) { int count; char nextCh; @@ -269,7 +298,7 @@ namespace IFF_RIFF { if ( strValue.size() > 0 ) { XMP_Uns64 uValue; try { - uValue = ConvertStringToUns64( strValue ); + uValue = ConvertStringToUns64( Trim( strValue ) ); } catch( ... ) { // some nodes like tape can be non integer also. Treat it as warning XMP_Error error( kXMPErr_BadFileFormat, "iXML Metadata reconciliation failure: node is supposed to have integer value" ); @@ -298,7 +327,7 @@ namespace IFF_RIFF { // top level properties ParseAndSetStringProperty( mRootNode, kTape ); - ParseAndSetIntegerProperty( mRootNode, kTake ); + ParseAndSetStringProperty( mRootNode, kTake ); ParseAndSetStringProperty( mRootNode, kScene ); ParseAndSetStringProperty( mRootNode, kNote ); ParseAndSetStringProperty( mRootNode, kProject ); @@ -331,6 +360,12 @@ namespace IFF_RIFF { ParseAndSetStringProperty( bextNode, kBWFHistory ); ParseAndSetStringProperty( bextNode, kBWFUMID ); } + + // TRACK_LIST + XML_Node * trackListNode = mRootNode->GetNamedElement( "", tagNames[ kTrackList ] ); + if ( trackListNode ) { + ParseAndSetTrackListInfo( trackListNode ); + } } void iXMLMetadata::UpdateStringProperty( XML_Node * parentNode, XMP_Uns32 id ) { @@ -431,10 +466,67 @@ namespace IFF_RIFF { } } + void iXMLMetadata::UpdateTrackListInfo( XML_Node * parentNode ) { + if ( valueExists( kTrackList ) ) { + XMP_Uns32 size; + const TrackListInfo * arrayObj( NULL ); + try { + arrayObj = this->getArray< TrackListInfo >( kTrackList, size ); + } catch( ... ) { + XMP_Error error( kXMPErr_BadValue, "iXML Metadata reconciliation failure: expected the array of TrackListInfo type" ); + NotifyClient( kXMPErrSev_Recoverable, error ); + return; + } + + if ( size > 0 ) { + XML_Node * node = parentNode->GetNamedElement( "", tagNames[ kTrackList ] ); + + if ( node == NULL ) { + node = new XML_Node( parentNode, tagNames[ kTrackList ], kElemNode ); + if ( node == NULL ) { + XMP_Error error( kXMPErr_NoMemory, "Unable to create new objects" ); + NotifyClient( kXMPErrSev_OperationFatal, error ); + return; + } + parentNode->content.push_back( node ); + } + + // add count + std::string count = ConvertUns64ToString( size ); + UpdateXMLNode( node, trackCountTagName, count ); + + for ( XMP_Uns32 i = 0; i < size; i++ ) { + XML_Node * track = node->GetNamedElement( "", trackTagName, i ); + if ( track == NULL ) { + track = new XML_Node( parentNode, trackTagName, kElemNode ); + if ( track == NULL ) { + XMP_Error error( kXMPErr_NoMemory, "Unable to create new objects" ); + NotifyClient( kXMPErrSev_OperationFatal, error ); + return; + } + node->content.push_back( track ); + } + const TrackListInfo & ref = arrayObj[i]; + count = ConvertUns64ToString( ref.mChannelIndex ); + UpdateXMLNode( track, trackChannelIndexTagName, count ); + if ( ref.mChannelIndex != i + 1 ) + count = ConvertUns64ToString( i + 1 ); + UpdateXMLNode( track, trackInterleaveIndexTagName, count ); + UpdateXMLNode( track, trackNameTagName, ref.mName ); + UpdateXMLNode( track, trackFunctionTagName, ref.mFunction ); + } + } else { + RemoveXMLNode( parentNode, tagNames[ kTrackList ] ); + } + } else { + RemoveXMLNode( parentNode, tagNames[ kTrackList ] ); + } + } + void iXMLMetadata::UpdateProperties() { // top level properties UpdateStringProperty( mRootNode, kTape ); - UpdateIntegerProperty( mRootNode, kTake ); + UpdateStringProperty( mRootNode, kTake ); UpdateStringProperty( mRootNode, kScene ); UpdateStringProperty( mRootNode, kNote ); UpdateStringProperty( mRootNode, kProject ); @@ -468,6 +560,7 @@ namespace IFF_RIFF { UpdateStringProperty( bextNode, kBWFUMID ); } + UpdateTrackListInfo( mRootNode ); } bool iXMLMetadata::valueValid( XMP_Uns32 id, ValueObject * valueObj ) { @@ -477,7 +570,7 @@ namespace IFF_RIFF { break; case kTake: - return validateInt( valueObj ); + return validateStringSize( valueObj ); break; case kScene: @@ -752,8 +845,12 @@ namespace IFF_RIFF { } std::string iXMLMetadata::ParseStringValue( XML_Node * parentNode, XMP_Uns32 id ) { + return ParseStringValue( parentNode, tagNames[ id ] ); + } + + std::string iXMLMetadata::ParseStringValue( XML_Node * parentNode, const char * tagName, bool recoverable ) { std::string nodeValue; - XML_Node * node = parentNode->GetNamedElement( "", tagNames[ id ] ); + XML_Node * node = parentNode->GetNamedElement( "", tagName ); if ( node ) { if ( node->IsLeafContentNode() && node->content.size() != 0 ) { size_t lengthOfValue = node->content[0]->value.size(); @@ -762,12 +859,84 @@ namespace IFF_RIFF { } } else { XMP_Error error( kXMPErr_BadBlockFormat, "iXML Metadata reconciliation failure: node was supposed to be a leaf node" ); - NotifyClient( kXMPErrSev_Recoverable, error ); + NotifyClient( recoverable ? kXMPErrSev_Recoverable : kXMPErrSev_OperationFatal, error ); } + } else { + XMP_Error error ( recoverable ? kXMPErrSev_Recoverable : kXMPErrSev_OperationFatal, "iXML Metadata reconciliation failure: node not present" ); } return nodeValue; } + XMP_Uns64 iXMLMetadata::ParseUns64Value( XML_Node * parentNode, const char * tagName ) { + std::string strValue = ParseStringValue( parentNode, tagName, false ); + + if ( strValue.size() > 0 ) { + XMP_Uns64 uValue; + try { + uValue = ConvertStringToUns64( Trim( strValue ) ); + } catch( ... ) { + // some nodes like tape can be non integer also. Treat it as warning + XMP_Error error( kXMPErr_BadFileFormat, "iXML Metadata reconciliation failure: node is supposed to have integer value" ); + NotifyClient( kXMPErrSev_OperationFatal, error ); + } + return uValue; + } + return Max_XMP_Uns64; + } + + void iXMLMetadata::ParseAndSetTrackListInfo( XML_Node * parentNode ) { + XMP_Uns64 trackCount( 0 ); + try { + trackCount = ParseUns64Value( parentNode, trackCountTagName ); + } catch( ... ) { + XMP_Error error( kXMPErr_BadBlockFormat, "iXML Metadata reconciliation failure: failed parsing track list" ); + NotifyClient( kXMPErrSev_Recoverable, error ); + return; + } + std::vector< TrackListInfo > trackInfoListVector( trackCount ); + + for ( size_t i = 0; i < trackCount; i++ ) { + XML_Node * trackElement = parentNode->GetNamedElement( "", trackTagName, i ); + if ( trackElement ) { + XMP_Uns64 channelIndex( 0 ), interleaveIndex( 0 ); + std::string name, function; + + try { + channelIndex = ParseUns64Value( trackElement, trackChannelIndexTagName ); + interleaveIndex = ParseUns64Value( trackElement, trackInterleaveIndexTagName ); + name = ParseStringValue( trackElement, trackNameTagName ); + function = ParseStringValue( trackElement, trackFunctionTagName ); + } catch( ... ) { + XMP_Error error( kXMPErr_BadBlockFormat, "iXML Metadata reconciliation failure: failed parsing track list" ); + NotifyClient( kXMPErrSev_Recoverable, error ); + return; + } + + // check value of interleave index it should be between 1 and trackCount. + if ( interleaveIndex > 0 && interleaveIndex <= trackCount + && trackInfoListVector[ interleaveIndex - 1 ].mChannelIndex == 0 ) + { + TrackListInfo & currentElement = trackInfoListVector[ interleaveIndex - 1 ]; + currentElement.mChannelIndex = channelIndex; + currentElement.mName = name; + currentElement.mFunction = function; + } else { + XMP_Error error( kXMPErr_BadBlockFormat, "iXML Metadata reconciliation failure: interleave index is not correct" ); + NotifyClient( kXMPErrSev_Recoverable, error ); + return; + } + } else { + XMP_Error error( kXMPErr_BadBlockFormat, "iXML Metadata reconciliation failure: number of track elements is less than expected" ); + NotifyClient( kXMPErrSev_Recoverable, error ); + return; + } + } + + if ( trackCount > 0 ) { + this->setArray( kTrackList, trackInfoListVector.data(), ( XMP_Uns32 ) trackInfoListVector.size() ); + } + } + bool iXMLMetadata::validateTimeCodeFlag( ValueObject * value ) { bool returnValue = validateStringSize( value, 2, 3 ); if ( returnValue ) { @@ -812,4 +981,8 @@ namespace IFF_RIFF { return false; } + bool iXMLMetadata::validateTrackListInfo( ValueObject * value ) { + return true; + } + } |