diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index cd2242c7d..683810a50 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -422,6 +422,8 @@ HISTORY_MSG_195;CAM02 - Courbe tonale
HISTORY_MSG_196;CAM02 - Courbe tonale 2
HISTORY_MSG_197;CAM02 - Courbe couleur
HISTORY_MSG_198;CAM02 - Courbe couleur
+HISTORY_MSG_199;CAM02 - Montre les histogrammes CIECAM
+HISTORY_MSG_200;CAM02 - Compression tonale avec Q
HISTORY_NEWSNAPSHOTAS;Sous...
HISTORY_NEWSNAPSHOT;Ajouter
HISTORY_NEWSSDIALOGLABEL;Label de la capture:
@@ -682,6 +684,9 @@ PREFERENCES_D50;5000K
PREFERENCES_D55;5500K
PREFERENCES_D60;6000K
PREFERENCES_D65;6500K
+PREFERENCES_CIEART;CIECAM02 optimisation
+PREFERENCES_CIEART_LABEL;Utilise la précision float au lieu de double pour CIECAM02
+PREFERENCES_CIEART_TOOLTIP;Si activé, les calculs CIECAM sont réalisés en précision float au lieu de précision double. Cela amène un léger accroissement de vitesse, et une légère réduction de qualité
PREFERENCES_DARKFRAMEFOUND;Trouvé
PREFERENCES_DARKFRAMESHOTS;image(s)
PREFERENCES_DARKFRAMETEMPLATES;modèle(s)
@@ -980,7 +985,7 @@ TP_CROP_X;X
TP_CROP_Y;Y
TP_DARKFRAME_AUTOSELECT;Sélection automatique
TP_DARKFRAME_LABEL;Trame Noire
-TP_DEFRINGE_LABEL;Aberration chromatique
+TP_DEFRINGE_LABEL;Aberration chromatique (lab / ciecam02)
TP_DEFRINGE_RADIUS;Rayon
TP_DEFRINGE_THRESHOLD;Seuil
TP_DETAIL_AMOUNT;Quantité
@@ -988,7 +993,7 @@ TP_DIRPYRDENOISE_CHROMA;Chrominance
TP_DIRPYRDENOISE_GAMMA;Gamma
TP_DIRPYRDENOISE_LABEL;Réduction du bruit
TP_DIRPYRDENOISE_LUMA;Luminance
-TP_DIRPYREQUALIZER_LABEL;Contraste par niveaux de détail
+TP_DIRPYREQUALIZER_LABEL;Contraste par niveaux de détail (lab / ciecam02)
TP_DIRPYREQUALIZER_LUMACOARSEST;les plus gros
TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contraste-
TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contraste+
@@ -1000,7 +1005,7 @@ TP_DISTORTION_AUTO;Correction auto de la distorsion
TP_DISTORTION_AUTO_TIP;(Experimental) Corrige la distorsion de l'objectif automatiquement pour certains APN (M4/3, quelques compacts, etc.)
TP_DISTORTION_LABEL;Distorsion
TP_EPD_EDGESTOPPING;Arrêt des bords
-TP_EPD_LABEL;Compression tonale [Lab] ou [CIECAM02]
+TP_EPD_LABEL;Compression tonale (lab / ciecam02)
TP_EPD_REWEIGHTINGITERATES;Itérations de la pondération
TP_EPD_SCALE;Échelle
TP_EPD_STRENGTH;Force
@@ -1197,6 +1202,7 @@ TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste local
TP_SHADOWSHLIGHTS_RADIUS;Rayon
TP_SHADOWSHLIGHTS_SHADOWS;Ombres
TP_SHADOWSHLIGHTS_SHTONALW;Amplitude tonale des ombres
+TP_SHARPENING_TOOLTIP;Un effet légèrement différent peut être obtenu avec CIECAM02. Si différence observée, ajuster les réglages
TP_SHARPENEDGE_AMOUNT;Quantité
TP_SHARPENEDGE_LABEL;Bords
TP_SHARPENEDGE_PASSES;Itérations
@@ -1206,7 +1212,7 @@ TP_SHARPENING_EDRADIUS;Rayon
TP_SHARPENING_EDTOLERANCE;Tolérance des bords
TP_SHARPENING_HALOCONTROL;Contrôle du halo
TP_SHARPENING_HCAMOUNT;Quantité
-TP_SHARPENING_LABEL;Netteté
+TP_SHARPENING_LABEL;Netteté (lab / ciecam02)
TP_SHARPENING_METHOD;Méthode
TP_SHARPENING_ONLYEDGES;Améliorer seulement les bords
TP_SHARPENING_RADIUS;Rayon
@@ -1217,7 +1223,7 @@ TP_SHARPENING_RLD_ITERATIONS;Itérations
TP_SHARPENING_THRESHOLD;Seuil
TP_SHARPENING_USM;Masque flou
TP_SHARPENMICRO_AMOUNT;Quantité
-TP_SHARPENMICRO_LABEL;Microcontraste
+TP_SHARPENMICRO_LABEL;Microcontraste (lab / ciecam02)
TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformité
TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte
@@ -1307,8 +1313,6 @@ ZOOMPANEL_ZOOMOUT;Zoom -
!GENERAL_CLOSE;Close
!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram
-!HISTORY_MSG_199;CAM02 - Show CIECAM in histograms
-!HISTORY_MSG_200;CAM02 - Tone mapping with Q
!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
!PARTIALPASTE_LENSPROFILE;Lens correction profile
!PREFERENCES_FLUOF2;Fluorescent F2
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 6fa811a08..8428dea72 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -425,7 +425,7 @@ HISTORY_MSG_196;CAM02 - Tone curve 2
HISTORY_MSG_197;CAM02 - Color curve
HISTORY_MSG_198;CAM02 - Color curve
HISTORY_MSG_199;CAM02 - Show CIECAM in histograms
-HISTORY_MSG_200;CAM02 - Tone mapping with Q
+HISTORY_MSG_200;CAMO2 - Tone mapping with Q
HISTORY_NEWSNAPSHOTAS;As...
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
@@ -688,6 +688,9 @@ PREFERENCES_D50;5000K
PREFERENCES_D55;5500K
PREFERENCES_D60;6000K
PREFERENCES_D65;6500K
+PREFERENCES_CIEART;CIECAM02 optimization
+PREFERENCES_CIEART_LABEL;Use float precision instead of double in CIECAM02
+PREFERENCES_CIEART_TOOLTIP;If enabled, CIECAM02 calculations are performed in float precision instead of double precision. This provides a small increase in speed at expense of a minor loss of quality
PREFERENCES_DARKFRAMEFOUND;Found
PREFERENCES_DARKFRAMESHOTS;shots
PREFERENCES_DARKFRAMETEMPLATES;templates
@@ -894,9 +897,9 @@ TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally
TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\nShortcut: [
TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\nShortcut: ]
TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically
-TP_COLORAPP_ADAPTSCENE;Adaptation luminosity (cd/m2)
+TP_COLORAPP_ADAPTSCENE;Adaptation scene luminosity(cd/m2)
TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environnement\n(usually 2000cd/m2)
-TP_COLORAPP_ADAPTVIEWING;Adaptation luminosity (cd/m2)
+TP_COLORAPP_ADAPTVIEWING;Adaptation viewing luminosity (cd/m2)
TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m2)
TP_COLORAPP_ALGO;Algorithm
TP_COLORAPP_ALGO_ALL;All
@@ -959,6 +962,8 @@ TP_COLORAPP_TCMODE_LIGHTNESS;Lightness
TP_COLORAPP_TCMODE_SATUR;Saturation
TP_COLORAPP_TONECIE;Tone-mapping with Q brightness CIECAM
TP_COLORAPP_TONECIE_TOOLTIP;Additional tone mapping adjustments are controlled in Tone Mapping section and must be enabled for tone mapping to engage.
+TP_COLORAPP_SHARPCIE;Sharpening & Contrast(det/mic) & Defringe with Q/C
+TP_COLORAPP_SHARPCIE_TOOLTIP;Additional sharpening / Contrast by details / Microcontrast / Defringe are controlled in appropriates sections and must be enabled to engage\n. See label (lab / ciecam02)
TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output]
TP_COLORAPP_WBRT;WB [RT] + [output]
TP_CROP_FIXRATIO;Fix ratio:
@@ -982,7 +987,7 @@ TP_CROP_X;X
TP_CROP_Y;Y
TP_DARKFRAME_AUTOSELECT;Auto selection
TP_DARKFRAME_LABEL;Dark Frame
-TP_DEFRINGE_LABEL;Defringe
+TP_DEFRINGE_LABEL;Defringe (lab / ciecam02)
TP_DEFRINGE_RADIUS;Radius
TP_DEFRINGE_THRESHOLD;Threshold
TP_DIRPYRDENOISE_CHROMA;Chrominance
@@ -990,10 +995,10 @@ TP_DIRPYRDENOISE_GAMMA;Gamma
TP_DIRPYRDENOISE_LABEL;Noise Reduction (raw images only)
TP_DIRPYRDENOISE_LDETAIL;Luminance Detail
TP_DIRPYRDENOISE_LUMA;Luminance
-TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels
+TP_DIRPYREQUALIZER_LABEL;Contrast by Detail Levels (lab / ciecam02)
TP_DIRPYREQUALIZER_LUMACOARSEST;Coarsest
TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast-
-TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+
+TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+
TP_DIRPYREQUALIZER_LUMAFINEST;Finest
TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral
TP_DIRPYREQUALIZER_THRESHOLD;Threshold
@@ -1002,7 +1007,7 @@ TP_DISTORTION_AUTO;Auto Distortion Correction
TP_DISTORTION_AUTO_TIP;(Exprimental) Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.)
TP_DISTORTION_LABEL;Distortion
TP_EPD_EDGESTOPPING;Edge Stopping
-TP_EPD_LABEL;Tone Mapping [Lab] or [CIECAM02]
+TP_EPD_LABEL;Tone Mapping (lab / ciecam02)
TP_EPD_REWEIGHTINGITERATES;Reweighting Iterates
TP_EPD_SCALE;Scale
TP_EPD_STRENGTH;Strength
@@ -1189,6 +1194,7 @@ TP_SHADOWSHLIGHTS_LOCALCONTR;Local Contrast
TP_SHADOWSHLIGHTS_RADIUS;Radius
TP_SHADOWSHLIGHTS_SHADOWS;Shadows
TP_SHADOWSHLIGHTS_SHTONALW;Tonal Width for Shadows
+TP_SHARPENING_TOOLTIP;Expect a slightly different effect when used with CIECAM02. If difference is observed, adjust to taste.
TP_SHARPENEDGE_AMOUNT;Quantity
TP_SHARPENEDGE_LABEL;Edges
TP_SHARPENEDGE_PASSES;Iterations
@@ -1198,7 +1204,7 @@ TP_SHARPENING_EDRADIUS;Radius
TP_SHARPENING_EDTOLERANCE;Edge Tolerance
TP_SHARPENING_HALOCONTROL;Halo control
TP_SHARPENING_HCAMOUNT;Amount
-TP_SHARPENING_LABEL;Sharpening
+TP_SHARPENING_LABEL;Sharpening (lab / ciecam02)
TP_SHARPENING_METHOD;Method
TP_SHARPENING_ONLYEDGES;Sharpen only edges
TP_SHARPENING_RADIUS;Radius
@@ -1209,7 +1215,7 @@ TP_SHARPENING_RLD_ITERATIONS;Iterations
TP_SHARPENING_THRESHOLD;Threshold
TP_SHARPENING_USM;Unsharp Mask
TP_SHARPENMICRO_AMOUNT;Quantity
-TP_SHARPENMICRO_LABEL;Microcontrast
+TP_SHARPENMICRO_LABEL;Microcontrast (lab / ciecam02)
TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5
TP_SHARPENMICRO_UNIFORMITY;Uniformity
TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift
diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc
index ed8f623c7..a6efb85e0 100644
--- a/rtengine/PF_correct_RT.cc
+++ b/rtengine/PF_correct_RT.cc
@@ -79,7 +79,7 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
}
}
chromave /= (height*width);
-
+// printf("Chro %f \n",chromave);
#ifdef _OPENMP
#pragma omp parallel for
#endif
@@ -91,15 +91,15 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
//test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average
/*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/
/*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/
- if (33*fringe[i*width+j]>thresh*chromave) {
- float atot=0;
- float btot=0;
- float norm=0;
+ if (33.f*fringe[i*width+j]>thresh*chromave) {
+ float atot=0.f;
+ float btot=0.f;
+ float norm=0.f;
float wt;
for (int i1=max(0,i-halfwin+1); i1a[i1][j1];
btot += wt*src->b[i1][j1];
norm += wt;
@@ -125,6 +125,145 @@ void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radiu
delete tmp1;
free(fringe);
}
+void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) {
+ int halfwin = ceil(2*radius)+1;
+
+#include "rt_math.h"
+
+ // local variables
+ int width=src->W, height=src->H;
+ float piid=3.14159265f/180.f;
+ //temporary array to store chromaticity
+ int (*fringe);
+ fringe = (int (*)) calloc ((height)*(width), sizeof *fringe);
+
+ float** sraa;
+ sraa = new float*[height];
+ for (int i=0; iC_p[i][j]*cos(piid*src->h_p[i][j]);
+ }
+ float** tmaa;
+ tmaa = new float*[height];
+ for (int i=0; iC_p[i][j]*sin(piid*src->h_p[i][j]);
+ }
+ float** tmbb;
+ tmbb = new float*[height];
+ for (int i=0; i buffer(max(src->W,src->H));
+ gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius);
+ gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius);
+ gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius);
+ gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius);
+ // gaussHorizontal (src->sh_p, tmL, buffer, src->W, src->H, radius);
+ // gaussVertical (tmL, tmL, buffer, src->W, src->H, radius);
+
+ }
+
+//#ifdef _OPENMP
+//#pragma omp parallel for
+//#endif
+ float chromave=0;
+ for(int i = 0; i < height; i++ ) {
+ for(int j = 0; j < width; j++) {
+ float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]);
+ chromave += chroma;
+ fringe[i*width+j]=chroma;
+ }
+ }
+ chromave /= (height*width);
+ // printf("Chromave CAM %f \n",chromave);
+
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+
+ for(int i = 0; i < height; i++ ) {
+ for(int j = 0; j < width; j++) {
+ tmaa[i][j] = sraa[i][j];
+ tmbb[i][j] = srbb[i][j];
+
+ //test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average
+ /*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/
+ /*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/
+ if (33.f*fringe[i*width+j]>thresh*chromave) {
+ float atot=0.f;
+ float btot=0.f;
+ float norm=0.f;
+ float wt;
+ for (int i1=max(0,i-halfwin+1); i1sh_p[i][j] = src->sh_p[i][j];
+ float intera = tmaa[i][j];
+ float interb = tmbb[i][j];
+ dst->h_p[i][j]=(atan2(interb,intera))/piid;
+ dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera));
+ }
+ }
+ for (int i=0; idata, W*H*5*sizeof(float));
+ memcpy(data, Img->data, W*H*6*sizeof(float));
}
}
diff --git a/rtengine/cieimage.h b/rtengine/cieimage.h
index ee9534451..ca6e5785c 100644
--- a/rtengine/cieimage.h
+++ b/rtengine/cieimage.h
@@ -34,7 +34,8 @@ public:
float** Q_p;
float** M_p;
float** C_p;
- //float** s_p;
+ float** sh_p;
+// float** ch_p;
float** h_p;
CieImage (int w, int h);
diff --git a/rtengine/color.cc b/rtengine/color.cc
index 4db2bcce8..738211e92 100644
--- a/rtengine/color.cc
+++ b/rtengine/color.cc
@@ -561,6 +561,48 @@ namespace rtengine {
else s=ko*sres;
}
+ void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s)
+ {
+ float factorskin, factorsat,factor, factorskinext, interm;
+ float scale = 100.0f/100.1f;//reduction in normal zone
+ float scaleext=1.0f;//reduction in transition zone
+ float protect_redh;
+ float deltaHH=0.3f;//HH value transition : I have choice 0.3 radians
+ float HH;
+ bool doskin=false;
+ //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear
+ if ((float)h>8.6f && (float)h<=74.f ) {HH=(1.15f/65.4f)*(float)h-0.0012f; doskin=true;}//H > 0.15 H<1.3
+ else if((float)h>0.f && (float)h<=8.6f ) {HH=(0.19f/8.6f )*(float)h-0.04f; doskin=true;}//H>-0.04 H < 0.15
+ else if((float)h>355.f && (float)h<=360.f) {HH=(0.11f/5.0f )*(float)h-7.96f; doskin=true;}//H>-0.15 <-0.04
+ else if((float)h>74.f && (float)h<95.f ) {HH=(0.30f/21.0f)*(float)h+0.24285f; doskin=true;}//H>1.3 H<1.6
+
+ if(doskin)
+ {
+ float chromapro=sres/Sp;
+ if(sk==1){//in C mode to adapt dred to J
+ if (J<16.0) dred = 40.0f;
+ else if(J<22.0) dred = (4.1666f)*(float)J -26.6f;
+ else if(J<60.0) dred = 55.0f;
+ else if(J<70.0) dred = -1.5f*(float)J +145.0f;
+ else dred = 40.0f;
+ }
+ if(chromapro>0.0) Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor
+ if(chromapro>1.0) {interm=(chromapro-1.0f)*100.0f;
+ factorskin= 1.0f+(interm*scale)/100.0f;
+ factorskinext=1.0f+(interm*scaleext)/100.0f;}
+ else {
+ factorskin= chromapro ;
+ factorskinext= chromapro ;
+ }
+ factorsat=chromapro;
+ factor=factorsat;
+ Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition
+ s*=factor;
+ }
+ else s=ko*sres;
+
+ }
+
void Color::scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext)
diff --git a/rtengine/color.h b/rtengine/color.h
index b0836f1a2..5ddfa91d4 100644
--- a/rtengine/color.h
+++ b/rtengine/color.h
@@ -165,6 +165,7 @@ public:
static void scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale, float &scaleext);
static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor);
static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s);
+ static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s);
//void gamutmap(LabImage* );
static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]);
diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc
index 2bdf6816d..db0b35925 100644
--- a/rtengine/colortemp.cc
+++ b/rtengine/colortemp.cc
@@ -903,6 +903,16 @@ void ColorTemp::curvecolor(double satind, double satval, double &sres, double pa
sres = satval*(1.+(satind)/100.);
}
}
+void ColorTemp::curvecolorfloat(float satind, float satval, float &sres, float parsat) {
+ if (satind >=0.0f) {
+ sres = (1.-(satind)/100.f)*satval+(satind)/100.f*(1.f-SQR(SQR(1.f-min(satval,1.0f))));
+ if (sres>parsat) sres=parsat;
+ if (sres<0.f) sres=0.f;
+ } else {
+ if (satind < -0.1f)
+ sres = satval*(1.f+(satind)/100.f);
+ }
+}
void ColorTemp::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu & histogram ) {
@@ -1001,6 +1011,102 @@ void ColorTemp::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu &
// for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i];
for (int i=0; i<(db*32768); i++) outCurve[i] = db*32768.0*dcurve[i];
}
+void ColorTemp::curveJfloat (float br, float contr, int db, LUTf & outCurve, LUTu & histogram ) {
+ LUTf dcurve(65536,0);
+ int skip=1;
+
+ // check if brightness curve is needed
+ if (br>0.00001f || br<-0.00001f) {
+
+ std::vector brightcurvePoints;
+ brightcurvePoints.resize(9);
+ brightcurvePoints.at(0) = double(DCT_NURBS);
+
+ brightcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range
+ brightcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range
+
+ if (br>0) {
+ brightcurvePoints.at(3) = 0.1f; // toe point
+ brightcurvePoints.at(4) = 0.1f+br/150.0f; //value at toe point
+
+ brightcurvePoints.at(5) = 0.7f; // shoulder point
+ brightcurvePoints.at(6) = min(1.0f,0.7f+br/300.0f); //value at shoulder point
+ } else {
+ brightcurvePoints.at(3) = 0.1f-br/150.0f; // toe point
+ brightcurvePoints.at(4) = 0.1f; // value at toe point
+
+ brightcurvePoints.at(5) = min(1.0f,0.7f-br/300.0f); // shoulder point
+ brightcurvePoints.at(6) = 0.7f; // value at shoulder point
+ }
+ brightcurvePoints.at(7) = 1.f; // white point
+ brightcurvePoints.at(8) = 1.f; // value at white point
+
+ DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip);
+
+ // Applying brightness curve
+ for (int i=0; i<32768; i++) {
+
+ // change to [0,1] range
+ float val = (float)i / 32767.0f;
+
+ // apply brightness curve
+ val = brightcurve->getVal (val);
+
+ // store result in a temporary array
+ dcurve[i] = CLIPD(val);
+ }
+ delete brightcurve;
+ }
+ else {
+ // for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow
+ for (int i=0; i<(32768*db); i++) { // L values range up to 32767, higher values are for highlight overflow
+
+ // set the identity curve in the temporary array
+ dcurve[i] = (float)i / (db*32768.0f);
+ }
+ }
+
+
+ if (contr>0.00001f || contr<-0.00001f) {
+
+ // compute mean luminance of the image with the curve applied
+ int sum = 0;
+ float avg = 0;
+ //float sqavg = 0;
+ for (int i=0; i<32768; i++) {
+ avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J
+ sum += histogram[i];
+ }
+ avg /= sum;
+ std::vector contrastcurvePoints;
+ contrastcurvePoints.resize(9);
+ contrastcurvePoints.at(0) = double(DCT_NURBS);
+
+ contrastcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range
+ contrastcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range
+
+ contrastcurvePoints.at(3) = avg-avg*(0.6f-contr/250.0f); // toe point
+ contrastcurvePoints.at(4) = avg-avg*(0.6f+contr/250.0f); // value at toe point
+
+ contrastcurvePoints.at(5) = avg+(1-avg)*(0.6f-contr/250.0f); // shoulder point
+ contrastcurvePoints.at(6) = avg+(1-avg)*(0.6f+contr/250.0f); // value at shoulder point
+
+ contrastcurvePoints.at(7) = 1.f; // white point
+ contrastcurvePoints.at(8) = 1.f; // value at white point
+
+ DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip);
+
+ // apply contrast enhancement
+ for (int i=0; i<(32768*db); i++) {
+ dcurve[i] = contrastcurve->getVal (dcurve[i]);
+ }
+
+ delete contrastcurve;
+ }
+
+ // for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i];
+ for (int i=0; i<(db*32768); i++) outCurve[i] = db*32768.0f*dcurve[i];
+}
void ColorTemp::cieCAT02(double Xw, double Yw, double Zw, double &CAM02BB00,double &CAM02BB01,double &CAM02BB02,double &CAM02BB10,double &CAM02BB11,double &CAM02BB12,double &CAM02BB20,double &CAM02BB21,double &CAM02BB22, double adap ) {
@@ -1596,8 +1702,131 @@ and also gamut correction M.H.Brill S.Susstrunk
* SOFTWARE.
*
*/
+void ColorTemp::xyz_to_cat02( double &r, double &g, double &b, double x, double y, double z, int gamu )
+{
+gamu=1;
+if(gamu==0){
+ r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
+ g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
+ b = ( 0.0030 * x) + (0.0136 * y) + (0.9834 * z);
+ }
+else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
+ //r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
+ //g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
+ //b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
+ r = ( 1.007245 * x) + (0.011136* y) - (0.018381 * z);//Changjun Li
+ g = (-0.318061 * x) + (1.314589 * y) + (0.003471 * z);
+ b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
+
+}
+}
-inline void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb )
+ void ColorTemp::xyz_to_cat02float( float &r, float &g, float &b, float x, float y, float z, int gamu )
+{
+gamu=1;
+if(gamu==0){
+ r = ( 0.7328f * x) + (0.4296f * y) - (0.1624f * z);
+ g = (-0.7036f * x) + (1.6975f * y) + (0.0061f * z);
+ b = ( 0.0030f * x) + (0.0136f * y) + (0.9834f * z);
+ }
+else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
+ //r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
+ //g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
+ //b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
+ r = ( 1.007245f * x) + (0.011136f* y) - (0.018381f * z);//Changjun Li
+ g = (-0.318061f * x) + (1.314589f * y) + (0.003471f * z);
+ b = ( 0.0000f * x) + (0.0000f * y) + (1.0000f * z);
+
+}
+}
+
+
+ void ColorTemp::cat02_to_xyz( double &x, double &y, double &z, double r, double g, double b, int gamu )
+{
+gamu=1;
+if(gamu==0) {
+ x = ( 1.096124 * r) - (0.278869 * g) + (0.182745 * b);
+ y = ( 0.454369 * r) + (0.473533 * g) + (0.072098 * b);
+ z = (-0.009628 * r) - (0.005698 * g) + (1.015326 * b);
+ }
+else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
+ //x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
+ //y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
+ //z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
+ x = ( 0.99015849 * r) - (0.00838772* g) + (0.018229217 * b);//Changjun Li
+ y = ( 0.239565979 * r) + (0.758664642 * g) + (0.001770137* b);
+ z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
+
+}
+}
+
+ void ColorTemp::cat02_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b, int gamu )
+{
+gamu=1;
+if(gamu==0) {
+ x = ( 1.096124f * r) - (0.278869f * g) + (0.182745f * b);
+ y = ( 0.454369f * r) + (0.473533f * g) + (0.072098f * b);
+ z = (-0.009628f * r) - (0.005698f * g) + (1.015326f * b);
+ }
+else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
+ //x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
+ //y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
+ //z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
+ x = ( 0.99015849f * r) - (0.00838772f* g) + (0.018229217f * b);//Changjun Li
+ y = ( 0.239565979f * r) + (0.758664642f * g) + (0.001770137f* b);
+ z = ( 0.000000f * r) - (0.000000f * g) + (1.000000f * b);
+
+}
+}
+
+
+void ColorTemp::hpe_to_xyz( double &x, double &y, double &z, double r, double g, double b )
+{
+ x = (1.910197 * r) - (1.112124 * g) + (0.201908 * b);
+ y = (0.370950 * r) + (0.629054 * g) - (0.000008 * b);
+ z = b;
+
+}
+
+ void ColorTemp::hpe_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b )
+{
+ x = (1.910197f * r) - (1.112124f * g) + (0.201908f * b);
+ y = (0.370950f * r) + (0.629054f * g) - (0.000008f * b);
+ z = b;
+
+}
+
+
+
+void ColorTemp::cat02_to_hpe( double &rh, double &gh, double &bh, double r, double g, double b, int gamu )
+{ gamu=1;
+ if(gamu==0){
+ rh = ( 0.7409792 * r) + (0.2180250 * g) + (0.0410058 * b);
+ gh = ( 0.2853532 * r) + (0.6242014 * g) + (0.0904454 * b);
+ bh = (-0.0096280 * r) - (0.0056980 * g) + (1.0153260 * b);
+ }
+ else if (gamu==1) {//Changjun Li
+ rh = ( 0.550930835 * r) + (0.519435987* g) - ( 0.070356303* b);
+ gh = ( 0.055954056 * r) + (0.89973132 * g) + (0.044315524 * b);
+ bh = (0.0 * r) - (0.0* g) + (1.0 * b);
+ }
+}
+void ColorTemp::cat02_to_hpefloat( float &rh, float &gh, float &bh, float r, float g, float b, int gamu )
+{ gamu=1;
+ if(gamu==0){
+ rh = ( 0.7409792f * r) + (0.2180250f * g) + (0.0410058f * b);
+ gh = ( 0.2853532f * r) + (0.6242014f * g) + (0.0904454f * b);
+ bh = (-0.0096280f * r) - (0.0056980f * g) + (1.0153260f * b);
+ }
+ else if (gamu==1) {//Changjun Li
+ rh = ( 0.550930835f * r) + (0.519435987f* g) - ( 0.070356303f* b);
+ gh = ( 0.055954056f * r) + (0.89973132f * g) + (0.044315524f * b);
+ bh = (0.0f * r) - (0.0f* g) + (1.0f * b);
+ }
+}
+
+
+ void ColorTemp::Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb )
{
double x = (A / nbb) + 0.305;
@@ -1608,8 +1837,19 @@ inline void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, do
/* c1 c6 c7 */
b = (0.32787 * x) - (0.15681 * aa) - (4.49038 * bb);
}
+ void ColorTemp::Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb )
+{
+ float x = (A / nbb) + 0.305f;
-inline void calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a )
+ /* c1 c2 c3 */
+ r = (0.32787f * x) + (0.32145f * aa) + (0.20527f * bb);
+ /* c1 c4 c5 */
+ g = (0.32787f * x) - (0.63507f * aa) - (0.18603f * bb);
+ /* c1 c6 c7 */
+ b = (0.32787f * x) - (0.15681f * aa) - (4.49038f * bb);
+}
+
+void ColorTemp::calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a )
{
double hrad = (h * M_PI) / 180.0;
double sinh = sin( hrad );
@@ -1636,6 +1876,36 @@ inline void calculate_ab( double &aa, double &bb, double h, double e, double t,
bb = (aa * sinh) / cosh;
}
}
+void ColorTemp::calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a )
+{
+ float hrad = (h * M_PI) / 180.0f;
+ float sinh = sin( hrad );
+ float cosh = cos( hrad );
+ float x = (a / nbb) + 0.305f;
+ float p3 = 21.0f/20.0f;
+ if( fabs( sinh ) >= fabs( cosh ) ) {
+ bb = ((0.32787f * x) * (2.0f + p3)) /
+ ((e / (t * sinh)) -
+ // ((0.32145 - 0.63507 - (p3 * 0.15681)) * (cosh / sinh)) -
+ // (0.20527 - 0.18603 - (p3 * 4.49038)));
+ ((-0.31362f - (p3 * 0.15681f)) * (cosh / sinh)) -
+ (0.01924f - (p3 * 4.49038f)));
+
+ aa = (bb * cosh) / sinh;
+ } else {
+ aa = ((0.32787f * x) * (2.0f + p3)) /
+ ((e / (t * cosh)) -
+ // (0.32145 - 0.63507 - (p3 * 0.15681)) -
+ // ((0.20527 - 0.18603 - (p3 * 4.49038)) * (sinh / cosh)));
+ (-0.31362f - (p3 * 0.15681f)) -
+ ((0.01924f - (p3 * 4.49038f)) * (sinh / cosh)));
+
+ bb = (aa * sinh) / cosh;
+ }
+}
+
+
+
void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q, double &M, double &s,double &aw, double &fl, double &wh,
double x, double y, double z, double xw, double yw, double zw,
double yb, double la, double f, double c, double nc, double pilotd, bool doneinit, int gamu)
@@ -1727,6 +1997,98 @@ void ColorTemp::xyz2jchqms_ciecam02( double &J, double &C, double &h, double &Q,
}
+void ColorTemp::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s,float &aw, float &fl, float &wh,
+ float x, float y, float z, float xw, float yw, float zw,
+ float yb, float la, float f, float c, float nc, float pilotd, bool doneinit, int gamu)
+{
+ float r, g, b;
+ float rw, gw, bw;
+ float rc, gc, bc;
+ float rp, gp, bp;
+ float rpa, gpa, bpa;
+ float a, ca, cb;
+ float d;
+ float n, nbb, ncb;
+ float e, t;
+ float cz;
+ float myh, myj, myc, myq, mym, mys;
+ float pfl;
+ gamu=1;
+ xyz_to_cat02float( r, g, b, x, y, z, gamu );
+ xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
+
+ if(doneinit){//if one day, we have a pipette...
+ n = yb / yw;
+ if(pilotd==2.0) d = d_factorfloat( f, la );else d=pilotd;
+ fl = calculate_fl_from_la_ciecam02float( la );
+ nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
+ cz = 1.48f + sqrt( n );
+ aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
+ wh =( 4.0f / c ) * ( aw + 4.0f ) * pow_F( fl, 0.25f );
+ pfl = pow_F( fl, 0.25f );
+ doneinit=false;
+ }
+
+ rc = r * (((yw * d) / rw) + (1.0 - d));
+ gc = g * (((yw * d) / gw) + (1.0 - d));
+ bc = b * (((yw * d) / bw) + (1.0 - d));
+
+ ColorTemp::cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu );
+ if(gamu==1){//gamut correction M.H.Brill S.Susstrunk
+ rp=MAXR(rp,0.0f);
+ gp=MAXR(gp,0.0f);
+ bp=MAXR(bp,0.0f);
+ }
+ rpa = nonlinear_adaptationfloat( rp, fl );
+ gpa = nonlinear_adaptationfloat( gp, fl );
+ bpa = nonlinear_adaptationfloat( bp, fl );
+
+ ca = rpa - ((12.0f * gpa) / 11.0f) + (bpa / 11.0f);
+ cb = (1.0f / 9.0f) * (rpa + gpa - (2.0f * bpa));
+
+ myh = (180.0f / M_PI) * atan2( cb, ca );
+ if( myh < 0.0f ) myh += 360.0f;
+ //we can also calculate H, if necessary...but it's using time...for what usage ?
+ /*double temp;
+ if(myh<20.14) {
+ temp = ((myh + 122.47)/1.2) + ((20.14 - myh)/0.8);
+ H = 300 + (100*((myh + 122.47)/1.2)) / temp;
+ }
+ else if(myh < 90.0) {
+ temp = ((myh - 20.14)/0.8) + ((90.00 - myh)/0.7);
+ H = (100*((myh - 20.14)/0.8)) / temp;
+ }
+ else if (myh < 164.25) {
+ temp = ((myh - 90.00)/0.7) + ((164.25 - myh)/1.0);
+ H = 100 + ((100*((myh - 90.00)/0.7)) / temp);
+ }
+ else if (myh < 237.53) {
+ temp = ((myh - 164.25)/1.0) + ((237.53 - myh)/1.2);
+ H = 200 + ((100*((myh - 164.25)/1.0)) / temp);
+ }
+ else {
+ temp = ((myh - 237.53)/1.2) + ((360 - myh + 20.14)/0.8);
+ H = 300 + ((100*((myh - 237.53)/1.2)) / temp);
+ }
+ */
+ a = ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb;
+ if (gamu==1) a=MAXR(a,0.0f);//gamut correction M.H.Brill S.Susstrunk
+ J = 100.0f * pow_F( a / aw, c * cz );
+
+ e = ((12500.0f / 13.0f) * nc * ncb) * (cos( ((myh * M_PI) / 180.0f) + 2.0f ) + 3.8f);
+ t = (e * sqrt( (ca * ca) + (cb * cb) )) / (rpa + gpa + ((21.0f / 20.0f) * bpa));
+
+ C = pow_F( t, 0.9f ) * sqrt( J / 100.0f )
+ * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f );
+
+ Q = wh * sqrt( J / 100.0f );
+ M = C * pfl;
+ s = 100.0f * sqrt( M / Q );
+ h = myh;
+
+}
+
+
void ColorTemp::jch2xyz_ciecam02( double &x, double &y, double &z, double J, double C, double h,
double xw, double yw, double zw, double yb, double la,
@@ -1775,6 +2137,53 @@ void ColorTemp::jch2xyz_ciecam02( double &x, double &y, double &z, double J, dou
ColorTemp::cat02_to_xyz( x, y, z, r, g, b, gamu );
}
+void ColorTemp::jch2xyz_ciecam02float( float &x, float &y, float &z, float J, float C, float h,
+ float xw, float yw, float zw, float yb, float la,
+ float f, float c, float nc , bool doneinit2, int gamu)
+{
+ float r, g, b;
+ float rc, gc, bc;
+ float rp, gp, bp;
+ float rpa, gpa, bpa;
+ float rw, gw, bw;
+ float fl, d;
+ float n, nbb, ncb;
+ float a, ca, cb;
+ float aw;
+ float e, t;
+ float cz;
+ gamu=1;
+ ColorTemp::xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu );
+ if(doneinit2){
+ n = yb / yw;
+ d = d_factorfloat( f, la );
+ fl = calculate_fl_from_la_ciecam02float( la );
+ nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f );
+ cz = 1.48f + sqrt( n );
+ aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu );
+ doneinit2=false;
+ }
+ e = ((12500.0f / 13.0f) * nc * ncb) * (cos( ((h * M_PI) / 180.0f) + 2.0f ) + 3.8f);
+ a = pow_F( J / 100.0f, 1.0f / (c * cz) ) * aw;
+ t = pow_F( C / (sqrt( J / 100.f) * pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f )), 10.0f / 9.0f );
+
+ calculate_abfloat( ca, cb, h, e, t, nbb, a );
+ Aab_to_rgbfloat( rpa, gpa, bpa, a, ca, cb, nbb );
+
+ rp = inverse_nonlinear_adaptationfloat( rpa, fl );
+ gp = inverse_nonlinear_adaptationfloat( gpa, fl );
+ bp = inverse_nonlinear_adaptationfloat( bpa, fl );
+
+ ColorTemp::hpe_to_xyzfloat( x, y, z, rp, gp, bp );
+ ColorTemp::xyz_to_cat02float( rc, gc, bc, x, y, z, gamu );
+
+ r = rc / (((yw * d) / rw) + (1.0f - d));
+ g = gc / (((yw * d) / gw) + (1.0f - d));
+ b = bc / (((yw * d) / bw) + (1.0f - d));
+
+ ColorTemp::cat02_to_xyzfloat( x, y, z, r, g, b, gamu );
+}
+
//end CIECAM Billy Bigg
diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h
index 3373dd0ae..2e20acff3 100644
--- a/rtengine/colortemp.h
+++ b/rtengine/colortemp.h
@@ -25,6 +25,8 @@
#include "imagefloat.h"
#include "labimage.h"
#define MAXR(a,b) ((a) > (b) ? (a) : (b))
+#define pow_F(a,b) (exp(b*log(a)))
+
namespace rtengine {
@@ -66,6 +68,9 @@ class ColorTemp {
static double d_factor( double f, double la ) {
return f * (1.0 - ((1.0 / 3.6) * exp((-la - 42.0) / 92.0)));
}
+ static float d_factorfloat( float f, float la ) {
+ return f * (1.0f - ((1.0f / 3.6f) * exp((-la - 42.0f) / 92.0f)));
+ }
static double calculate_fl_from_la_ciecam02( double la ) {
double la5 = la * 5.0;
@@ -77,6 +82,16 @@ class ColorTemp {
return (0.2 * k * la5) + (0.1 * (1.0 - k) * (1.0 - k) * pow(la5, 1.0 / 3.0));
}
+ static float calculate_fl_from_la_ciecam02float( float la ) {
+ float la5 = la * 5.0f;
+ float k = 1.0f / (la5 + 1.0f);
+
+ /* Calculate k^4. */
+ k = k * k;
+ k = k * k;
+
+ return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * pow_F(la5, 1.0f / 3.0f));
+ }
static double achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu ) {
double r, g, b;
@@ -103,25 +118,76 @@ class ColorTemp {
return ((2.0 * rpa) + gpa + ((1.0 / 20.0) * bpa) - 0.305) * nbb;
}
+
+ static float achromatic_response_to_whitefloat( float x, float y, float z, float d, float fl, float nbb, int gamu ) {
+ float r, g, b;
+ float rc, gc, bc;
+ float rp, gp, bp;
+ float rpa, gpa, bpa;
+ gamu=1;
+ xyz_to_cat02float( r, g, b, x, y, z, gamu );
+
+ rc = r * (((y * d) / r) + (1.0f - d));
+ gc = g * (((y * d) / g) + (1.0f - d));
+ bc = b * (((y * d) / b) + (1.0f - d));
+
+ cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu );
+ if(gamu==1){//gamut correction M.H.Brill S.Susstrunk
+ rp=MAXR(rp,0.0f);
+ gp=MAXR(gp,0.0f);
+ bp=MAXR(bp,0.0f);
+ }
+
+ rpa = nonlinear_adaptationfloat( rp, fl );
+ gpa = nonlinear_adaptationfloat( gp, fl );
+ bpa = nonlinear_adaptationfloat( bp, fl );
+
+ return ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb;
+ }
static void xyz_to_cat02 ( double &r, double &g, double &b, double x, double y, double z, int gamu );
static void cat02_to_hpe ( double &rh, double &gh, double &bh, double r, double g, double b, int gamu );
static void cat02_to_xyz ( double &x, double &y, double &z, double r, double g, double b, int gamu );
static void hpe_to_xyz ( double &x, double &y, double &z, double r, double g, double b );
+ static void xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int gamu );
+ static void cat02_to_hpefloat ( float &rh, float &gh, float &bh, float r, float g, float b, int gamu );
+ static void cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int gamu );
+ static void hpe_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b );
+
+ static void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb );
+ static void Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb );
+ static void calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a );
+ static void calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a );
+
+
static double nonlinear_adaptation( double c, double fl ) {
double p;
if(c<0.0){ p = pow( (-1.0*fl * c) / 100.0, 0.42 );return ((-1.0*400.0 * p) / (27.13 + p)) + 0.1;}
else {p = pow( (fl * c) / 100.0, 0.42 ); return ((400.0 * p) / (27.13 + p)) + 0.1;}
}
+ static float nonlinear_adaptationfloat( float c, float fl ) {
+ float p;
+ if(c<0.0f){ p = pow_F( (-1.0f*fl * c) / 100.0f, 0.42f );return ((-1.0f*400.0f * p) / (27.13f + p)) + 0.1f;}
+ else {p = pow_F( (fl * c) / 100.0f, 0.42f ); return ((400.0f * p) / (27.13f + p)) + 0.1f;}
+ }
static double inverse_nonlinear_adaptation( double c, double fl ) {
int c1;
if(c-0.1 < 0.0) c1=-1; else c1=1;
return c1*(100.0 / fl) * pow( (27.13 * fabs( c - 0.1 )) / (400.0 - fabs( c - 0.1 )), 1.0 / 0.42 );
}
+ static float inverse_nonlinear_adaptationfloat( float c, float fl ) {
+ int c1;
+ if(c-0.1f < 0.0f) c1=-1; else c1=1;
+ return c1*(100.0f / fl) * pow_F( (27.13f * fabs( c - 0.1f )) / (400.0f - fabs( c - 0.1f )), 1.0f / 0.42f );
+ }
+
+
static void curvecolor(double satind, double satval, double &sres, double parsat);
+ static void curvecolorfloat(float satind, float satval, float &sres, float parsat);
static void curveJ (double br, double contr, int db, LUTf & outCurve , LUTu & histogram ) ;
+ static void curveJfloat (float br, float contr, int db, LUTf & outCurve , LUTu & histogram ) ;
bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; }
bool operator!= (const ColorTemp& other) { return !(*this==other); }
@@ -234,6 +300,13 @@ class ColorTemp {
double xw, double yw, double zw,
double yb, double la,
double f, double c, double nc, bool doneinit2, int gamu );
+
+ static void jch2xyz_ciecam02float( float &x, float &y, float &z,
+ float J, float C, float h,
+ float xw, float yw, float zw,
+ float yb, float la,
+ float f, float c, float nc, bool doneinit2, int gamu );
+
/**
* Forward transform from XYZ to CIECAM02 JCh.
*/
@@ -244,69 +317,14 @@ class ColorTemp {
double yb, double la,
double f, double c, double nc, double pilotd, bool doneinit1, int gamu );
+ static void xyz2jchqms_ciecam02float( float &J, float &C, float &h,
+ float &Q, float &M, float &s,float &aw, float &fl, float &wh,
+ float x, float y, float z,
+ float xw, float yw, float zw,
+ float yb, float la,
+ float f, float c, float nc, float pilotd, bool doneinit1, int gamu );
+
+
};
-inline void ColorTemp::xyz_to_cat02( double &r, double &g, double &b, double x, double y, double z, int gamu )
-{
-gamu=1;
-if(gamu==0){
- r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
- g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
- b = ( 0.0030 * x) + (0.0136 * y) + (0.9834 * z);
- }
-else if (gamu==1) {//gamut correction M.H.Brill S.Susstrunk
- //r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z);
- //g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z);
- //b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
- r = ( 1.007245 * x) + (0.011136* y) - (0.018381 * z);//Changjun Li
- g = (-0.318061 * x) + (1.314589 * y) + (0.003471 * z);
- b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z);
-
-}
-}
-
-inline void ColorTemp::cat02_to_xyz( double &x, double &y, double &z, double r, double g, double b, int gamu )
-{
-gamu=1;
-if(gamu==0) {
- x = ( 1.096124 * r) - (0.278869 * g) + (0.182745 * b);
- y = ( 0.454369 * r) + (0.473533 * g) + (0.072098 * b);
- z = (-0.009628 * r) - (0.005698 * g) + (1.015326 * b);
- }
-else if(gamu==1) {//gamut correction M.H.Brill S.Susstrunk
- //x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b);
- //y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b);
- //z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
- x = ( 0.99015849 * r) - (0.00838772* g) + (0.018229217 * b);//Changjun Li
- y = ( 0.239565979 * r) + (0.758664642 * g) + (0.001770137* b);
- z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b);
-
-}
-}
-
-inline void ColorTemp::hpe_to_xyz( double &x, double &y, double &z, double r, double g, double b )
-{
- x = (1.910197 * r) - (1.112124 * g) + (0.201908 * b);
- y = (0.370950 * r) + (0.629054 * g) - (0.000008 * b);
- z = b;
-
-}
-
-
-
-
-inline void ColorTemp::cat02_to_hpe( double &rh, double &gh, double &bh, double r, double g, double b, int gamu )
-{ gamu=1;
- if(gamu==0){
- rh = ( 0.7409792 * r) + (0.2180250 * g) + (0.0410058 * b);
- gh = ( 0.2853532 * r) + (0.6242014 * g) + (0.0904454 * b);
- bh = (-0.0096280 * r) - (0.0056980 * g) + (1.0153260 * b);
- }
- else if (gamu==1) {//Changjun Li
- rh = ( 0.550930835 * r) + (0.519435987* g) - ( 0.070356303* b);
- gh = ( 0.055954056 * r) + (0.89973132 * g) + (0.044315524 * b);
- bh = (0.0 * r) - (0.0* g) + (1.0 * b);
- }
-}
-
}
#endif
diff --git a/rtengine/curves.cc b/rtengine/curves.cc
index 1da822266..37c5f3d99 100644
--- a/rtengine/curves.cc
+++ b/rtengine/curves.cc
@@ -831,7 +831,6 @@ void CurveFactory::curveLightBrightColor (
}*/
}
-
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index 73b5ea567..e894eecbe 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -1,3 +1,4 @@
+/*
/*
* This file is part of RawTherapee.
*
@@ -186,26 +187,24 @@ void Crop::update (int todo) {
LUTu dummy;
parent->ipf.chromiLuminanceCurve (1,labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili, dummy);
parent->ipf.vibrance (labnCrop);
- // if(!params.colorappearance.tonecie) parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay.
- // if(!params.colorappearance.tonecie) parent->ipf.EPDToneMap(labnCrop, 0, 1); //Go with much fewer than normal iterates for fast redisplay.
- if(params.colorappearance.enabled && !params.colorappearance.tonecie)parent->ipf.EPDToneMap(labnCrop, 5, 1);
-
- if(!params.colorappearance.enabled){parent->ipf.EPDToneMap(labnCrop, 5, 1);}
-
+ if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) parent->ipf.EPDToneMap(labnCrop,5,1);
// parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay.
-
+ // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
if (skip==1) {
parent->ipf.impulsedenoise (labnCrop);
- parent->ipf.defringe (labnCrop);
+ if((params.colorappearance.enabled && !settings->autocielab) ||(!params.colorappearance.enabled) ) {parent->ipf.defringe (labnCrop);}
parent->ipf.MLsharpen (labnCrop);
- parent->ipf.MLmicrocontrast (labnCrop);
- //parent->ipf.MLmicrocontrast (labnCrop);
- parent->ipf.sharpening (labnCrop, (float**)cbuffer);
- parent->ipf.dirpyrequalizer (labnCrop);
+ if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) {
+ parent->ipf.MLmicrocontrast (labnCrop);
+ parent->ipf.sharpening (labnCrop, (float**)cbuffer);
+ parent->ipf.dirpyrequalizer (labnCrop);
+ }
}
int begh = 0, endh = labnCrop->H;
-
- parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1);
+ bool execsharp=false;
+ if(skip==1) execsharp=true;
+ if(settings->ciecamfloat) parent->ipf.ciecam_02float (cieCrop,begh, endh, 1,labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp);
+ else parent->ipf.ciecam_02 (cieCrop,begh, endh, 1,labnCrop, ¶ms,parent->customColCurve1,parent->customColCurve2,parent->customColCurve3, dummy, dummy, 5, 1,(float**)cbuffer, execsharp);
}
// switch back to rgb
parent->ipf.lab2monitorRgb (labnCrop, cropImg);
@@ -287,8 +286,8 @@ void Crop::freeAll () {
delete labnCrop;
delete cropImg;
delete cshmap;
- //for (int i=0; i
#endif
+#define CLIPI(a) ((a)>0 ?((a)<32768 ?(a):32768):0)
#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000)
#define DIRWT(i1,j1,i,j) ( domker[(i1-i)/scale+halfwin][(j1-j)/scale+halfwin] * rangefn[abs((int)data_fine[i1][j1]-data_fine[i][j])] )
@@ -48,7 +49,7 @@ namespace rtengine {
//scale is spacing of directional averaging weights
- void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, const double * mult )
+ void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, const double * mult)
{
int lastlevel=maxlevel;
@@ -135,8 +136,7 @@ namespace rtengine {
for (int i=0; i0) {
+ lastlevel--;
+ //printf("last level to process %d \n",lastlevel);
+ }
+ if (lastlevel==0) return;
+
+
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ LUTf rangefn(0x10000);
+
+ int intfactor = 1024;//16384;
+
+
+ //set up range functions
+
+ for (int i=0; i<0x10000; i++) {
+ rangefn[i] = (int)((thresh/((double)(i) + thresh))*intfactor);
+ }
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+ int level;
+ array2D buffer (srcwidth, srcheight);
+
+ multi_array2D dirpyrlo (srcwidth, srcheight);
+
+
+ for (int i=0; i 0; level--)
+ {
+ idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult );
+ }
+
+
+ scale = scales[0];
+
+ idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult );
+
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+ for (int i=0; iJ_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) dst[i][j] = CLIP((int)( buffer[i][j] )); // TODO: Really a clip necessary?
+ else dst[i][j]=src[i][j];}
+ else dst[i][j] = CLIP((int)( buffer[i][j] )); // TODO: Really a clip necessary?
+
+ }
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+
+ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ }
+
+
+
+
void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale, const double * mult )
{
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 07cf6c672..c6b56c65d 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -349,35 +349,31 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
ipf.chromiLuminanceCurve (pW,nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve,lhskcurve, lumacurve, utili, autili, butili, ccutili,cclutili, histCCurve);
ipf.vibrance(nprevl);
- // if(!params.colorappearance.tonecie) ipf.EPDToneMap(nprevl,0,scale);
-/* if(params.colorappearance.enabled){
- if(!params.colorappearance.tonecie) ipf.EPDToneMap(nprevl,5,1);
- }
- if(!params.colorappearance.enabled){ipf.EPDToneMap(nprevl,5,1);}
- */
- if(params.colorappearance.enabled && !params.colorappearance.tonecie) ipf.EPDToneMap(nprevl,5,1);
-
- if(!params.colorappearance.enabled){ipf.EPDToneMap(nprevl,5,1);}
-
+ if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) ipf.EPDToneMap(nprevl,5,1);
+ // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled
readyphase++;
if (scale==1) {
progress ("Denoising luminance impulse...",100*readyphase/numofphases);
ipf.impulsedenoise (nprevl);
readyphase++;
+ if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
progress ("Defringing...",100*readyphase/numofphases);
- ipf.defringe (nprevl);
- readyphase++;
+ ipf.defringe (nprevl);
+ readyphase++;
+ }
if (params.sharpenEdge.enabled) {
progress ("Edge sharpening...",100*readyphase/numofphases);
ipf.MLsharpen (nprevl);
readyphase++;
}
if (params.sharpenMicro.enabled) {
+ if(( params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
progress ("Microcontrast...",100*readyphase/numofphases);
ipf.MLmicrocontrast (nprevl);
readyphase++;
+ }
}
- if (params.sharpening.enabled) {
+ if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) {
progress ("Sharpening...",100*readyphase/numofphases);
float **buffer = new float*[pH];
@@ -391,10 +387,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
delete [] buffer;
readyphase++;
}
-
- progress ("Pyramid equalizer...",100*readyphase/numofphases);
- ipf.dirpyrequalizer (nprevl);
- readyphase++;
+ if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){
+// if(params.colorappearance.enabled && !params.colorappearance.sharpcie){
+ progress ("Pyramid equalizer...",100*readyphase/numofphases);
+ ipf.dirpyrequalizer (nprevl);
+ readyphase++;
+ }
+
}
//L histo and Chroma histo for ciecam
// histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C
@@ -425,7 +424,16 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
int Iterates=0;
int begh=0;
int endh=pH;
- ipf.ciecam_02 (ncie, begh, endh, pW, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1);
+
+ float **buffer = new float*[pH];
+ for (int i=0; iciecamfloat) ipf.ciecam_02float (ncie, begh, endh, pW, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
+ else ipf.ciecam_02 (ncie, begh, endh, pW, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, 5, 1, (float**)buffer, true);
+ for (int i=0; idelImage (previmg);
diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc
index 25e1efdf9..c12d5db23 100644
--- a/rtengine/improcfun.cc
+++ b/rtengine/improcfun.cc
@@ -237,7 +237,7 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par
}
// Copyright (c) 2012 Jacques Desmis
-void ImProcFunctions::ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale )
+void ImProcFunctions::ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp)
{
if(params->colorappearance.enabled) {
@@ -654,18 +654,22 @@ if(params->colorappearance.enabled) {
h=hpro;
s=spro;
- if(params->colorappearance.tonecie){//use pointer for tonemapping with CIECAM
+ if(params->colorappearance.tonecie || settings->autocielab){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail
+ // if(params->colorappearance.tonecie || params->colorappearance.sharpcie){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail
+ float Qred= ( 4.0 / c) * ( aw + 4.0 );//estimate Q max if J=100.0
ncie->Q_p[i][j]=(float)Q+epsil;//epsil to avoid Q=0
ncie->M_p[i][j]=(float)M+epsil;
ncie->J_p[i][j]=(float)J+epsil;
ncie->h_p[i][j]=(float)h;
ncie->C_p[i][j]=(float)C+epsil;
- // ciec->s_p[i][j]=(float)s;
-
+ // ncie->s_p[i][j]=(float)s;
+ ncie->sh_p[i][j]=(float) 32768.*(( 4.0 / c )*sqrt( J / 100.0 ) * ( aw + 4.0 ))/Qred ;
+ // ncie->ch_p[i][j]=(float) 327.68*C;
if(ncie->Q_p[i][j]Q_p[i][j];//minima
if(ncie->Q_p[i][j]>maxQ) maxQ=ncie->Q_p[i][j];//maxima
}
- if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie){
+ if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){
+ // if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){
int posl, posc;
double brli=327.;
double chsacol=327.;
@@ -736,7 +740,8 @@ if(params->colorappearance.enabled) {
}
}
// End of parallelization
-if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie){//normal
+if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){//normal
+//if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){//normal
if(ciedata) {
//update histogram J
@@ -769,10 +774,44 @@ if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.to
// printf("minc=%f maxc=%f minj=%f maxj=%f\n",minc,maxc,minj,maxj);
}
#endif
-//select here tonemapping with Q
-if(params->colorappearance.tonecie && params->edgePreservingDecompositionUI.enabled) {
- //EPDToneMapCIE adated to CIECAM
- ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale );
+
+if(settings->autocielab) {
+//if(params->colorappearance.sharpcie) {
+
+//all this treatments reduce artefacts, but can leed to slighty different results
+if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);//defringe adapted to CIECAM
+
+if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie);
+
+if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM
+
+if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, true);//contrast by detail adapted to CIECAM
+
+ float Qredi= ( 4.0 / c_) * ( a_w + 4.0 );
+ float co_e=(pow(f_l,0.25));
+
+#ifndef _DEBUG
+#pragma omp parallel default(shared) firstprivate(height,width, Qredi,a_w,c_)
+#endif
+{
+#ifndef _DEBUG
+ #pragma omp for schedule(dynamic, 10)
+#endif
+ for (int i=0; ish_p[i][j]/(32768.f);
+ ncie->J_p[i][j]=100.0* interm*interm/((a_w+4.)*(a_w+4.)*(4./c_)*(4./c_));
+ ncie->Q_p[i][j]=( 4.0 / c_) * ( a_w + 4.0 ) * sqrt(ncie->J_p[i][j]/100.f);
+ ncie->M_p[i][j]=ncie->C_p[i][j]*co_e;
+ }
+ }
+}
+if((params->colorappearance.tonecie || params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.enabled)) || (params->sharpening.enabled && settings->autocielab)
+ || (params->dirpyrequalizer.enabled && settings->autocielab) ||(params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab)) {
+
+ if(params->edgePreservingDecompositionUI.enabled && params->colorappearance.tonecie) ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale );
+ //EPDToneMapCIE adated to CIECAM
+
#ifndef _DEBUG
#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh,doneinit2, nc2,f2,c2, gamu, highlight,pW)
@@ -790,14 +829,13 @@ if(params->colorappearance.tonecie && params->edgePreservingDecompositionUI.enab
#pragma omp for schedule(dynamic, 10)
#endif
for (int i=0; iJ_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j]) /(w_h*w_h);
+ if(params->edgePreservingDecompositionUI.enabled) ncie->J_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h);
ncie->C_p[i][j] =(ncie->M_p[i][j])/co_e;
//show histogram in CIECAM mode (Q,J, M,s,C)
int posl, posc;
@@ -902,6 +940,721 @@ if(params->colorappearance.tonecie && params->edgePreservingDecompositionUI.enab
//end CIECAM
+// Copyright (c) 2012 Jacques Desmis
+void ImProcFunctions::ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, LUTu & histLCAM, LUTu & histCCAM, int Iterates, int scale, float** buffer, bool execsharp)
+{
+if(params->colorappearance.enabled) {
+//printf("ciecam float\n");
+
+#ifdef _DEBUG
+ MyTime t1e,t2e;
+ t1e.set();
+#endif
+ LUTf dLcurve(65536,0);
+ LUTu hist16JCAM(65536);
+ bool jp=false;
+ float val;
+ //preparate for histograms CIECAM
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<32768; i++) { //# 32768*1.414 approximation maxi for chroma
+ val = (double)i / 32767.0;
+ dLcurve[i] = CLIPD(val);
+ }
+ hist16JCAM.clear();
+ }
+ LUTf dCcurve(65536,0);
+ LUTu hist16_CCAM(65536);
+ bool chropC=false;
+ float valc;
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma
+ valc = (double)i / 47999.0;
+ dCcurve[i] = CLIPD(valc);
+ }
+ hist16_CCAM.clear();
+ }
+ //end preparate histogram
+ int width = lab->W, height = lab->H;
+ int Np=width*height;
+ float minQ=10000.f;
+ float minM=10000.f;
+ float maxQ= -1000.f;
+ float maxM= -1000.f;
+ float w_h;
+ float a_w;
+ float c_;
+ float f_l;
+ float Yw;
+ Yw=1.0;
+ double Xw, Zw;
+ float f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2;
+ float z,fl,n,nbb,ncb,d,aw;
+ float xwd,ywd,zwd;
+ int alg=0;
+ float sum=0.f;
+ float mean;
+ //LUTf for sliders J and Q
+ LUTf bright_curve (65536,0);//init curve
+ LUTf bright_curveQ (65536,0);//init curve
+
+ LUTu hist16J (65536);
+ LUTu hist16Q (65536);
+ float koef=1.0f;//rough correspondence between L and J
+ hist16J.clear();hist16Q.clear();
+ for (int i=0; iL[i][j])/327.68f)>95.) koef=1.f;
+ else if(((lab->L[i][j])/327.68f)>85.) koef=0.97f;
+ else if(((lab->L[i][j])/327.68f)>80.) koef=0.93f;
+ else if(((lab->L[i][j])/327.68f)>70.) koef=0.87f;
+ else if(((lab->L[i][j])/327.68f)>60.) koef=0.85f;
+ else if(((lab->L[i][j])/327.68f)>50.) koef=0.8f;
+ else if(((lab->L[i][j])/327.68f)>40.) koef=0.75f;
+ else if(((lab->L[i][j])/327.68f)>30.) koef=0.7f;
+ else if(((lab->L[i][j])/327.68f)>20.) koef=0.7f;
+ else if(((lab->L[i][j])/327.68f)>10.) koef=0.9f;
+ else if(((lab->L[i][j])/327.68f)>0.) koef=1.0f;
+
+ hist16J[CLIP((int)((koef*lab->L[i][j])))]++;//evaluate histogram luminance L # J
+ sum+=koef*lab->L[i][j];//evaluate mean J to calcualte Yb
+ hist16Q[CLIP((int) (32768.f*sqrt((koef*(lab->L[i][j]))/32768.f)))]++; //for brightness Q : approximation for Q=wh*sqrt(J/100) J not equal L
+ }
+ //mean=(sum/((endh-begh)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone
+ mean=(sum/((height)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone
+ if (mean<15.f) yb=3.0;
+ else if(mean<30.f) yb=5.0;
+ else if(mean<40.f) yb=10.0;
+ else if(mean<45.f) yb=15.0;
+ else if(mean<50.f) yb=18.0;
+ else if(mean<55.f) yb=23.0;
+ else if(mean<60.f) yb=30.0;
+ else if(mean<70.f) yb=40.0;
+ else if(mean<80.f) yb=60.0;
+ else if(mean<90.f) yb=80.0;
+ else yb=90.0;
+
+ bool ciedata=params->colorappearance.datacie;
+
+ ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB
+ //viewing condition for surround
+ if(params->colorappearance.surround=="Average") { f = 1.00; c = 0.69; nc = 1.00;f2=1.0,c2=0.69,nc2=1.0;}
+ else if(params->colorappearance.surround=="Dim"){ f2 = 0.9; c2 = 0.59; nc2 = 0.9;f=1.0,c=0.69,nc=1.0;}
+ else if(params->colorappearance.surround=="Dark"){f2 = 0.8; c2 = 0.525;nc2 = 0.8;f=1.0,c=0.69,nc=1.0;}
+ else if(params->colorappearance.surround=="ExtremelyDark"){f2 = 0.8; c2 = 0.41;nc2 = 0.8;f=1.0,c=0.69,nc=1.0;}
+
+ //scene condition for surround
+ if(params->colorappearance.surrsource==true) {f = 0.85; c = 0.55; nc = 0.85;}// if user => source image has surround very dark
+ //with which algorithme
+ if (params->colorappearance.algo=="JC") alg=0;
+ else if(params->colorappearance.algo=="JS") alg=1;
+ else if(params->colorappearance.algo=="QM") alg=2;
+ else if(params->colorappearance.algo=="ALL") alg=3;
+ //settings white point of output device - or illuminant viewing
+ if(settings->viewingdevice==0) {xwd=96.42;ywd=100.0;zwd=82.52;}//5000K
+ else if(settings->viewingdevice==1) {xwd=95.68;ywd=100.0;zwd=92.15;}//5500
+ else if(settings->viewingdevice==2) {xwd=95.24;ywd=100.0;zwd=100.81;}//6000
+ else if(settings->viewingdevice==3) {xwd=95.04;ywd=100.0;zwd=108.88;}//6500
+ else if(settings->viewingdevice==4) {xwd=109.85;ywd=100.0;zwd=35.58;}//tungsten
+ else if(settings->viewingdevice==5) {xwd=99.18;ywd=100.0;zwd=67.39;}//fluo F2
+ else if(settings->viewingdevice==6) {xwd=95.04;ywd=100.0;zwd=108.75;}//fluo F7
+ else if(settings->viewingdevice==7) {xwd=100.96;ywd=100.0;zwd=64.35;}//fluo F11
+
+
+ //settings mean Luminance Y of output device or viewing
+ if(settings->viewingdevicegrey==0) {yb2=5.0;}
+ else if(settings->viewingdevicegrey==1) {yb2=10.0;}
+ else if(settings->viewingdevicegrey==2) {yb2=15.0;}
+ else if(settings->viewingdevicegrey==3) {yb2=18.0;}
+ else if(settings->viewingdevicegrey==4) {yb2=23.0;}
+ else if(settings->viewingdevicegrey==5) {yb2=30.0;}
+ else if(settings->viewingdevicegrey==6) {yb2=40.0;}
+
+ //La and la2 = ambiant luminosity scene and viewing
+ la=float(params->colorappearance.adapscen);
+ la2=float(params->colorappearance.adaplum);
+
+ // level of adaptation
+ float deg=(params->colorappearance.degree)/100.0;
+ float pilot=params->colorappearance.autodegree ? 2.0 : deg;
+
+ //algoritm's params
+ float jli=params->colorappearance.jlight;
+ float chr=params->colorappearance.chroma;
+ float contra=params->colorappearance.contrast;
+ float qbri=params->colorappearance.qbright;
+ float schr=params->colorappearance.schroma;
+ float mchr=params->colorappearance.mchroma;
+ float qcontra=params->colorappearance.qcontrast;
+ float hue=params->colorappearance.colorh;
+ float rstprotection = 100.-params->colorappearance.rstprotection;
+ if(schr>0.0) schr=schr/2.0f;//divide sensibility for saturation
+
+ // extracting datas from 'params' to avoid cache flush (to be confirmed)
+ ColorAppearanceParams::eTCModeId curveMode = params->colorappearance.curveMode;
+ ColorAppearanceParams::eTCModeId curveMode2 = params->colorappearance.curveMode2;
+ bool hasColCurve1 = bool(customColCurve1);
+ bool hasColCurve2 = bool(customColCurve2);
+ ColorAppearanceParams::eCTCModeId curveMode3 = params->colorappearance.curveMode3;
+ bool hasColCurve3 = bool(customColCurve3);
+
+
+
+ //evaluate lightness, contrast
+ ColorTemp::curveJfloat (jli, contra, 1, bright_curve,hist16J);//lightness and contrast J
+ ColorTemp::curveJfloat (qbri, qcontra, 1, bright_curveQ, hist16Q);//brightness and contrast Q
+ int gamu=0;
+ bool highlight = params->hlrecovery.enabled; //Get the value if "highlight reconstruction" is activated
+
+ if(params->colorappearance.gamut==true) gamu=1;//enabled gamut control
+ xw=100.0*Xw;
+ yw=100.0*Yw;
+ zw=100.0*Zw;
+ float xw1,yw1,zw1,xw2,yw2,zw2;
+ // settings of WB: scene and viewing
+ if(params->colorappearance.wbmodel=="RawT") {xw1=96.46;yw1=100.0;zw1=82.445;xw2=xwd;yw2=ywd;zw2=zwd;} //use RT WB; CAT 02 is used for output device (see prefreneces)
+ else if(params->colorappearance.wbmodel=="RawTCAT02") {xw1=xw;yw1=yw;zw1=zw;xw2=xwd;yw2=ywd;zw2=zwd;} // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences
+ bool doneinit=true;
+ bool doneinit2=true;
+#ifndef _DEBUG
+#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh, doneinit,doneinit2, nc2,f2,c2, alg, gamu, highlight, rstprotection, pW)
+#endif
+{ //matrix for current working space
+ TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working);
+ double wip[3][3] = {
+ {wiprof[0][0],wiprof[0][1],wiprof[0][2]},
+ {wiprof[1][0],wiprof[1][1],wiprof[1][2]},
+ {wiprof[2][0],wiprof[2][1],wiprof[2][2]}
+ };
+
+#ifndef _DEBUG
+#pragma omp for schedule(dynamic, 10)
+#endif
+ for (int i=0; iL[i][j];
+ float a=lab->a[i][j];
+ float b=lab->b[i][j];
+ float x1,y1,z1;
+ float x,y,z;
+ float epsil=0.0001;
+ //convert Lab => XYZ
+ Color::Lab2XYZ(L, a, b, x1, y1, z1);
+ float J, C, h, Q, M, s, aw, fl, wh;
+ float Jp,Cpr;
+ float Jpro,Cpro, hpro, Qpro, Mpro, spro;
+ bool t1L=false;
+ bool t1B=false;
+ bool t2L=false;
+ bool t2B=false;
+ int c1C=0;
+ int c1s=0;
+ int c1co=0;
+
+ x=(float)x1/655.35f;
+ y=(float)y1/655.35f;
+ z=(float)z1/655.35f;
+ //process source==> normal
+ ColorTemp::xyz2jchqms_ciecam02float( J, C, h,
+ Q, M, s, aw, fl, wh,
+ x, y, z,
+ xw1, yw1, zw1,
+ yb, la,
+ f, c, nc, pilot, doneinit, gamu );
+ Jpro=J;
+ Cpro=C;
+ hpro=h;
+ Qpro=Q;
+ Mpro=M;
+ spro=s;
+ w_h=wh+epsil;
+ a_w=aw;
+ c_=c;
+ f_l=fl;
+ // we cannot have all algoritms with all chroma curves
+ if(alg==1) {
+ // Lightness saturation
+ Jpro=(bright_curve[(float)(Jpro*327.68f)])/327.68f;//ligthness CIECAM02 + contrast
+ float sres;
+ float Sp=spro/100.0f;
+ float parsat=1.5f;
+ parsat=1.5f;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation)
+ if(schr==-100.0f) schr=-99.8f;
+ ColorTemp::curvecolorfloat(schr, Sp , sres, parsat);
+ float coe=pow_F(fl,0.25f);
+ float dred=100.f;// in C mode
+ float protect_red=80.0f; // in C mode
+ dred = 100.0f * sqrt((dred*coe)/Qpro);
+ protect_red=100.0 * sqrt((protect_red*coe)/Qpro);
+ int sk=0;
+ float ko=100.f;
+ Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro);
+ Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ;
+ Cpro=(spro*spro*Qpro)/(10000.0f);
+ }
+ else if(alg==3 || alg==0 || alg==2) {
+ float coef=32760.f/wh;
+ if(alg==3 || alg==2) Qpro=(bright_curveQ[(float)(Qpro*coef)])/coef;//brightness and contrast
+ float Mp, sres;
+ float coe=pow_F(fl,0.25f);
+ Mp=Mpro/100.0f;
+ float parsat=2.5f;
+ if(mchr==-100.0f) mchr=-99.8f ;
+ if(mchr==100.0f) mchr=99.9f;
+ if(alg==3 || alg==2) ColorTemp::curvecolorfloat(mchr, Mp , sres, parsat); else ColorTemp::curvecolorfloat(0.0, Mp , sres, parsat);//colorfullness
+ float dred=100.f;//in C mode
+ float protect_red=80.0f;// in C mode
+ dred *=coe;//in M mode
+ protect_red *=coe;//M mode
+ int sk=0;
+ float ko=100.f;
+ Color::skinredfloat(Jpro, hpro, sres, Mp, dred, protect_red,sk,rstprotection,ko, Mpro);
+ Jpro=(100.0f* Qpro*Qpro) /(wh*wh);
+ Cpro= Mpro/coe;
+ spro = 100.0f * sqrt( Mpro / Qpro );
+ if(alg!=2) Jpro=(bright_curve[(float)(Jpro*327.68f)])/327.68f;//ligthness CIECAM02 + contrast
+ float Cp;
+ float Sp=spro/100.0f;
+ parsat=1.5;
+ if(schr==-100.0f) schr=-99.f;
+ if(schr==100.0f) schr=98.f;
+ if(alg==3) ColorTemp::curvecolorfloat(schr, Sp , sres, parsat); else ColorTemp::curvecolorfloat(0.0, Sp , sres, parsat); //saturation
+ dred=100.f;// in C mode
+ protect_red=80.0f; // in C mode
+ dred = 100.0 * sqrt((dred*coe)/Q);
+ protect_red=100.0f * sqrt((protect_red*coe)/Q);
+ sk=0;
+ Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro);
+ Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ;
+ Cpro=(spro*spro*Qpro)/(10000.0f);
+ Cp=Cpro/100.0f;
+ parsat=1.8f;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation : for not)
+ if(chr==-100.0f) chr=-99.8f;
+ if(alg!=2) ColorTemp::curvecolorfloat(chr, Cp , sres, parsat);else ColorTemp::curvecolorfloat(0.0, Cp , sres, parsat); //chroma
+ dred=55.f;
+ protect_red=30.0f;
+ sk=1;
+ Color::skinredfloat(Jpro, hpro, sres, Cp, dred, protect_red,sk,rstprotection, ko, Cpro);
+
+ hpro=hpro+hue;if( hpro < 0.0f ) hpro += 360.0f;//hue
+ }
+
+ if (hasColCurve1) {//curve 1 with Lightness and Brightness
+ if (curveMode==ColorAppearanceParams::TC_MODE_LIGHT){
+ float Jj=(float) Jpro*327.68f;
+ float Jold=Jj;
+ const Lightcurve& userColCurve = static_cast(customColCurve1);
+ userColCurve.Apply(Jj);
+ Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility
+ Jpro=(float)(Jj/327.68f);
+ t1L=true;
+ }
+ else if (curveMode==ColorAppearanceParams::TC_MODE_BRIGHT){
+ float coef=32760.f/wh;
+ float Qq=(float) Qpro*coef;
+ float Qold=Qq;
+ const Brightcurve& userColCurve = static_cast(customColCurve1);
+ userColCurve.Apply(Qq);
+ Qq=0.5f*(Qq-Qold)+Qold;//divide sensibility
+ Qpro=(float)(Qq/coef);
+ Jpro=(100.0f* Qpro*Qpro) /(wh*wh);
+ t1B=true;
+ }
+ }
+
+ if (hasColCurve2) {//curve 2 with Lightness and Brightness
+ if (curveMode2==ColorAppearanceParams::TC_MODE_LIGHT){
+ float Jj=(float) Jpro*327.68f;
+ float Jold=Jj;
+ const Lightcurve& userColCurve = static_cast(customColCurve2);
+ userColCurve.Apply(Jj);
+ Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility
+ Jpro=(float)(Jj/327.68f);
+ t2L=true;
+ }
+ else if (curveMode2==ColorAppearanceParams::TC_MODE_BRIGHT){ //
+ float coef=32760.f/wh;
+ float Qq=(float) Qpro*coef;
+ float Qold = Qq;
+ const Brightcurve& userColCurve = static_cast(customColCurve2);
+ userColCurve.Apply(Qq);
+ Qq=0.5f*(Qq-Qold)+Qold;//divide sensibility
+ Qpro=(float)(Qq/coef);
+ Jpro=(100.0f* Qpro*Qpro) /(wh*wh);
+ t2B=true;
+ }
+ }
+
+ if (hasColCurve3) {//curve 3 with chroma saturation colorfullness
+ if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA){
+ float parsat=0.8f;//0.68;
+ float coef=327.68f/parsat;
+ float Cc=(float) Cpro*coef;
+ float Ccold=Cc;
+ const Chromacurve& userColCurve = static_cast(customColCurve3);
+ userColCurve.Apply(Cc);
+ float dred=55.f;
+ float protect_red=30.0f;
+ float sk=1;
+ float ko=1.f/coef;
+ Color::skinredfloat(Jpro, hpro, Cc, Ccold, dred, protect_red,sk,rstprotection,ko, Cpro);
+ // Cpro=Cc/coef;
+ c1C=1;
+ }
+ else if (curveMode3==ColorAppearanceParams::TC_MODE_SATUR){ //
+ float parsat=0.8f;//0.6
+ float coef=327.68f/parsat;
+ float Ss=(float) spro*coef;
+ float Sold=Ss;
+ const Saturcurve& userColCurve = static_cast(customColCurve3);
+ userColCurve.Apply(Ss);
+ Ss=0.6f*(Ss-Sold)+Sold;//divide sensibility saturation
+ float coe=pow_F(fl,0.25f);
+ float dred=100.f;// in C mode
+ float protect_red=80.0f; // in C mode
+ dred = 100.0 * sqrt((dred*coe)/Qpro);
+ protect_red=100.0 * sqrt((protect_red*coe)/Qpro);
+ int sk=0;
+ float ko=1.f/coef;
+ Color::skinredfloat(Jpro, hpro, Ss, Sold, dred, protect_red,sk,rstprotection,ko, spro);
+ Qpro= ( 4.0 / c ) * sqrt( Jpro / 100.0 ) * ( aw + 4.0 ) ;
+ Cpro=(spro*spro*Qpro)/(10000.0f);
+ c1s=1;
+
+ }
+ else if (curveMode3==ColorAppearanceParams::TC_MODE_COLORF){ //
+ float parsat=0.8f;//0.68;
+ float coef=327.68f/parsat;
+ float Mm=(float) Mpro*coef;
+ float Mold=Mm;
+ const Colorfcurve& userColCurve = static_cast(customColCurve3);
+ userColCurve.Apply(Mm);
+ float coe=pow_F(fl,0.25f);
+ float dred=100.f;//in C mode
+ float protect_red=80.0f;// in C mode
+ dred *=coe;//in M mode
+ protect_red *=coe;
+ int sk=0;
+ float ko=1.f/coef;
+ Color::skinredfloat(Jpro, hpro, Mm, Mold, dred, protect_red,sk,rstprotection,ko, Mpro);
+ Cpro= Mpro/coe;
+ c1co=1;
+ }
+ }
+ //to retrieve the correct values of variables
+ if(t2B && t1B) Jpro=(100.0* Qpro*Qpro) /(wh*wh);// for brightness curve
+ if(c1s==1) {
+ Qpro= ( 4.0f / c ) * sqrt( Jpro / 100.0f ) * ( aw + 4.0f ) ;//for saturation curve
+ Cpro=(spro*spro*Qpro)/(10000.0);
+ }
+ if(c1co==1) { float coe=pow_F(fl,0.25f);Cpro= Mpro/coe;} // for colorfullness curve
+ //retrieve values C,J...s
+ C=Cpro;
+ J=Jpro;
+ Q=Qpro;
+ M=Mpro;
+ h=hpro;
+ s=spro;
+
+ if(params->colorappearance.tonecie || settings->autocielab){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail
+ // if(params->colorappearance.tonecie || params->colorappearance.sharpcie){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail
+ float Qred= ( 4.0f / c) * ( aw + 4.0f );//estimate Q max if J=100.0
+ ncie->Q_p[i][j]=(float)Q+epsil;//epsil to avoid Q=0
+ ncie->M_p[i][j]=(float)M+epsil;
+ ncie->J_p[i][j]=(float)J+epsil;
+ ncie->h_p[i][j]=(float)h;
+ ncie->C_p[i][j]=(float)C+epsil;
+ // ncie->s_p[i][j]=(float)s;
+ ncie->sh_p[i][j]=(float) 32768.f*(( 4.0f / c )*sqrt( J / 100.0f ) * ( aw + 4.0f ))/Qred ;
+ // ncie->ch_p[i][j]=(float) 327.68*C;
+ if(ncie->Q_p[i][j]Q_p[i][j];//minima
+ if(ncie->Q_p[i][j]>maxQ) maxQ=ncie->Q_p[i][j];//maxima
+ }
+ if(!params->colorappearance.tonecie || !settings->autocielab){
+ // if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){
+ // if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){
+ int posl, posc;
+ float brli=327.f;
+ float chsacol=327.f;
+ int libr=0;
+ int colch=0;
+ if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0f; libr=1;}
+ else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.f;libr=0;}
+ if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.f;colch=0;}
+ else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0f;colch=1;}
+ else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0f;colch=2;}
+ if(ciedata) {
+ // Data for J Q M s and C histograms
+ //update histogram
+ jp=true;
+ if(pW!=1){//only with improccoordinator
+ if(libr==1) posl=CLIP((int)(Q*brli));//40.0 to 100.0 approximative factor for Q - 327 for J
+ else if(libr==0) posl=CLIP((int)(J*brli));//327 for J
+ hist16JCAM[posl]++;
+ }
+ chropC=true;
+ if(pW!=1){//only with improccoordinator
+ if(colch==0) posc=CLIP((int)(C*chsacol));//450.0 approximative factor for s 320 for M
+ else if(colch==1) posc=CLIP((int)(s*chsacol));
+ else if(colch==2) posc=CLIP((int)(M*chsacol));
+ hist16_CCAM[posc]++;
+ }
+ }
+ float xx,yy,zz;
+ //process normal==> viewing
+ ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
+ J, C, h,
+ xw2, yw2, zw2,
+ yb2, la2,
+ f2, c2, nc2, doneinit2, gamu);
+ x=(float)xx*655.35f;
+ y=(float)yy*655.35f;
+ z=(float)zz*655.35f;
+ float Ll,aa,bb;
+ //convert xyz=>lab
+ Color::XYZ2Lab(x, y, z, Ll, aa, bb);
+ lab->L[i][j]=Ll;
+ lab->a[i][j]=aa;
+ lab->b[i][j]=bb;
+ // gamut control in Lab mode; I must study how to do with cIECAM only
+ if(gamu==1) {
+ float R,G,B;
+ float HH, Lprov1, Chprov1;
+ Lprov1=lab->L[i][j]/327.68f;
+ Chprov1=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f));
+ HH=atan2(lab->b[i][j],lab->a[i][j]);
+
+#ifdef _DEBUG
+ bool neg=false;
+ bool more_rgb=false;
+ //gamut control : Lab values are in gamut
+ Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb);
+#else
+ //gamut control : Lab values are in gamut
+ Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f);
+#endif
+
+ lab->L[i][j]=Lprov1*327.68f;
+ lab->a[i][j]=327.68f*Chprov1*cos(HH);
+ lab->b[i][j]=327.68f*Chprov1*sin(HH);
+
+ }
+ }
+ }
+ }
+ // End of parallelization
+if(!params->colorappearance.tonecie || !settings->autocielab){//normal
+
+//if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !settings->autocielab){//normal
+//if(!params->edgePreservingDecompositionUI.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){//normal
+
+ if(ciedata) {
+ //update histogram J
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<=32768; i++) {//
+ float val;
+ if (jp) {
+ float hval = dLcurve[i];
+ int hi = (int)(255.0f*CLIPD(hval)); //
+ histLCAM[hi] += hist16JCAM[i] ;
+ }
+ }
+ }
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<=48000; i++) {//
+ float valc;
+ if (chropC) {
+ float hvalc = dCcurve[i];
+ int hic = (int)(255.0f*CLIPD(hvalc)); //
+ histCCAM[hic] += hist16_CCAM[i] ;
+ }
+ }
+ }
+ }
+}
+#ifdef _DEBUG
+ if (settings->verbose) {
+ t2e.set();
+ printf("CIECAM02 performed in %d usec:\n", t2e.etime(t1e));
+ // printf("minc=%f maxc=%f minj=%f maxj=%f\n",minc,maxc,minj,maxj);
+ }
+#endif
+
+if(settings->autocielab) {
+//if(params->colorappearance.sharpcie) {
+
+//all this treatments reduce artefacts, but can leed to slighty different results
+if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);//defringe adapted to CIECAM
+
+if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie);
+
+if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM
+
+if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, true);//contrast by detail adapted to CIECAM
+
+ float Qredi= ( 4.0f / c_) * ( a_w + 4.0f );
+ float co_e=(pow_F(f_l,0.25f));
+
+#ifndef _DEBUG
+#pragma omp parallel default(shared) firstprivate(height,width, Qredi,a_w,c_)
+#endif
+{
+#ifndef _DEBUG
+ #pragma omp for schedule(dynamic, 10)
+#endif
+ for (int i=0; ish_p[i][j]/(32768.f);
+ ncie->J_p[i][j]=100.0f* interm*interm/((a_w+4.f)*(a_w+4.f)*(4.f/c_)*(4.f/c_));
+ ncie->Q_p[i][j]=( 4.0f / c_) * ( a_w + 4.0f ) * sqrt(ncie->J_p[i][j]/100.f);
+ ncie->M_p[i][j]=ncie->C_p[i][j]*co_e;
+ }
+ }
+}
+if((params->colorappearance.tonecie && (params->edgePreservingDecompositionUI.enabled)) || (params->sharpening.enabled && settings->autocielab)
+ || (params->dirpyrequalizer.enabled && settings->autocielab) ||(params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab)) {
+
+ if(params->edgePreservingDecompositionUI.enabled && params->colorappearance.tonecie) ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale );
+ //EPDToneMapCIE adated to CIECAM
+
+
+#ifndef _DEBUG
+#pragma omp parallel default(shared) firstprivate(lab,xw2,yw2,zw2,chr,yb,la2,yb2, height,width,begh, endh,doneinit2, nc2,f2,c2, gamu, highlight,pW)
+#endif
+{
+ TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working);
+ double wipa[3][3] = {
+ {wiprofa[0][0],wiprofa[0][1],wiprofa[0][2]},
+ {wiprofa[1][0],wiprofa[1][1],wiprofa[1][2]},
+ {wiprofa[2][0],wiprofa[2][1],wiprofa[2][2]}
+ };
+
+
+#ifndef _DEBUG
+ #pragma omp for schedule(dynamic, 10)
+#endif
+ for (int i=0; iedgePreservingDecompositionUI.enabled) ncie->J_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h);
+ ncie->C_p[i][j] =(ncie->M_p[i][j])/co_e;
+ //show histogram in CIECAM mode (Q,J, M,s,C)
+ int posl, posc;
+ float brli=327.;
+ float chsacol=327.;
+ int libr=0;
+ int colch=0;
+ float sa_t;
+ if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0f; libr=1;}
+ else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.f;libr=0;}
+ if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.f;colch=0;}
+ else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0f;colch=1;}
+ else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0f;colch=2;}
+ if(ciedata) {
+ // Data for J Q M s and C histograms
+ //update histogram
+ jp=true;
+ if(pW!=1){//only with improccoordinator
+ if(libr==1) posl=CLIP((int)(ncie->Q_p[i][j]*brli));//40.0 to 100.0 approximative factor for Q - 327 for J
+ else if(libr==0) posl=CLIP((int)(ncie->J_p[i][j]*brli));//327 for J
+ hist16JCAM[posl]++;
+ }
+ chropC=true;
+ if(pW!=1){//only with improccoordinator
+ if(colch==0) posc=CLIP((int)(ncie->C_p[i][j]*chsacol));//450.0 approximative factor for s 320 for M
+ else if(colch==1) {sa_t=100.f*sqrt(ncie->C_p[i][j]/ncie->Q_p[i][j]); posc=CLIP((int)(sa_t*chsacol));}//Q_p always > 0
+ else if(colch==2) posc=CLIP((int)(ncie->M_p[i][j]*chsacol));
+ hist16_CCAM[posc]++;
+ }
+ }
+ //end histograms
+ ColorTemp::jch2xyz_ciecam02float( xx, yy, zz,
+ ncie->J_p[i][j], ncie->C_p[i][j], ncie->h_p[i][j],
+ xw2, yw2, zw2,
+ yb2, la2,
+ f2, c2, nc2, doneinit2, gamu);
+ x=(float)xx*655.35f;
+ y=(float)yy*655.35f;
+ z=(float)zz*655.35f;
+ float Ll,aa,bb;
+ //convert xyz=>lab
+ Color::XYZ2Lab(x, y, z, Ll, aa, bb);
+ lab->L[i][j]=Ll;
+ lab->a[i][j]=aa;
+ lab->b[i][j]=bb;
+ if(gamu==1) {
+ float R,G,B;
+ float HH, Lprov1, Chprov1;
+ Lprov1=lab->L[i][j]/327.68f;
+ Chprov1=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f));
+ HH=atan2(lab->b[i][j],lab->a[i][j]);
+
+#ifdef _DEBUG
+ bool neg=false;
+ bool more_rgb=false;
+ //gamut control : Lab values are in gamut
+ Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f, neg, more_rgb);
+#else
+ //gamut control : Lab values are in gamut
+ Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f);
+#endif
+
+ lab->L[i][j]=Lprov1*327.68f;
+ lab->a[i][j]=327.68f*Chprov1*cos(HH);
+ lab->b[i][j]=327.68f*Chprov1*sin(HH);
+ }
+ }
+
+
+ }
+ //end parallelization
+ //show CIECAM histograms
+ if(ciedata) {
+ //update histogram J and Q
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<=32768; i++) {//
+ float val;
+ if (jp) {
+ float hval = dLcurve[i];
+ int hi = (int)(255.0f*CLIPD(hval)); //
+ histLCAM[hi] += hist16JCAM[i] ;
+ }
+ }
+ }
+ //update color histogram M,s,C
+ if(pW!=1){//only with improccoordinator
+ for (int i=0; i<=48000; i++) {//
+ float valc;
+ if (chropC) {
+ float hvalc = dCcurve[i];
+ int hic = (int)(255.0f*CLIPD(hvalc)); //
+ histCCAM[hic] += hist16_CCAM[i] ;
+ }
+ }
+ }
+ }
+
+ }
+ hist16JCAM.reset();
+ hist16_CCAM.reset();
+ dLcurve.reset();
+ dCcurve.reset();
+ bright_curve.reset();
+ bright_curveQ.reset();
+ hist16J.reset();
+ hist16Q.reset();
+
+}
+}
+//end CIECAM
+
+
@@ -1187,6 +1940,7 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, LUTf & hltone
}
}
+
if (hasToneCurve2) {
if (curveMode2==ToneCurveParams::TC_MODE_STD){ // Standard
#ifdef _OPENMP
@@ -1432,6 +2186,7 @@ void ImProcFunctions::chromiLuminanceCurve (int pW, LabImage* lold, LabImage* ln
LUTu hist16Clad(65536);
bool chrop=false;
float val;
+ //preparate for histograms CIECAM
if(pW!=1){//only with improccoordinator
for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma
val = (double)i / 47999.0;
@@ -1877,14 +2632,19 @@ void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) {
PF_correct_RT(lab, lab, params->defringe.radius, params->defringe.threshold);
}
+ void ImProcFunctions::defringecam (CieImage* ncie) {
+
+ if (params->defringe.enabled && ncie->W>=8 && ncie->H>=8)
+
+ PF_correct_RTcam(ncie, ncie, params->defringe.radius, params->defringe.threshold);
+ }
void ImProcFunctions::dirpyrequalizer (LabImage* lab) {
if (params->dirpyrequalizer.enabled && lab->W>=8 && lab->H>=8) {
//dirpyrLab_equalizer(lab, lab, params->dirpyrequalizer.mult);
- dirpyr_equalizer(lab->L, lab->L, lab->W, lab->H, params->dirpyrequalizer.mult);
-
+ dirpyr_equalizer(lab->L, lab->L, lab->W, lab->H, params->dirpyrequalizer.mult);
}
}
void ImProcFunctions::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, int skip){
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index c3480288d..92ef0c675 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -55,6 +55,7 @@ class ImProcFunctions {
void transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, 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);
@@ -93,18 +94,22 @@ class ImProcFunctions {
SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2,
double expcomp, int hlcompr, int hlcomprthresh);
void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve);
- void ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale );
+ void ciecam_02float (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp );
+ void ciecam_02 (CieImage* ncie, int begh, int endh, int pW, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, LUTu &histLCAM, LUTu &histCCAM,int Iterates, int scale, float** buffer, bool execsharp );
void chromiLuminanceCurve (int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, LUTu &histCCurve);
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,
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 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 impulse_nr (LabImage* lab, double thresh);
@@ -144,12 +149,15 @@ class ImProcFunctions {
float MadMax(float * HH_Coeffs, int &max, int datalen);
// pyramid equalizer
- void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, const double * mult );//Emil's directional pyramid equalizer
+ void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, const double * mult);//Emil's directional pyramid equalizer
+ void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, const double * mult, bool execdir );//Emil's directional pyramid equalizer
void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale, const double * mult );
void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, const double * mult );
void defringe (LabImage* lab);
+ void defringecam (CieImage* ncie);
void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh);
+ void PF_correct_RTcam (CieImage * src, CieImage * dst, double radius, int thresh);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
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);// for gamma output
diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc
index f71c8e3be..f6a78d899 100644
--- a/rtengine/ipsharpen.cc
+++ b/rtengine/ipsharpen.cc
@@ -404,7 +404,9 @@ void ImProcFunctions::MLsharpen (LabImage* lab) {
if ((wH!=0.0f)&&(wV!=0.0f)&&(wD1!=0.0f)&&(wD2!=0.0f)) {
iii = offset/width;
kkk = offset-iii*width;
- templab = v*(1-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s;
+ float provL=lab->L[iii][kkk]/327.68f;
+ if(c==0){ if(provL < 92.f) templab = v*(1-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s; else templab=provL;}
+ else templab = v*(1-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s;
if (c==0) lab->L[iii][kkk] = fabs(327.68f*templab); // fabs because lab->L always >0
else if (c==1) lab->a[iii][kkk] = 327.68f*templab ;
else if (c==2) lab->b[iii][kkk] = 327.68f*templab ;
@@ -618,4 +620,385 @@ void ImProcFunctions::MLmicrocontrast(LabImage* lab) {
}
+void ImProcFunctions::MLmicrocontrastcam(CieImage* ncie) {
+ if (params->sharpenMicro.enabled==false)
+ return;
+ MyTime t1e,t2e;
+ t1e.set();
+ int k;
+ if (params->sharpenMicro.matrix == false) k=2; else k=1;
+ // k=2 matrix 5x5 k=1 matrix 3x3
+ int offset,offset2,i,j,col,row,n;
+ float temp,temp2,temp3,temp4,tempL;
+ float *LM,v,s,contrast;
+ int signs[25];
+ int width = ncie->W, height = ncie->H;
+ float uniform = params->sharpenMicro.uniformity;//between 0 to 100
+ int unif;
+ unif = (int)(uniform/10.0f); //put unif between 0 to 10
+ float amount = params->sharpenMicro.amount/1500.0f; //amount 2000.0 quasi no artefacts ==> 1500 = maximum, after artefacts
+ if (amount < 0.000001f)
+ return;
+ if (k==1)
+ amount *= 2.7f; //25/9 if 3x3
+ if (settings->verbose)
+ printf ("Micro-contrast amount %f\n", amount);
+ if (settings->verbose)
+ printf ("Micro-contrast uniformity %i\n",unif);
+ //modulation uniformity in function of luminance
+ float L98[11] = {0.001f,0.0015f,0.002f,0.004f,0.006f,0.008f,0.01f,0.03f,0.05f,0.1f,0.1f};
+ float L95[11] = {0.0012f,0.002f,0.005f,0.01f,0.02f,0.05f,0.1f,0.12f,0.15f,0.2f,0.25f};
+ float L92[11] = {0.01f,0.015f,0.02f,0.06f,0.10f,0.13f,0.17f,0.25f,0.3f,0.32f,0.35f};
+ float L90[11] = {0.015f,0.02f,0.04f,0.08f,0.12f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f};
+ float L87[11] = {0.025f,0.03f,0.05f,0.1f,0.15f,0.25f,0.3f,0.4f,0.5f,0.63f,0.75f};
+ float L83[11] = {0.055f,0.08f,0.1f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f,0.75f,0.85f};
+ float L80[11] = {0.15f,0.2f,0.25f,0.3f,0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f};
+ float L75[11] = {0.22f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,0.95f};
+ float L70[11] = {0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.97f,1.0f,1.0f,1.0f,1.0f};
+ float L63[11] = {0.55f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f};
+ float L58[11] = {0.75f,0.77f,0.8f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f};
+ //default 5
+ //modulation contrast
+ float Cont0[11] = {0.05f,0.1f,0.2f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f};
+ float Cont1[11] = {0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,0.95f,1.0f};
+ float Cont2[11] = {0.2f,0.40f,0.6f,0.7f,0.8f,0.85f,0.90f,0.95f,1.0f,1.05f,1.10f};
+ float Cont3[11] = {0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.05f,1.10f,1.20f};
+ float Cont4[11] = {0.8f,0.85f,0.9f,0.95f,1.0f,1.05f,1.10f,1.150f,1.2f,1.25f,1.40f};
+ float Cont5[11] = {1.0f,1.1f,1.2f,1.25f,1.3f,1.4f,1.45f,1.50f,1.6f,1.65f,1.80f};
+
+ float chmax=8.0f;
+ LM = new float[width*height];//allocation for Luminance
+#pragma omp parallel for private(offset, i,j) shared(LM)
+ for(j=0; jsh_p[j][i]/327.68f;// adjust to 0.100 and to RT variables
+ }
+
+#pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,temp2,temp3,tempL,temp4) shared(ncie,LM,amount,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58,Cont0,Cont1,Cont2,Cont3,Cont4,Cont5)
+ for(j=k; jLM[offset2]) signs[n]=1;
+ n++;
+ }
+ if (k==1) contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]))/chmax; //for 3x3
+ else if (k==2) contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width])
+ +fabs(LM[offset+2]-LM[offset-2])*fabs(LM[offset+2]-LM[offset-2])+fabs(LM[offset+2*width]-LM[offset-2*width])*fabs(LM[offset+2*width]-LM[offset-2*width]))/(2*chmax); //for 5x5
+
+ if (contrast>1.0f)
+ contrast=1.0f;
+ //matrix 5x5
+ temp=ncie->sh_p[j][i]/327.68f; //begin 3x3
+ temp += CLIREF(v-LM[offset-width-1])*sqrtf(2.0f)*s;
+ temp += CLIREF(v-LM[offset-width])*s;
+ temp += CLIREF(v-LM[offset-width+1])*sqrtf(2.0f)*s;
+ temp += CLIREF(v-LM[offset-1])*s;
+ temp += CLIREF(v-LM[offset+1])*s;
+ temp += CLIREF(v-LM[offset+width-1])*sqrtf(2.0f)*s;
+ temp += CLIREF(v-LM[offset+width])*s;
+ temp += CLIREF(v-LM[offset+width+1])*sqrtf(2.0f)*s;//end 3x3
+
+ // add JD continue 5x5
+ if (k==2) {
+ temp += 2.0f*CLIREF(v-LM[offset+2*width])*s;
+ temp += 2.0f*CLIREF(v-LM[offset-2*width])*s;
+ temp += 2.0f*CLIREF(v-LM[offset-2 ])*s;
+ temp += 2.0f*CLIREF(v-LM[offset+2 ])*s;
+
+ temp += 2.0f*CLIREF(v-LM[offset+2*width-1])*s*sqrtf(1.25f);// 1.25 = 1*1 + 0.5*0.5
+ temp += 2.0f*CLIREF(v-LM[offset+2*width-2])*s*sqrtf(2.00f);
+ temp += 2.0f*CLIREF(v-LM[offset+2*width+1])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset+2*width+2])*s*sqrtf(2.00f);
+ temp += 2.0f*CLIREF(v-LM[offset+ width+2])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset+ width-2])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset-2*width-1])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset-2*width-2])*s*sqrtf(2.00f);
+ temp += 2.0f*CLIREF(v-LM[offset-2*width+1])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset-2*width+2])*s*sqrtf(2.00f);
+ temp += 2.0f*CLIREF(v-LM[offset- width+2])*s*sqrtf(1.25f);
+ temp += 2.0f*CLIREF(v-LM[offset- width-2])*s*sqrtf(1.25f);
+ }
+ if (temp <0.0f) temp = 0.0f;
+ v=temp;
+
+ n=0;
+
+ for(row=j-k; row<=j+k; row++)
+ for(col=i-k,offset2=row*width+col; col<=i+k; col++,offset2++){
+ if (((v0))||((v>LM[offset2])&&(signs[n]<0))) {
+ temp = v*0.75f+LM[offset2]*0.25f;// 0.75 0.25
+ n++;
+ }
+ }
+ if (LM[offset]>95.0f || LM[offset]<5.0f)
+ contrast *= Cont0[unif]; //+ JD : luminance pyramid to adjust contrast by evaluation of LM[offset]
+ else if (LM[offset]>90.0f || LM[offset]<10.0f)
+ contrast *= Cont1[unif];
+ else if (LM[offset]>80.0f || LM[offset]<20.0f)
+ contrast *= Cont2[unif];
+ else if (LM[offset]>70.0f || LM[offset]<30.0f)
+ contrast *= Cont3[unif];
+ else if (LM[offset]>60.0f || LM[offset]<40.0f)
+ contrast *= Cont4[unif];
+ else
+ contrast *= Cont5[unif];//(2.0f/k)*Cont5[unif];
+
+ if (contrast>1.0f)
+ contrast=1.0f;
+ tempL = 327.68f*(temp*(1.0f-contrast)+LM[offset]*contrast);
+ // JD: modulation of microcontrast in function of original Luminance and modulation of luminance
+ temp2 = tempL/(327.68f*LM[offset]);//for highlights
+ if (temp2>1.0f) {
+ if (temp2>1.70f) temp2=1.70f;//limit action
+ if (LM[offset]>98.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f; }
+ else if (LM[offset]>95.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>92.0f) { temp3=temp2-1.0f; temp=(L92[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>90.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>87.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>83.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>80.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>75.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>70.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>63.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>58.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>42.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>37.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>30.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>25.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>20.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>17.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>13.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]>10.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]> 5.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; }
+ else if (LM[offset]> 0.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f;}
+ }
+ temp4 = (327.68f*LM[offset])/tempL;//
+ if (temp4>1.0f) {
+ if (temp4>1.7f)
+ temp4 = 1.7f;//limit action
+ if (LM[offset]< 2.0f) { temp3=temp4-1.0f; temp=(L98[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]< 5.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]< 8.0f) { temp3=temp4-1.0f; temp=(L92[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<10.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<13.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<17.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<20.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<25.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<30.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<37.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<42.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<58.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<63.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<70.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<75.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<80.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<83.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<87.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<90.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<95.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; }
+ else if (LM[offset]<100.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f; }
+ }
+
+ }
+ delete [] LM;
+ t2e.set();
+ if (settings->verbose)
+ printf("Micro-contrast %d usec\n", t2e.etime(t1e));
+
+}
+
+
+
+
+void ImProcFunctions::deconvsharpeningcam (CieImage* ncie, float** b2) {
+
+ if (params->sharpening.enabled==false || params->sharpening.deconvamount<1)
+ return;
+
+ int W = ncie->W, H = ncie->H;
+
+ float** tmpI = new float*[H];
+ for (int i=0; ish_p[i][j];
+ }
+
+ float** tmp = (float**)b2;
+
+#ifdef _OPENMP
+#pragma omp parallel
+#endif
+ {
+ AlignedBufferMP buffer(max(W,H));
+
+ float damping = params->sharpening.deconvdamping / 5.0;
+ bool needdamp = params->sharpening.deconvdamping > 0;
+ for (int k=0; ksharpening.deconviter; k++) {
+
+ // apply blur function (gaussian blur)
+ gaussHorizontal (tmpI, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+ gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+
+ if (!needdamp) {
+#ifdef _OPENMP
+#pragma omp for
+#endif
+ for (int i=0; i0)
+ tmp[i][j] = (float)ncie->sh_p[i][j] / tmp[i][j];
+ }
+ else
+ dcdamping (tmp, ncie->sh_p, damping, W, H);
+
+ gaussHorizontal (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+ gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+
+#ifdef _OPENMP
+#pragma omp for
+#endif
+ for (int i=0; isharpening.deconvamount / 100.0;
+ float p2 = params->sharpening.deconvamount / 100.0;
+ float p1 = 1.0 - p2;
+
+#ifdef _OPENMP
+#pragma omp for
+#endif
+ for (int i=0; iJ_p[i][j] > 8.0f && ncie->J_p[i][j] < 92.0f) ncie->sh_p[i][j] = ncie->sh_p[i][j]*p1 + max(tmpI[i][j],0.0f)*p2;
+
+ } // end parallel
+
+ for (int i=0; isharpening.method=="rld") {
+ deconvsharpeningcam (ncie, b2);
+ return;
+ }
+
+ // Rest is UNSHARP MASK
+ if (params->sharpening.enabled==false || params->sharpening.amount<1 || ncie->W<8 || ncie->H<8)
+ return;
+
+ int W = ncie->W, H = ncie->H;
+ float** b3;
+ if (params->sharpening.edgesonly) {
+ b3 = new float*[H];
+ for (int i=0; i buffer(max(W,H));
+
+ if (params->sharpening.edgesonly==false) {
+
+ gaussHorizontal (ncie->sh_p, b2, buffer, W, H, params->sharpening.radius / scale);
+ gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale);
+ }
+ else {
+ bilateral (ncie->sh_p, (float**)b3, b2, W, H, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance, multiThread);
+ gaussHorizontal (b3, b2, buffer, W, H, params->sharpening.radius / scale);
+ gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale);
+ }
+
+ float** base = ncie->sh_p;
+ if (params->sharpening.edgesonly)
+ base = b3;
+
+ if (params->sharpening.halocontrol==false) {
+ #pragma omp for
+ for (int i=0; isharpening.threshold.multiply(
+ min(ABS(diff), upperBound), // X axis value = absolute value of the difference, truncated to the max value of this field
+ params->sharpening.amount * diff * 0.01f // Y axis max value
+ );
+ if(ncie->J_p[i][j] > 8.0f && ncie->J_p[i][j] < 92.0f) ncie->sh_p[i][j] = ncie->sh_p[i][j] + delta;
+ }
+ }
+ else
+ sharpenHaloCtrlcam (ncie, b2, base, W, H);
+
+ } // end parallel
+
+ if (params->sharpening.edgesonly) {
+ for (int i=0; isharpening.halocontrol_amount) * 0.01f;
+ float sharpFac = params->sharpening.amount * 0.01f;
+ float** nL = base;
+
+#pragma omp parallel for if (multiThread)
+ for (int i=2; ish_p[i][j];
+ if (max_ < labL) max_ = labL;
+ if (min_ > labL) min_ = labL;
+
+ // deviation from the environment as measurement
+ float diff = nL[i][j] - blurmap[i][j];
+
+ const float upperBound = 2000.f; // WARNING: Duplicated value, it's baaaaaad !
+ float delta = params->sharpening.threshold.multiply(
+ min(ABS(diff), upperBound), // X axis value = absolute value of the difference
+ sharpFac * diff // Y axis max value = sharpening.amount * signed difference
+ );
+ float newL = labL + delta;
+ // applying halo control
+ if (newL > max_)
+ newL = max_ + (newL-max_) * scale;
+ else if (newL < min_)
+ newL = min_ - (min_-newL) * scale;
+
+ ncie->sh_p[i][j] = newL;
+ }
+ }
+}
+
}
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index 226cfa62b..febfb1d42 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -222,6 +222,7 @@ enum ProcEvent {
EvCATCurveMode3=197,
EvCATdatacie=198,
EvCATtonecie=199,
+// EvCATsharpcie=200,
NUMOFEVENTS=200
};
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index 4abf1c21f..9ef9dcc44 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -232,6 +232,7 @@ void ProcParams::setDefaults () {
colorappearance.gamut = true;
colorappearance.datacie = false;
colorappearance.tonecie = false;
+ // colorappearance.sharpcie = false;
colorappearance.curve.clear ();
colorappearance.curve.push_back(DCT_Linear);
colorappearance.curve2.clear ();
@@ -595,6 +596,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p
if (!pedited || pedited->colorappearance.gamut) keyFile.set_boolean ("Color appearance", "Gamut", colorappearance.gamut);
if (!pedited || pedited->colorappearance.datacie) keyFile.set_boolean ("Color appearance", "Datacie", colorappearance.datacie);
if (!pedited || pedited->colorappearance.tonecie) keyFile.set_boolean ("Color appearance", "Tonecie", colorappearance.tonecie);
+// if (!pedited || pedited->colorappearance.sharpcie) keyFile.set_boolean ("Color appearance", "Sharpcie", colorappearance.sharpcie);
if (!pedited || pedited->colorappearance.curveMode) {
Glib::ustring method;
switch (colorappearance.curveMode) {
@@ -1114,6 +1116,7 @@ if (keyFile.has_group ("Color appearance")) {
if (keyFile.has_key ("Color appearance", "Gamut")) {colorappearance.gamut = keyFile.get_boolean ("Color appearance", "Gamut"); if (pedited) pedited->colorappearance.gamut = true; }
if (keyFile.has_key ("Color appearance", "Datacie")) {colorappearance.datacie = keyFile.get_boolean ("Color appearance", "Datacie"); if (pedited) pedited->colorappearance.datacie = true; }
if (keyFile.has_key ("Color appearance", "Tonecie")) {colorappearance.tonecie = keyFile.get_boolean ("Color appearance", "Tonecie"); if (pedited) pedited->colorappearance.tonecie = true; }
+// if (keyFile.has_key ("Color appearance", "Sharpcie")) {colorappearance.sharpcie = keyFile.get_boolean ("Color appearance", "Sharpcie"); if (pedited) pedited->colorappearance.sharpcie = true; }
if (keyFile.has_key ("Color appearance", "CurveMode")) {
Glib::ustring sMode = keyFile.get_string ("Color appearance", "CurveMode");
if (sMode == "Lightness") colorappearance.curveMode = ColorAppearanceParams::TC_MODE_LIGHT;
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index a7a7f0da9..6872bd448 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -390,6 +390,7 @@ class WBParams {
bool gamut;
bool datacie;
bool tonecie;
+ // bool sharpcie;
};
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index f1882bcb8..5a22d365b 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -220,6 +220,7 @@ LUMINANCECURVE, // EvCATcurve3
LUMINANCECURVE, // EvCATcurvemode3
LUMINANCECURVE, // EvCATdatacie
LUMINANCECURVE // EvCATtonecie
+//LUMINANCECURVE // EvCATsharpcie
};
diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc
index 627d700b3..33fd52c96 100644
--- a/rtengine/rtthumbnail.cc
+++ b/rtengine/rtthumbnail.cc
@@ -791,15 +791,15 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve, curve1, curve2, satcurve,lhskcurve,
hist16C, hist16C, dummy,
16);
- //ipf.luminanceCurve (labView, labView, curve);
+ // ipf.luminanceCurve (labView, labView, curve);
ipf.chromiLuminanceCurve (1,labView, labView, curve1, curve2, satcurve,lhskcurve, curve, utili, autili, butili, ccutili,cclutili, dummy);
ipf.vibrance(labView);
int begh = 0, endh = labView->H;
- if(params.colorappearance.enabled && !params.colorappearance.tonecie) ipf.EPDToneMap(labView,5,6);
+ if((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) ipf.EPDToneMap(labView,5,6);
- if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);}
+// if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);}
CurveFactory::curveLightBrightColor (
params.colorappearance.curveMode, params.colorappearance.curve,
@@ -811,8 +811,16 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei
customColCurve2,
customColCurve3,
16);
-
- ipf.ciecam_02 (cieView, begh, endh, 1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 6);
+
+ int f_h=2,f_w=2;
+ float** buffer = new float*[fh];
+ for (int i=0; iwidth / fh;
diff --git a/rtengine/settings.h b/rtengine/settings.h
index c0f067f0e..0fd851f2c 100644
--- a/rtengine/settings.h
+++ b/rtengine/settings.h
@@ -31,7 +31,7 @@ namespace rtengine {
Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended)
bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile
-
+ bool autocielab;
bool verbose;
Glib::ustring darkFramesPath; ///< The default directory for dark frames
Glib::ustring flatFieldsPath; ///< The default directory for flat fields
@@ -48,6 +48,7 @@ namespace rtengine {
bool gamutICC;
bool gamutLch;
+ bool ciecamfloat;
int protectred;
double protectredh;
int CRI_color; // N° for display Lab value ; 0 disabled
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 097b79ee4..7251c6550 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -29,6 +29,9 @@
#include "rawimagesource.h"
#include "../rtgui/ppversion.h"
#undef THREAD_PRIORITY_NORMAL
+#ifdef _OPENMP
+#include
+#endif
namespace rtengine {
extern const Settings* settings;
@@ -167,7 +170,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
LUTf curve (65536,0);
LUTf satcurve (65536,0);
LUTf lhskcurve (65536,0);
-
+ LUTf lumacurve(65536,0);
+
LUTf rCurve (65536,0);
LUTf gCurve (65536,0);
LUTf bCurve (65536,0);
@@ -204,47 +208,68 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
// start tile processing...???
hist16.clear(); hist16C.clear();
+ if(params.labCurve.contrast !=0) {//only use hist16 for contrast
+
+#ifdef _OPENMP
+#pragma omp parallel shared(hist16,labView, fh, fw)
+#endif
+{
+#ifdef _OPENMP
+#pragma omp for schedule(static)
+#endif
+ for (int i=0; iL[i][j])))]++;
+ }
+}
+
+
+ }
bool utili=false;
bool autili=false;
bool butili=false;
bool ccutili=false;
bool cclutili=false;
- CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, hist16, hist16, curve, dummy, 1, utili);
+ CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,hist16, hist16, lumacurve, dummy, 1, utili);
CurveFactory::complexsgnCurve (autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection,
params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,params.labCurve.lccurve,curve1, curve2, satcurve,lhskcurve,
hist16C, hist16C,dummy,
1);
- ipf.chromiLuminanceCurve (1,labView, labView, curve1, curve2, satcurve,lhskcurve,curve, utili, autili, butili, ccutili,cclutili,dummy);
+
+ ipf.chromiLuminanceCurve (1,labView, labView, curve1, curve2, satcurve,lhskcurve,lumacurve, utili, autili, butili, ccutili,cclutili,dummy);
- if(params.colorappearance.enabled && !params.colorappearance.tonecie)ipf.EPDToneMap(labView,5,1);
+ if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled))ipf.EPDToneMap(labView,5,1);
- if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,1);}
ipf.vibrance(labView);
ipf.impulsedenoise (labView);
- ipf.defringe (labView);
+ // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled
+
+ if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ipf.defringe (labView);
+
if (params.sharpenEdge.enabled) {
ipf.MLsharpen(labView);
}
if (params.sharpenMicro.enabled) {
- ipf.MLmicrocontrast (labView);
+ if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ipf.MLmicrocontrast (labView);//!params.colorappearance.sharpcie
}
- if (params.sharpening.enabled) {
- float** buffer = new float*[fh];
- for (int i=0; iautocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) {
+
+ float **buffer = new float*[fh];
+ for (int i=0; iautocielab) || !params.colorappearance.enabled) ipf.dirpyrequalizer (labView);//TODO: this is the luminance tonecurve, not the RGB one
//Colorappearance and tone-mapping associated
@@ -264,9 +289,30 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
customColCurve2,
customColCurve3,
1);
-
- ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1);
-
+ if (params.sharpening.enabled) {
+ float** buffer = new float*[fh];
+ for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
+ else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
+
+ for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
+else ipf.ciecam_02 (cieView, begh, endh,1, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, 5, 1, (float**)buffer, true);
+
+ for (int i=0; isetProgress (0.75);
-
+/* curve1.reset();curve2.reset();
+ curve.reset();
+ satcurve.reset();
+ lhskcurve.reset();
+
+ rCurve.reset();
+ gCurve.reset();
+ bCurve.reset();
+ hist16.reset();
+ hist16C.reset();
+*/
return readyImg;
}
diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc
index 89274c791..58fd51a67 100644
--- a/rtgui/colorappearance.cc
+++ b/rtgui/colorappearance.cc
@@ -181,7 +181,12 @@ ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) {
tonecie->set_tooltip_markup (M("TP_COLORAPP_TONECIE_TOOLTIP"));
tonecieconn = tonecie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::tonecie_toggled) );
p2VBox->pack_start (*tonecie);
-
+/*
+ sharpcie = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_SHARPCIE")));
+ sharpcie->set_tooltip_markup (M("TP_COLORAPP_SHARPCIE_TOOLTIP"));
+ sharpcieconn = sharpcie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::sharpcie_toggled) );
+ p2VBox->pack_start (*sharpcie);
+*/
p2VBox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4);
toneCurveMode = Gtk::manage (new MyComboBoxText ());
@@ -337,12 +342,6 @@ ColorAppearance::ColorAppearance () : Gtk::VBox(), FoldableToolPanel(this) {
gamut->set_tooltip_markup (M("TP_COLORAPP_GAMUT_TOOLTIP"));
gamutconn = gamut->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::gamut_toggled) );
pack_start (*gamut, Gtk::PACK_SHRINK);
-/*
- tonecie = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_TONECIE")));
- tonecie->set_tooltip_markup (M("TP_COLORAPP_TONECIE_TOOLTIP"));
- tonecieconn = tonecie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::tonecie_toggled) );
- pack_start (*tonecie, Gtk::PACK_SHRINK);
-*/
// ------------------------ Listening events
@@ -415,6 +414,7 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) {
gamut->set_inconsistent (!pedited->colorappearance.gamut);
datacie->set_inconsistent (!pedited->colorappearance.datacie);
tonecie->set_inconsistent (!pedited->colorappearance.tonecie);
+ // sharpcie->set_inconsistent (!pedited->colorappearance.sharpcie);
degree->setAutoInconsistent (multiImage && !pedited->colorappearance.autodegree);
enabled->set_inconsistent (multiImage && !pedited->colorappearance.enabled);
@@ -491,11 +491,15 @@ void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) {
tonecieconn.block (true);
tonecie->set_active (pp->colorappearance.tonecie);
tonecieconn.block (false);
+// sharpcieconn.block (true);
+// sharpcie->set_active (pp->colorappearance.sharpcie);
+// sharpcieconn.block (false);
lastsurr=pp->colorappearance.surrsource;
lastgamut=pp->colorappearance.gamut;
lastdatacie=pp->colorappearance.datacie;
lasttonecie=pp->colorappearance.tonecie;
+// lastsharpcie=pp->colorappearance.sharpcie;
lastEnabled = pp->colorappearance.enabled;
lastAutoDegree = pp->colorappearance.autodegree;
@@ -547,6 +551,7 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) {
pp->colorappearance.gamut = gamut->get_active();
pp->colorappearance.datacie = datacie->get_active();
pp->colorappearance.tonecie = tonecie->get_active();
+// pp->colorappearance.sharpcie = sharpcie->get_active();
pp->colorappearance.curve = shape->getCurve ();
pp->colorappearance.curve2 = shape2->getCurve ();
pp->colorappearance.curve3 = shape3->getCurve ();
@@ -586,6 +591,7 @@ void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) {
pedited->colorappearance.gamut = !gamut->get_inconsistent();
pedited->colorappearance.datacie = !datacie->get_inconsistent();
pedited->colorappearance.tonecie = !tonecie->get_inconsistent();
+ // pedited->colorappearance.sharpcie = !sharpcie->get_inconsistent();
pedited->colorappearance.curve = !shape->isUnChanged ();
pedited->colorappearance.curve2 = !shape2->isUnChanged ();
pedited->colorappearance.curve3 = !shape3->isUnChanged ();
@@ -753,7 +759,30 @@ void ColorAppearance::tonecie_toggled () {
}
}
+/*
+void ColorAppearance::sharpcie_toggled () {
+ if (batchMode) {
+ if (sharpcie->get_inconsistent()) {
+ sharpcie->set_inconsistent (false);
+ sharpcieconn.block (true);
+ sharpcie->set_active (false);
+ sharpcieconn.block (false);
+ }
+ else if (lastsharpcie)
+ sharpcie->set_inconsistent (true);
+
+ lastsharpcie = sharpcie->get_active ();
+ }
+ if (listener) {
+ if (sharpcie->get_active ())
+ listener->panelChanged (EvCATsharpcie, M("GENERAL_ENABLED"));
+ else
+ listener->panelChanged (EvCATsharpcie, M("GENERAL_DISABLED"));
+ }
+
+}
+*/
void ColorAppearance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
@@ -929,6 +958,7 @@ void ColorAppearance::algoChanged () {
qbright->hide();
colorh->hide();
tonecie->hide();
+ // sharpcie->hide();
curveEditorG->show();
curveEditorG2->show();
curveEditorG3->show();
@@ -944,6 +974,7 @@ void ColorAppearance::algoChanged () {
qbright->hide();
colorh->hide();
tonecie->hide();
+// sharpcie->hide();
curveEditorG->show();
curveEditorG2->show();
curveEditorG3->show();
@@ -959,6 +990,8 @@ void ColorAppearance::algoChanged () {
qbright->show();
colorh->hide();
tonecie->show();
+ // sharpcie->show();
+ // sharpcie->hide();
curveEditorG->show();
curveEditorG2->show();
curveEditorG3->show();
@@ -974,6 +1007,8 @@ void ColorAppearance::algoChanged () {
qbright->show();
colorh->show();
tonecie->show();
+// sharpcie->show();
+// sharpcie->hide();
curveEditorG->show();
curveEditorG2->show();
curveEditorG3->show();
diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h
index abcc8354f..0b69002a0 100644
--- a/rtgui/colorappearance.h
+++ b/rtgui/colorappearance.h
@@ -57,6 +57,7 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
Gtk::CheckButton* gamut;
Gtk::CheckButton* datacie;
Gtk::CheckButton* tonecie;
+ // Gtk::CheckButton* sharpcie;
Gtk::CheckButton* enabled;
MyComboBoxText* surround;
@@ -66,7 +67,7 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
MyComboBoxText* algo;
sigc::connection algoconn;
sigc::connection surrconn;
- sigc::connection gamutconn, datacieconn, tonecieconn;
+ sigc::connection gamutconn, datacieconn, tonecieconn /*, sharpcieconn*/;
sigc::connection tcmodeconn, tcmode2conn, tcmode3conn;
CurveEditorGroup* curveEditorG;
CurveEditorGroup* curveEditorG2;
@@ -83,7 +84,8 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
bool lastgamut;
bool lastdatacie;
bool lasttonecie;
- bool bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip);
+ // bool lastsharpcie;
+ bool bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip);
bool srTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip);
public:
@@ -106,6 +108,7 @@ class ColorAppearance : public Gtk::VBox, public AdjusterListener, public Foldab
void gamut_toggled ();
void datacie_toggled ();
void tonecie_toggled ();
+// void sharpcie_toggled ();
void curveChanged (CurveEditor* ce);
void curveMode1Changed ();
diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc
index 0a4142299..3fc98d497 100644
--- a/rtgui/defringe.cc
+++ b/rtgui/defringe.cc
@@ -29,6 +29,8 @@ Defringe::Defringe () : Gtk::VBox(), FoldableToolPanel(this) {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
+ enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP"));
+
enabled->show ();
pack_start (*enabled);
diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc
index 57ca3b8bb..edfb1fcd7 100644
--- a/rtgui/dirpyrequalizer.cc
+++ b/rtgui/dirpyrequalizer.cc
@@ -30,6 +30,7 @@ DirPyrEqualizer::DirPyrEqualizer () : Gtk::VBox(), FoldableToolPanel(this) {
enabled->set_active (true);
pack_start(*enabled);
enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrEqualizer::enabledToggled) );
+ enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP"));
Gtk::HSeparator *separator1 = Gtk::manage (new Gtk::HSeparator());
pack_start(*separator1, Gtk::PACK_SHRINK, 2);
diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc
index 4cc81855f..2208886c6 100644
--- a/rtgui/labcurve.cc
+++ b/rtgui/labcurve.cc
@@ -239,6 +239,7 @@ void LCurve::autoOpenCurve () {
if (!active) ccshape->openIfNonlinear();
if (!active) chshape->openIfNonlinear();
if (!active) lcshape->openIfNonlinear();
+
}
void LCurve::write (ProcParams* pp, ParamsEdited* pedited) {
diff --git a/rtgui/options.cc b/rtgui/options.cc
index d4fc3002d..4f924a2a9 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -438,10 +438,11 @@ void Options::setDefaults () {
rtSettings.verbose = false;
rtSettings.gamutICC = true;
rtSettings.gamutLch = true;
+ rtSettings.ciecamfloat = true;
rtSettings.protectred = 60;
rtSettings.protectredh = 0.3;
rtSettings.CRI_color =0;
-
+ rtSettings.autocielab=true;
lastIccDir = rtSettings.iccDirectory;
lastDarkframeDir = rtSettings.darkFramesPath;
lastFlatfieldDir = rtSettings.flatFieldsPath;
@@ -647,6 +648,8 @@ if (keyFile.has_group ("Color Management")) {
if (keyFile.has_key ("Color Management", "ICCDirectory")) rtSettings.iccDirectory = keyFile.get_string ("Color Management", "ICCDirectory");
if (keyFile.has_key ("Color Management", "MonitorProfile")) rtSettings.monitorProfile = keyFile.get_string ("Color Management", "MonitorProfile");
if (keyFile.has_key ("Color Management", "AutoMonitorProfile")) rtSettings.autoMonitorProfile = keyFile.get_boolean ("Color Management", "AutoMonitorProfile");
+ if (keyFile.has_key ("Color Management", "Autocielab")) rtSettings.autocielab = keyFile.get_boolean ("Color Management", "Autocielab");
+ if (keyFile.has_key ("Color Management", "Ciencamfloat")) rtSettings.ciecamfloat = keyFile.get_boolean ("Color Management", "Ciecamfloat");
if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent");
if (keyFile.has_key ("Color Management", "CRI")) rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI");
@@ -655,6 +658,7 @@ if (keyFile.has_group ("Color Management")) {
if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize");
if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC");
+ if( keyFile.has_key ("Color Management", "Ciecamfloat")) rtSettings.ciecamfloat = keyFile.get_boolean("Color Management", "Ciecamfloat");
if( keyFile.has_key ("Color Management", "AdobeRGB")) rtSettings.adobe = keyFile.get_string("Color Management", "AdobeRGB");
if( keyFile.has_key ("Color Management", "ProPhoto")) rtSettings.prophoto = keyFile.get_string("Color Management", "ProPhoto");
if( keyFile.has_key ("Color Management", "ProPhoto10")) rtSettings.prophoto10 = keyFile.get_string("Color Management", "ProPhoto10");
@@ -894,6 +898,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory);
keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile);
keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile);
+ keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab);
keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent);
keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice);
keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevice);
@@ -909,6 +914,7 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce);
keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize);
keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC);
+ keyFile.set_boolean ("Color Management", "Ciecamfloat", rtSettings.ciecamfloat);
keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch);
keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred);
keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh);
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index e03324c0a..1e95c0a86 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -114,6 +114,7 @@ void ParamsEdited::set (bool v) {
colorappearance.gamut = v;
colorappearance.datacie = v;
colorappearance.tonecie = v;
+// colorappearance.sharpcie = v;
colorappearance.curve = v;
colorappearance.curve2 = v;
colorappearance.curve3 = v;
@@ -345,6 +346,7 @@ void ParamsEdited::initFrom (const std::vector
colorappearance.gamut = colorappearance.gamut && p.colorappearance.gamut == other.colorappearance.gamut;
colorappearance.datacie = colorappearance.datacie && p.colorappearance.datacie == other.colorappearance.datacie;
colorappearance.tonecie = colorappearance.tonecie && p.colorappearance.tonecie == other.colorappearance.tonecie;
+ // colorappearance.sharpcie = colorappearance.sharpcie && p.colorappearance.sharpcie == other.colorappearance.sharpcie;
colorappearance.curve = colorappearance.curve && p.colorappearance.curve == other.colorappearance.curve;
colorappearance.curve3 = colorappearance.curve3 && p.colorappearance.curve3 == other.colorappearance.curve3;
colorappearance.curve2 = colorappearance.curve2 && p.colorappearance.curve2 == other.colorappearance.curve2;
@@ -612,6 +614,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (colorappearance.gamut) toEdit.colorappearance.gamut = mods.colorappearance.gamut;
if (colorappearance.datacie) toEdit.colorappearance.datacie = mods.colorappearance.datacie;
if (colorappearance.tonecie) toEdit.colorappearance.tonecie = mods.colorappearance.tonecie;
+// if (colorappearance.sharpcie) toEdit.colorappearance.sharpcie = mods.colorappearance.sharpcie;
if (impulseDenoise.enabled) toEdit.impulseDenoise.enabled = mods.impulseDenoise.enabled;
if (impulseDenoise.thresh) toEdit.impulseDenoise.thresh = mods.impulseDenoise.thresh;
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index cf8f3902a..3b3472ffc 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -211,6 +211,7 @@ public:
bool gamut;
bool datacie;
bool tonecie;
+// bool sharpcie;
};
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index 036263202..a331bf4a6 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -195,7 +195,6 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
mi->set_value (behavColumns.label, M("TP_COLORAPP_LABEL"));
appendBehavList (mi, M("TP_COLORAPP_CIECAT_DEGREE"),ADDSET_CAT_DEGREE, true);
appendBehavList (mi, M("TP_COLORAPP_ADAPTSCENE"),ADDSET_CAT_ADAPTSCENE, true);
- appendBehavList (mi, M("TP_COLORAPP_ADAPTVIEWING"),ADDSET_CAT_ADAPTVIEWING, true);
appendBehavList (mi, M("TP_COLORAPP_LIGHT"),ADDSET_CAT_LIGHT, true);
appendBehavList (mi, M("TP_COLORAPP_BRIGHT"),ADDSET_CAT_BRIGHT, true);
appendBehavList (mi, M("TP_COLORAPP_CHROMA"),ADDSET_CAT_CHROMA, true);
@@ -205,6 +204,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () {
appendBehavList (mi, M("TP_COLORAPP_CHROMA_S"),ADDSET_CAT_CHROMA_S, true);
appendBehavList (mi, M("TP_COLORAPP_CHROMA_M"),ADDSET_CAT_CHROMA_M, true);
appendBehavList (mi, M("TP_COLORAPP_HUE"),ADDSET_CAT_HUE, true);
+ appendBehavList (mi, M("TP_COLORAPP_ADAPTVIEWING"),ADDSET_CAT_ADAPTVIEWING, true);
mi = behModel->append ();
mi->set_value (behavColumns.label, M("TP_VIBRANCE_LABEL"));
@@ -460,9 +460,21 @@ Gtk::Widget* Preferences::getColorManagementPanel () {
colo->attach (*greylab, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2);
colo->attach (*grey, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
colo->attach (*restartNeeded2, 2, 3, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2);
-
mvbcm->pack_start (*colo, Gtk::PACK_SHRINK, 4);
+ Gtk::Label* cielab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CIEART")+":", Gtk::ALIGN_LEFT));
+ cbciecamfloat = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_CIEART_LABEL")));
+ //autocielabConn = cbAutocielab->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::autocielabToggled));
+ Gtk::Table* coltcie = Gtk::manage (new Gtk::Table (1, 2));
+ coltcie->attach (*cielab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2);
+ // coltcie->attach (*cbAutocielab, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
+ //cbAutocielab->set_tooltip_markup (M("PREFERENCES_CIEART_TOOLTIP"));
+ coltcie->attach (*cbciecamfloat, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
+ cbciecamfloat->set_tooltip_markup (M("PREFERENCES_CIEART_TOOLTIP"));
+
+ mvbcm->pack_start (*coltcie, Gtk::PACK_SHRINK, 4);
+ // autocielabToggled();
+
return mvbcm;
}
@@ -1077,6 +1089,8 @@ void Preferences::storePreferences () {
moptions.rtSettings.colorimetricIntent = intent->get_active_row_number ();
moptions.rtSettings.viewingdevice = view->get_active_row_number ();
moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number ();
+ // moptions.rtSettings.autocielab = cbAutocielab->get_active ();
+ moptions.rtSettings.ciecamfloat = cbciecamfloat->get_active ();
if (sdcurrent->get_active ())
moptions.startupDir = STARTUPDIR_CURRENT;
@@ -1165,7 +1179,8 @@ void Preferences::fillPreferences () {
intent->set_active (moptions.rtSettings.colorimetricIntent);
view->set_active (moptions.rtSettings.viewingdevice);
grey->set_active (moptions.rtSettings.viewingdevicegrey);
-
+// cbAutocielab->set_active (moptions.rtSettings.autocielab);
+ cbciecamfloat->set_active (moptions.rtSettings.ciecamfloat);
languages->set_active_text (moptions.language);
ckbLangAutoDetect->set_active (moptions.languageAutoDetect);
theme->set_active_text (moptions.theme);
@@ -1312,7 +1327,11 @@ void Preferences::savePressed () {
void Preferences::autoMonProfileToggled () {
monProfile->set_sensitive(!cbAutoMonProfile->get_active());
}
-
+/*
+void Preferences::autocielabToggled () {
+// cbAutocielab->set_sensitive(cbAutocielab->get_active());
+}
+*/
void Preferences::sndEnableToggled () {
txtSndBatchQueueDone->set_sensitive(ckbSndEnable->get_active());
txtSndLngEditProcDone->set_sensitive(ckbSndEnable->get_active());
diff --git a/rtgui/preferences.h b/rtgui/preferences.h
index 3ee715847..d0cd991e7 100644
--- a/rtgui/preferences.h
+++ b/rtgui/preferences.h
@@ -80,6 +80,8 @@ class Preferences : public Gtk::Dialog {
Gtk::FileChooserButton* iccDir;
Gtk::FileChooserButton* monProfile;
Gtk::CheckButton* cbAutoMonProfile;
+ //Gtk::CheckButton* cbAutocielab;
+ Gtk::CheckButton* cbciecamfloat;
Gtk::CheckButton* blinkClipped;
Gtk::SpinButton* hlThresh;
@@ -144,7 +146,7 @@ class Preferences : public Gtk::Dialog {
Options moptions;
sigc::connection tconn, sconn, fconn, usethcon, addc, setc, dfconn, ffconn;
- sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn;
+ sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn, autocielabConn;
Glib::ustring initialTheme;
Glib::ustring initialFont;
@@ -186,6 +188,7 @@ class Preferences : public Gtk::Dialog {
void autoMonProfileToggled ();
void sndEnableToggled ();
void langAutoDetectToggled ();
+ void autocielabToggled ();
void selectStartupDir ();
void addExtPressed ();
diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc
index 0d257f074..0555bc609 100644
--- a/rtgui/sharpening.cc
+++ b/rtgui/sharpening.cc
@@ -33,6 +33,8 @@ Sharpening::Sharpening () : Gtk::VBox(), FoldableToolPanel(this) {
milestones.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) );
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
+ enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP"));
+
enabled->set_active (true);
pack_start(*enabled);
enabled->show ();
diff --git a/rtgui/sharpenmicro.cc b/rtgui/sharpenmicro.cc
index 9e9978abd..7d20822e4 100644
--- a/rtgui/sharpenmicro.cc
+++ b/rtgui/sharpenmicro.cc
@@ -33,6 +33,8 @@ SharpenMicro::SharpenMicro () : Gtk::VBox(), FoldableToolPanel(this) {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (true);
+ enabled->set_tooltip_markup (M("TP_SHARPENING_TOOLTIP"));
+
pack_start(*enabled, Gtk::PACK_SHRINK, 0);
enabled->show ();
diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc
index e35c4018f..69a819f77 100644
--- a/rtgui/tonecurve.cc
+++ b/rtgui/tonecurve.cc
@@ -212,8 +212,8 @@ void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) {
}
void ToneCurve::autoOpenCurve () {
- shape->openIfNonlinear();
- shape2->openIfNonlinear();
+ shape->openIfNonlinear();
+ shape2->openIfNonlinear();
}
void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) {