Use camera crop factor to select Lensfun lens

This commit is contained in:
Lawrence Lee
2024-05-02 22:12:44 -07:00
parent c72e67ae24
commit 068420da60
3 changed files with 69 additions and 14 deletions

View File

@@ -25,6 +25,61 @@
#include "rtlensfun.h"
#include "settings.h"
namespace
{
bool isCStringIn(const char *str, const char *const *list)
{
for (auto element_ptr = list; *element_ptr; element_ptr++) {
if (!strcmp(str, *element_ptr)) {
return true;
}
}
return false;
}
bool isNextLensCropFactorBetter(const lfLens *current_lens, const lfCamera *camera, float next_lens_crop_factor)
{
if (!current_lens) {
// No current lens, so next lens's crop factor is
// automatically better.
return true;
}
const float current_lens_crop_factor = current_lens->CropFactor;
if (!camera) {
// Favor the smaller crop factor for maximum coverage.
return current_lens_crop_factor > next_lens_crop_factor;
}
const float camera_crop_factor = camera->CropFactor;
if (current_lens_crop_factor > camera_crop_factor) {
// Current lens's data does not cover the entire camera
// sensor. Any lens's data with a smaller crop factor is
// better.
return current_lens->CropFactor > next_lens_crop_factor;
}
// Current lens's data covers the entire camera sensor. A lens
// with data from a larger crop factor will be more precise, but
// also must not be larger than the camera sensor's crop factor
// to maintain full coverage.
return current_lens->CropFactor < next_lens_crop_factor &&
next_lens_crop_factor <= camera_crop_factor;
}
bool isNextLensBetter(const lfCamera *camera, const lfLens *current_lens, const lfLens &next_lens, const Glib::ustring &lens_name, const Glib::ustring &next_lens_name)
{
return isNextLensCropFactorBetter(current_lens, camera, next_lens.CropFactor) &&
lens_name == next_lens_name &&
(!camera || isCStringIn(camera->Mount, next_lens.Mounts));
}
} // namespace
namespace rtengine
{
@@ -460,20 +515,25 @@ LFCamera LFDatabase::findCamera(const Glib::ustring &make, const Glib::ustring &
}
LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name) const
LFLens LFDatabase::findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const
{
LFLens ret;
if (data_ && !name.empty()) {
MyMutex::MyLock lock(lfDBMutex);
if (!camera.data_) {
if (!autoMatch) {
// Only the lens name provided. Try to find exact match by name.
LFLens candidate;
LFLens bestCandidate;
for (auto lens_list = data_->GetLenses(); lens_list[0]; lens_list++) {
candidate.data_ = lens_list[0];
if (name == candidate.getLens()) {
return candidate;
if (isNextLensBetter(camera.data_, bestCandidate.data_, *(candidate.data_), name, candidate.getLens())) {
bestCandidate.data_ = candidate.data_;
}
}
if (bestCandidate.data_) {
return bestCandidate;
}
}
auto found = data_->FindLenses(camera.data_, nullptr, name.c_str());
for (size_t pos = 0; !found && pos < name.size(); ) {
@@ -562,12 +622,7 @@ std::unique_ptr<LFModifier> LFDatabase::findModifier(
}
const LFCamera c = findCamera(make, model, lensProf.lfAutoMatch());
const LFLens l = findLens(
lensProf.lfAutoMatch()
? c
: LFCamera(),
lens
);
const LFLens l = findLens(c, lens, lensProf.lfAutoMatch());
bool swap_xy = false;
if (rawRotationDeg >= 0) {

View File

@@ -121,7 +121,7 @@ public:
std::vector<LFCamera> getCameras() const;
std::vector<LFLens> getLenses() const;
LFCamera findCamera(const Glib::ustring &make, const Glib::ustring &model, bool autoMatch) const;
LFLens findLens(const LFCamera &camera, const Glib::ustring &name) const;
LFLens findLens(const LFCamera &camera, const Glib::ustring &name, bool autoMatch) const;
std::unique_ptr<LFModifier> findModifier(
const procparams::LensProfParams &lensProf,

View File

@@ -251,7 +251,7 @@ void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const Pa
if (pp->lensProf.lfAutoMatch()) {
if (metadata) {
const LFLens l = db->findLens(c, metadata->getLens());
const LFLens l = db->findLens(c, metadata->getLens(), true);
setLensfunLens(l.getLens());
}
} else if (pp->lensProf.lfManual()) {
@@ -522,7 +522,7 @@ void LensProfilePanel::onCorrModeChanged(const Gtk::RadioButton* rbChanged)
} else if (metadata) {
const LFDatabase* const db = LFDatabase::getInstance();
const LFCamera c = db->findCamera(metadata->getMake(), metadata->getModel(), true);
const LFLens l = db->findLens(c, metadata->getLens());
const LFLens l = db->findLens(c, metadata->getLens(), true);
setLensfunCamera(c.getMake(), c.getModel());
setLensfunLens(l.getLens());
}
@@ -808,7 +808,7 @@ void LensProfilePanel::updateLensfunWarning()
return;
}
const LFLens l = db->findLens(LFCamera(), (*itl)[lf->lensfunModelLens.lens]);
const LFLens l = db->findLens(c, (*itl)[lf->lensfunModelLens.lens], false);
const float lenscrop = l.getCropFactor();
const float camcrop = c.getCropFactor();