TuttleOFX
1
|
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 }