diff options
Diffstat (limited to 'src/qtff/ColorParameterBox.cpp')
-rw-r--r-- | src/qtff/ColorParameterBox.cpp | 341 |
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 |