TuttleOFX  1
RawReaderPlugin.cpp
Go to the documentation of this file.
00001 #include "RawReaderPlugin.hpp"
00002 #include "RawReaderProcess.hpp"
00003 #include "RawReaderDefinitions.hpp"
00004 
00005 #include <libraw/libraw.h>
00006 
00007 #include <boost/gil/gil_all.hpp>
00008 #include <boost/filesystem.hpp>
00009 
00010 namespace tuttle {
00011 namespace plugin {
00012 namespace raw {
00013 namespace reader {
00014 
00015 namespace bfs = boost::filesystem;
00016 using namespace boost::gil;
00017 
00018 RawReaderPlugin::RawReaderPlugin( OfxImageEffectHandle handle )
00019         : ReaderPlugin( handle )
00020 {
00021         _paramFiltering     = fetchChoiceParam( kParamFiltering );
00022         _paramInterpolation = fetchChoiceParam( kParamInterpolation );
00023         
00024         _paramGreyboxPoint = fetchDouble2DParam( kParamGreyboxPoint );
00025         _paramGreyboxSize  = fetchDouble2DParam( kParamGreyboxSize );
00026         
00027         _paramGammaPower = fetchDoubleParam( kParamGammaPower );
00028         _paramGammaToe   = fetchDoubleParam( kParamGammaToe );
00029         _paramRedAbber   = fetchDoubleParam( kParamRedAbber );
00030         _paramBlueAbber = fetchDoubleParam( kParamBlueAbber );
00031         
00032         _paramBright     = fetchDoubleParam( kParamBright );
00033         _paramThreshold  = fetchDoubleParam( kParamThreshold );
00034         
00035         _paramFourColorRgb = fetchBooleanParam( kParamFourColorRgb );
00036         _paramDocumentMode = fetchChoiceParam( kParamDocumentMode );
00037         
00038         _paramExposure         = fetchDoubleParam( kParamExposure );
00039         _paramExposurePreserve = fetchDoubleParam( kParamExposurePreserve );
00040         
00041         _paramWhiteBalance     = fetchChoiceParam( kParamWhiteBalance );
00042         
00043         _paramHighlight = fetchChoiceParam( kParamHighlight ) ;
00044         
00045         // metadatas
00046         _paramManufacturer   = fetchStringParam( kParamManufacturer );
00047         _paramModel          = fetchStringParam( kParamModel );
00048         _paramIso            = fetchIntParam   ( kParamIso );
00049         _paramShutter        = fetchIntParam   ( kParamShutter );
00050         _paramAperture       = fetchDoubleParam( kParamAperture );
00051         _paramDateOfShooting = fetchStringParam( kParamDateOfShooting );
00052         _paramGPS            = fetchStringParam( kParamGPS );
00053         _paramDesc           = fetchStringParam( kParamDesc );
00054         _paramArtist         = fetchStringParam( kParamArtist );
00055 }
00056 
00057 RawReaderProcessParams<RawReaderPlugin::Scalar> RawReaderPlugin::getProcessParams( const OfxTime time )
00058 {
00059         RawReaderProcessParams<Scalar> params;
00060 
00061         params._filepath      = getAbsoluteFilenameAt( time );
00062         params._filtering     = static_cast<EFiltering>( _paramFiltering->getValue() );
00063         params._interpolation = static_cast<EInterpolation>( _paramInterpolation->getValue() );
00064         
00065         params._gammaPower = _paramGammaPower->getValue();
00066         params._gammaToe   = _paramGammaToe->getValue();
00067         params._redAbber   = _paramRedAbber->getValue();
00068         params._blueAbber = _paramBlueAbber->getValue();
00069         
00070         params._bright     = _paramBright->getValue();
00071         params._threshold  = _paramThreshold->getValue();
00072         
00073         params._fourColorRgb = _paramFourColorRgb->getValue();
00074         params._documentMode = static_cast<EDocumentMode>( _paramDocumentMode->getValue() );
00075         
00076         params._greyboxPoint.x = _paramGreyboxPoint->getValue().x;
00077         params._greyboxPoint.y = _paramGreyboxPoint->getValue().y;
00078         
00079         params._greyboxSize.x = _paramGreyboxSize->getValue().x;
00080         params._greyboxSize.y = _paramGreyboxSize->getValue().y;
00081         
00082         params._exposure         = _paramExposure->getValue();
00083         params._exposurePreserve = _paramExposurePreserve->getValue();
00084         
00085         params._whiteBalance     = static_cast<EWhiteBalance>( _paramWhiteBalance->getValue() );
00086         
00087         params._hightlight = static_cast<EHighlight>( _paramHighlight->getValue() );
00088         
00089         return params;
00090 }
00091 
00092 void RawReaderPlugin::updateInfos( const OfxTime time )
00093 {
00094         RawReaderProcessParams<Scalar> params = getProcessParams( time );
00095 
00096         LibRaw rawProcessor;
00097         libraw_iparams_t& p1          = rawProcessor.imgdata.idata;
00098         libraw_image_sizes_t& sizes   = rawProcessor.imgdata.sizes;
00099         libraw_colordata_t& color     = rawProcessor.imgdata.color;
00100         libraw_thumbnail_t& thumbnail = rawProcessor.imgdata.thumbnail;
00101         libraw_imgother_t& p2         = rawProcessor.imgdata.other;
00102         //      libraw_output_params_t& out = rawProcessor.imgdata.params;
00103 
00104         if( const int ret = rawProcessor.open_file( params._filepath.c_str() ) )
00105         {
00106                 BOOST_THROW_EXCEPTION( exception::FileNotExist()
00107                         << exception::user( "RAW: Unable to open file" )
00108                         << exception::dev( libraw_strerror( ret ) )
00109                         << exception::filename( params._filepath ) );
00110         }
00111         if( const int ret = rawProcessor.adjust_sizes_info_only() )
00112         {
00113                 BOOST_THROW_EXCEPTION( exception::FileInSequenceNotExist()
00114                         << exception::user( "RAW: Cannot decode infos for file" )
00115                         << exception::dev( libraw_strerror( ret ) )
00116                         << exception::filename( params._filepath ) );
00117         }
00118 
00119         _paramManufacturer->setValue( p1.make );
00120         _paramModel->setValue( p1.model );
00121         _paramIso->setValue( (int) p2.iso_speed );
00122         
00123         if( p2.shutter > 0 && p2.shutter < 1 )
00124                 p2.shutter = 1 / p2.shutter;
00125         _paramShutter->setValue( p2.shutter );
00126         _paramAperture->setValue( p2.aperture );
00127         _paramDateOfShooting->setValue( ctime( &( p2.timestamp ) ) );
00128         
00129         if( p2.gpsdata[0] )
00130                 _paramGPS->setValue( (const char*)p2.gpsdata );
00131         if( p2.desc[0] )
00132                 _paramDesc->setValue( p2.desc );
00133         if( p2.artist[0] )
00134                 _paramArtist->setValue( p2.artist );
00135         
00136         std::ostringstream ss;
00137 
00138         ss << "Filename: " << params._filepath << "\n";
00139         ss << "Timestamp: " << ctime( &( p2.timestamp ) ) << "\n";
00140         ss << "Camera: " << p1.make << " " << p1.model << "\n";
00141         if( p2.artist[0] )
00142                 ss << "Owner: " << p2.artist << "\n";
00143         if( p1.dng_version )
00144         {
00145                 ss << "DNG Version: ";
00146                 for( int i = 24; i >= 0; i -= 8 )
00147                         ss << ( p1.dng_version >> i & 255 ) << ( i ? '.' : '\n' );
00148                 ss << "\n";
00149         }
00150 
00151         ss << "ISO speed: " << (int) p2.iso_speed << "\n";
00152         ss << "Shutter: ";
00153         /*if( p2.shutter > 0 && p2.shutter < 1 )
00154                 p2.shutter = 1 / p2.shutter;*/
00155         ss << p2.shutter << " sec" << "\n"; // %0.1f
00156         ss << "Aperture: f/" << p2.aperture << "\n";
00157         ss << "Focal length: " << p2.focal_len << " mm" << "\n";
00158         if( color.profile )
00159                 ss << "Embedded ICC profile: yes, " << color.profile_length << " bytes" << "\n";
00160         else
00161                 ss << "Embedded ICC profile: no" << "\n";
00162 
00163         ss << "Number of raw images: " << p1.raw_count;
00164         if( sizes.pixel_aspect != 1 )
00165                 ss << "Pixel Aspect Ratio: " << sizes.pixel_aspect << "\n";
00166         if( thumbnail.tlength )
00167                 ss << "Thumb size:  " << thumbnail.twidth << " x " << thumbnail.theight << "\n";
00168         ss << "Full size:   " << sizes.raw_width << " x " << sizes.raw_height << "\n";
00169 
00170         ss << "Image size:  " << sizes.width << " x " << sizes.height << "\n";
00171         ss << "Output size: " << sizes.iwidth << " x " << sizes.iheight << "\n";
00172         ss << "Raw colors: " << p1.colors << "\n";
00173         if( p1.filters )
00174         {
00175                 ss << "Filter pattern: ";
00176                 if( !p1.cdesc[3] )
00177                         p1.cdesc[3] = 'G';
00178                 for( int i = 0; i < 16; ++i )
00179                         putchar( p1.cdesc[rawProcessor.fc( i >> 1, i & 1 )] );
00180                 ss << "\n";
00181         }
00182         ss << "Daylight multipliers: ";
00183         for( int c = 0; c < p1.colors; ++c )
00184                 ss << " " << color.pre_mul[c];
00185         ss << "\n";
00186         if( color.cam_mul[0] > 0 )
00187         {
00188                 ss << "Camera multipliers: ";
00189                 for( int c = 0; c < 4; ++c )
00190                         ss << " " << color.cam_mul[c];
00191                 ss << "\n";
00192         }
00193         const char* csl[] = { "U", "I", "CO", "L", "CA" };
00194         ss << "Color sources /Legend: (U)nknown, (I)nit, (CO)nstant, (L)oaded, (CA)lculated/:" << "\n";
00195         ss << "\tcurve=" << csl[color.color_flags.curve_state] << ",";
00196         ss << " rgb_cam=" << csl[color.color_flags.rgb_cam_state] << ",";
00197         ss << " cmatrix=" << csl[color.color_flags.cmatrix_state] << ",";
00198         ss << " pre_mul=" << csl[color.color_flags.pre_mul_state] << ",";
00199         ss << " cam_mul=" << csl[color.color_flags.cam_mul_state] << "\n";
00200         ss << "Cam->XYZ matrix:" << "\n";
00201         for( int i = 0; i < 4; ++i )
00202                 ss << color.cam_xyz[i][0] << "\t" << color.cam_xyz[i][1] << "\t" << color.cam_xyz[i][2] << "\n"; // %6.4f
00203 
00204         TUTTLE_LOG_DEBUG( TUTTLE_INFO, ss );
00205 }
00206 
00207 void RawReaderPlugin::changedParam( const OFX::InstanceChangedArgs& args, const std::string& paramName )
00208 {
00209 //      else if( paramName == kRawReaderUpdateInfosButton )
00210 //      {
00211 //              updateInfos();
00212 //      }
00213 //      else
00214 //      {
00215         ReaderPlugin::changedParam( args, paramName );
00216 //      }
00217 }
00218 
00219 bool RawReaderPlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod )
00220 {
00221         updateInfos( args.time );
00222 
00223         RawReaderProcessParams<Scalar> params = getProcessParams( args.time );
00224 
00225         LibRaw rawProcessor;
00226         libraw_image_sizes_t& sizes = rawProcessor.imgdata.sizes;
00227         //libraw_output_params_t& out = rawProcessor.imgdata.params;
00228         //      out.half_size  = 1;
00229 
00230         if( rawProcessor.open_file( params._filepath.c_str() ) )
00231         {
00232                 BOOST_THROW_EXCEPTION( exception::FileNotExist()
00233                         << exception::user( "RAW: Unable to open file" )
00234                         << exception::filename( params._filepath ) );
00235         }
00236         if( rawProcessor.adjust_sizes_info_only() )
00237         {
00238                 BOOST_THROW_EXCEPTION( exception::File()
00239                         << exception::user( "RAW: Cannot decode infos" )
00240                         << exception::filename( params._filepath ) );
00241         }
00242 
00243         //      point2<ptrdiff_t> dims( sizes.raw_width, sizes.raw_height );
00244         point2<ptrdiff_t> dims( sizes.width, sizes.height );
00245         //TUTTLE_LOG_VAR( TUTTLE_INFO, dims );
00246         rod.x1 = 0;
00247         rod.x2 = dims.x * this->_clipDst->getPixelAspectRatio();
00248         rod.y1 = 0;
00249         rod.y2 = dims.y;
00250         return true;
00251 }
00252 
00253 void RawReaderPlugin::getClipPreferences( OFX::ClipPreferencesSetter& clipPreferences )
00254 {
00255         ReaderPlugin::getClipPreferences( clipPreferences );
00256 //      const std::string filename( getAbsoluteFirstFilename() );
00257         if( getExplicitBitDepthConversion() == eParamReaderBitDepthAuto )
00258         {
00259                 OFX::EBitDepth bd = OFX::eBitDepthNone;
00260                 int bitDepth      = 32;    //raw_read_precision( filename );
00261                 switch( bitDepth )
00262                 {
00263                         case 8:
00264                                 bd = OFX::eBitDepthUByte;
00265                                 break;
00266                         case 16:
00267                                 bd = OFX::eBitDepthUShort;
00268                                 break;
00269                         case 32:
00270                                 bd = OFX::eBitDepthFloat;
00271                                 break;
00272                         default:
00273                                 BOOST_THROW_EXCEPTION( exception::ImageFormat() );
00274                 }
00275                 clipPreferences.setClipBitDepth( *this->_clipDst, bd );
00276         }
00277         clipPreferences.setClipComponents( *this->_clipDst, OFX::ePixelComponentRGBA );
00278         clipPreferences.setPixelAspectRatio( *this->_clipDst, 1.0 );
00279 }
00280 
00281 /**
00282  * @brief The overridden render function
00283  * @param[in]   args     Rendering parameters
00284  */
00285 void RawReaderPlugin::render( const OFX::RenderArguments& args )
00286 {
00287         ReaderPlugin::render( args );
00288         doGilRender<RawReaderProcess>( *this, args );
00289 }
00290 
00291 }
00292 }
00293 }
00294 }