aboutsummaryrefslogtreecommitdiff
path: root/src/qtff/ColorParameterBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qtff/ColorParameterBox.cpp')
-rw-r--r--src/qtff/ColorParameterBox.cpp341
1 files changed, 341 insertions, 0 deletions
diff --git a/src/qtff/ColorParameterBox.cpp b/src/qtff/ColorParameterBox.cpp
new file mode 100644
index 0000000..54a85a4
--- /dev/null
+++ b/src/qtff/ColorParameterBox.cpp
@@ -0,0 +1,341 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// The contents of this file are subject to the Mozilla Public License
+// Version 1.1 (the "License"); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://www.mozilla.org/MPL/
+//
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+// License for the specific language governing rights and limitations
+// under the License.
+//
+// The Original Code is MP4v2.
+//
+// The Initial Developer of the Original Code is Kona Blend.
+// Portions created by Kona Blend are Copyright (C) 2008.
+// All Rights Reserved.
+//
+// Contributors:
+// Kona Blend, kona8lend@@gmail.com
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "impl.h"
+
+namespace mp4v2 { namespace impl { namespace qtff {
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+ const string BOX_CODE = "colr";
+
+ bool findColorParameterBox( MP4FileHandle file, MP4Atom& coding, MP4Atom*& colr );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::add( MP4FileHandle file, uint16_t trackIndex, const Item& item )
+{
+ MP4Atom* coding;
+ if( findCoding( file, trackIndex, coding ))
+ throw new MP4Exception( "supported coding not found" );
+
+ MP4Atom* colr;
+ if( !findColorParameterBox( file, *coding, colr ))
+ throw new MP4Exception( "colr-box already exists" );
+
+ colr = MP4Atom::CreateAtom( coding, BOX_CODE.c_str() );
+ coding->AddChildAtom( colr );
+ colr->Generate();
+
+ MP4StringProperty* type;
+ MP4Integer16Property* primariesIndex;
+ MP4Integer16Property* transferFunctionIndex;
+ MP4Integer16Property* matrixIndex;
+
+ if( colr->FindProperty( "colr.colorParameterType", (MP4Property**)&type ))
+ type->SetValue( "nclc" );
+
+ if( colr->FindProperty( "colr.primariesIndex", (MP4Property**)&primariesIndex ))
+ primariesIndex->SetValue( item.primariesIndex );
+
+ if( colr->FindProperty( "colr.transferFunctionIndex", (MP4Property**)&transferFunctionIndex ))
+ transferFunctionIndex->SetValue( item.transferFunctionIndex );
+
+ if( colr->FindProperty( "colr.matrixIndex", (MP4Property**)&matrixIndex ))
+ matrixIndex->SetValue( item.matrixIndex );
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::add( MP4FileHandle file, MP4TrackId trackId, const Item& item )
+{
+ MP4File& mp4 = *((MP4File*)file);
+ return add( file, mp4.FindTrackIndex( trackId ), item );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::get( MP4FileHandle file, uint16_t trackIndex, Item& item )
+{
+ item.reset();
+
+ MP4Atom* coding;
+ if( findCoding( file, trackIndex, coding ))
+ throw new MP4Exception( "supported coding not found" );
+
+ MP4Atom* colr;
+ if( findColorParameterBox( file, *coding, colr ))
+ throw new MP4Exception( "colr-box not found" );
+
+ MP4Integer16Property* primariesIndex;
+ MP4Integer16Property* transferFunctionIndex;
+ MP4Integer16Property* matrixIndex;
+
+ if( colr->FindProperty( "colr.primariesIndex", (MP4Property**)&primariesIndex ))
+ item.primariesIndex = primariesIndex->GetValue();
+
+ if( colr->FindProperty( "colr.transferFunctionIndex", (MP4Property**)&transferFunctionIndex ))
+ item.transferFunctionIndex = transferFunctionIndex->GetValue();
+
+ if( colr->FindProperty( "colr.matrixIndex", (MP4Property**)&matrixIndex ))
+ item.matrixIndex = matrixIndex->GetValue();
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::get( MP4FileHandle file, MP4TrackId trackId, Item& item )
+{
+ MP4File& mp4 = *((MP4File*)file);
+ return get( file, mp4.FindTrackIndex( trackId ), item );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::list( MP4FileHandle file, ItemList& itemList )
+{
+ itemList.clear();
+ MP4File& mp4 = *((MP4File*)file);
+
+ const uint16_t trackc = mp4.GetNumberOfTracks();
+ for( uint16_t i = 0; i < trackc; i++) {
+ MP4TrackId id = mp4.FindTrackId( i );
+ if( id == MP4_INVALID_TRACK_ID )
+ continue;
+
+ const char* type = mp4.GetTrackType( id );
+ if( !type )
+ continue;
+
+ itemList.resize( itemList.size() + 1 );
+ IndexedItem& xitem = itemList[itemList.size()-1];
+
+ xitem.trackIndex = i;
+ xitem.trackId = id;
+
+ bool success = false;
+ try {
+ success = !get( file, i, xitem.item );
+ }
+ catch( MP4Exception* x ) {
+ delete x;
+ }
+
+ if( !success ) {
+ itemList.resize( itemList.size() - 1 );
+ continue;
+ }
+ }
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::remove( MP4FileHandle file, uint16_t trackIndex )
+{
+ MP4Atom* coding;
+ if( findCoding( file, trackIndex, coding ))
+ throw new MP4Exception( "supported coding not found" );
+
+ MP4Atom* colr;
+ if( findColorParameterBox( file, *coding, colr ))
+ throw new MP4Exception( "colr-box not found" );
+
+ coding->DeleteChildAtom( colr );
+ delete colr;
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::remove( MP4FileHandle file, MP4TrackId trackId )
+{
+ MP4File& mp4 = *((MP4File*)file);
+ return remove( file, mp4.FindTrackIndex( trackId ));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::set( MP4FileHandle file, uint16_t trackIndex, const Item& item )
+{
+ MP4Atom* coding;
+ if( findCoding( file, trackIndex, coding ))
+ throw new MP4Exception( "supported coding not found" );
+
+ MP4Atom* colr;
+ if( findColorParameterBox( file, *coding, colr ))
+ throw new MP4Exception( "colr-box not found" );
+
+ MP4Integer16Property* primariesIndex;
+ MP4Integer16Property* transferFunctionIndex;
+ MP4Integer16Property* matrixIndex;
+
+ if( colr->FindProperty( "colr.primariesIndex", (MP4Property**)&primariesIndex ))
+ primariesIndex->SetValue( item.primariesIndex );
+
+ if( colr->FindProperty( "colr.transferFunctionIndex", (MP4Property**)&transferFunctionIndex ))
+ transferFunctionIndex->SetValue( item.transferFunctionIndex );
+
+ if( colr->FindProperty( "colr.matrixIndex", (MP4Property**)&matrixIndex ))
+ matrixIndex->SetValue( item.matrixIndex );
+
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+ColorParameterBox::set( MP4FileHandle file, MP4TrackId trackId, const Item& item )
+{
+ MP4File& mp4 = *((MP4File*)file);
+ return set( file, mp4.FindTrackIndex( trackId ), item );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ColorParameterBox::IndexedItem::IndexedItem()
+ : trackIndex ( numeric_limits<uint16_t>::max() )
+ , trackId ( MP4_INVALID_TRACK_ID )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ColorParameterBox::Item::Item()
+ : primariesIndex ( 6 )
+ , transferFunctionIndex ( 1 )
+ , matrixIndex ( 6 )
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void
+ColorParameterBox::Item::convertFromCSV( const string& text )
+{
+ istringstream iss( text );
+ char delim;
+
+ iss >> primariesIndex;
+ iss >> delim;
+ iss >> transferFunctionIndex;
+ iss >> delim;
+ iss >> matrixIndex;
+
+ // input was good if we end up with only eofbit set
+ if( iss.rdstate() != ios::eofbit ) {
+ reset();
+ ostringstream xss;
+ xss << "invalid ColorParameterBox format"
+ << " (expecting: INDEX1,INDEX2,INDEX3)"
+ << " got: " << text;
+ throw new MP4Exception( xss );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+string
+ColorParameterBox::Item::convertToCSV() const
+{
+ string buffer;
+ return convertToCSV( buffer );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+string&
+ColorParameterBox::Item::convertToCSV( string& buffer ) const
+{
+ ostringstream oss;
+ oss << primariesIndex << ',' << transferFunctionIndex << ',' << matrixIndex;
+ buffer = oss.str();
+ return buffer;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void
+ColorParameterBox::Item::reset()
+{
+ primariesIndex = 6;
+ transferFunctionIndex = 1;
+ matrixIndex = 6;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace {
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool
+findColorParameterBox( MP4FileHandle file, MP4Atom& coding, MP4Atom*& colr )
+{
+ colr = NULL;
+
+ MP4Atom* found = NULL;
+ const uint32_t atomc = coding.GetNumberOfChildAtoms();
+ for( uint32_t i = 0; i < atomc; i++ ) {
+ MP4Atom* atom = coding.GetChildAtom( i );
+ if( BOX_CODE != atom->GetType() )
+ continue;
+ found = atom;
+ }
+ if( !found )
+ return true;
+
+ MP4StringProperty* type;
+ if( !found->FindProperty( "colr.colorParameterType", (MP4Property**)&type ))
+ return true;
+
+ const string type_nclc = "nclc";
+ if( type_nclc != type->GetValue() )
+ return true;
+
+ colr = found;
+ return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+} // anonymous
+
+///////////////////////////////////////////////////////////////////////////////
+
+}}} // namespace mp4v2::impl::qtff