TuttleOFX
1
|
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 }