TuttleOFX  1
DPXReaderProcess.tcc
Go to the documentation of this file.
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 }