TuttleOFX
1
|
00001 #include "DPXReaderPlugin.hpp" 00002 #include "DPXReaderDefinitions.hpp" 00003 00004 #include <terry/globals.hpp> 00005 #include <tuttle/plugin/ImageGilProcessor.hpp> 00006 #include <tuttle/plugin/exceptions.hpp> 00007 00008 #include <ofxsImageEffect.h> 00009 #include <ofxsMultiThread.h> 00010 00011 #include <terry/typedefs.hpp> 00012 #include <boost/gil/gil_all.hpp> 00013 #include <boost/gil/packed_pixel.hpp> 00014 00015 #include <boost/integer.hpp> // for boost::uint_t 00016 #include <boost/cstdint.hpp> 00017 #include <boost/mpl/vector.hpp> 00018 #include <boost/scoped_ptr.hpp> 00019 #include <boost/filesystem/fstream.hpp> 00020 00021 namespace tuttle { 00022 namespace plugin { 00023 namespace dpx { 00024 namespace reader { 00025 00026 namespace bfs = boost::filesystem; 00027 00028 template<class View> 00029 DPXReaderProcess<View>::DPXReaderProcess( DPXReaderPlugin& instance ) 00030 : ImageGilProcessor<View>( instance, eImageOrientationFromTopToBottom ) 00031 , _plugin( instance ) 00032 { 00033 this->setNoMultiThreading(); 00034 } 00035 00036 template<class View> 00037 DPXReaderProcess<View>::~DPXReaderProcess() 00038 {} 00039 00040 template<class View> 00041 void DPXReaderProcess<View>::setup( const OFX::RenderArguments& args ) 00042 { 00043 using namespace boost::gil; 00044 ImageGilProcessor<View>::setup( args ); 00045 _params = _plugin.getProcessParams( args.time ); 00046 } 00047 00048 /** 00049 * @brief Function called by rendering thread each time a process must be done. 00050 * @param[in] procWindowRoW Processing window in RoW 00051 */ 00052 template<class View> 00053 void DPXReaderProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00054 { 00055 using namespace boost::gil; 00056 readImage( this->_dstView ); 00057 } 00058 00059 template<class View> 00060 View& DPXReaderProcess<View>::readImage( View& dst ) 00061 { 00062 using namespace boost; 00063 using namespace mpl; 00064 using namespace boost::gil; 00065 00066 _dpxImage.read( _params._filepath, true ); 00067 00068 switch( _dpxImage.componentsType() ) 00069 { 00070 case tuttle::io::DpxImage::eCompTypeR8G8B8: 00071 { 00072 // Tests passed: fill, non fill, big endian, little endian 00073 rgb8c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00074 (const rgb8_pixel_t*)( _dpxImage.data() ), 00075 _dpxImage.width() * 3 ); 00076 copy_and_convert_pixels( src, dst ); 00077 break; 00078 } 00079 case tuttle::io::DpxImage::eCompTypeR8G8B8A8: 00080 { 00081 // Tests passed: fill, non fill, big endian, little endian 00082 rgba8c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00083 (const rgba8_pixel_t*)( _dpxImage.data() ), 00084 _dpxImage.width() * 4 ); 00085 00086 copy_and_convert_pixels( src, dst ); 00087 break; 00088 } 00089 case tuttle::io::DpxImage::eCompTypeA8B8G8R8: 00090 { 00091 // Untested (need images samples), quite sure it is working 00092 abgr8c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00093 (const abgr8_pixel_t*)( _dpxImage.data() ), 00094 _dpxImage.width() * 4 ); 00095 00096 copy_and_convert_pixels( src, dst ); 00097 break; 00098 } 00099 case tuttle::io::DpxImage::eCompTypeR10G10B10: 00100 { 00101 // Tests passed: fill, non fill, big endian, little endian 00102 // Interpret pixels according to its bit packing 00103 switch( _dpxImage.packing() ) 00104 { 00105 // bit stream 00106 case 0: 00107 { 00108 rgb16_image_t img( dst.width(), dst.height() ); 00109 rgb16_view_t vw( view( img ) ); 00110 bitStreamToView<rgb10_stream_ptr_t>( vw, 3, 10 ); 00111 copy_and_convert_pixels( vw, dst ); 00112 break; 00113 } 00114 default: 00115 { 00116 int width = _dpxImage.width(); 00117 int height = _dpxImage.height(); 00118 gray32_view_t src = interleaved_view( width, height, 00119 ( gray32_pixel_t* )( _dpxImage.rawData() ), 00120 width * sizeof( uint32_t ) ); 00121 00122 rgb16_image_t img16( width, height ); 00123 rgb16_view_t vw16( view( img16 ) ); 00124 for( typename gray32_view_t::y_coord_t y = 0; y < height; ++y ) 00125 { 00126 typename gray32_view_t::x_iterator sit = src.row_begin( y ); 00127 typename rgb16_view_t::x_iterator dit = vw16.row_begin( y ); 00128 for( typename gray32_view_t::x_coord_t x = 0; x < width; ++x ) 00129 { 00130 uint32_t pixel = (uint32_t) *sit; 00131 00132 short red = ( ( pixel & 0xffc00000 ) >> 22 ); 00133 short green = ( ( pixel & 0x003ff000 ) >> 12 ); 00134 short blue = ( ( pixel & 0x00000ffc ) >> 2 ); 00135 00136 get_color( *dit, red_t() ) = red ; 00137 get_color( *dit, green_t() ) = green ; 00138 get_color( *dit, blue_t() ) = blue ; 00139 00140 ++sit; 00141 ++dit; 00142 } 00143 } 00144 00145 copy_and_convert_pixels( vw16, dst ); 00146 break; 00147 } 00148 } 00149 break; 00150 } 00151 case tuttle::io::DpxImage::eCompTypeR10G10B10A10: 00152 { 00153 // Tests passed: fill with big endian or little endian 00154 // Tests failed: non fill 00155 // Interpret pixels according to its bit packing 00156 switch( _dpxImage.packing() ) 00157 { 00158 // bit stream 00159 case 0: 00160 { 00161 rgba16_image_t img( dst.width(), dst.height() ); 00162 rgba16_view_t vw( view( img ) ); 00163 bitStreamToView<rgba10_stream_ptr_t>( vw, 4, 10 ); 00164 copy_and_convert_pixels( vw, dst ); 00165 break; 00166 } 00167 default: 00168 { 00169 BOOST_THROW_EXCEPTION( exception::Failed() 00170 << exception::dev() + "Unsupported dpx file format (RGBA10 byte packed). " ); 00171 } 00172 } 00173 break; 00174 } 00175 case tuttle::io::DpxImage::eCompTypeA10B10G10R10: 00176 { 00177 // Untested (need images samples), quite sure it is not working :( 00178 // Interpret pixels according to its bit packing 00179 switch( _dpxImage.packing() ) 00180 { 00181 // bit stream 00182 case 0: 00183 { 00184 rgba16_image_t img( dst.width(), dst.height() ); 00185 rgba16_view_t vw( view( img ) ); 00186 bitStreamToView<abgr10_stream_ptr_t>( vw, 4, 10 ); 00187 copy_and_convert_pixels( vw, dst ); 00188 break; 00189 } 00190 case 1: 00191 case 2: 00192 { 00193 BOOST_THROW_EXCEPTION( exception::Failed() 00194 << exception::dev() + "Unsupported dpx file format (ABGR10 byte packed). " ); 00195 } 00196 } 00197 break; 00198 } 00199 case tuttle::io::DpxImage::eCompTypeR12G12B12: 00200 { 00201 // Tests failed: all (sick) ! 00202 // Probable bug in gil... 00203 // Interpret pixels according to its bit packing 00204 switch( _dpxImage.packing() ) 00205 { 00206 // bit stream 00207 case 0: 00208 { 00209 rgb16_image_t img( dst.width(), dst.height() ); 00210 rgb16_view_t vw( view( img ) ); 00211 bitStreamToView<rgb12_stream_ptr_t>( vw, 3, 12 ); 00212 copy_and_convert_pixels( vw, dst ); 00213 break; 00214 } 00215 default: 00216 { 00217 int width = _dpxImage.width(); 00218 int height = _dpxImage.height(); 00219 rgb12_packed_view_t src = interleaved_view( width, height, 00220 ( rgb12_packed_pixel_t* )( _dpxImage.data() ), 00221 _dpxImage.width() * 6 ); 00222 // This is temporary but needed because of a probable bug in gil 00223 // Should be using copy_and_convert_pixels 00224 rgb16_image_t img16( width, height ); 00225 rgb16_view_t vw16( view( img16 ) ); 00226 for( typename rgb12_packed_view_t::y_coord_t y = 0; y < height; ++y ) 00227 { 00228 typename rgb12_packed_view_t::x_iterator sit = src.row_begin( y ); 00229 typename rgb16_view_t::x_iterator dit = vw16.row_begin( y ); 00230 for( typename rgb12_packed_view_t::x_coord_t x = 0; x < width; ++x ) 00231 { 00232 color_convert( *sit, *dit ); 00233 ++sit; 00234 ++dit; 00235 } 00236 } 00237 copy_and_convert_pixels( vw16, dst ); 00238 break; 00239 00240 } 00241 } 00242 break; 00243 } 00244 case tuttle::io::DpxImage::eCompTypeR12G12B12A12: 00245 { 00246 // Tests passed: fill big endian or little endian, non fill little endian or big endian 00247 // Interpret pixels according to its bit packing 00248 switch( _dpxImage.packing() ) 00249 { 00250 // bit stream 00251 case 0: 00252 { 00253 rgba16_image_t img( dst.width(), dst.height() ); 00254 rgba16_view_t vw( view( img ) ); 00255 bitStreamToView<rgba12_stream_ptr_t>( vw, 4, 12 ); 00256 copy_and_convert_pixels( vw, dst ); 00257 break; 00258 } 00259 default: 00260 { 00261 BOOST_THROW_EXCEPTION( exception::Failed() 00262 << exception::dev() + "Unsupported dpx file format (RGBA12 byte packed). " ); 00263 rgba12_packed_view_t vw = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00264 ( rgba12_packed_pixel_t* )( _dpxImage.data() ), 00265 _dpxImage.width() * sizeof( uint64_t ) ); 00266 00267 //copy_and_convert_pixels( vw, dst ); 00268 break; 00269 } 00270 } 00271 break; 00272 } 00273 case tuttle::io::DpxImage::eCompTypeA12B12G12R12: 00274 { 00275 // Untested 00276 // Interpret pixels according to its bit packing 00277 switch( _dpxImage.packing() ) 00278 { 00279 // bit stream 00280 case 0: 00281 { 00282 rgba16_image_t img( dst.width(), dst.height() ); 00283 rgba16_view_t vw( view( img ) ); 00284 bitStreamToView<abgr12_stream_ptr_t>( vw, 4, 12 ); 00285 copy_and_convert_pixels( vw, dst ); 00286 break; 00287 } 00288 default: 00289 { 00290 BOOST_THROW_EXCEPTION( exception::Failed() 00291 << exception::dev() + "Unsupported dpx file format (ABGR12 byte packed). " ); 00292 /* 00293 abgr12_packed_view_t vw = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00294 ( abgr12_packed_pixel_t* )( _dpxImage.data() ), 00295 _dpxImage.width() * sizeof( uint64_t ) ); 00296 00297 //copy_and_convert_pixels( vw, dst );*/ 00298 break; 00299 } 00300 } 00301 break; 00302 } 00303 case tuttle::io::DpxImage::eCompTypeR16G16B16: 00304 { 00305 /// @todo: bug here. 00306 //TUTTLE_LOG_INFOS; 00307 //TUTTLE_LOG_VAR( TUTTLE_INFO, _dpxImage.width() ); 00308 //TUTTLE_LOG_VAR( TUTTLE_INFO, _dpxImage.height() ); 00309 //TUTTLE_LOG_VAR( TUTTLE_INFO, sizeof( rgb16_pixel_t ) ); 00310 // Tests passed: fill, non fill, big endian, little endian 00311 rgb16c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00312 (const rgb16_pixel_t*)( _dpxImage.data() ), 00313 _dpxImage.width() * sizeof( rgb16_pixel_t ) ); 00314 copy_and_convert_pixels( src, dst ); 00315 break; 00316 } 00317 case tuttle::io::DpxImage::eCompTypeR16G16B16A16: 00318 { 00319 // Tests passed: fill, non fill, big endian, little endian 00320 rgba16c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00321 (const rgba16_pixel_t*)( _dpxImage.data() ), 00322 _dpxImage.width() * sizeof( uint64_t ) ); 00323 00324 copy_and_convert_pixels( src, dst ); 00325 break; 00326 } 00327 case tuttle::io::DpxImage::eCompTypeA16B16G16R16: 00328 { 00329 // Untested (need images samples), quite sure it is working 00330 abgr16c_view_t src = interleaved_view( _dpxImage.width(), _dpxImage.height(), 00331 (const abgr16_pixel_t*)( _dpxImage.data() ), 00332 _dpxImage.width() * sizeof( uint64_t ) ); 00333 00334 copy_and_convert_pixels( src, dst ); 00335 break; 00336 } 00337 case tuttle::io::DpxImage::eCompTypeUnknown: 00338 { 00339 BOOST_THROW_EXCEPTION( exception::Failed() 00340 << exception::dev() + "Unrecognized image type, bit depth is " + _dpxImage.getHeader().bitSize() + ", component type is: " + _dpxImage.getHeader().descriptor() + ".\n" 00341 + "DPX HEADER:\n" 00342 + _dpxImage.getHeader() ); 00343 break; 00344 } 00345 } 00346 00347 return dst; 00348 } 00349 00350 template<class View> 00351 template<class T, class DST_V> 00352 void DPXReaderProcess<View>::bitStreamToView( DST_V& dst, const int nc, const int channelSize ) 00353 { 00354 boost::uint8_t* pData = _dpxImage.data(); 00355 00356 typedef unsigned char byte_t; 00357 int width = _dpxImage.width(); 00358 int height = _dpxImage.height(); 00359 int scanline_in_bits = width * nc * channelSize; 00360 int scanline_in_bytes = scanline_in_bits / 8; 00361 scanline_in_bytes += ( scanline_in_bits % 8 != 0 ) ? 1 : 0; 00362 T p( pData, 0 ); 00363 00364 for( typename DST_V::y_coord_t y = 0; y < height; ++y ) 00365 { 00366 typename DST_V::x_iterator it = dst.row_begin( y ); 00367 00368 for( typename DST_V::x_coord_t x = 0; x < width; ++x ) 00369 { 00370 color_convert( *p, *it ); 00371 ++p; 00372 ++it; 00373 } 00374 } 00375 } 00376 00377 } 00378 } 00379 } 00380 }