TuttleOFX  1
DPXWriterProcess.tcc
Go to the documentation of this file.
00001 #include "DPXWriterDefinitions.hpp"
00002 #include "DPXWriterPlugin.hpp"
00003 
00004 #include "DPXWriterAlgorithm.hpp"
00005 
00006 #include <terry/typedefs.hpp>
00007 
00008 #include <tuttle/plugin/memory/OfxAllocator.hpp>
00009 
00010 #include <boost/exception/errinfo_file_name.hpp>
00011 #include <boost/assert.hpp>
00012 
00013 #include <boost/gil/gil_all.hpp>
00014 #include <boost/gil/packed_pixel.hpp>
00015 
00016 #include <boost/integer.hpp>  // for boost::uint_t
00017 #include <boost/cstdint.hpp>
00018 #include <boost/mpl/vector.hpp>
00019 #include <boost/scoped_ptr.hpp>
00020 #include <boost/filesystem/fstream.hpp>
00021 
00022 namespace tuttle {
00023 namespace plugin {
00024 namespace dpx {
00025 namespace writer {
00026 
00027 using namespace boost::gil;
00028 
00029 template<class View>
00030 DPXWriterProcess<View>::DPXWriterProcess( DPXWriterPlugin& instance )
00031         : ImageGilFilterProcessor<View>( instance, eImageOrientationFromTopToBottom )
00032         , _plugin( instance )
00033 {
00034         this->setNoMultiThreading();
00035 }
00036 
00037 template<class View>
00038 void DPXWriterProcess<View>::setup( const OFX::RenderArguments& args )
00039 {
00040         using namespace boost::gil;
00041         ImageGilFilterProcessor<View>::setup( args );
00042         _params = _plugin.getProcessParams( args.time );
00043 }
00044 
00045 /**
00046  * @brief Function called by rendering thread each time a process must be done.
00047  * @param[in] procWindowRoW  Processing window in RoW
00048  */
00049 template<class View>
00050 void DPXWriterProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00051 {
00052         using namespace boost::gil;
00053         OfxRectI procWindowOutput = this->translateRoWToOutputClipCoordinates( procWindowRoW );
00054         OfxPointI procWindowSize  = {
00055                 procWindowRoW.x2 - procWindowRoW.x1,
00056                 procWindowRoW.y2 - procWindowRoW.y1
00057         };
00058 
00059         View src = subimage_view( this->_srcView, procWindowOutput.x1, procWindowOutput.y1,
00060                                    procWindowSize.x,
00061                                    procWindowSize.y );
00062 
00063         ::dpx::Writer   writer;
00064         ::dpx::DataSize dataSize = ::dpx::kByte;
00065 
00066         OutStream       stream;
00067 
00068         if( ! stream.Open( _params._filepath.c_str() ) )
00069         {
00070                 BOOST_THROW_EXCEPTION( exception::File()
00071                         << exception::user( "Dpx: Unable to open output file" ) );
00072         }
00073 
00074         writer.SetOutStream( &stream );
00075         writer.Start();
00076         writer.SetFileInfo( _params._filepath.c_str(), 0, "TuttleOFX DPX Writer", _params._project.c_str(), _params._copyright.c_str(), ~0, _params._swapEndian );
00077         writer.SetImageInfo( procWindowSize.x, procWindowSize.y );
00078 
00079 #ifndef TUTTLE_PRODUCTION
00080         writer.header.SetImageOrientation( _params._orientation );
00081 #endif
00082 
00083         switch ( _params._bitDepth )
00084         {
00085                 case eTuttlePluginBitDepth8:
00086                         dataSize = ::dpx::kByte;
00087                         break;
00088                 case eTuttlePluginBitDepth10:
00089                 case eTuttlePluginBitDepth12:
00090                 case eTuttlePluginBitDepth16:
00091                         dataSize = ::dpx::kWord;
00092                         break;
00093                 case eTuttlePluginBitDepth32:
00094                 case eTuttlePluginBitDepth64:
00095                         dataSize = ::dpx::kFloat;
00096                         break;
00097         }
00098 
00099 
00100         writer.SetElement( 0,
00101                         _params._descriptor,
00102                         _params._iBitDepth,
00103                         _params._transfer,
00104                         _params._colorimetric,
00105                         _params._packed,
00106                         _params._encoding );
00107 
00108         
00109         if( ! writer.WriteHeader() )
00110         {
00111                 BOOST_THROW_EXCEPTION( exception::Data()
00112                         << exception::user( "Dpx: Unable to write data (DPX Header)" ) );
00113         }
00114 
00115         //TUTTLE_LOG_VAR( TUTTLE_INFO, _params._descriptor);
00116         switch( _params._descriptor )
00117         {
00118                 case ::dpx::kUserDefinedDescriptor:
00119                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00120                                                                 << exception::user( "Dpx: Unable to write user defined" ) );
00121                         break;
00122                 case ::dpx::kRed:
00123                         break;
00124                 case ::dpx::kGreen:
00125                         break;
00126                 case ::dpx::kBlue:
00127                         break;
00128                 case ::dpx::kAlpha:
00129                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00130                                                                 << exception::user( "Dpx: Unable to write user defined" ) );
00131                         break;
00132                 case ::dpx::kLuma:
00133                         switch ( _params._bitDepth )
00134                         {
00135                                 case eTuttlePluginBitDepth8:
00136                                         writeImage<gray8_pixel_t>( writer, src, dataSize, 1 );
00137                                         break;
00138                                 case eTuttlePluginBitDepth10:
00139                                 case eTuttlePluginBitDepth12:
00140                                 case eTuttlePluginBitDepth16:
00141                                         writeImage<gray16_pixel_t>( writer, src, dataSize, 2 );
00142                                         break;
00143                                 case eTuttlePluginBitDepth32:
00144                                 case eTuttlePluginBitDepth64:
00145                                         writeImage<gray32f_pixel_t>( writer, src, dataSize, 4 );
00146                                         break;
00147                         }
00148                         break;
00149                         break;
00150                 case ::dpx::kColorDifference:
00151                         break;
00152                 case ::dpx::kDepth:
00153                         break;
00154                 case ::dpx::kCompositeVideo:
00155                         break;
00156                 case ::dpx::kRGB:
00157                         switch ( _params._bitDepth )
00158                         {
00159                                 case eTuttlePluginBitDepth8:
00160                                         writeImage<rgb8_pixel_t>( writer, src, dataSize, 3 );
00161                                         break;
00162                                 case eTuttlePluginBitDepth10:
00163                                 case eTuttlePluginBitDepth12:
00164                                 case eTuttlePluginBitDepth16:
00165                                         writeImage<rgb16_pixel_t>( writer, src, dataSize, 6 );
00166                                         break;
00167                                 case eTuttlePluginBitDepth32:
00168                                 case eTuttlePluginBitDepth64:
00169                                         writeImage<rgb32f_pixel_t>( writer, src, dataSize, 12 );
00170                                         break;
00171                         }
00172                         break;
00173                 case ::dpx::kRGBA:
00174                         switch ( _params._bitDepth )
00175                         {
00176                                 case eTuttlePluginBitDepth8:
00177                                         writeImage<rgba8_pixel_t>( writer, src, dataSize, 4 );
00178                                         break;
00179                                 case eTuttlePluginBitDepth10:
00180                                 case eTuttlePluginBitDepth12:
00181                                 case eTuttlePluginBitDepth16:
00182                                         writeImage<rgba16_pixel_t>( writer, src, dataSize, 8 );
00183                                         break;
00184                                 case eTuttlePluginBitDepth32:
00185                                 case eTuttlePluginBitDepth64:
00186                                         writeImage<rgba32f_pixel_t>( writer, src, dataSize, 16 );
00187                                         break;
00188                         }
00189                         break;
00190                 case ::dpx::kABGR:
00191                         switch ( _params._bitDepth )
00192                         {
00193                                 case eTuttlePluginBitDepth8:
00194                                         writeImage<abgr8_pixel_t>( writer, src, dataSize, 4 );
00195                                         break;
00196                                 case eTuttlePluginBitDepth10:
00197                                 case eTuttlePluginBitDepth12:
00198                                 case eTuttlePluginBitDepth16:
00199                                         writeImage<abgr16_pixel_t>( writer, src, dataSize, 8 );
00200                                         break;
00201                                 case eTuttlePluginBitDepth32:
00202                                 case eTuttlePluginBitDepth64:
00203                                         writeImage<abgr32f_pixel_t>( writer, src, dataSize, 16 );
00204                                         break;
00205                         }
00206                         break;
00207                 case ::dpx::kCbYCrY:
00208                         break;
00209                 case ::dpx::kCbYACrYA:
00210                         break;
00211                 case ::dpx::kCbYCr:
00212                         break;
00213                 case ::dpx::kCbYCrA:
00214                         break;
00215                 case ::dpx::kUserDefined2Comp:
00216                         break;
00217                 case ::dpx::kUserDefined3Comp:
00218                         break;
00219                 case ::dpx::kUserDefined4Comp:
00220                         break;
00221                 case ::dpx::kUserDefined5Comp:
00222                         break;
00223                 case ::dpx::kUserDefined6Comp:
00224                         break;
00225                 case ::dpx::kUserDefined7Comp:
00226                         break;
00227                 case ::dpx::kUserDefined8Comp:
00228                         break;
00229                 case ::dpx::kUndefinedDescriptor:
00230                         break;
00231         }
00232         
00233         if( ! writer.Finish() )
00234         {
00235                 BOOST_THROW_EXCEPTION( exception::Data()
00236                         << exception::user( "Dpx: Unable to write data (DPX finish)" ) );
00237         }
00238         
00239         stream.Close();
00240 }
00241 
00242 template<class View>
00243 template<class WPixel>
00244 void DPXWriterProcess<View>::writeImage( ::dpx::Writer& writer, View& src, ::dpx::DataSize& dataSize, size_t pixelSize )
00245 {
00246         using namespace terry;
00247         typedef image<WPixel, false> image_t; // interleaved image
00248         typedef typename image_t::view_t view_t;
00249         image_t img( src.width(), src.height() );
00250         view_t  dvw( view( img ) );
00251         copy_and_convert_pixels( src, dvw );
00252         
00253         typedef std::vector<char, OfxAllocator<char> > DataVector;
00254         const size_t rowBytesToCopy = src.width() * pixelSize;
00255 
00256         DataVector data( rowBytesToCopy * src.height() );
00257         char* dataPtrIt = &data.front();
00258 
00259         for( int y = 0; y < src.height(); y++ )
00260         {
00261                 void* dataSrcPtr = reinterpret_cast<void*>( &dvw(0,y)[0] );
00262                 memcpy( dataPtrIt, dataSrcPtr, rowBytesToCopy );
00263 
00264                 dataPtrIt += rowBytesToCopy;
00265         }
00266 
00267         if( ! writer.WriteElement( 0, &data.front(), dataSize ) )
00268         {
00269                 BOOST_THROW_EXCEPTION( exception::Data()
00270                         << exception::user( "Dpx: Unable to write data (DPX User Data)" ) );
00271         }
00272 }
00273 
00274 
00275 }
00276 }
00277 }
00278 }