305 lines
16 KiB
C++
305 lines
16 KiB
C++
/*
|
|
* This file is part of RawTherapee.
|
|
*
|
|
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
|
*
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef _IMPROCFUN_H_
|
|
#define _IMPROCFUN_H_
|
|
|
|
#include "imagefloat.h"
|
|
#include "image16.h"
|
|
#include "image8.h"
|
|
#include "procparams.h"
|
|
#include "shmap.h"
|
|
#include "coord2d.h"
|
|
#include "color.h"
|
|
#include "labimage.h"
|
|
#include "cieimage.h"
|
|
#include "LUT.h"
|
|
#include "lcp.h"
|
|
#include "curves.h"
|
|
#include <fftw3.h>
|
|
#include "cplx_wavelet_dec.h"
|
|
#include "editbuffer.h"
|
|
|
|
|
|
namespace rtengine {
|
|
|
|
using namespace procparams;
|
|
|
|
class ImProcFunctions {
|
|
|
|
static LUTf gamma2curve;
|
|
|
|
cmsHTRANSFORM monitorTransform;
|
|
|
|
const ProcParams* params;
|
|
double scale;
|
|
bool multiThread;
|
|
|
|
void calcVignettingParams(int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul);
|
|
|
|
void transformPreview (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap);
|
|
void transformLuminanceOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH);
|
|
void transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap, bool fullImage);
|
|
|
|
void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H);
|
|
void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H);
|
|
void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to);
|
|
void dcdamping (float** aI, float** aO, float damping, int W, int H);
|
|
|
|
bool needsCA ();
|
|
bool needsDistortion ();
|
|
bool needsRotation ();
|
|
bool needsPerspective ();
|
|
bool needsGradient ();
|
|
bool needsVignetting ();
|
|
bool needsLCP ();
|
|
// static cmsUInt8Number* Mempro = NULL;
|
|
|
|
inline void interpolateTransformCubic (Imagefloat* src, int xs, int ys, double Dx, double Dy, float *r, float *g, float *b, double mul) {
|
|
const double A=-0.85;
|
|
|
|
double w[4];
|
|
|
|
{
|
|
double t1, t2;
|
|
t1 = -A*(Dx-1.0)*Dx;
|
|
t2 = (3.0-2.0*Dx)*Dx*Dx;
|
|
w[3] = t1*Dx;
|
|
w[2] = t1*(Dx-1.0) + t2;
|
|
w[1] = -t1*Dx + 1.0 - t2;
|
|
w[0] = -t1*(Dx-1.0);
|
|
}
|
|
|
|
double rd, gd, bd;
|
|
double yr[4], yg[4], yb[4];
|
|
|
|
for (int k=ys, kx=0; k<ys+4; k++, kx++) {
|
|
rd = gd = bd = 0.0;
|
|
for (int i=xs, ix=0; i<xs+4; i++, ix++) {
|
|
rd += src->r(k,i) * w[ix];
|
|
gd += src->g(k,i) * w[ix];
|
|
bd += src->b(k,i) * w[ix];
|
|
}
|
|
yr[kx] = rd; yg[kx] = gd; yb[kx] = bd;
|
|
}
|
|
|
|
|
|
{
|
|
double t1, t2;
|
|
|
|
t1 = -A*(Dy-1.0)*Dy;
|
|
t2 = (3.0-2.0*Dy)*Dy*Dy;
|
|
w[3] = t1*Dy;
|
|
w[2] = t1*(Dy-1.0) + t2;
|
|
w[1] = -t1*Dy + 1.0 - t2;
|
|
w[0] = -t1*(Dy-1.0);
|
|
}
|
|
|
|
rd = gd = bd = 0.0;
|
|
for (int i=0; i<4; i++) {
|
|
rd += yr[i] * w[i];
|
|
gd += yg[i] * w[i];
|
|
bd += yb[i] * w[i];
|
|
}
|
|
|
|
*r = rd * mul;
|
|
*g = gd * mul;
|
|
*b = bd * mul;
|
|
|
|
// if (xs==100 && ys==100)
|
|
// printf ("r=%g, g=%g\n", *r, *g);
|
|
}
|
|
|
|
inline void interpolateTransformChannelsCubic (float** src, int xs, int ys, double Dx, double Dy, float *r, double mul) {
|
|
const double A=-0.85;
|
|
|
|
double w[4];
|
|
|
|
{
|
|
double t1, t2;
|
|
t1 = -A*(Dx-1.0)*Dx;
|
|
t2 = (3.0-2.0*Dx)*Dx*Dx;
|
|
w[3] = t1*Dx;
|
|
w[2] = t1*(Dx-1.0) + t2;
|
|
w[1] = -t1*Dx + 1.0 - t2;
|
|
w[0] = -t1*(Dx-1.0);
|
|
}
|
|
|
|
double rd;
|
|
double yr[4];
|
|
|
|
for (int k=ys, kx=0; k<ys+4; k++, kx++) {
|
|
rd = 0.0;
|
|
for (int i=xs, ix=0; i<xs+4; i++, ix++) {
|
|
rd += src[k][i] * w[ix];
|
|
}
|
|
yr[kx] = rd;
|
|
}
|
|
|
|
|
|
{
|
|
double t1, t2;
|
|
t1 = -A*(Dy-1.0)*Dy;
|
|
t2 = (3.0-2.0*Dy)*Dy*Dy;
|
|
w[3] = t1*Dy;
|
|
w[2] = t1*(Dy-1.0) + t2;
|
|
w[1] = -t1*Dy + 1.0 - t2;
|
|
w[0] = -t1*(Dy-1.0);
|
|
}
|
|
|
|
rd = 0.0;
|
|
for (int i=0; i<4; i++)
|
|
rd += yr[i] * w[i];
|
|
|
|
*r = rd * mul;
|
|
}
|
|
|
|
|
|
public:
|
|
|
|
bool iGamma; // true if inverse gamma has to be applied in rgbProc
|
|
double g;
|
|
static LUTf cachef;
|
|
float noisered;
|
|
float noiseblue;
|
|
bool perf;
|
|
|
|
double lumimul[3];
|
|
|
|
static void initCache ();
|
|
static void cleanupCache ();
|
|
|
|
ImProcFunctions (const ProcParams* iparams, bool imultiThread=true)
|
|
: monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread), iGamma(true), g(0.0) {}
|
|
~ImProcFunctions ();
|
|
|
|
void setScale (double iscale);
|
|
|
|
bool needsTransform ();
|
|
bool needsPCVignetting ();
|
|
|
|
void firstAnalysis (Imagefloat* working, const ProcParams* params, LUTu & vhist16, double gamma);
|
|
void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
|
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
|
const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob);
|
|
void rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve,
|
|
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
|
|
const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob,
|
|
double expcomp, int hlcompr, int hlcomprthresh);
|
|
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
|
|
void ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params,
|
|
const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3,
|
|
LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d, int scalecd, int rtt);
|
|
void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params,
|
|
const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3,
|
|
LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d, int scalecd, int rtt);
|
|
void chromiLuminanceCurve (EditBuffer *editBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve);
|
|
void vibrance (LabImage* lab);//Jacques' vibrance
|
|
void colorCurve (LabImage* lold, LabImage* lnew);
|
|
void sharpening (LabImage* lab, float** buffer);
|
|
void sharpeningcam (CieImage* ncie, float** buffer);
|
|
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
|
|
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
|
|
void lab2monitorRgb (LabImage* lab, Image8* image);
|
|
void resize (Image16* src, Image16* dst, float dScale);
|
|
// void Lanczoslab (LabImage* src, LabImage* dst, float scale);
|
|
|
|
void deconvsharpening (LabImage* lab, float** buffer);
|
|
void deconvsharpeningcam (CieImage* ncie, float** buffer);
|
|
void MLsharpen (LabImage* lab);// Manuel's clarity / sharpening
|
|
void MLmicrocontrast(LabImage* lab ); //Manuel's microcontrast
|
|
void MLmicrocontrastcam(CieImage* ncie ); //Manuel's microcontrast
|
|
|
|
void impulsedenoise (LabImage* lab);//Emil's impulse denoise
|
|
void impulsedenoisecam (CieImage* ncie);
|
|
void impulse_nr (LabImage* lab, double thresh);
|
|
void impulse_nrcam (CieImage* ncie, double thresh);
|
|
|
|
void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise
|
|
void dirpyrequalizer (LabImage* lab, int scale);//Emil's equalizer
|
|
|
|
void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1);
|
|
void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates=0, int skip =1);
|
|
// void CAT02 (Imagefloat* baseImg, const ProcParams* params);
|
|
|
|
// pyramid denoise
|
|
procparams::DirPyrDenoiseParams dnparams;
|
|
void dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams );//Emil's directional pyramid denoise
|
|
void dirpyr (LabImage* data_fine, LabImage* data_coarse, int level, LUTf &rangefn_L, LUTf &rangefn_ab,
|
|
int pitch, int scale, const int luma, int chroma );
|
|
void idirpyr (LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab,
|
|
int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/ );
|
|
|
|
// FT denoise
|
|
//void RGB_InputTransf(Imagefloat * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe);
|
|
//void RGB_OutputTransf(LabImage * src, Imagefloat * dst, const procparams::DirPyrDenoiseParams & dnparams);
|
|
//void output_tile_row (float *Lbloxrow, float ** Lhipassdn, float ** tilemask, int height, int width, int top, int blkrad );
|
|
void RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp);
|
|
void RGBtile_denoise (float * fLblox, int hblproc, float noisevar_L, float * nbrwt, float * blurbuffer ); //for DCT
|
|
void RGBoutput_tile_row (float *Lbloxrow, float ** Ldetail, float ** tilemask_out, int height, int width, int top );
|
|
//void WaveletDenoise(cplx_wavelet_decomposition &DualTreeCoeffs, float noisevar );
|
|
//void WaveletDenoise(wavelet_decomposition &WaveletCoeffs, float noisevar );
|
|
// void WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a,
|
|
// wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_ab, wavelet_decomposition &wch, NoiImage * noi );
|
|
void WaveletDenoiseAll(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a,
|
|
wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi );
|
|
|
|
void WaveletDenoiseAll_BiShrink(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_a,
|
|
wavelet_decomposition &WaveletCoeffs_b, float noisevar_L, float noisevar_abr, float noisevar_abb, LabImage * noi);
|
|
//void BiShrink(float * ReCoeffs, float * ImCoeffs, float * ReParents, float * ImParents,
|
|
// int W, int H, int level, int padding, float noisevar);
|
|
//void Shrink(float ** WavCoeffs, int W, int H, int level, float noisevar);
|
|
// void ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level,
|
|
// int W_L, int H_L, int W_ab, int H_ab, int W_h, int H_h, int skip_L, int skip_ab, int skip_h, float noisevar_L, float noisevar_ab, float **WavCoeffs_h, LabImage * noi);
|
|
|
|
void ShrinkAll(float ** WavCoeffs_L, float ** WavCoeffs_a, float ** WavCoeffs_b, int level,
|
|
int W_L, int H_L, int W_ab, int H_ab, int skip_L, int skip_ab, float noisevar_L, float noisevar_abr, float noisevar_abb,LabImage * noi, float * madaa = NULL, float * madab = NULL, float * madaL = NULL, bool madCalculated = false);
|
|
|
|
float MadMax(float * HH_Coeffs, int &max, int datalen);
|
|
float Mad(float * HH_Coeffs, int datalen, int * histo);
|
|
|
|
// pyramid equalizer
|
|
void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid equalizer
|
|
void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid equalizer
|
|
void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, int level, int scale, float ** l_a_h, float ** l_b_c, bool ciec);
|
|
void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[5], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, bool ciec, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice);
|
|
|
|
void defringe (LabImage* lab);
|
|
void defringecam (CieImage* ncie);
|
|
void badpixcam (CieImage* ncie, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad);
|
|
void badpixlab (LabImage* lab, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom);
|
|
|
|
void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh);
|
|
void PF_correct_RTcam (CieImage * src, CieImage * dst, double radius, int thresh);
|
|
void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad);
|
|
void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom);
|
|
|
|
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma);
|
|
Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw);// for gamma output
|
|
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw);//without gamma ==>default
|
|
// CieImage *ciec;
|
|
|
|
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 LCPMapper *pLCPMap=NULL);
|
|
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 LCPMapper *pLCPMap=NULL);
|
|
static void getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh);
|
|
static double getAutoDistor (const Glib::ustring& fname, int thumb_size);
|
|
double getTransformAutoFill (int oW, int oH, const LCPMapper *pLCPMap=NULL);
|
|
};
|
|
}
|
|
#endif
|