TuttleOFX  1
EXRWriterProcess.tcc
Go to the documentation of this file.
00001 #include "EXRWriterDefinitions.hpp"
00002 #include "EXRWriterPlugin.hpp"
00003 
00004 
00005 #include <terry/globals.hpp>
00006 #include <terry/openexr/half.hpp>
00007 
00008 #include <tuttle/plugin/ImageGilProcessor.hpp>
00009 #include <tuttle/plugin/exceptions.hpp>
00010 
00011 #include <boost/gil/gil_all.hpp>
00012 #include <boost/cstdint.hpp>
00013 #include <boost/assert.hpp>
00014 
00015 namespace tuttle {
00016 namespace plugin {
00017 namespace exr {
00018 namespace writer {
00019 
00020 using namespace boost::gil;
00021 
00022 template<class View>
00023 EXRWriterProcess<View>::EXRWriterProcess( EXRWriterPlugin& instance )
00024         : ImageGilFilterProcessor<View>( instance, eImageOrientationFromTopToBottom )
00025         , _plugin( instance )
00026 {
00027         this->setNoMultiThreading();
00028 }
00029 
00030 template<class View>
00031 void EXRWriterProcess<View>::setup( const OFX::RenderArguments& args )
00032 {
00033         using namespace boost::gil;
00034         ImageGilFilterProcessor<View>::setup( args );
00035         _params = _plugin.getProcessParams( args.time );
00036 }
00037 
00038 /**
00039  * @brief Function called by rendering thread each time a process must be done.
00040  * @param[in] procWindowRoW  Processing window in RoW
00041  */
00042 template<class View>
00043 void EXRWriterProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW )
00044 {
00045         // no tiles and no multithreading supported
00046         BOOST_ASSERT( ( procWindowRoW == this->_dstPixelRod ) );
00047         BOOST_ASSERT( ( this->_srcPixelRod == this->_dstPixelRod ) );
00048 
00049         View src = this->_srcView;
00050 
00051         try
00052         {
00053                 switch( _params._bitDepth )
00054                 {
00055                         case eTuttlePluginBitDepth16f:
00056                         {
00057                                 switch( _params._componentsType )
00058                                 {
00059                                         case eTuttlePluginComponentsAuto:
00060                                         {
00061                                                 switch ( _plugin._clipSrc->getPixelComponents() )
00062                                                 {
00063                                                         case OFX::ePixelComponentAlpha:
00064                                                                 writeGrayImage<gray16h_pixel_t>( src, _params._filepath, Imf::HALF );
00065                                                                 break;
00066                                                         case OFX::ePixelComponentRGB:
00067                                                                 writeImage<rgb16h_pixel_t>( src, _params._filepath, Imf::HALF );
00068                                                                 break;
00069                                                         case OFX::ePixelComponentRGBA:
00070                                                                 writeImage<rgba16h_pixel_t>( src, _params._filepath, Imf::HALF );
00071                                                                 break;
00072                                                         default:
00073                                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00074                                                                     << exception::user( "Exr Writer: components not supported" ) );
00075                                                                 break;
00076                                                 }
00077                                                 break;
00078                                         }
00079                                         case eTuttlePluginComponentsGray:
00080                                         {
00081                                                 writeGrayImage<gray16h_pixel_t>( src, _params._filepath, Imf::HALF );
00082                                                 break;
00083                                         }
00084                                         case eTuttlePluginComponentsRGB:
00085                                         {
00086                                                 writeImage<rgb16h_pixel_t>( src, _params._filepath, Imf::HALF );
00087                                                 break;
00088                                         }
00089                                         case eTuttlePluginComponentsRGBA:
00090                                         {
00091                                                 writeImage<rgba16h_pixel_t>( src, _params._filepath, Imf::HALF );
00092                                                 break;
00093                                         }
00094                                         default:
00095                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00096                                                     << exception::user( "Exr Writer: components not supported" ) );
00097                                 }
00098                                 break;
00099                         }
00100                         case eTuttlePluginBitDepth32f:
00101                         {
00102                                 switch( _params._componentsType )
00103                                 {
00104                                         case eTuttlePluginComponentsAuto:
00105                                         {
00106                                                 switch ( _plugin._clipSrc->getPixelComponents() )
00107                                                 {
00108                                                         case OFX::ePixelComponentAlpha:
00109                                                                 writeGrayImage<gray32f_pixel_t>( src, _params._filepath, Imf::FLOAT );
00110                                                                 break;
00111                                                         case OFX::ePixelComponentRGB:
00112                                                                 writeImage<rgb32f_pixel_t>( src, _params._filepath, Imf::FLOAT );
00113                                                                 break;
00114                                                         case OFX::ePixelComponentRGBA:
00115                                                                 writeImage<rgba32f_pixel_t>( src, _params._filepath, Imf::FLOAT );
00116                                                                 break;
00117                                                         default:
00118                                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00119                                                                     << exception::user( "Exr Writer: components not supported" ) );
00120                                                                 break;
00121                                                 }
00122                                                 break;
00123                                         }
00124                                         case eTuttlePluginComponentsGray:
00125                                         {
00126                                                 writeGrayImage<gray32f_pixel_t>(src, _params._filepath, Imf::FLOAT);
00127                                                 break;
00128                                         }
00129                                         case eTuttlePluginComponentsRGB:
00130                                         {
00131                                                 writeImage<rgb32f_pixel_t>( src, _params._filepath, Imf::FLOAT );
00132                                                 break;
00133                                         }
00134                                         case eTuttlePluginComponentsRGBA:
00135                                         {
00136                                                 writeImage<rgba32f_pixel_t>( src, _params._filepath, Imf::FLOAT );
00137                                                 break;
00138                                         }
00139                                         default:
00140                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00141                                                     << exception::user( "Exr Writer: components not supported" ) );
00142                                 }
00143                                 break;
00144                         }
00145                         case eTuttlePluginBitDepth32:
00146                         {
00147                                 switch( _params._componentsType )
00148                                 {
00149                                         case eTuttlePluginComponentsAuto:
00150                                         {
00151                                                 switch ( _plugin._clipSrc->getPixelComponents() )
00152                                                 {
00153                                                         case OFX::ePixelComponentAlpha:
00154                                                                 writeGrayImage<gray32_pixel_t>( src, _params._filepath, Imf::HALF );
00155                                                                 break;
00156                                                         case OFX::ePixelComponentRGB:
00157                                                                 writeImage<rgb32_pixel_t>( src, _params._filepath, Imf::HALF );
00158                                                                 break;
00159                                                         case OFX::ePixelComponentRGBA:
00160                                                                 writeImage<rgba32_pixel_t>( src, _params._filepath, Imf::HALF );
00161                                                                 break;
00162                                                         default:
00163                                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00164                                                                     << exception::user( "Exr Writer: components not supported" ) );
00165                                                                 break;
00166                                                 }
00167                                                 break;
00168                                         }
00169                                         case eTuttlePluginComponentsGray:
00170                                         {
00171                                                 writeGrayImage<gray32_pixel_t>(src, _params._filepath, Imf::UINT);
00172                                                 break;
00173                                         }
00174                                         case eTuttlePluginComponentsRGB:
00175                                         {
00176                                                 writeImage<rgb32_pixel_t>( src, _params._filepath, Imf::UINT );
00177                                                 break;
00178                                         }
00179                                         case eTuttlePluginComponentsRGBA:
00180                                         {
00181                                                 writeImage<rgba32_pixel_t>( src, _params._filepath, Imf::UINT );
00182                                                 break;
00183                                         }
00184                                         default:
00185                                                 BOOST_THROW_EXCEPTION( exception::Unsupported()
00186                                                     << exception::user( "Exr Writer: components not supported" ) );
00187                                 }
00188                                 break;
00189                         }
00190                 }
00191         }
00192         catch( exception::Common& e )
00193         {
00194                 e << exception::filename( _params._filepath );
00195                 throw;
00196         }
00197         catch(... )
00198         {
00199                 BOOST_THROW_EXCEPTION( exception::Unknown()
00200                         << exception::user( "Unable to write image" )
00201                         << exception::dev( boost::current_exception_diagnostic_information() )
00202                         << exception::filename( _params._filepath ) );
00203         }
00204         // @todo: This is sometimes not neccessary... Checkbox it.
00205         copy_and_convert_pixels( this->_srcView, this->_dstView );
00206 }
00207 
00208 template<class View>
00209 template<class WPixel>
00210 void EXRWriterProcess<View>::writeGrayImage( View& src, std::string& filepath, Imf::PixelType pixType )
00211 {
00212         using namespace terry;
00213 
00214         std::size_t bitsTypeSize = 0;
00215 
00216         typedef image<WPixel, false> image_t;
00217         typedef typename image_t::view_t view_t;
00218         image_t img( src.width(), src.height() );
00219         view_t  dvw( view( img ) );
00220         copy_and_convert_pixels( src, dvw );
00221         Imf::Header header( src.width(), src.height() );
00222         switch( pixType )
00223         {
00224                 case Imf::HALF:
00225                         bitsTypeSize = sizeof( half );
00226                         break;
00227                 case Imf::FLOAT:
00228                         bitsTypeSize = sizeof( float );
00229                         break;
00230                 case Imf::UINT:
00231                         bitsTypeSize = sizeof( boost::uint32_t );
00232                         break;
00233                 default:
00234                         break;
00235         }
00236 
00237         switch( dvw.num_channels() )
00238         {
00239                 // Gray
00240                 case 1:
00241                 {
00242                         header.channels().insert( "Y", Imf::Channel( pixType ) );
00243                         break;
00244                 }
00245                 // RGB
00246                 // RGBA
00247                 default:
00248                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00249                             << exception::user( "ExrWriter: incompatible image type" ) );
00250                         break;
00251         }
00252 
00253         Imf::OutputFile file( filepath.c_str(), header );
00254         Imf::FrameBuffer frameBuffer;
00255 
00256         switch( dvw.num_channels() )
00257         {
00258                 // Gray
00259                 case 1:
00260                 {
00261                         char* pixelsY = (char*)boost::gil::interleaved_view_get_raw_data( dvw );
00262                         frameBuffer.insert( "Y", Imf::Slice( pixType, pixelsY, bitsTypeSize, bitsTypeSize * src.width() ) );
00263                         break;
00264                 }
00265                 // RGB
00266                 // RGBA
00267                 default:
00268                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00269                             << exception::user( "ExrWriter: incompatible image type" ) );
00270                         break;
00271         }
00272         file.setFrameBuffer( frameBuffer );
00273         // Finalize output
00274         file.writePixels( src.height() );
00275 }
00276 
00277 
00278 template<class View>
00279 template<class WPixel>
00280 void EXRWriterProcess<View>::writeImage( View& src, std::string& filepath, Imf::PixelType pixType )
00281 {
00282         using namespace terry;
00283 
00284         std::size_t bitsTypeSize = 0;
00285 
00286         typedef image<WPixel, true> image_t;
00287         typedef typename image_t::view_t view_t;
00288         image_t img( src.width(), src.height() );
00289         view_t  dvw( view( img ) );
00290         copy_and_convert_pixels( src, dvw );
00291         Imf::Header header( src.width(), src.height() );
00292         switch( pixType )
00293         {
00294                 case Imf::HALF:
00295                         bitsTypeSize = sizeof( half );
00296                         break;
00297                 case Imf::FLOAT:
00298                         bitsTypeSize = sizeof( float );
00299                         break;
00300                 case Imf::UINT:
00301                         bitsTypeSize = sizeof( boost::uint32_t );
00302                         break;
00303                 default:
00304                         break;
00305         }
00306 
00307         switch( dvw.num_channels() )
00308         {
00309                 case 3:
00310                 {
00311                         header.channels().insert( "R", Imf::Channel( pixType ) );
00312                         header.channels().insert( "G", Imf::Channel( pixType ) );
00313                         header.channels().insert( "B", Imf::Channel( pixType ) );
00314                         break;
00315                 }
00316                 case 4:
00317                 {
00318                         header.channels().insert( "R", Imf::Channel( pixType ) );
00319                         header.channels().insert( "G", Imf::Channel( pixType ) );
00320                         header.channels().insert( "B", Imf::Channel( pixType ) );
00321                         header.channels().insert( "A", Imf::Channel( pixType ) );
00322                         break;
00323                 }
00324                 // Gray
00325                 case 1:
00326                 default:
00327                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00328                             << exception::user( "ExrWriter: incompatible image type" ) );
00329         }
00330 
00331         Imf::OutputFile file( filepath.c_str(), header );
00332         Imf::FrameBuffer frameBuffer;
00333 
00334         switch( dvw.num_channels() )
00335         {
00336                 // RGB
00337                 case 3:
00338                 {
00339                         char* pixelsR = (char*)boost::gil::planar_view_get_raw_data( dvw, 0 );
00340                         char* pixelsG = (char*)boost::gil::planar_view_get_raw_data( dvw, 1 );
00341                         char* pixelsB = (char*)boost::gil::planar_view_get_raw_data( dvw, 2 );
00342                         frameBuffer.insert( "R", Imf::Slice( pixType, pixelsR, bitsTypeSize, bitsTypeSize * src.width() ) );
00343                         frameBuffer.insert( "G", Imf::Slice( pixType, pixelsG, bitsTypeSize, bitsTypeSize * src.width() ) );
00344                         frameBuffer.insert( "B", Imf::Slice( pixType, pixelsB, bitsTypeSize, bitsTypeSize * src.width() ) );
00345                         break;
00346                 }
00347                 // RGBA
00348                 case 4:
00349                 {
00350                         char* pixelsR = (char*)boost::gil::planar_view_get_raw_data( dvw, 0 );
00351                         char* pixelsG = (char*)boost::gil::planar_view_get_raw_data( dvw, 1 );
00352                         char* pixelsB = (char*)boost::gil::planar_view_get_raw_data( dvw, 2 );
00353                         char* pixelsA = (char*)boost::gil::planar_view_get_raw_data( dvw, 3 );
00354                         frameBuffer.insert( "R", Imf::Slice( pixType, pixelsR, bitsTypeSize, bitsTypeSize * src.width() ) );
00355                         frameBuffer.insert( "G", Imf::Slice( pixType, pixelsG, bitsTypeSize, bitsTypeSize * src.width() ) );
00356                         frameBuffer.insert( "B", Imf::Slice( pixType, pixelsB, bitsTypeSize, bitsTypeSize * src.width() ) );
00357                         frameBuffer.insert( "A", Imf::Slice( pixType, pixelsA, bitsTypeSize, bitsTypeSize * src.width() ) );
00358                         break;
00359                 }
00360                 // Gray
00361                 case 1:
00362                 default:
00363                         BOOST_THROW_EXCEPTION( exception::ImageFormat()
00364                             << exception::user( "ExrWriter: incompatible image type" ) );
00365                         break;
00366         }
00367         file.setFrameBuffer( frameBuffer );
00368         // Finalize output
00369         file.writePixels( src.height() );
00370 }
00371 
00372 }
00373 }
00374 }
00375 }