/* * This file is part of RawTherapee. * * Copyright (c) 2012 Oliver Duis * * RawTherapee is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ #pragma once #include #include #include #include #include #include #include "imagefloat.h" #include "opthelper.h" namespace rtengine { // Perspective model common data, also used for Vignette and Fisheye class LCPModelCommon final { public: LCPModelCommon(); bool empty() const; // is it empty void print() const; // printf all values void merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA); void prepareParams(int fullWidth, int fullHeight, float focalLength, float focalLength35mm, float sensorFormatFactor, bool swapXY, bool mirrorX, bool mirrorY); //private: using Param = std::array; using VignParam = std::array; float foc_len_x; float foc_len_y; float img_center_x; float img_center_y; Param param; // k1..k5, resp. alpha1..5 float scale_factor; // alpha0 double mean_error; bool bad_error; // prepared params float x0; float y0; float fx; float fy; float rfx; float rfy; VignParam vign_param; }; class LCPPersModel { public: float focLen, focDist, aperture; // this is what it refers to LCPModelCommon base; // base perspective correction LCPModelCommon chromRG, chromG, chromBG; // red/green, green, blue/green (may be empty) LCPModelCommon vignette; // vignette (may be empty) LCPPersModel(); bool hasModeData(int mode) const; void print() const; }; class LCPProfile { // Temporary data for parsing bool inCamProfiles, firstLIDone, inPerspect, inAlternateLensID, inAlternateLensNames; char lastTag[256], inInvalidTag[256]; LCPPersModel* pCurPersModel; LCPModelCommon* pCurCommon; static void XMLCALL XmlStartHandler(void *pLCPProfile, const char *el, const char **attr); static void XMLCALL XmlTextHandler (void *pLCPProfile, const XML_Char *s, int len); static void XMLCALL XmlEndHandler (void *pLCPProfile, const char *el); int filterBadFrames(double maxAvgDevFac, int minFramesLeft); void handle_text(std::string text); std::ostringstream textbuf; public: // Common data Glib::ustring profileName, lensPrettyName, cameraPrettyName, lens, camera; // lens/camera(=model) can be auto-matched with DNG bool isRaw, isFisheye; float sensorFormatFactor; int persModelCount; // The correction frames static const int MaxPersModelCount = 3000; LCPPersModel* aPersModel[MaxPersModelCount]; // Do NOT use std::list or something, it's buggy in GCC! explicit LCPProfile(const Glib::ustring &fname); ~LCPProfile(); void calcParams(int mode, float focalLength, float focusDist, float aperture, LCPModelCommon *pCorr1, LCPModelCommon *pCorr2, LCPModelCommon *pCorr3) const; // Interpolates between the persModels frames void print() const; }; class LCPStore { MyMutex mtx; // Maps file name to profile as cache std::map profileCache; public: ~LCPStore(); Glib::ustring getDefaultCommonDirectory() const; bool isValidLCPFileName(Glib::ustring filename) const; LCPProfile* getProfile(Glib::ustring filename); static LCPStore* getInstance(); }; #define lcpStore LCPStore::getInstance() class LensCorrection { public: virtual ~LensCorrection() {} virtual void correctDistortion(double &x, double &y, int cx, int cy, double scale) const = 0; virtual bool supportsAutoFill() const = 0; virtual bool supportsCA() const = 0; virtual void correctCA(double &x, double &y, int channel) const = 0; virtual void processVignetteLine(int width, int y, float *line) const = 0; virtual void processVignetteLine3Channels(int width, int y, float *line) const = 0; }; // Once precalculated class to correct a point class LCPMapper: public LensCorrection { bool useCADist; // should the distortion in the CA info be used? bool swapXY; LCPModelCommon mc; LCPModelCommon chrom[3]; // in order RedGreen/Green/BlueGreen bool isFisheye; public: bool enableCA; // is the mapper capable if CA correction? // precalculates the mapper. LCPMapper(LCPProfile* pProf, float focalLength, float focalLength35mm, float focusDist, float aperture, bool vignette, bool useCADistP, int fullWidth, int fullHeight, const CoarseTransformParams& coarse, int rawRotationDeg); void correctDistortion(double &x, double &y, int cx, int cy, double scale) const; // MUST be the first stage bool supportsCA() const { return enableCA; } bool supportsAutoFill() const { return true; } void correctCA(double& x, double& y, int channel) const; void processVignetteLine(int width, int y, float *line) const; void processVignetteLine3Channels(int width, int y, float *line) const; }; }