Merge pull request #7065 from Lawrence37/lensfun-lens-crop-factor

Lensfun lens selection using camera crop factor
This commit is contained in:
Lawrence37
2024-06-22 18:59:31 -07:00
committed by GitHub
3 changed files with 69 additions and 14 deletions

View File

@@ -26,6 +26,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
{
@@ -461,20 +516,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;
}
}
const auto find_lens_from_name = [](const lfDatabase *database, const lfCamera *cam, const Glib::ustring &lens_name) {
auto found = database->FindLenses(cam, nullptr, lens_name.c_str());
@@ -576,12 +636,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) {