dfmanager cleanup (#6211)
* Turn `DFManager` into a singleton * PIMPL `DFManager` * Cleanup namespace usage in `dfmanager.cc` * Constify `DFManager` interface * Fix bad `reinterpret_cast` between `std::string` and `Glib::ustring` Co-authored-by: Flössie <floessie.mail@gmail.com> Co-authored-by: Thanatomanic <6567747+Thanatomanic@users.noreply.github.com>
This commit is contained in:
parent
d8320bc8b7
commit
f564394bbc
@ -17,28 +17,82 @@
|
||||
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
|
||||
#include <giomm.h>
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include "dfmanager.h"
|
||||
#include "../rtgui/options.h"
|
||||
#include "rawimage.h"
|
||||
|
||||
#include "imagedata.h"
|
||||
#include "jaggedarray.h"
|
||||
#include "noncopyable.h"
|
||||
#include "pixelsmap.h"
|
||||
#include "rawimage.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace rtengine
|
||||
#include "../rtgui/options.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// *********************** class dfInfo **************************************
|
||||
std::string toUppercase(const std::string& string)
|
||||
{
|
||||
return Glib::ustring(string).uppercase();
|
||||
}
|
||||
|
||||
class dfInfo final
|
||||
{
|
||||
public:
|
||||
Glib::ustring pathname; // filename of dark frame
|
||||
std::list<Glib::ustring> pathNames; // other similar dark frames, used for average
|
||||
std::string maker; // manufacturer
|
||||
std::string model; // model
|
||||
int iso; // ISO (gain)
|
||||
double shutter; // shutter or exposure time in sec
|
||||
time_t timestamp; // seconds since 1 Jan 1970
|
||||
|
||||
|
||||
dfInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod, int iso, double shut, time_t t)
|
||||
: pathname(name), maker(mak), model(mod), iso(iso), shutter(shut), timestamp(t), ri(nullptr) {}
|
||||
|
||||
dfInfo(const dfInfo &o)
|
||||
: pathname(o.pathname), maker(o.maker), model(o.model), iso(o.iso), shutter(o.shutter), timestamp(o.timestamp), ri(nullptr) {}
|
||||
~dfInfo();
|
||||
|
||||
dfInfo &operator =(const dfInfo &o);
|
||||
|
||||
// Calculate virtual distance between two shots; different model return infinite
|
||||
double distance(const std::string &mak, const std::string &mod, int iso, double shutter) const;
|
||||
|
||||
static std::string key(const std::string &mak, const std::string &mod, int iso, double shut);
|
||||
std::string key() const
|
||||
{
|
||||
return key(maker, model, iso, shutter);
|
||||
}
|
||||
|
||||
const rtengine::RawImage* getRawImage();
|
||||
const std::vector<rtengine::badPix>& getHotPixels();
|
||||
|
||||
private:
|
||||
rtengine::RawImage* ri; // Dark Frame raw data
|
||||
std::vector<rtengine::badPix> badPixels; // Extracted hot pixels
|
||||
|
||||
void updateBadPixelList(const rtengine::RawImage* df);
|
||||
void updateRawImage();
|
||||
};
|
||||
|
||||
dfInfo::~dfInfo()
|
||||
{
|
||||
delete ri;
|
||||
}
|
||||
|
||||
inline dfInfo& dfInfo::operator =(const dfInfo &o)
|
||||
inline dfInfo& dfInfo::operator = (const dfInfo &o)
|
||||
{
|
||||
if (this != &o) {
|
||||
pathname = o.pathname;
|
||||
@ -48,7 +102,7 @@ inline dfInfo& dfInfo::operator =(const dfInfo &o)
|
||||
shutter = o.shutter;
|
||||
timestamp = o.timestamp;
|
||||
|
||||
if( ri ) {
|
||||
if (ri) {
|
||||
delete ri;
|
||||
ri = nullptr;
|
||||
}
|
||||
@ -57,38 +111,13 @@ inline dfInfo& dfInfo::operator =(const dfInfo &o)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool dfInfo::operator <(const dfInfo &e2) const
|
||||
{
|
||||
if( this->maker.compare( e2.maker) >= 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->model.compare( e2.model) >= 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->iso >= e2.iso ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->shutter >= e2.shutter ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if( this->timestamp >= e2.timestamp ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string dfInfo::key(const std::string &mak, const std::string &mod, int iso, double shut )
|
||||
std::string dfInfo::key(const std::string &mak, const std::string &mod, int iso, double shut)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod << " ";
|
||||
s.width(5);
|
||||
s << iso << "ISO ";
|
||||
s.precision( 2 );
|
||||
s.precision(2);
|
||||
s.width(4);
|
||||
s << shut << "s";
|
||||
return s.str();
|
||||
@ -96,115 +125,106 @@ std::string dfInfo::key(const std::string &mak, const std::string &mod, int iso,
|
||||
|
||||
double dfInfo::distance(const std::string &mak, const std::string &mod, int iso, double shutter) const
|
||||
{
|
||||
if( this->maker.compare( mak) != 0 ) {
|
||||
if (this->maker.compare(mak) != 0) {
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
if( this->model.compare( mod) != 0 ) {
|
||||
if (this->model.compare(mod) != 0) {
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
double dISO = (log(this->iso / 100.) - log(iso / 100.)) / log(2);
|
||||
double dShutter = (log(this->shutter) - log(shutter)) / log(2);
|
||||
return sqrt( dISO * dISO + dShutter * dShutter);
|
||||
const double dISO = (log(this->iso / 100.) - log(iso / 100.)) / log(2);
|
||||
const double dShutter = (log(this->shutter) - log(shutter)) / log(2);
|
||||
return std::sqrt(dISO * dISO + dShutter * dShutter);
|
||||
}
|
||||
|
||||
RawImage* dfInfo::getRawImage()
|
||||
const rtengine::RawImage* dfInfo::getRawImage()
|
||||
{
|
||||
if(ri) {
|
||||
if (ri) {
|
||||
return ri;
|
||||
}
|
||||
|
||||
updateRawImage();
|
||||
updateBadPixelList( ri );
|
||||
updateBadPixelList(ri);
|
||||
|
||||
return ri;
|
||||
}
|
||||
|
||||
std::vector<badPix>& dfInfo::getHotPixels()
|
||||
const std::vector<rtengine::badPix>& dfInfo::getHotPixels()
|
||||
{
|
||||
if( !ri ) {
|
||||
if (!ri) {
|
||||
updateRawImage();
|
||||
updateBadPixelList( ri );
|
||||
updateBadPixelList(ri);
|
||||
}
|
||||
|
||||
return badPixels;
|
||||
}
|
||||
|
||||
/* updateRawImage() load into ri the actual pixel data from pathname if there is a single shot
|
||||
* otherwise load each file from the pathNames list and extract a template from the media;
|
||||
* the first file is used also for reading all information other than pixels
|
||||
*/
|
||||
void dfInfo::updateRawImage()
|
||||
{
|
||||
typedef unsigned int acc_t;
|
||||
|
||||
if( !pathNames.empty() ) {
|
||||
std::list<Glib::ustring>::iterator iName = pathNames.begin();
|
||||
ri = new RawImage(*iName); // First file used also for extra pixels information (width,height, shutter, filters etc.. )
|
||||
if (!pathNames.empty()) {
|
||||
std::list<Glib::ustring>::const_iterator iName = pathNames.begin();
|
||||
ri = new rtengine::RawImage(*iName); // First file used also for extra pixels information (width,height, shutter, filters etc.. )
|
||||
|
||||
if( ri->loadRaw(true)) {
|
||||
if (ri->loadRaw(true)) {
|
||||
delete ri;
|
||||
ri = nullptr;
|
||||
} else {
|
||||
int H = ri->get_height();
|
||||
int W = ri->get_width();
|
||||
const int H = ri->get_height();
|
||||
const int W = ri->get_width();
|
||||
ri->compress_image(0);
|
||||
int rSize = W * ((ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS) ? 1 : 3);
|
||||
acc_t **acc = new acc_t*[H];
|
||||
|
||||
for( int row = 0; row < H; row++) {
|
||||
acc[row] = new acc_t[rSize ];
|
||||
}
|
||||
const int rSize = W * ((ri->getSensorType() == rtengine::ST_BAYER || ri->getSensorType() == rtengine::ST_FUJI_XTRANS) ? 1 : 3);
|
||||
rtengine::JaggedArray<float> acc(W, H);
|
||||
|
||||
// copy first image into accumulators
|
||||
for (int row = 0; row < H; row++)
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < rSize; col++) {
|
||||
acc[row][col] = ri->data[row][col];
|
||||
}
|
||||
}
|
||||
|
||||
int nFiles = 1; // First file data already loaded
|
||||
|
||||
for( ++iName; iName != pathNames.end(); ++iName) {
|
||||
RawImage* temp = new RawImage(*iName);
|
||||
for (++iName; iName != pathNames.end(); ++iName) {
|
||||
rtengine::RawImage temp(*iName);
|
||||
|
||||
if( !temp->loadRaw(true)) {
|
||||
temp->compress_image(0); //\ TODO would be better working on original, because is temporary
|
||||
if (!temp.loadRaw(true)) {
|
||||
temp.compress_image(0); //\ TODO would be better working on original, because is temporary
|
||||
nFiles++;
|
||||
|
||||
if( ri->getSensorType() == ST_BAYER || ri->getSensorType() == ST_FUJI_XTRANS ) {
|
||||
for( int row = 0; row < H; row++) {
|
||||
for( int col = 0; col < W; col++) {
|
||||
acc[row][col] += temp->data[row][col];
|
||||
if (ri->getSensorType() == rtengine::ST_BAYER || ri->getSensorType() == rtengine::ST_FUJI_XTRANS) {
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
acc[row][col] += temp.data[row][col];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for( int row = 0; row < H; row++) {
|
||||
for( int col = 0; col < W; col++) {
|
||||
acc[row][3 * col + 0] += temp->data[row][3 * col + 0];
|
||||
acc[row][3 * col + 1] += temp->data[row][3 * col + 1];
|
||||
acc[row][3 * col + 2] += temp->data[row][3 * col + 2];
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < W; col++) {
|
||||
acc[row][3 * col + 0] += temp.data[row][3 * col + 0];
|
||||
acc[row][3 * col + 1] += temp.data[row][3 * col + 1];
|
||||
acc[row][3 * col + 2] += temp.data[row][3 * col + 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete temp;
|
||||
}
|
||||
|
||||
const float factor = 1.f / nFiles;
|
||||
for (int row = 0; row < H; row++) {
|
||||
for (int col = 0; col < rSize; col++) {
|
||||
ri->data[row][col] = acc[row][col] / nFiles;
|
||||
ri->data[row][col] = acc[row][col] * factor;
|
||||
}
|
||||
|
||||
delete [] acc[row];
|
||||
}
|
||||
|
||||
delete [] acc;
|
||||
}
|
||||
} else {
|
||||
ri = new RawImage(pathname);
|
||||
ri = new rtengine::RawImage(pathname);
|
||||
|
||||
if( ri->loadRaw(true)) {
|
||||
if (ri->loadRaw(true)) {
|
||||
delete ri;
|
||||
ri = nullptr;
|
||||
} else {
|
||||
@ -213,35 +233,36 @@ void dfInfo::updateRawImage()
|
||||
}
|
||||
}
|
||||
|
||||
void dfInfo::updateBadPixelList( RawImage *df )
|
||||
void dfInfo::updateBadPixelList(const rtengine::RawImage *df)
|
||||
{
|
||||
if(!df) {
|
||||
if (!df) {
|
||||
return;
|
||||
}
|
||||
const float threshold = 10.f / 8.f;
|
||||
constexpr float threshold = 10.f / 8.f;
|
||||
|
||||
if( df->getSensorType() == ST_BAYER || df->getSensorType() == ST_FUJI_XTRANS ) {
|
||||
std::vector<badPix> badPixelsTemp;
|
||||
if (df->getSensorType() == rtengine::ST_BAYER || df->getSensorType() == rtengine::ST_FUJI_XTRANS) {
|
||||
std::vector<rtengine::badPix> badPixelsTemp;
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel
|
||||
#endif
|
||||
{
|
||||
std::vector<badPix> badPixelsThread;
|
||||
std::vector<rtengine::badPix> badPixelsThread;
|
||||
#ifdef _OPENMP
|
||||
#pragma omp for nowait
|
||||
#endif
|
||||
|
||||
for( int row = 2; row < df->get_height() - 2; row++)
|
||||
for( int col = 2; col < df->get_width() - 2; col++) {
|
||||
float m = (df->data[row - 2][col - 2] + df->data[row - 2][col] + df->data[row - 2][col + 2] +
|
||||
for (int row = 2; row < df->get_height() - 2; ++row) {
|
||||
for (int col = 2; col < df->get_width() - 2; ++col) {
|
||||
const float m = df->data[row - 2][col - 2] + df->data[row - 2][col] + df->data[row - 2][col + 2] +
|
||||
df->data[row][col - 2] + df->data[row][col + 2] +
|
||||
df->data[row + 2][col - 2] + df->data[row + 2][col] + df->data[row + 2][col + 2]);
|
||||
df->data[row + 2][col - 2] + df->data[row + 2][col] + df->data[row + 2][col + 2];
|
||||
|
||||
if( df->data[row][col] > m * threshold ) {
|
||||
if (df->data[row][col] > m * threshold) {
|
||||
badPixelsThread.emplace_back(col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp critical
|
||||
@ -250,48 +271,78 @@ void dfInfo::updateBadPixelList( RawImage *df )
|
||||
}
|
||||
badPixels.insert(badPixels.end(), badPixelsTemp.begin(), badPixelsTemp.end());
|
||||
} else {
|
||||
for( int row = 1; row < df->get_height() - 1; row++)
|
||||
for( int col = 1; col < df->get_width() - 1; col++) {
|
||||
for (int row = 1; row < df->get_height() - 1; ++row) {
|
||||
for (int col = 1; col < df->get_width() - 1; ++col) {
|
||||
float m[3];
|
||||
|
||||
for( int c = 0; c < 3; c++) {
|
||||
m[c] = (df->data[row - 1][3 * (col - 1) + c] + df->data[row - 1][3 * col + c] + df->data[row - 1][3 * (col + 1) + c] +
|
||||
for (int c = 0; c < 3; c++) {
|
||||
m[c] = df->data[row - 1][3 * (col - 1) + c] + df->data[row - 1][3 * col + c] + df->data[row - 1][3 * (col + 1) + c] +
|
||||
df->data[row] [3 * (col - 1) + c] + df->data[row] [3 * col + c] +
|
||||
df->data[row + 1][3 * (col - 1) + c] + df->data[row + 1][3 * col + c] + df->data[row + 1][3 * (col + 1) + c]);
|
||||
df->data[row + 1][3 * (col - 1) + c] + df->data[row + 1][3 * col + c] + df->data[row + 1][3 * (col + 1) + c];
|
||||
}
|
||||
|
||||
if( df->data[row][3 * col] > m[0]*threshold || df->data[row][3 * col + 1] > m[1]*threshold || df->data[row][3 * col + 2] > m[2]*threshold) {
|
||||
if (df->data[row][3 * col] > m[0]*threshold || df->data[row][3 * col + 1] > m[1]*threshold || df->data[row][3 * col + 2] > m[2]*threshold) {
|
||||
badPixels.emplace_back(col, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( settings->verbose ) {
|
||||
if (rtengine::settings->verbose) {
|
||||
std::cout << "Extracted " << badPixels.size() << " pixels from darkframe:" << df->get_filename().c_str() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************* class DFManager *********************************
|
||||
}
|
||||
|
||||
void DFManager::init(const Glib::ustring& pathname)
|
||||
class rtengine::DFManager::Implementation final :
|
||||
public NonCopyable
|
||||
{
|
||||
public:
|
||||
void init(const Glib::ustring& pathname);
|
||||
Glib::ustring getPathname() const
|
||||
{
|
||||
return currentPath;
|
||||
};
|
||||
void getStat(int& totFiles, int& totTemplates) const;
|
||||
const RawImage* searchDarkFrame(const std::string& mak, const std::string& mod, int iso, double shut, time_t t);
|
||||
const RawImage* searchDarkFrame(const Glib::ustring& filename);
|
||||
const std::vector<badPix>* getHotPixels(const std::string& mak, const std::string& mod, int iso, double shut, time_t t);
|
||||
const std::vector<badPix>* getHotPixels(const Glib::ustring& filename);
|
||||
const std::vector<badPix>* getBadPixels(const std::string& mak, const std::string& mod, const std::string& serial) const;
|
||||
|
||||
private:
|
||||
typedef std::multimap<std::string, dfInfo> dfList_t;
|
||||
typedef std::map<std::string, std::vector<badPix> > bpList_t;
|
||||
dfList_t dfList;
|
||||
bpList_t bpList;
|
||||
bool initialized;
|
||||
Glib::ustring currentPath;
|
||||
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(const Glib::ustring &filename);
|
||||
};
|
||||
|
||||
|
||||
void rtengine::DFManager::Implementation::init(const Glib::ustring& pathname)
|
||||
{
|
||||
if (pathname.empty()) {
|
||||
return;
|
||||
}
|
||||
std::vector<Glib::ustring> names;
|
||||
|
||||
auto dir = Gio::File::create_for_path (pathname);
|
||||
const auto dir = Gio::File::create_for_path(pathname);
|
||||
if (!dir || !dir->query_exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
auto enumerator = dir->enumerate_children ("standard::name");
|
||||
const auto enumerator = dir->enumerate_children("standard::name");
|
||||
|
||||
while (auto file = enumerator->next_file ()) {
|
||||
names.emplace_back (Glib::build_filename (pathname, file->get_name ()));
|
||||
while (const auto file = enumerator->next_file()) {
|
||||
names.emplace_back(Glib::build_filename(pathname, file->get_name()));
|
||||
}
|
||||
|
||||
} catch (Glib::Exception&) {}
|
||||
@ -299,40 +350,40 @@ void DFManager::init(const Glib::ustring& pathname)
|
||||
dfList.clear();
|
||||
bpList.clear();
|
||||
|
||||
for (size_t i = 0; i < names.size(); i++) {
|
||||
size_t lastdot = names[i].find_last_of ('.');
|
||||
for (const auto &name : names) {
|
||||
const auto lastdot = name.find_last_of('.');
|
||||
|
||||
if (lastdot != Glib::ustring::npos && names[i].substr(lastdot) == ".badpixels" ) {
|
||||
int n = scanBadPixelsFile( names[i] );
|
||||
if (lastdot != Glib::ustring::npos && name.substr(lastdot) == ".badpixels") {
|
||||
const int n = scanBadPixelsFile(name);
|
||||
|
||||
if( n > 0 && settings->verbose) {
|
||||
printf("Loaded %s: %d pixels\n", names[i].c_str(), n);
|
||||
if (n > 0 && settings->verbose) {
|
||||
printf("Loaded %s: %d pixels\n", name.c_str(), n);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
addFileInfo(names[i]);
|
||||
} catch( std::exception& e ) {}
|
||||
addFileInfo(name);
|
||||
} catch(std::exception& e) {}
|
||||
}
|
||||
|
||||
// Where multiple shots exist for same group, move filename to list
|
||||
for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) {
|
||||
dfInfo &i = iter->second;
|
||||
for (auto &df : dfList) {
|
||||
dfInfo &i = df.second;
|
||||
|
||||
if( !i.pathNames.empty() && !i.pathname.empty() ) {
|
||||
i.pathNames.push_back( i.pathname );
|
||||
if (!i.pathNames.empty() && !i.pathname.empty()) {
|
||||
i.pathNames.push_back(i.pathname);
|
||||
i.pathname.clear();
|
||||
}
|
||||
|
||||
if( settings->verbose ) {
|
||||
if( !i.pathname.empty() ) {
|
||||
printf( "%s: %s\n", i.key().c_str(), i.pathname.c_str());
|
||||
if (settings->verbose) {
|
||||
if (!i.pathname.empty()) {
|
||||
printf("%s: %s\n", i.key().c_str(), i.pathname.c_str());
|
||||
} else {
|
||||
printf( "%s: MEAN of \n ", i.key().c_str());
|
||||
printf("%s: MEAN of \n ", i.key().c_str());
|
||||
|
||||
for(std::list<Glib::ustring>::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) {
|
||||
for (std::list<Glib::ustring>::iterator path = i.pathNames.begin(); path != i.pathNames.end(); ++path) {
|
||||
printf("%s, ", path->c_str());
|
||||
}
|
||||
|
||||
@ -345,9 +396,140 @@ void DFManager::init(const Glib::ustring& pathname)
|
||||
return;
|
||||
}
|
||||
|
||||
dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
|
||||
void rtengine::DFManager::Implementation::getStat(int& totFiles, int& totTemplates) const
|
||||
{
|
||||
auto ext = getFileExtension(filename);
|
||||
totFiles = 0;
|
||||
totTemplates = 0;
|
||||
|
||||
for (const auto &df : dfList) {
|
||||
const dfInfo &i = df.second;
|
||||
|
||||
if (i.pathname.empty()) {
|
||||
totTemplates++;
|
||||
totFiles += i.pathNames.size();
|
||||
} else {
|
||||
totFiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The search for the best match is twofold:
|
||||
* if perfect matches for iso and shutter 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 shutter
|
||||
*/
|
||||
const rtengine::RawImage* rtengine::DFManager::Implementation::searchDarkFrame(const std::string& mak, const std::string& mod, int iso, double shut, time_t t)
|
||||
{
|
||||
dfInfo* df = find(toUppercase(mak), toUppercase(mod), iso, shut, t);
|
||||
|
||||
if (df) {
|
||||
return df->getRawImage();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const rtengine::RawImage* rtengine::DFManager::Implementation::searchDarkFrame(const Glib::ustring& filename)
|
||||
{
|
||||
for (auto& df : dfList) {
|
||||
if (df.second.pathname.compare(filename) == 0) {
|
||||
return df.second.getRawImage();
|
||||
}
|
||||
}
|
||||
|
||||
dfInfo *df = addFileInfo(filename, false);
|
||||
|
||||
if (df) {
|
||||
return df->getRawImage();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::Implementation::getHotPixels(const Glib::ustring& filename)
|
||||
{
|
||||
for (auto& df : dfList) {
|
||||
if (df.second.pathname.compare(filename) == 0) {
|
||||
return &df.second.getHotPixels();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::Implementation::getHotPixels(const std::string& mak, const std::string& mod, int iso, double shut, time_t t)
|
||||
{
|
||||
dfInfo* df = find(toUppercase(mak), toUppercase(mod), iso, shut, t);
|
||||
|
||||
if (df) {
|
||||
if (settings->verbose) {
|
||||
if (!df->pathname.empty()) {
|
||||
printf("Searched hotpixels from %s\n", df->pathname.c_str());
|
||||
} else {
|
||||
if (!df->pathNames.empty()) {
|
||||
printf("Searched hotpixels from template (first %s)\n", df->pathNames.begin()->c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &df->getHotPixels();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::Implementation::getBadPixels(const std::string& mak, const std::string& mod, const std::string& serial) const
|
||||
{
|
||||
bpList_t::const_iterator iter;
|
||||
bool found = false;
|
||||
|
||||
if (!serial.empty()) {
|
||||
// search with serial number first
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod << " " << serial;
|
||||
iter = bpList.find(s.str());
|
||||
|
||||
if (iter != bpList.end()) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (settings->verbose) {
|
||||
if (found) {
|
||||
printf("%s.badpixels found\n", s.str().c_str());
|
||||
} else {
|
||||
printf("%s.badpixels not found\n", s.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// search without serial number
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod;
|
||||
iter = bpList.find(s.str());
|
||||
|
||||
if (iter != bpList.end()) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (settings->verbose) {
|
||||
if (found) {
|
||||
printf("%s.badpixels found\n", s.str().c_str());
|
||||
} else {
|
||||
printf("%s.badpixels not found\n", s.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return &(iter->second);
|
||||
}
|
||||
}
|
||||
|
||||
dfInfo* rtengine::DFManager::Implementation::addFileInfo(const Glib::ustring& filename, bool pool)
|
||||
{
|
||||
const auto ext = getFileExtension(filename);
|
||||
|
||||
if (ext.empty() || !options.is_extention_enabled(ext)) {
|
||||
return nullptr;
|
||||
@ -376,37 +558,34 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
|
||||
}
|
||||
|
||||
RawImage ri(filename);
|
||||
int res = ri.loadRaw(false); // Read information about shot
|
||||
|
||||
if (res != 0) {
|
||||
if (ri.loadRaw(false) != 0) { // Read information about shot
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dfList_t::iterator iter;
|
||||
|
||||
if(!pool) {
|
||||
dfInfo n(filename, "", "", 0, 0, 0);
|
||||
iter = dfList.emplace("", n);
|
||||
if (!pool) {
|
||||
const dfInfo n(filename, "", "", 0, 0, 0);
|
||||
auto iter = dfList.emplace("", n);
|
||||
return &(iter->second);
|
||||
}
|
||||
|
||||
FramesData idata(filename, std::unique_ptr<RawMetaDataLocation>(new RawMetaDataLocation(ri.get_exifBase(), ri.get_ciffBase(), ri.get_ciffLen())), true);
|
||||
/* Files are added in the map, divided by same maker/model,ISO and shutter*/
|
||||
std::string key(dfInfo::key(((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed()));
|
||||
iter = dfList.find(key);
|
||||
std::string key(dfInfo::key(toUppercase(idata.getMake()), toUppercase(idata.getModel()), idata.getISOSpeed(), idata.getShutterSpeed()));
|
||||
auto iter = dfList.find(key);
|
||||
|
||||
if(iter == dfList.end()) {
|
||||
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
|
||||
if (iter == dfList.end()) {
|
||||
dfInfo n(filename, toUppercase(idata.getMake()), toUppercase(idata.getModel()), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
|
||||
iter = dfList.emplace(key, n);
|
||||
} else {
|
||||
while(iter != dfList.end() && iter->second.key() == key && ABS(iter->second.timestamp - idata.getDateTimeAsTS()) > 60 * 60 * 6) { // 6 hour difference
|
||||
++iter;
|
||||
}
|
||||
|
||||
if(iter != dfList.end()) {
|
||||
if (iter != dfList.end()) {
|
||||
iter->second.pathNames.push_back(filename);
|
||||
} else {
|
||||
dfInfo n(filename, ((Glib::ustring)idata.getMake()).uppercase(), ((Glib::ustring)idata.getModel()).uppercase(), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
|
||||
dfInfo n(filename, toUppercase(idata.getMake()), toUppercase(idata.getModel()), idata.getISOSpeed(), idata.getShutterSpeed(), idata.getDateTimeAsTS());
|
||||
iter = dfList.emplace(key, n);
|
||||
}
|
||||
}
|
||||
@ -418,44 +597,23 @@ dfInfo* DFManager::addFileInfo (const Glib::ustring& filename, bool pool)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DFManager::getStat( int &totFiles, int &totTemplates)
|
||||
dfInfo* rtengine::DFManager::Implementation::find(const std::string& mak, const std::string& mod, int isospeed, double shut, time_t t)
|
||||
{
|
||||
totFiles = 0;
|
||||
totTemplates = 0;
|
||||
|
||||
for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) {
|
||||
dfInfo &i = iter->second;
|
||||
|
||||
if( i.pathname.empty() ) {
|
||||
totTemplates++;
|
||||
totFiles += i.pathNames.size();
|
||||
} else {
|
||||
totFiles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The search for the best match is twofold:
|
||||
* if perfect matches for iso and shutter 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 shutter
|
||||
*/
|
||||
dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t )
|
||||
{
|
||||
if( dfList.empty() ) {
|
||||
if (dfList.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string key( dfInfo::key(mak, mod, isospeed, shut) );
|
||||
dfList_t::iterator iter = dfList.find( key );
|
||||
const std::string key(dfInfo::key(mak, mod, isospeed, shut));
|
||||
dfList_t::iterator iter = dfList.find(key);
|
||||
|
||||
if( iter != dfList.end() ) {
|
||||
if (iter != dfList.end()) {
|
||||
dfList_t::iterator bestMatch = iter;
|
||||
time_t bestDeltaTime = ABS(iter->second.timestamp - t);
|
||||
|
||||
for(++iter; iter != dfList.end() && !key.compare( iter->second.key() ); ++iter ) {
|
||||
time_t d = ABS(iter->second.timestamp - t );
|
||||
for (++iter; iter != dfList.end() && !key.compare(iter->second.key()); ++iter) {
|
||||
const time_t d = ABS(iter->second.timestamp - t);
|
||||
|
||||
if( d < bestDeltaTime ) {
|
||||
if (d < bestDeltaTime) {
|
||||
bestMatch = iter;
|
||||
bestDeltaTime = d;
|
||||
}
|
||||
@ -465,12 +623,12 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso
|
||||
} else {
|
||||
iter = dfList.begin();
|
||||
dfList_t::iterator bestMatch = iter;
|
||||
double bestD = iter->second.distance( mak, mod, isospeed, shut );
|
||||
double bestD = iter->second.distance(mak, mod, isospeed, shut);
|
||||
|
||||
for( ++iter; iter != dfList.end(); ++iter ) {
|
||||
double d = iter->second.distance( mak, mod, isospeed, shut );
|
||||
for (++iter; iter != dfList.end(); ++iter) {
|
||||
const double d = iter->second.distance(mak, mod, isospeed, shut);
|
||||
|
||||
if( d < bestD ) {
|
||||
if (d < bestD) {
|
||||
bestD = d;
|
||||
bestMatch = iter;
|
||||
}
|
||||
@ -480,170 +638,107 @@ dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int iso
|
||||
}
|
||||
}
|
||||
|
||||
RawImage* DFManager::searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
|
||||
{
|
||||
dfInfo *df = find( ((Glib::ustring)mak).uppercase(), ((Glib::ustring)mod).uppercase(), iso, shut, t );
|
||||
|
||||
if( df ) {
|
||||
return df->getRawImage();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RawImage* DFManager::searchDarkFrame( const Glib::ustring filename )
|
||||
{
|
||||
for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) {
|
||||
if( iter->second.pathname.compare( filename ) == 0 ) {
|
||||
return iter->second.getRawImage();
|
||||
}
|
||||
}
|
||||
|
||||
dfInfo *df = addFileInfo( filename, false );
|
||||
|
||||
if(df) {
|
||||
return df->getRawImage();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<badPix> *DFManager::getHotPixels ( const Glib::ustring filename )
|
||||
{
|
||||
for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end(); ++iter ) {
|
||||
if( iter->second.pathname.compare( filename ) == 0 ) {
|
||||
return &iter->second.getHotPixels();
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<badPix> *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
|
||||
{
|
||||
dfInfo *df = find( ((Glib::ustring)mak).uppercase(), ((Glib::ustring)mod).uppercase(), iso, shut, t );
|
||||
|
||||
if( df ) {
|
||||
if( settings->verbose ) {
|
||||
if( !df->pathname.empty() ) {
|
||||
printf( "Searched hotpixels from %s\n", df->pathname.c_str());
|
||||
} else {
|
||||
if( !df->pathNames.empty() ) {
|
||||
printf( "Searched hotpixels from template (first %s)\n", df->pathNames.begin()->c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &df->getHotPixels();
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int DFManager::scanBadPixelsFile( Glib::ustring filename )
|
||||
int rtengine::DFManager::Implementation::scanBadPixelsFile(const Glib::ustring& filename)
|
||||
{
|
||||
FILE *file = ::fopen( filename.c_str(), "r" );
|
||||
|
||||
if( !file ) {
|
||||
return false;
|
||||
if (!file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t lastdot = filename.find_last_of ('.');
|
||||
size_t dirpos1 = filename.find_last_of ('/');
|
||||
size_t dirpos2 = filename.find_last_of ('\\');
|
||||
const auto lastdot = filename.find_last_of('.');
|
||||
auto dirpos1 = filename.find_last_of('/');
|
||||
auto dirpos2 = filename.find_last_of('\\');
|
||||
|
||||
if( dirpos1 == Glib::ustring::npos && dirpos2 == Glib::ustring::npos ) {
|
||||
if (dirpos1 == Glib::ustring::npos && dirpos2 == Glib::ustring::npos) {
|
||||
dirpos1 = 0;
|
||||
} else if( dirpos1 != Glib::ustring::npos && dirpos2 != Glib::ustring::npos ) {
|
||||
} else if (dirpos1 != Glib::ustring::npos && dirpos2 != Glib::ustring::npos) {
|
||||
dirpos1 = (dirpos1 > dirpos2 ? dirpos1 : dirpos2);
|
||||
} else if( dirpos1 == Glib::ustring::npos ) {
|
||||
} else if (dirpos1 == Glib::ustring::npos) {
|
||||
dirpos1 = dirpos2;
|
||||
}
|
||||
|
||||
std::string makmodel(filename, dirpos1 + 1, lastdot - (dirpos1 + 1) );
|
||||
const std::string makmodel(filename, dirpos1 + 1, lastdot - (dirpos1 + 1));
|
||||
std::vector<badPix> bp;
|
||||
char line[256];
|
||||
|
||||
if(fgets(line, sizeof(line), file )) {
|
||||
if (fgets(line, sizeof(line), file)) {
|
||||
int x, y;
|
||||
int offset = 0;
|
||||
int numparms = sscanf(line, "%d %d", &x, &y);
|
||||
|
||||
if( numparms == 1 ) { // only one number in first line means, that this is the offset.
|
||||
if (numparms == 1) { // only one number in first line means, that this is the offset.
|
||||
offset = x;
|
||||
} else if(numparms == 2) {
|
||||
} else if (numparms == 2) {
|
||||
bp.emplace_back(x + offset, y + offset);
|
||||
}
|
||||
|
||||
while( fgets(line, sizeof(line), file ) ) {
|
||||
if( sscanf(line, "%d %d", &x, &y) == 2 ) {
|
||||
while(fgets(line, sizeof(line), file)) {
|
||||
if (sscanf(line, "%d %d", &x, &y) == 2) {
|
||||
bp.emplace_back(x + offset, y + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int numPixels = bp.size();
|
||||
const int numPixels = bp.size();
|
||||
|
||||
if( numPixels > 0 ) {
|
||||
bpList[ makmodel ] = bp;
|
||||
if (numPixels > 0) {
|
||||
bpList[makmodel] = bp;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return numPixels;
|
||||
}
|
||||
|
||||
std::vector<badPix> *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial)
|
||||
rtengine::DFManager& rtengine::DFManager::getInstance()
|
||||
{
|
||||
bpList_t::iterator iter;
|
||||
bool found = false;
|
||||
|
||||
if( !serial.empty() ) {
|
||||
// search with serial number first
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod << " " << serial;
|
||||
iter = bpList.find( s.str() );
|
||||
|
||||
if( iter != bpList.end() ) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if( settings->verbose ) {
|
||||
if(found) {
|
||||
printf("%s.badpixels found\n", s.str().c_str());
|
||||
} else {
|
||||
printf("%s.badpixels not found\n", s.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
// search without serial number
|
||||
std::ostringstream s;
|
||||
s << mak << " " << mod;
|
||||
iter = bpList.find( s.str() );
|
||||
|
||||
if( iter != bpList.end() ) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if( settings->verbose ) {
|
||||
if(found) {
|
||||
printf("%s.badpixels found\n", s.str().c_str());
|
||||
} else {
|
||||
printf("%s.badpixels not found\n", s.str().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return &(iter->second);
|
||||
}
|
||||
static DFManager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Global variable
|
||||
DFManager dfm;
|
||||
|
||||
|
||||
void rtengine::DFManager::init(const Glib::ustring& pathname)
|
||||
{
|
||||
implementation->init(pathname);
|
||||
}
|
||||
|
||||
Glib::ustring rtengine::DFManager::getPathname() const
|
||||
{
|
||||
return implementation->getPathname();
|
||||
}
|
||||
|
||||
void rtengine::DFManager::getStat(int& totFiles, int& totTemplates) const
|
||||
{
|
||||
implementation->getStat(totFiles, totTemplates);
|
||||
}
|
||||
|
||||
const rtengine::RawImage* rtengine::DFManager::searchDarkFrame(const std::string& mak, const std::string& mod, int iso, double shut, time_t t)
|
||||
{
|
||||
return implementation->searchDarkFrame(mak, mod, iso, shut, t);
|
||||
}
|
||||
|
||||
const rtengine::RawImage* rtengine::DFManager::searchDarkFrame(const Glib::ustring& filename)
|
||||
{
|
||||
return implementation->searchDarkFrame(filename);
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::getHotPixels(const std::string& mak, const std::string& mod, int iso, double shut, time_t t)
|
||||
{
|
||||
return implementation->getHotPixels(mak, mod, iso, shut, t);
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::getHotPixels(const Glib::ustring& filename)
|
||||
{
|
||||
return implementation->getHotPixels(filename);
|
||||
}
|
||||
|
||||
const std::vector<rtengine::badPix>* rtengine::DFManager::getBadPixels(const std::string& mak, const std::string& mod, const std::string& serial) const
|
||||
{
|
||||
return implementation->getBadPixels(mak, mod, serial);
|
||||
}
|
||||
|
||||
rtengine::DFManager::DFManager() :
|
||||
implementation(new Implementation)
|
||||
{
|
||||
}
|
||||
|
||||
rtengine::DFManager::~DFManager() = default;
|
||||
|
@ -18,89 +18,40 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <glibmm/ustring.h>
|
||||
|
||||
#include "pixelsmap.h"
|
||||
|
||||
namespace rtengine
|
||||
{
|
||||
|
||||
struct badPix;
|
||||
|
||||
class RawImage;
|
||||
class dfInfo final
|
||||
{
|
||||
public:
|
||||
|
||||
Glib::ustring pathname; // filename of dark frame
|
||||
std::list<Glib::ustring> pathNames; // other similar dark frames, used for average
|
||||
std::string maker; ///< manufacturer
|
||||
std::string model; ///< model
|
||||
int iso; ///< ISO (gain)
|
||||
double shutter; ///< shutter or exposure time in sec
|
||||
time_t timestamp; ///< seconds since 1 Jan 1970
|
||||
|
||||
|
||||
dfInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod, int iso, double shut, time_t t)
|
||||
: pathname(name), maker(mak), model(mod), iso(iso), shutter(shut), timestamp(t), ri(nullptr) {}
|
||||
|
||||
dfInfo( const dfInfo &o)
|
||||
: pathname(o.pathname), maker(o.maker), model(o.model), iso(o.iso), shutter(o.shutter), timestamp(o.timestamp), ri(nullptr) {}
|
||||
~dfInfo();
|
||||
|
||||
dfInfo &operator =(const dfInfo &o);
|
||||
bool operator <(const dfInfo &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) const;
|
||||
|
||||
static std::string key(const std::string &mak, const std::string &mod, int iso, double shut );
|
||||
std::string key()
|
||||
{
|
||||
return key( maker, model, iso, shutter);
|
||||
}
|
||||
|
||||
RawImage *getRawImage();
|
||||
std::vector<badPix> &getHotPixels();
|
||||
|
||||
protected:
|
||||
RawImage *ri; ///< Dark Frame raw data
|
||||
std::vector<badPix> badPixels; ///< Extracted hot pixels
|
||||
|
||||
void updateBadPixelList( RawImage *df );
|
||||
void updateRawImage();
|
||||
};
|
||||
|
||||
class DFManager final
|
||||
{
|
||||
public:
|
||||
void init(const Glib::ustring &pathname);
|
||||
Glib::ustring getPathname()
|
||||
{
|
||||
return currentPath;
|
||||
};
|
||||
void getStat( int &totFiles, int &totTemplate);
|
||||
RawImage *searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
|
||||
RawImage *searchDarkFrame( const Glib::ustring filename );
|
||||
std::vector<badPix> *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
|
||||
std::vector<badPix> *getHotPixels ( const Glib::ustring filename );
|
||||
std::vector<badPix> *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
|
||||
static DFManager& getInstance();
|
||||
|
||||
protected:
|
||||
typedef std::multimap<std::string, dfInfo> dfList_t;
|
||||
typedef std::map<std::string, std::vector<badPix> > bpList_t;
|
||||
dfList_t dfList;
|
||||
bpList_t bpList;
|
||||
bool initialized;
|
||||
Glib::ustring currentPath;
|
||||
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 );
|
||||
void init(const Glib::ustring& pathname);
|
||||
Glib::ustring getPathname() const;
|
||||
void getStat(int& totFiles, int& totTemplates) const;
|
||||
const RawImage* searchDarkFrame(const std::string& mak, const std::string& mod, int iso, double shut, time_t t);
|
||||
const RawImage* searchDarkFrame(const Glib::ustring& filename);
|
||||
const std::vector<badPix>* getHotPixels(const std::string& mak, const std::string& mod, int iso, double shut, time_t t);
|
||||
const std::vector<badPix>* getHotPixels(const Glib::ustring& filename);
|
||||
const std::vector<badPix>* getBadPixels(const std::string& mak, const std::string& mod, const std::string& serial) const;
|
||||
|
||||
private:
|
||||
DFManager();
|
||||
~DFManager();
|
||||
|
||||
class Implementation;
|
||||
|
||||
const std::unique_ptr<Implementation> implementation;
|
||||
};
|
||||
|
||||
extern DFManager dfm;
|
||||
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ int init (const Settings* s, const Glib::ustring& baseDir, const Glib::ustring&
|
||||
#pragma omp section
|
||||
#endif
|
||||
{
|
||||
dfm.init(s->darkFramesPath);
|
||||
DFManager::getInstance().init(s->darkFramesPath);
|
||||
}
|
||||
#ifdef _OPENMP
|
||||
#pragma omp section
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "median.h"
|
||||
#include "mytime.h"
|
||||
#include "pdaflinesfilter.h"
|
||||
#include "pixelsmap.h"
|
||||
#include "procparams.h"
|
||||
#include "rawimage.h"
|
||||
#include "rawimagesource_i.h"
|
||||
@ -41,6 +42,7 @@
|
||||
#include "rt_math.h"
|
||||
#include "rtengine.h"
|
||||
#include "rtlensfun.h"
|
||||
|
||||
#include "../rtgui/options.h"
|
||||
|
||||
#define BENCHMARK
|
||||
@ -1307,14 +1309,14 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
|
||||
|
||||
Glib::ustring newDF = raw.dark_frame;
|
||||
RawImage *rid = nullptr;
|
||||
const RawImage* rid = nullptr;
|
||||
|
||||
if (!raw.df_autoselect) {
|
||||
if (!raw.dark_frame.empty()) {
|
||||
rid = dfm.searchDarkFrame(raw.dark_frame);
|
||||
rid = DFManager::getInstance().searchDarkFrame(raw.dark_frame);
|
||||
}
|
||||
} else {
|
||||
rid = dfm.searchDarkFrame(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS());
|
||||
rid = DFManager::getInstance().searchDarkFrame(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS());
|
||||
}
|
||||
|
||||
if (rid && settings->verbose) {
|
||||
@ -1387,7 +1389,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
|
||||
|
||||
// Always correct camera badpixels from .badpixels file
|
||||
std::vector<badPix> *bp = dfm.getBadPixels(ri->get_maker(), ri->get_model(), idata->getSerialNumber());
|
||||
const std::vector<badPix> *bp = DFManager::getInstance().getBadPixels(ri->get_maker(), ri->get_model(), idata->getSerialNumber());
|
||||
|
||||
if (bp) {
|
||||
if (!bitmapBads) {
|
||||
@ -1405,9 +1407,9 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
|
||||
bp = nullptr;
|
||||
|
||||
if (raw.df_autoselect) {
|
||||
bp = dfm.getHotPixels(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS());
|
||||
bp = DFManager::getInstance().getHotPixels(idata->getMake(), idata->getModel(), idata->getISOSpeed(), idata->getShutterSpeed(), idata->getDateTimeAsTS());
|
||||
} else if (!raw.dark_frame.empty()) {
|
||||
bp = dfm.getHotPixels(raw.dark_frame);
|
||||
bp = DFManager::getInstance().getHotPixels(raw.dark_frame);
|
||||
}
|
||||
|
||||
if (bp) {
|
||||
@ -2453,7 +2455,7 @@ void RawImageSource::HLRecovery_Global(const ToneCurveParams &hrp)
|
||||
/* Copy original pixel data and
|
||||
* subtract dark frame (if present) from current image and apply flat field correction (if present)
|
||||
*/
|
||||
void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData)
|
||||
void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData)
|
||||
{
|
||||
const auto tmpfilters = ri->get_filters();
|
||||
ri->set_filters(ri->prefilters); // we need 4 blacks for bayer processing
|
||||
|
@ -138,7 +138,7 @@ public:
|
||||
}
|
||||
|
||||
void processFlatField(const procparams::RAWParams &raw, const RawImage *riFlatFile, array2D<float> &rawData, const float black[4]);
|
||||
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
|
||||
void copyOriginalPixels(const procparams::RAWParams &raw, RawImage *ri, const RawImage *riDark, RawImage *riFlatFile, array2D<float> &rawData );
|
||||
void scaleColors (int winx, int winy, int winw, int winh, const procparams::RAWParams &raw, array2D<float> &rawData); // raw for cblack
|
||||
void WBauto(double &tempref, double &greenref, array2D<float> &redloc, array2D<float> &greenloc, array2D<float> &blueloc, int bfw, int bfh, double &avg_rm, double &avg_gm, double &avg_bm, double &tempitc, double &greenitc, float &studgood, bool &twotimes, const procparams::WBParams & wbpar, int begx, int begy, int yEn, int xEn, int cx, int cy, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
|
||||
void getAutoWBMultipliersitc(double &tempref, double &greenref, double &tempitc, double &greenitc, float &studgood, int begx, int begy, int yEn, int xEn, int cx, int cy, int bf_h, int bf_w, double &rm, double &gm, double &bm, const procparams::WBParams & wbpar, const procparams::ColorManagementParams &cmp, const procparams::RAWParams &raw) override;
|
||||
|
@ -97,7 +97,7 @@ void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdi
|
||||
|
||||
if( pp->raw.df_autoselect && dfp && !multiImage) {
|
||||
// retrieve the auto-selected df filename
|
||||
rtengine::RawImage *img = dfp->getDF();
|
||||
const rtengine::RawImage *img = dfp->getDF();
|
||||
|
||||
if( img ) {
|
||||
dfInfo->set_text( Glib::ustring::compose("%1: %2ISO %3s", Glib::path_get_basename(img->get_filename()), img->get_ISOspeed(), img->get_shutter()) );
|
||||
@ -179,7 +179,7 @@ void DarkFrame::dfAutoChanged()
|
||||
|
||||
if(dfAuto->get_active() && dfp && !batchMode) {
|
||||
// retrieve the auto-selected df filename
|
||||
rtengine::RawImage *img = dfp->getDF();
|
||||
const rtengine::RawImage *img = dfp->getDF();
|
||||
|
||||
if( img ) {
|
||||
dfInfo->set_text( Glib::ustring::compose("%1: %2ISO %3s", Glib::path_get_basename(img->get_filename()), img->get_ISOspeed(), img->get_shutter()) );
|
||||
|
@ -36,7 +36,7 @@ class DFProvider
|
||||
{
|
||||
public:
|
||||
virtual ~DFProvider() = default;
|
||||
virtual rtengine::RawImage* getDF() = 0;
|
||||
virtual const rtengine::RawImage* getDF() = 0;
|
||||
virtual Glib::ustring GetCurrentImageFilePath() = 0;
|
||||
// add other info here
|
||||
};
|
||||
|
@ -875,7 +875,7 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m)
|
||||
}
|
||||
|
||||
// Reinit cache
|
||||
rtengine::dfm.init( options.rtSettings.darkFramesPath );
|
||||
rtengine::DFManager::getInstance().init( options.rtSettings.darkFramesPath );
|
||||
} else {
|
||||
// Target directory creation failed, we clear the darkFramesPath setting
|
||||
options.rtSettings.darkFramesPath.clear();
|
||||
|
@ -2641,8 +2641,8 @@ void Preferences::darkFrameChanged()
|
||||
{
|
||||
//Glib::ustring s(darkFrameDir->get_filename());
|
||||
Glib::ustring s(darkFrameDir->get_current_folder());
|
||||
//if( s.compare( rtengine::dfm.getPathname()) !=0 ){
|
||||
rtengine::dfm.init(s);
|
||||
//if( s.compare( rtengine::DFManager::getInstance().getPathname()) !=0 ){
|
||||
rtengine::DFManager::getInstance().init(s);
|
||||
updateDFinfos();
|
||||
//}
|
||||
}
|
||||
@ -2660,7 +2660,7 @@ void Preferences::flatFieldChanged()
|
||||
void Preferences::updateDFinfos()
|
||||
{
|
||||
int t1, t2;
|
||||
rtengine::dfm.getStat(t1, t2);
|
||||
rtengine::DFManager::getInstance().getStat(t1, t2);
|
||||
Glib::ustring s = Glib::ustring::compose("%1: %2 %3, %4 %5", M("PREFERENCES_DARKFRAMEFOUND"), t1, M("PREFERENCES_DARKFRAMESHOTS"), t2, M("PREFERENCES_DARKFRAMETEMPLATES"));
|
||||
dfLabel->set_text(s);
|
||||
}
|
||||
|
@ -944,7 +944,7 @@ void ToolPanelCoordinator::autoCropRequested()
|
||||
crop->cropManipReady();
|
||||
}
|
||||
|
||||
rtengine::RawImage* ToolPanelCoordinator::getDF()
|
||||
const rtengine::RawImage* ToolPanelCoordinator::getDF()
|
||||
{
|
||||
if (!ipc) {
|
||||
return nullptr;
|
||||
@ -959,7 +959,7 @@ rtengine::RawImage* ToolPanelCoordinator::getDF()
|
||||
std::string model(imd->getModel());
|
||||
time_t timestamp = imd->getDateTimeAsTS();
|
||||
|
||||
return rtengine::dfm.searchDarkFrame(maker, model, iso, shutter, timestamp);
|
||||
return rtengine::DFManager::getInstance().searchDarkFrame(maker, model, iso, shutter, timestamp);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -307,7 +307,7 @@ public:
|
||||
}
|
||||
|
||||
//DFProvider interface
|
||||
rtengine::RawImage* getDF() override;
|
||||
const rtengine::RawImage* getDF() override;
|
||||
|
||||
//FFProvider interface
|
||||
rtengine::RawImage* getFF() override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user