TuttleOFX
1
|
00001 #include "OpenImageIOReaderDefinitions.hpp" 00002 #include "OpenImageIOReaderProcess.hpp" 00003 00004 #include <terry/globals.hpp> 00005 #include <tuttle/plugin/exceptions.hpp> 00006 00007 #include <imageio.h> 00008 00009 #include <boost/gil/gil_all.hpp> 00010 #include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp> 00011 #include <boost/filesystem/fstream.hpp> 00012 #include <boost/mpl/map.hpp> 00013 #include <boost/mpl/at.hpp> 00014 00015 #include <boost/scoped_ptr.hpp> 00016 #include <boost/assert.hpp> 00017 00018 namespace tuttle { 00019 namespace plugin { 00020 namespace openImageIO { 00021 namespace reader { 00022 00023 using namespace boost::gil; 00024 namespace bfs = boost::filesystem; 00025 00026 template<class View> 00027 OpenImageIOReaderProcess<View>::OpenImageIOReaderProcess( OpenImageIOReaderPlugin& instance ) 00028 : ImageGilProcessor<View>( instance, eImageOrientationFromTopToBottom ) 00029 , _plugin( instance ) 00030 { 00031 this->setNoMultiThreading(); 00032 } 00033 00034 /** 00035 * @brief Function called by rendering thread each time a process must be done. 00036 * @param[in] procWindowRoW Processing window in RoW 00037 */ 00038 template<class View> 00039 void OpenImageIOReaderProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00040 { 00041 // no tiles and no multithreading supported 00042 BOOST_ASSERT( procWindowRoW == this->_dstPixelRod ); 00043 00044 std::string filename = _plugin.getProcessParams( this->_renderArgs.time )._filepath; 00045 00046 boost::scoped_ptr<OpenImageIO::ImageInput> img( OpenImageIO::ImageInput::create( filename ) ); 00047 00048 if( img.get() == NULL ) 00049 { 00050 BOOST_THROW_EXCEPTION( OFX::Exception::Suite( kOfxStatErrValue ) ); 00051 } 00052 OpenImageIO::ImageSpec spec; 00053 00054 if( ! img->open( filename, spec ) ) 00055 { 00056 BOOST_THROW_EXCEPTION( exception::Unknown() 00057 << exception::user( "OIIO Reader: " + img->geterror () ) 00058 << exception::filename( filename ) ); 00059 } 00060 00061 switch( spec.format.basetype ) 00062 { 00063 case OpenImageIO::TypeDesc::UINT8: 00064 case OpenImageIO::TypeDesc::INT8: 00065 { 00066 switch( spec.nchannels ) 00067 { 00068 case 1 : 00069 readImage<bits8, gray_layout_t, gray8_view_t>( this->_dstView, img, 1 ); 00070 break; 00071 case 3 : 00072 readImage<bits8, rgb_layout_t, rgb8_view_t>( this->_dstView, img, 1 ); 00073 break; 00074 case 4 : 00075 readImage<bits8, rgba_layout_t, rgba8_view_t>( this->_dstView, img, 1 ); 00076 break; 00077 default: 00078 img->close(); 00079 BOOST_THROW_EXCEPTION( exception::ImageFormat() 00080 << exception::user("bad input format") ); 00081 break; 00082 } 00083 break; 00084 } 00085 case OpenImageIO::TypeDesc::HALF: 00086 case OpenImageIO::TypeDesc::UINT16: 00087 case OpenImageIO::TypeDesc::INT16: 00088 { 00089 switch( spec.nchannels ) 00090 { 00091 case 1 : 00092 readImage<bits16, gray_layout_t, gray16_view_t>( this->_dstView, img, 2 ); 00093 break; 00094 case 3 : 00095 readImage<bits16, rgb_layout_t, rgb16_view_t>( this->_dstView, img, 2 ); 00096 break; 00097 case 4 : 00098 readImage<bits16, rgba_layout_t, rgba16_view_t>( this->_dstView, img, 2 ); 00099 break; 00100 default: 00101 img->close(); 00102 BOOST_THROW_EXCEPTION( exception::ImageFormat() 00103 << exception::user("bad input format") ); 00104 break; 00105 } 00106 break; 00107 } 00108 case OpenImageIO::TypeDesc::UINT32: 00109 case OpenImageIO::TypeDesc::INT32: 00110 case OpenImageIO::TypeDesc::UINT64: 00111 case OpenImageIO::TypeDesc::INT64: 00112 case OpenImageIO::TypeDesc::FLOAT: 00113 case OpenImageIO::TypeDesc::DOUBLE: 00114 { 00115 switch( spec.nchannels ) 00116 { 00117 case 1 : 00118 readImage<bits32f, gray_layout_t, gray32f_view_t>( this->_dstView, img, 4 ); 00119 break; 00120 case 3 : 00121 readImage<bits32f, rgb_layout_t, rgb32f_view_t>( this->_dstView, img, 4 ); 00122 break; 00123 case 4 : 00124 readImage<bits32f, rgba_layout_t, rgba32f_view_t>( this->_dstView, img, 4 ); 00125 break; 00126 default: 00127 img->close(); 00128 BOOST_THROW_EXCEPTION( exception::ImageFormat() 00129 << exception::user("bad input format") ); 00130 break; 00131 } 00132 break; 00133 } 00134 case OpenImageIO::TypeDesc::STRING: 00135 case OpenImageIO::TypeDesc::PTR: 00136 case OpenImageIO::TypeDesc::LASTBASE: 00137 case OpenImageIO::TypeDesc::UNKNOWN: 00138 case OpenImageIO::TypeDesc::NONE: 00139 default: 00140 { 00141 img->close(); 00142 BOOST_THROW_EXCEPTION( exception::ImageFormat() 00143 << exception::user("bad input format") ); 00144 } 00145 } 00146 00147 00148 img->close(); 00149 } 00150 00151 /** 00152 */ 00153 template<class View> 00154 template<typename bitDepth, typename layout, typename fileView> 00155 View& OpenImageIOReaderProcess<View>::readImage( View& dst, boost::scoped_ptr<OpenImageIO::ImageInput>& img, int pixelSize ) 00156 { 00157 using namespace boost; 00158 using namespace boost::gil; 00159 using namespace OpenImageIO; 00160 00161 typedef pixel<bitDepth, layout> pixel_t; 00162 typedef image<pixel_t, false> image_t; 00163 00164 image_t tmpImg ( dst.width(), dst.height() ); 00165 fileView tmpView = view( tmpImg ); 00166 00167 const stride_t xstride = tmpView.num_channels() * pixelSize; 00168 const stride_t ystride = tmpView.pixels().row_size(); 00169 const stride_t zstride = ystride * tmpView.height() ; 00170 00171 img->read_image( 00172 TypeDesc::UNKNOWN, // it's to not convert into OpenImageIO, convert with GIL 00173 &( ( *tmpView.begin() )[0] ), // get the adress of the first channel value from the first pixel 00174 xstride, 00175 ystride, 00176 zstride, 00177 &progressCallback, 00178 this 00179 ); 00180 00181 copy_and_convert_pixels( tmpView, dst ); 00182 return dst; 00183 } 00184 00185 } 00186 } 00187 } 00188 }