TuttleOFX
1
|
00001 #include "RawReaderDefinitions.hpp" 00002 #include "RawReaderProcess.hpp" 00003 #include "RawReaderPlugin.hpp" 00004 00005 #include <terry/globals.hpp> 00006 #include <terry/point/ostream.hpp> 00007 #include <tuttle/plugin/exceptions.hpp> 00008 00009 #include <boost/gil/gil_all.hpp> 00010 #include <boost/filesystem/fstream.hpp> 00011 00012 #include <boost/scoped_ptr.hpp> 00013 #include <boost/assert.hpp> 00014 00015 namespace tuttle { 00016 namespace plugin { 00017 namespace raw { 00018 namespace reader { 00019 00020 template<class View> 00021 static int progressCallback( void* data, LibRaw_progress p, int iteration, int expected ) 00022 { 00023 typedef RawReaderProcess<View> PluginProcess; 00024 //PluginProcess* process = reinterpret_cast<PluginProcess*>( data ); 00025 TUTTLE_LOG_DEBUG( TUTTLE_INFO, "Callback: " << libraw_strprogress( p ) << " pass " << iteration << " of " << expected ); 00026 /*if( process->progressUpdate( iteration / (double)expected ) ) 00027 return 1; // cancel processing immediately*/ 00028 return 0; // can continue 00029 } 00030 00031 //typedef void (*data_callback)(void *callback_data,const char *file, const int offset); 00032 //void LibRaw::set_dataerror_handler(data_callback func, void *callback_data); 00033 00034 //typedef void (* memory_callback)(void *callback_data,const char *file, const char *where); 00035 //void LibRaw::set_memerror_handler(memory_callback func,void *callback_data); 00036 00037 using namespace boost::gil; 00038 namespace bfs = boost::filesystem; 00039 00040 template<class View> 00041 RawReaderProcess<View>::RawReaderProcess( RawReaderPlugin& instance ) 00042 : ImageGilProcessor<View>( instance, eImageOrientationFromTopToBottom ) 00043 , _plugin( instance ) 00044 , _p1( _rawProcessor.imgdata.idata ) 00045 , _size( _rawProcessor.imgdata.sizes ) 00046 , _color( _rawProcessor.imgdata.color ) 00047 , _thumbnail( _rawProcessor.imgdata.thumbnail ) 00048 , _p2( _rawProcessor.imgdata.other ) 00049 , _out( _rawProcessor.imgdata.params ) 00050 { 00051 this->setNoMultiThreading(); 00052 00053 _rawProcessor.set_progress_handler( progressCallback<View>, reinterpret_cast<void*>( this ) ); 00054 // _rawProcessor.set_memerror_handler( xxxCallback, reinterpret_cast<void*>(this) ); 00055 // _rawProcessor.set_dataerror_handler( xxxCallback, reinterpret_cast<void*>(this) ); 00056 } 00057 00058 template<class View> 00059 void RawReaderProcess<View>::setup( const OFX::RenderArguments& args ) 00060 { 00061 ImageGilProcessor<View>::setup( args ); 00062 _params = _plugin.getProcessParams( args.time ); 00063 } 00064 00065 template<class View> 00066 void RawReaderProcess<View>::preProcess() 00067 { 00068 // remove default implementation 00069 } 00070 00071 /** 00072 * @brief Function called by rendering thread each time a process must be done. 00073 * @param[in] procWindowRoW Processing window in RoW 00074 */ 00075 template<class View> 00076 void RawReaderProcess<View>::multiThreadProcessImages( const OfxRectI& procWindowRoW ) 00077 { 00078 // no tiles and no multithreading supported 00079 BOOST_ASSERT( procWindowRoW == this->_dstPixelRod ); 00080 00081 try 00082 { 00083 _out.output_bps = 16; 00084 00085 _out.greybox[0] = _params._greyboxPoint.x; 00086 _out.greybox[1] = _params._greyboxPoint.y; 00087 _out.greybox[2] = _params._greyboxSize.x; 00088 _out.greybox[3] = _params._greyboxSize.y; 00089 00090 _out.aber[0] = _params._redAbber; 00091 _out.aber[2] = _params._blueAbber; 00092 00093 _out.bright = _params._bright; 00094 _out.threshold = _params._threshold; 00095 _out.gamm[0] = _params._gammaPower; 00096 _out.gamm[1] = _params._gammaToe; 00097 _out.user_qual = _params._interpolation; 00098 _out.no_auto_bright = 0; 00099 00100 _out.four_color_rgb = _params._fourColorRgb; 00101 _out.document_mode = _params._documentMode; 00102 00103 _out.exp_correc = 1; // every time correct exposure (use default parameters to don't change) 00104 _out.exp_shift = _params._exposure; 00105 _out.exp_preser = _params._exposurePreserve; 00106 00107 _out.highlight = _params._hightlight; 00108 _out.use_fuji_rotate = 0; // don't use 00109 00110 _out.use_auto_wb = 0; 00111 _out.use_camera_wb = 0; 00112 00113 switch( _params._whiteBalance ) 00114 { 00115 case eAutoWb: _out.use_auto_wb = 1; break; 00116 case eCameraWb: _out.use_camera_wb = 1; break; 00117 case eManualWb: break; 00118 case e2500: break; 00119 case e2550: break; 00120 case e2650: break; 00121 case e2700: break; 00122 case e2800: break; 00123 case e2850: break; 00124 case e2950: break; 00125 case e3000: break; 00126 case e3100: break; 00127 case e3200: break; 00128 case e3300: break; 00129 case e3400: break; 00130 case e3600: break; 00131 case e3700: break; 00132 case e3800: break; 00133 case e4000: break; 00134 case e4200: break; 00135 case e4300: break; 00136 case e4500: break; 00137 case e4800: break; 00138 case e5000: break; 00139 case e5300: break; 00140 case e5600: break; 00141 case e5900: break; 00142 case e6300: break; 00143 case e6700: break; 00144 case e7100: break; 00145 case e7700: break; 00146 case e8300: break; 00147 case e9100: break; 00148 case e10000: break; 00149 } 00150 00151 /* 00152 #define greybox (imgdata.params.greybox) 00153 #define cropbox (imgdata.params.cropbox) 00154 #define aber (imgdata.params.aber) 00155 #define gamm (imgdata.params.gamm) 00156 #define user_mul (imgdata.params.user_mul) 00157 #define shot_select (imgdata.params.shot_select) 00158 #define bright (imgdata.params.bright) 00159 #define threshold (imgdata.params.threshold) 00160 #define half_size (imgdata.params.half_size) 00161 #define four_color_rgb (imgdata.params.four_color_rgb) 00162 #define document_mode (imgdata.params.document_mode) 00163 #define highlight (imgdata.params.highlight) 00164 //#define verbose (imgdata.params.verbose) 00165 #define use_auto_wb (imgdata.params.use_auto_wb) 00166 #define use_camera_wb (imgdata.params.use_camera_wb) 00167 #define use_camera_matrix (imgdata.params.use_camera_matrix) 00168 #define output_color (imgdata.params.output_color) 00169 #define output_bps (imgdata.params.output_bps) 00170 #define gamma_16bit (imgdata.params.gamma_16bit) 00171 #define output_tiff (imgdata.params.output_tiff) 00172 #define med_passes (imgdata.params.med_passes) 00173 #define no_auto_bright (imgdata.params.no_auto_bright) 00174 #define use_fuji_rotate (imgdata.params.use_fuji_rotate) 00175 #define filtering_mode (imgdata.params.filtering_mode) 00176 */ 00177 00178 /*switch( _params._filtering ) 00179 { 00180 case eFilteringAuto: 00181 _out.filtering_mode = LIBRAW_FILTERING_AUTOMATIC; 00182 break; 00183 case eFilteringNone: 00184 _out.filtering_mode = LIBRAW_FILTERING_NONE; // output RGBG ? 00185 break; 00186 }*/ 00187 00188 if( const int ret = _rawProcessor.open_file( _params._filepath.c_str() ) ) 00189 { 00190 BOOST_THROW_EXCEPTION( exception::Unknown() 00191 << exception::user() + "Cannot open file: " + libraw_strerror( ret ) 00192 << exception::filename( _params._filepath ) ); 00193 } 00194 00195 if( const int ret = _rawProcessor.unpack() ) 00196 { 00197 BOOST_THROW_EXCEPTION( exception::Unknown() 00198 << exception::user() + "Cannot unpack file: " + libraw_strerror( ret ) 00199 << exception::filename( _params._filepath ) ); 00200 } 00201 00202 // we should call dcraw_process before thumbnail extraction because for 00203 // some cameras (i.e. Kodak ones) white balance for thumbnal should be set 00204 // from main image settings 00205 00206 // Data unpacking 00207 int ret = 0; 00208 if( _out.document_mode ) 00209 ret = _rawProcessor.dcraw_document_mode_processing(); 00210 else 00211 ret = _rawProcessor.dcraw_process(); 00212 00213 if( LIBRAW_SUCCESS != ret ) 00214 { 00215 if( LIBRAW_FATAL_ERROR( ret ) ) 00216 { 00217 BOOST_THROW_EXCEPTION( exception::Unknown() 00218 << exception::user() + "Cannot do postprocessing: " + libraw_strerror( ret ) 00219 << exception::filename( _params._filepath ) ); 00220 } 00221 else 00222 { 00223 TUTTLE_LOG_ERROR( "Error on postprocessing (" << quotes(_params._filepath) << "): " << libraw_strerror( ret ) ); 00224 TUTTLE_LOG_ERROR( "Try to continue..." ); 00225 } 00226 } 00227 // libraw_processed_image_t* image = _rawProcessor.dcraw_make_mem_image( &ret ); 00228 // if( ! image ) 00229 // { 00230 // TUTTLE_LOG_ERROR( "Cannot unpack " << filepath << " to memory buffer: " << libraw_strerror( ret ) ); 00231 // return dst; 00232 // } 00233 00234 // int ret = _rawProcessor.dcraw_document_mode_processing(); 00235 // if( LIBRAW_SUCCESS != ret ) 00236 // { 00237 // TUTTLE_LOG_ERROR( "Cannot do document_mode_processing on " << filepath << " : " << libraw_strerror( ret ) ); 00238 // if( LIBRAW_FATAL_ERROR( ret ) ) 00239 // return dst; 00240 // } 00241 00242 // The metadata are accessible through data fields of the class 00243 TUTTLE_TLOG( TUTTLE_INFO, "Image size: " << _rawProcessor.imgdata.sizes.width << ", " << _rawProcessor.imgdata.sizes.height ); 00244 00245 // TUTTLE_LOG_VAR2( image->width, image->height ); 00246 TUTTLE_TLOG_VAR2( TUTTLE_INFO, _rawProcessor.imgdata.sizes.width, _rawProcessor.imgdata.sizes.height ); 00247 00248 // // And let us print its dump; the data are accessible through data fields of the class 00249 // for( int i = 0; 00250 // i < _rawProcessor.imgdata.sizes.iwidth * _rawProcessor.imgdata.sizes.iheight; 00251 // ++i ) 00252 // TUTTLE_LOG( "i=" << i << 00253 // " R=" << _rawProcessor.imgdata.image[i][0] << 00254 // " G=" << _rawProcessor.imgdata.image[i][1] << 00255 // " B=" << _rawProcessor.imgdata.image[i][2] << 00256 // " G2=" << _rawProcessor.imgdata.image[i][3] 00257 // ); 00258 00259 typedef boost::gil::rgba16c_view_t RawView; 00260 typedef RawView::value_type RawPixel; 00261 RawView imageView = interleaved_view( _size.width, _size.height, //image->width, image->height, 00262 (const RawPixel*)( _rawProcessor.imgdata.image /*image->data*/ ), 00263 _size.width /*image->width*/ * sizeof( RawPixel ) /*image->data_size*/ ); 00264 00265 View dst = this->_dstView; 00266 TUTTLE_LOG_VAR( TUTTLE_INFO, sizeof( RawPixel ) ); 00267 TUTTLE_LOG_VAR2( TUTTLE_INFO, imageView.dimensions().x, imageView.dimensions().y ); 00268 TUTTLE_LOG_VAR2( TUTTLE_INFO, dst.dimensions().x, dst.dimensions().y ); 00269 copy_and_convert_pixels( imageView, dst ); 00270 // free( image ); 00271 _rawProcessor.recycle(); 00272 } 00273 catch( boost::exception& e ) 00274 { 00275 e << exception::filename( _params._filepath ); 00276 TUTTLE_LOG_ERROR( boost::diagnostic_information( e ) ); 00277 // throw; 00278 } 00279 catch( ... ) 00280 { 00281 // BOOST_THROW_EXCEPTION( exception::Unknown() 00282 // << exception::user( "Unable to write image") 00283 // << exception::filename(filepath) ); 00284 TUTTLE_LOG_ERROR( boost::current_exception_diagnostic_information() ); 00285 } 00286 } 00287 00288 } 00289 } 00290 } 00291 }