diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 757d3d54c..08ee9a4a0 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -1233,12 +1233,12 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I double Dx = Dxr; double Dy = Dyr; - if (enableLCPCA) { - pLCPMap->correctCA(Dx, Dy, w2, h2, c); - } - - if (enableLCPDist) { + if (enableLCPDist && enableLCPCA) { + pLCPMap->correctDistortionAndCA(Dx, Dy, w2, h2, c); + } else if (enableLCPDist) { pLCPMap->correctDistortion(Dx, Dy, w2, h2); + } else if (enableLCPCA) { + pLCPMap->correctCA(Dx, Dy, w2, h2, c); } // distortion correction diff --git a/rtengine/lcp.cc b/rtengine/lcp.cc index 7507bbb11..ba96147dc 100644 --- a/rtengine/lcp.cc +++ b/rtengine/lcp.cc @@ -990,6 +990,12 @@ bool rtengine::LCPMapper::isCACorrectionAvailable() const return enableCA; } +void rtengine::LCPMapper::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const +{ + correctDistortion(x, y, cx, cy); + correctCA(x, y, cx, cy, channel); +} + void rtengine::LCPMapper::correctDistortion(double &x, double &y, int cx, int cy) const { x += cx; diff --git a/rtengine/lcp.h b/rtengine/lcp.h index b59cc84c6..97cdd0890 100644 --- a/rtengine/lcp.h +++ b/rtengine/lcp.h @@ -166,6 +166,8 @@ private: class LensCorrection { public: virtual ~LensCorrection() {} + + virtual void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const = 0; virtual void correctDistortion(double &x, double &y, int cx, int cy) const = 0; virtual bool isCACorrectionAvailable() const = 0; virtual void correctCA(double &x, double &y, int cx, int cy, int channel) const = 0; @@ -194,6 +196,7 @@ public: ); + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; bool isCACorrectionAvailable() const override; void correctCA(double& x, double& y, int cx, int cy, int channel) const override; diff --git a/rtengine/rtlensfun.cc b/rtengine/rtlensfun.cc index 08010f50f..505346ad0 100644 --- a/rtengine/rtlensfun.cc +++ b/rtengine/rtlensfun.cc @@ -125,7 +125,6 @@ void LFModifier::correctDistortion(double &x, double &y, int cx, int cy) const } } - bool LFModifier::isCACorrectionAvailable() const { return (flags_ & LF_MODIFY_TCA); @@ -141,7 +140,7 @@ void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) co // channels. We could consider caching the info to speed this up x += cx; y += cy; - + float pos[6]; if (swap_xy_) { std::swap(x, y); @@ -156,6 +155,31 @@ void LFModifier::correctCA(double &x, double &y, int cx, int cy, int channel) co y -= cy; } +void LFModifier::correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const +{ + assert(channel >= 0 && channel <= 2); + + // RT currently applies the CA correction per channel, whereas + // lensfun applies it to all the three channels simultaneously. This means + // we do the work 3 times, because each time we discard 2 of the 3 + // channels. We could consider caching the info to speed this up + x += cx; + y += cy; + + float pos[6]; + if (swap_xy_) { + std::swap(x, y); + } + data_->ApplySubpixelGeometryDistortion(x, y, 1, 1, pos); // This is thread-safe + x = pos[2*channel]; + y = pos[2*channel+1]; + if (swap_xy_) { + std::swap(x, y); + } + x -= cx; + y -= cy; +} + #ifdef _OPENMP void LFModifier::processVignette(int width, int height, float** rawData) const { @@ -396,7 +420,7 @@ bool LFDatabase::init(const Glib::ustring &dbdir) if (settings->verbose) { std::cout << (ok ? "OK" : "FAIL") << std::endl; } - + return ok; } diff --git a/rtengine/rtlensfun.h b/rtengine/rtlensfun.h index 1d941246f..39ca67ec2 100644 --- a/rtengine/rtlensfun.h +++ b/rtengine/rtlensfun.h @@ -53,6 +53,7 @@ public: explicit operator bool() const; + void correctDistortionAndCA(double &x, double &y, int cx, int cy, int channel) const override; void correctDistortion(double &x, double &y, int cx, int cy) const override; bool isCACorrectionAvailable() const override; void correctCA(double &x, double &y, int cx, int cy, int channel) const override;