diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index e3b91ceff..80b0f8b9c 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -247,7 +247,7 @@ void DFManager::init( Glib::ustring pathname ) return; } -dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ) +dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ,bool pool ) { Glib::RefPtr file = Gio::File::create_for_path(filename); if (!file ) @@ -261,6 +261,12 @@ dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ) RawImage ri(filename); int res = ri.loadRaw(false); // Read informations about shot if( !res ){ + dfList_t::iterator iter; + if(!pool){ + dfInfo n(filename,"","",0,0,0); + iter = dfList.insert(std::pair< std::string,dfInfo>( "", n ) ); + return &(iter->second); + } RawMetaDataLocation rml; rml.exifBase = ri.get_exifBase(); rml.ciffBase = ri.get_ciffBase(); @@ -268,7 +274,7 @@ dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ) ImageData idata(filename, &rml); /* Files are added in the map, divided by same maker/model,ISO and shutter*/ std::string key( dfInfo::key(idata.getMake(), idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed()) ); - dfList_t::iterator iter = dfList.find( key ); + iter = dfList.find( key ); if( iter == dfList.end() ){ dfInfo n(filename, idata.getMake(), idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed(), idata.getDateTimeAsTS() ); iter = dfList.insert(std::pair< std::string,dfInfo>( key,n ) ); @@ -356,7 +362,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename ) if( iter->second.pathname.compare( filename )==0 ) return iter->second.getRawImage(); } - dfInfo *df = addFileInfo( filename ); + dfInfo *df = addFileInfo( filename, false ); if(df) return df->getRawImage(); return 0; diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h index 16b9d4e88..9d2b2a53f 100644 --- a/rtengine/dfmanager.h +++ b/rtengine/dfmanager.h @@ -84,7 +84,7 @@ protected: bpList_t bpList; bool initialized; Glib::ustring currentPath; - dfInfo *addFileInfo(const Glib::ustring &filename ); + dfInfo *addFileInfo(const Glib::ustring &filename, bool pool=true ); dfInfo *find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t ); int scanBadPixelsFile( Glib::ustring filename ); }; diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 061b9eaeb..a9454167d 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -36,8 +36,9 @@ inline ffInfo& ffInfo::operator =(const ffInfo &o){ pathname = o.pathname; maker = o.maker; model = o.model; - iso = o.iso; + lens = o.lens; shutter = o.shutter; + focallength = o.focallength; timestamp = o.timestamp; if( ri ){ delete ri; @@ -52,37 +53,39 @@ bool ffInfo::operator <(const ffInfo &e2) const return false; if( this->model.compare( e2.model) >=0 ) return false; - if( this->iso >= e2.iso ) + if( this->lens.compare( e2.lens) >=0 ) return false; - if( this->shutter >= e2.shutter ) + if( this->focallength >= e2.focallength ) return false; if( this->timestamp >= e2.timestamp ) return false; return true; } -std::string ffInfo::key(const std::string &mak, const std::string &mod, int iso, double shut, double apert ) +std::string ffInfo::key(const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert ) { std::ostringstream s; s << mak << " " << mod << " "; s.width(5); - s << iso << "ISO "; + s << len << " "; s.precision( 2 ); s.width(4); - s << shut << "s"; + s << focal << "mm F" << apert; return s.str(); } -double ffInfo::distance(const std::string &mak, const std::string &mod, int iso, double shutter, double aperture) const +double ffInfo::distance(const std::string &mak, const std::string &mod, const std::string &len, double focallength, double aperture) const { if( this->maker.compare( mak) != 0 ) return INFINITY; if( this->model.compare( mod) != 0 ) return INFINITY; + if( this->lens.compare( len) != 0 ) + return INFINITY; double dAperture = 2*(log(this->aperture) - log(aperture))/log(2);//more important for vignette - double dISO = (log(this->iso/100.) - log(iso/100.))/log(2);//more important for PRNU - //double dShutter = (log(this->shutter) - log(shutter))/log(2); - return sqrt( dISO*dISO + dAperture*dAperture); + double dfocallength = (log(this->focallength/100.) - log(focallength/100.))/log(2);//more important for PRNU + + return sqrt( dfocallength*dfocallength + dAperture*dAperture); } RawImage* ffInfo::getRawImage() @@ -101,6 +104,8 @@ RawImage* ffInfo::getRawImage() void ffInfo::updateRawImage() { typedef unsigned int acc_t; + // averaging of flatfields if more than one is found matching the same key. + // this may not be necessary, as flatfield is further blurred before being applied to the processed image. if( pathNames.size() >0 ){ std::list::iterator iName = pathNames.begin(); ri = new RawImage(*iName); // First file used also for extra pixels informations (width,height, shutter, filters etc.. ) @@ -201,7 +206,7 @@ void FFManager::init( Glib::ustring pathname ) return; } -ffInfo *FFManager::addFileInfo(const Glib::ustring &filename ) +ffInfo *FFManager::addFileInfo(const Glib::ustring &filename, bool pool ) { Glib::RefPtr file = Gio::File::create_for_path(filename); if (!file ) @@ -215,16 +220,22 @@ ffInfo *FFManager::addFileInfo(const Glib::ustring &filename ) RawImage ri(filename); int res = ri.loadRaw(false); // Read informations about shot if( !res ){ + ffList_t::iterator iter; + if(!pool){ + ffInfo n(filename,"","","",0,0,0); + iter = ffList.insert(std::pair< std::string,ffInfo>( "", n ) ); + return &(iter->second); + } RawMetaDataLocation rml; rml.exifBase = ri.get_exifBase(); rml.ciffBase = ri.get_ciffBase(); rml.ciffLength = ri.get_ciffLen(); ImageData idata(filename, &rml); - /* Files are added in the map, divided by same maker/model,ISO and shutter*/ - std::string key( ffInfo::key(idata.getMake(),idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed(),idata.getFNumber()) ); - ffList_t::iterator iter = ffList.find( key ); + /* Files are added in the map, divided by same maker/model,lens and aperture*/ + std::string key( ffInfo::key(idata.getMake(),idata.getModel(),idata.getLens(),idata.getFocalLen(),idata.getFNumber()) ); + iter = ffList.find( key ); if( iter == ffList.end() ){ - ffInfo n(filename,idata.getMake(),idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed(),idata.getFNumber(),idata.getDateTimeAsTS()); + ffInfo n(filename,idata.getMake(),idata.getModel(),idata.getLens(),idata.getFocalLen(),idata.getFNumber(),idata.getDateTimeAsTS()); iter = ffList.insert(std::pair< std::string,ffInfo>( key,n ) ); }else{ while( iter != ffList.end() && iter->second.key() == key && ABS(iter->second.timestamp - ri.get_timestamp()) >60*60*6 ) // 6 hour difference @@ -233,7 +244,7 @@ ffInfo *FFManager::addFileInfo(const Glib::ustring &filename ) if( iter != ffList.end() ) iter->second.pathNames.push_back( filename ); else{ - ffInfo n(filename,idata.getMake(),idata.getModel(),idata.getISOSpeed(),idata.getShutterSpeed(),idata.getFNumber(),idata.getDateTimeAsTS()); + ffInfo n(filename,idata.getMake(),idata.getModel(),idata.getLens(),idata.getFocalLen(),idata.getFNumber(),idata.getDateTimeAsTS()); iter = ffList.insert(std::pair< std::string,ffInfo>( key,n ) ); } } @@ -259,14 +270,14 @@ void FFManager::getStat( int &totFiles, int &totTemplates) } /* The search for the best match is twofold: - * if perfect matches for iso and aperture are found, then the list is scanned for lesser distance in time - * otherwise if no match is found, the whole list is searched for lesser distance in iso and aperture + * if perfect matches for make and model are found, then the list is scanned for lesser distance in time + * otherwise if no match is found, the whole list is searched for lesser distance in lens and aperture */ -ffInfo* FFManager::find( const std::string &mak, const std::string &mod, int isospeed, double shut, double apert, time_t t ) +ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ) { if( ffList.size() == 0 ) return 0; - std::string key( ffInfo::key(mak,mod,isospeed,shut,apert) ); + std::string key( ffInfo::key(mak,mod,len,focal,apert) ); ffList_t::iterator iter = ffList.find( key ); if( iter != ffList.end() ){ @@ -283,9 +294,9 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, int iso }else{ iter = ffList.begin(); ffList_t::iterator bestMatch = iter; - double bestD = iter->second.distance( mak, mod, isospeed, shut, apert ); + double bestD = iter->second.distance( mak, mod, len, focal, apert ); for( iter++; iter != ffList.end();iter++ ){ - double d = iter->second.distance( mak, mod, isospeed, shut, apert ); + double d = iter->second.distance( mak, mod, len, focal, apert ); if( d < bestD ){ bestD = d; bestMatch = iter; @@ -295,9 +306,9 @@ ffInfo* FFManager::find( const std::string &mak, const std::string &mod, int iso } } -RawImage* FFManager::searchFlatField( const std::string &mak, const std::string &mod, int iso, double shut, double apert, time_t t ) +RawImage* FFManager::searchFlatField( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ) { - ffInfo *ff = find( mak, mod, iso, shut, apert, t ); + ffInfo *ff = find( mak, mod, len, focal, apert, t ); if( ff ) return ff->getRawImage(); else @@ -310,7 +321,7 @@ RawImage* FFManager::searchFlatField( const Glib::ustring filename ) if( iter->second.pathname.compare( filename )==0 ) return iter->second.getRawImage(); } - ffInfo *ff = addFileInfo( filename ); + ffInfo *ff = addFileInfo( filename , false); if(ff) return ff->getRawImage(); return 0; diff --git a/rtengine/ffmanager.h b/rtengine/ffmanager.h index 8c51d8527..9be96c3e4 100644 --- a/rtengine/ffmanager.h +++ b/rtengine/ffmanager.h @@ -32,17 +32,19 @@ public: std::list pathNames; // other similar dark frames, used for average std::string maker; ///< manufacturer std::string model; ///< model - int iso; ///< ISO (gain) + std::string lens; ///< lens + int iso; ///< ISO (gain) double shutter; ///< shutter or exposure time in sec double aperture; ///< aperture in stops + double focallength; ///< focal length in mm time_t timestamp; ///< seconds since 1 Jan 1970 - ffInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod,int iso,double shut,double apert,time_t t) - :pathname(name),maker(mak),model(mod),iso(iso),shutter(shut),aperture(apert),timestamp(t),ri(NULL){} + ffInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod,const std::string & len,double focal,double apert,time_t t) + :pathname(name),maker(mak),model(mod),lens(len),focallength(focal),aperture(apert),timestamp(t),ri(NULL){} ffInfo( const ffInfo &o) - :pathname(o.pathname),maker(o.maker),model(o.model),iso(o.iso),shutter(o.shutter),aperture(o.aperture),timestamp(o.timestamp),ri(NULL){} + :pathname(o.pathname),maker(o.maker),model(o.model),lens(o.lens),focallength(o.focallength),aperture(o.aperture),timestamp(o.timestamp),ri(NULL){} ~ffInfo() { if( ri ) delete ri; } @@ -50,10 +52,10 @@ public: bool operator <(const ffInfo &e2) const; // Calculate virtual distance between two shots; different model return infinite - double distance(const std::string &mak, const std::string &mod, int iso, double shutter, double aperture) const; + double distance(const std::string &mak, const std::string &mod, const std::string &lens, double focallength, double aperture) const; - static std::string key(const std::string &mak, const std::string &mod, int iso, double shut, double apert ); - std::string key(){ return key( maker,model,iso,shutter,aperture); } + static std::string key(const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert ); + std::string key(){ return key( maker,model,lens,focallength,aperture); } RawImage *getRawImage(); @@ -69,7 +71,7 @@ public: void init( Glib::ustring pathname ); Glib::ustring getPathname(){ return currentPath; }; void getStat( int &totFiles, int &totTemplate); - RawImage *searchFlatField( const std::string &mak, const std::string &mod, int iso, double shut, double apert, time_t t ); + RawImage *searchFlatField( const std::string &mak, const std::string &mod, const std::string &len, double focallength, double apert, time_t t ); RawImage *searchFlatField( const Glib::ustring filename ); protected: @@ -78,8 +80,8 @@ protected: ffList_t ffList; bool initialized; Glib::ustring currentPath; - ffInfo *addFileInfo(const Glib::ustring &filename ); - ffInfo *find( const std::string &mak, const std::string &mod, int isospeed, double shut, double apert, time_t t ); + ffInfo *addFileInfo(const Glib::ustring &filename, bool pool=true ); + ffInfo *find( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ); }; extern FFManager ffm; diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index f6390f8f4..db3ab0999 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -968,7 +968,7 @@ void RawImageSource::preprocess (const RAWParams &raw) if( raw.ff_file.size()>0) rif = ffm.searchFlatField( raw.ff_file ); } else { - rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getISOSpeed(),idata->getShutterSpeed(), idata->getFNumber(), idata->getDateTimeAsTS()); + rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getLens(),idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS()); } if( rif && settings->verbose) { printf( "Flat Field Correction:%s\n",rif->get_filename().c_str()); diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index 5556603c4..455e43973 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -181,7 +181,7 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd rtengine::RawImage *img = dfp->getDF(); if( img ){ std::ostringstream s; - s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + s << Glib::path_get_basename(img->get_filename()) << ": " <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; dfInfo->set_text( s.str() ); }else{ dfInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); @@ -195,7 +195,7 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd rtengine::RawImage *img = ffp->getFF(); if( img ){ std::ostringstream s; - s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO f/" << img->get_aperture(); + s << Glib::path_get_basename(img->get_filename()) << ": " << "f/" << img->get_aperture(); // !!! need to add focallength in mm and format aperture to ##.# ffInfo->set_text( s.str() ); }else{ ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); @@ -375,7 +375,7 @@ void PreProcess::dfAutoChanged() rtengine::RawImage *img = dfp->getDF(); if( img ){ std::ostringstream s; - s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + s << Glib::path_get_basename(img->get_filename()) << ": " <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; dfInfo->set_text( s.str() ); }else{ dfInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); @@ -483,7 +483,7 @@ void PreProcess::flatFieldAutoSelectChanged() rtengine::RawImage *img = ffp->getFF(); if( img ){ std::ostringstream s; - s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + s << Glib::path_get_basename(img->get_filename()) << ": " << "f/" << img->get_aperture(); // !!! need to add focallength in mm and format aperture to ##.# ffInfo->set_text( s.str() ); }else{ ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index 643b8464b..6bde5ba3c 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -424,11 +424,13 @@ rtengine::RawImage* ToolPanelCoordinator::getFF() int iso = imd->getISOSpeed(); double shutter = imd->getShutterSpeed(); double aperture = imd->getFNumber(); + double focallength = imd->getFocalLen(); std::string maker( imd->getMake() ); std::string model( imd->getModel() ); + std::string lens( imd->getLens() ); time_t timestamp = imd->getDateTimeAsTS(); - return rtengine::ffm.searchFlatField( maker,model,iso,shutter,aperture,timestamp); + return rtengine::ffm.searchFlatField( maker,model,lens,focallength,aperture,timestamp); } return NULL; }