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