1 /* 2 * This file is part of RawTherapee. 3 * 4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com> 5 * 6 * RawTherapee is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * RawTherapee is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with RawTherapee. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 #pragma once 20 21 #include <memory> 22 23 #include "coord2d.h" 24 #include "gamutwarning.h" 25 #include "pipettebuffer.h" 26 27 template<typename T> 28 class LUT; 29 30 using LUTu = LUT<uint32_t>; 31 using LUTf = LUT<float>; 32 33 template<typename T, const size_t num> 34 class multi_array2D; 35 namespace rtengine 36 { 37 38 class ColorAppearance; 39 class ColorGradientCurve; 40 class DCPProfile; 41 class DCPProfileApplyState; 42 class FlatCurve; 43 class FramesMetaData; 44 class LensCorrection; 45 class NoiseCurve; 46 class OpacityCurve; 47 class ToneCurve; 48 class WavCurve; 49 class WavOpacityCurveBY; 50 class WavOpacityCurveRG; 51 class WavOpacityCurveW; 52 class WavOpacityCurveWL; 53 54 class CieImage; 55 class Image8; 56 class Imagefloat; 57 class LabImage; 58 class wavelet_decomposition; 59 60 namespace procparams 61 { 62 63 class ProcParams; 64 65 struct ColorManagementParams; 66 struct DirPyrDenoiseParams; 67 struct SharpeningParams; 68 struct VignettingParams; 69 struct WaveletParams; 70 71 } 72 73 enum RenderingIntent : int; 74 75 class ImProcFunctions 76 { 77 cmsHTRANSFORM monitorTransform; 78 std::unique_ptr<GamutWarning> gamutWarning; 79 80 const procparams::ProcParams* params; 81 double scale; 82 bool multiThread; 83 84 void calcVignettingParams(int oW, int oH, const procparams::VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul); 85 86 void transformLuminanceOnly(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH); 87 void transformGeneral(bool highQuality, Imagefloat *original, Imagefloat *transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LensCorrection *pLCPMap, bool useOriginalBuffer); 88 void transformLCPCAOnly(Imagefloat *original, Imagefloat *transformed, int cx, int cy, const LensCorrection *pLCPMap, bool useOriginalBuffer); 89 90 bool needsCA() const; 91 bool needsDistortion() const; 92 bool needsRotation() const; 93 bool needsPerspective() const; 94 bool needsGradient() const; 95 bool needsVignetting() const; 96 bool needsLCP() const; 97 bool needsLensfun() const; 98 // static cmsUInt8Number* Mempro = NULL; 99 100 101 public: 102 enum class Median { 103 TYPE_3X3_SOFT, 104 TYPE_3X3_STRONG, 105 TYPE_5X5_SOFT, 106 TYPE_5X5_STRONG, 107 TYPE_7X7, 108 TYPE_9X9 109 }; 110 111 double lumimul[3]; 112 113 explicit ImProcFunctions(const procparams::ProcParams* iparams, bool imultiThread = true) monitorTransform(nullptr)114 : monitorTransform(nullptr), params(iparams), scale(1), multiThread(imultiThread), lumimul{} {} 115 ~ImProcFunctions(); needsLuminanceOnly()116 bool needsLuminanceOnly() 117 { 118 return !(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient()); 119 } 120 void setScale(double iscale); 121 122 bool needsTransform(int oW, int oH, int rawRotationDeg, const FramesMetaData *metadata) const; 123 bool needsPCVignetting() const; 124 125 void firstAnalysis(const Imagefloat* const working, const procparams::ProcParams ¶ms, LUTu & vhist16); 126 void updateColorProfiles(const Glib::ustring& monitorProfile, RenderingIntent monitorIntent, bool softProof, bool gamutCheck); 127 void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, 128 int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, 129 const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, 130 const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, 131 double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf, 132 const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); 133 void rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer *pipetteBuffer, const LUTf& hltonecurve, const LUTf& shtonecurve, const LUTf& tonecurve, 134 int sat, const LUTf& rCurve, const LUTf& gCurve, const LUTf& bCurve, float satLimit, float satLimitOpacity, const ColorGradientCurve& ctColorCurve, 135 const OpacityCurve& ctOpacityCurve, bool opautili, const LUTf& clcurve, const LUTf& cl2curve, const ToneCurve& customToneCurve1, 136 const ToneCurve& customToneCurve2, const ToneCurve& customToneCurvebw1, const ToneCurve& customToneCurvebw2, 137 double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, 138 int hlcomprthresh, DCPProfile *dcpProf, const DCPProfileApplyState& asIn, LUTu& histToneCurve, size_t chunkSize = 1, bool measure = false); 139 void labtoning(float r, float g, float b, float &ro, float &go, float &bo, int algm, int metchrom, int twoc, float satLimit, float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, const LUTf & clToningcurve, const LUTf & cl2Toningcurve, float iplow, float iphigh, double wp[3][3], double wip[3][3]); 140 void toning2col(float r, float g, float b, float &ro, float &go, float &bo, float iplow, float iphigh, float rl, float gl, float bl, float rh, float gh, float bh, float SatLow, float SatHigh, float balanS, float balanH, float reducac, int mode, int preser, float strProtect); 141 void toningsmh(float r, float g, float b, float &ro, float &go, float &bo, float RedLow, float GreenLow, float BlueLow, float RedMed, float GreenMed, float BlueMed, float RedHigh, float GreenHigh, float BlueHigh, float reducac, int mode, float strProtect); 142 void toningsmh2(float r, float g, float b, float &ro, float &go, float &bo, float low[3], float satLow, float med[3], float satMed, float high[3], float satHigh, float reducac, int mode, int preser); 143 void secondeg_begin(float reducac, float vend, float &aam, float &bbm); 144 void secondeg_end(float reducac, float vinf, float &aa, float &bb, float &cc); 145 146 void retreavergb(float &r, float &g, float &b); 147 void moyeqt(Imagefloat* working, float &moyS, float &eqty); 148 149 void luminanceCurve(LabImage* lold, LabImage* lnew, const LUTf &curve); 150 void ciecam_02float(CieImage* ncie, float adap, int pW, int pwb, LabImage* lab, const procparams::ProcParams* params, 151 const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, 152 LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, bool execsharp, float &d, float &dj, float &yb, int rtt, 153 bool showSharpMask = false); 154 void chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, const LUTf& acurve, const LUTf& bcurve, const LUTf& satcurve, const LUTf& satclcurve, const LUTf& clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLurve); 155 void vibrance(LabImage* lab); //Jacques' vibrance 156 // void colorCurve (LabImage* lold, LabImage* lnew); 157 void sharpening(LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask = false); 158 void sharpeningcam(CieImage* ncie, float** buffer, bool showMask = false); 159 void transform(Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const FramesMetaData *metadata, int rawRotationDeg, bool fullImage, bool useOriginalBuffer = false); 160 float resizeScale(const procparams::ProcParams* params, int fw, int fh, int &imw, int &imh); 161 void lab2monitorRgb(LabImage* lab, Image8* image); 162 void resize(Imagefloat* src, Imagefloat* dst, float dScale); 163 void Lanczos(const LabImage* src, LabImage* dst, float scale); 164 void Lanczos(const Imagefloat* src, Imagefloat* dst, float scale); 165 166 void deconvsharpening(float** luminance, float** buffer, const float* const * blend, int W, int H, const procparams::SharpeningParams &sharpenParam, double Scale); 167 void MLsharpen(LabImage* lab); // Manuel's clarity / sharpening 168 void MLmicrocontrast(float** luminance, int W, int H); //Manuel's microcontrast 169 void MLmicrocontrast(LabImage* lab); //Manuel's microcontrast 170 void MLmicrocontrastcam(CieImage* ncie); //Manuel's microcontrast 171 172 void impulsedenoise(LabImage* lab); //Emil's impulse denoise 173 void impulsedenoisecam(CieImage* ncie, float **buffers[3]); 174 void impulse_nr(LabImage* lab, double thresh); 175 void impulse_nrcam(CieImage* ncie, double thresh, float **buffers[3]); 176 177 void dirpyrdenoise(LabImage* src); //Emil's pyramid denoise 178 void dirpyrequalizer(LabImage* lab, int scale); //Emil's wavelet 179 180 181 void EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params& cp, int W_L, int H_L, float max0, float min0); 182 void CompressDR(float *Source, int W_L, int H_L, float Compression, float DetailBoost); 183 void ContrastResid(float * WavCoeffs_L0, struct cont_params &cp, int W_L, int H_L, float max0, float min0); 184 185 void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); 186 void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, int Wid, int Hei, float minQ, float maxQ, unsigned int Iterates = 0, int skip = 1); 187 188 // pyramid denoise 189 // procparams::DirPyrDenoiseParams dnparams; 190 void dirpyr(LabImage* data_fine, LabImage* data_coarse, int level, LUTf &rangefn_L, LUTf &rangefn_ab, 191 int pitch, int scale, const int luma, int chroma); 192 void idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, 193 int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/); 194 195 void Tile_calc(int tilesize, int overlap, int kall, int imwidth, int imheight, int &numtiles_W, int &numtiles_H, int &tilewidth, int &tileheight, int &tileWskip, int &tileHskip); 196 void ip_wavelet(LabImage * lab, LabImage * dst, int kall, const procparams::WaveletParams & waparams, const WavCurve & wavCLVCcurve, const WavOpacityCurveRG & waOpacityCurveRG, const WavOpacityCurveBY & waOpacityCurveBY, const WavOpacityCurveW & waOpacityCurveW, const WavOpacityCurveWL & waOpacityCurveWL, LUTf &wavclCurve, int skip); 197 198 void WaveletcontAllL(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_L, 199 struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); 200 void WaveletcontAllLfinal(wavelet_decomposition &WaveletCoeffs_L, struct cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); 201 void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_a, const WavOpacityCurveW & waOpacityCurveW, 202 struct cont_params &cp, const bool useChannelA); 203 void WaveletAandBAllAB(wavelet_decomposition &WaveletCoeffs_a, wavelet_decomposition &WaveletCoeffs_b, 204 struct cont_params &cp, FlatCurve* hhcurve, bool hhutili); 205 void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, 206 int W_L, int H_L, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); 207 void finalContAllL(float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, 208 int W_L, int H_L, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); 209 void ContAllAB(LabImage * lab, int maxlvl, float **varhue, float **varchrom, float ** WavCoeffs_a, float * WavCoeffs_a0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params &cp, 210 int W_ab, int H_ab, const bool useChannelA); 211 void Evaluate2(wavelet_decomposition &WaveletCoeffs_L, 212 float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); 213 void Eval2(float ** WavCoeffs_L, int level, 214 int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); 215 216 void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); 217 void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); 218 void calckoe(float ** WavCoeffs_LL, const struct cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); 219 220 221 222 void Median_Denoise(float **src, float **dst, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); 223 void Median_Denoise(float **src, float **dst, float upperBound, int width, int height, Median medianType, int iterations, int numThreads, float **buffer = nullptr); 224 void RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi); 225 void RGB_denoise_infoGamCurve(const procparams::DirPyrDenoiseParams & dnparams, const bool isRAW, LUTf &gamcurve, float &gam, float &gamthresh, float &gamslope); 226 void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); 227 void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT 228 void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); 229 bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); 230 bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); 231 void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, 232 const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, 233 float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); 234 235 bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); 236 bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, 237 const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); 238 void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); 239 void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, 240 float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false); 241 void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, 242 int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, 243 float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); 244 void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); 245 void calcautodn_info(float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); 246 float Mad(const float * DataList, int datalen); 247 float MadRgb(const float * DataList, int datalen); 248 249 // pyramid wavelet 250 void dirpyr_equalizer(const float * const * src, float ** dst, int srcwidth, int srcheight, const float * const * l_a, const float * const * l_b, const double * mult, double dirpyrThreshold, double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet 251 void dirpyr_equalizercam(const CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, const float * const * h_p, const float * const * C_p, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet 252 void defringe(LabImage* lab); 253 void defringecam(CieImage* ncie); 254 void badpixcam(CieImage* ncie, double rad, int thr, int mode, float chrom, bool hotbad); 255 void badpixlab(LabImage* lab, double rad, int thr, float chrom); 256 257 void PF_correct_RT(LabImage * lab, double radius, int thresh); 258 void PF_correct_RTcam(CieImage * ncie, double radius, int thresh); 259 void Badpixelscam(CieImage * ncie, double radius, int thresh, int mode, float chrom, bool hotbad); 260 void BadpixelsLab(LabImage * lab, double radius, int thresh, float chrom); 261 262 void dehaze(Imagefloat *rgb); 263 void ToneMapFattal02(Imagefloat *rgb); 264 void localContrast(LabImage *lab); 265 void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); 266 void shadowsHighlights(LabImage *lab); 267 void softLight(LabImage *lab); 268 void labColorCorrectionRegions(LabImage *lab); 269 270 Image8* lab2rgb(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, bool consider_histogram_settings = true); 271 Imagefloat* lab2rgbOut(LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm); 272 // CieImage *ciec; 273 void workingtrc(const Imagefloat* src, Imagefloat* dst, int cw, int ch, int mul, const Glib::ustring &profile, double gampos, double slpos, cmsHTRANSFORM &transform, bool normalizeIn = true, bool normalizeOut = true, bool keepTransForm = false) const; 274 275 bool transCoord(int W, int H, int x, int y, int w, int h, int& xv, int& yv, int& wv, int& hv, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr) const; 276 bool transCoord(int W, int H, const std::vector<Coord2D> &src, std::vector<Coord2D> &red, std::vector<Coord2D> &green, std::vector<Coord2D> &blue, double ascaleDef = -1, const LensCorrection *pLCPMap = nullptr) const; 277 static void getAutoExp(const LUTu & histogram, int histcompr, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh); 278 static double getAutoDistor(const Glib::ustring& fname, int thumb_size); 279 double getTransformAutoFill(int oW, int oH, const LensCorrection *pLCPMap = nullptr) const; 280 void rgb2lab(const Imagefloat &src, LabImage &dst, const Glib::ustring &workingSpace); 281 void lab2rgb(const LabImage &src, Imagefloat &dst, const Glib::ustring &workingSpace); 282 }; 283 284 } 285