diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais index dfa62c3df..a0c4493ed 100644 --- a/rtdata/languages/Francais +++ b/rtdata/languages/Francais @@ -202,6 +202,7 @@ GENERAL_PORTRAIT;Portrait GENERAL_SAVE;Enregistrer GENERAL_UNCHANGED;(Inchangé) GENERAL_YES;Oui +GENERAL_WARNING;Attention HISTOGRAM_BUTTON_BAR;RVB HISTOGRAM_BUTTON_B;B HISTOGRAM_BUTTON_G;V @@ -314,7 +315,7 @@ HISTORY_MSG_91;Réd. de bruit Chrominance HISTORY_MSG_92;Réd. de bruit Gamma HISTORY_MSG_93;Param. de contraste HISTORY_MSG_94;Contraste par niveau de détail -HISTORY_MSG_95;Saturation +HISTORY_MSG_95;Chromaticité HISTORY_MSG_96;Courbe 'a' HISTORY_MSG_97;Courbe 'b' HISTORY_MSG_98;Algorithme de dématriçage @@ -330,9 +331,9 @@ HISTORY_MSG_107;A.C. - Seuil HISTORY_MSG_108;Seuil de compr. des hautes lumières HISTORY_MSG_109;Redim. - boîte englobante HISTORY_MSG_110;Redim. s'applique à -HISTORY_MSG_111;Éviter l'écrêtage couleur -HISTORY_MSG_112;Limiteur de saturation -HISTORY_MSG_113;Limite de saturation +HISTORY_MSG_111;Éviter les dérives de teinte +HISTORY_MSG_112;--inutilisé-- +HISTORY_MSG_113;Protection des tons rouges et chair HISTORY_MSG_114;Nbr d'itération DCB HISTORY_MSG_115;Nbr d'itération des fausses couleurs HISTORY_MSG_116;DCB amélioré @@ -386,6 +387,10 @@ HISTORY_MSG_163;Courbes RVB - R HISTORY_MSG_164;Courbes RVB - V HISTORY_MSG_165;Courbes RVB - B HISTORY_MSG_166;Niveaux neutre +HISTORY_MSG_167;Mode N&B colorisable +HISTORY_MSG_168;Courbe 'Cc' +HISTORY_MSG_169;Courbe 'Ct' +HISTORY_MSG_170;Vibrance - courbe HISTORY_NEWSNAPSHOTAS;Sous... HISTORY_NEWSNAPSHOT;Ajouter HISTORY_NEWSSDIALOGLABEL;Label de la capture: @@ -803,6 +808,8 @@ SAVEDLG_SAVEIMMEDIATELY;Enregistrer immédiatement SAVEDLG_SAVESPP;Enregistrer les paramètres de développement avec l'image SAVEDLG_TIFFFILTER;Fichiers TIFF SAVEDLG_TIFFUNCOMPRESSED;TIFF non compressé +SAVEDLG_WARNFILENAME;Le fichier sera nommé +SHCSELECTOR_TOOLTIP;Cliquez le bouton droit de la souris\npour réinitiliser la position de ces 3 curseurs THRESHOLDSELECTOR_B;Bas THRESHOLDSELECTOR_BL;Bas-gauche THRESHOLDSELECTOR_BR;Bas-droite @@ -958,14 +965,32 @@ TP_ICM_SAVEREFERENCE;Utiliser l'image comme profil de référence TP_ICM_WORKINGPROFILE;Profil de Travail TP_IMPULSEDENOISE_LABEL;Réduction du bruit d'impulsion TP_IMPULSEDENOISE_THRESH;Seuil -TP_LABCURVE_AVOIDCOLORCLIP;Éviter l'écrêtage couleur +TP_LABCURVE_AVOIDCOLORSHIFT;Éviter les dérives de teinte +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Ramènes les données dans le gamut de l'espace couleur de travail\npuis applique la correction de Munsell TP_LABCURVE_BRIGHTNESS;Luminosité +TP_LABCURVE_BWTONING;Mode N&B colorisable +TP_LABCURVE_BWTONING_TIP;Avec le mode N&B colorisable activé, la Chromaticité, la courbe Cc et Ct sont sans effet.\nLa colorisation peut être effctué en utilisant les courbes a et b. TP_LABCURVE_CONTRAST;Contraste TP_LABCURVE_CURVEEDITOR;Courbe de luminance -TP_LABCURVE_ENABLESATLIMITER;Activer le limiteur de saturation +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Vert saturé +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Vert pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rouge pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rouge saturé +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Bleu saturé +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Bleu pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Jaune pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Jaune saturé +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutre +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Terne +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturé +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticité en fonction de la Chromaticité +TP_LABCURVE_CURVEEDITOR_CH;CT +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticité en fonction de la Teinte TP_LABCURVE_LABEL;Courbes Lab -TP_LABCURVE_SATLIMIT;Limite de saturation -TP_LABCURVE_SATURATION;Saturation +TP_LABCURVE_RSTPROTECTION;Protection des tons rouges et chair +TP_LABCURVE_CHROMATICITY;Chromaticité TP_LENSGEOM_AUTOCROP;Recadrage auto TP_LENSGEOM_FILL;Remplir TP_LENSGEOM_LABEL;Objectif / Géométrie @@ -1060,6 +1085,13 @@ TP_SHARPENMICRO_LABEL;Microcontraste TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformité TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte +TP_VIBRANCE_CURVEEDITOR_SKINTONES;TT +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tons chair +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rouge/Pourpre +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rouge +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rouge/Jaune +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Jaune +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Teinte en fonction de la teinte TP_VIBRANCE_LABEL;Vibrance TP_VIBRANCE_PASTELS;Tons pastels TP_VIBRANCE_PASTSATTOG;Lier Pastels et Saturés diff --git a/rtdata/languages/default b/rtdata/languages/default index dd06445c9..909ab7fe4 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -316,7 +316,7 @@ HISTORY_MSG_91;NR - Chrominance HISTORY_MSG_92;NR - Gamma HISTORY_MSG_93;Contrast by Detail Levels Value HISTORY_MSG_94;Contrast by Detail Levels -HISTORY_MSG_95;Saturation +HISTORY_MSG_95;Chromaticity HISTORY_MSG_96;'a' Curve HISTORY_MSG_97;'b' Curve HISTORY_MSG_98;Demosaicing Method @@ -332,9 +332,9 @@ HISTORY_MSG_107;Defringing Threshold HISTORY_MSG_108;Highlight Compr. Threshold HISTORY_MSG_109;Resize Bounding Box HISTORY_MSG_110;Resizing applies o -HISTORY_MSG_111;Avoid Color Clipping -HISTORY_MSG_112;Saturation Limiter -HISTORY_MSG_113;Saturation Limit +HISTORY_MSG_111;Avoid Color Shift +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;Red and Skin Tones Protection HISTORY_MSG_114;DCB Iterations HISTORY_MSG_115;False Color Iterations HISTORY_MSG_116;Enhanced DCB @@ -388,7 +388,10 @@ HISTORY_MSG_163;RGB Curves - R HISTORY_MSG_164;RGB Curves - G HISTORY_MSG_165;RGB Curves - B HISTORY_MSG_166;Neutral Levels -HISTORY_MSG_167;BW Toning +HISTORY_MSG_167;B&W Toning +HISTORY_MSG_168;'Cc' curve +HISTORY_MSG_169;'Ch' curve +HISTORY_MSG_170;Vibrance - Curve HISTORY_NEWSNAPSHOTAS;As... HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSSDIALOGLABEL;Label of the snapshot: @@ -807,6 +810,7 @@ SAVEDLG_SAVESPP;Save processing parameters with image SAVEDLG_TIFFFILTER;TIFF files SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF SAVEDLG_WARNFILENAME;File will be named +SHCSELECTOR_TOOLTIP;Click right mouse button to reset\nthe position of those 3 sliders THRESHOLDSELECTOR_B;Bottom THRESHOLDSELECTOR_BL;Bottom-left THRESHOLDSELECTOR_BR;Bottom-right @@ -967,16 +971,32 @@ TP_ICM_SAVEREFERENCE;Save reference image for profiling TP_ICM_WORKINGPROFILE;Working Profile TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction TP_IMPULSEDENOISE_THRESH;Impulse NR Threshold -TP_LABCURVE_AVOIDCOLORCLIP;Avoid color clipping +TP_LABCURVE_AVOIDCOLORSHIFT;Avoid Color Shift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space\nand apply Munsell correction TP_LABCURVE_BRIGHTNESS;Brightness -TP_LABCURVE_BWTONING;BW Toning -TP_LABCURVE_BWTONING_TIP;With BW Toning option enabled the Lab Saturation is not in effect.\nToning can be achieved using the a and b curves +TP_LABCURVE_BWTONING;B&W Toning +TP_LABCURVE_BWTONING_TIP;With B&W Toning option enabled, the Lab Chromaticity, Cc and Ch curves are not in effect.\nToning can be achieved using the a and b curves TP_LABCURVE_CONTRAST;Contrast TP_LABCURVE_CURVEEDITOR;Luminance Curve -TP_LABCURVE_ENABLESATLIMITER;Enable saturation limiter +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green saturated +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red saturated +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue saturated +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow saturated +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to the Chromaticity +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to the Hue TP_LABCURVE_LABEL;Lab Adjustments -TP_LABCURVE_SATLIMIT;Saturation limit -TP_LABCURVE_SATURATION;Saturation +TP_LABCURVE_RSTPROTECTION;Red and Skin Tones Protection +TP_LABCURVE_CHROMATICITY;Chromaticity TP_LENSGEOM_AUTOCROP; Auto Crop TP_LENSGEOM_FILL;Auto Fill TP_LENSGEOM_LABEL;Lens / Geometry @@ -1074,6 +1094,13 @@ TP_SHARPENMICRO_LABEL;Microcontrast TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 TP_SHARPENMICRO_UNIFORMITY;Uniformity TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin tones +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to the Hue TP_VIBRANCE_LABEL;Vibrance TP_VIBRANCE_PASTELS;Pastel tones TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones diff --git a/rtdata/profiles/BW-1.pp3 b/rtdata/profiles/BW-1.pp3 index cc5e02b89..b4830cd18 100644 --- a/rtdata/profiles/BW-1.pp3 +++ b/rtdata/profiles/BW-1.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=-100 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/BW-2.pp3 b/rtdata/profiles/BW-2.pp3 index 835632359..bc7f34a7f 100644 --- a/rtdata/profiles/BW-2.pp3 +++ b/rtdata/profiles/BW-2.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=-100 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/BW-3.pp3 b/rtdata/profiles/BW-3.pp3 index 31db39f9f..fbde7b35a 100644 --- a/rtdata/profiles/BW-3.pp3 +++ b/rtdata/profiles/BW-3.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=-25 -Saturation=-100 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=2;0.25;0.5;0.75;50;12;-12;-50; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/BW-4.pp3 b/rtdata/profiles/BW-4.pp3 index 3674873ca..b1f8785b5 100644 --- a/rtdata/profiles/BW-4.pp3 +++ b/rtdata/profiles/BW-4.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=-35 -Saturation=-100 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=true +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=3;0;0;0.18623481781376497;0.028340080971659902;0.50607287449392713;0.50607287449392713;0.77732793522267185;0.97975708502024295;1;1; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Default-ISO-High.pp3 b/rtdata/profiles/Default-ISO-High.pp3 index 9c3babc28..0aa28f95f 100644 --- a/rtdata/profiles/Default-ISO-High.pp3 +++ b/rtdata/profiles/Default-ISO-High.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Default-ISO-Medium.pp3 b/rtdata/profiles/Default-ISO-Medium.pp3 index 9ba98b5c1..07ecc0e93 100644 --- a/rtdata/profiles/Default-ISO-Medium.pp3 +++ b/rtdata/profiles/Default-ISO-Medium.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 index 10e34eb9d..03a3d099f 100644 --- a/rtdata/profiles/Default.pp3 +++ b/rtdata/profiles/Default.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Highkey-1.pp3 b/rtdata/profiles/Highkey-1.pp3 index e35e54cfc..ffad5dae4 100644 --- a/rtdata/profiles/Highkey-1.pp3 +++ b/rtdata/profiles/Highkey-1.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=5 -Saturation=-10 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=-10 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Natural-1.pp3 b/rtdata/profiles/Natural-1.pp3 index e055627e2..94b353aff 100644 --- a/rtdata/profiles/Natural-1.pp3 +++ b/rtdata/profiles/Natural-1.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=0 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Natural-2.pp3 b/rtdata/profiles/Natural-2.pp3 index e9a9bed1a..3ef8a8984 100644 --- a/rtdata/profiles/Natural-2.pp3 +++ b/rtdata/profiles/Natural-2.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Neutral.pp3 b/rtdata/profiles/Neutral.pp3 index ab0a4e582..9b512ac42 100644 --- a/rtdata/profiles/Neutral.pp3 +++ b/rtdata/profiles/Neutral.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=0 -Saturation=0 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=0 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Punchy-1.pp3 b/rtdata/profiles/Punchy-1.pp3 index e6da63749..d98ef925d 100644 --- a/rtdata/profiles/Punchy-1.pp3 +++ b/rtdata/profiles/Punchy-1.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=-10;-10;120; [Luminance Curve] Brightness=0 Contrast=10 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=false Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtdata/profiles/Punchy-2.pp3 b/rtdata/profiles/Punchy-2.pp3 index c8352acaf..bffb76f12 100644 --- a/rtdata/profiles/Punchy-2.pp3 +++ b/rtdata/profiles/Punchy-2.pp3 @@ -1,7 +1,7 @@ [Version] AppVersion=4.0.9 -Version=302 +Version=303 [General] Rank=0 @@ -29,13 +29,15 @@ Blue=0;0;100; [Luminance Curve] Brightness=0 Contrast=10 -Saturation=5 -AvoidColorClipping=false -SaturationLimiter=false -SaturationLimit=50 +Chromaticity=5 +BWtoning=false +AvoidColorShift=true +RedAndSkinTonesProtection=0 LCurve=0; aCurve=0; bCurve=0; +ccCurve=0; +chCurve=0; [Sharpening] Enabled=false @@ -57,10 +59,11 @@ DeconvIterations=30 Enabled=true Pastels=50 Saturated=50 -PSThreshold=1;75; +PSThreshold=0;75; ProtectSkins=false AvoidColorShift=true PastSatTog=true +SkinTonesCurve=0; [SharpenEdge] Enabled=false diff --git a/rtengine/LUT.h b/rtengine/LUT.h index ad43ab471..9c497a7cc 100644 --- a/rtengine/LUT.h +++ b/rtengine/LUT.h @@ -66,6 +66,9 @@ #define LUTu LUT #include +#ifndef NDEBUG +#include +#endif template class LUT { @@ -165,6 +168,22 @@ public: T p2 = data[idx + 1]-p1; return (p1 + p2*diff); } +#ifndef NDEBUG + // Debug facility ; dump the content of the LUT in a file. No control of the filename is done + void dump(Glib::ustring fname) { + if (size) { + Glib::ustring fname_ = fname + ".xyz"; // TopSolid'Design "plot" file format + std::ofstream f (fname_.c_str()); + f << "$" << std::endl;; + for (unsigned int iter=0; iter + */ + // Munsell Lch LUTf : 195 LUT + // about 70% data are corrected with significative corrections + // almost all data are taken for BG, YR, G excepted a few extreme values with a slight correction + // No LUTf for BG and Y : low corrections + // Only between 5B and 5PB for L > 40 : under very low corrections for L < 40 + + //give hue in function of L and C : Munsell correction + LUTf Color::_4P10, Color::_4P20, Color::_4P30, Color::_4P40, Color::_4P50, Color::_4P60; + LUTf Color::_1P10, Color::_1P20, Color::_1P30, Color::_1P40, Color::_1P50, Color::_1P60; + LUTf Color::_10PB10, Color::_10PB20, Color::_10PB30, Color::_10PB40, Color::_10PB50, Color::_10PB60; + LUTf Color::_9PB10, Color::_9PB20, Color::_9PB30, Color::_9PB40, Color::_9PB50, Color::_9PB60, Color::_9PB70, Color::_9PB80; + LUTf Color::_75PB10, Color::_75PB20, Color::_75PB30, Color::_75PB40, Color::_75PB50, Color::_75PB60, Color::_75PB70, Color::_75PB80; + LUTf Color::_6PB10, Color::_6PB20, Color::_6PB30, Color::_6PB40, Color::_6PB50, Color::_6PB60, Color::_6PB70, Color::_6PB80; + LUTf Color::_45PB10, Color::_45PB20, Color::_45PB30, Color::_45PB40, Color::_45PB50, Color::_45PB60, Color::_45PB70, Color::_45PB80; + LUTf Color::_3PB10, Color::_3PB20, Color::_3PB30, Color::_3PB40, Color::_3PB50, Color::_3PB60, Color::_3PB70, Color::_3PB80; + LUTf Color::_15PB10, Color::_15PB20, Color::_15PB30, Color::_15PB40, Color::_15PB50, Color::_15PB60, Color::_15PB70, Color::_15PB80; + LUTf Color::_05PB40, Color::_05PB50, Color::_05PB60, Color::_05PB70, Color::_05PB80; + LUTf Color::_10B40, Color::_10B50, Color::_10B60, Color::_10B70, Color::_10B80; + LUTf Color::_9B40, Color::_9B50, Color::_9B60, Color::_9B70, Color::_9B80; + LUTf Color::_7B40, Color::_7B50, Color::_7B60, Color::_7B70, Color::_7B80; + LUTf Color::_5B40, Color::_5B50, Color::_5B60, Color::_5B70, Color::_5B80; + LUTf Color::_10YR20, Color::_10YR30, Color::_10YR40, Color::_10YR50, Color::_10YR60, Color::_10YR70, Color::_10YR80, Color::_10YR90; + LUTf Color::_85YR20, Color::_85YR30, Color::_85YR40, Color::_85YR50, Color::_85YR60, Color::_85YR70, Color::_85YR80, Color::_85YR90; + LUTf Color::_7YR30, Color::_7YR40, Color::_7YR50, Color::_7YR60, Color::_7YR70, Color::_7YR80; + LUTf Color::_55YR30, Color::_55YR40, Color::_55YR50, Color::_55YR60, Color::_55YR70, Color::_55YR80, Color::_55YR90; + LUTf Color::_4YR30, Color::_4YR40, Color::_4YR50, Color::_4YR60, Color::_4YR70, Color::_4YR80; + LUTf Color::_25YR30, Color::_25YR40, Color::_25YR50, Color::_25YR60, Color::_25YR70; + LUTf Color::_10R30, Color::_10R40, Color::_10R50, Color::_10R60, Color::_10R70; + LUTf Color::_9R30, Color::_9R40, Color::_9R50, Color::_9R60, Color::_9R70; + LUTf Color::_7R30, Color::_7R40, Color::_7R50, Color::_7R60, Color::_7R70; + LUTf Color::_5R10, Color::_5R20, Color::_5R30; + LUTf Color::_25R10, Color::_25R20, Color::_25R30; + LUTf Color::_10RP10, Color::_10RP20, Color::_10RP30; + LUTf Color::_7G30, Color::_7G40, Color::_7G50, Color::_7G60, Color::_7G70, Color::_7G80; + LUTf Color::_5G30, Color::_5G40, Color::_5G50, Color::_5G60, Color::_5G70, Color::_5G80; + LUTf Color::_25G30, Color::_25G40, Color::_25G50, Color::_25G60, Color::_25G70, Color::_25G80; + LUTf Color::_1G30, Color::_1G40, Color::_1G50, Color::_1G60, Color::_1G70, Color::_1G80; + LUTf Color::_10GY30, Color::_10GY40, Color::_10GY50, Color::_10GY60, Color::_10GY70, Color::_10GY80; + LUTf Color::_75GY30, Color::_75GY40, Color::_75GY50, Color::_75GY60, Color::_75GY70, Color::_75GY80; + LUTf Color::_5GY30, Color::_5GY40, Color::_5GY50, Color::_5GY60, Color::_5GY70, Color::_5GY80; + +#ifdef _DEBUG + MunsellDebugInfo::MunsellDebugInfo() { + reinitValues(); + } + void MunsellDebugInfo::reinitValues() { + maxdhue[0]=maxdhue[1]=maxdhue[2]=maxdhue[3]=0.0f; + maxdhuelum[0]=maxdhuelum[1]=maxdhuelum[2]=maxdhuelum[3]=0.0f; + depass=depassLum=0; + } +#endif + + void Color::init () { int maxindex = 65536; @@ -84,6 +144,7 @@ namespace rtengine { fprintf (f, "%g %g\n", i/255.0, clower (i/255.0, 2.0, 1.0)); fclose (f);*/ + initMunsell(); } void Color::cleanup () { @@ -330,25 +391,26 @@ namespace rtengine { return (f > epsilonExpInv3) ? f*f*f : (116 * f - 16) * kappaInv; } -/* Gamut mapping algorithm - copyright (c) 2010-2011 Emil Martinec - solutions to scaling u and v to XYZ paralleliped boundaries - some equations: - fu(X,Y,Z) = 4 X/(X + 15 Y + 3 Z); - fv(X,Y,Z) = 9 Y/(X + 15 Y + 3 Z); - - take the plane spanned by X=a*Xr+b*Xg+c*Xb etc with one of a,b,c equal to 0 or 1, - and itersect with the line u0+lam*u, or in other words solve - - u0+lam*u=fu(X,Y,Z) - v0+lam*v=fv(X,Y,Z) - - the value of lam is the scale factor that takes the color to the gamut boundary - - columns of the matrix p=xyz_rgb are RGB tristimulus primaries in XYZ - c is the color fixed on the boundary; and m=0 for c=0, m=1 for c=255 -*/ - + /* + * Gamut mapping algorithm + * Copyright (c) 2010-2011 Emil Martinec + * + * Solutions to scaling u and v to XYZ paralleliped boundaries + * Some equations: + * + * fu(X,Y,Z) = 4 X/(X + 15 Y + 3 Z); + * fv(X,Y,Z) = 9 Y/(X + 15 Y + 3 Z); + * + * take the plane spanned by X=a*Xr+b*Xg+c*Xb etc with one of a,b,c equal to 0 or 1, + * and itersect with the line u0+lam*u, or in other words solve + * + * u0+lam*u=fu(X,Y,Z) + * v0+lam*v=fv(X,Y,Z) + * + * The value of lam is the scale factor that takes the color to the gamut boundary + * columns of the matrix p=xyz_rgb are RGB tristimulus primaries in XYZ + * c is the color fixed on the boundary; and m=0 for c=0, m=1 for c=255 + */ void Color::gamutmap(float &X, float &Y, float &Z, const double p[3][3]) { float u = 4*X/(X+15*Y+3*Z)-u0; @@ -383,4 +445,2023 @@ namespace rtengine { X = (9*u*Y)/(4*v); Z = (12 - 3*u - 20*v)*Y/(4*v); } + + /* + * AllMunsellLch correction + * Copyright (c) 2012 Jacques Desmis + * + * This function corrects the color (hue) for changes in chromaticity and luminance + * to use in a "for" or "do while" statement + * + * Parameters: + * bool lumaMuns : true => luminance correction (for delta L > 10) and chroma correction ; false : only chroma + * float Lprov1 , Loldd : luminance after and before + * float HH: hue before + * float Chprov1, CC : chroma after and before + * float coorectionHuechroma : correction Hue for chromaticity (saturation) + * float correctlum : correction Hue for luminance (brigtness, contrast,...) + * MunsellDebugInfo* munsDbgInfo: (Debug target only) object to collect information. + */ +#ifdef _DEBUG + void Color::AllMunsellLch(bool lumaMuns, float Lprov1,float Loldd,float HH,float Chprov1,float CC,float &correctionHuechroma,float &correctlum, MunsellDebugInfo* munsDbgInfo) +#else + void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHuechroma, float &correctlum) +#endif + { + + bool contin1,contin2; + float correctionHue=0.0,correctionHueLum=0.0; + float correctlumprov=0.0; + float correctlumprov2=0.0; + bool correctL=false; + float huelimit[8]={-2.48,-0.55,0.44,1.52,1.87,3.09,-0.27,0.44};//limits hue of blue-purple, red-yellow, green-yellow, red-purple + if(CC >= 6.0 && CC < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) + if (Chprov1 > 140) Chprov1=139; //limits of LUTf + if (Chprov1 < 6) Chprov1=6; + for(int zo=1;zo<=4;zo++) { + if(HH>huelimit[2*zo-2] && HHmaxdhue[idx] = MAX(munsDbgInfo->maxdhue[idx], absCorrectionHue); +} + } + if(absCorrectionHue > 0.45) +#pragma omp atomic + munsDbgInfo->depass++; //verify if no bug in calculation +#endif + correctionHuechroma=correctionHue; //preserve + if(lumaMuns) { + if(correctL) { + //for Munsell luminance correction + correctlumprov=correctionHueLum; + contin1=true; + correctL=false; + } + correctionHueLum=0.0; + correctionHue=0.0; + if(fabs(Lprov1-Loldd) > 6.0) { + // correction if delta L significative..Munsell luminance + MunsellLch (Loldd, HH,Chprov1, Chprov1, correctionHue, zo, correctionHueLum, correctL); + + if(correctL) { + correctlumprov2=correctionHueLum; + contin2=true; + correctL=false; + } + correctionHueLum=0.0; + + if(contin1==true && contin2==true) + correctlum=correctlumprov2-correctlumprov; +#ifdef _DEBUG + float absCorrectLum = fabs(correctlum); + if(correctlum !=0.0) { + int idx=zo-1; +#pragma omp critical (maxdhuelum) +{ + munsDbgInfo->maxdhuelum[idx] = MAX(munsDbgInfo->maxdhuelum[idx],absCorrectLum); +} + } + if(absCorrectLum > 0.35) +#pragma omp atomic + munsDbgInfo->depassLum++; //verify if no bug in calculation +#endif + } + } + } + } + + } + +#ifdef _DEBUG + if (correctlum < -0.35f) correctlum =-0.35f; + else if(correctlum > 0.35f) correctlum = 0.35f; + if (correctionHuechroma<-0.45f) correctionHuechroma=-0.45f; + else if(correctionHuechroma> 0.45f) correctionHuechroma= 0.45f; +#endif + + } + + /* + * GamutLchonly correction + * Copyright (c)2012 Jacques Desmis and Jean-Christophe Frisch + * + * This function puts the data (Lab) in the gamut of "working profile": + * it returns the corrected values of the chromaticity and luminance + * + * float HH : hue + * float Lprov1 : input luminance value, sent back corrected + * float Chprov1: input chroma value, sent back corrected + * float R,G,B : red, green and blue value of the corrected color + * double wip : working profile + * bool isHLEnabled : if "highlight reconstruction " is enabled + * float coef : a float number between [0.95 ; 1.0[... the nearest it is from 1.0, the more precise it will be... and the longer too as more iteration will be necessary) + * bool neg and moreRGB : only in DEBUG mode to calculate iterations for negatives values and > 65535 + */ +#ifdef _DEBUG + void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +#else + void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +#endif + { + + bool inGamut; +#ifdef _DEBUG + neg=false, more_rgb=false; +#endif + do { + inGamut=true; + + //Lprov1=LL; + float aprov1=Chprov1*cos(HH); + float bprov1=Chprov1*sin(HH); + + //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction + float fy = (0.00862069f *Lprov1 )+ 0.137932f; + float fx = (0.002f * aprov1) + fy; + float fz = fy - (0.005f * bprov1); + + float x_ = 65535.0f * f2xyz(fx)*D50x; + float y_ = 65535.0f * f2xyz(fy); + float z_ = 65535.0f * f2xyz(fz)*D50z; + xyz2rgb(x_,y_,z_,R,G,B,wip); + + // gamut control before saturation to put Lab values in future gamut, but not RGB + if (R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + neg=true; +#endif + if (Lprov1 < 0.01f) + Lprov1 = 0.05f; + Chprov1 *= higherCoef; // decrease the chromaticity value + if (Chprov1 <= 3.0f) + Lprov1 += lowerCoef; + inGamut = false; + } + // if "highlight reconstruction" is enabled, don't control Gamut + else if ((!isHLEnabled) && (R>65534.5f || G>65534.5f || B>65534.5f)) { +#ifdef _DEBUG + more_rgb=true; +#endif + if (Lprov1 > 99.99f) + Lprov1 = 99.8f; + Chprov1 *= higherCoef; + if (Chprov1 <= 3.0f) + Lprov1 -= lowerCoef; + inGamut = false; + } + } + while (!inGamut); + //end first gamut control + } + + + /* + * LabGamutMunsell + * Copyright (c) 2012 Jacques Desmis + * + * This function is the overall Munsell's corrections, but only on global statement: I think it's better to use local statement with AllMunsellLch + * not for use in a "for" or "do while" loop + * they are named accordingly : gamutLchonly and AllMunsellLch + * it can be used before and after treatment (saturation, gamma, luminance, ...) + * + * Parameters: + * Labimage *lab : RT Lab data + * float *Lold : luminance before - data: i*width + j + * float *Cold : chrominance before - data: i*width + j + * bool corMuns : performs Munsell correction + * bool lumaMuns : (used only if corMuns=true) + * true: apply luma + chroma Munsell correction if delta L > 10; + * false: only chroma correction only + * bool gamut : performs gamutLch + * Glib::ustring &working: working profile's name + * bool multiThread : parallelize the loop + */ + void Color::LabGamutMunsell(LabImage *lab, float *Lold, float *Cold, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const Glib::ustring &working, bool multiThread ) { +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + int negat=0, moreRGB=0; + MunsellDebugInfo* MunsDebugInfo=NULL; + if (corMunsell) + MunsDebugInfo = new MunsellDebugInfo(); + + #pragma omp parallel default(shared) firstprivate(MunsDebugInfo) reduction(+: negat, moreRGB) if (multiThread) +#else + #pragma omp parallel default(shared) if (multiThread) +#endif + { + + //unsigned int N = lab->W*lab->H; + int width = lab->W, height = lab->H; + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (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]} + }; + float correctlum=0.0; + float correctionHuechroma=0.0; + + #pragma omp for schedule(dynamic, 10) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f)); + float HH=atan2(lab->b[i][j],lab->a[i][j]); + float Chprov1=CC; + float Lprov1=LL; + float Loldd, Coldd; + if(gamut) { + bool neg, more_rgb; + float R, G, B; + + //gamut control : Lab values are in gamut +#ifdef _DEBUG + gamutLchonly(HH, Lprov1, Chprov1, R, G, B, wip, isHLEnabled, 0.4f, 0.95f, neg, more_rgb); +#else + gamutLchonly(HH, Lprov1, Chprov1, R, G, B, wip, isHLEnabled, 0.4f, 0.95f); +#endif + +#ifdef _DEBUG + if(neg) negat++; + if(more_rgb) moreRGB++; +#endif + } + + Loldd = Lold[i*width + j]; + Coldd = Cold[i*width + j]; + lab->L[i][j] = Lprov1*327.68f; + correctionHuechroma = 0.0; + correctlum = 0.0; + + if(corMunsell) +#ifdef _DEBUG + AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum, MunsDebugInfo); +#else + AllMunsellLch(lumaMuns, Lprov1, Loldd, HH, Chprov1, Coldd, correctionHuechroma, correctlum); +#endif + + HH+=correctlum; //hue Munsell luminance correction + + correctlum = 0.0f; + lab->a[i][j] = Chprov1*cos(HH+correctionHuechroma)*327.68f; + lab->b[i][j] = Chprov1*sin(HH+correctionHuechroma)*327.68f; + + } + } // end of parallelization + +#ifdef _DEBUG + t2e.set(); + if (settings->verbose) { + printf("Color::LabGamutMunsell (correction performed in %d usec):\n", t2e.etime(t1e)); + printf(" Gamut : G1negat=%iiter G165535=%iiter \n",negat,moreRGB); + if (MunsDebugInfo) { + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); + printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhuelum[0] ,MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); + } + else { + printf(" Munsell correction wasn't requested\n"); + } + } + if (MunsDebugInfo) + delete MunsDebugInfo; +#endif + + } + + /* + * MunsellLch correction + * Copyright (c) 2012 Jacques Desmis + * + * Find the right LUT and calculate the correction + */ + void Color::MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL) { + + int x = int(memChprov); + int y = int(chrom); + + //begin PB correction + sky + if(zone==1) { + if(lum > 5.0) { + if(lum <15.0) { + if( (hue >= (_15PB10[x] - 0.035)) && (hue < (_15PB10[x] + 0.052) && x<=45)) {if(y>49) y=49;correction = _15PB10[y] - _15PB10[x] ;lbe=_15PB10[y];correctL=true;} + else if (( hue>=( _3PB10[x] -0.052)) && (hue < (_45PB10[x] + _3PB10[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB10[y] - _3PB10[x]; lbe =_3PB10[y];correctL=true;} + else if (( hue>=(_45PB10[x] + _3PB10[x])/2.0) && (hue < (_45PB10[x] +0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB10[y] - _45PB10[x] ;lbe=_45PB10[y];correctL=true;} + else if (( hue>=(_6PB10[x] -0.052) && (hue < (_6PB10[x] + _75PB10[x])/2.0))) {correction = _6PB10[y] - _6PB10[x] ;lbe=_6PB10[y];correctL=true;} + else if (( hue>=(_6PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _75PB10[x])/2.0)) {correction = _75PB10[y] - _75PB10[x] ;lbe=_75PB10[y];correctL=true;} + else if (( hue>=(_9PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _10PB10[x])/2.0)) {correction = _9PB10[y] - _9PB10[x] ; lbe=_9PB10[y];correctL=true;} + else if (( hue>=(_10PB10[x] + _9PB10[x])/2.0) && (hue < (_1P10[x] + _10PB10[x])/2.0)) {correction = _10PB10[y] - _10PB10[x] ;lbe=_10PB10[y];correctL=true;} + else if (( hue>=(_10PB10[x] + _1P10[x])/2.0) && (hue < (_1P10[x] + _4P10[x])/2.0)) {correction = _1P10[y] - _1P10[x];lbe=_1P10[y];correctL=true;} + else if (( hue>=(_1P10[x] + _4P10[x])/2.0) && (hue < (0.035 + _4P10[x])/2.0)) {correction = _4P10[y] - _4P10[x] ;lbe=_4P10[y];correctL=true;} + } + else if (lum <25.0) { + if( (hue >= (_15PB20[x] - 0.035)) && (hue < (_15PB20[x] + _3PB20[x])/2.0) && x<=85) {if(y>89) y=89;correction = _15PB20[y] - _15PB20[x] ;lbe= _15PB20[y];correctL=true;} + else if (( hue>=(_15PB20[x] + _3PB20[x])/2.0) && (hue < (_45PB20[x] + _3PB20[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB20[y] - _3PB20[x] ;lbe= _3PB20[y];correctL=true;} + else if (( hue>=(_45PB20[x] + _3PB20[x])/2.0) && (hue < ( _45PB20[x] + 0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB20[y] - _45PB20[x] ;lbe=_45PB20[y];correctL=true;} + else if (( hue>=(_45PB20[x] + 0.052)) && (hue < (_6PB20[x] + _75PB20[x])/2.0)) {correction = _6PB20[y] - _6PB20[x];lbe=_6PB20[y];correctL=true;} + else if (( hue>=(_6PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _75PB20[x])/2.0)) {correction = _75PB20[y] - _75PB20[x] ;lbe=_75PB20[y];correctL=true;} + else if (( hue>=(_9PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _10PB20[x])/2.0)) {correction = _9PB20[y] - _9PB20[x] ;lbe= _9PB20[y];correctL=true; } + else if (( hue>=(_10PB20[x] + _9PB20[x])/2.0) && (hue < (_1P20[x] + _10PB20[x])/2.0)) {correction = _10PB20[y] - _10PB20[x] ;lbe= _10PB20[y];correctL=true;} + else if (( hue>=(_10PB20[x] + _1P20[x])/2.0) && (hue < (_1P20[x] + _4P20[x])/2.0)) {correction = _1P20[y] - _1P20[x] ; lbe=_1P20[y];correctL=true;} + else if (( hue>=(_1P20[x] + _4P20[x])/2.0) && (hue < (0.035 + _4P20[x])/2.0)) {correction = _4P20[y] - _4P20[x] ; lbe=_4P20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue >= (_15PB30[x] - 0.035)) && (hue < (_15PB30[x] + _3PB30[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB30[y] - _15PB30[x] ;lbe=_15PB30[y];correctL=true;} + else if (( hue>=(_15PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x] + _3PB30[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB30[y] - _3PB30[x] ;lbe=_3PB30[y];correctL=true;} + else if (( hue>=(_45PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB30[y] - _45PB30[x] ;lbe= _45PB30[y];correctL=true;} + else if (( hue>=( _45PB30[x]+ 0.052)) && (hue < (_6PB30[x] + _75PB30[x])/2.0)) {correction = _6PB30[y] - _6PB30[x] ; lbe=_6PB30[y];correctL=true;} + else if (( hue>=(_6PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _75PB30[x])/2.0)) {correction = _75PB30[y] - _75PB30[x] ;lbe= _75PB30[y] ;correctL=true;} + else if (( hue>=(_9PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _10PB30[x])/2.0)) {correction = _9PB30[y] - _9PB30[x] ;lbe=_9PB30[y]; correctL=true;} + else if (( hue>=(_10PB30[x] + _9PB30[x])/2.0) && (hue < (_1P30[x] + _10PB30[x])/2.0)) {correction = _10PB30[y] - _10PB30[x] ;lbe=_10PB30[y];correctL=true;} + else if (( hue>=(_10PB30[x] + _1P30[x])/2.0) && (hue < (_1P30[x] + _4P30[x])/2.0)) {correction = _1P30[y] - _1P30[x] ;lbe=_1P30[y];correctL=true; } + else if (( hue>=(_1P30[x] + _4P30[x])/2.0) && (hue < (0.035 + _4P30[x])/2.0)) {correction = _4P30[y] - _4P30[x] ;lbe=_4P30[y];correctL=true;} + } + else if (lum <45.0) { + if( (hue <= (_05PB40[x] + _15PB40[x])/2.0) && (hue > (_05PB40[x] + _10B40[x])/2.0) && x<75 ) {if(y>75) y=75; correction = _05PB40[y] - _05PB40[x] ;lbe=_05PB40[y];correctL=true;} + else if( (hue <= (_05PB40[x] + _10B40[x])/2.0) && (hue >(_10B40[x] + _9B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _10B40[y] - _10B40[x] ;lbe=_10B40[y];correctL=true;} + else if( (hue <= (_10B40[x] + _9B40[x])/2.0) && (hue >(_9B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _9B40[y] - _9B40[x] ;lbe=_9B40[y];correctL=true;} + else if( (hue <= (_9B40[x] + _7B40[x])/2.0) && (hue >(_5B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _7B40[y] - _7B40[x] ;lbe= _7B40[y];correctL=true;} + else if (( hue<=(_5B40[x] + _7B40[x])/2.0) && (hue > (_5B40[x]-0.035)) && x < 70) {if(y>70) y=70; correction = _5B40[y] - _5B40[x] ;lbe= _5B40[y];correctL=true;} // + + else if( (hue >= (_15PB40[x] - 0.035)) && (hue < (_15PB40[x] + _3PB40[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB40[y] - _15PB40[x] ; lbe= _15PB40[y];correctL=true;} + else if (( hue>=(_15PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x] + _3PB40[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB40[y] - _3PB40[x] ;lbe=_3PB40[y];correctL=true;} + else if (( hue>=(_45PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB40[y] - _45PB40[x] ;lbe=_45PB40[y] ;correctL=true;} + else if (( hue>=(_45PB40[x]+0.052)) && (hue < (_6PB40[x] + _75PB40[x])/2.0)) {correction = _6PB40[y] - _6PB40[x] ;lbe=_6PB40[y];correctL=true; } + else if (( hue>=(_6PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _75PB40[x])/2.0)) {correction = _75PB40[y] - _75PB40[x] ; lbe=_75PB40[y];correctL=true;} + else if (( hue>=(_9PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _10PB40[x])/2.0)) {correction = _9PB40[y] - _9PB40[x] ;lbe= _9PB40[y]; correctL=true;} + else if (( hue>=(_10PB40[x] + _9PB40[x])/2.0) && (hue < (_1P40[x] + _10PB40[x])/2.0)) {correction = _10PB40[y] - _10PB40[x] ;lbe=_10PB40[y];correctL=true;} + else if (( hue>=(_10PB40[x] + _1P40[x])/2.0) && (hue < (_1P40[x] + _4P40[x])/2.0)) {correction = _1P40[y] - _1P40[x] ;lbe=_1P40[y];correctL=true;} + else if (( hue>=(_1P40[x] + _4P40[x])/2.0) && (hue < (0.035 + _4P40[x])/2.0)) {correction = _4P40[y] - _4P40[x] ;lbe= _4P40[y];correctL=true;} + } + else if (lum <55.0) { + if( (hue <= (_05PB50[x] + _15PB50[x])/2.0) && (hue > (_05PB50[x] + _10B50[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB50[y] - _05PB50[x] ;lbe= _05PB50[y];correctL=true;} + else if( (hue <= (_05PB50[x] + _10B50[x])/2.0) && (hue >(_10B50[x] + _9B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B50[y] - _10B50[x] ;lbe=_10B50[y];correctL=true;} + else if( (hue <= (_10B50[x] + _9B50[x])/2.0) && (hue >(_9B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B50[y] - _9B50[x] ;lbe=_9B50[y];correctL=true;} + else if( (hue <= (_9B50[x] + _7B50[x])/2.0) && (hue >(_5B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B50[y] - _7B50[x] ;lbe=_7B50[y];correctL=true;} + else if (( hue<=(_5B50[x] + _7B50[x])/2.0) && (hue > (_5B50[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B50[y] - _5B50[x] ;lbe=_5B50[y];correctL=true; } // + + else if( (hue >= (_15PB50[x] - 0.035)) && (hue < (_15PB50[x] + _3PB50[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB50[y] - _15PB50[x] ; lbe= _15PB50[y];correctL=true;} + else if (( hue>=(_15PB50[x] + _3PB50[x])/2.0) && (hue < (_45PB50[x] + _3PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB50[y] - _3PB50[x] ;lbe=_3PB50[y];correctL=true;} + else if (( hue>=(_45PB50[x] + _3PB50[x])/2.0) && (hue < (_6PB50[x] + _45PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB50[y] - _45PB50[x] ;lbe=_45PB50[y];correctL=true; } + else if (( hue>=(_6PB50[x] + _45PB50[x])/2.0) && (hue < (_6PB50[x] + _75PB50[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB50[y] - _6PB50[x] ;lbe=_6PB50[y];correctL=true;} + else if (( hue>=(_6PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _75PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB50[y] - _75PB50[x] ;lbe=_75PB50[y];correctL=true;} + else if (( hue>=(_9PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB50[y] - _9PB50[x] ;lbe=_9PB50[y];correctL=true;} + else if (( hue>=(_10PB50[x] + _9PB50[x])/2.0) && (hue < (_1P50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB50[y] - _10PB50[x] ;lbe=_10PB50[y];correctL=true;} + else if (( hue>=(_10PB50[x] + _1P50[x])/2.0) && (hue < (_1P50[x] + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P50[y] - _1P50[x] ;lbe=_1P50[y];correctL=true; } + else if (( hue>=(_1P50[x] + _4P50[x])/2.0) && (hue < (0.035 + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P50[y] - _4P50[x] ;lbe=_4P50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_05PB60[x] + _15PB60[x])/2.0) && (hue > (_05PB60[x] + _10B60[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB60[y] - _05PB60[x] ;lbe=_05PB60[y];correctL=true;} + else if( (hue <= (_05PB60[x] + _10B60[x])/2.0) && (hue >(_10B60[x] + _9B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B60[y] - _10B60[x] ;lbe= _10B60[y];correctL=true;} + else if( (hue <= (_10B60[x] + _9B60[x])/2.0) && (hue >(_9B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B60[y] - _9B60[x] ;lbe=_9B60[y];correctL=true;} + else if( (hue <= (_9B60[x] + _7B60[x])/2.0) && (hue >(_5B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B60[y] - _7B60[x] ;lbe= _7B60[y];correctL=true;} + else if (( hue<=(_5B60[x] + _7B60[x])/2.0) && (hue > (_5B60[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B60[y] - _5B60[x] ;lbe= _5B60[y];correctL=true;} // + + else if( (hue >= (_15PB60[x] - 0.035)) && (hue < (_15PB60[x] + _3PB60[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB60[y] - _15PB60[x] ;lbe=_15PB60[y];correctL=true; } + else if (( hue>=(_15PB60[x] + _3PB60[x])/2.0) && (hue < (_45PB60[x] + _3PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB60[y] - _3PB60[x] ;lbe=_3PB60[y];correctL=true;} + else if (( hue>=(_45PB60[x] + _3PB60[x])/2.0) && (hue < (_6PB60[x] + _45PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB60[y] - _45PB60[x] ;lbe=_45PB60[y];correctL=true;} + else if (( hue>=(_6PB60[x] + _45PB60[x])/2.0) && (hue < (_6PB60[x] + _75PB60[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB60[y] - _6PB60[x] ;lbe= _6PB60[y];correctL=true;} + else if (( hue>=(_6PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _75PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB60[y] - _75PB60[x] ;lbe= _75PB60[y];correctL=true;} + else if (( hue>=(_9PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB60[y] - _9PB60[x] ;lbe= _9PB60[y];correctL=true;} + else if (( hue>=(_10PB60[x] + _9PB60[x])/2.0) && (hue < (_1P60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB60[y] - _10PB60[x] ;lbe=_10PB60[y]; correctL=true;} + else if (( hue>=(_10PB60[x] + _1P60[x])/2.0) && (hue < (_1P60[x] + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P60[y] - _1P60[x] ; lbe= _1P60[y];correctL=true;} + else if (( hue>=(_1P60[x] + _4P60[x])/2.0) && (hue < (0.035 + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P60[y] - _4P60[x] ;lbe=_4P60[y];correctL=true; } + } + else if (lum < 75.0) { + if( (hue <= (_05PB70[x] + _15PB70[x])/2.0) && (hue > (_05PB70[x] + _10B70[x])/2.0) && x<50 ) {if(y>49) y=49; correction = _05PB70[y] - _05PB70[x] ;lbe=_05PB70[y];correctL=true;} + else if( (hue <= (_05PB70[x] + _10B70[x])/2.0) && (hue >(_10B70[x] + _9B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _10B70[y] - _10B70[x] ;lbe=_10B70[y];correctL=true;} + else if( (hue <= (_10B70[x] + _9B70[x])/2.0) && (hue >(_9B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _9B70[y] - _9B70[x] ;lbe= _9B70[y];correctL=true;} + else if( (hue <= (_9B70[x] + _7B70[x])/2.0) && (hue >(_5B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B70[y] - _7B70[x] ;lbe=_7B70[y];correctL=true;} + else if (( hue<=(_5B70[x] + _7B70[x])/2.0) && (hue > (_5B70[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B70[y] - _5B70[x] ;lbe= _5B70[y];correctL=true;} // + + else if( (hue >= (_15PB70[x] - 0.035)) && (hue < (_15PB70[x] + _3PB70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB70[y] - _15PB70[x] ;lbe=_15PB70[y];correctL=true; } + else if (( hue>=(_45PB70[x] + _3PB70[x])/2.0) && (hue < (_6PB70[x] + _45PB70[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB70[y] - _45PB70[x] ;lbe=_45PB70[y];correctL=true;} + else if (( hue>=(_6PB70[x] + _45PB70[x])/2.0) && (hue < (_6PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB70[y] - _6PB70[x] ;lbe=_6PB70[y];correctL=true;} + else if (( hue>=(_6PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB70[y] - _75PB70[x] ;lbe=_75PB70[y];correctL=true; } + else if (( hue>=(_9PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB70[y] - _9PB70[x] ;lbe=_9PB70[y];correctL=true;} + } + else if (lum < 85.0) { + if( (hue <= (_05PB80[x] + _15PB80[x])/2.0) && (hue > (_05PB80[x] + _10B80[x])/2.0) && x<40 ) {if(y>39) y=39; correction = _05PB80[y] - _05PB80[x] ;lbe=_05PB80[y] ;correctL=true;} + else if( (hue <= (_05PB80[x] + _10B80[x])/2.0) && (hue >(_10B80[x] + _9B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _10B80[y] - _10B80[x] ;lbe=_10B80[y];correctL=true;} + else if( (hue <= (_10B80[x] + _9B80[x])/2.0) && (hue >(_9B80[x] + _7B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _9B80[y] - _9B80[x] ;lbe= _9B80[y];correctL=true;} + else if( (hue <= (_9B80[x] + _7B80[x])/2.0) && (hue >(_5B80[x] + _7B80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B80[y] - _7B80[x] ;lbe=_7B80[y];correctL=true;} + else if (( hue<=(_5B80[x] + _7B80[x])/2.0) && (hue > (_5B80[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B80[y] - _5B80[x] ; lbe=_5B80[y];correctL=true;} // + + else if( (hue >= (_15PB80[x] - 0.035)) && (hue < (_15PB80[x] + _3PB80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB80[y] - _15PB80[x] ; lbe=_15PB80[y];correctL=true;} + else if (( hue>=(_45PB80[x] + _3PB80[x])/2.0) && (hue < (_6PB80[x] + _45PB80[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB80[y] - _45PB80[x] ;lbe= _45PB80[y];correctL=true;} + else if (( hue>=(_6PB80[x] + _45PB80[x])/2.0) && (hue < (_6PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB80[y] - _6PB80[x] ;lbe=_6PB80[y];correctL=true;} + else if (( hue>=(_6PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB80[y] - _75PB80[x] ;lbe=_75PB80[y];correctL=true; } + else if (( hue>=(_9PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB80[y] - _9PB80[x] ;lbe=_9PB80[y]; correctL=true;} + } + } + } + // end PB correction + + //red yellow correction + else if(zone==2) { + if(lum > 15.0) { + if(lum < 25.0) { + if( (hue <= (_10YR20[x] + 0.035)) && (hue > (_10YR20[x] + _85YR20[x])/2.0) && x<=45) {if(y>49) y=49;correction = _10YR20[y] - _10YR20[x] ;lbe=_10YR20[y];correctL=true;} + else if (( hue<=(_85YR20[x] + _10YR20[x])/2.0) && (hue > (_85YR20[x] + 0.035) && x <= 45)) {if(y>49) y=49;correction = _85YR20[y] - _85YR20[x] ;lbe= _85YR20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue <= (_10YR30[x] + 0.035)) && (hue > (_10YR30[x] + _85YR30[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10YR30[y] - _10YR30[x] ;lbe=_10YR30[y];correctL=true;} + else if( (hue <= (_10YR30[x] + _85YR30[x])/2.0) && (hue >(_85YR30[x] + _7YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _85YR30[y] - _85YR30[x] ;lbe= _85YR30[y];correctL=true;} + else if (( hue<=(_85YR30[x] + _7YR30[x])/2.0) && (hue > (_7YR30[x] + _55YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR30[y] - _7YR30[x] ;lbe=_7YR30[y];correctL=true;} + else if (( hue<=(_7YR30[x] + _55YR30[x])/2.0) && (hue > (_55YR30[x] + _4YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR30[y] - _55YR30[x] ;lbe=_55YR30[y];correctL=true; } + else if (( hue<=(_55YR30[x] + _4YR30[x])/2.0) && (hue > (_4YR30[x] + _25YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR30[y] - _4YR30[x] ;lbe= _4YR30[y];correctL=true;} + else if (( hue<=(_4YR30[x] + _25YR30[x])/2.0) && (hue > (_25YR30[x] + _10R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR30[y] - _25YR30[x] ;lbe=_25YR30[y];correctL=true;} + else if (( hue<=(_25YR30[x] + _10R30[x])/2.0) && (hue > (_10R30[x] + _9R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R30[y] - _10R30[x] ; lbe=_10R30[y];correctL=true;} + else if (( hue<=(_10R30[x] + _9R30[x])/2.0) && (hue > (_9R30[x] + _7R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R30[y] - _9R30[x] ;lbe=_9R30[y];correctL=true;} + else if (( hue<=(_9R30[x] + _7R30[x])/2.0) && (hue > (_7R30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R30[y] - _7R30[x] ; lbe=_7R30[y] ;correctL=true;} + } + else if (lum <45.0) { + if( (hue <= (_10YR40[x] + 0.035)) && (hue > (_10YR40[x] + _85YR40[x])/2.0)&& x<85) {if(y>89) y=89;correction = _10YR40[y] - _10YR40[x] ;lbe=_10YR40[y];correctL=true;} + else if( (hue <= (_10YR40[x] + _85YR40[x])/2.0) && (hue >(_85YR40[x] + _7YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR40[y] - _85YR40[x] ;lbe= _85YR40[y];correctL=true;} + else if (( hue<=(_85YR40[x] + _7YR40[x])/2.0) && (hue > (_7YR40[x] + _55YR40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _7YR40[y] - _7YR40[x] ;lbe= _7YR40[y];correctL=true;} + else if (( hue<=(_7YR40[x] + _55YR40[x])/2.0) && (hue > (_55YR40[x] + _4YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _55YR40[y] - _55YR40[x] ;lbe=_55YR40[y];correctL=true; } + else if (( hue<=(_55YR40[x] + _4YR40[x])/2.0) && (hue > (_4YR40[x] + _25YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _4YR40[y] - _4YR40[x] ;lbe=_4YR40[y]; correctL=true;} + else if (( hue<=(_4YR40[x] + _25YR40[x])/2.0) && (hue > (_25YR40[x] + _10R40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR40[y] - _25YR40[x] ;lbe=_25YR40[y] ;correctL=true;} + else if (( hue<=(_25YR40[x] + _10R40[x])/2.0) && (hue > (_10R40[x] + _9R40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10R40[y] - _10R40[x] ; lbe=_10R40[y];correctL=true;} + else if (( hue<=(_10R40[x] + _9R40[x])/2.0) && (hue > (_9R40[x] + _7R40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _9R40[y] - _9R40[x] ;lbe=_9R40[y];correctL=true;} + else if (( hue<=(_9R40[x] + _7R40[x])/2.0) && (hue > (_7R40[x] -0.035))&& x < 85 ) {if(y>89) y=89;correction = _7R40[y] - _7R40[x] ; lbe=_7R40[y];correctL=true;} + } + else if (lum <55.0) { + if( (hue <= (_10YR50[x] + 0.035)) && (hue > (_10YR50[x] + _85YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10YR50[y] - _10YR50[x] ;lbe=_10YR50[y];correctL=true;} + else if( (hue <= (_10YR50[x] + _85YR50[x])/2.0) && (hue >(_85YR50[x] + _7YR50[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR50[y] - _85YR50[x] ;lbe=_85YR50[y];correctL=true;} + else if (( hue<=(_85YR50[x] + _7YR50[x])/2.0) && (hue > (_7YR50[x] + _55YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR50[y] - _7YR50[x] ;lbe=_7YR50[y];correctL=true;} + else if (( hue<=(_7YR50[x] + _55YR50[x])/2.0) && (hue > (_55YR50[x] + _4YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR50[y] - _55YR50[x] ; lbe=_55YR50[y];correctL=true;} + else if (( hue<=(_55YR50[x] + _4YR50[x])/2.0) && (hue > (_4YR50[x] + _25YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR50[y] - _4YR50[x] ;lbe=_4YR50[y]; correctL=true;} + else if (( hue<=(_4YR50[x] + _25YR50[x])/2.0) && (hue > (_25YR50[x] + _10R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR50[y] - _25YR50[x] ;lbe=_25YR50[y];correctL=true;} + else if (( hue<=(_25YR50[x] + _10R50[x])/2.0) && (hue > (_10R50[x] + _9R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R50[y] - _10R50[x] ;lbe= _10R50[y]; correctL=true;} + else if (( hue<=(_10R50[x] + _9R50[x])/2.0) && (hue > (_9R50[x] + _7R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R50[y] - _9R50[x] ;lbe=_9R50[y];correctL=true;} + else if (( hue<=(_9R50[x] + _7R50[x])/2.0) && (hue > (_7R50[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R50[y] - _7R50[x] ; lbe=_7R50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_10YR60[x] + 0.035)) && (hue > (_10YR60[x] + _85YR60[x])/2.0)) {;correction = _10YR60[y] - _10YR60[x] ;lbe= _10YR60[y];correctL=true;} + else if( (hue <= (_10YR60[x] + _85YR60[x])/2.0) && (hue >(_85YR60[x] + _7YR60[x])/2.0) ) {;correction = _85YR60[y] - _85YR60[x] ;lbe= _85YR60[y];correctL=true;} + else if (( hue<=(_85YR60[x] + _7YR60[x])/2.0) && (hue > (_7YR60[x] + _55YR60[x])/2.0)) {correction = _7YR60[y] - _7YR60[x] ;lbe=_7YR60[y];correctL=true;} + else if (( hue<=(_7YR60[x] + _55YR60[x])/2.0) && (hue > (_55YR60[x] + _4YR60[x])/2.0)) {correction = _55YR60[y] - _55YR60[x] ;lbe= _55YR60[y];correctL=true;} + else if (( hue<=(_55YR60[x] + _4YR60[x])/2.0) && (hue > (_4YR60[x] + _25YR60[x])/2.0)) {correction = _4YR60[y] - _4YR60[x] ;lbe=_4YR60[y]; correctL=true;} + else if (( hue<=(_4YR60[x] + _25YR60[x])/2.0) && (hue > (_25YR60[x] + _10R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR60[y] - _25YR60[x] ;lbe=_25YR60[y];correctL=true;} + else if (( hue<=(_25YR60[x] + _10R60[x])/2.0) && (hue > (_10R60[x] + _9R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R60[y] - _10R60[x] ;lbe= _10R60[y];correctL=true; } + else if (( hue<=(_10R60[x] + _9R60[x])/2.0) && (hue > (_9R60[x] + _7R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R60[y] - _9R60[x] ;lbe=_9R60[y];correctL=true;} + else if (( hue<=(_9R60[x] + _7R60[x])/2.0) && (hue > (_7R60[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R60[y] - _7R60[x] ;lbe=_7R60[y]; correctL=true;} + } + else if (lum <75.0) { + if( (hue <= (_10YR70[x] + 0.035)) && (hue > (_10YR70[x] + _85YR70[x])/2.0)) {correction = _10YR70[y] - _10YR70[x] ;lbe= _10YR70[y];correctL=true;} + else if( (hue <= (_10YR70[x] + _85YR70[x])/2.0) && (hue >(_85YR70[x] + _7YR70[x])/2.0)) {correction = _85YR70[y] - _85YR70[x] ;lbe=_85YR70[y];correctL=true;} + if (( hue<=(_85YR70[x] + _7YR70[x])/2.0) && (hue > (_7YR70[x] + _55YR70[x])/2.0)) {correction = _7YR70[y] - _7YR70[x] ;lbe=_7YR70[y];correctL=true;} + else if (( hue<=(_7YR70[x] + _55YR70[x])/2.0) && (hue > (_55YR70[x] + _4YR70[x])/2.0)) {correction = _55YR70[y] - _55YR70[x] ;lbe=_55YR70[y];correctL=true; } + else if (( hue<=(_55YR70[x] + _4YR70[x])/2.0) && (hue > (_4YR70[x] + _25YR70[x])/2.0)) {correction = _4YR70[y] - _4YR70[x] ;lbe=_4YR70[y];correctL=true; } + else if (( hue<=(_4YR70[x] + _25YR70[x])/2.0) && (hue > (_25YR70[x] + _10R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR70[y] - _25YR70[x] ;lbe= _25YR70[y];correctL=true;} + else if (( hue<=(_25YR70[x] + _10R70[x])/2.0) && (hue > (_10R70[x] + _9R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R70[y] - _10R70[x] ;lbe= _10R70[y];correctL=true;} + else if (( hue<=(_10R70[x] + _9R70[x])/2.0) && (hue > (_9R70[x] + _7R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R70[y] - _9R70[x] ;lbe= _9R70[y] ;correctL=true;} + else if (( hue<=(_9R70[x] + _7R70[x])/2.0) && (hue > (_7R70[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R70[y] - _7R70[x] ;lbe=_7R70[y];correctL=true; } + } + else if (lum <85.0) { + if( (hue <= (_10YR80[x] + 0.035)) && (hue > (_10YR80[x] + _85YR80[x])/2.0)) {correction = _10YR80[y] - _10YR80[x] ;lbe=_10YR80[y];correctL=true;} + else if( (hue <= (_10YR80[x] + _85YR80[x])/2.0) && (hue >(_85YR80[x] + _7YR80[x])/2.0)) {correction = _85YR80[y] - _85YR80[x] ;lbe= _85YR80[y];} + else if (( hue<=(_85YR80[x] + _7YR80[x])/2.0) && (hue > (_7YR80[x] + _55YR80[x])/2.0) && x<85) {if(y>89) y=89;correction = _7YR80[y] - _7YR80[x] ;lbe=_7YR80[y];correctL=true;} + else if (( hue<=(_7YR80[x] + _55YR80[x])/2.0) && (hue > (_55YR80[x] + _4YR80[x])/2.0) && x <45) {correction = _55YR80[y] - _55YR80[x] ;lbe=_55YR80[y];correctL=true; } + else if (( hue<=(_55YR80[x] + _4YR80[x])/2.0) && (hue > (_4YR80[x] - 0.035) && x<45)) {if(y>49) y=49;correction = _4YR80[y] - _4YR80[x] ; lbe=_4YR80[y] ;correctL=true;} + } + else if (lum <95.0) { + if( (hue <= (_10YR90[x] + 0.035)) && (hue > (_10YR90[x] -0.035) && x<85)) {if(y>89) y=89;correction = _10YR90[y] - _10YR90[x] ;lbe= _10YR90[y];correctL=true;} + else if ( hue<=(_85YR90[x] + 0.035) && hue > (_85YR90[x] -0.035) && x<85) {if(y>89) y=89;correction = _85YR90[y] - _85YR90[x] ;lbe=_85YR90[y];correctL=true;} + else if (( hue<=(_55YR90[x] + 0.035) && (hue > (_55YR90[x] - 0.035) && x<45))) {if(y>49) y=49;correction = _55YR90[y] - _55YR90[x] ;lbe= _55YR90[y];correctL=true; } + } + } + } + //end red yellow + + //Green yellow correction + else if(zone==3) { + if (lum >= 25.0) { + if (lum <35.0) { + if( (hue <= (_7G30[x] + 0.035)) && (hue > (_7G30[x] + _5G30[x])/2.0) ) {correction = _7G30[y] - _7G30[x] ;lbe=_7G30[y];correctL=true;} + else if( (hue <= (_7G30[x] + _5G30[x])/2.0) && (hue >(_5G30[x] + _25G30[x])/2.0)) {correction = _5G30[y] - _5G30[x] ;lbe= _5G30[y];correctL=true;} + else if (( hue<=(_25G30[x] + _5G30[x])/2.0) && (hue > (_25G30[x] + _1G30[x])/2.0)) {correction = _25G30[y] - _25G30[x] ;lbe=_25G30[y];correctL=true;} + else if (( hue<=(_1G30[x] + _25G30[x])/2.0) && (hue > (_1G30[x] + _10GY30[x])/2.0)) {correction = _1G30[y] - _1G30[x] ;lbe= _1G30[y];correctL=true;} + else if (( hue<=(_1G30[x] + _10GY30[x])/2.0) && (hue > (_10GY30[x] + _75GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY30[y] - _10GY30[x] ;lbe= _10GY30[y];correctL=true;} + else if (( hue<=(_10GY30[x] + _75GY30[x])/2.0) && (hue > (_75GY30[x] + _5GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY30[y] - _75GY30[x] ;lbe=_75GY30[y];correctL=true;} + else if (( hue<=(_5GY30[x] + _75GY30[x])/2.0) && (hue > (_5GY30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _5GY30[y] - _5GY30[x] ;lbe= _5GY30[y] ;correctL=true; } + } + else if (lum <45.0) { + if( (hue <= (_7G40[x] + 0.035)) && (hue > (_7G40[x] + _5G40[x])/2.0) ) {correction = _7G40[y] - _7G40[x] ;lbe= _7G40[y];correctL=true;} + else if( (hue <= (_7G40[x] + _5G40[x])/2.0) && (hue >(_5G40[x] + _25G40[x])/2.0)) {correction = _5G40[y] - _5G40[x] ;lbe=_5G40[y];correctL=true;} + else if (( hue<=(_25G40[x] + _5G40[x])/2.0) && (hue > (_25G40[x] + _1G40[x])/2.0)) {correction = _25G40[y] - _25G40[x] ;lbe=_25G40[y];correctL=true;} + else if (( hue<=(_1G40[x] + _25G40[x])/2.0) && (hue > (_1G40[x] + _10GY40[x])/2.0)) {correction = _1G40[y] - _1G40[x] ;lbe=_1G40[y];correctL=true; } + else if (( hue<=(_1G40[x] + _10GY40[x])/2.0) && (hue > (_10GY40[x] + _75GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY40[y] - _10GY40[x] ;lbe=_10GY40[y];correctL=true; } + else if (( hue<=(_10GY40[x] + _75GY40[x])/2.0) && (hue > (_75GY40[x] + _5GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY40[y] - _75GY40[x] ;lbe=_75GY40[y];correctL=true;} + else if (( hue<=(_5GY40[x] + _75GY40[x])/2.0) && (hue > (_5GY40[x]-0.035)) && x < 85) {if(y>89) y=89; correction = _5GY40[y] - _5GY40[x] ;lbe=_5GY40[y];correctL=true; } // + } + else if (lum <55.0) { + if( (hue <= (_7G50[x] + 0.035)) && (hue > (_7G50[x] + _5G50[x])/2.0) ) {correction = _7G50[y] - _7G50[x] ;lbe=_7G50[y];correctL=true;} + else if( (hue <= (_7G50[x] + _5G50[x])/2.0) && (hue >(_5G50[x] + _25G50[x])/2.0)) {correction = _5G50[y] - _5G50[x] ;lbe=_5G50[y];correctL=true;} + else if (( hue<=(_25G50[x] + _5G50[x])/2.0) && (hue > (_25G50[x] + _1G50[x])/2.0)) {correction = _25G50[y] - _25G50[x] ;lbe= _25G50[y];correctL=true;} + else if (( hue<=(_1G50[x] + _25G50[x])/2.0) && (hue > (_1G50[x] + _10GY50[x])/2.0)) {correction = _1G50[y] - _1G50[x] ; lbe=_1G50[y];correctL=true;} + else if (( hue<=(_1G50[x] + _10GY50[x])/2.0) && (hue > (_10GY50[x] + _75GY50[x])/2.0)) {correction = _10GY50[y] - _10GY50[x] ;lbe= _10GY50[y];correctL=true;} + else if (( hue<=(_10GY50[x] + _75GY50[x])/2.0) && (hue > (_75GY50[x] + _5GY50[x])/2.0)) {correction = _75GY50[y] - _75GY50[x] ;lbe=_75GY50[y];correctL=true;} + else if (( hue<=(_5GY50[x] + _75GY50[x])/2.0) && (hue > (_5GY50[x] -0.035))) {correction = _5GY50[y] - _5GY50[x] ; lbe=_5GY50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_7G60[x] + 0.035)) && (hue > (_7G60[x] + _5G60[x])/2.0) ) {correction = _7G60[y] - _7G60[x] ;lbe=_7G60[y];correctL=true;} + else if( (hue <= (_7G60[x] + _5G60[x])/2.0) && (hue >(_5G60[x] + _25G60[x])/2.0)) {correction = _5G60[y] - _5G60[x] ;lbe=_5G60[y];correctL=true;} + else if (( hue<=(_25G60[x] + _5G60[x])/2.0) && (hue > (_25G60[x] + _1G60[x])/2.0)) {correction = _25G60[y] - _25G60[x] ;lbe=_25G60[y];correctL=true;} + else if (( hue<=(_1G60[x] + _25G60[x])/2.0) && (hue > (_1G60[x] + _10GY60[x])/2.0)) {correction = _1G60[y] - _1G60[x] ; lbe=_1G60[y];correctL=true;} + else if (( hue<=(_1G60[x] + _10GY60[x])/2.0) && (hue > (_10GY60[x] + _75GY60[x])/2.0)) {correction = _10GY60[y] - _10GY60[x] ;lbe= _10GY60[y];correctL=true;} + else if (( hue<=(_10GY60[x] + _75GY60[x])/2.0) && (hue > (_75GY60[x] + _5GY60[x])/2.0)) {correction = _75GY60[y] - _75GY60[x] ;lbe=_75GY60[y] ;correctL=true;} + else if (( hue<=(_5GY60[x] + _75GY60[x])/2.0) && (hue > (_5GY60[x] -0.035))) {correction = _5GY60[y] - _5GY60[x] ; lbe=_5GY60[y];correctL=true;} + } + else if (lum <75.0) { + if( (hue <= (_7G70[x] + 0.035)) && (hue > (_7G70[x] + _5G70[x])/2.0) ) {correction = _7G70[y] - _7G70[x] ;lbe= _7G70[y];correctL=true;} + else if( (hue <= (_7G70[x] + _5G70[x])/2.0) && (hue >(_5G70[x] + _25G70[x])/2.0)) {correction = _5G70[y] - _5G70[x] ;lbe= _5G70[y];correctL=true;} + else if (( hue<=(_25G70[x] + _5G70[x])/2.0) && (hue > (_25G70[x] + _1G70[x])/2.0)) {correction = _25G70[y] - _25G70[x] ;lbe=_25G70[y];correctL=true;} + else if (( hue<=(_1G70[x] + _25G70[x])/2.0) && (hue > (_1G70[x] + _10GY70[x])/2.0)) {correction = _1G70[y] - _1G70[x] ;lbe= _1G70[y] ;correctL=true;} + else if (( hue<=(_1G70[x] + _10GY70[x])/2.0) && (hue > (_10GY70[x] + _75GY70[x])/2.0)) {correction = _10GY70[y] - _10GY70[x] ; lbe=_10GY70[y];correctL=true;} + else if (( hue<=(_10GY70[x] + _75GY70[x])/2.0) && (hue > (_75GY70[x] + _5GY70[x])/2.0)) {correction = _75GY70[y] - _75GY70[x] ;lbe=_75GY70[y];correctL=true;} + else if (( hue<=(_5GY70[x] + _75GY70[x])/2.0) && (hue > (_5GY70[x] -0.035))) {correction = _5GY70[y] - _5GY70[x] ;lbe= _5GY70[y];correctL=true;} + } + else if (lum <85.0) { + if( (hue <= (_7G80[x] + 0.035)) && (hue > (_7G80[x] + _5G80[x])/2.0) ) {correction = _7G80[y] - _7G80[x] ;lbe=_7G80[y];correctL=true;} + else if( (hue <= (_7G80[x] + _5G80[x])/2.0) && (hue >(_5G80[x] + _25G80[x])/2.0)) {correction = _5G80[y] - _5G80[x] ;lbe=_5G80[y];correctL=true;} + else if (( hue<=(_25G80[x] + _5G80[x])/2.0) && (hue > (_25G80[x] + _1G80[x])/2.0)) {correction = _25G80[y] - _25G80[x] ;lbe=_25G80[y];correctL=true;} + else if (( hue<=(_1G80[x] + _25G80[x])/2.0) && (hue > (_1G80[x] + _10GY80[x])/2.0)) {correction = _1G80[y] - _1G80[x] ; lbe= _1G80[y];correctL=true;} + else if (( hue<=(_1G80[x] + _10GY80[x])/2.0) && (hue > (_10GY80[x] + _75GY80[x])/2.0)) {correction = _10GY80[y] - _10GY80[x] ;lbe=_10GY80[y];correctL=true; } + else if (( hue<=(_10GY80[x] + _75GY80[x])/2.0) && (hue > (_75GY80[x] + _5GY80[x])/2.0)) {correction = _75GY80[y] - _75GY80[x] ;lbe=_75GY80[y];correctL=true;} + else if (( hue<=(_5GY80[x] + _75GY80[x])/2.0) && (hue > (_5GY80[x] -0.035))) {correction = _5GY80[y] - _5GY80[x] ; lbe=_5GY80[y];correctL=true;} + } + } + } + //end green yellow + + //Red purple correction : only for L < 30 + else if(zone==4) { + if (lum > 5.0) { + if (lum < 15.0) { + if( (hue <= (_5R10[x] + 0.035)) && (hue > (_5R10[x] - 0.043)) && x<45) {if(y>44) y=44;correction = _5R10[y] - _5R10[x] ;lbe=_5R10[y];correctL=true;} + else if( (hue <= (_25R10[x] + 0.043)) && (hue >(_25R10[x] + _10RP10[x])/2.0) && x<45 ) {if(y>44) y=44;correction = _25R10[y] - _25R10[x] ;lbe= _25R10[y];correctL=true;} + else if ( (hue <=(_25R10[x] + _10RP10[x])/2.0) && (hue > (_10RP10[x] -0.035) ) && x<45){if(y>44) y=44; correction = _10RP10[y] - _10RP10[x] ;lbe=_10RP10[y];correctL=true;} + } + else if (lum <25.0) { + if( (hue <= (_5R20[x] + 0.035)) && (hue > (_5R20[x] + _25R20[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _5R20[y] - _5R20[x] ;lbe= _5R20[y];correctL=true;} + else if( (hue <= (_5R20[x] + _25R20[x])/2.0) && (hue >(_10RP20[x] + _25R20[x])/2.0) && x<70) {if(y>70) y=70;correction = _25R20[y] - _25R20[x] ;lbe=_25R20[y];correctL=true;} + else if (( hue<=(_10RP20[x] + _25R20[x])/2.0) && (hue > (_10RP20[x] -0.035)) && x<70) {if(y>70) y=70; correction = _10RP20[y] - _10RP20[x] ;lbe=_10RP20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue <= (_5R30[x] + 0.035)) && (hue > (_5R30[x] + _25R30[x])/2.0) && x<85 ) {if(y>85) y=85;correction = _5R30[y] - _5R30[x] ;lbe= _5R30[y];correctL=true;} + else if( (hue <= (_5R30[x] + _25R30[x])/2.0) && (hue >(_10RP30[x] + _25R30[x])/2.0) && x< 85) {if(y>85) y=85;correction = _25R30[y] - _25R30[x] ;lbe=_25R30[y];correctL=true;} + else if (( hue<=(_10RP30[x] + _25R30[x])/2.0) && (hue > (_10RP30[x] -0.035)) && x<85) {if(y>85) y=85; correction = _10RP30[y] - _10RP30[x] ;lbe= _10RP30[y];correctL=true;} + } + } + } + //end red purple + } + + + /* + * SkinSat + * Copyright (c)2011 Jacques Desmis + * + * skin color: mixed from NX2 skin color palette, Von Luschan, and photos of people white, + * black, yellow....there are some little exceptions...cover 99% case + * pay attention to white balance, and do not change hue and saturation, upstream of the modification + * + */ + void Color::SkinSat (float lum, float hue, float chrom, float &satreduc, int chromx) { + + float reduction=0.3;// to be adapted...by tests + float extendedreduction=0.4; + float extendedreduction2=0.6; + + if(chromx==1) {reduction=0.6;extendedreduction=0.7;extendedreduction2=0.8;} + + float C9=0.0, C8=0.0, C7=0.0, C4=0.0, C3=0.0, C2=0.0, C1=0.0; + float H9=0.0, H8=0.0, H7=0.0, H4=0.0, H3=0.0, H2=0.0, H1=0.0, H10=0.0,H11=0.0; + H9=0.05;H8=0.25;H7=0.1;H4=0.02;H3=0.02;H2=0.1;H1=0.1;H10=-0.2;H11=-0.2;//H10 and H11 are curious...H11=-0.8 ?? + C9=8.0;C8=15.0;C7=12.0;C4=7.0;C3=5.0;C2=5.0;C1=5.0; + + // wide area for transition + + if (lum >= 92.0 && (hue > -0.1 && hue < 1.65) && (chrom > 7.0 && chrom < (18.0))) satreduc=extendedreduction2; + else if (lum >= 85.0 && lum < 92.0 && (hue > 0.0 && hue < 1.65) && (chrom > 7.0 && chrom < (35.0+C9))) satreduc=extendedreduction2; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.65) && (chrom > 7.0 && chrom < (55.0+C9) )) satreduc=extendedreduction2; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.60) && (chrom > 7.0 && chrom < (45.0+C1) )) satreduc=extendedreduction2; + + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation + + if (lum >= 92.0 && (hue > 0.8 && hue < 1.65) && (chrom > 7.0 && chrom < (15.0))) satreduc=extendedreduction; + else if (lum >= 85.0 && lum < 92.0 && (hue > 0.70 && hue < 1.4) && (chrom > 7.0 && chrom < (26.0+C9))) satreduc=extendedreduction; + else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.5) && (chrom > 7.0 && chrom < (48.0+C9) )) satreduc=extendedreduction; + else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.0) && (chrom > 7.0 && chrom < (35.0+C1) )) satreduc=extendedreduction; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 + + if (lum >= 85.0 && (hue > (0.78-H9) && hue < (1.18+H9)) && (chrom > 8.0 && chrom < (14.0+C9))) satreduc=reduction; + else if ((lum >= 70.0 && lum < 85.0) && (hue > 0.4 && hue < (1.04+H8)) && (chrom > 8.0 && chrom < (35.0+C8))) satreduc=reduction; + else if ((lum >= 52.0 && lum < 70.0) && (hue > 0.3 && hue < (1.27+H7)) && (chrom > 11.0 && chrom < (35.0+C7))) satreduc=reduction; + else if ((lum >= 35.0 && lum < 52.0) && (hue > 0.3 && hue < (1.25+H4)) && (chrom > 13.0 && chrom < (37.0+C4))) satreduc=reduction; + else if ((lum >= 20.0 && lum < 35.0) && (hue > 0.3 && hue < (1.20+H3)) && (chrom > 7.0 && chrom <(35.0+C3) )) satreduc=reduction; + else if ((lum > 10.0 && lum < 20.0) && (hue > (0.0 + H10) && hue < (0.95 +H2)) && (chrom > 8.0 && chrom < (23.0+C2))) satreduc=reduction; + else if ((lum < 10.0) && (hue > (0.02 + H10) && hue < (0.90+H1)) && (chrom > 8.0 && chrom < (23.0+C1))) satreduc=reduction; // no data : extrapolate + } + + /* + * Munsell Lch correction + * Copyright (c) 2011 Jacques Desmis + * + * data (Munsell ==> Lab) obtained with WallKillcolor and http://www.cis.rit.edu/research/mcsl2/online/munsell.php + * each LUT give Hue in function of C, for each color Munsell and Luminance + * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation betwwen values + * no value for C<5 (gray) + * low memory footprint -- maximum: 195 LUTf * 140 values + * errors due to small number of samples in LUT and linearization are very low (1 to 2%) + * errors due to a different illuminant "Daylight" than "C" are low, about 10%. For example, a theoretical correction of 0.1 radian will be made with a real correction of 0.09 or 0.11 depending on the color illuminant D50 + * errors due to the use of a very different illuminant "C", for example illuminant "A" (tungsten) are higher, about 20%. Theoretical correction of 0.52 radians will be made with a real correction of 0.42 + */ + void Color::initMunsell () { + #ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + #endif + + const int maxInd = 140; + const int maxInd2 = 90; + const int maxInd3 = 50; + + //blue for sky + _5B40(maxInd2); + for (int i=0; i5) _5B40[i] = -2.3 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B40[i] = -2.2 + 0.00*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B40[44],_5B40[89]); + _5B50(maxInd2); + for (int i=0; i5) _5B50[i] = -2.34 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B50[i] = -2.24+0.0003*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B50[44],_5B50[89]); + _5B60(maxInd2); + for (int i=0; i5) _5B60[i] = -2.4 + 0.003*(i-5); + else if (i<90 && i>=45) _5B60[i] = -2.28+0.0005*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B60[44],_5B60[89]); + _5B70(maxInd2); + for (int i=0; i5) _5B70[i] = -2.41 + 0.00275*(i-5); + else if (i<90 && i>=45) _5B70[i] = -2.30+0.00025*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B70[44],_5B70[89]); + _5B80(maxInd3); + for (int i=0; i5) _5B80[i] = -2.45 +0.003*(i-5); + } + //printf("5B %1.2f\n",_5B80[49]); + + _7B40(maxInd2); + for (int i=0; i5) _7B40[i] = -2.15 + 0.0027*(i-5); + else if (i<90 && i>=45) _7B40[i] = -2.04 + 0.00*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B40[44],_7B40[89]); + _7B50(maxInd2); + for (int i=0; i5) _7B50[i] = -2.20 + 0.003*(i-5); + else if (i<90 && i>=45) _7B50[i] = -2.08 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B50[44],_7B50[79]); + _7B60(maxInd2); + for (int i=0; i5) _7B60[i] = -2.26 + 0.0035*(i-5); + else if (i<90 && i>=45) _7B60[i] = -2.12 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B60[44],_7B60[79]); + _7B70(maxInd2); + for (int i=0; i5) _7B70[i] = -2.28 + 0.003*(i-5); + else if (i<90 && i>=45) _7B70[i] = -2.16 + 0.0015*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B70[44],_7B70[64]); + _7B80(maxInd3); + for (int i=0; i5) _7B80[i] = -2.30 +0.0028*(i-5); + } + //printf("5B %1.2f\n",_7B80[49]); + + _9B40(maxInd2); + for (int i=0; i5) _9B40[i] = -1.99 + 0.0022*(i-5); + else if (i<90 && i>=45) _9B40[i] = -1.90 + 0.0008*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B40[44],_9B40[69]); + _9B50(maxInd2); + for (int i=0; i5) _9B50[i] = -2.04 + 0.0025*(i-5); + else if (i<90 && i>=45) _9B50[i] = -1.94 + 0.0013*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B50[44],_9B50[77]); + _9B60(maxInd2); + for (int i=0; i5) _9B60[i] = -2.10 + 0.0033*(i-5); + else if (i<90 && i>=45) _9B60[i] = -1.97 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B60[44],_9B60[79]); + _9B70(maxInd2); + for (int i=0; i5) _9B70[i] = -2.12 + 0.003*(i-5); + else if (i<90 && i>=45) _9B70[i] = -2.00 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B70[44],_9B70[54]); + _9B80(maxInd3); + for (int i=0; i5) _9B80[i] = -2.16 +0.0025*(i-5); + } + //printf("9B %1.2f\n",_9B80[49]); + + _10B40(maxInd2); + for (int i=0; i5) _10B40[i] = -1.92 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B40[i] = -1.83 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B40[44],_10B40[76]); + _10B50(maxInd2); + for (int i=0; i5) _10B50[i] = -1.95 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B50[i] = -1.86 + 0.0008*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B50[44],_10B50[85]); + _10B60(maxInd2); + for (int i=0; i5) _10B60[i] = -2.01 + 0.0027*(i-5); + else if (i<90 && i>=45) _10B60[i] = -1.90 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B60[44],_10B60[70]); + _10B70(maxInd3); + for (int i=0; i5) _10B70[i] = -2.03 +0.0025*(i-5); + } + //printf("10B %1.2f\n",_10B70[49]); + _10B80(maxInd3); + for (int i=0; i5) _10B80[i] = -2.08 +0.0032*(i-5); + } + //printf("10B %1.2f\n",_10B80[39]); + + _05PB40(maxInd2); + for (int i=0; i5) _05PB40[i] = -1.87 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB40[i] = -1.78 + 0.0015*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB40[44],_05PB40[74]); + _05PB50(maxInd2); + for (int i=0; i5) _05PB50[i] = -1.91 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB50[i] = -1.82 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB50[44],_05PB50[85]); + _05PB60(maxInd2); + for (int i=0; i5) _05PB60[i] = -1.96 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB60[i] = -1.85 + 0.0013*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB60[44],_05PB60[70]); + _05PB70(maxInd2); + for (int i=0; i5) _05PB70[i] = -1.99 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB70[i] = -1.88 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB70[44],_05PB70[54]); + _05PB80(maxInd3); + for (int i=0; i5) _05PB80[i] = -2.03 +0.003*(i-5); + } + //printf("05PB %1.2f\n",_05PB80[39]); + + + + //blue purple correction + //between 15PB to 4P + //maximum deviation 75PB + + //15PB + _15PB10(maxInd3); + for (int i=0; i5) _15PB10[i] = -1.66 +0.0035*(i-5); + } + //printf("15 %1.2f\n",_15PB10[49]); + _15PB20(maxInd2); + for (int i=0; i5) _15PB20[i] = -1.71 +0.00275*(i-5); + else if (i<90 && i>=45) _15PB20[i] = -1.60+0.0012*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB20[44],_15PB20[89]); + + _15PB30(maxInd2); + for (int i=0; i5) _15PB30[i] = -1.75 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB30[i] = -1.65+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB30[44],_15PB30[89]); + + _15PB40(maxInd2); + for (int i=0; i5) _15PB40[i] = -1.79 +0.002*(i-5); + else if (i<90 && i>=45) _15PB40[i] = -1.71+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB40[44],_15PB40[89]); + + _15PB50(maxInd2); + for (int i=0; i5) _15PB50[i] = -1.82 +0.002*(i-5); + else if (i<90 && i>=45) _15PB50[i] = -1.74+0.0011*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB50[44],_15PB50[89]); + + _15PB60(maxInd2); + for (int i=0; i5) _15PB60[i] = -1.87 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB60[i] = -1.77+0.001*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB60[44],_15PB60[89]); + _15PB70(maxInd3); + for (int i=0; i5) _15PB70[i] = -1.90 +0.0027*(i-5); + } + // printf("15 %1.2f\n",_15PB70[49]); + _15PB80(maxInd3); + for (int i=0; i5) _15PB80[i] = -1.93 +0.0027*(i-5); + } + //printf("15 %1.2f %1.2f\n",_15PB80[38], _15PB80[49]); + + //3PB + _3PB10(maxInd2); + for (int i=0; i5) _3PB10[i] = -1.56 +0.005*(i-5); + else if (i<90 && i>=45) _3PB10[i] = -1.36+0.001*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB10[44],_3PB10[89]); + + _3PB20(maxInd2); + for (int i=0; i5) _3PB20[i] = -1.59 +0.00275*(i-5); + else if (i<90 && i>=45) _3PB20[i] = -1.48+0.003*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB20[44],_3PB20[89]); + + _3PB30(maxInd2); + for (int i=0; i5) _3PB30[i] = -1.62 +0.00225*(i-5); + else if (i<90 && i>=45) _3PB30[i] = -1.53+0.0032*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB30[44],_3PB30[89]); + + _3PB40(maxInd2); + for (int i=0; i5) _3PB40[i] = -1.64 +0.0015*(i-5); + else if (i<90 && i>=45) _3PB40[i] = -1.58+0.0025*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB40[44],_3PB40[89]); + + _3PB50(maxInd2); + for (int i=0; i5) _3PB50[i] = -1.69 +0.00175*(i-5); + else if (i<90 && i>=45) _3PB50[i] = -1.62+0.002*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB50[44],_3PB50[89]); + + _3PB60(maxInd2); + for (int i=0; i5) _3PB60[i] = -1.73 +0.002*(i-5); + else if (i<90 && i>=45) _3PB60[i] = -1.65+0.0012*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB60[44],_3PB60[89]); + _3PB70(maxInd3); + for (int i=0; i5) _3PB70[i] = -1.76 +0.002*(i-5); + } + //printf("30 %1.2f\n",_3PB70[49]); + _3PB80(maxInd3); + for (int i=0; i5) _3PB80[i] = -1.78 +0.0025*(i-5); + } + //printf("30 %1.2f %1.2f\n",_3PB80[38], _3PB80[49]); + + //45PB + _45PB10(maxInd2); + for (int i=0; i5) _45PB10[i] = -1.46 +0.0045*(i-5); + else if (i<90 && i>=45) _45PB10[i] = -1.28+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB10[44],_45PB10[89]); + + _45PB20(maxInd2); + for (int i=0; i5) _45PB20[i] = -1.48 +0.00275*(i-5); + else if (i<90 && i>=45) _45PB20[i] = -1.37+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB20[44],_45PB20[89]); + + _45PB30(maxInd2); + for (int i=0; i5) _45PB30[i] = -1.51 +0.00175*(i-5); + else if (i<90 && i>=45) _45PB30[i] = -1.44+0.0035*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB30[44],_45PB30[89]); + + _45PB40(maxInd2); + for (int i=0; i5) _45PB40[i] = -1.52 +0.001*(i-5); + else if (i<90 && i>=45) _45PB40[i] = -1.48+0.003*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB40[44],_45PB40[89]); + + _45PB50(maxInd2); + for (int i=0; i5) _45PB50[i] = -1.55 +0.001*(i-5); + else if (i<90 && i>=45) _45PB50[i] = -1.51+0.0022*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB50[44],_45PB50[89]); + + _45PB60(maxInd2); + for (int i=0; i5) _45PB60[i] = -1.6 +0.0015*(i-5); + else if (i<90 && i>=45) _45PB60[i] = -1.54+0.001*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB60[44],_45PB60[89]); + _45PB70(maxInd3); + for (int i=0; i5) _45PB70[i] = -1.63 +0.0017*(i-5); + } + //printf("45 %1.2f\n",_45PB70[49]); + _45PB80(maxInd3); + for (int i=0; i5) _45PB80[i] = -1.67 +0.0025*(i-5); + } + //printf("45 %1.2f %1.2f\n",_45PB80[38], _45PB80[49]); + + //_6PB + _6PB10(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB10[i] = -1.33 +0.005*(i-5); + else if (i<85 && i>=45) _6PB10[i] = -1.13+0.0045*(i-45); + else if (i<140 && i >=85) _6PB10[i] = -0.95+0.0015*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB10[44],_6PB10[84],_6PB10[139]); + + _6PB20(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB20[i] = -1.36 +0.004*(i-5); + else if (i<85 && i>=45) _6PB20[i] = -1.20+0.00375*(i-45); + else if (i<140 && i >=85) _6PB20[i] = -1.05+0.0017*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB20[44],_6PB20[84],_6PB20[139]); + + _6PB30(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB30[i] = -1.38 +0.00225*(i-5); + else if (i<85 && i>=45) _6PB30[i] = -1.29+0.00375*(i-45); + else if (i<140 && i >=85) _6PB30[i] = -1.14+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB30[44],_6PB30[84],_6PB30[139]); + + _6PB40(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _6PB40[i] = -1.39 +0.00125*(i-5); + else if (i<85 && i>=45) _6PB40[i] = -1.34+0.00275*(i-45); + else if (i<140 && i >=85) _6PB40[i] = -1.23+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB40[44],_6PB40[84],_6PB40[139]); + + _6PB50(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _6PB50[i] = -1.43 +0.00125*(i-5); + else if (i<90 && i>=45) _6PB50[i] = -1.38+0.00225*(i-45); + } + //printf("60 %1.2f %1.2f \n",_6PB50[44],_6PB50[89]); + + _6PB60(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _6PB60[i] = -1.46 +0.0012*(i-5); + else if (i<90 && i>=45) _6PB60[i] = -1.40+0.000875*(i-45); + } + //printf("60 %1.2f %1.2f\n",_6PB60[44],_6PB60[89]); + _6PB70(maxInd3); + for (int i=0; i5) _6PB70[i] = -1.49 +0.0018*(i-5); + } + //printf("6 %1.2f\n",_6PB70[49]); + _6PB80(maxInd3); + for (int i=0; i5) _6PB80[i] = -1.52 +0.0022*(i-5); + } + //printf("6 %1.2f %1.2f\n",_6PB80[38], _6PB80[49]); + + + //_75PB : notation Munsell for maximum deviation blue purple + _75PB10(maxInd);//limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 + for (int i=0; i140 + if (i<45 && i>5) _75PB10[i] = -1.23 +0.0065*(i-5); + else if (i<85 && i>=45) _75PB10[i] = -0.97+0.00375*(i-45); + else if (i<140 && i >=85) _75PB10[i] = -0.82+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB10[44],_75PB10[84],_75PB10[139]); + + _75PB20(maxInd);//limits -1.24 -0.79 for L>15 <=25 + for (int i=0; i5) _75PB20[i] = -1.24 +0.004*(i-5); + else if (i<85 && i>=45) _75PB20[i] = -1.08+0.00425*(i-45); + else if (i<140 && i >=85) _75PB20[i] = -0.91+0.0017*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB20[44],_75PB20[84],_75PB20[139]); + + _75PB30(maxInd);//limits -1.25 -0.85 + for (int i=0; i5) _75PB30[i] = -1.25 +0.00275*(i-5); + else if (i<85 && i>=45) _75PB30[i] = -1.14+0.004*(i-45); + else if (i<140 && i >=85) _75PB30[i] = -0.98+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB30[44],_75PB30[84],_75PB30[139]); + + _75PB40(maxInd);//limits -1.27 -0.92 + for (int i=0; i5) _75PB40[i] = -1.27 +0.002*(i-5); + else if (i<85 && i>=45) _75PB40[i] = -1.19+0.003*(i-45); + else if (i<140 && i >=85) _75PB40[i] = -1.07+0.0022*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB40[44],_75PB40[84],_75PB40[139]); + + _75PB50(maxInd2);//limits -1.3 -1.11 + for (int i=0; i5) _75PB50[i] = -1.3 +0.00175*(i-5); + else if (i<90 && i>=45) _75PB50[i] = -1.23+0.0025*(i-45); + } + //printf("75 %1.2f %1.2f\n",_75PB50[44],_75PB50[89]); + + _75PB60(maxInd2); + for (int i=0; i5) _75PB60[i] = -1.32 +0.0015*(i-5); + else if (i<90 && i>=45) _75PB60[i] = -1.26+0.002*(i-45); + } + //printf("75 %1.2f %1.2f \n",_75PB60[44],_75PB60[89]); + + _75PB70(maxInd3); + for (int i=0; i5) _75PB70[i] = -1.34 +0.002*(i-5); + } + _75PB80(maxInd3); + for (int i=0; i5) _75PB80[i] = -1.35 +0.00125*(i-5); + } + + + _9PB10(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB10[i] = -1.09 +0.00475*(i-5); + else if (i<85 && i>=45) _9PB10[i] = -0.9+0.003*(i-45); + else if (i<140 && i >=85) _9PB10[i] = -0.78+0.0013*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB10[44],_9PB10[84],_9PB10[139]); + + _9PB20(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB20[i] = -1.12 +0.0035*(i-5); + else if (i<85 && i>=45) _9PB20[i] = -0.98+0.00325*(i-45); + else if (i<140 && i >=85) _9PB20[i] = -0.85+0.0015*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB20[44],_9PB20[84],_9PB20[139]); + + _9PB30(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB30[i] = -1.14 +0.0028*(i-5); + else if (i<85 && i>=45) _9PB30[i] = -1.03+0.003*(i-45); + else if (i<140 && i >=85) _9PB30[i] = -0.91+0.0017*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB30[44],_9PB30[84],_9PB30[139]); + + _9PB40(maxInd); + for (int i=0; i140 + if (i<45 && i>5) _9PB40[i] = -1.16 +0.002*(i-5); + else if (i<85 && i>=45) _9PB40[i] = -1.08+0.00275*(i-45); + else if (i<140 && i >=85) _9PB40[i] = -0.97+0.0016*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB40[44],_9PB40[84],_9PB40[139]); + + _9PB50(maxInd2); + for (int i=0; i5) _9PB50[i] = -1.19 +0.00175*(i-5); + else if (i<90 && i>=45) _9PB50[i] = -1.12+0.00225*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB50[44],_9PB50[84]); + + _9PB60(maxInd2); + for (int i=0; i5) _9PB60[i] = -1.21 +0.0015*(i-5); + else if (i<90 && i>=45) _9PB60[i] = -1.15+0.002*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB60[44],_9PB60[89]); + _9PB70(maxInd3); + for (int i=0; i5) _9PB70[i] = -1.23 +0.0018*(i-5); + } + //printf("9 %1.2f\n",_9PB70[49]); + _9PB80(maxInd3); + for (int i=0; i5) _9PB80[i] = -1.24 +0.002*(i-5); + } + //printf("9 %1.2f %1.2f\n",_9PB80[38], _9PB80[49]); + + + //10PB + _10PB10(maxInd); + for (int i=0; i5) _10PB10[i] = -1.02 +0.00425*(i-5); + else if (i<85 && i>=45) _10PB10[i] = -0.85+0.0025*(i-45); + else if (i<140 && i >=85) _10PB10[i] = -0.75+0.0012*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB10[44],_10PB10[84],_10PB10[139]); + + _10PB20(maxInd); + for (int i=0; i5) _10PB20[i] = -1.05 +0.00325*(i-5); + else if (i<85 && i>=45) _10PB20[i] = -0.92+0.00275*(i-45); + else if (i<140 && i >=85) _10PB20[i] = -0.81+0.0014*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB20[44],_10PB20[84],_10PB20[139]); + + _10PB30(maxInd); + for (int i=0; i5) _10PB30[i] = -1.07 +0.00275*(i-5); + else if (i<85 && i>=45) _10PB30[i] = -0.96+0.0025*(i-45); + else if (i<140 && i >=85) _10PB30[i] = -0.86+0.0015*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB30[44],_10PB30[84],_10PB30[139]); + + _10PB40(maxInd); + for (int i=0; i5) _10PB40[i] = -1.09 +0.002*(i-5); + else if (i<85 && i>=45) _10PB40[i] = -1.01+0.00225*(i-45); + else if (i<140 && i >=85) _10PB40[i] = -0.92+0.0016*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB40[44],_10PB40[84],_10PB40[139]); + + _10PB50(maxInd2); + for (int i=0; i5) _10PB50[i] = -1.12 +0.00175*(i-5); + else if (i<90 && i>=45) _10PB50[i] = -1.05+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB50[44],_10PB50[84]); + + _10PB60(maxInd2); + for (int i=0; i5) _10PB60[i] = -1.14 +0.0015*(i-5); + else if (i<90 && i>=45) _10PB60[i] = -1.08+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB60[44],_10PB60[89]); + + + //1P + _1P10(maxInd); + for (int i=0; i5) _1P10[i] = -0.96 +0.00375*(i-5); + else if (i<85 && i>=45) _1P10[i] = -0.81+0.00225*(i-45); + else if (i<140 && i >=85) _1P10[i] = -0.72+0.001*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P10[44],_1P10[84],_1P10[139]); + + _1P20(maxInd); + for (int i=0; i5) _1P20[i] = -1.0 +0.00325*(i-5); + else if (i<85 && i>=45) _1P20[i] = -0.87+0.0025*(i-45); + else if (i<140 && i >=85) _1P20[i] = -0.77+0.0012*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P20[44],_1P20[84],_1P20[139]); + + _1P30(maxInd); + for (int i=0; i5) _1P30[i] = -1.02 +0.00275*(i-5); + else if (i<85 && i>=45) _1P30[i] = -0.91+0.00225*(i-45); + else if (i<140 && i >=85) _1P30[i] = -0.82+0.0011*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P30[44],_1P30[84],_1P30[139]); + + _1P40(maxInd); + for (int i=0; i5) _1P40[i] = -1.04 +0.00225*(i-5); + else if (i<85 && i>=45) _1P40[i] = -0.95+0.00225*(i-45); + else if (i<140 && i >=85) _1P40[i] = -0.86+0.0015*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P40[44],_1P40[84],_1P40[139]); + + _1P50(maxInd2); + for (int i=0; i5) _1P50[i] = -1.06 +0.002*(i-5); + else if (i<90 && i>=45) _1P50[i] = -0.98+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P50[44],_1P50[89]); + + _1P60(maxInd2); + for (int i=0; i5) _1P60[i] = -1.07 +0.0015*(i-5); + else if (i<90 && i>=45) _1P60[i] = -1.01+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P60[44],_1P60[84],_1P60[139]); + + //4P + _4P10(maxInd); + for (int i=0; i5) _4P10[i] = -0.78 +0.002*(i-5); + else if (i<85 && i>=45) _4P10[i] = -0.7+0.00125*(i-45); + else if (i<140 && i >=85) _4P10[i] = -0.65+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P10[44],_4P10[84],_4P10[139]); + + _4P20(maxInd); + for (int i=0; i5) _4P20[i] = -0.84 +0.0025*(i-5); + else if (i<85 && i>=45) _4P20[i] = -0.74+0.00175*(i-45); + else if (i<140 && i >=85) _4P20[i] = -0.67+0.00085*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P20[44],_4P20[84],_4P20[139]); + + _4P30(maxInd); + for (int i=0; i5) _4P30[i] = -0.85 +0.00225*(i-5); + else if (i<85 && i>=45) _4P30[i] = -0.76+0.00125*(i-45); + else if (i<140 && i >=85) _4P30[i] = -0.71+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P30[44],_4P30[84],_4P30[139]); + + _4P40(maxInd); + for (int i=0; i5) _4P40[i] = -0.87 +0.00175*(i-5); + else if (i<85 && i>=45) _4P40[i] = -0.8+0.00175*(i-45); + else if (i<140 && i >=85) _4P40[i] = -0.73+0.00075*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P40[44],_4P40[84],_4P40[139]); + + _4P50(maxInd2); + for (int i=0; i5) _4P50[i] = -0.88 +0.0015*(i-5); + else if (i<90 && i>=45) _4P50[i] = -0.82+0.0015*(i-45); + } + //printf("4P %1.2f %1.2f \n",_4P50[44],_4P50[89]); + + _4P60(maxInd2); + for (int i=0; i5) _4P60[i] = -0.89 +0.00125*(i-5); + else if (i<90 && i>=45) _4P60[i] = -0.84+0.00125*(i-45); + } + //printf("4P %1.2f %1.2f\n",_4P60[44],_4P60[89]); + + + //red yellow correction + _10YR20(maxInd2); + for (int i=0; i5) _10YR20[i] = 1.22 +0.002*(i-5); + else if (i<90 && i>=45) _10YR20[i] = 1.30+0.006*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR20[44],_10YR20[56]); + _10YR30(maxInd2); + for (int i=0; i5) _10YR30[i] = 1.27 +0.00175*(i-5); + else if (i<90 && i>=45) _10YR30[i] = 1.34+0.0017*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR30[44],_10YR30[75]); + _10YR40(maxInd2); + for (int i=0; i5) _10YR40[i] = 1.32 +0.00025*(i-5); + else if (i<90 && i>=45) _10YR40[i] = 1.33+0.0015*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR40[44],_10YR40[85]); + _10YR50(maxInd2); + for (int i=0; i5) _10YR50[i] = 1.35 +0.000*(i-5); + else if (i<90 && i>=45) _10YR50[i] = 1.35+0.0012*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR50[44],_10YR50[80]); + _10YR60(maxInd); + for (int i=0; i5) _10YR60[i] = 1.38 - 0.00025*(i-5); + else if (i<85 && i>=45) _10YR60[i] = 1.37+0.0005*(i-45); + else if (i<140 && i >=85) _10YR60[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR60[44],_10YR60[85],_10YR60[139] ); + _10YR70(maxInd); + for (int i=0; i5) _10YR70[i] = 1.41 - 0.0005*(i-5); + else if (i<85 && i>=45) _10YR70[i] = 1.39+0.000*(i-45); + else if (i<140 && i >=85) _10YR70[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR70[44],_10YR70[85],_10YR70[139] ); + _10YR80(maxInd); + for (int i=0; i5) _10YR80[i] = 1.45 - 0.00125*(i-5); + else if (i<85 && i>=45) _10YR80[i] = 1.40+0.000*(i-45); + else if (i<140 && i >=85) _10YR80[i] = 1.40+0.00072*(i-85);//1.436 + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR80[44],_10YR80[84],_10YR80[139] ); + _10YR90(maxInd2); + for (int i=0; i5) _10YR90[i] = 1.48 -0.001*(i-5); + else if (i<90 && i>=45) _10YR90[i] = 1.44-0.0009*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR90[45],_10YR90[80]); + _85YR20(maxInd3); + for (int i=0; i5) _85YR20[i] = 1.12 +0.004*(i-5); + } + + //printf("85YR %1.2f \n",_85YR20[44]); + _85YR30(maxInd2); + for (int i=0; i5) _85YR30[i] = 1.16 + 0.0025*(i-5); + else if (i<90 && i>=45) _85YR30[i] = 1.26+0.0028*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR30[44],_85YR30[75]); + _85YR40(maxInd2); + for (int i=0; i5) _85YR40[i] = 1.20 + 0.0015*(i-5); + else if (i<90 && i>=45) _85YR40[i] = 1.26+0.0024*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR40[44],_85YR40[75]); + _85YR50(maxInd); + for (int i=0; i5) _85YR50[i] = 1.24 + 0.0005*(i-5); + else if (i<85 && i>=45) _85YR50[i] = 1.26+0.002*(i-45); + else if (i<140 && i >=85) _85YR50[i] = 1.34+0.0015*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR50[44],_85YR50[85],_85YR50[110] ); + _85YR60(maxInd); + for (int i=0; i5) _85YR60[i] = 1.27 + 0.00025*(i-5); + else if (i<85 && i>=45) _85YR60[i] = 1.28+0.0015*(i-45); + else if (i<140 && i >=85) _85YR60[i] = 1.34+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR60[44],_85YR60[85],_85YR60[139] ); + + _85YR70(maxInd); + for (int i=0; i5) _85YR70[i] = 1.31 - 0.00025*(i-5); + else if (i<85 && i>=45) _85YR70[i] = 1.30+0.0005*(i-45); + else if (i<140 && i >=85) _85YR70[i] = 1.32+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR70[44],_85YR70[85],_85YR70[139] ); + _85YR80(maxInd); + for (int i=0; i5) _85YR80[i] = 1.35 - 0.00075*(i-5); + else if (i<85 && i>=45) _85YR80[i] = 1.32+0.00025*(i-45); + else if (i<140 && i >=85) _85YR80[i] = 1.33+0.00125*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR80[44],_85YR80[85],_85YR80[139] ); + _85YR90(maxInd2); + for (int i=0; i5) _85YR90[i] = 1.39 - 0.00125*(i-5); + else if (i<90 && i>=45) _85YR90[i] = 1.34+0.00*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR90[44],_85YR90[85]); + + //7YR + _7YR30(maxInd2); + for (int i=0; i5) _7YR30[i] = 1.06 + 0.0028*(i-5); + else if (i<90 && i>=45) _7YR30[i] = 1.17+0.0045*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR30[44],_7YR30[66]); + _7YR40(maxInd2); + for (int i=0; i5) _7YR40[i] = 1.10 + 0.0018*(i-5); + else if (i<90 && i>=45) _7YR40[i] = 1.17+0.0035*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR40[44],_7YR40[89]); + _7YR50(maxInd2); + for (int i=0; i5) _7YR50[i] = 1.14 + 0.00125*(i-5); + else if (i<90 && i>=45) _7YR50[i] = 1.19+0.002*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR50[44],_7YR50[89] ); + _7YR60(maxInd); + for (int i=0; i5) _7YR60[i] = 1.17 + 0.00075*(i-5); + else if (i<85 && i>=45) _7YR60[i] = 1.20+0.00175*(i-45); + else if (i<140 && i >=85) _7YR60[i] = 1.27+0.002*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR60[44],_7YR60[84],_7YR60[125] ); + + _7YR70(maxInd); + for (int i=0; i5) _7YR70[i] = 1.20 + 0.0005*(i-5); + else if (i<85 && i>=45) _7YR70[i] = 1.22+0.00125*(i-45); + else if (i<140 && i >=85) _7YR70[i] = 1.27+0.0015*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR70[44],_7YR70[84],_7YR70[125] ); + _7YR80(maxInd3); + for (int i=0; i5) _7YR80[i] = 1.29 - 0.0008*(i-5); + } + //printf("7YR %1.2f \n",_7YR80[44] ); + _55YR30(maxInd3); + for (int i=0; i5) _55YR30[i] = 0.96 + 0.0038*(i-5); + } + //printf("55YR %1.2f \n",_55YR30[44] ); + _55YR40(maxInd2); + for (int i=0; i5) _55YR40[i] = 1.01 + 0.0022*(i-5); + else if (i<90 && i>=45) _55YR40[i] = 1.10+0.0037*(i-45); + } + //printf("55YR %1.2f %1.2f\n",_55YR40[44],_55YR40[89] ); + _55YR50(maxInd); + for (int i=0; i5) _55YR50[i] = 1.06 + 0.0015*(i-5); + else if (i<85 && i>=45) _55YR50[i] = 1.12+0.00225*(i-45); + else if (i<140 && i >=85) _55YR50[i] = 1.21+0.0015*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR50[44],_55YR50[84],_55YR50[125] ); + _55YR60(maxInd); + for (int i=0; i5) _55YR60[i] = 1.08 + 0.0012*(i-5); + else if (i<85 && i>=45) _55YR60[i] = 1.13+0.0018*(i-45); + else if (i<140 && i >=85) _55YR60[i] = 1.20+0.0025*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR60[44],_55YR60[84],_55YR60[125] ); + _55YR70(maxInd); + for (int i=0; i5) _55YR70[i] = 1.11 + 0.00075*(i-5); + else if (i<85 && i>=45) _55YR70[i] = 1.14+0.0012*(i-45); + else if (i<140 && i >=85) _55YR70[i] = 1.19+0.00225*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR70[44],_55YR70[84],_55YR70[125] ); + _55YR80(maxInd); + for (int i=0; i5) _55YR80[i] = 1.16 + 0.00*(i-5); + else if (i<85 && i>=45) _55YR80[i] = 1.16+0.00075*(i-45); + else if (i<140 && i >=85) _55YR80[i] = 1.19+0.00175*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR80[44],_55YR80[84],_55YR80[125] ); + _55YR90(maxInd3); + for (int i=0; i5) _55YR90[i] = 1.19 - 0.0005*(i-5); + } + //printf("55YR %1.2f \n",_55YR90[44] ); + + _4YR30(maxInd2); + for (int i=0; i5) _4YR30[i] = 0.87 + 0.0035*(i-5); + else if (i<90 && i>=45) _4YR30[i] = 1.01+0.0043*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR30[44],_4YR30[78] ); + _4YR40(maxInd2); + for (int i=0; i5) _4YR40[i] = 0.92 + 0.0025*(i-5); + else if (i<90 && i>=45) _4YR40[i] = 1.02+0.0033*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR40[44],_4YR40[74] ); + _4YR50(maxInd2); + for (int i=0; i5) _4YR50[i] = 0.97 + 0.0015*(i-5); + else if (i<90 && i>=45) _4YR50[i] = 1.03+0.0025*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR50[44],_4YR50[85] ); + _4YR60(maxInd); + for (int i=0; i5) _4YR60[i] = 0.99 + 0.00125*(i-5); + else if (i<85 && i>=45) _4YR60[i] = 1.04+0.002*(i-45); + else if (i<140 && i >=85) _4YR60[i] = 1.12+0.003*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR60[44],_4YR60[84],_4YR60[125] ); + _4YR70(maxInd); + for (int i=0; i5) _4YR70[i] = 1.02 + 0.00075*(i-5); + else if (i<85 && i>=45) _4YR70[i] = 1.05+0.00175*(i-45); + else if (i<140 && i >=85) _4YR70[i] = 1.12+0.002*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR70[44],_4YR70[84],_4YR70[125] ); + _4YR80(maxInd3); + for (int i=0; i5) _4YR80[i] = 1.09 - 0.0002*(i-5); + } + //printf("4YR %1.2f \n",_4YR80[41] ); + + _25YR30(maxInd2); + for (int i=0; i5) _25YR30[i] = 0.77 + 0.004*(i-5); + else if (i<90 && i>=45) _25YR30[i] = 0.94+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR30[44],_25YR30[74] ); + _25YR40(maxInd2); + for (int i=0; i5) _25YR40[i] = 0.82 + 0.003*(i-5); + else if (i<90 && i>=45) _25YR40[i] = 0.94+0.002*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR40[44],_25YR40[84] ); + _25YR50(maxInd2); + for (int i=0; i5) _25YR50[i] = 0.87+ 0.002*(i-5); + else if (i<90 && i>=45) _25YR50[i] = 0.95+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR50[44],_25YR50[84] ); + _25YR60(maxInd2); + for (int i=0; i5) _25YR60[i] = 0.89+ 0.0015*(i-5); + else if (i<90 && i>=45) _25YR60[i] = 0.95+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR60[44],_25YR60[84] ); + _25YR70(maxInd2); + for (int i=0; i5) _25YR70[i] = 0.92+ 0.001*(i-5); + else if (i<90 && i>=45) _25YR70[i] = 0.96+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR70[44],_25YR70[84] ); + + _10R30(maxInd2); + for (int i=0; i5) _10R30[i] = 0.62 + 0.00225*(i-5); + else if (i<90 && i>=45) _10R30[i] = 0.71+0.003*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R30[44],_10R30[84] ); + _10R40(maxInd2); + for (int i=0; i5) _10R40[i] = 0.66 + 0.0025*(i-5); + else if (i<90 && i>=45) _10R40[i] = 0.76+0.0035*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R40[44],_10R40[84] ); + _10R50(maxInd2); + for (int i=0; i5) _10R50[i] = 0.71 + 0.002*(i-5); + else if (i<90 && i>=45) _10R50[i] = 0.79+0.0043*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R50[44],_10R50[84] ); + _10R60(maxInd); + for (int i=0; i5) _10R60[i] = 0.73 + 0.00175*(i-5); + else if (i<85 && i>=45) _10R60[i] = 0.80 +0.0033*(i-45); + else if (i<140 && i >=85) _10R60[i] = 0.93+0.0018*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R60[44],_10R60[84],_10R60[125] ); + _10R70(maxInd); + for (int i=0; i5) _10R70[i] = 0.75 + 0.0015*(i-5); + else if (i<85 && i>=45) _10R70[i] = 0.81 +0.0017*(i-45); + else if (i<140 && i >=85) _10R70[i] = 0.88+0.0025*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R70[44],_10R70[84],_10R70[125] ); + + _9R30(maxInd2); + for (int i=0; i5) _9R30[i] = 0.57 + 0.002*(i-5); + else if (i<90 && i>=45) _9R30[i] = 0.65+0.0018*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R30[44],_9R30[84] ); + _9R40(maxInd2); + for (int i=0; i5) _9R40[i] = 0.61 + 0.002*(i-5); + else if (i<90 && i>=45) _9R40[i] = 0.69+0.0025*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R40[44],_9R40[84] ); + _9R50(maxInd); + for (int i=0; i5) _9R50[i] = 0.66 + 0.00175*(i-5); + else if (i<85 && i>=45) _9R50[i] = 0.73 +0.0025*(i-45); + else if (i<140 && i >=85) _9R50[i] = 0.83+0.0035*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R50[44],_9R50[84],_9R50[125] ); + _9R60(maxInd); + for (int i=0; i5) _9R60[i] = 0.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _9R60[i] = 0.74 +0.0022*(i-45); + else if (i<140 && i >=85) _9R60[i] = 0.93+0.0022*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R60[44],_9R60[84],_9R60[125] ); + _9R70(maxInd2); + for (int i=0; i5) _9R70[i] = 0.70 + 0.0012*(i-5); + else if (i<90 && i>=45) _9R70[i] = 0.75+0.0013*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R70[44],_9R70[84] ); + + _7R30(maxInd2); + for (int i=0; i5) _7R30[i] = 0.48 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R30[i] = 0.54-0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R30[44],_7R30[84] ); + _7R40(maxInd2); + for (int i=0; i5) _7R40[i] = 0.51 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R40[i] = 0.57+0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R40[44],_7R40[84] ); + _7R50(maxInd); + for (int i=0; i5) _7R50[i] = 0.54 + 0.0015*(i-5); + else if (i<85 && i>=45) _7R50[i] = 0.60 +0.0005*(i-45); + else if (i<140 && i >=85) _7R50[i] = 0.62+0.0025*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R50[44],_7R50[84],_7R50[125] ); + _7R60(maxInd); + for (int i=0; i5) _7R60[i] = 0.58 + 0.00075*(i-5); + else if (i<85 && i>=45) _7R60[i] = 0.61 +0.00075*(i-45); + else if (i<140 && i >=85) _7R60[i] = 0.64+0.001*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R60[44],_7R60[84],_7R60[107] ); + _7R70(maxInd2); + for (int i=0; i5) _7R70[i] = 0.59 + 0.00075*(i-5); + else if (i<90 && i>=45) _7R70[i] = 0.62+0.00075*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R70[44],_7R70[84] ); + + //5R 1 2 3 + + //5R + _5R10(maxInd2); + for (int i=0; i5) _5R10[i] = 0.10 - 0.0018*(i-5); + else if (i<90 && i>=45) _5R10[i] = 0.035-0.003*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R10[44],_5R10[51] ); + _5R20(maxInd2); + for (int i=0; i5) _5R20[i] = 0.26 - 0.00075*(i-5); + else if (i<90 && i>=45) _5R20[i] = 0.023-0.0002*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R20[44],_5R20[70] ); + _5R30(maxInd2); + for (int i=0; i5) _5R30[i] = 0.39 + 0.00075*(i-5); + else if (i<90 && i>=45) _5R30[i] = 0.42-0.0007*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R30[44],_5R30[85] ); + + //25R + _25R10(maxInd3); + for (int i=0; i5) _25R10[i] = -0.03 - 0.002*(i-5); + } + //printf("25R %1.2f \n",_25R10[44]); + _25R20(maxInd2); + for (int i=0; i5) _25R20[i] = 0.13 - 0.0012*(i-5); + else if (i<90 && i>=45) _25R20[i] = 0.08-0.002*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R20[44],_25R20[69] ); + //25R30: 0.28, 0.26, 0.22 + _25R30(maxInd2); + for (int i=0; i5) _25R30[i] = 0.28 - 0.0005*(i-5); + else if (i<90 && i>=45) _25R30[i] = 0.26-0.0009*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R30[44],_25R30[85] ); + + + _10RP10(maxInd3); + for (int i=0; i5) _10RP10[i] = -0.16 - 0.0017*(i-5); + } + //printf("10RP %1.2f \n",_10RP10[44]); + _10RP20(maxInd2); + for (int i=0; i5) _10RP20[i] = 0.0 - 0.0018*(i-5); + else if (i<90 && i>=45) _10RP20[i] = -0.07-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP20[44],_10RP20[69] ); + _10RP30(maxInd2); + for (int i=0; i5) _10RP30[i] = 0.15 - 0.001*(i-5); + else if (i<90 && i>=45) _10RP30[i] = 0.11-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP30[44],_10RP30[85] ); + + //7G + _7G30(maxInd); + for (int i=0; i5) _7G30[i] = 2.90 + 0.0027*(i-5); + else if (i<85 && i>=45) _7G30[i] = 3.01+0.0005*(i-45); + else if (i<140 && i >=85) _7G30[i] = 3.03+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G30[44],_7G30[84],_7G30[125] ); + _7G40(maxInd); + for (int i=0; i5) _7G40[i] = 2.89 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G40[i] = 2.94+0.0015*(i-45); + else if (i<140 && i >=85) _7G40[i] = 3.0+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G40[44],_7G40[84],_7G40[125] ); + _7G50(maxInd); + for (int i=0; i5) _7G50[i] = 2.87 + 0.0015*(i-5); + else if (i<85 && i>=45) _7G50[i] = 2.93+0.00125*(i-45); + else if (i<140 && i >=85) _7G50[i] = 2.98+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G50[44],_7G50[84],_7G50[125] ); + _7G60(maxInd); + for (int i=0; i5) _7G60[i] = 2.86 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G60[i] = 2.91+0.00125*(i-45); + else if (i<140 && i >=85) _7G60[i] = 2.96+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G60[44],_7G60[84],_7G60[125] ); + _7G70(maxInd); + for (int i=0; i5) _7G70[i] = 2.85 + 0.001*(i-5); + else if (i<85 && i>=45) _7G70[i] = 2.89+0.00125*(i-45); + else if (i<140 && i >=85) _7G70[i] = 2.94+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G70[44],_7G70[84],_7G70[125] ); + _7G80(maxInd); + for (int i=0; i5) _7G80[i] = 2.84 + 0.001*(i-5); + else if (i<85 && i>=45) _7G80[i] = 2.88+0.001*(i-45); + else if (i<140 && i >=85) _7G80[i] = 2.92+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G80[44],_7G80[84],_7G80[125] ); + + + //5G + _5G30(maxInd); + for (int i=0; i5) _5G30[i] = 2.82 + 0.00175*(i-5); + else if (i<85 && i>=45) _5G30[i] = 2.89+0.0018*(i-45); + else if (i<140 && i >=85) _5G30[i] = 2.96+0.0012*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G30[44],_5G30[84],_5G30[125] ); + _5G40(maxInd); + for (int i=0; i5) _5G40[i] = 2.80 + 0.0015*(i-5); + else if (i<85 && i>=45) _5G40[i] = 2.86+0.00175*(i-45); + else if (i<140 && i >=85) _5G40[i] = 2.93+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G40[44],_5G40[84],_5G40[125] ); + _5G50(maxInd); + for (int i=0; i5) _5G50[i] = 2.79 + 0.001*(i-5); + else if (i<85 && i>=45) _5G50[i] = 2.84+0.0015*(i-45); + else if (i<140 && i >=85) _5G50[i] = 2.90+0.0015*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G50[44],_5G50[84],_5G50[125] ); + _5G60(maxInd); + for (int i=0; i5) _5G60[i] = 2.78 + 0.001*(i-5); + else if (i<85 && i>=45) _5G60[i] = 2.82+0.00175*(i-45); + else if (i<140 && i >=85) _5G60[i] = 2.89+0.001*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G60[44],_5G60[84],_5G60[125] ); + _5G70(maxInd); + for (int i=0; i5) _5G70[i] = 2.77 + 0.001*(i-5); + else if (i<85 && i>=45) _5G70[i] = 2.81+0.00125*(i-45); + else if (i<140 && i >=85) _5G70[i] = 2.86+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G70[44],_5G70[84],_5G70[125] ); + _5G80(maxInd); + for (int i=0; i5) _5G80[i] = 2.76 + 0.001*(i-5); + else if (i<85 && i>=45) _5G80[i] = 2.8+0.00125*(i-45); + else if (i<140 && i >=85) _5G80[i] = 2.85+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G80[44],_5G80[84],_5G80[125] ); + + //25G + _25G30(maxInd); + for (int i=0; i5) _25G30[i] = 2.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _25G30[i] = 2.74+0.0018*(i-45); + else if (i<140 && i >=85) _25G30[i] = 2.81+0.002*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G30[44],_25G30[84],_25G30[125] ); + _25G40(maxInd); + for (int i=0; i5) _25G40[i] = 2.68 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G40[i] = 2.71+0.0015*(i-45); + else if (i<140 && i >=85) _25G40[i] = 2.77+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G40[44],_25G40[84],_25G40[125] ); + _25G50(maxInd); + for (int i=0; i5) _25G50[i] = 2.65 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G50[i] = 2.68+0.00125*(i-45); + else if (i<140 && i >=85) _25G50[i] = 2.73+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G50[44],_25G50[84],_25G50[125] ); + _25G60(maxInd); + for (int i=0; i5) _25G60[i] = 2.64 + 0.0005*(i-5); + else if (i<85 && i>=45) _25G60[i] = 2.66+0.001*(i-45); + else if (i<140 && i >=85) _25G60[i] = 2.70+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G60[44],_25G60[84],_25G60[125] ); + _25G70(maxInd); + for (int i=0; i5) _25G70[i] = 2.64 + 0.00*(i-5); + else if (i<85 && i>=45) _25G70[i] = 2.64+0.00075*(i-45); + else if (i<140 && i >=85) _25G70[i] = 2.67+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G70[44],_25G70[84],_25G70[125] ); + _25G80(maxInd); + for (int i=0; i5) _25G80[i] = 2.63 + 0.00*(i-5); + else if (i<85 && i>=45) _25G80[i] = 2.63+0.0005*(i-45); + else if (i<140 && i >=85) _25G80[i] = 2.65+0.0005*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G80[44],_25G80[84],_25G80[125] ); + + + //1G + _1G30(maxInd); + for (int i=0; i5) _1G30[i] = 2.58 + 0.00025*(i-5); + else if (i<85 && i>=45) _1G30[i] = 2.59+0.001*(i-45); + else if (i<140 && i >=85) _1G30[i] = 2.63+0.00125*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G30[44],_1G30[84],_1G30[125] ); + _1G40(maxInd); + for (int i=0; i5) _1G40[i] = 2.56 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G40[i] = 2.55+0.0005*(i-45); + else if (i<140 && i >=85) _1G40[i] = 2.57+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G40[44],_1G40[84],_1G40[125] ); + _1G50(maxInd); + for (int i=0; i5) _1G50[i] = 2.55 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G50[i] = 2.54+0.00025*(i-45); + else if (i<140 && i >=85) _1G50[i] = 2.55+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G50[44],_1G50[84],_1G50[125] ); + _1G60(maxInd); + for (int i=0; i5) _1G60[i] = 2.54 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G60[i] = 2.52+0.00025*(i-45); + else if (i<140 && i >=85) _1G60[i] = 2.53+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G60[44],_1G60[84],_1G60[125] ); + _1G70(maxInd); + for (int i=0; i5) _1G70[i] = 2.53 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G70[i] = 2.51+0.0*(i-45); + else if (i<140 && i >=85) _1G70[i] = 2.51+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G70[44],_1G70[84],_1G70[125] ); + _1G80(maxInd); + for (int i=0; i5) _1G80[i] = 2.52 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G80[i] = 2.50+0.00*(i-45); + else if (i<140 && i >=85) _1G80[i] = 2.50+0.00*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G80[44],_1G80[84],_1G80[125] ); + + + //10GY + _10GY30(maxInd); + for (int i=0; i5) _10GY30[i] = 2.52 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY30[i] = 2.48-0.002*(i-45); + else if (i<140 && i >=85) _10GY30[i] = 2.40+0.0025*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY30[44],_10GY30[84],_10GY30[125] ); + _10GY40(maxInd); + for (int i=0; i5) _10GY40[i] = 2.48 - 0.0005*(i-5); + else if (i<85 && i>=45) _10GY40[i] = 2.46-0.0005*(i-45); + else if (i<140 && i >=85) _10GY40[i] = 2.44-0.0015*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY40[44],_10GY40[84],_10GY40[125] ); + _10GY50(maxInd); + for (int i=0; i5) _10GY50[i] = 2.48 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY50[i] = 2.45-0.00075*(i-45); + else if (i<140 && i >=85) _10GY50[i] = 2.42-0.00175*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY50[44],_10GY50[84],_10GY50[125] ); + _10GY60(maxInd); + for (int i=0; i5) _10GY60[i] = 2.47 - 0.00125*(i-5); + else if (i<85 && i>=45) _10GY60[i] = 2.42-0.00025*(i-45); + else if (i<140 && i >=85) _10GY60[i] = 2.41-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY60[44],_10GY60[84],_10GY60[125] ); + _10GY70(maxInd); + for (int i=0; i5) _10GY70[i] = 2.46 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY70[i] = 2.42+0.0*(i-45); + else if (i<140 && i >=85) _10GY70[i] = 2.42-0.001*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY70[44],_10GY70[84],_10GY70[125] ); + _10GY80(maxInd); + for (int i=0; i5) _10GY80[i] = 2.45 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY80[i] = 2.42 - 0.0005*(i-45); + else if (i<140 && i >=85) _10GY80[i] = 2.40-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY80[44],_10GY80[84],_10GY80[125] ); + + + //75GY + _75GY30(maxInd2); + for (int i=0; i5) _75GY30[i] = 2.36 - 0.0025*(i-5); + else if (i<90 && i>=45) _75GY30[i] = 2.26-0.00175*(i-45); + } + //printf("75GY %1.2f %1.2f\n",_75GY30[44],_75GY30[84] ); + _75GY40(maxInd2); + for (int i=0; i5) _75GY40[i] = 2.34 - 0.00175*(i-5); + else if (i<90 && i>=45) _75GY40[i] = 2.27-0.00225*(i-45); + } + //printf("75GY %1.2f %1.2f \n",_75GY40[44],_75GY40[84] ); + _75GY50(maxInd); + for (int i=0; i5) _75GY50[i] = 2.32 - 0.0015*(i-5); + else if (i<85 && i>=45) _75GY50[i] = 2.26-0.00175*(i-45); + else if (i<140 && i >=85) _75GY50[i] = 2.19-0.00325*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f %1.2f\n",_75GY50[44],_75GY50[84],_75GY50[125],_75GY50[139] ); + _75GY60(maxInd); + for (int i=0; i5) _75GY60[i] = 2.30 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY60[i] = 2.25-0.001*(i-45); + else if (i<140 && i >=85) _75GY60[i] = 2.21-0.0027*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY60[44],_75GY60[84],_75GY60[125] ); + _75GY70(maxInd); + for (int i=0; i5) _75GY70[i] = 2.29 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY70[i] = 2.24-0.0015*(i-45); + else if (i<140 && i >=85) _75GY70[i] = 2.18-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY70[44],_75GY70[84],_75GY70[125] ); + _75GY80(maxInd); + for (int i=0; i5) _75GY80[i] = 2.27 - 0.001*(i-5); + else if (i<85 && i>=45) _75GY80[i] = 2.23 - 0.001*(i-45); + else if (i<140 && i >=85) _75GY80[i] = 2.19-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY80[44],_75GY80[84],_75GY80[125] ); + + + //55GY + _5GY30(maxInd2); + for (int i=0; i5) _5GY30[i] = 2.16 - 0.002*(i-5); + else if (i<90 && i>=45) _5GY30[i] = 2.07-0.0025*(i-45); + } + //printf("5GY %1.2f %1.2f\n",_5GY30[44],_5GY30[84] ); + + //5GY4: 2.14,2.04, 1.96, 1.91 //95 + + _5GY40(maxInd2); + for (int i=0; i5) _5GY40[i] = 2.14 - 0.0025*(i-5); + else if (i<90 && i>=45) _5GY40[i] = 2.04-0.003*(i-45); + } + //printf("5GY %1.2f %1.2f \n",_5GY40[44],_5GY40[84] ); + _5GY50(maxInd); + for (int i=0; i5) _5GY50[i] = 2.13 - 0.00175*(i-5); + else if (i<85 && i>=45) _5GY50[i] = 2.06-0.002*(i-45); + else if (i<140 && i >=85) _5GY50[i] = 1.98-0.00225*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY50[44],_5GY50[84],_5GY50[125] ); + _5GY60(maxInd); + for (int i=0; i5) _5GY60[i] = 2.11 - 0.0015*(i-5); + else if (i<85 && i>=45) _5GY60[i] = 2.05-0.002*(i-45); + else if (i<140 && i >=85) _5GY60[i] = 1.97-0.00275*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY60[44],_5GY60[84],_5GY60[125] ); + _5GY70(maxInd); + for (int i=0; i5) _5GY70[i] = 2.09 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY70[i] = 2.05-0.00175*(i-45); + else if (i<140 && i >=85) _5GY70[i] = 1.98-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY70[44],_5GY70[84],_5GY70[125] ); + _5GY80(maxInd); + for (int i=0; i5) _5GY80[i] = 2.07 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY80[i] = 2.03 - 0.00075*(i-45); + else if (i<140 && i >=85) _5GY80[i] = 2.0-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY80[44],_5GY80[84],_5GY80[125] ); + + #ifdef _DEBUG + t2e.set(); + if (settings->verbose) + printf("Lutf Munsell %d usec\n", t2e.etime(t1e)); + #endif + } + } diff --git a/rtengine/color.h b/rtengine/color.h index 7b6a3b57a..08e547797 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -22,26 +22,82 @@ #include #include "LUT.h" +#include "labimage.h" +#include "iccstore.h" namespace rtengine { +#ifdef _DEBUG + +class MunsellDebugInfo { +public: + float maxdhuelum[4]; + float maxdhue[4]; + unsigned int depass; + unsigned int depassLum; + + MunsellDebugInfo(); + void reinitValues(); +}; + +#endif + class Color { +private: + // Jacques' 195 LUTf for Munsell Lch correction + static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60; + static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60; + static LUTf _5B40,_5B50,_5B60, _5B70,_5B80; + static LUTf _7B40,_7B50,_7B60, _7B70,_7B80; + static LUTf _9B40,_9B50,_9B60, _9B70,_9B80; + static LUTf _10B40,_10B50,_10B60, _10B70,_10B80; + static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80; + static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60; + static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80; + static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80; + static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80; + static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80; + static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80; + static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80; + static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90; + static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90; + static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80; + static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90; + static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80; + static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70; + static LUTf _10R30, _10R40,_10R50,_10R60,_10R70; + static LUTf _9R30, _9R40,_9R50,_9R60,_9R70; + static LUTf _7R30, _7R40,_7R50,_7R60,_7R70; + static LUTf _5R10, _5R20,_5R30; + static LUTf _25R10, _25R20,_25R30; + static LUTf _10RP10, _10RP20,_10RP30; + static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80; + static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80; + static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80; + static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80; + static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80; + static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80; + static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80; + + // Separated from init() to keep the code clear + static void initMunsell (); + public: const static double sRGBGamma; // standard average gamma - const static double sRGBGammaCurve; // 2.4 in the curve - const static double eps_max, kappa; - const static float D50x, D50z; - const static double u0, v0; + const static double sRGBGammaCurve; // 2.4 in the curve + const static double eps_max, kappa; + const static float D50x, D50z; + const static double u0, v0; - static LUTf cachef; + static LUTf cachef; static LUTf gamma2curve; - // look-up tables for the standard srgb gamma and its inverse (filled by init()) - static LUTf igammatab_srgb; - static LUTf gammatab_srgb; - // look-up tables for the simple exponential gamma - static LUTf gammatab; + // look-up tables for the standard srgb gamma and its inverse (filled by init()) + static LUTf igammatab_srgb; + static LUTf gammatab_srgb; + // look-up tables for the simple exponential gamma + static LUTf gammatab; static void init (); @@ -50,10 +106,10 @@ public: static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); static void hsv2rgb (float h, float s, float v, float &r, float &g, float &b); static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); - static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b); + static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b); static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b); static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, double rgb_xyz[3][3]); - static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, float rgb_xyz[3][3]); static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); static void XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b); static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v); @@ -87,6 +143,20 @@ public: //static inline float gamma (double x) { return gammatab[x]; } //static inline float igamma_srgb (double x) { return igammatab_srgb[x]; } + //Jacques's Munsell correction +#ifdef _DEBUG + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo); + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb); +#else + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum); + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef); +#endif + static void LabGamutMunsell (LabImage *lab, float *Lold, float *Cold, bool corMunsell, bool lumaMuns, bool isHLEnabled, bool gamut, const Glib::ustring &working, bool multiThread ); + + static void SkinSat (float lum, float hue, float chrom, float &satreduc, int chromx);//jacques Skin color + static void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL);//jacques: Munsell correction + // end Munsell + //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 0e6d4bc4e..747aa107d 100644 --- a/rtengine/colortemp.cc +++ b/rtengine/colortemp.cc @@ -554,11 +554,13 @@ void ColorTemp::temp2mul (double temp, double green, double& rmul, double& gmul, xD=x; yD=y; + /* if (settings->verbose) { double u=4*xD/(-2*xD+12*yD+3); double v=6*yD/(-2*xD+12*yD+3); printf("xD=%f yD=%f u=%f v=%f\n",xD,yD,u,v); } + */ double X = xD/yD; double Y = 1.0; diff --git a/rtengine/curves.cc b/rtengine/curves.cc index e6ef98cf6..62ac0e568 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -154,9 +154,9 @@ namespace rtengine { } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - void CurveFactory::complexsgnCurve (double saturation, bool satlimit, double satlimthresh, - const std::vector& acurvePoints, const std::vector& bcurvePoints, - LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip) { + void CurveFactory::complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, double saturation, double rstprotection, + const std::vector& acurvePoints, const std::vector& bcurvePoints,const std::vector& cccurvePoints, + /*const std::vector& cbgcurvePoints,*/ LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve,/* LUTf & satbgCurve,*/ int skip) { //colormult = chroma_scale for Lab manipulations @@ -164,7 +164,7 @@ namespace rtengine { bool needed; DiagonalCurve* dCurve = NULL; - +/* // check if contrast curve is needed needed = (saturation<-0.0001 || saturation>0.0001); @@ -194,13 +194,15 @@ namespace rtengine { satcurvePoints.push_back(0.5+0.5*scale); //shoulder point satcurvePoints.push_back(0.5+0.5*scale); //value at shoulder point - /*} else { - satcurvePoints.push_back(0.25+saturation/500.0); //toe point - satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point + / Commented out... + } else { + satcurvePoints.push_back(0.25+saturation/500.0); //toe point + satcurvePoints.push_back(0.25-saturation/500.0); //value at toe point - satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point - satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point - }*/ + satcurvePoints.push_back(0.75-saturation/500.0); //shoulder point + satcurvePoints.push_back(0.75+saturation/500.0); //value at shoulder point + } + / satcurvePoints.push_back(1); // white point satcurvePoints.push_back(1); // value at white point @@ -222,17 +224,21 @@ namespace rtengine { else { fillCurveArray(NULL, satCurve, skip, needed); } - +*/ //----------------------------------------------------- needed = false; // create a curve if needed if (!acurvePoints.empty() && acurvePoints[0]!=0) { dCurve = new DiagonalCurve (acurvePoints, CURVES_MIN_POLY_POINTS/skip); - if (dCurve && !dCurve->isIdentity()) + if (dCurve && !dCurve->isIdentity()) { needed = true; + autili=true; + } } fillCurveArray(dCurve, aoutCurve, skip, needed); + //if(autili) aoutCurve.dump("acurve"); + if (dCurve) { delete dCurve; dCurve = NULL; @@ -243,14 +249,43 @@ namespace rtengine { needed = false; if (!bcurvePoints.empty() && bcurvePoints[0]!=0) { dCurve = new DiagonalCurve (bcurvePoints, CURVES_MIN_POLY_POINTS/skip); - if (dCurve && !dCurve->isIdentity()) + if (dCurve && !dCurve->isIdentity()) { needed = true; + butili=true; + } } fillCurveArray(dCurve, boutCurve, skip, needed); if (dCurve) { delete dCurve; dCurve = NULL; } + + //----------------------------------------------- + needed = false; + if (!cccurvePoints.empty() && cccurvePoints[0]!=0) { + dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (dCurve && !dCurve->isIdentity()) + {needed = true;ccutili=true;} + } + fillCurveArray(dCurve, satCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + //---------------------------- + /*needed = false; + if (!cbgcurvePoints.empty() && cbgcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (cbgcurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (dCurve && !dCurve->isIdentity()) + {needed = true;cbgutili=true;} + } + fillCurveArray(dCurve, satbgCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + */ + } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -489,7 +524,7 @@ namespace rtengine { void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, - LUTu & outBeforeCCurveHistogram, int skip) { + LUTu & outBeforeCCurveHistogram, int skip, bool & utili) { // curve without contrast LUTf dcurve(65536,0); @@ -504,6 +539,7 @@ namespace rtengine { // check if brightness curve is needed if (br>0.00001 || br<-0.00001) { + utili=true; std::vector brightcurvePoints; brightcurvePoints.push_back((double)((CurveType)DCT_NURBS)); @@ -550,13 +586,13 @@ namespace rtengine { dcurve[i] = (float)i / 32767.0; } } - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // check if contrast curve is needed if (contr>0.00001 || contr<-0.00001) { + utili=true; // compute mean luminance of the image with the curve applied int sum = 0; @@ -613,6 +649,8 @@ namespace rtengine { } if (tcurve) { + utili=true;//if active + // L values go up to 32767, last stop is for highlight overflow for (int i=0; i<32768; i++) { float val; diff --git a/rtengine/curves.h b/rtengine/curves.h index 5d27da3f2..c165e7288 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -178,11 +178,12 @@ class CurveFactory { static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, double gamma_, bool igamma_, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip=1); - static void complexsgnCurve (double saturation, bool satlimit, double satlimthresh, const std::vector& acurvePoints, - const std::vector& bcurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, int skip=1); + static void complexsgnCurve ( bool & autili, bool & butili, bool & ccutili, double saturation, double rstprotection, const std::vector& acurvePoints, + const std::vector& bcurvePoints,const std::vector& cccurvePoints,/*const std::vector& cbgurvePoints,*/ LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, /*LUTf & satbgCurve,*/ int skip=1); static void complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, - LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip); + LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); static void RGBCurve (const std::vector& curvePoints, LUTf & outCurve, int skip); + }; class Curve { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 6b52463e3..04b02fcdb 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -166,8 +166,13 @@ void Crop::update (int todo) { parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay. - parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve); - parent->ipf.chrominanceCurve (labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve); + // parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve); + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + + parent->ipf.chromiLuminanceCurve (labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve,/*parent->satbgcurve,*/ parent->lumacurve, utili, autili, butili, ccutili); //parent->ipf.colorCurve (labnCrop, labnCrop); parent->ipf.vibrance (labnCrop); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 0d5c9901e..361c3aecc 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -41,6 +41,7 @@ ImProcCoordinator::ImProcCoordinator () chroma_acurve(65536,0); chroma_bcurve(65536,0); satcurve(65536,0); +// satbgcurve(65536,0); vhist16(65536); lhist16(65536); lhist16Cropped(65536); @@ -264,16 +265,19 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { } readyphase++; - + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + if ((todo & M_LUMACURVE) || todo==CROP) { - CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, lhist16, lhist16Cropped, - lumacurve, histLCurve, scale==1 ? 1 : 16); + lumacurve, histLCurve, scale==1 ? 1 : 16, utili); } if (todo & M_LUMACURVE) { - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, - params.labCurve.acurve, params.labCurve.bcurve, chroma_acurve, chroma_bcurve, satcurve, scale==1 ? 1 : 16); + CurveFactory::complexsgnCurve (autili, butili,ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve/*,params.labCurve.cbgcurve*/, chroma_acurve, chroma_bcurve, satcurve,/*satbgcurve,*/ scale==1 ? 1 : 16); } if (todo & (M_LUMINANCE+M_COLOR) ) { @@ -281,13 +285,13 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { ipf.EPDToneMap(nprevl,0,scale); - progress ("Applying Luminance Curve...",100*readyphase/numofphases); + //progress ("Applying Luminance Curve...",100*readyphase/numofphases); - ipf.luminanceCurve (nprevl, nprevl, lumacurve); + //ipf.luminanceCurve (nprevl, nprevl, lumacurve); - readyphase++; + //readyphase++; progress ("Applying Color Boost...",100*readyphase/numofphases); - ipf.chrominanceCurve (nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*, params.labCurve.saturation*/); + ipf.chromiLuminanceCurve (nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve/*,satbgcurve*/, lumacurve, utili, autili, butili, ccutili); //ipf.colorCurve (nprevl, nprevl); ipf.vibrance(nprevl); readyphase++; diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 872f27b6d..aca603c24 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -73,6 +73,7 @@ class ImProcCoordinator : public StagedImageProcessor { LUTf chroma_acurve; LUTf chroma_bcurve; LUTf satcurve; + // LUTf satbgcurve; LUTf rCurve; LUTf gCurve; diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 9e4dc8d91..283fca526 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -441,64 +441,307 @@ void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & cur lnew->L[i][j] = curve[Lin]; } } - - -void ImProcFunctions::chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve) { + +void ImProcFunctions::chromiLuminanceCurve (LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve/*,LUTf & satbgcurve*/, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili) { int W = lold->W; int H = lold->H; + //init Flatcurve for C=f(H) + FlatCurve* chCurve = NULL; + bool chutili = false; + if (!params->labCurve.bwtoning) { + chCurve = new FlatCurve(params->labCurve.chcurve); + if (chCurve && !chCurve->isIdentity()) { + chutili=true; + }//do not use "Munsell" if Chcurve not used + } +#ifdef _DEBUG + MyTime t1e,t2e, t3e, t4e; + t1e.set(); + // init variables to display Munsell corrections + MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); +#endif + + unsigned int N = W*H; + float *L = lold->L[0]; + float *a= lold->a[0]; + float *b= lold->b[0]; + + float* Lold = new float [lold->W*lold->H];//to save L before any used + float* Cold = new float [lold->W*lold->H];//to save C before any used + float adjustr=1.0f, adjustbg=1.0f; + +// if(params->labCurve.avoidclip ){ + for (unsigned int j=0; j!=N; j++){ + Lold[j]=L[j]/327.68f; + Cold[j]=sqrt(SQR(a[j]/327.68f)+SQR(b[j]/327.68f)); +// Hr=atan2(b[j],a[j]); +// if(Hr >-0.15f && Hr < 1.5f && Cold[j]>maxCr) +// maxCr=Cold[j]; // I do not take into account "acurve" and "bcurve" to adjust max +// else if (Cold[j]>maxCbg) +// maxCbg=Cold[j]; + } + // parameter to adapt curve C=f(C) to gamut + if (params->icm.working=="ProPhoto") {adjustr = adjustbg = 1.2f;}// 1.2 instead 1.0 because it's very rare to have C>170.. + else if (params->icm.working=="Adobe RGB") {adjustr = 1.8f; adjustbg = 1.4f;} + else if (params->icm.working=="sRGB") {adjustr = 2.0f; adjustbg = 1.7f;} + else if (params->icm.working=="WideGamut") {adjustr = adjustbg = 1.2f;} + else if (params->icm.working=="Beta RGB") {adjustr = adjustbg = 1.4f;} + else if (params->icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;} + else if (params->icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;} + + + // reference to the params structure has to be done outside of the parallelization to avoid CPU cache problem + bool highlight = params->hlrecovery.enabled; //Get the value if "highlight reconstruction" is activated + int chromaticity = params->labCurve.chromaticity; + bool bwToning = params->labCurve.bwtoning; + double rstprotection = 100.-params->labCurve.rstprotection; // Red and Skin Tones Protection + // avoid color shift is disabled when bwToning is activated + bool avoidColorShift = params->labCurve.avoidcolorshift && !bwToning; + int protectRed = settings->protectred; + double protectRedH = settings->protectredh; + bool gamutLch = settings->gamutLch; + + // only if user activate Lab adjustements + if (avoidColorShift) { + if(autili || butili || ccutili || chutili || utili || chromaticity) + Color::LabGamutMunsell(lold, Lold, Cold, /*corMunsell*/true, /*lumaMuns*/false, params->hlrecovery.enabled, /*gamut*/true, params->icm.working, multiThread); + } + + +#ifdef _DEBUG +#pragma omp parallel default(shared) firstprivate(highlight, chromaticity, bwToning, rstprotection, avoidColorShift, protectRed, protectRedH, gamutLch, lold, lnew, MunsDebugInfo) if (multiThread) +#else +#pragma omp parallel default(shared) firstprivate(highlight, chromaticity, bwToning, rstprotection, avoidColorShift, protectRed, protectRedH, gamutLch, lold, lnew) if (multiThread) +#endif +{ + + 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]} + }; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); - + //if(utili) curve.dump("Lcurve"); + double wp[3][3] = { {wprof[0][0],wprof[0][1],wprof[0][2]}, {wprof[1][0],wprof[1][1],wprof[1][2]}, {wprof[2][0],wprof[2][1],wprof[2][2]}}; - -#pragma omp parallel for if (multiThread) - for (int i=0; ia[i][j]+32768.0f]-32768.0f; - float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f; - + + //float maxlp=-100.0, minlp=200.0; + +#pragma omp for schedule(dynamic, 10) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lold->a[i][j]/327.68f) + SQR(lold->b[i][j]/327.68f)); + float HH=atan2(lold->b[i][j],lold->a[i][j]); + float Chprov=CC; + float Chprov1=CC; + float memChprov=Chprov; + float Lprov2=LL; + float Lin=lold->L[i][j]; + lnew->L[i][j] = curve[Lin]; + float Lprov1=(lnew->L[i][j])/327.68f; + float chromaChfactor=1.0f; + float atmp = acurve[lold->a[i][j]+32768.0f]-32768.0f;// curves Lab a + float btmp = bcurve[lold->b[i][j]+32768.0f]-32768.0f;// curves Lab b + //float chromaCredfactor=1.0f; + //float chromaCbgfactor=1.0f; +// chromaCfactor=(satcurve[chroma*adjustr])/(chroma*adjustr);//apply C=f(C) +// chromaCbgfactor=(satbgcurve[chroma*adjustbg])/(chroma*adjustbg); +// calculate C=f(H) + if (chutili) { + double hr; + //hr=translate Hue Lab value (-Pi +Pi) in approximative hr (hsv values) (0 1) [red 1/6 yellow 1/6 green 1/6 cyan 1/6 blue 1/6 magenta 1/6 ] + // with multi linear correspondances (I expect there is no error !!) + if (HH<-2.7f) hr=0.020380804*double(HH)+0.970281708; //Lab green =>hr # 0.33 ==> 0.33 0.42 + else if (HH<-2.1f) hr=0.266666667*double(HH)+1.14; //Lab cyan =>hr # 0.50 ==> 0.42 0.58 + else if (HH<-0.9f) hr=0.141666 *double(HH)+0.8775; //Lab blue =>hr # 0.67 ==> 0.58 0.75 + else if (HH<-0.1f) hr=0.2125 *double(HH)+0.94125; //Lab magenta (purple) =>hr # 0.83 ==> 0.75 0.92 + else if (HH< 1.3f) hr=0.12142857 *double(HH)+0.932142857; //Lab red and skin =>hr # 0 ==> 0.92 1.09 + else if (HH< 2.2f) hr=0.1666667 *double(HH)-0.1266667; //Lab yellow and green yellow =>hr # 0.16 ==> 0.09 0.24 + else hr=0.0955828 *double(HH)+0.02971784; //Lab green =>hr # 0.33 ==> 0.24 0.33 + + //allways put h between 0 and 1 + if (hr<0.0) hr += 1.0; + else if(hr>1.0) hr -= 1.0; + float chparam = float((chCurve->getVal(hr)-0.5f) * 2.0f);//get C=f(H) + chromaChfactor=1.0f+chparam; + } + atmp *= chromaChfactor;//apply C=f(H) + btmp *= chromaChfactor; +// if (params->labCurve.chromaticity) {// if user use sliders + if(chromaticity!=0 && !bwToning){ + // approximation in Lab mode to protect skin tones and avoid too big gamut clip for red + float scale = 100.0f/100.1f;//reduction in normal zone + float scaleext=1.0f;//reduction in transition zone + float protect_red,protect_redh; + float deltaHH;//HH value transition + float dred=55.0f;//C red value limit + protect_red=float(protectRed);//default=60 chroma: one can put more or less if necessary...in 'option' 40...160 + if(protect_red < 20.0f) protect_red=20.0; // avoid too low value + if(protect_red > 180.0f) protect_red=180.0; // avoid too high value + protect_redh=float(protectRedH);//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1.0 + if(protect_redh<0.1f) protect_redh=0.1f;//avoid divide by 0 and negatives values + if(protect_redh>1.0f) protect_redh=1.0f;//avoid too big values + + deltaHH=protect_redh;//transition hue + + //simulate very approximative gamut f(L) : with pyramid transition + if (Lprov1<25.0f) dred = 40.0f; + else if(Lprov1<30.0f) dred = 3.0f*Lprov1 -35.0f; + else if(Lprov1<70.0f) dred = 55.0f; + else if(Lprov1<75.0f) dred = -3.0f*Lprov1 +265.0f; + else dred = 40.0f; + + if(rstprotection<99.9999) { + if(chromaticity>0) + scale = rstprotection/100.1f; + if((HH< (1.3f+deltaHH) && HH >=1.3f)) + scaleext=HH*(1.0f-scale)/deltaHH + 1.0f - (1.3f+deltaHH)*(1.0f-scale)/deltaHH; //transition for Hue (red - yellow) + else if((HH< 0.15f && HH >(0.15f-deltaHH))) + scaleext=HH*(scale-1.0f)/deltaHH + 1.0f - (0.15f-deltaHH)*(scale-1.0f)/deltaHH; //transition for hue (red purple) + } + + //transition for red , near skin tones + float factorskin, factorsat, factor, factorskinext; + factorskin=1.0f+(chromaticity*scale)/100.0f; + factorskinext=1.0f+(chromaticity*scaleext)/100.0f; + factorsat=1.0f+(chromaticity)/100.0f;/*if(factorsat==1.0f) factorsat=1.1f;*/ + + factor = factorsat; + // Test if chroma is in the normal range first + if(HH>=0.15f && HH<1.3f) { + if (Chprov1(0.15f-deltaHH) || HH<(1.3f+deltaHH) ) { + if (Chprov1 < dred) + factor = factorskinext;// C=dred=55 => real max of skin tones + else if (Chprov1 < (dred+protect_red))// transition + factor = (factorsat-factorskinext)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskinext)/protect_red; + } + + atmp *= factor; + btmp *= factor; + // end approximation + } + + // I have placed C=f(C) after all C treatments to assure maximum amplitude of "C" + if (!bwToning) { + float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001f); + float chromaCfactor = (satcurve[chroma*adjustr])/(chroma*adjustr);//apply C=f(C) + atmp *= chromaCfactor; + btmp *= chromaCfactor; + } + // end chroma C=f(C) + + Chprov1 = sqrt(SQR(atmp/327.68f)+SQR(btmp/327.68f)); + +/* // modulation of a and b curves with saturation - if (params->labCurve.saturation!=0 && !params->labCurve.bwtoning) { + if (params->labCurve.chromaticity!=0 && !params->labCurve.bwtoning) { float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001); float satfactor = (satcurve[chroma+32768.0f]-32768.0f)/chroma; atmp *= satfactor; btmp *= satfactor; } +*/ // labCurve.bwtoning option allows to decouple modulation of a & b curves by saturation // with bwtoning enabled the net effect of a & b curves is visible - if (params->labCurve.bwtoning) { + if (bwToning) { atmp -= lold->a[i][j]; btmp -= lold->b[i][j]; } - - if (params->labCurve.avoidclip) { - //Luv limiter - float Y,u,v; - Color::Lab2Yuv(lnew->L[i][j],atmp,btmp,Y,u,v); - //Yuv2Lab includes gamut restriction map - Color::Yuv2Lab(Y,u,v,lnew->L[i][j],lnew->a[i][j],lnew->b[i][j], wp); - - } else { + + if (avoidColorShift) { + //gamutmap Lch ==> preserve Hue,but a little slower than gamutbdy for high values...and little faster for low values + if(gamutLch) { + float R,G,B; + +#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.4f, 0.95f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.4f, 0.95f); +#endif + Lprov2 = Lprov1; + + lnew->L[i][j]=Lprov1*327.68f; + lnew->a[i][j]=327.68f*Chprov1*cos(HH); + lnew->b[i][j]=327.68f*Chprov1*sin(HH); + } + else { + //use gamutbdy + //Luv limiter + float Y,u,v; + Color::Lab2Yuv(lnew->L[i][j],atmp,btmp,Y,u,v); + //Yuv2Lab includes gamut restriction map + Color::Yuv2Lab(Y,u,v,lnew->L[i][j],lnew->a[i][j],lnew->b[i][j], wp); + } + + if (utili || autili || butili || ccutili || chutili || chromaticity) { + float correctionHue=0.0f; // Munsell's correction + float correctlum=0.0f; + + Lprov1=lnew->L[i][j]/327.68f; + Chprov=sqrt(SQR(lnew->a[i][j]/327.68f)+ SQR(lnew->b[i][j]/327.68f)); + +#ifdef _DEBUG + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum); +#endif + + if(fabs(correctionHue) < 0.015f) HH+=correctlum; // correct only if correct Munsell chroma very little. + + lnew->a[i][j]=327.68f*Chprov*cos(HH+correctionHue);// apply Munsell + lnew->b[i][j]=327.68f*Chprov*sin(HH+correctionHue); + } + } + else { +// if(Lprov1 > maxlp) maxlp=Lprov1; +// if(Lprov1 < minlp) minlp=Lprov1; + lnew->L[i][j]=Lprov1*327.68f; + //Luv limiter only lnew->a[i][j] = atmp; lnew->b[i][j] = btmp; } + } +} // end of parallelization - } - - //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - +#ifdef _DEBUG + if (settings->verbose) { + t3e.set(); + printf("Color::AllMunsellLch (correction performed in %d usec):\n", t3e.etime(t1e)); + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); + printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); } - + delete MunsDebugInfo; +#endif + delete [] Lold; + delete [] Cold; + + if (chutili) delete chCurve; +} + //#include "cubic.cc" @@ -933,4 +1176,4 @@ fclose(f);*/ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -} \ No newline at end of file +} diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index f3a039f41..ed902f4f4 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -66,46 +66,11 @@ class ImProcFunctions { public: static LUTf cachef; - // 195 LUTf for Munsell Lch correction - static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60; - static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60; - static LUTf _5B40,_5B50,_5B60, _5B70,_5B80; - static LUTf _7B40,_7B50,_7B60, _7B70,_7B80; - static LUTf _9B40,_9B50,_9B60, _9B70,_9B80; - static LUTf _10B40,_10B50,_10B60, _10B70,_10B80; - static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80; - static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60; - static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80; - static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80; - static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80; - static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80; - static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80; - static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80; - static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90; - static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90; - static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80; - static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90; - static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80; - static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70; - static LUTf _10R30, _10R40,_10R50,_10R60,_10R70; - static LUTf _9R30, _9R40,_9R50,_9R60,_9R70; - static LUTf _7R30, _7R40,_7R50,_7R60,_7R70; - static LUTf _5R10, _5R20,_5R30; - static LUTf _25R10, _25R20,_25R30; - static LUTf _10RP10, _10RP20,_10RP30; - static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80; - static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80; - static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80; - static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80; - static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80; - static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80; - static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80; double lumimul[3]; static void initCache (); static void cleanupCache (); - static void initMunsell (); ImProcFunctions (const ProcParams* iparams, bool imultiThread=true) : monitorTransform(NULL), params(iparams), scale(1), multiThread(imultiThread) {} @@ -122,10 +87,8 @@ class ImProcFunctions { SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, double expcomp, int hlcompr, int hlcomprthresh); void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); - void chrominanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve); + void chromiLuminanceCurve (LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve/*,LUTf & satbgcurve*/, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili); void vibrance (LabImage* lab);//Jacques' vibrance - void skinsat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color - void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone);//jacques: Munsell correction void colorCurve (LabImage* lold, LabImage* lnew); void sharpening (LabImage* lab, float** buffer); void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, diff --git a/rtengine/init.cc b/rtengine/init.cc index 81b422257..b5e79092a 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -43,7 +43,6 @@ int init (const Settings* s, Glib::ustring baseDir) { profileStore.init (); ProcParams::init (); Color::init(); - ImProcFunctions::initMunsell(); ImProcFunctions::initCache (); Thumbnail::initGamma (); delete lcmsMutex; diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc index af06a172a..e37f6753e 100644 --- a/rtengine/ipvibrance.cc +++ b/rtengine/ipvibrance.cc @@ -19,13 +19,15 @@ */ #include "rt_math.h" +//#include #include "rtengine.h" #include "improcfun.h" #include "iccstore.h" #include "mytime.h" -#include "rt_math.h" #include "../rtgui/thresholdselector.h" +#include "curves.h" +//#include "calc_distort.h" #ifdef _OPENMP #include @@ -41,1969 +43,92 @@ using namespace procparams; extern const Settings* settings; -//Munsell Lch LUTf : 195 LUT -LUTf ImProcFunctions::_4P10 ;//give hue in function of L and C : Munsell correction -LUTf ImProcFunctions::_4P20 ; -LUTf ImProcFunctions::_4P30 ; -LUTf ImProcFunctions::_4P40 ; -LUTf ImProcFunctions::_4P50 ; -LUTf ImProcFunctions::_4P60 ; - - -LUTf ImProcFunctions::_1P10 ; -LUTf ImProcFunctions::_1P20 ; -LUTf ImProcFunctions::_1P30 ; -LUTf ImProcFunctions::_1P40 ; -LUTf ImProcFunctions::_1P50 ; -LUTf ImProcFunctions::_1P60 ; - - -LUTf ImProcFunctions::_10PB10 ; -LUTf ImProcFunctions::_10PB20 ; -LUTf ImProcFunctions::_10PB30 ; -LUTf ImProcFunctions::_10PB40 ; -LUTf ImProcFunctions::_10PB50 ; -LUTf ImProcFunctions::_10PB60 ; - - -LUTf ImProcFunctions::_9PB10 ; -LUTf ImProcFunctions::_9PB20 ; -LUTf ImProcFunctions::_9PB30 ; -LUTf ImProcFunctions::_9PB40 ; -LUTf ImProcFunctions::_9PB50 ; -LUTf ImProcFunctions::_9PB60 ; -LUTf ImProcFunctions::_9PB70 ; -LUTf ImProcFunctions::_9PB80 ; - -LUTf ImProcFunctions::_75PB10 ; -LUTf ImProcFunctions::_75PB20 ; -LUTf ImProcFunctions::_75PB30 ; -LUTf ImProcFunctions::_75PB40 ; -LUTf ImProcFunctions::_75PB50 ; -LUTf ImProcFunctions::_75PB60 ; -LUTf ImProcFunctions::_75PB70 ; -LUTf ImProcFunctions::_75PB80 ; - -LUTf ImProcFunctions::_6PB10 ; -LUTf ImProcFunctions::_6PB20 ; -LUTf ImProcFunctions::_6PB30 ; -LUTf ImProcFunctions::_6PB40 ; -LUTf ImProcFunctions::_6PB50 ; -LUTf ImProcFunctions::_6PB60 ; -LUTf ImProcFunctions::_6PB70 ; -LUTf ImProcFunctions::_6PB80 ; - -LUTf ImProcFunctions::_45PB10 ; -LUTf ImProcFunctions::_45PB20 ; -LUTf ImProcFunctions::_45PB30 ; -LUTf ImProcFunctions::_45PB40 ; -LUTf ImProcFunctions::_45PB50 ; -LUTf ImProcFunctions::_45PB60 ; -LUTf ImProcFunctions::_45PB70 ; -LUTf ImProcFunctions::_45PB80 ; - -LUTf ImProcFunctions::_3PB10 ; -LUTf ImProcFunctions::_3PB20 ; -LUTf ImProcFunctions::_3PB30 ; -LUTf ImProcFunctions::_3PB40 ; -LUTf ImProcFunctions::_3PB50 ; -LUTf ImProcFunctions::_3PB60 ; -LUTf ImProcFunctions::_3PB70 ; -LUTf ImProcFunctions::_3PB80 ; - -LUTf ImProcFunctions::_15PB10 ; -LUTf ImProcFunctions::_15PB20 ; -LUTf ImProcFunctions::_15PB30 ; -LUTf ImProcFunctions::_15PB40 ; -LUTf ImProcFunctions::_15PB50 ; -LUTf ImProcFunctions::_15PB60 ; -LUTf ImProcFunctions::_15PB70 ; -LUTf ImProcFunctions::_15PB80 ; - -LUTf ImProcFunctions::_05PB40 ; -LUTf ImProcFunctions::_05PB50 ; -LUTf ImProcFunctions::_05PB60 ; -LUTf ImProcFunctions::_05PB70 ; -LUTf ImProcFunctions::_05PB80 ; - -LUTf ImProcFunctions::_10B40 ; -LUTf ImProcFunctions::_10B50 ; -LUTf ImProcFunctions::_10B60 ; -LUTf ImProcFunctions::_10B70 ; -LUTf ImProcFunctions::_10B80 ; - -LUTf ImProcFunctions::_9B40 ; -LUTf ImProcFunctions::_9B50 ; -LUTf ImProcFunctions::_9B60 ; -LUTf ImProcFunctions::_9B70 ; -LUTf ImProcFunctions::_9B80 ; - -LUTf ImProcFunctions::_7B40 ; -LUTf ImProcFunctions::_7B50 ; -LUTf ImProcFunctions::_7B60 ; -LUTf ImProcFunctions::_7B70 ; -LUTf ImProcFunctions::_7B80 ; - -LUTf ImProcFunctions::_5B40 ; -LUTf ImProcFunctions::_5B50 ; -LUTf ImProcFunctions::_5B60 ; -LUTf ImProcFunctions::_5B70 ; -LUTf ImProcFunctions::_5B80 ; - -LUTf ImProcFunctions::_10YR20; -LUTf ImProcFunctions::_10YR30; -LUTf ImProcFunctions::_10YR40; -LUTf ImProcFunctions::_10YR50; -LUTf ImProcFunctions::_10YR60; -LUTf ImProcFunctions::_10YR70; -LUTf ImProcFunctions::_10YR80; -LUTf ImProcFunctions::_10YR90; - -LUTf ImProcFunctions::_85YR20; -LUTf ImProcFunctions::_85YR30; -LUTf ImProcFunctions::_85YR40; -LUTf ImProcFunctions::_85YR50; -LUTf ImProcFunctions::_85YR60; -LUTf ImProcFunctions::_85YR70; -LUTf ImProcFunctions::_85YR80; -LUTf ImProcFunctions::_85YR90; - -LUTf ImProcFunctions::_7YR30; -LUTf ImProcFunctions::_7YR40; -LUTf ImProcFunctions::_7YR50; -LUTf ImProcFunctions::_7YR60; -LUTf ImProcFunctions::_7YR70; -LUTf ImProcFunctions::_7YR80; - -LUTf ImProcFunctions::_55YR30; -LUTf ImProcFunctions::_55YR40; -LUTf ImProcFunctions::_55YR50; -LUTf ImProcFunctions::_55YR60; -LUTf ImProcFunctions::_55YR70; -LUTf ImProcFunctions::_55YR80; -LUTf ImProcFunctions::_55YR90; - -LUTf ImProcFunctions::_4YR30; -LUTf ImProcFunctions::_4YR40; -LUTf ImProcFunctions::_4YR50; -LUTf ImProcFunctions::_4YR60; -LUTf ImProcFunctions::_4YR70; -LUTf ImProcFunctions::_4YR80; - -LUTf ImProcFunctions::_25YR30; -LUTf ImProcFunctions::_25YR40; -LUTf ImProcFunctions::_25YR50; -LUTf ImProcFunctions::_25YR60; -LUTf ImProcFunctions::_25YR70; - -LUTf ImProcFunctions::_10R30; -LUTf ImProcFunctions::_10R40; -LUTf ImProcFunctions::_10R50; -LUTf ImProcFunctions::_10R60; -LUTf ImProcFunctions::_10R70; - -LUTf ImProcFunctions::_9R30; -LUTf ImProcFunctions::_9R40; -LUTf ImProcFunctions::_9R50; -LUTf ImProcFunctions::_9R60; -LUTf ImProcFunctions::_9R70; - -LUTf ImProcFunctions::_7R30; -LUTf ImProcFunctions::_7R40; -LUTf ImProcFunctions::_7R50; -LUTf ImProcFunctions::_7R60; -LUTf ImProcFunctions::_7R70; - -LUTf ImProcFunctions::_5R10; -LUTf ImProcFunctions::_5R20; -LUTf ImProcFunctions::_5R30; - -LUTf ImProcFunctions::_25R10; -LUTf ImProcFunctions::_25R20; -LUTf ImProcFunctions::_25R30; - -LUTf ImProcFunctions::_10RP10; -LUTf ImProcFunctions::_10RP20; -LUTf ImProcFunctions::_10RP30; - -LUTf ImProcFunctions::_7G30; -LUTf ImProcFunctions::_7G40; -LUTf ImProcFunctions::_7G50; -LUTf ImProcFunctions::_7G60; -LUTf ImProcFunctions::_7G70; -LUTf ImProcFunctions::_7G80; - -LUTf ImProcFunctions::_5G30; -LUTf ImProcFunctions::_5G40; -LUTf ImProcFunctions::_5G50; -LUTf ImProcFunctions::_5G60; -LUTf ImProcFunctions::_5G70; -LUTf ImProcFunctions::_5G80; - -LUTf ImProcFunctions::_25G30; -LUTf ImProcFunctions::_25G40; -LUTf ImProcFunctions::_25G50; -LUTf ImProcFunctions::_25G60; -LUTf ImProcFunctions::_25G70; -LUTf ImProcFunctions::_25G80; - -LUTf ImProcFunctions::_1G30; -LUTf ImProcFunctions::_1G40; -LUTf ImProcFunctions::_1G50; -LUTf ImProcFunctions::_1G60; -LUTf ImProcFunctions::_1G70; -LUTf ImProcFunctions::_1G80; - -LUTf ImProcFunctions::_10GY30; -LUTf ImProcFunctions::_10GY40; -LUTf ImProcFunctions::_10GY50; -LUTf ImProcFunctions::_10GY60; -LUTf ImProcFunctions::_10GY70; -LUTf ImProcFunctions::_10GY80; - -LUTf ImProcFunctions::_75GY30; -LUTf ImProcFunctions::_75GY40; -LUTf ImProcFunctions::_75GY50; -LUTf ImProcFunctions::_75GY60; -LUTf ImProcFunctions::_75GY70; -LUTf ImProcFunctions::_75GY80; - -LUTf ImProcFunctions::_5GY30; -LUTf ImProcFunctions::_5GY40; -LUTf ImProcFunctions::_5GY50; -LUTf ImProcFunctions::_5GY60; -LUTf ImProcFunctions::_5GY70; -LUTf ImProcFunctions::_5GY80; - -/* - * Munsell Lch correction - * copyright (c) 2011 Jacques Desmis - * - * data (Munsell ==> Lab) obtained with WallKillcolor and http://www.cis.rit.edu/research/mcsl2/online/munsell.php - * each LUT give Hue in function of C, for each color Munsell and Luminance - * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation betwwen values - * no value for C<5 (gray) - * low memory usage -- maximum: 195 LUT * 140 values - * errors due to small number of point of LUT and linearization are very low (1 to 2%) - * errors due to a different illuminant "Daylight" than "C" are low in the order of 10%. For example, a theoretical correction of 0.1 radian will be made with a real correction of 0.09 or 0.11 depending on the color illuminant D50 - * errors due to the use of a very different illuminant "C", for example illuminant "A" (tungsten) are higher in the order of 20%. Theoretical correction of 0.52 radians will be made with a real correction of 0.42 - */ -void ImProcFunctions::initMunsell () { -#ifdef _DEBUG - MyTime t1e,t2e; - t1e.set(); -#endif - -int maxInd = 140; -int maxInd2 = 90; -int maxInd3 = 50; - -//blue for sky -_5B40(maxInd2); - for (int i=0; i5) _5B40[i] = -2.3 + 0.0025*(i-5); - else if (i<90 && i>=45) _5B40[i] = -2.2 + 0.00*(i-45); - } - //printf("5B %1.2f %1.2f\n",_5B40[44],_5B40[89]); -_5B50(maxInd2); - for (int i=0; i5) _5B50[i] = -2.34 + 0.0025*(i-5); - else if (i<90 && i>=45) _5B50[i] = -2.24+0.0003*(i-45); - } - //printf("5B %1.2f %1.2f\n",_5B50[44],_5B50[89]); -_5B60(maxInd2); - for (int i=0; i5) _5B60[i] = -2.4 + 0.003*(i-5); - else if (i<90 && i>=45) _5B60[i] = -2.28+0.0005*(i-45); - } - //printf("5B %1.2f %1.2f\n",_5B60[44],_5B60[89]); -_5B70(maxInd2); - for (int i=0; i5) _5B70[i] = -2.41 + 0.00275*(i-5); - else if (i<90 && i>=45) _5B70[i] = -2.30+0.00025*(i-45); - } - //printf("5B %1.2f %1.2f\n",_5B70[44],_5B70[89]); -_5B80(maxInd3); - for (int i=0; i5) _5B80[i] = -2.45 +0.003*(i-5); - } - //printf("5B %1.2f\n",_5B80[49]); - -_7B40(maxInd2); - for (int i=0; i5) _7B40[i] = -2.15 + 0.0027*(i-5); - else if (i<90 && i>=45) _7B40[i] = -2.04 + 0.00*(i-45); - } - //printf("7B %1.2f %1.2f\n",_7B40[44],_7B40[89]); -_7B50(maxInd2); - for (int i=0; i5) _7B50[i] = -2.20 + 0.003*(i-5); - else if (i<90 && i>=45) _7B50[i] = -2.08 + 0.001*(i-45); - } - //printf("7B %1.2f %1.2f\n",_7B50[44],_7B50[79]); -_7B60(maxInd2); - for (int i=0; i5) _7B60[i] = -2.26 + 0.0035*(i-5); - else if (i<90 && i>=45) _7B60[i] = -2.12 + 0.001*(i-45); - } - //printf("7B %1.2f %1.2f\n",_7B60[44],_7B60[79]); -_7B70(maxInd2); - for (int i=0; i5) _7B70[i] = -2.28 + 0.003*(i-5); - else if (i<90 && i>=45) _7B70[i] = -2.16 + 0.0015*(i-45); - } - //printf("7B %1.2f %1.2f\n",_7B70[44],_7B70[64]); -_7B80(maxInd3); - for (int i=0; i5) _7B80[i] = -2.30 +0.0028*(i-5); - } - //printf("5B %1.2f\n",_7B80[49]); - -_9B40(maxInd2); - for (int i=0; i5) _9B40[i] = -1.99 + 0.0022*(i-5); - else if (i<90 && i>=45) _9B40[i] = -1.90 + 0.0008*(i-45); - } - //printf("9B %1.2f %1.2f\n",_9B40[44],_9B40[69]); -_9B50(maxInd2); - for (int i=0; i5) _9B50[i] = -2.04 + 0.0025*(i-5); - else if (i<90 && i>=45) _9B50[i] = -1.94 + 0.0013*(i-45); - } - //printf("9B %1.2f %1.2f\n",_9B50[44],_9B50[77]); -_9B60(maxInd2); - for (int i=0; i5) _9B60[i] = -2.10 + 0.0033*(i-5); - else if (i<90 && i>=45) _9B60[i] = -1.97 + 0.001*(i-45); - } - //printf("9B %1.2f %1.2f\n",_9B60[44],_9B60[79]); -_9B70(maxInd2); - for (int i=0; i5) _9B70[i] = -2.12 + 0.003*(i-5); - else if (i<90 && i>=45) _9B70[i] = -2.00 + 0.001*(i-45); - } - //printf("9B %1.2f %1.2f\n",_9B70[44],_9B70[54]); -_9B80(maxInd3); - for (int i=0; i5) _9B80[i] = -2.16 +0.0025*(i-5); - } - //printf("9B %1.2f\n",_9B80[49]); - -_10B40(maxInd2); - for (int i=0; i5) _10B40[i] = -1.92 + 0.0022*(i-5); - else if (i<90 && i>=45) _10B40[i] = -1.83 + 0.0012*(i-45); - } - //printf("10B %1.2f %1.2f\n",_10B40[44],_10B40[76]); -_10B50(maxInd2); - for (int i=0; i5) _10B50[i] = -1.95 + 0.0022*(i-5); - else if (i<90 && i>=45) _10B50[i] = -1.86 + 0.0008*(i-45); - } - //printf("10B %1.2f %1.2f\n",_10B50[44],_10B50[85]); -_10B60(maxInd2); - for (int i=0; i5) _10B60[i] = -2.01 + 0.0027*(i-5); - else if (i<90 && i>=45) _10B60[i] = -1.90 + 0.0012*(i-45); - } - //printf("10B %1.2f %1.2f\n",_10B60[44],_10B60[70]); -_10B70(maxInd3); - for (int i=0; i5) _10B70[i] = -2.03 +0.0025*(i-5); - } - //printf("10B %1.2f\n",_10B70[49]); -_10B80(maxInd3); - for (int i=0; i5) _10B80[i] = -2.08 +0.0032*(i-5); - } - //printf("10B %1.2f\n",_10B80[39]); - -_05PB40(maxInd2); - for (int i=0; i5) _05PB40[i] = -1.87 + 0.0022*(i-5); - else if (i<90 && i>=45) _05PB40[i] = -1.78 + 0.0015*(i-45); - } - //printf("05PB %1.2f %1.2f\n",_05PB40[44],_05PB40[74]); -_05PB50(maxInd2); - for (int i=0; i5) _05PB50[i] = -1.91 + 0.0022*(i-5); - else if (i<90 && i>=45) _05PB50[i] = -1.82 + 0.001*(i-45); - } - //printf("05PB %1.2f %1.2f\n",_05PB50[44],_05PB50[85]); -_05PB60(maxInd2); - for (int i=0; i5) _05PB60[i] = -1.96 + 0.0027*(i-5); - else if (i<90 && i>=45) _05PB60[i] = -1.85 + 0.0013*(i-45); - } - //printf("05PB %1.2f %1.2f\n",_05PB60[44],_05PB60[70]); -_05PB70(maxInd2); - for (int i=0; i5) _05PB70[i] = -1.99 + 0.0027*(i-5); - else if (i<90 && i>=45) _05PB70[i] = -1.88 + 0.001*(i-45); - } - //printf("05PB %1.2f %1.2f\n",_05PB70[44],_05PB70[54]); -_05PB80(maxInd3); - for (int i=0; i5) _05PB80[i] = -2.03 +0.003*(i-5); - } - //printf("05PB %1.2f\n",_05PB80[39]); - - - -//blue purple correction -//between 15PB to 4P -//maximum deviation 75PB - -//15PB -_15PB10(maxInd3); - for (int i=0; i5) _15PB10[i] = -1.66 +0.0035*(i-5); - } - //printf("15 %1.2f\n",_15PB10[49]); -_15PB20(maxInd2); - for (int i=0; i5) _15PB20[i] = -1.71 +0.00275*(i-5); - else if (i<90 && i>=45) _15PB20[i] = -1.60+0.0012*(i-45); - } - //printf("15 %1.2f %1.2f\n",_15PB20[44],_15PB20[89]); - -_15PB30(maxInd2); - for (int i=0; i5) _15PB30[i] = -1.75 +0.0025*(i-5); - else if (i<90 && i>=45) _15PB30[i] = -1.65+0.002*(i-45); - } - //printf("15 %1.2f %1.2f\n",_15PB30[44],_15PB30[89]); - -_15PB40(maxInd2); - for (int i=0; i5) _15PB40[i] = -1.79 +0.002*(i-5); - else if (i<90 && i>=45) _15PB40[i] = -1.71+0.002*(i-45); - } - //printf("15 %1.2f %1.2f\n",_15PB40[44],_15PB40[89]); - -_15PB50(maxInd2); - for (int i=0; i5) _15PB50[i] = -1.82 +0.002*(i-5); - else if (i<90 && i>=45) _15PB50[i] = -1.74+0.0011*(i-45); - } - //printf("15 %1.2f %1.2f\n",_15PB50[44],_15PB50[89]); - -_15PB60(maxInd2); - for (int i=0; i5) _15PB60[i] = -1.87 +0.0025*(i-5); - else if (i<90 && i>=45) _15PB60[i] = -1.77+0.001*(i-45); - } - //printf("15 %1.2f %1.2f\n",_15PB60[44],_15PB60[89]); -_15PB70(maxInd3); - for (int i=0; i5) _15PB70[i] = -1.90 +0.0027*(i-5); - } - // printf("15 %1.2f\n",_15PB70[49]); -_15PB80(maxInd3); - for (int i=0; i5) _15PB80[i] = -1.93 +0.0027*(i-5); - } - //printf("15 %1.2f %1.2f\n",_15PB80[38], _15PB80[49]); - -//3PB -_3PB10(maxInd2); - for (int i=0; i5) _3PB10[i] = -1.56 +0.005*(i-5); - else if (i<90 && i>=45) _3PB10[i] = -1.36+0.001*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB10[44],_3PB10[89]); - -_3PB20(maxInd2); - for (int i=0; i5) _3PB20[i] = -1.59 +0.00275*(i-5); - else if (i<90 && i>=45) _3PB20[i] = -1.48+0.003*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB20[44],_3PB20[89]); - -_3PB30(maxInd2); - for (int i=0; i5) _3PB30[i] = -1.62 +0.00225*(i-5); - else if (i<90 && i>=45) _3PB30[i] = -1.53+0.0032*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB30[44],_3PB30[89]); - -_3PB40(maxInd2); - for (int i=0; i5) _3PB40[i] = -1.64 +0.0015*(i-5); - else if (i<90 && i>=45) _3PB40[i] = -1.58+0.0025*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB40[44],_3PB40[89]); - -_3PB50(maxInd2); - for (int i=0; i5) _3PB50[i] = -1.69 +0.00175*(i-5); - else if (i<90 && i>=45) _3PB50[i] = -1.62+0.002*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB50[44],_3PB50[89]); - -_3PB60(maxInd2); - for (int i=0; i5) _3PB60[i] = -1.73 +0.002*(i-5); - else if (i<90 && i>=45) _3PB60[i] = -1.65+0.0012*(i-45); - } - //printf("30 %1.2f %1.2f\n",_3PB60[44],_3PB60[89]); -_3PB70(maxInd3); - for (int i=0; i5) _3PB70[i] = -1.76 +0.002*(i-5); - } - //printf("30 %1.2f\n",_3PB70[49]); -_3PB80(maxInd3); - for (int i=0; i5) _3PB80[i] = -1.78 +0.0025*(i-5); - } - //printf("30 %1.2f %1.2f\n",_3PB80[38], _3PB80[49]); - -//45PB -_45PB10(maxInd2); - for (int i=0; i5) _45PB10[i] = -1.46 +0.0045*(i-5); - else if (i<90 && i>=45) _45PB10[i] = -1.28+0.0025*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB10[44],_45PB10[89]); - -_45PB20(maxInd2); - for (int i=0; i5) _45PB20[i] = -1.48 +0.00275*(i-5); - else if (i<90 && i>=45) _45PB20[i] = -1.37+0.0025*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB20[44],_45PB20[89]); - -_45PB30(maxInd2); - for (int i=0; i5) _45PB30[i] = -1.51 +0.00175*(i-5); - else if (i<90 && i>=45) _45PB30[i] = -1.44+0.0035*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB30[44],_45PB30[89]); - -_45PB40(maxInd2); - for (int i=0; i5) _45PB40[i] = -1.52 +0.001*(i-5); - else if (i<90 && i>=45) _45PB40[i] = -1.48+0.003*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB40[44],_45PB40[89]); - -_45PB50(maxInd2); - for (int i=0; i5) _45PB50[i] = -1.55 +0.001*(i-5); - else if (i<90 && i>=45) _45PB50[i] = -1.51+0.0022*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB50[44],_45PB50[89]); - -_45PB60(maxInd2); - for (int i=0; i5) _45PB60[i] = -1.6 +0.0015*(i-5); - else if (i<90 && i>=45) _45PB60[i] = -1.54+0.001*(i-45); - } - //printf("45 %1.2f %1.2f\n",_45PB60[44],_45PB60[89]); -_45PB70(maxInd3); - for (int i=0; i5) _45PB70[i] = -1.63 +0.0017*(i-5); - } - //printf("45 %1.2f\n",_45PB70[49]); -_45PB80(maxInd3); - for (int i=0; i5) _45PB80[i] = -1.67 +0.0025*(i-5); - } - //printf("45 %1.2f %1.2f\n",_45PB80[38], _45PB80[49]); - -//_6PB -_6PB10(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _6PB10[i] = -1.33 +0.005*(i-5); - else if (i<85 && i>=45) _6PB10[i] = -1.13+0.0045*(i-45); - else if (i<140 && i >=85) _6PB10[i] = -0.95+0.0015*(i-85); - } - //printf("60 %1.2f %1.2f %1.2f\n",_6PB10[44],_6PB10[84],_6PB10[139]); - -_6PB20(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _6PB20[i] = -1.36 +0.004*(i-5); - else if (i<85 && i>=45) _6PB20[i] = -1.20+0.00375*(i-45); - else if (i<140 && i >=85) _6PB20[i] = -1.05+0.0017*(i-85); - } - //printf("60 %1.2f %1.2f %1.2f\n",_6PB20[44],_6PB20[84],_6PB20[139]); - -_6PB30(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _6PB30[i] = -1.38 +0.00225*(i-5); - else if (i<85 && i>=45) _6PB30[i] = -1.29+0.00375*(i-45); - else if (i<140 && i >=85) _6PB30[i] = -1.14+0.002*(i-85); - } - //printf("60 %1.2f %1.2f %1.2f\n",_6PB30[44],_6PB30[84],_6PB30[139]); - -_6PB40(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _6PB40[i] = -1.39 +0.00125*(i-5); - else if (i<85 && i>=45) _6PB40[i] = -1.34+0.00275*(i-45); - else if (i<140 && i >=85) _6PB40[i] = -1.23+0.002*(i-85); - } - //printf("60 %1.2f %1.2f %1.2f\n",_6PB40[44],_6PB40[84],_6PB40[139]); - -_6PB50(maxInd2);//limits -1.3 -1.11 - for (int i=0; i5) _6PB50[i] = -1.43 +0.00125*(i-5); - else if (i<90 && i>=45) _6PB50[i] = -1.38+0.00225*(i-45); - } - //printf("60 %1.2f %1.2f \n",_6PB50[44],_6PB50[89]); - -_6PB60(maxInd2);//limits -1.3 -1.11 - for (int i=0; i5) _6PB60[i] = -1.46 +0.0012*(i-5); - else if (i<90 && i>=45) _6PB60[i] = -1.40+0.000875*(i-45); - } - //printf("60 %1.2f %1.2f\n",_6PB60[44],_6PB60[89]); -_6PB70(maxInd3); - for (int i=0; i5) _6PB70[i] = -1.49 +0.0018*(i-5); - } - //printf("6 %1.2f\n",_6PB70[49]); -_6PB80(maxInd3); - for (int i=0; i5) _6PB80[i] = -1.52 +0.0022*(i-5); - } - //printf("6 %1.2f %1.2f\n",_6PB80[38], _6PB80[49]); - - -//_75PB : notation Munsell for maximum deviation blue purple -_75PB10(maxInd);//limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 - for (int i=0; i140 - if (i<45 && i>5) _75PB10[i] = -1.23 +0.0065*(i-5); - else if (i<85 && i>=45) _75PB10[i] = -0.97+0.00375*(i-45); - else if (i<140 && i >=85) _75PB10[i] = -0.82+0.0015*(i-85); - } - //printf("75 %1.2f %1.2f %1.2f\n",_75PB10[44],_75PB10[84],_75PB10[139]); - -_75PB20(maxInd);//limits -1.24 -0.79 for L>15 <=25 - for (int i=0; i5) _75PB20[i] = -1.24 +0.004*(i-5); - else if (i<85 && i>=45) _75PB20[i] = -1.08+0.00425*(i-45); - else if (i<140 && i >=85) _75PB20[i] = -0.91+0.0017*(i-85); - } - //printf("75 %1.2f %1.2f %1.2f\n",_75PB20[44],_75PB20[84],_75PB20[139]); - -_75PB30(maxInd);//limits -1.25 -0.85 - for (int i=0; i5) _75PB30[i] = -1.25 +0.00275*(i-5); - else if (i<85 && i>=45) _75PB30[i] = -1.14+0.004*(i-45); - else if (i<140 && i >=85) _75PB30[i] = -0.98+0.0015*(i-85); - } - //printf("75 %1.2f %1.2f %1.2f\n",_75PB30[44],_75PB30[84],_75PB30[139]); - -_75PB40(maxInd);//limits -1.27 -0.92 - for (int i=0; i5) _75PB40[i] = -1.27 +0.002*(i-5); - else if (i<85 && i>=45) _75PB40[i] = -1.19+0.003*(i-45); - else if (i<140 && i >=85) _75PB40[i] = -1.07+0.0022*(i-85); - } - //printf("75 %1.2f %1.2f %1.2f\n",_75PB40[44],_75PB40[84],_75PB40[139]); - -_75PB50(maxInd2);//limits -1.3 -1.11 - for (int i=0; i5) _75PB50[i] = -1.3 +0.00175*(i-5); - else if (i<90 && i>=45) _75PB50[i] = -1.23+0.0025*(i-45); - } - //printf("75 %1.2f %1.2f\n",_75PB50[44],_75PB50[89]); - -_75PB60(maxInd2); - for (int i=0; i5) _75PB60[i] = -1.32 +0.0015*(i-5); - else if (i<90 && i>=45) _75PB60[i] = -1.26+0.002*(i-45); - } - //printf("75 %1.2f %1.2f \n",_75PB60[44],_75PB60[89]); - -_75PB70(maxInd3); - for (int i=0; i5) _75PB70[i] = -1.34 +0.002*(i-5); - } -_75PB80(maxInd3); - for (int i=0; i5) _75PB80[i] = -1.35 +0.00125*(i-5); - } - - -_9PB10(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _9PB10[i] = -1.09 +0.00475*(i-5); - else if (i<85 && i>=45) _9PB10[i] = -0.9+0.003*(i-45); - else if (i<140 && i >=85) _9PB10[i] = -0.78+0.0013*(i-85); - } - //printf("90 %1.2f %1.2f %1.2f\n",_9PB10[44],_9PB10[84],_9PB10[139]); - -_9PB20(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _9PB20[i] = -1.12 +0.0035*(i-5); - else if (i<85 && i>=45) _9PB20[i] = -0.98+0.00325*(i-45); - else if (i<140 && i >=85) _9PB20[i] = -0.85+0.0015*(i-85); - } - //printf("90 %1.2f %1.2f %1.2f\n",_9PB20[44],_9PB20[84],_9PB20[139]); - -_9PB30(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _9PB30[i] = -1.14 +0.0028*(i-5); - else if (i<85 && i>=45) _9PB30[i] = -1.03+0.003*(i-45); - else if (i<140 && i >=85) _9PB30[i] = -0.91+0.0017*(i-85); - } - //printf("90 %1.2f %1.2f %1.2f\n",_9PB30[44],_9PB30[84],_9PB30[139]); - -_9PB40(maxInd); - for (int i=0; i140 - if (i<45 && i>5) _9PB40[i] = -1.16 +0.002*(i-5); - else if (i<85 && i>=45) _9PB40[i] = -1.08+0.00275*(i-45); - else if (i<140 && i >=85) _9PB40[i] = -0.97+0.0016*(i-85); - } - //printf("90 %1.2f %1.2f %1.2f\n",_9PB40[44],_9PB40[84],_9PB40[139]); - -_9PB50(maxInd2); - for (int i=0; i5) _9PB50[i] = -1.19 +0.00175*(i-5); - else if (i<90 && i>=45) _9PB50[i] = -1.12+0.00225*(i-45); - } - //printf("90 %1.2f %1.2f \n",_9PB50[44],_9PB50[84]); - -_9PB60(maxInd2); - for (int i=0; i5) _9PB60[i] = -1.21 +0.0015*(i-5); - else if (i<90 && i>=45) _9PB60[i] = -1.15+0.002*(i-45); - } - //printf("90 %1.2f %1.2f \n",_9PB60[44],_9PB60[89]); -_9PB70(maxInd3); - for (int i=0; i5) _9PB70[i] = -1.23 +0.0018*(i-5); - } - //printf("9 %1.2f\n",_9PB70[49]); -_9PB80(maxInd3); - for (int i=0; i5) _9PB80[i] = -1.24 +0.002*(i-5); - } - //printf("9 %1.2f %1.2f\n",_9PB80[38], _9PB80[49]); - - -//10PB -_10PB10(maxInd); - for (int i=0; i5) _10PB10[i] = -1.02 +0.00425*(i-5); - else if (i<85 && i>=45) _10PB10[i] = -0.85+0.0025*(i-45); - else if (i<140 && i >=85) _10PB10[i] = -0.75+0.0012*(i-85); - } - //printf("10 %1.2f %1.2f %1.2f\n",_10PB10[44],_10PB10[84],_10PB10[139]); - -_10PB20(maxInd); - for (int i=0; i5) _10PB20[i] = -1.05 +0.00325*(i-5); - else if (i<85 && i>=45) _10PB20[i] = -0.92+0.00275*(i-45); - else if (i<140 && i >=85) _10PB20[i] = -0.81+0.0014*(i-85); - } - //printf("10 %1.2f %1.2f %1.2f\n",_10PB20[44],_10PB20[84],_10PB20[139]); - -_10PB30(maxInd); - for (int i=0; i5) _10PB30[i] = -1.07 +0.00275*(i-5); - else if (i<85 && i>=45) _10PB30[i] = -0.96+0.0025*(i-45); - else if (i<140 && i >=85) _10PB30[i] = -0.86+0.0015*(i-85); - } - //printf("10 %1.2f %1.2f %1.2f\n",_10PB30[44],_10PB30[84],_10PB30[139]); - -_10PB40(maxInd); - for (int i=0; i5) _10PB40[i] = -1.09 +0.002*(i-5); - else if (i<85 && i>=45) _10PB40[i] = -1.01+0.00225*(i-45); - else if (i<140 && i >=85) _10PB40[i] = -0.92+0.0016*(i-85); - } - //printf("10 %1.2f %1.2f %1.2f\n",_10PB40[44],_10PB40[84],_10PB40[139]); - -_10PB50(maxInd2); - for (int i=0; i5) _10PB50[i] = -1.12 +0.00175*(i-5); - else if (i<90 && i>=45) _10PB50[i] = -1.05+0.00225*(i-45); - } - //printf("10 %1.2f %1.2f\n",_10PB50[44],_10PB50[84]); - -_10PB60(maxInd2); - for (int i=0; i5) _10PB60[i] = -1.14 +0.0015*(i-5); - else if (i<90 && i>=45) _10PB60[i] = -1.08+0.00225*(i-45); - } - //printf("10 %1.2f %1.2f\n",_10PB60[44],_10PB60[89]); - - -//1P -_1P10(maxInd); - for (int i=0; i5) _1P10[i] = -0.96 +0.00375*(i-5); - else if (i<85 && i>=45) _1P10[i] = -0.81+0.00225*(i-45); - else if (i<140 && i >=85) _1P10[i] = -0.72+0.001*(i-85); - } - //printf("1P %1.2f %1.2f %1.2f\n",_1P10[44],_1P10[84],_1P10[139]); - -_1P20(maxInd); - for (int i=0; i5) _1P20[i] = -1.0 +0.00325*(i-5); - else if (i<85 && i>=45) _1P20[i] = -0.87+0.0025*(i-45); - else if (i<140 && i >=85) _1P20[i] = -0.77+0.0012*(i-85); - } - //printf("1P %1.2f %1.2f %1.2f\n",_1P20[44],_1P20[84],_1P20[139]); - -_1P30(maxInd); - for (int i=0; i5) _1P30[i] = -1.02 +0.00275*(i-5); - else if (i<85 && i>=45) _1P30[i] = -0.91+0.00225*(i-45); - else if (i<140 && i >=85) _1P30[i] = -0.82+0.0011*(i-85); - } - //printf("1P %1.2f %1.2f %1.2f\n",_1P30[44],_1P30[84],_1P30[139]); - -_1P40(maxInd); - for (int i=0; i5) _1P40[i] = -1.04 +0.00225*(i-5); - else if (i<85 && i>=45) _1P40[i] = -0.95+0.00225*(i-45); - else if (i<140 && i >=85) _1P40[i] = -0.86+0.0015*(i-85); - } - //printf("1P %1.2f %1.2f %1.2f\n",_1P40[44],_1P40[84],_1P40[139]); - -_1P50(maxInd2); - for (int i=0; i5) _1P50[i] = -1.06 +0.002*(i-5); - else if (i<90 && i>=45) _1P50[i] = -0.98+0.00175*(i-45); - } - //printf("1P %1.2f %1.2f \n",_1P50[44],_1P50[89]); - -_1P60(maxInd2); - for (int i=0; i5) _1P60[i] = -1.07 +0.0015*(i-5); - else if (i<90 && i>=45) _1P60[i] = -1.01+0.00175*(i-45); - } - //printf("1P %1.2f %1.2f \n",_1P60[44],_1P60[84],_1P60[139]); - - //4P -_4P10(maxInd); - for (int i=0; i5) _4P10[i] = -0.78 +0.002*(i-5); - else if (i<85 && i>=45) _4P10[i] = -0.7+0.00125*(i-45); - else if (i<140 && i >=85) _4P10[i] = -0.65+0.001*(i-85); - } - //printf("4P %1.2f %1.2f %1.2f\n",_4P10[44],_4P10[84],_4P10[139]); - -_4P20(maxInd); - for (int i=0; i5) _4P20[i] = -0.84 +0.0025*(i-5); - else if (i<85 && i>=45) _4P20[i] = -0.74+0.00175*(i-45); - else if (i<140 && i >=85) _4P20[i] = -0.67+0.00085*(i-85); - } - //printf("4P %1.2f %1.2f %1.2f\n",_4P20[44],_4P20[84],_4P20[139]); - -_4P30(maxInd); - for (int i=0; i5) _4P30[i] = -0.85 +0.00225*(i-5); - else if (i<85 && i>=45) _4P30[i] = -0.76+0.00125*(i-45); - else if (i<140 && i >=85) _4P30[i] = -0.71+0.001*(i-85); - } - //printf("4P %1.2f %1.2f %1.2f\n",_4P30[44],_4P30[84],_4P30[139]); - -_4P40(maxInd); - for (int i=0; i5) _4P40[i] = -0.87 +0.00175*(i-5); - else if (i<85 && i>=45) _4P40[i] = -0.8+0.00175*(i-45); - else if (i<140 && i >=85) _4P40[i] = -0.73+0.00075*(i-85); - } - //printf("4P %1.2f %1.2f %1.2f\n",_4P40[44],_4P40[84],_4P40[139]); - -_4P50(maxInd2); - for (int i=0; i5) _4P50[i] = -0.88 +0.0015*(i-5); - else if (i<90 && i>=45) _4P50[i] = -0.82+0.0015*(i-45); - } - //printf("4P %1.2f %1.2f \n",_4P50[44],_4P50[89]); - -_4P60(maxInd2); - for (int i=0; i5) _4P60[i] = -0.89 +0.00125*(i-5); - else if (i<90 && i>=45) _4P60[i] = -0.84+0.00125*(i-45); - } - //printf("4P %1.2f %1.2f\n",_4P60[44],_4P60[89]); - - -//red yellow correction -_10YR20(maxInd2); - for (int i=0; i5) _10YR20[i] = 1.22 +0.002*(i-5); - else if (i<90 && i>=45) _10YR20[i] = 1.30+0.006*(i-45); - } - //printf("10YR %1.2f %1.2f\n",_10YR20[44],_10YR20[56]); -_10YR30(maxInd2); - for (int i=0; i5) _10YR30[i] = 1.27 +0.00175*(i-5); - else if (i<90 && i>=45) _10YR30[i] = 1.34+0.0017*(i-45); - } - //printf("10YR %1.2f %1.2f\n",_10YR30[44],_10YR30[75]); -_10YR40(maxInd2); - for (int i=0; i5) _10YR40[i] = 1.32 +0.00025*(i-5); - else if (i<90 && i>=45) _10YR40[i] = 1.33+0.0015*(i-45); - } - //printf("10YR %1.2f %1.2f\n",_10YR40[44],_10YR40[85]); -_10YR50(maxInd2); - for (int i=0; i5) _10YR50[i] = 1.35 +0.000*(i-5); - else if (i<90 && i>=45) _10YR50[i] = 1.35+0.0012*(i-45); - } - //printf("10YR %1.2f %1.2f\n",_10YR50[44],_10YR50[80]); -_10YR60(maxInd); - for (int i=0; i5) _10YR60[i] = 1.38 - 0.00025*(i-5); - else if (i<85 && i>=45) _10YR60[i] = 1.37+0.0005*(i-45); - else if (i<140 && i >=85) _10YR60[i] = 1.39+0.0013*(i-85); - } - //printf("10YR %1.2f %1.2f %1.2f\n",_10YR60[44],_10YR60[85],_10YR60[139] ); -_10YR70(maxInd); - for (int i=0; i5) _10YR70[i] = 1.41 - 0.0005*(i-5); - else if (i<85 && i>=45) _10YR70[i] = 1.39+0.000*(i-45); - else if (i<140 && i >=85) _10YR70[i] = 1.39+0.0013*(i-85); - } - //printf("10YR %1.2f %1.2f %1.2f\n",_10YR70[44],_10YR70[85],_10YR70[139] ); -_10YR80(maxInd); - for (int i=0; i5) _10YR80[i] = 1.45 - 0.00125*(i-5); - else if (i<85 && i>=45) _10YR80[i] = 1.40+0.000*(i-45); - else if (i<140 && i >=85) _10YR80[i] = 1.40+0.00072*(i-85);//1.436 - } - //printf("10YR %1.2f %1.2f %1.2f\n",_10YR80[44],_10YR80[84],_10YR80[139] ); -_10YR90(maxInd2); - for (int i=0; i5) _10YR90[i] = 1.48 -0.001*(i-5); - else if (i<90 && i>=45) _10YR90[i] = 1.44-0.0009*(i-45); - } - //printf("10YR %1.2f %1.2f\n",_10YR90[45],_10YR90[80]); -_85YR20(maxInd3); - for (int i=0; i5) _85YR20[i] = 1.12 +0.004*(i-5); - } - - //printf("85YR %1.2f \n",_85YR20[44]); -_85YR30(maxInd2); - for (int i=0; i5) _85YR30[i] = 1.16 + 0.0025*(i-5); - else if (i<90 && i>=45) _85YR30[i] = 1.26+0.0028*(i-45); - } - //printf("85YR %1.2f %1.2f\n",_85YR30[44],_85YR30[75]); -_85YR40(maxInd2); - for (int i=0; i5) _85YR40[i] = 1.20 + 0.0015*(i-5); - else if (i<90 && i>=45) _85YR40[i] = 1.26+0.0024*(i-45); +void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) { + if (needed && diagCurve) { + LUTf lutCurve (65536); + + for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { + // change to [0,1] range + // apply custom/parametric/NURBS curve, if any + // and store result in a temporary array + lutCurve[i] = diagCurve->getVal( double(i)/65535.0 ); + } + + // if skip>1, let apply linear interpolation in the skipped points of the curve + if (skip > 1) { + int prev = 0; + for (int i=1; i<=0xffff-skip; i++) { + int iMod = i%skip; + if (!iMod) { + prev+=skip; + continue; + } + lutCurve[i] = ( lutCurve[prev] * (skip-iMod) + lutCurve[prev+skip]*iMod ) / skip; + } + } + + for (int i=0; i<=0xffff; i++) { + outCurve[i] = (65535.0f * lutCurve[i]); + } + } + else { + for (int i=0; i<=0xffff; i++) { + outCurve[i] = float(i); + } } - //printf("85YR %1.2f %1.2f\n",_85YR40[44],_85YR40[75]); -_85YR50(maxInd); - for (int i=0; i5) _85YR50[i] = 1.24 + 0.0005*(i-5); - else if (i<85 && i>=45) _85YR50[i] = 1.26+0.002*(i-45); - else if (i<140 && i >=85) _85YR50[i] = 1.34+0.0015*(i-85); - } - //printf("85YR %1.2f %1.2f %1.2f\n",_85YR50[44],_85YR50[85],_85YR50[110] ); -_85YR60(maxInd); - for (int i=0; i5) _85YR60[i] = 1.27 + 0.00025*(i-5); - else if (i<85 && i>=45) _85YR60[i] = 1.28+0.0015*(i-45); - else if (i<140 && i >=85) _85YR60[i] = 1.34+0.0012*(i-85); - } - //printf("85YR %1.2f %1.2f %1.2f\n",_85YR60[44],_85YR60[85],_85YR60[139] ); - -_85YR70(maxInd); - for (int i=0; i5) _85YR70[i] = 1.31 - 0.00025*(i-5); - else if (i<85 && i>=45) _85YR70[i] = 1.30+0.0005*(i-45); - else if (i<140 && i >=85) _85YR70[i] = 1.32+0.0012*(i-85); - } - //printf("85YR %1.2f %1.2f %1.2f\n",_85YR70[44],_85YR70[85],_85YR70[139] ); -_85YR80(maxInd); - for (int i=0; i5) _85YR80[i] = 1.35 - 0.00075*(i-5); - else if (i<85 && i>=45) _85YR80[i] = 1.32+0.00025*(i-45); - else if (i<140 && i >=85) _85YR80[i] = 1.33+0.00125*(i-85); - } - //printf("85YR %1.2f %1.2f %1.2f\n",_85YR80[44],_85YR80[85],_85YR80[139] ); -_85YR90(maxInd2); - for (int i=0; i5) _85YR90[i] = 1.39 - 0.00125*(i-5); - else if (i<90 && i>=45) _85YR90[i] = 1.34+0.00*(i-45); - } - //printf("85YR %1.2f %1.2f\n",_85YR90[44],_85YR90[85]); - -//7YR -_7YR30(maxInd2); - for (int i=0; i5) _7YR30[i] = 1.06 + 0.0028*(i-5); - else if (i<90 && i>=45) _7YR30[i] = 1.17+0.0045*(i-45); - } - //printf("7YR %1.2f %1.2f\n",_7YR30[44],_7YR30[66]); -_7YR40(maxInd2); - for (int i=0; i5) _7YR40[i] = 1.10 + 0.0018*(i-5); - else if (i<90 && i>=45) _7YR40[i] = 1.17+0.0035*(i-45); - } - //printf("7YR %1.2f %1.2f\n",_7YR40[44],_7YR40[89]); -_7YR50(maxInd2); - for (int i=0; i5) _7YR50[i] = 1.14 + 0.00125*(i-5); - else if (i<90 && i>=45) _7YR50[i] = 1.19+0.002*(i-45); - } - //printf("7YR %1.2f %1.2f\n",_7YR50[44],_7YR50[89] ); -_7YR60(maxInd); - for (int i=0; i5) _7YR60[i] = 1.17 + 0.00075*(i-5); - else if (i<85 && i>=45) _7YR60[i] = 1.20+0.00175*(i-45); - else if (i<140 && i >=85) _7YR60[i] = 1.27+0.002*(i-85); - } - //printf("7YR %1.2f %1.2f %1.2f\n",_7YR60[44],_7YR60[84],_7YR60[125] ); - -_7YR70(maxInd); - for (int i=0; i5) _7YR70[i] = 1.20 + 0.0005*(i-5); - else if (i<85 && i>=45) _7YR70[i] = 1.22+0.00125*(i-45); - else if (i<140 && i >=85) _7YR70[i] = 1.27+0.0015*(i-85); - } - //printf("7YR %1.2f %1.2f %1.2f\n",_7YR70[44],_7YR70[84],_7YR70[125] ); -_7YR80(maxInd3); - for (int i=0; i5) _7YR80[i] = 1.29 - 0.0008*(i-5); - } - //printf("7YR %1.2f \n",_7YR80[44] ); -_55YR30(maxInd3); - for (int i=0; i5) _55YR30[i] = 0.96 + 0.0038*(i-5); - } - //printf("55YR %1.2f \n",_55YR30[44] ); -_55YR40(maxInd2); - for (int i=0; i5) _55YR40[i] = 1.01 + 0.0022*(i-5); - else if (i<90 && i>=45) _55YR40[i] = 1.10+0.0037*(i-45); - } - //printf("55YR %1.2f %1.2f\n",_55YR40[44],_55YR40[89] ); -_55YR50(maxInd); - for (int i=0; i5) _55YR50[i] = 1.06 + 0.0015*(i-5); - else if (i<85 && i>=45) _55YR50[i] = 1.12+0.00225*(i-45); - else if (i<140 && i >=85) _55YR50[i] = 1.21+0.0015*(i-85); - } - //printf("55YR %1.2f %1.2f %1.2f\n",_55YR50[44],_55YR50[84],_55YR50[125] ); -_55YR60(maxInd); - for (int i=0; i5) _55YR60[i] = 1.08 + 0.0012*(i-5); - else if (i<85 && i>=45) _55YR60[i] = 1.13+0.0018*(i-45); - else if (i<140 && i >=85) _55YR60[i] = 1.20+0.0025*(i-85); - } - //printf("55YR %1.2f %1.2f %1.2f\n",_55YR60[44],_55YR60[84],_55YR60[125] ); -_55YR70(maxInd); - for (int i=0; i5) _55YR70[i] = 1.11 + 0.00075*(i-5); - else if (i<85 && i>=45) _55YR70[i] = 1.14+0.0012*(i-45); - else if (i<140 && i >=85) _55YR70[i] = 1.19+0.00225*(i-85); - } - //printf("55YR %1.2f %1.2f %1.2f\n",_55YR70[44],_55YR70[84],_55YR70[125] ); -_55YR80(maxInd); - for (int i=0; i5) _55YR80[i] = 1.16 + 0.00*(i-5); - else if (i<85 && i>=45) _55YR80[i] = 1.16+0.00075*(i-45); - else if (i<140 && i >=85) _55YR80[i] = 1.19+0.00175*(i-85); - } - //printf("55YR %1.2f %1.2f %1.2f\n",_55YR80[44],_55YR80[84],_55YR80[125] ); -_55YR90(maxInd3); - for (int i=0; i5) _55YR90[i] = 1.19 - 0.0005*(i-5); - } - //printf("55YR %1.2f \n",_55YR90[44] ); - -_4YR30(maxInd2); - for (int i=0; i5) _4YR30[i] = 0.87 + 0.0035*(i-5); - else if (i<90 && i>=45) _4YR30[i] = 1.01+0.0043*(i-45); - } - //printf("4YR %1.2f %1.2f\n",_4YR30[44],_4YR30[78] ); -_4YR40(maxInd2); - for (int i=0; i5) _4YR40[i] = 0.92 + 0.0025*(i-5); - else if (i<90 && i>=45) _4YR40[i] = 1.02+0.0033*(i-45); - } - //printf("4YR %1.2f %1.2f\n",_4YR40[44],_4YR40[74] ); -_4YR50(maxInd2); - for (int i=0; i5) _4YR50[i] = 0.97 + 0.0015*(i-5); - else if (i<90 && i>=45) _4YR50[i] = 1.03+0.0025*(i-45); - } - //printf("4YR %1.2f %1.2f\n",_4YR50[44],_4YR50[85] ); -_4YR60(maxInd); - for (int i=0; i5) _4YR60[i] = 0.99 + 0.00125*(i-5); - else if (i<85 && i>=45) _4YR60[i] = 1.04+0.002*(i-45); - else if (i<140 && i >=85) _4YR60[i] = 1.12+0.003*(i-85); - } - //printf("4YR %1.2f %1.2f %1.2f\n",_4YR60[44],_4YR60[84],_4YR60[125] ); -_4YR70(maxInd); - for (int i=0; i5) _4YR70[i] = 1.02 + 0.00075*(i-5); - else if (i<85 && i>=45) _4YR70[i] = 1.05+0.00175*(i-45); - else if (i<140 && i >=85) _4YR70[i] = 1.12+0.002*(i-85); - } - //printf("4YR %1.2f %1.2f %1.2f\n",_4YR70[44],_4YR70[84],_4YR70[125] ); -_4YR80(maxInd3); - for (int i=0; i5) _4YR80[i] = 1.09 - 0.0002*(i-5); - } - //printf("4YR %1.2f \n",_4YR80[41] ); - -_25YR30(maxInd2); - for (int i=0; i5) _25YR30[i] = 0.77 + 0.004*(i-5); - else if (i<90 && i>=45) _25YR30[i] = 0.94+0.004*(i-45); - } - //printf("25YR %1.2f %1.2f\n",_25YR30[44],_25YR30[74] ); -_25YR40(maxInd2); - for (int i=0; i5) _25YR40[i] = 0.82 + 0.003*(i-5); - else if (i<90 && i>=45) _25YR40[i] = 0.94+0.002*(i-45); - } - //printf("25YR %1.2f %1.2f\n",_25YR40[44],_25YR40[84] ); -_25YR50(maxInd2); - for (int i=0; i5) _25YR50[i] = 0.87+ 0.002*(i-5); - else if (i<90 && i>=45) _25YR50[i] = 0.95+0.003*(i-45); - } - //printf("25YR %1.2f %1.2f\n",_25YR50[44],_25YR50[84] ); -_25YR60(maxInd2); - for (int i=0; i5) _25YR60[i] = 0.89+ 0.0015*(i-5); - else if (i<90 && i>=45) _25YR60[i] = 0.95+0.004*(i-45); - } - //printf("25YR %1.2f %1.2f\n",_25YR60[44],_25YR60[84] ); -_25YR70(maxInd2); - for (int i=0; i5) _25YR70[i] = 0.92+ 0.001*(i-5); - else if (i<90 && i>=45) _25YR70[i] = 0.96+0.003*(i-45); - } - //printf("25YR %1.2f %1.2f\n",_25YR70[44],_25YR70[84] ); - -_10R30(maxInd2); - for (int i=0; i5) _10R30[i] = 0.62 + 0.00225*(i-5); - else if (i<90 && i>=45) _10R30[i] = 0.71+0.003*(i-45); - } - //printf("10R %1.2f %1.2f\n",_10R30[44],_10R30[84] ); -_10R40(maxInd2); - for (int i=0; i5) _10R40[i] = 0.66 + 0.0025*(i-5); - else if (i<90 && i>=45) _10R40[i] = 0.76+0.0035*(i-45); - } - //printf("10R %1.2f %1.2f\n",_10R40[44],_10R40[84] ); -_10R50(maxInd2); - for (int i=0; i5) _10R50[i] = 0.71 + 0.002*(i-5); - else if (i<90 && i>=45) _10R50[i] = 0.79+0.0043*(i-45); - } - //printf("10R %1.2f %1.2f\n",_10R50[44],_10R50[84] ); -_10R60(maxInd); - for (int i=0; i5) _10R60[i] = 0.73 + 0.00175*(i-5); - else if (i<85 && i>=45) _10R60[i] = 0.80 +0.0033*(i-45); - else if (i<140 && i >=85) _10R60[i] = 0.93+0.0018*(i-85); - } - //printf("10R %1.2f %1.2f %1.2f\n",_10R60[44],_10R60[84],_10R60[125] ); -_10R70(maxInd); - for (int i=0; i5) _10R70[i] = 0.75 + 0.0015*(i-5); - else if (i<85 && i>=45) _10R70[i] = 0.81 +0.0017*(i-45); - else if (i<140 && i >=85) _10R70[i] = 0.88+0.0025*(i-85); - } - //printf("10R %1.2f %1.2f %1.2f\n",_10R70[44],_10R70[84],_10R70[125] ); - -_9R30(maxInd2); - for (int i=0; i5) _9R30[i] = 0.57 + 0.002*(i-5); - else if (i<90 && i>=45) _9R30[i] = 0.65+0.0018*(i-45); - } - //printf("9R %1.2f %1.2f\n",_9R30[44],_9R30[84] ); -_9R40(maxInd2); - for (int i=0; i5) _9R40[i] = 0.61 + 0.002*(i-5); - else if (i<90 && i>=45) _9R40[i] = 0.69+0.0025*(i-45); - } - //printf("9R %1.2f %1.2f\n",_9R40[44],_9R40[84] ); -_9R50(maxInd); - for (int i=0; i5) _9R50[i] = 0.66 + 0.00175*(i-5); - else if (i<85 && i>=45) _9R50[i] = 0.73 +0.0025*(i-45); - else if (i<140 && i >=85) _9R50[i] = 0.83+0.0035*(i-85); - } - //printf("9R %1.2f %1.2f %1.2f\n",_9R50[44],_9R50[84],_9R50[125] ); -_9R60(maxInd); - for (int i=0; i5) _9R60[i] = 0.68 + 0.0015*(i-5); - else if (i<85 && i>=45) _9R60[i] = 0.74 +0.0022*(i-45); - else if (i<140 && i >=85) _9R60[i] = 0.93+0.0022*(i-85); - } - //printf("9R %1.2f %1.2f %1.2f\n",_9R60[44],_9R60[84],_9R60[125] ); -_9R70(maxInd2); - for (int i=0; i5) _9R70[i] = 0.70 + 0.0012*(i-5); - else if (i<90 && i>=45) _9R70[i] = 0.75+0.0013*(i-45); - } - //printf("9R %1.2f %1.2f\n",_9R70[44],_9R70[84] ); - -_7R30(maxInd2); - for (int i=0; i5) _7R30[i] = 0.48 + 0.0015*(i-5); - else if (i<90 && i>=45) _7R30[i] = 0.54-0.0005*(i-45); - } - //printf("7R %1.2f %1.2f\n",_7R30[44],_7R30[84] ); -_7R40(maxInd2); - for (int i=0; i5) _7R40[i] = 0.51 + 0.0015*(i-5); - else if (i<90 && i>=45) _7R40[i] = 0.57+0.0005*(i-45); - } - //printf("7R %1.2f %1.2f\n",_7R40[44],_7R40[84] ); -_7R50(maxInd); - for (int i=0; i5) _7R50[i] = 0.54 + 0.0015*(i-5); - else if (i<85 && i>=45) _7R50[i] = 0.60 +0.0005*(i-45); - else if (i<140 && i >=85) _7R50[i] = 0.62+0.0025*(i-85); - } - //printf("7R %1.2f %1.2f %1.2f\n",_7R50[44],_7R50[84],_7R50[125] ); -_7R60(maxInd); - for (int i=0; i5) _7R60[i] = 0.58 + 0.00075*(i-5); - else if (i<85 && i>=45) _7R60[i] = 0.61 +0.00075*(i-45); - else if (i<140 && i >=85) _7R60[i] = 0.64+0.001*(i-85); - } - //printf("7R %1.2f %1.2f %1.2f\n",_7R60[44],_7R60[84],_7R60[107] ); -_7R70(maxInd2); - for (int i=0; i5) _7R70[i] = 0.59 + 0.00075*(i-5); - else if (i<90 && i>=45) _7R70[i] = 0.62+0.00075*(i-45); - } - //printf("7R %1.2f %1.2f\n",_7R70[44],_7R70[84] ); - -//5R 1 2 3 - -//5R -_5R10(maxInd2); - for (int i=0; i5) _5R10[i] = 0.10 - 0.0018*(i-5); - else if (i<90 && i>=45) _5R10[i] = 0.035-0.003*(i-45); - } - //printf("5R %1.2f %1.2f\n",_5R10[44],_5R10[51] ); -_5R20(maxInd2); - for (int i=0; i5) _5R20[i] = 0.26 - 0.00075*(i-5); - else if (i<90 && i>=45) _5R20[i] = 0.023-0.0002*(i-45); - } - //printf("5R %1.2f %1.2f\n",_5R20[44],_5R20[70] ); -_5R30(maxInd2); - for (int i=0; i5) _5R30[i] = 0.39 + 0.00075*(i-5); - else if (i<90 && i>=45) _5R30[i] = 0.42-0.0007*(i-45); - } - //printf("5R %1.2f %1.2f\n",_5R30[44],_5R30[85] ); - -//25R -_25R10(maxInd3); - for (int i=0; i5) _25R10[i] = -0.03 - 0.002*(i-5); - } - //printf("25R %1.2f \n",_25R10[44]); -_25R20(maxInd2); - for (int i=0; i5) _25R20[i] = 0.13 - 0.0012*(i-5); - else if (i<90 && i>=45) _25R20[i] = 0.08-0.002*(i-45); - } - //printf("25R %1.2f %1.2f\n",_25R20[44],_25R20[69] ); - //25R30: 0.28, 0.26, 0.22 -_25R30(maxInd2); - for (int i=0; i5) _25R30[i] = 0.28 - 0.0005*(i-5); - else if (i<90 && i>=45) _25R30[i] = 0.26-0.0009*(i-45); - } - //printf("25R %1.2f %1.2f\n",_25R30[44],_25R30[85] ); - - -_10RP10(maxInd3); - for (int i=0; i5) _10RP10[i] = -0.16 - 0.0017*(i-5); - } - //printf("10RP %1.2f \n",_10RP10[44]); -_10RP20(maxInd2); - for (int i=0; i5) _10RP20[i] = 0.0 - 0.0018*(i-5); - else if (i<90 && i>=45) _10RP20[i] = -0.07-0.0012*(i-45); - } - //printf("10RP %1.2f %1.2f\n",_10RP20[44],_10RP20[69] ); -_10RP30(maxInd2); - for (int i=0; i5) _10RP30[i] = 0.15 - 0.001*(i-5); - else if (i<90 && i>=45) _10RP30[i] = 0.11-0.0012*(i-45); - } - //printf("10RP %1.2f %1.2f\n",_10RP30[44],_10RP30[85] ); - -//7G -_7G30(maxInd); - for (int i=0; i5) _7G30[i] = 2.90 + 0.0027*(i-5); - else if (i<85 && i>=45) _7G30[i] = 3.01+0.0005*(i-45); - else if (i<140 && i >=85) _7G30[i] = 3.03+0.00075*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G30[44],_7G30[84],_7G30[125] ); -_7G40(maxInd); - for (int i=0; i5) _7G40[i] = 2.89 + 0.00125*(i-5); - else if (i<85 && i>=45) _7G40[i] = 2.94+0.0015*(i-45); - else if (i<140 && i >=85) _7G40[i] = 3.0+0.001*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G40[44],_7G40[84],_7G40[125] ); -_7G50(maxInd); - for (int i=0; i5) _7G50[i] = 2.87 + 0.0015*(i-5); - else if (i<85 && i>=45) _7G50[i] = 2.93+0.00125*(i-45); - else if (i<140 && i >=85) _7G50[i] = 2.98+0.001*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G50[44],_7G50[84],_7G50[125] ); -_7G60(maxInd); - for (int i=0; i5) _7G60[i] = 2.86 + 0.00125*(i-5); - else if (i<85 && i>=45) _7G60[i] = 2.91+0.00125*(i-45); - else if (i<140 && i >=85) _7G60[i] = 2.96+0.00075*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G60[44],_7G60[84],_7G60[125] ); -_7G70(maxInd); - for (int i=0; i5) _7G70[i] = 2.85 + 0.001*(i-5); - else if (i<85 && i>=45) _7G70[i] = 2.89+0.00125*(i-45); - else if (i<140 && i >=85) _7G70[i] = 2.94+0.00075*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G70[44],_7G70[84],_7G70[125] ); -_7G80(maxInd); - for (int i=0; i5) _7G80[i] = 2.84 + 0.001*(i-5); - else if (i<85 && i>=45) _7G80[i] = 2.88+0.001*(i-45); - else if (i<140 && i >=85) _7G80[i] = 2.92+0.001*(i-85); - } - //printf("7G %1.2f %1.2f %1.2f\n",_7G80[44],_7G80[84],_7G80[125] ); - - -//5G -_5G30(maxInd); - for (int i=0; i5) _5G30[i] = 2.82 + 0.00175*(i-5); - else if (i<85 && i>=45) _5G30[i] = 2.89+0.0018*(i-45); - else if (i<140 && i >=85) _5G30[i] = 2.96+0.0012*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G30[44],_5G30[84],_5G30[125] ); -_5G40(maxInd); - for (int i=0; i5) _5G40[i] = 2.80 + 0.0015*(i-5); - else if (i<85 && i>=45) _5G40[i] = 2.86+0.00175*(i-45); - else if (i<140 && i >=85) _5G40[i] = 2.93+0.00125*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G40[44],_5G40[84],_5G40[125] ); -_5G50(maxInd); - for (int i=0; i5) _5G50[i] = 2.79 + 0.001*(i-5); - else if (i<85 && i>=45) _5G50[i] = 2.84+0.0015*(i-45); - else if (i<140 && i >=85) _5G50[i] = 2.90+0.0015*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G50[44],_5G50[84],_5G50[125] ); -_5G60(maxInd); - for (int i=0; i5) _5G60[i] = 2.78 + 0.001*(i-5); - else if (i<85 && i>=45) _5G60[i] = 2.82+0.00175*(i-45); - else if (i<140 && i >=85) _5G60[i] = 2.89+0.001*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G60[44],_5G60[84],_5G60[125] ); -_5G70(maxInd); - for (int i=0; i5) _5G70[i] = 2.77 + 0.001*(i-5); - else if (i<85 && i>=45) _5G70[i] = 2.81+0.00125*(i-45); - else if (i<140 && i >=85) _5G70[i] = 2.86+0.00125*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G70[44],_5G70[84],_5G70[125] ); -_5G80(maxInd); - for (int i=0; i5) _5G80[i] = 2.76 + 0.001*(i-5); - else if (i<85 && i>=45) _5G80[i] = 2.8+0.00125*(i-45); - else if (i<140 && i >=85) _5G80[i] = 2.85+0.00125*(i-85); - } - //printf("5G %1.2f %1.2f %1.2f\n",_5G80[44],_5G80[84],_5G80[125] ); - -//25G -_25G30(maxInd); - for (int i=0; i5) _25G30[i] = 2.68 + 0.0015*(i-5); - else if (i<85 && i>=45) _25G30[i] = 2.74+0.0018*(i-45); - else if (i<140 && i >=85) _25G30[i] = 2.81+0.002*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G30[44],_25G30[84],_25G30[125] ); -_25G40(maxInd); - for (int i=0; i5) _25G40[i] = 2.68 + 0.00075*(i-5); - else if (i<85 && i>=45) _25G40[i] = 2.71+0.0015*(i-45); - else if (i<140 && i >=85) _25G40[i] = 2.77+0.00125*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G40[44],_25G40[84],_25G40[125] ); -_25G50(maxInd); - for (int i=0; i5) _25G50[i] = 2.65 + 0.00075*(i-5); - else if (i<85 && i>=45) _25G50[i] = 2.68+0.00125*(i-45); - else if (i<140 && i >=85) _25G50[i] = 2.73+0.00125*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G50[44],_25G50[84],_25G50[125] ); -_25G60(maxInd); - for (int i=0; i5) _25G60[i] = 2.64 + 0.0005*(i-5); - else if (i<85 && i>=45) _25G60[i] = 2.66+0.001*(i-45); - else if (i<140 && i >=85) _25G60[i] = 2.70+0.001*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G60[44],_25G60[84],_25G60[125] ); -_25G70(maxInd); - for (int i=0; i5) _25G70[i] = 2.64 + 0.00*(i-5); - else if (i<85 && i>=45) _25G70[i] = 2.64+0.00075*(i-45); - else if (i<140 && i >=85) _25G70[i] = 2.67+0.001*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G70[44],_25G70[84],_25G70[125] ); -_25G80(maxInd); - for (int i=0; i5) _25G80[i] = 2.63 + 0.00*(i-5); - else if (i<85 && i>=45) _25G80[i] = 2.63+0.0005*(i-45); - else if (i<140 && i >=85) _25G80[i] = 2.65+0.0005*(i-85); - } - //printf("25G %1.2f %1.2f %1.2f\n",_25G80[44],_25G80[84],_25G80[125] ); - - -//1G -_1G30(maxInd); - for (int i=0; i5) _1G30[i] = 2.58 + 0.00025*(i-5); - else if (i<85 && i>=45) _1G30[i] = 2.59+0.001*(i-45); - else if (i<140 && i >=85) _1G30[i] = 2.63+0.00125*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G30[44],_1G30[84],_1G30[125] ); -_1G40(maxInd); - for (int i=0; i5) _1G40[i] = 2.56 - 0.00025*(i-5); - else if (i<85 && i>=45) _1G40[i] = 2.55+0.0005*(i-45); - else if (i<140 && i >=85) _1G40[i] = 2.57+0.0005*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G40[44],_1G40[84],_1G40[125] ); -_1G50(maxInd); - for (int i=0; i5) _1G50[i] = 2.55 - 0.00025*(i-5); - else if (i<85 && i>=45) _1G50[i] = 2.54+0.00025*(i-45); - else if (i<140 && i >=85) _1G50[i] = 2.55+0.0005*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G50[44],_1G50[84],_1G50[125] ); -_1G60(maxInd); - for (int i=0; i5) _1G60[i] = 2.54 - 0.0005*(i-5); - else if (i<85 && i>=45) _1G60[i] = 2.52+0.00025*(i-45); - else if (i<140 && i >=85) _1G60[i] = 2.53+0.00025*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G60[44],_1G60[84],_1G60[125] ); -_1G70(maxInd); - for (int i=0; i5) _1G70[i] = 2.53 - 0.0005*(i-5); - else if (i<85 && i>=45) _1G70[i] = 2.51+0.0*(i-45); - else if (i<140 && i >=85) _1G70[i] = 2.51+0.00025*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G70[44],_1G70[84],_1G70[125] ); -_1G80(maxInd); - for (int i=0; i5) _1G80[i] = 2.52 - 0.0005*(i-5); - else if (i<85 && i>=45) _1G80[i] = 2.50+0.00*(i-45); - else if (i<140 && i >=85) _1G80[i] = 2.50+0.00*(i-85); - } - //printf("1G %1.2f %1.2f %1.2f\n",_1G80[44],_1G80[84],_1G80[125] ); - - -//10GY -_10GY30(maxInd); - for (int i=0; i5) _10GY30[i] = 2.52 - 0.001*(i-5); - else if (i<85 && i>=45) _10GY30[i] = 2.48-0.002*(i-45); - else if (i<140 && i >=85) _10GY30[i] = 2.40+0.0025*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY30[44],_10GY30[84],_10GY30[125] ); -_10GY40(maxInd); - for (int i=0; i5) _10GY40[i] = 2.48 - 0.0005*(i-5); - else if (i<85 && i>=45) _10GY40[i] = 2.46-0.0005*(i-45); - else if (i<140 && i >=85) _10GY40[i] = 2.44-0.0015*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY40[44],_10GY40[84],_10GY40[125] ); -_10GY50(maxInd); - for (int i=0; i5) _10GY50[i] = 2.48 - 0.00075*(i-5); - else if (i<85 && i>=45) _10GY50[i] = 2.45-0.00075*(i-45); - else if (i<140 && i >=85) _10GY50[i] = 2.42-0.00175*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY50[44],_10GY50[84],_10GY50[125] ); -_10GY60(maxInd); - for (int i=0; i5) _10GY60[i] = 2.47 - 0.00125*(i-5); - else if (i<85 && i>=45) _10GY60[i] = 2.42-0.00025*(i-45); - else if (i<140 && i >=85) _10GY60[i] = 2.41-0.0005*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY60[44],_10GY60[84],_10GY60[125] ); -_10GY70(maxInd); - for (int i=0; i5) _10GY70[i] = 2.46 - 0.001*(i-5); - else if (i<85 && i>=45) _10GY70[i] = 2.42+0.0*(i-45); - else if (i<140 && i >=85) _10GY70[i] = 2.42-0.001*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY70[44],_10GY70[84],_10GY70[125] ); -_10GY80(maxInd); - for (int i=0; i5) _10GY80[i] = 2.45 - 0.00075*(i-5); - else if (i<85 && i>=45) _10GY80[i] = 2.42 - 0.0005*(i-45); - else if (i<140 && i >=85) _10GY80[i] = 2.40-0.0005*(i-85); - } - //printf("10GY %1.2f %1.2f %1.2f\n",_10GY80[44],_10GY80[84],_10GY80[125] ); - - -//75GY -_75GY30(maxInd2); - for (int i=0; i5) _75GY30[i] = 2.36 - 0.0025*(i-5); - else if (i<90 && i>=45) _75GY30[i] = 2.26-0.00175*(i-45); - } - //printf("75GY %1.2f %1.2f\n",_75GY30[44],_75GY30[84] ); -_75GY40(maxInd2); - for (int i=0; i5) _75GY40[i] = 2.34 - 0.00175*(i-5); - else if (i<90 && i>=45) _75GY40[i] = 2.27-0.00225*(i-45); - } - //printf("75GY %1.2f %1.2f \n",_75GY40[44],_75GY40[84] ); -_75GY50(maxInd); - for (int i=0; i5) _75GY50[i] = 2.32 - 0.0015*(i-5); - else if (i<85 && i>=45) _75GY50[i] = 2.26-0.00175*(i-45); - else if (i<140 && i >=85) _75GY50[i] = 2.19-0.00325*(i-85); - } - //printf("75GY %1.2f %1.2f %1.2f %1.2f\n",_75GY50[44],_75GY50[84],_75GY50[125],_75GY50[139] ); -_75GY60(maxInd); - for (int i=0; i5) _75GY60[i] = 2.30 - 0.00125*(i-5); - else if (i<85 && i>=45) _75GY60[i] = 2.25-0.001*(i-45); - else if (i<140 && i >=85) _75GY60[i] = 2.21-0.0027*(i-85); - } - //printf("75GY %1.2f %1.2f %1.2f\n",_75GY60[44],_75GY60[84],_75GY60[125] ); -_75GY70(maxInd); - for (int i=0; i5) _75GY70[i] = 2.29 - 0.00125*(i-5); - else if (i<85 && i>=45) _75GY70[i] = 2.24-0.0015*(i-45); - else if (i<140 && i >=85) _75GY70[i] = 2.18-0.00175*(i-85); - } - //printf("75GY %1.2f %1.2f %1.2f\n",_75GY70[44],_75GY70[84],_75GY70[125] ); -_75GY80(maxInd); - for (int i=0; i5) _75GY80[i] = 2.27 - 0.001*(i-5); - else if (i<85 && i>=45) _75GY80[i] = 2.23 - 0.001*(i-45); - else if (i<140 && i >=85) _75GY80[i] = 2.19-0.00175*(i-85); - } - //printf("75GY %1.2f %1.2f %1.2f\n",_75GY80[44],_75GY80[84],_75GY80[125] ); - - -//55GY -_5GY30(maxInd2); - for (int i=0; i5) _5GY30[i] = 2.16 - 0.002*(i-5); - else if (i<90 && i>=45) _5GY30[i] = 2.07-0.0025*(i-45); - } - //printf("5GY %1.2f %1.2f\n",_5GY30[44],_5GY30[84] ); - -//5GY4: 2.14,2.04, 1.96, 1.91 //95 - -_5GY40(maxInd2); - for (int i=0; i5) _5GY40[i] = 2.14 - 0.0025*(i-5); - else if (i<90 && i>=45) _5GY40[i] = 2.04-0.003*(i-45); - } - //printf("5GY %1.2f %1.2f \n",_5GY40[44],_5GY40[84] ); -_5GY50(maxInd); - for (int i=0; i5) _5GY50[i] = 2.13 - 0.00175*(i-5); - else if (i<85 && i>=45) _5GY50[i] = 2.06-0.002*(i-45); - else if (i<140 && i >=85) _5GY50[i] = 1.98-0.00225*(i-85); - } - //printf("5GY %1.2f %1.2f %1.2f\n",_5GY50[44],_5GY50[84],_5GY50[125] ); -_5GY60(maxInd); - for (int i=0; i5) _5GY60[i] = 2.11 - 0.0015*(i-5); - else if (i<85 && i>=45) _5GY60[i] = 2.05-0.002*(i-45); - else if (i<140 && i >=85) _5GY60[i] = 1.97-0.00275*(i-85); - } - //printf("5GY %1.2f %1.2f %1.2f\n",_5GY60[44],_5GY60[84],_5GY60[125] ); -_5GY70(maxInd); - for (int i=0; i5) _5GY70[i] = 2.09 - 0.001*(i-5); - else if (i<85 && i>=45) _5GY70[i] = 2.05-0.00175*(i-45); - else if (i<140 && i >=85) _5GY70[i] = 1.98-0.002*(i-85); - } - //printf("5GY %1.2f %1.2f %1.2f\n",_5GY70[44],_5GY70[84],_5GY70[125] ); -_5GY80(maxInd); - for (int i=0; i5) _5GY80[i] = 2.07 - 0.001*(i-5); - else if (i<85 && i>=45) _5GY80[i] = 2.03 - 0.00075*(i-45); - else if (i<140 && i >=85) _5GY80[i] = 2.0-0.002*(i-85); - } - //printf("5GY %1.2f %1.2f %1.2f\n",_5GY80[44],_5GY80[84],_5GY80[125] ); - -#ifdef _DEBUG - t2e.set(); - if (settings->verbose) - printf("Lutf Munsell %d usec\n", t2e.etime(t1e)); -#endif } -void ImProcFunctions::MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone) { - int x=(int) memChprov; - int y=(int) chrom; - - //found the good LUT and calculate correction - - - //Blue purple correction PB + sky - if(zone==1) {//begin PB correction - if((lum > 5.0 && lum <15.0) ) { - if( (hue >= (_15PB10[x] - 0.035)) && (hue < (_15PB10[x] + 0.052) && x<=45)) {if(y>49) y=49;correction = _15PB10[y] - _15PB10[x] ;} - else if (( hue>=( _3PB10[x] -0.052)) && (hue < (_45PB10[x] + _3PB10[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB10[y] - _3PB10[x] ;} - else if (( hue>=(_45PB10[x] + _3PB10[x])/2.0) && (hue < (_45PB10[x] +0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB10[y] - _45PB10[x] ;} - else if (( hue>=(_6PB10[x] -0.052) && (hue < (_6PB10[x] + _75PB10[x])/2.0))) {correction = _6PB10[y] - _6PB10[x] ; } - else if (( hue>=(_6PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _75PB10[x])/2.0)) {correction = _75PB10[y] - _75PB10[x] ;} - else if (( hue>=(_9PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _10PB10[x])/2.0)) {correction = _9PB10[y] - _9PB10[x] ; } - else if (( hue>=(_10PB10[x] + _9PB10[x])/2.0) && (hue < (_1P10[x] + _10PB10[x])/2.0)) {correction = _10PB10[y] - _10PB10[x] ;} - else if (( hue>=(_10PB10[x] + _1P10[x])/2.0) && (hue < (_1P10[x] + _4P10[x])/2.0)) {correction = _1P10[y] - _1P10[x];} - else if (( hue>=(_1P10[x] + _4P10[x])/2.0) && (hue < (0.035 + _4P10[x])/2.0)) {correction = _4P10[y] - _4P10[x] ;} - } - else if ((lum >= 15.0 && lum <25.0)) { - if( (hue >= (_15PB20[x] - 0.035)) && (hue < (_15PB20[x] + _3PB20[x])/2.0) && x<=85) {if(y>89) y=89;correction = _15PB20[y] - _15PB20[x] ; } - else if (( hue>=(_15PB20[x] + _3PB20[x])/2.0) && (hue < (_45PB20[x] + _3PB20[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB20[y] - _3PB20[x] ; } - else if (( hue>=(_45PB20[x] + _3PB20[x])/2.0) && (hue < ( _45PB20[x] + 0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB20[y] - _45PB20[x] ;} - else if (( hue>=(_45PB20[x] + 0.052)) && (hue < (_6PB20[x] + _75PB20[x])/2.0)) {correction = _6PB20[y] - _6PB20[x];} - else if (( hue>=(_6PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _75PB20[x])/2.0)) {correction = _75PB20[y] - _75PB20[x] ;} - else if (( hue>=(_9PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _10PB20[x])/2.0)) {correction = _9PB20[y] - _9PB20[x] ; } - else if (( hue>=(_10PB20[x] + _9PB20[x])/2.0) && (hue < (_1P20[x] + _10PB20[x])/2.0)) {correction = _10PB20[y] - _10PB20[x] ;} - else if (( hue>=(_10PB20[x] + _1P20[x])/2.0) && (hue < (_1P20[x] + _4P20[x])/2.0)) {correction = _1P20[y] - _1P20[x] ; } - else if (( hue>=(_1P20[x] + _4P20[x])/2.0) && (hue < (0.035 + _4P20[x])/2.0)) {correction = _4P20[y] - _4P20[x] ; } - } - else if ((lum >= 25.0 && lum <35.0)) { - if( (hue >= (_15PB30[x] - 0.035)) && (hue < (_15PB30[x] + _3PB30[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB30[y] - _15PB30[x] ;} - else if (( hue>=(_15PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x] + _3PB30[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB30[y] - _3PB30[x] ;} - else if (( hue>=(_45PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB30[y] - _45PB30[x] ; } - else if (( hue>=( _45PB30[x]+ 0.052)) && (hue < (_6PB30[x] + _75PB30[x])/2.0)) {correction = _6PB30[y] - _6PB30[x] ; } - else if (( hue>=(_6PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _75PB30[x])/2.0)) {correction = _75PB30[y] - _75PB30[x] ;} - else if (( hue>=(_9PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _10PB30[x])/2.0)) {correction = _9PB30[y] - _9PB30[x] ; } - else if (( hue>=(_10PB30[x] + _9PB30[x])/2.0) && (hue < (_1P30[x] + _10PB30[x])/2.0)) {correction = _10PB30[y] - _10PB30[x] ;} - else if (( hue>=(_10PB30[x] + _1P30[x])/2.0) && (hue < (_1P30[x] + _4P30[x])/2.0)) {correction = _1P30[y] - _1P30[x] ; } - else if (( hue>=(_1P30[x] + _4P30[x])/2.0) && (hue < (0.035 + _4P30[x])/2.0)) {correction = _4P30[y] - _4P30[x] ;} - } - else if ((lum >= 35.0 && lum <45.0) ) { - if( (hue <= (_05PB40[x] + _15PB40[x])/2.0) && (hue > (_05PB40[x] + _10B40[x])/2.0) && x<75 ) {if(y>75) y=75; correction = _05PB40[y] - _05PB40[x] ;} - else if( (hue <= (_05PB40[x] + _10B40[x])/2.0) && (hue >(_10B40[x] + _9B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _10B40[y] - _10B40[x] ;} - else if( (hue <= (_10B40[x] + _9B40[x])/2.0) && (hue >(_9B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _9B40[y] - _9B40[x] ;} - else if( (hue <= (_9B40[x] + _7B40[x])/2.0) && (hue >(_5B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _7B40[y] - _7B40[x] ;} - else if (( hue<=(_5B40[x] + _7B40[x])/2.0) && (hue > (_5B40[x]-0.035)) && x < 70) {if(y>70) y=70; correction = _5B40[y] - _5B40[x] ; } // - - else if( (hue >= (_15PB40[x] - 0.035)) && (hue < (_15PB40[x] + _3PB40[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB40[y] - _15PB40[x] ; } - else if (( hue>=(_15PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x] + _3PB40[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB40[y] - _3PB40[x] ;} - else if (( hue>=(_45PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB40[y] - _45PB40[x] ;} - else if (( hue>=(_45PB40[x]+0.052)) && (hue < (_6PB40[x] + _75PB40[x])/2.0)) {correction = _6PB40[y] - _6PB40[x] ; } - else if (( hue>=(_6PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _75PB40[x])/2.0)) {correction = _75PB40[y] - _75PB40[x] ; } - else if (( hue>=(_9PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _10PB40[x])/2.0)) {correction = _9PB40[y] - _9PB40[x] ; } - else if (( hue>=(_10PB40[x] + _9PB40[x])/2.0) && (hue < (_1P40[x] + _10PB40[x])/2.0)) {correction = _10PB40[y] - _10PB40[x] ;} - else if (( hue>=(_10PB40[x] + _1P40[x])/2.0) && (hue < (_1P40[x] + _4P40[x])/2.0)) {correction = _1P40[y] - _1P40[x] ;} - else if (( hue>=(_1P40[x] + _4P40[x])/2.0) && (hue < (0.035 + _4P40[x])/2.0)) {correction = _4P40[y] - _4P40[x] ;} - } - else if ((lum >= 45.0 && lum <55.0) ) { - if( (hue <= (_05PB50[x] + _15PB50[x])/2.0) && (hue > (_05PB50[x] + _10B50[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB50[y] - _05PB50[x] ;} - else if( (hue <= (_05PB50[x] + _10B50[x])/2.0) && (hue >(_10B50[x] + _9B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B50[y] - _10B50[x] ;} - else if( (hue <= (_10B50[x] + _9B50[x])/2.0) && (hue >(_9B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B50[y] - _9B50[x] ;} - else if( (hue <= (_9B50[x] + _7B50[x])/2.0) && (hue >(_5B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B50[y] - _7B50[x] ;} - else if (( hue<=(_5B50[x] + _7B50[x])/2.0) && (hue > (_5B50[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B50[y] - _5B50[x] ; } // - - else if( (hue >= (_15PB50[x] - 0.035)) && (hue < (_15PB50[x] + _3PB50[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB50[y] - _15PB50[x] ; } - else if (( hue>=(_15PB50[x] + _3PB50[x])/2.0) && (hue < (_45PB50[x] + _3PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB50[y] - _3PB50[x] ;} - else if (( hue>=(_45PB50[x] + _3PB50[x])/2.0) && (hue < (_6PB50[x] + _45PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB50[y] - _45PB50[x] ; } - else if (( hue>=(_6PB50[x] + _45PB50[x])/2.0) && (hue < (_6PB50[x] + _75PB50[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB50[y] - _6PB50[x] ;} - else if (( hue>=(_6PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _75PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB50[y] - _75PB50[x] ;} - else if (( hue>=(_9PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB50[y] - _9PB50[x] ;} - else if (( hue>=(_10PB50[x] + _9PB50[x])/2.0) && (hue < (_1P50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB50[y] - _10PB50[x] ;} - else if (( hue>=(_10PB50[x] + _1P50[x])/2.0) && (hue < (_1P50[x] + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P50[y] - _1P50[x] ; } - else if (( hue>=(_1P50[x] + _4P50[x])/2.0) && (hue < (0.035 + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P50[y] - _4P50[x] ;} - } - else if ((lum >= 55.0 && lum <65.0) ) { - if( (hue <= (_05PB60[x] + _15PB60[x])/2.0) && (hue > (_05PB60[x] + _10B60[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB60[y] - _05PB60[x] ;} - else if( (hue <= (_05PB60[x] + _10B60[x])/2.0) && (hue >(_10B60[x] + _9B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B60[y] - _10B60[x] ;} - else if( (hue <= (_10B60[x] + _9B60[x])/2.0) && (hue >(_9B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B60[y] - _9B60[x] ;} - else if( (hue <= (_9B60[x] + _7B60[x])/2.0) && (hue >(_5B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B60[y] - _7B60[x] ;} - else if (( hue<=(_5B60[x] + _7B60[x])/2.0) && (hue > (_5B60[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B60[y] - _5B60[x] ; } // - - else if( (hue >= (_15PB60[x] - 0.035)) && (hue < (_15PB60[x] + _3PB60[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB60[y] - _15PB60[x] ; } - else if (( hue>=(_15PB60[x] + _3PB60[x])/2.0) && (hue < (_45PB60[x] + _3PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB60[y] - _3PB60[x] ;} - else if (( hue>=(_45PB60[x] + _3PB60[x])/2.0) && (hue < (_6PB60[x] + _45PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB60[y] - _45PB60[x] ;} - else if (( hue>=(_6PB60[x] + _45PB60[x])/2.0) && (hue < (_6PB60[x] + _75PB60[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB60[y] - _6PB60[x] ;} - else if (( hue>=(_6PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _75PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB60[y] - _75PB60[x] ; } - else if (( hue>=(_9PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB60[y] - _9PB60[x] ; } - else if (( hue>=(_10PB60[x] + _9PB60[x])/2.0) && (hue < (_1P60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB60[y] - _10PB60[x] ; } - else if (( hue>=(_10PB60[x] + _1P60[x])/2.0) && (hue < (_1P60[x] + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P60[y] - _1P60[x] ; } - else if (( hue>=(_1P60[x] + _4P60[x])/2.0) && (hue < (0.035 + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P60[y] - _4P60[x] ; } - } - else if ((lum >= 65.0 && lum < 75.0) ) { - if( (hue <= (_05PB70[x] + _15PB70[x])/2.0) && (hue > (_05PB70[x] + _10B70[x])/2.0) && x<50 ) {if(y>49) y=49; correction = _05PB70[y] - _05PB70[x] ;} - else if( (hue <= (_05PB70[x] + _10B70[x])/2.0) && (hue >(_10B70[x] + _9B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _10B70[y] - _10B70[x] ;} - else if( (hue <= (_10B70[x] + _9B70[x])/2.0) && (hue >(_9B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _9B70[y] - _9B70[x] ;} - else if( (hue <= (_9B70[x] + _7B70[x])/2.0) && (hue >(_5B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B70[y] - _7B70[x] ;} - else if (( hue<=(_5B70[x] + _7B70[x])/2.0) && (hue > (_5B70[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B70[y] - _5B70[x] ; } // - - else if( (hue >= (_15PB70[x] - 0.035)) && (hue < (_15PB70[x] + _3PB70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB70[y] - _15PB70[x] ; } - else if (( hue>=(_45PB70[x] + _3PB70[x])/2.0) && (hue < (_6PB70[x] + _45PB70[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB70[y] - _45PB70[x] ;} - else if (( hue>=(_6PB70[x] + _45PB70[x])/2.0) && (hue < (_6PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB70[y] - _6PB70[x] ;} - else if (( hue>=(_6PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB70[y] - _75PB70[x] ; } - else if (( hue>=(_9PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB70[y] - _9PB70[x] ; } - } - else if ((lum >= 75.0 && lum < 85.0) ) { - if( (hue <= (_05PB80[x] + _15PB80[x])/2.0) && (hue > (_05PB80[x] + _10B80[x])/2.0) && x<40 ) {if(y>39) y=39; correction = _05PB80[y] - _05PB80[x] ;} - else if( (hue <= (_05PB80[x] + _10B80[x])/2.0) && (hue >(_10B80[x] + _9B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _10B80[y] - _10B80[x] ;} - else if( (hue <= (_10B80[x] + _9B80[x])/2.0) && (hue >(_9B80[x] + _7B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _9B80[y] - _9B80[x] ;} - else if( (hue <= (_9B80[x] + _7B80[x])/2.0) && (hue >(_5B80[x] + _7B80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B80[y] - _7B80[x] ;} - else if (( hue<=(_5B80[x] + _7B80[x])/2.0) && (hue > (_5B80[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B80[y] - _5B80[x] ; } // - - else if( (hue >= (_15PB80[x] - 0.035)) && (hue < (_15PB80[x] + _3PB80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB80[y] - _15PB80[x] ; } - else if (( hue>=(_45PB80[x] + _3PB80[x])/2.0) && (hue < (_6PB80[x] + _45PB80[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB80[y] - _45PB80[x] ;} - else if (( hue>=(_6PB80[x] + _45PB80[x])/2.0) && (hue < (_6PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB80[y] - _6PB80[x] ;} - else if (( hue>=(_6PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB80[y] - _75PB80[x] ; } - else if (( hue>=(_9PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB80[y] - _9PB80[x] ; } - } - } // end PB correction - if(zone==2) {//red yellow correction - if((lum > 15.0 && lum < 25.0) ) { - if( (hue <= (_10YR20[x] + 0.035)) && (hue > (_10YR20[x] + _85YR20[x])/2.0) && x<=45) {if(y>49) y=49;correction = _10YR20[y] - _10YR20[x] ;} - else if (( hue<=(_85YR20[x] + _10YR20[x])/2.0) && (hue > (_85YR20[x] + 0.035) && x <= 45)) {if(y>49) y=49;correction = _85YR20[y] - _85YR20[x] ;} - } - else if ((lum >= 25.0 && lum <35.0)) { - if( (hue <= (_10YR30[x] + 0.035)) && (hue > (_10YR30[x] + _85YR30[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10YR30[y] - _10YR30[x] ;} - else if( (hue <= (_10YR30[x] + _85YR30[x])/2.0) && (hue >(_85YR30[x] + _7YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _85YR30[y] - _85YR30[x] ;} - else if (( hue<=(_85YR30[x] + _7YR30[x])/2.0) && (hue > (_7YR30[x] + _55YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR30[y] - _7YR30[x] ;} - else if (( hue<=(_7YR30[x] + _55YR30[x])/2.0) && (hue > (_55YR30[x] + _4YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR30[y] - _55YR30[x] ; } - else if (( hue<=(_55YR30[x] + _4YR30[x])/2.0) && (hue > (_4YR30[x] + _25YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR30[y] - _4YR30[x] ; } - else if (( hue<=(_4YR30[x] + _25YR30[x])/2.0) && (hue > (_25YR30[x] + _10R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR30[y] - _25YR30[x] ;} - else if (( hue<=(_25YR30[x] + _10R30[x])/2.0) && (hue > (_10R30[x] + _9R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R30[y] - _10R30[x] ; } - else if (( hue<=(_10R30[x] + _9R30[x])/2.0) && (hue > (_9R30[x] + _7R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R30[y] - _9R30[x] ;} - else if (( hue<=(_9R30[x] + _7R30[x])/2.0) && (hue > (_7R30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R30[y] - _7R30[x] ; } - } - else if ((lum >= 35.0 && lum <45.0)) { - if( (hue <= (_10YR40[x] + 0.035)) && (hue > (_10YR40[x] + _85YR40[x])/2.0)&& x<85) {if(y>89) y=89;correction = _10YR40[y] - _10YR40[x] ;} - else if( (hue <= (_10YR40[x] + _85YR40[x])/2.0) && (hue >(_85YR40[x] + _7YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR40[y] - _85YR40[x] ;} - else if (( hue<=(_85YR40[x] + _7YR40[x])/2.0) && (hue > (_7YR40[x] + _55YR40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _7YR40[y] - _7YR40[x] ;} - else if (( hue<=(_7YR40[x] + _55YR40[x])/2.0) && (hue > (_55YR40[x] + _4YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _55YR40[y] - _55YR40[x] ; } - else if (( hue<=(_55YR40[x] + _4YR40[x])/2.0) && (hue > (_4YR40[x] + _25YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _4YR40[y] - _4YR40[x] ; } - else if (( hue<=(_4YR40[x] + _25YR40[x])/2.0) && (hue > (_25YR40[x] + _10R40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR40[y] - _25YR40[x] ;} - else if (( hue<=(_25YR40[x] + _10R40[x])/2.0) && (hue > (_10R40[x] + _9R40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10R40[y] - _10R40[x] ; } - else if (( hue<=(_10R40[x] + _9R40[x])/2.0) && (hue > (_9R40[x] + _7R40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _9R40[y] - _9R40[x] ;} - else if (( hue<=(_9R40[x] + _7R40[x])/2.0) && (hue > (_7R40[x] -0.035))&& x < 85 ) {if(y>89) y=89;correction = _7R40[y] - _7R40[x] ; } - } - else if ((lum >= 45.0 && lum <55.0)) { - if( (hue <= (_10YR50[x] + 0.035)) && (hue > (_10YR50[x] + _85YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10YR50[y] - _10YR50[x] ;} - else if( (hue <= (_10YR50[x] + _85YR50[x])/2.0) && (hue >(_85YR50[x] + _7YR50[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR50[y] - _85YR50[x] ;} - else if (( hue<=(_85YR50[x] + _7YR50[x])/2.0) && (hue > (_7YR50[x] + _55YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR50[y] - _7YR50[x] ;} - else if (( hue<=(_7YR50[x] + _55YR50[x])/2.0) && (hue > (_55YR50[x] + _4YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR50[y] - _55YR50[x] ; } - else if (( hue<=(_55YR50[x] + _4YR50[x])/2.0) && (hue > (_4YR50[x] + _25YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR50[y] - _4YR50[x] ; } - else if (( hue<=(_4YR50[x] + _25YR50[x])/2.0) && (hue > (_25YR50[x] + _10R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR50[y] - _25YR50[x] ;} - else if (( hue<=(_25YR50[x] + _10R50[x])/2.0) && (hue > (_10R50[x] + _9R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R50[y] - _10R50[x] ; } - else if (( hue<=(_10R50[x] + _9R50[x])/2.0) && (hue > (_9R50[x] + _7R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R50[y] - _9R50[x] ;} - else if (( hue<=(_9R50[x] + _7R50[x])/2.0) && (hue > (_7R50[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R50[y] - _7R50[x] ; } - } - else if ((lum >= 55.0 && lum <65.0)) { - if( (hue <= (_10YR60[x] + 0.035)) && (hue > (_10YR60[x] + _85YR60[x])/2.0)) {;correction = _10YR60[y] - _10YR60[x] ;} - else if( (hue <= (_10YR60[x] + _85YR60[x])/2.0) && (hue >(_85YR60[x] + _7YR60[x])/2.0) ) {;correction = _85YR60[y] - _85YR60[x] ;} - else if (( hue<=(_85YR60[x] + _7YR60[x])/2.0) && (hue > (_7YR60[x] + _55YR60[x])/2.0)) {correction = _7YR60[y] - _7YR60[x] ;} - else if (( hue<=(_7YR60[x] + _55YR60[x])/2.0) && (hue > (_55YR60[x] + _4YR60[x])/2.0)) {correction = _55YR60[y] - _55YR60[x] ; } - else if (( hue<=(_55YR60[x] + _4YR60[x])/2.0) && (hue > (_4YR60[x] + _25YR60[x])/2.0)) {correction = _4YR60[y] - _4YR60[x] ; } - else if (( hue<=(_4YR60[x] + _25YR60[x])/2.0) && (hue > (_25YR60[x] + _10R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR60[y] - _25YR60[x] ;} - else if (( hue<=(_25YR60[x] + _10R60[x])/2.0) && (hue > (_10R60[x] + _9R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R60[y] - _10R60[x] ; } - else if (( hue<=(_10R60[x] + _9R60[x])/2.0) && (hue > (_9R60[x] + _7R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R60[y] - _9R60[x] ;} - else if (( hue<=(_9R60[x] + _7R60[x])/2.0) && (hue > (_7R60[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R60[y] - _7R60[x] ; } - } - else if ((lum >= 65.0 && lum <75.0)) { - if( (hue <= (_10YR70[x] + 0.035)) && (hue > (_10YR70[x] + _85YR70[x])/2.0)) {correction = _10YR70[y] - _10YR70[x] ;} - else if( (hue <= (_10YR70[x] + _85YR70[x])/2.0) && (hue >(_85YR70[x] + _7YR70[x])/2.0)) {correction = _85YR70[y] - _85YR70[x] ;} - if (( hue<=(_85YR70[x] + _7YR70[x])/2.0) && (hue > (_7YR70[x] + _55YR70[x])/2.0)) {correction = _7YR70[y] - _7YR70[x] ;} - else if (( hue<=(_7YR70[x] + _55YR70[x])/2.0) && (hue > (_55YR70[x] + _4YR70[x])/2.0)) {correction = _55YR70[y] - _55YR70[x] ; } - else if (( hue<=(_55YR70[x] + _4YR70[x])/2.0) && (hue > (_4YR70[x] + _25YR70[x])/2.0)) {correction = _4YR70[y] - _4YR70[x] ; } - else if (( hue<=(_4YR70[x] + _25YR70[x])/2.0) && (hue > (_25YR70[x] + _10R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR70[y] - _25YR70[x] ;} - else if (( hue<=(_25YR70[x] + _10R70[x])/2.0) && (hue > (_10R70[x] + _9R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R70[y] - _10R70[x] ; } - else if (( hue<=(_10R70[x] + _9R70[x])/2.0) && (hue > (_9R70[x] + _7R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R70[y] - _9R70[x] ;} - else if (( hue<=(_9R70[x] + _7R70[x])/2.0) && (hue > (_7R70[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R70[y] - _7R70[x] ; } - } - else if ((lum >= 75.0 && lum <85.0)) { - if( (hue <= (_10YR80[x] + 0.035)) && (hue > (_10YR80[x] + _85YR80[x])/2.0)) {correction = _10YR80[y] - _10YR80[x] ;} - else if( (hue <= (_10YR80[x] + _85YR80[x])/2.0) && (hue >(_85YR80[x] + _7YR80[x])/2.0)) {correction = _85YR80[y] - _85YR80[x] ;} - else if (( hue<=(_85YR80[x] + _7YR80[x])/2.0) && (hue > (_7YR80[x] + _55YR80[x])/2.0) && x<85) {if(y>89) y=89;correction = _7YR80[y] - _7YR80[x] ;} - else if (( hue<=(_7YR80[x] + _55YR80[x])/2.0) && (hue > (_55YR80[x] + _4YR80[x])/2.0) && x <45) {correction = _55YR80[y] - _55YR80[x] ; } - else if (( hue<=(_55YR80[x] + _4YR80[x])/2.0) && (hue > (_4YR80[x] - 0.035) && x<45)) {if(y>49) y=49;correction = _4YR80[y] - _4YR80[x] ; } - } - else if ((lum >= 85.0 && lum <95.0)) { - if( (hue <= (_10YR90[x] + 0.035)) && (hue > (_10YR90[x] -0.035) && x<85)) {if(y>89) y=89;correction = _10YR90[y] - _10YR90[x] ;} - else if ( hue<=(_85YR90[x] + 0.035) && hue > (_85YR90[x] -0.035) && x<85) {if(y>89) y=89;correction = _85YR90[y] - _85YR90[x] ;} - else if (( hue<=(_55YR90[x] + 0.035) && (hue > (_55YR90[x] - 0.035) && x<45))) {if(y>49) y=49;correction = _55YR90[y] - _55YR90[x] ; } - }//end red yellow - } - if(zone==3) {//Green yellow correction - if ((lum >= 25.0 && lum <35.0)) { - if( (hue <= (_7G30[x] + 0.035)) && (hue > (_7G30[x] + _5G30[x])/2.0) ) {correction = _7G30[y] - _7G30[x] ;} - else if( (hue <= (_7G30[x] + _5G30[x])/2.0) && (hue >(_5G30[x] + _25G30[x])/2.0)) {correction = _5G30[y] - _5G30[x] ;} - else if (( hue<=(_25G30[x] + _5G30[x])/2.0) && (hue > (_25G30[x] + _1G30[x])/2.0)) {correction = _25G30[y] - _25G30[x] ;} - else if (( hue<=(_1G30[x] + _25G30[x])/2.0) && (hue > (_1G30[x] + _10GY30[x])/2.0)) {correction = _1G30[y] - _1G30[x] ; } - else if (( hue<=(_1G30[x] + _10GY30[x])/2.0) && (hue > (_10GY30[x] + _75GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY30[y] - _10GY30[x] ; } - else if (( hue<=(_10GY30[x] + _75GY30[x])/2.0) && (hue > (_75GY30[x] + _5GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY30[y] - _75GY30[x] ;} - else if (( hue<=(_5GY30[x] + _75GY30[x])/2.0) && (hue > (_5GY30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _5GY30[y] - _5GY30[x] ; } - } - else if ((lum >= 35.0 && lum <45.0)) { - if( (hue <= (_7G40[x] + 0.035)) && (hue > (_7G40[x] + _5G40[x])/2.0) ) {correction = _7G40[y] - _7G40[x] ;} - else if( (hue <= (_7G40[x] + _5G40[x])/2.0) && (hue >(_5G40[x] + _25G40[x])/2.0)) {correction = _5G40[y] - _5G40[x] ;} - else if (( hue<=(_25G40[x] + _5G40[x])/2.0) && (hue > (_25G40[x] + _1G40[x])/2.0)) {correction = _25G40[y] - _25G40[x] ;} - else if (( hue<=(_1G40[x] + _25G40[x])/2.0) && (hue > (_1G40[x] + _10GY40[x])/2.0)) {correction = _1G40[y] - _1G40[x] ; } - else if (( hue<=(_1G40[x] + _10GY40[x])/2.0) && (hue > (_10GY40[x] + _75GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY40[y] - _10GY40[x] ; } - else if (( hue<=(_10GY40[x] + _75GY40[x])/2.0) && (hue > (_75GY40[x] + _5GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY40[y] - _75GY40[x] ;} - else if (( hue<=(_5GY40[x] + _75GY40[x])/2.0) && (hue > (_5GY40[x]-0.035)) && x < 85) {if(y>89) y=89; correction = _5GY40[y] - _5GY40[x] ; } // - } - else if ((lum >= 45.0 && lum <55.0)) { - if( (hue <= (_7G50[x] + 0.035)) && (hue > (_7G50[x] + _5G50[x])/2.0) ) {correction = _7G50[y] - _7G50[x] ;} - else if( (hue <= (_7G50[x] + _5G50[x])/2.0) && (hue >(_5G50[x] + _25G50[x])/2.0)) {correction = _5G50[y] - _5G50[x] ;} - else if (( hue<=(_25G50[x] + _5G50[x])/2.0) && (hue > (_25G50[x] + _1G50[x])/2.0)) {correction = _25G50[y] - _25G50[x] ;} - else if (( hue<=(_1G50[x] + _25G50[x])/2.0) && (hue > (_1G50[x] + _10GY50[x])/2.0)) {correction = _1G50[y] - _1G50[x] ; } - else if (( hue<=(_1G50[x] + _10GY50[x])/2.0) && (hue > (_10GY50[x] + _75GY50[x])/2.0)) {correction = _10GY50[y] - _10GY50[x] ; } - else if (( hue<=(_10GY50[x] + _75GY50[x])/2.0) && (hue > (_75GY50[x] + _5GY50[x])/2.0)) {correction = _75GY50[y] - _75GY50[x] ;} - else if (( hue<=(_5GY50[x] + _75GY50[x])/2.0) && (hue > (_5GY50[x] -0.035))) {correction = _5GY50[y] - _5GY50[x] ; } - } - else if ((lum >= 55.0 && lum <65.0)) { - if( (hue <= (_7G60[x] + 0.035)) && (hue > (_7G60[x] + _5G60[x])/2.0) ) {correction = _7G60[y] - _7G60[x] ;} - else if( (hue <= (_7G60[x] + _5G60[x])/2.0) && (hue >(_5G60[x] + _25G60[x])/2.0)) {correction = _5G60[y] - _5G60[x] ;} - else if (( hue<=(_25G60[x] + _5G60[x])/2.0) && (hue > (_25G60[x] + _1G60[x])/2.0)) {correction = _25G60[y] - _25G60[x] ;} - else if (( hue<=(_1G60[x] + _25G60[x])/2.0) && (hue > (_1G60[x] + _10GY60[x])/2.0)) {correction = _1G60[y] - _1G60[x] ; } - else if (( hue<=(_1G60[x] + _10GY60[x])/2.0) && (hue > (_10GY60[x] + _75GY60[x])/2.0)) {correction = _10GY60[y] - _10GY60[x] ; } - else if (( hue<=(_10GY60[x] + _75GY60[x])/2.0) && (hue > (_75GY60[x] + _5GY60[x])/2.0)) {correction = _75GY60[y] - _75GY60[x] ;} - else if (( hue<=(_5GY60[x] + _75GY60[x])/2.0) && (hue > (_5GY60[x] -0.035))) {correction = _5GY60[y] - _5GY60[x] ; } - } - else if ((lum >= 65.0 && lum <75.0)) { - if( (hue <= (_7G70[x] + 0.035)) && (hue > (_7G70[x] + _5G70[x])/2.0) ) {correction = _7G70[y] - _7G70[x] ;} - else if( (hue <= (_7G70[x] + _5G70[x])/2.0) && (hue >(_5G70[x] + _25G70[x])/2.0)) {correction = _5G70[y] - _5G70[x] ;} - else if (( hue<=(_25G70[x] + _5G70[x])/2.0) && (hue > (_25G70[x] + _1G70[x])/2.0)) {correction = _25G70[y] - _25G70[x] ;} - else if (( hue<=(_1G70[x] + _25G70[x])/2.0) && (hue > (_1G70[x] + _10GY70[x])/2.0)) {correction = _1G70[y] - _1G70[x] ; } - else if (( hue<=(_1G70[x] + _10GY70[x])/2.0) && (hue > (_10GY70[x] + _75GY70[x])/2.0)) {correction = _10GY70[y] - _10GY70[x] ; } - else if (( hue<=(_10GY70[x] + _75GY70[x])/2.0) && (hue > (_75GY70[x] + _5GY70[x])/2.0)) {correction = _75GY70[y] - _75GY70[x] ;} - else if (( hue<=(_5GY70[x] + _75GY70[x])/2.0) && (hue > (_5GY70[x] -0.035))) {correction = _5GY70[y] - _5GY70[x] ; } - } - else if ((lum >= 75.0 && lum <85.0)) { - if( (hue <= (_7G80[x] + 0.035)) && (hue > (_7G80[x] + _5G80[x])/2.0) ) {correction = _7G80[y] - _7G80[x] ;} - else if( (hue <= (_7G80[x] + _5G80[x])/2.0) && (hue >(_5G80[x] + _25G80[x])/2.0)) {correction = _5G80[y] - _5G80[x] ;} - else if (( hue<=(_25G80[x] + _5G80[x])/2.0) && (hue > (_25G80[x] + _1G80[x])/2.0)) {correction = _25G80[y] - _25G80[x] ;} - else if (( hue<=(_1G80[x] + _25G80[x])/2.0) && (hue > (_1G80[x] + _10GY80[x])/2.0)) {correction = _1G80[y] - _1G80[x] ; } - else if (( hue<=(_1G80[x] + _10GY80[x])/2.0) && (hue > (_10GY80[x] + _75GY80[x])/2.0)) {correction = _10GY80[y] - _10GY80[x] ; } - else if (( hue<=(_10GY80[x] + _75GY80[x])/2.0) && (hue > (_75GY80[x] + _5GY80[x])/2.0)) {correction = _75GY80[y] - _75GY80[x] ;} - else if (( hue<=(_5GY80[x] + _75GY80[x])/2.0) && (hue > (_5GY80[x] -0.035))) {correction = _5GY80[y] - _5GY80[x] ; } - }//end green yellow - - } - - if(zone==4) {//Red purple correction : only for L < 30 - if ((lum > 5.0 && lum < 15.0)) { - if( (hue <= (_5R10[x] + 0.035)) && (hue > (_5R10[x] - 0.043)) && x<45) {if(y>44) y=44;correction = _5R10[y] - _5R10[x] ;} - else if( (hue <= (_25R10[x] + 0.043)) && (hue >(_25R10[x] + _10RP10[x])/2.0) && x<45 ) {if(y>44) y=44;correction = _25R10[y] - _25R10[x] ;} - else if ( (hue <=(_25R10[x] + _10RP10[x])/2.0) && (hue > (_10RP10[x] -0.035) ) && x<45){if(y>44) y=44; correction = _10RP10[y] - _10RP10[x] ;} - } - else if ((lum >= 15.0 && lum <25.0)) { - if( (hue <= (_5R20[x] + 0.035)) && (hue > (_5R20[x] + _25R20[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _5R20[y] - _5R20[x] ;} - else if( (hue <= (_5R20[x] + _25R20[x])/2.0) && (hue >(_10RP20[x] + _25R20[x])/2.0) && x<70) {if(y>70) y=70;correction = _25R20[y] - _25R20[x] ;} - else if (( hue<=(_10RP20[x] + _25R20[x])/2.0) && (hue > (_10RP20[x] -0.035)) && x<70) {if(y>70) y=70; correction = _10RP20[y] - _10RP20[x] ;} - } - else if ((lum >= 25.0 && lum <35.0)) { - if( (hue <= (_5R30[x] + 0.035)) && (hue > (_5R30[x] + _25R30[x])/2.0) && x<85 ) {if(y>85) y=85;correction = _5R30[y] - _5R30[x] ;} - else if( (hue <= (_5R30[x] + _25R30[x])/2.0) && (hue >(_10RP30[x] + _25R30[x])/2.0) && x< 85) {if(y>85) y=85;correction = _25R30[y] - _25R30[x] ;} - else if (( hue<=(_10RP30[x] + _25R30[x])/2.0) && (hue > (_10RP30[x] -0.035)) && x<85) {if(y>85) y=85; correction = _10RP30[y] - _10RP30[x] ;} - }//end red purple - } -} - - /* - * copyright (c)2011 Jacques Desmis - * skin color: mixed from NX2 skin color palette, Von Luschan, and photos of people white, - * black, yellow....there are some little exceptions...cover 99% case - * pay attention to white balance, and do not change hue and saturation, upstream of the modification - * - */ -void ImProcFunctions::skinsat (float lum, float hue, float chrom, float &satreduc) { - - float reduction=0.3;// to be adapted...by tests - float extendedreduction=0.4; - float extendedreduction2=0.6; - - float C9=0.0, C8=0.0, C7=0.0, C4=0.0, C3=0.0, C2=0.0, C1=0.0; - float H9=0.0, H8=0.0, H7=0.0, H4=0.0, H3=0.0, H2=0.0, H1=0.0, H10=0.0,H11=0.0; - H9=0.05;H8=0.25;H7=0.1;H4=0.02;H3=0.02;H2=0.1;H1=0.1;H10=-0.2;H11=-0.2;//H10 and H11 are curious...H11=-0.8 ?? - C9=8.0;C8=15.0;C7=12.0;C4=7.0;C3=5.0;C2=5.0;C1=5.0; - // wide area for transition - if(lum >= 92.0 && (hue > -0.1 && hue < 1.65) && (chrom > 7.0 && chrom < (18.0))) satreduc=extendedreduction2; - else if (lum >= 85.0 && lum < 92.0 && (hue > 0.0 && hue < 1.65) && (chrom > 7.0 && chrom < (35.0+C9))) satreduc=extendedreduction2; - else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.65) && (chrom > 7.0 && chrom < (55.0+C9) )) satreduc=extendedreduction2; - else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.60) && (chrom > 7.0 && chrom < (45.0+C1) )) satreduc=extendedreduction2; - - // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation - - if(lum >= 92.0 && (hue > 0.8 && hue < 1.65) && (chrom > 7.0 && chrom < (15.0))) satreduc=extendedreduction; - else if(lum >= 85.0 && lum < 92.0 && (hue > 0.70 && hue < 1.4) && (chrom > 7.0 && chrom < (26.0+C9))) satreduc=extendedreduction; - else if ((lum > 20 && lum < 85) && (hue > (0.02 + H11) && hue < 1.5) && (chrom > 7.0 && chrom < (48.0+C9) )) satreduc=extendedreduction; - else if (lum < 20.0 && (hue > (0.02+H11) && hue < 1.0) && (chrom > 7.0 && chrom < (35.0+C1) )) satreduc=extendedreduction; - - // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 - if(lum >= 85.0 && (hue > (0.78-H9) && hue < (1.18+H9)) && (chrom > 8.0 && chrom < (14.0+C9))) satreduc=reduction; - else if ((lum >= 70.0 && lum < 85.0) && (hue > 0.4 && hue < (1.04+H8)) && (chrom > 8.0 && chrom < (35.0+C8))) satreduc=reduction; - else if ((lum >= 52.0 && lum < 70.0) && (hue > 0.3 && hue < (1.27+H7)) && (chrom > 11.0 && chrom < (35.0+C7))) satreduc=reduction; - else if ((lum >= 35.0 && lum < 52.0) && (hue > 0.3 && hue < (1.25+H4)) && (chrom > 13.0 && chrom < (37.0+C4))) satreduc=reduction; - else if ((lum >= 20.0 && lum < 35.0) && (hue > 0.3 && hue < (1.20+H3)) && (chrom > 7.0 && chrom <(35.0+C3) )) satreduc=reduction; - else if ((lum > 10.0 && lum < 20.0) && (hue > (0.0 + H10) && hue < (0.95 +H2)) && (chrom > 8.0 && chrom < (23.0+C2))) satreduc=reduction; - else if ((lum < 10.0) && (hue > (0.02 + H10) && hue < (0.90+H1)) && (chrom > 8.0 && chrom < (23.0+C1))) satreduc=reduction; // no data : extrapolate -} - -/* - * vibrance correction + * Vibrance correction * copyright (c)2011 Jacques Desmis and Jean-Christophe Frisch * */ void ImProcFunctions::vibrance (LabImage* lab) { - if (!params->vibrance.enabled || (!params->vibrance.pastels && !params->vibrance.saturated)) + + int skip=1; //scale==1 ? 1 : 16; + bool skinCurveIsSet=false; + DiagonalCurve* dcurve = NULL; + dcurve = new DiagonalCurve (params->vibrance.skintonescurve, CURVES_MIN_POLY_POINTS/skip); + if (dcurve) { + if (!dcurve->isIdentity()) { + skinCurveIsSet = true; + } + else { + delete dcurve; + dcurve = NULL; + } + } + + if (!params->vibrance.enabled || (!skinCurveIsSet && !params->vibrance.pastels && !params->vibrance.saturated)) { + if (dcurve) { + delete dcurve; + dcurve = NULL; + } return; + } int width = lab->W, height = lab->H; #ifdef _DEBUG MyTime t1e,t2e; t1e.set(); - - float maxdeltaHueBP=0.0,maxdeltaHueRY=0.0,maxdeltaHueGY=0.0, maxdeltaHueRP=0.0; - int negat=0, moreRGB=0, negsat=0 ,moresat=0; - int Munspb=0, Munsry=0, Munsgy=0, Munsrp=0; - int depass=0; + int negat=0, moreRGB=0, negsat=0, moresat=0; #endif - /*float *LL,*CC,*HH; + // skin hue curve + // I use diagonal because I think it's better + LUTf skin_curve (65536,0); - LL = new float[width*height];//pointer for ulterior usage(convolution...) - CC = new float[width*height]; - HH = new float[width*height]; - */ + fillCurveArrayVib(dcurve, skin_curve, skip, skinCurveIsSet); + if (dcurve) { + delete dcurve; + dcurve = NULL; + } + + +// skin_curve.dump("skin_curve"); float chromaPastel = float(params->vibrance.pastels) / 100.0f; float chromaSatur = float(params->vibrance.saturated) / 100.0f; @@ -2011,18 +136,23 @@ void ImProcFunctions::vibrance (LabImage* lab) { float transitionweighting = static_cast(params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f; bool highlight = params->hlrecovery.enabled;//Get the value if "highlight reconstruction" is activated + bool protectskins = params->vibrance.protectskins; + bool avoidcolorshift = params->vibrance.avoidcolorshift; + #ifdef _DEBUG -#pragma omp parallel default(shared) firstprivate(lab, width, chromaPastel, chromaSatur, highlight, limitpastelsatur, transitionweighting) reduction(+: negat, moreRGB, negsat ,moresat, Munspb, Munsry, Munsgy, Munsrp, depass) if (multiThread) + MunsellDebugInfo* MunsDebugInfo = NULL; + if (avoidcolorshift) + MunsDebugInfo = new MunsellDebugInfo(); + +#pragma omp parallel default(shared) firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, \ + transitionweighting, protectskins, avoidcolorshift, MunsDebugInfo) reduction(+: negat, moreRGB, negsat, moresat) if (multiThread) #else -#pragma omp parallel default(shared) firstprivate(lab, width, chromaPastel, chromaSatur, highlight, limitpastelsatur, transitionweighting) if (multiThread) +#pragma omp parallel default(shared) firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, \ + transitionweighting, protectskins, avoidcolorshift) if (multiThread) #endif { - float LL,CC,HH; - float R,G,B,RR,GG,BB; - float fy,fx,fz,x_,y_,z_,Lprov,Lprov1,aprov1,bprov1,aprovn,bprovn,fxx,fyy,fzz,xx_,yy_,zz_; - float saturation; TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); //inverse matrix user select double wip[3][3] = { @@ -2030,202 +160,160 @@ void ImProcFunctions::vibrance (LabImage* lab) { {wiprof[1][0],wiprof[1][1],wiprof[1][2]}, {wiprof[2][0],wiprof[2][1],wiprof[2][2]} }; - float Chprov,memChprov,Chprov1; - float satredu;//reduct sat in function of skin float sathue[5],sathue2[4];// adjust sat in function of hue - float correctionHue; // Munsell's correction - int zone=0; - bool allwaysingamut=true; + const float p00=0.07f; // Fitting limitpastelsatur into the real 0.07->1.0 range - limitpastelsatur = limitpastelsatur*0.93f + 0.07f; - + limitpastelsatur = limitpastelsatur*(1.0f-p00) + p00; float p0,p1,p2;//adapt limit of pyramid to psThreshold float s0,s1,s2; - float maxdp=(limitpastelsatur-0.07)/4.0; - float maxds=(1.0-limitpastelsatur)/4.0; - p0=0.07+maxdp; - p1=0.07+2.0*maxdp; - p2=0.07+3.0*maxdp; + float maxdp=(limitpastelsatur-p00)/4.0f; + float maxds=(1.0-limitpastelsatur)/4.0f; + p0=p00+maxdp; + p1=p00+2.0f*maxdp; + p2=p00+3.0f*maxdp; s0=limitpastelsatur + maxds; - s1=limitpastelsatur + 2.0*maxds; - s2=limitpastelsatur + 3.0*maxds; + s1=limitpastelsatur + 2.0f*maxds; + s2=limitpastelsatur + 3.0f*maxds; - float chromamean=0.; + float chromamean=0.0f; if(chromaPastel != chromaSatur){ //if sliders pastels and saturated are different: transition with a double linear interpolation: between p2 and limitpastelsatur, and between limitpastelsatur and s0 //modify the "mean" point in function of double threshold => differential transition chromamean = maxdp * (chromaSatur-chromaPastel) / (s0-p2) + chromaPastel; // move chromaMean up or down depending on transitionCtrl - if (transitionweighting > 0.0) { - float _chromamean = chromamean; + if (transitionweighting > 0.0f) { chromamean = (chromaSatur-chromamean) * transitionweighting + chromamean; } - else if (transitionweighting < 0.0) { - float _chromamean = chromamean; + else if (transitionweighting < 0.0f) { chromamean = (chromamean-chromaPastel) * transitionweighting + chromamean; } } - if (settings->verbose) printf("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0,p1,p2,s0,s1,s2); - if (settings->verbose) printf("vibrance: pastel=%f satur=%f limit= %1.2f chromamean=%0.5f \n",1.0+chromaPastel,1.0+chromaSatur, limitpastelsatur, chromamean); - +#ifdef _OPENMP + if (settings->verbose && omp_get_thread_num()==0) { +#else + if (settings->verbose) { +#endif + printf("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0,p1,p2,s0,s1,s2); + printf(" pastel=%f satur=%f limit= %1.2f chromamean=%0.5f\n",1.0f+chromaPastel,1.0f+chromaSatur, limitpastelsatur, chromamean); + } #pragma omp for schedule(dynamic, 10) for (int i=0; iL[i][j]/327.68f; - CC=sqrt(lab->a[i][j]/327.68f*lab->a[i][j]/327.68f + lab->b[i][j]/327.68f*lab->b[i][j]/327.68f); - HH=atan2(lab->b[i][j],lab->a[i][j]); + float LL=lab->L[i][j]/327.68f; + float CC=sqrt(SQR(lab->a[i][j]/327.68f)+ SQR(lab->b[i][j]/327.68f)); + float HH=atan2(lab->b[i][j],lab->a[i][j]); //double pyramid: LL and HH //I try to take into account: Munsell response (human vision) and Gamut..(less response for red): preferably using Prophoto or WideGamut //blue: -1.80 -3.14 green = 2.1 3.14 green-yellow=1.4 2.1 red:0 1.4 blue-purple:-0.7 -1.4 purple: 0 -0.7 //these values allow a better and differential response - if(LL < 20.0) {//more for blue-purple, blue and red modulate - if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=1.05;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue - else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.4;sathue[1]=1.3;sathue[2]=1.2;sathue[3]=1.15;sathue[4]=0.4;sathue2[0]=1.15;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//green - else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//green yellow 1.2 1.1 - else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.6;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.15;sathue2[2]=1.1 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 - // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.1;sathue[2]=1.1;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//red 0.8 0.7 - else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//red 0.8 0.7 - else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple + if(LL < 20.0f) {//more for blue-purple, blue and red modulate + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=1.05f;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.6f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.15f;sathue2[2]=1.1f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.4f;sathue[1]=1.3f;sathue[2]=1.2f;sathue[3]=1.15f;sathue[4]=0.4f;sathue2[0]=1.15f;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green } - else if (LL>=20 && LL< 50) {//more for blue and green, less for red and green-yellow - if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.5;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue - else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.5;sathue[1]=1.4;sathue[2]=1.3;sathue[3]=1.2 ;sathue[4]=0.4;sathue2[0]=1.2 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//green - else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.1;sathue[1]=1.1;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=0.9 ;sathue2[1]=0.8 ;sathue2[2]=0.7 ;sathue2[3]=0.6;}//green yellow 1.2 1.1 - else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1;sathue[3]=1.05;sathue[4]=0.4;sathue2[0]=1.05;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 - else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=1.0 ;sathue[4]=0.4;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple - // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8;sathue[3]=0.8 ;sathue[4]=0.4;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 - else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8 ;sathue[4]=0.4;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else if (LL< 50.0f) {//more for blue and green, less for red and green-yellow + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.5f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=1.05f;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=0.9f ;sathue2[1]=0.8f ;sathue2[2]=0.7f ;sathue2[3]=0.6f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.5f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green } - else if (LL>=50 && LL< 80) {//more for green, less for red and green-yellow - if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.15;sathue[3]=1.1 ;sathue[4]=0.3;sathue2[0]=1.1 ;sathue2[1]=1.1 ;sathue2[2]=1.05;sathue2[3]=1.0;}//blue - else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.6;sathue[1]=1.4;sathue[2]=1.3 ;sathue[3]=1.25;sathue[4]=0.3;sathue2[0]=1.25;sathue2[1]=1.2 ;sathue2[2]=1.15;sathue2[3]=1.05;}//green - even with Prophoto green are too "little" 1.5 1.3 - else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.1 ;sathue[3]=1.05;sathue[4]=0.3;sathue2[0]=1.0 ;sathue2[1]=0.9 ;sathue2[2]=0.8 ;sathue2[3]=0.7;}//green yellow 1.2 1.1 - else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.3;sathue[1]=1.2;sathue[2]=1.15;sathue[3]=1.1 ;sathue[4]=0.3;sathue2[0]=1.1 ;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//blue purple 1.2 1.1 - else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0 ;sathue[3]=1.0 ;sathue[4]=0.3;sathue2[0]=1.0 ;sathue2[1]=1.0 ;sathue2[2]=1.0 ;sathue2[3]=1.0;}//purple - // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8 ;sathue[3]=0.8 ;sathue[4]=0.3;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 - else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9 ;sathue[3]=0.8 ;sathue[4]=0.3;sathue2[0]=0.8 ;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else if (LL< 80.0f) {//more for green, less for red and green-yellow + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.15f;sathue[3]=1.1f ;sathue[4]=0.3f;sathue2[0]=1.1f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.15f;sathue[3]=1.1f ;sathue[4]=0.3f;sathue2[0]=1.1f ;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f ;sathue[3]=1.0f ;sathue[4]=0.3f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f ;sathue[3]=1.05f;sathue[4]=0.3f;sathue2[0]=1.0f ;sathue2[1]=0.9f ;sathue2[2]=0.8f ;sathue2[3]=0.7f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.6f;sathue[1]=1.4f;sathue[2]=1.3f ;sathue[3]=1.25f;sathue[4]=0.3f;sathue2[0]=1.25f;sathue2[1]=1.2f ;sathue2[2]=1.15f;sathue2[3]=1.05f;}//green - even with Prophoto green are too "little" 1.5 1.3 } - else if (LL>=80) {//more for green-yellow, less for red and purple - if (HH< -1.5 && HH>- 3.1415) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//blue - else if(HH> 2.1 && HH<= 3.1415) {sathue[0]=1.4;sathue[1]=1.3;sathue[2]=1.2;sathue[3]=1.1;sathue[4]=0.2;sathue2[0]=1.1;sathue2[1]=1.05;sathue2[2]=1.05;sathue2[3]=1.0;}//green - else if(HH> 1.4 && HH<= 2.1 ) {sathue[0]=1.6;sathue[1]=1.5;sathue[2]=1.4;sathue[3]=1.2;sathue[4]=0.2;sathue2[0]=1.1;sathue2[1]=1.05;sathue2[2]=1.0 ;sathue2[3]=1.0;}//green yellow 1.2 1.1 - else if(HH< -0.7 && HH>=-1.5 ) {sathue[0]=1.0;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//blue purple 1.2 1.1 - else if(HH< 0.0 && HH>=-0.7 ) {sathue[0]=1.2;sathue[1]=1.0;sathue[2]=1.0;sathue[3]=0.9;sathue[4]=0.2;sathue2[0]=0.9;sathue2[1]=0.9 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//purple - // else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=0.8;sathue[1]=0.8;sathue[2]=0.8;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 - else if(HH>= 0.0 && HH<= 1.4 ) {sathue[0]=1.1;sathue[1]=1.0;sathue[2]=0.9;sathue[3]=0.8;sathue[4]=0.2;sathue2[0]=0.8;sathue2[1]=0.8 ;sathue2[2]=0.8 ;sathue2[3]=0.8;}//red 0.8 0.7 + else /*if (LL>=80.0f)*/ {//more for green-yellow, less for red and purple + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=0.9f;sathue[4]=0.2f;sathue2[0]=0.9f;sathue2[1]=0.9f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.6f;sathue[1]=1.5f;sathue[2]=1.4f;sathue[3]=1.2f;sathue[4]=0.2f;sathue2[0]=1.1f;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.4f;sathue[1]=1.3f;sathue[2]=1.2f;sathue[3]=1.1f;sathue[4]=0.2f;sathue2[0]=1.1f;sathue2[1]=1.05f;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green } - satredu=1.0; - if(params->vibrance.protectskins) - skinsat (LL, HH, CC, satredu);// for skin colors + float satredu=1.0f; //reduct sat in function of skin + if(protectskins) { + Color::SkinSat (LL, HH, CC, satredu, 0);// for skin colors + } // here we work on Chromaticity and Hue // variation of Chromaticity ==> saturation via RGB - // Munsell correction - // then conversion to Lab - Chprov=Chprov1=CC; - memChprov=Chprov; - Lprov1=LL; - bool inGamut; - //begin gamut control: specially if no ICC profil is used and if ICC and GamutICC=true - do { - inGamut=true; + // Munsell correction, then conversion to Lab + float Lprov=LL; + float Chprov=CC; + float memChprov=CC; + float R, G, B; - //Lprov1=LL; - aprov1=Chprov1*cos(HH); - bprov1=Chprov1*sin(HH); - - //conversion Lab RGB to limit Lab values - this conversion is usefull before Munsell correction - fy = (0.00862069 *Lprov1 )+ 0.137932; - fx = (0.002 * aprov1) + fy; - fz = fy - (0.005 * bprov1); - - x_ = 65535.0 * Color::f2xyz(fx)*Color::D50x; - y_ = 65535.0 * Color::f2xyz(fy); - z_ = 65535.0 * Color::f2xyz(fz)*Color::D50z; - Color::xyz2rgb(x_,y_,z_,R,G,B,wip); - - // gamut control before saturation to put Lab values in future gamut, but not RGB - if (allwaysingamut) { // gamut control - if (R<0.0f || G<0.0f || B<0.0f) { #ifdef _DEBUG - negat++; + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, Lprov, Chprov, R, G, B, wip, highlight, 0.2f, 0.98f, neg, more_rgb); + if(neg) negat++; + if(more_rgb) moreRGB++; +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, Lprov, Chprov, R, G, B, wip, highlight, 0.2f, 0.98f); #endif - if (Lprov1 < 0.01f) - Lprov1=0.05f; - Chprov1 *=0.95f; // one can modify this value... - if (Chprov1> 3.0f) - inGamut=false; - else { - Lprov1+=0.3f; - inGamut=false; - } - } - else if ((!highlight) && (R>65534.5f || G>65534.5f || B>65534.5f)){ // if "highlight reconstruction" is enabled, don't control Gamut -#ifdef _DEBUG - moreRGB++; -#endif - if (Lprov1>99.99f) - Lprov1=99.8f; - Chprov1 *=0.95f; - if (Chprov1> 3.0f) - inGamut=false; - else { - Lprov1 -=0.3f; - inGamut=false; - } - } - } - } - while (!inGamut); - //end first gamut control - Chprov=Chprov1; - Lprov=Lprov1; - - saturation=SAT(R,G,B); + float saturation=SAT(R,G,B); + //evaluate saturation with curve chroma +// saturation=(sat_curve[saturation*65535.0f])/65535.0f; + // work on saturation - if(Chprov > 6.0) { //protect gray and LUT Munsell + if(Chprov > 6.0f) { //protect gray and LUT Munsell //pyramid to adjust saturation in function of saturation and hue (and Luminance) - if(satredu!=1.0){ - // for skin, no differenciation - sathue [0]=1.; sathue [1]=1.; sathue [2]=1.; sathue [3]=1.0; sathue[4]=1.0; - sathue2[0]=1.; sathue2[1]=1.; sathue2[2]=1.; sathue2[3]=1.0; + if(satredu!=1.0f) { + // for skin, no differentiation + sathue [0]=sathue [1]=sathue [2]=sathue [3]=sathue[4]=1.0f; + sathue2[0]=sathue2[1]=sathue2[2]=sathue2[3] =1.0f; } - if(saturation>0.0) { + if(saturation>0.0f) { float chmodpastel,chmodsat; // variables to improve transitions - float p00=0.07; float pa, pb;// transition = pa*saturation + pb - float chl00=chromaPastel*satredu*sathue[4]; - float chl0=chromaPastel*satredu*sathue[0]; - float chl1=chromaPastel*satredu*sathue[1]; - float chl2=chromaPastel*satredu*sathue[2]; - float chl3=chromaPastel*satredu*sathue[3]; - float chs0=chromaSatur*satredu*sathue2[0]; - float chs1=chromaSatur*satredu*sathue2[1]; - float chs2=chromaSatur*satredu*sathue2[2]; - float chs3=chromaSatur*satredu*sathue2[3]; - float s3=1.0f; + float chl00 = chromaPastel*satredu*sathue[4]; + float chl0 = chromaPastel*satredu*sathue[0]; + float chl1 = chromaPastel*satredu*sathue[1]; + float chl2 = chromaPastel*satredu*sathue[2]; + float chl3 = chromaPastel*satredu*sathue[3]; + float chs0 = chromaSatur*satredu*sathue2[0]; + float chs1 = chromaSatur*satredu*sathue2[1]; + float chs2 = chromaSatur*satredu*sathue2[2]; + float chs3 = chromaSatur*satredu*sathue2[3]; + float s3 = 1.0f; // We handle only positive values here ; improve transitions - if (saturation < p00) chmodpastel = chl00 ; //neutral tones - else if (saturation < p0 ) { pa=(chl00- chl0)/(p00-p0);pb=chl00-pa*p00; chmodpastel = pa*saturation + pb;} - else if (saturation < p1) { pa=(chl0- chl1)/(p0-p1);pb=chl0-pa*p0; chmodpastel = pa*saturation + pb; } - else if (saturation < p2) { pa=(chl1- chl2)/(p1-p2);pb=chl1-pa*p1; chmodpastel = pa*saturation + pb; } - else if (saturation < limitpastelsatur) { pa=(chl2- chl3)/(p2-limitpastelsatur);pb=chl2-pa*p2; chmodpastel = pa*saturation + pb; } - else if (saturation < s0) { pa=(chl3 - chs0)/(limitpastelsatur-s0);pb=chl3-pa*limitpastelsatur; chmodsat = pa*saturation + pb; } - else if (saturation < s1) { pa=(chs0- chs1)/(s0-s1);pb=chs0-pa*s0; chmodsat = pa*saturation + pb; } - else if (saturation < s2) { pa=(chs1- chs2)/(s1-s2);pb=chs1-pa*s1; chmodsat = pa*saturation + pb; } - else { pa=(chs2- chs3)/(s2-s3);pb=chs2-pa*s2; chmodsat = pa*saturation + pb; } + if (saturation < p00) chmodpastel = chl00 ; //neutral tones + else if (saturation < p0 ) { pa=(chl00-chl0)/(p00-p0); pb=chl00-pa*p00; chmodpastel = pa*saturation + pb; } + else if (saturation < p1) { pa=(chl0-chl1)/(p0-p1); pb=chl0-pa*p0; chmodpastel = pa*saturation + pb; } + else if (saturation < p2) { pa=(chl1-chl2)/(p1-p2); pb=chl1-pa*p1; chmodpastel = pa*saturation + pb; } + else if (saturation < limitpastelsatur) { pa=(chl2- chl3)/(p2-limitpastelsatur); pb=chl2-pa*p2; chmodpastel = pa*saturation + pb; } + else if (saturation < s0) { pa=(chl3-chs0)/(limitpastelsatur-s0) ; pb=chl3-pa*limitpastelsatur; chmodsat = pa*saturation + pb; } + else if (saturation < s1) { pa=(chs0-chs1)/(s0-s1); pb=chs0-pa*s0; chmodsat = pa*saturation + pb; } + else if (saturation < s2) { pa=(chs1-chs2)/(s1-s2); pb=chs1-pa*s1; chmodsat = pa*saturation + pb; } + else { pa=(chs2-chs3)/(s2-s3); pb=chs2-pa*s2; chmodsat = pa*saturation + pb; } if(chromaPastel != chromaSatur){ + // Pastels if(saturation > p2 && saturation < limitpastelsatur) { float chromaPastel_a = (chromaPastel-chromamean)/(p2-limitpastelsatur); float chromaPastel_b = chromaPastel-chromaPastel_a*p2; @@ -2233,6 +321,7 @@ void ImProcFunctions::vibrance (LabImage* lab) { chmodpastel = newchromaPastel*satredu*sathue[3]; } + // Saturated if(saturation < s0 && saturation >=limitpastelsatur) { float chromaSatur_a=(chromaSatur-chromamean)/(s0-limitpastelsatur); float chromaSatur_b=chromaSatur-chromaSatur_a*s0; @@ -2240,133 +329,138 @@ void ImProcFunctions::vibrance (LabImage* lab) { chmodsat = newchromaSatur*satredu*sathue2[0]; } }// end transition - if (saturation <= limitpastelsatur) { - if(chmodpastel > 2.0 ) chmodpastel = 2.0; //avoid too big values - if(chmodpastel < -0.93) chmodpastel =-0.93; //avoid negative values - Chprov *=(1.0+chmodpastel); - if(Chprov<6.0) Chprov=6.0; + if (saturation <= limitpastelsatur) { + if (chmodpastel > 2.0f ) chmodpastel = 2.0f; //avoid too big values + else if(chmodpastel < -0.93f) chmodpastel =-0.93f; //avoid negative values + + Chprov *=(1.0f+chmodpastel); + if(Chprov<6.0f) Chprov=6.0f; } else { //if (saturation > limitpastelsatur) - if(chmodsat > 1.8 ) chmodsat = 1.8; //saturated - if(chmodsat < -0.93) chmodsat =-0.93; + if (chmodsat > 1.8f ) chmodsat = 1.8f; //saturated + else if(chmodsat < -0.93f) chmodsat =-0.93f; - Chprov *= 1.0+chmodsat; - if(Chprov <6.0) Chprov=6.0; + Chprov *= 1.0f+chmodsat; + if(Chprov < 6.0f) Chprov=6.0f; } } } + // Vibrance's Skin curve + if(skinCurveIsSet) { + const float dhue=0.15f;//hue transition + const float dchr=20.0f;//chroma transition + const float skbeg=-0.05f;//begin hue skin + const float skend=1.60f;//end hue skin + const float xx=0.5f;//soft : between 0.3 and 1.0 + + float ask=65535.0f/(skend-skbeg); + float bsk=-skbeg*ask; + + if (HH>skbeg && HH transition + float HHsk=ask*HH+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hc=(Hn*xx+HH*(1.0f-xx)); + HH=Hc; + } + else if(Chprov < (60.0f+dchr)) {//transition chroma + float HHsk=ask*HH+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hc=(Hn*xx+HH*(1.0f-xx)); + float aa= (HH-Hc)/dchr ; float bb= HH-(60.0f+dchr)*aa; + HH=aa*Chprov+bb; + } + } + //transition hue + else if(HH>(skbeg-dhue) && HH<=skbeg && Chprov < (60.0f+dchr/2.0f)) { + float HHsk=ask*skbeg+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hcc=(Hn*xx+skbeg*(1.0f-xx)); + float adh=(Hcc-(skbeg-dhue))/(dhue); + float bdh=Hcc-adh*skbeg; + HH=adh*HH+bdh; + } + else if(HH>=skend && HH<(skend+dhue) && Chprov < (60.0f+dchr/2.0f)) { + float HHsk=ask*skend+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hcc=(Hn*xx+skend*(1.0f-xx)); + float adh=(skend+dhue-Hcc)/(dhue); + float bdh=Hcc-adh*skend; + HH=adh*HH+bdh; + } + } // end skin hue + //Munsell correction - correctionHue=0.0; + float correctionHue=0.0f; + float correctlum; + + float aprovn,bprovn; + bool inGamut; do { inGamut=true; - if(params->vibrance.avoidcolorshift) { - if(memChprov >= 6.0 && memChprov < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) - if (Chprov > 140) Chprov=139; //limits of LUTf - if(HH > -2.48 && HH < -0.55) { //limits of hue Blue purple -1.90 - zone=1; // *** blue purple correction and blue correction for sky - MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); + if(avoidcolorshift) { + correctionHue=0.0f; + correctlum=0.0f; + #ifdef _DEBUG - if(correctionHue !=0.0) { - if(fabs(correctionHue) > maxdeltaHueBP) - maxdeltaHueBP=fabs(correctionHue); - Munspb++; - } - if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,memChprov,correctionHue,correctlum); #endif - } - if(HH > 0.44 && HH < 1.52) { //limits of hue red yellow - zone=2; // *** red yellow correction - MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); -#ifdef _DEBUG - if(correctionHue !=0.0) { - if(fabs(correctionHue) > maxdeltaHueRY) - maxdeltaHueRY=fabs(correctionHue); - Munsry++; - } - if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation -#endif - } - if(HH > 1.87 && HH < 3.09) { //limits of green and green yellow - zone=3; // *** green yellow correction - MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); -#ifdef _DEBUG - if(correctionHue !=0.0) { - if(fabs(correctionHue) > maxdeltaHueGY) - maxdeltaHueGY=fabs(correctionHue); - Munsgy++; - } - if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation -#endif - } - if(HH > -0.27 && HH <= 0.44) { //limits of Red purple - zone=4; // *** red purple correction - MunsellLch (Lprov, HH,Chprov, memChprov, correctionHue, zone); -#ifdef _DEBUG - if(correctionHue !=0.0) { - if(fabs(correctionHue) > maxdeltaHueRP) - maxdeltaHueRP=fabs(correctionHue); - Munsrp++; - } - if(fabs(correctionHue) > 0.45) depass++; //verify if no bug in calculation -#endif - } - } } - //second gamut control take into account Munsell and saturation if R G B > 65535 aprovn=Chprov*cos(HH+correctionHue); bprovn=Chprov*sin(HH+correctionHue); - if (allwaysingamut) { // gamut control - fyy = (0.00862069 *Lprov )+ 0.137932; - fxx = (0.002 * aprovn) + fyy; - fzz = fyy - (0.005 * bprovn); + float fyy = (0.00862069f *Lprov )+ 0.137932f; + float fxx = (0.002f * aprovn) + fyy; + float fzz = fyy - (0.005f * bprovn); - xx_ = 65535.0 * Color::f2xyz(fxx)*Color::D50x; - yy_ = 65535.0 * Color::f2xyz(fyy); - zz_ = 65535.0 * Color::f2xyz(fzz)*Color::D50z; - Color::xyz2rgb(xx_,yy_,zz_,RR,GG,BB,wip); + float xx_ = 65535.0f * Color::f2xyz(fxx)*Color::D50x; + float yy_ = 65535.0f * Color::f2xyz(fyy); + float zz_ = 65535.0f * Color::f2xyz(fzz)*Color::D50z; + Color::xyz2rgb(xx_,yy_,zz_,R,G,B,wip); - if(RR<0.0 || GG < 0.0 || BB < 0.0) { + if(R<0.0f || G<0.0f || B<0.0f) { #ifdef _DEBUG - negsat++; + negsat++; #endif - Chprov*=0.95; - inGamut=false; - } - if((!highlight) && (RR>65535.0 || GG > 65535.0 || BB>65535.0)) {// if "highlight reconstruction" enabled don't control Gamut for highlights - // if(RR>65535.0 || GG > 65535.0 || BB>65535.0) { -#ifdef _DEBUG - moresat++; -#endif - Chprov*=0.95; - inGamut=false; - } + Chprov*=0.98f; + inGamut=false; } - } while (!inGamut); - //put new values in Lab - lab->L[i][j]=Lprov*327.68; - lab->a[i][j]=aprovn*327.68; - lab->b[i][j]=bprovn*327.68; + // if "highlight reconstruction" enabled don't control Gamut for highlights + if((!highlight) && (R>65535.0f || G>65535.0f || B>65535.0f)) { +#ifdef _DEBUG + moresat++; +#endif + Chprov*=0.98f; + inGamut=false; + } + } + while (!inGamut); + //put new values in Lab + lab->L[i][j]=Lprov*327.68f; + lab->a[i][j]=aprovn*327.68f; + lab->b[i][j]=bprovn*327.68f; } -} -/* -delete [] LL; -delete [] CC; -delete [] HH; -*/ +} // end of parallelization #ifdef _DEBUG t2e.set(); if (settings->verbose) { - printf("Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n",negat,moreRGB,negsat,moresat); - printf("Munsell: MunPB=%ipix MunRY=%ipix MunGY=%ipix MunRP=%ipix MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n",Munspb, Munsry,Munsgy,Munsrp, maxdeltaHueBP,maxdeltaHueRY,maxdeltaHueGY,maxdeltaHueRP, depass); - printf("Vibrance %d usec\n", t2e.etime(t1e)); + printf("Vibrance (performed in %d usec):\n", t2e.etime(t1e)); + printf(" Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n",negat,moreRGB,negsat,moresat); + if (MunsDebugInfo) + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); } + if (MunsDebugInfo) + delete MunsDebugInfo; #endif -} + +} + } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 080515a6e..fc2908d61 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -132,9 +132,9 @@ enum ProcEvent { EvHLComprThreshold=107, EvResizeBoundingBox=108, EvResizeAppliesTo=109, - EvLAvoidClip=110, - EvLSatLimiter=111, - EvLSatLimit=112, + EvLAvoidColorShift=110, + EvLSatLimiter=111, // obsolete + EvLRSTProtection=112, EvDemosaicDCBIter=113, EvDemosaicFalseColorIter=114, EvDemosaicDCBEnhanced=115, @@ -189,7 +189,10 @@ enum ProcEvent { EvRGBbCurve=164, EvNeutralExp=165, EvLBWtoning=166, - NUMOFEVENTS=167 + EvLCCCurve=167, + EvLCHCurve=168, + EvVibranceSkinTonesCurve=169, + NUMOFEVENTS=170 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 7bcea73d6..3c89c0e7a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -139,19 +139,24 @@ void ProcParams::setDefaults () { toneCurve.curve.clear (); toneCurve.curve.push_back(DCT_Linear); - labCurve.brightness = 0; - labCurve.contrast = 0; - labCurve.saturation = 0; - labCurve.avoidclip = false; - labCurve.enable_saturationlimiter = false; - labCurve.saturationlimit = 50; - labCurve.bwtoning = false; + labCurve.brightness = 0; + labCurve.contrast = 0; + labCurve.chromaticity = 0; + labCurve.avoidcolorshift = true; + labCurve.rstprotection = 0; + labCurve.bwtoning = false; labCurve.lcurve.clear (); labCurve.lcurve.push_back(DCT_Linear); labCurve.acurve.clear (); labCurve.acurve.push_back(DCT_Linear); labCurve.bcurve.clear (); labCurve.bcurve.push_back(DCT_Linear); + labCurve.cccurve.clear (); + labCurve.cccurve.push_back(DCT_Linear); + labCurve.chcurve.clear (); + labCurve.chcurve.push_back(FCT_Linear); + //labCurve.cbgcurve.clear (); + //labCurve.cbgcurve.push_back(DCT_Linear); rgbCurves.rcurve.clear (); rgbCurves.rcurve.push_back(DCT_Linear); @@ -189,10 +194,12 @@ void ProcParams::setDefaults () { vibrance.enabled = false; vibrance.pastels = 0; vibrance.saturated = 0; - vibrance.psthreshold.setValues(1, 75); + vibrance.psthreshold.setValues(0, 75); vibrance.protectskins = false; vibrance.avoidcolorshift = true; vibrance.pastsattog = true; + vibrance.skintonescurve.clear (); + vibrance.skintonescurve.push_back(DCT_Linear); //colorBoost.amount = 0; //colorBoost.avoidclip = false; @@ -400,13 +407,12 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p } // save luma curve - if (!pedited || pedited->labCurve.brightness) keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness); - if (!pedited || pedited->labCurve.contrast) keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast); - if (!pedited || pedited->labCurve.saturation) keyFile.set_integer ("Luminance Curve", "Saturation", labCurve.saturation); - if (!pedited || pedited->labCurve.avoidclip) keyFile.set_boolean ("Luminance Curve", "AvoidColorClipping", labCurve.avoidclip); - if (!pedited || pedited->labCurve.enable_saturationlimiter) keyFile.set_boolean ("Luminance Curve", "SaturationLimiter", labCurve.enable_saturationlimiter); - if (!pedited || pedited->labCurve.saturationlimit) keyFile.set_double ("Luminance Curve", "SaturationLimit", labCurve.saturationlimit); - if (!pedited || pedited->labCurve.avoidclip) keyFile.set_boolean ("Luminance Curve", "BWtoning", labCurve.bwtoning); + if (!pedited || pedited->labCurve.brightness) keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness); + if (!pedited || pedited->labCurve.contrast) keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast); + if (!pedited || pedited->labCurve.chromaticity) keyFile.set_integer ("Luminance Curve", "Chromaticity", labCurve.chromaticity); + if (!pedited || pedited->labCurve.avoidcolorshift) keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift); + if (!pedited || pedited->labCurve.rstprotection) keyFile.set_double ("Luminance Curve", "SaturationLimit", labCurve.rstprotection); + if (!pedited || pedited->labCurve.bwtoning) keyFile.set_boolean ("Luminance Curve", "BWtoning", labCurve.bwtoning); if (!pedited || pedited->labCurve.lcurve) { Glib::ArrayHandle lcurve = labCurve.lcurve; keyFile.set_double_list("Luminance Curve", "LCurve", lcurve); @@ -419,7 +425,20 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p Glib::ArrayHandle bcurve = labCurve.bcurve; keyFile.set_double_list("Luminance Curve", "bCurve", bcurve); } - + if (!pedited || pedited->labCurve.cccurve) { + Glib::ArrayHandle cccurve = labCurve.cccurve; + keyFile.set_double_list("Luminance Curve", "ccCurve", cccurve); + } + if (!pedited || pedited->labCurve.chcurve) { + Glib::ArrayHandle chcurve = labCurve.chcurve; + keyFile.set_double_list("Luminance Curve", "chCurve", chcurve); + } +/* + if (!pedited || pedited->labCurve.cbgcurve) { + Glib::ArrayHandle cbgcurve = labCurve.cbgcurve; + keyFile.set_double_list("Luminance Curve", "cbgCurve", cbgcurve); + } +*/ // save sharpening if (!pedited || pedited->sharpening.enabled) keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled); if (!pedited || pedited->sharpening.method) keyFile.set_string ("Sharpening", "Method", sharpening.method); @@ -450,6 +469,10 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, ParamsEdited* p if (!pedited || pedited->vibrance.protectskins) keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins); if (!pedited || pedited->vibrance.avoidcolorshift) keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift); if (!pedited || pedited->vibrance.pastsattog) keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog); + if (!pedited || pedited->vibrance.skintonescurve) { + Glib::ArrayHandle skintonescurve = vibrance.skintonescurve; + keyFile.set_double_list("Vibrance", "SkinTonesCurve", skintonescurve); + } //save edge sharpening if (!pedited || pedited->sharpenEdge.enabled) keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled); @@ -778,16 +801,25 @@ if (keyFile.has_group ("Channel Mixer")) { // load luma curve if (keyFile.has_group ("Luminance Curve")) { - if (keyFile.has_key ("Luminance Curve", "Brightness")) { labCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); if (pedited) pedited->labCurve.brightness = true; } - if (keyFile.has_key ("Luminance Curve", "Contrast")) { labCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); if (pedited) pedited->labCurve.contrast = true; } - if (keyFile.has_key ("Luminance Curve", "Saturation")) { labCurve.saturation = keyFile.get_integer ("Luminance Curve", "Saturation"); if (pedited) pedited->labCurve.saturation = true; } - if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) { labCurve.avoidclip = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (pedited) pedited->labCurve.avoidclip = true; } - if (keyFile.has_key ("Luminance Curve", "SaturationLimiter")) { labCurve.enable_saturationlimiter = keyFile.get_boolean ("Luminance Curve", "SaturationLimiter"); if (pedited) pedited->labCurve.enable_saturationlimiter = true; } - if (keyFile.has_key ("Luminance Curve", "SaturationLimit")) { labCurve.saturationlimit = keyFile.get_double ("Luminance Curve", "SaturationLimit"); if (pedited) pedited->labCurve.saturationlimit = true; } - if (keyFile.has_key ("Luminance Curve", "BWtoning")) { labCurve.bwtoning = keyFile.get_boolean ("Luminance Curve", "BWtoning"); if (pedited) pedited->labCurve.bwtoning = true; } - if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (pedited) pedited->labCurve.lcurve = true; } - if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (pedited) pedited->labCurve.acurve = true; } - if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); if (pedited) pedited->labCurve.bcurve = true; } + if (keyFile.has_key ("Luminance Curve", "Brightness")) { labCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); if (pedited) pedited->labCurve.brightness = true; } + if (keyFile.has_key ("Luminance Curve", "Contrast")) { labCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); if (pedited) pedited->labCurve.contrast = true; } + if (keyFile.has_key ("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Chromaticity"); if (pedited) pedited->labCurve.chromaticity = true; } + + if (PPVERSION < 303) { + // transform AvoidColorClipping into AvoidColorShift + if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (pedited) pedited->labCurve.avoidcolorshift = true; } + } + else { + if (keyFile.has_key ("Luminance Curve", "AvoidColorShift")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorShift"); if (pedited) pedited->labCurve.avoidcolorshift = true; } + if (keyFile.has_key ("Luminance Curve", "RedAndSkinTonesProtection")) { labCurve.rstprotection = keyFile.get_double ("Luminance Curve", "RedAndSkinTonesProtection"); if (pedited) pedited->labCurve.rstprotection = true; } + } + + if (keyFile.has_key ("Luminance Curve", "BWtoning")) { labCurve.bwtoning = keyFile.get_boolean ("Luminance Curve", "BWtoning"); if (pedited) pedited->labCurve.bwtoning = true; } + if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (pedited) pedited->labCurve.lcurve = true; } + if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (pedited) pedited->labCurve.acurve = true; } + if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); if (pedited) pedited->labCurve.bcurve = true; } + if (keyFile.has_key ("Luminance Curve", "ccCurve")) { labCurve.cccurve = keyFile.get_double_list ("Luminance Curve", "ccCurve"); if (pedited) pedited->labCurve.cccurve = true; } + if (keyFile.has_key ("Luminance Curve", "chCurve")) { labCurve.chcurve = keyFile.get_double_list ("Luminance Curve", "chCurve"); if (pedited) pedited->labCurve.chcurve = true; } } // load sharpening @@ -853,6 +885,7 @@ if (keyFile.has_group ("Vibrance")) { if (keyFile.has_key ("Vibrance", "ProtectSkins")) { vibrance.protectskins = keyFile.get_boolean ("Vibrance", "ProtectSkins"); if (pedited) pedited->vibrance.protectskins = true; } if (keyFile.has_key ("Vibrance", "AvoidColorShift")) { vibrance.avoidcolorshift = keyFile.get_boolean ("Vibrance", "AvoidColorShift"); if (pedited) pedited->vibrance.avoidcolorshift = true; } if (keyFile.has_key ("Vibrance", "PastSatTog")) { vibrance.pastsattog = keyFile.get_boolean ("Vibrance", "PastSatTog"); if (pedited) pedited->vibrance.pastsattog = true; } + if (keyFile.has_key ("Vibrance", "SkinTonesCurve")) { vibrance.skintonescurve = keyFile.get_double_list ("Vibrance", "SkinTonesCurve"); if (pedited) pedited->vibrance.skintonescurve = true; } } // load colorBoost @@ -1196,12 +1229,14 @@ bool ProcParams::operator== (const ProcParams& other) { && labCurve.lcurve == other.labCurve.lcurve && labCurve.acurve == other.labCurve.acurve && labCurve.bcurve == other.labCurve.bcurve + && labCurve.cccurve == other.labCurve.cccurve + && labCurve.chcurve == other.labCurve.chcurve +// && labCurve.cbgcurve == other.labCurve.cbgcurve && labCurve.brightness == other.labCurve.brightness && labCurve.contrast == other.labCurve.contrast - && labCurve.saturation == other.labCurve.saturation - && labCurve.avoidclip == other.labCurve.avoidclip - && labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter - && labCurve.saturationlimit == other.labCurve.saturationlimit + && labCurve.chromaticity == other.labCurve.chromaticity + && labCurve.avoidcolorshift == other.labCurve.avoidcolorshift + && labCurve.rstprotection == other.labCurve.rstprotection && labCurve.bwtoning == other.labCurve.bwtoning && sharpenEdge.enabled == other.sharpenEdge.enabled && sharpenEdge.passes == other.sharpenEdge.passes @@ -1232,6 +1267,7 @@ bool ProcParams::operator== (const ProcParams& other) { && vibrance.protectskins == other.vibrance.protectskins && vibrance.avoidcolorshift == other.vibrance.avoidcolorshift && vibrance.pastsattog == other.vibrance.pastsattog + && vibrance.skintonescurve == other.vibrance.skintonescurve //&& colorBoost.amount == other.colorBoost.amount //&& colorBoost.avoidclip == other.colorBoost.avoidclip //&& colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2ef6c4a0d..f8c16a9b3 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -202,12 +202,14 @@ class LCurveParams { std::vector lcurve; std::vector acurve; std::vector bcurve; + std::vector cccurve; + std::vector chcurve; + //std::vector cbgcurve; int brightness; int contrast; - int saturation; - bool avoidclip; - bool enable_saturationlimiter; - double saturationlimit; + int chromaticity; + bool avoidcolorshift; + double rstprotection; bool bwtoning; }; @@ -273,8 +275,9 @@ class VibranceParams { bool protectskins; bool avoidcolorshift; bool pastsattog; + std::vector skintonescurve; - VibranceParams() : psthreshold(1, 75, false) {}; + VibranceParams() : psthreshold(0, 75, false) {}; }; /** diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 4a0a7d0a1..d25eccc58 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -152,7 +152,7 @@ class RawImageSource : public ImageSource { ColorTemp getWB () { return wb; } ColorTemp getAutoWB (); ColorTemp getSpotWB (std::vector red, std::vector green, std::vector& blue, int tran); - bool isWBProviderReady () { return rawData != NULL; }; + bool isWBProviderReady () { return rawData != (float**)NULL; }; double getDefGain () { return defGain; } diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 9703571f0..b04686dff 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -186,6 +186,9 @@ RGBCURVE, // EvRGBrCurve RGBCURVE, // EvRGBgCurve RGBCURVE, // EvRGBbCurve RGBCURVE, // EvNeutralExp -LUMINANCECURVE // EvLBWtoning +LUMINANCECURVE, // EvLBWtoning +LUMINANCECURVE, // EvLCCurve +LUMINANCECURVE, // EvLCHGurve +RGBCURVE // EvCCCurve }; diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 1d8af7231..d16aca20f 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -731,6 +731,8 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei LUTf curve2 (65536); LUTf curve (65536); LUTf satcurve (65536); + LUTf satbgcurve (65536); + LUTf rCurve (65536); LUTf gCurve (65536); LUTf bCurve (65536); @@ -762,13 +764,17 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei // luminance processing ipf.EPDToneMap(labView,0,6); - + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, - hist16, hist16, curve, dummy, 16); - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, - params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 16); - ipf.luminanceCurve (labView, labView, curve); - ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve); + hist16, hist16, curve, dummy, 16, utili); + CurveFactory::complexsgnCurve (autili, butili, ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve/*,params.labCurve.cbgcurve*/, curve1, curve2, satcurve,/*satbgcurve,*/ 16); + //ipf.luminanceCurve (labView, labView, curve); + ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,/*satbgcurve,*/ curve, utili, autili, butili, ccutili); ipf.vibrance(labView); // color processing diff --git a/rtengine/settings.h b/rtengine/settings.h index 81a30ce98..f4c93ab40 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -44,6 +44,9 @@ namespace rtengine { Glib::ustring srgb10; // default name of SRGB space profile bool gamutICC; // + bool gamutLch; + int protectred; + double protectredh; /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index deac00b14..693e7f046 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -155,6 +155,8 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p LUTf curve2 (65536,0); LUTf curve (65536,0); LUTf satcurve (65536,0); + //LUTf satbgcurve (65536,0); + LUTf rCurve (65536,0); LUTf gCurve (65536,0); LUTf bCurve (65536,0); @@ -192,13 +194,17 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p // luminance processing ipf.EPDToneMap(labView); + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=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, curve, dummy, 1); - - CurveFactory::complexsgnCurve (params.labCurve.saturation, params.labCurve.enable_saturationlimiter, params.labCurve.saturationlimit, - params.labCurve.acurve, params.labCurve.bcurve, curve1, curve2, satcurve, 1); - ipf.luminanceCurve (labView, labView, curve); - ipf.chrominanceCurve (labView, labView, curve1, curve2, satcurve); + CurveFactory::complexsgnCurve (autili, butili, ccutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,/*params.labCurve.cbgcurve,*/curve1, curve2, satcurve,/*satbgcurve,*/ 1); + //ipf.luminanceCurve (labView, labView, curve); + ipf.chromiLuminanceCurve (labView, labView, curve1, curve2, satcurve,/*satbgcurve,*/curve, utili, autili, butili, ccutili); ipf.vibrance(labView); ipf.impulsedenoise (labView); diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 395f33ac3..9fb7d7e34 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -4,7 +4,7 @@ set (BASESOURCEFILES exportpanel.cc cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc cachemanager.cc cacheimagedata.cc shcselector.cc perspective.cc thresholdselector.cc thresholdadjuster.cc - clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc + clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc coloredbar.cc coarsepanel.cc cacorrection.cc hlrec.cc chmixer.cc resize.cc icmpanel.cc crop.cc shadowshighlights.cc impulsedenoise.cc dirpyrdenoise.cc epd.cc diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index 3444c9fa5..2f491ce2f 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -26,7 +26,7 @@ #define ADDSET_PERSPECTIVE 18 #define ADDSET_CA 19 #define ADDSET_VIGN_AMOUNT 20 -#define ADDSET_LC_SATURATION 21 +#define ADDSET_LC_CHROMATICITY 21 #define ADDSET_TC_SATURATION 22 #define ADDSET_TC_HLCOMPAMOUNT 23 #define ADDSET_TC_HLCOMPTHRESH 24 diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h index 2ba69ff07..c097e9ea1 100644 --- a/rtgui/adjuster.h +++ b/rtgui/adjuster.h @@ -27,6 +27,7 @@ class Adjuster; class AdjusterListener { public: + virtual ~AdjusterListener() {}; virtual void adjusterChanged (Adjuster* a, double newval) {} }; @@ -71,13 +72,14 @@ class Adjuster : public Gtk::VBox { void setAdjusterListener (AdjusterListener* alistener) { adjusterListener = alistener; } // return the value trimmed to the limits at construction time - double getValue () { return spin->get_value (); } + double getValue () { return shapeValue(spin->get_value ()); } // return the value trimmed to the limits at construction time int getIntValue () { return spin->get_value_as_int (); } // return the value trimmed to the limits at construction time, // method only used by the history manager Glib::ustring getTextValue () { return spin->get_text (); } + void setLabel (Glib::ustring lbl) { label->set_label(lbl); } void setValue (double a); void setLimits (double vmin, double vmax, double vstep, double vdefault); void setEnabled (bool enabled); diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index d515534f5..ab2810935 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -145,7 +145,7 @@ void BatchToolPanelCoordinator::initSession () { else { toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]); - lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_SATURATION]); + lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_CHROMATICITY]); whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN]); vignetting->setAdjusterBehavior (options.baBehav[ADDSET_VIGN_AMOUNT]); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); @@ -179,7 +179,7 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_LC_BRIGHTNESS]) pparams.labCurve.brightness = 0; if (options.baBehav[ADDSET_LC_CONTRAST]) pparams.labCurve.contrast = 0; - if (options.baBehav[ADDSET_LC_SATURATION]) pparams.labCurve.saturation = 0; + if (options.baBehav[ADDSET_LC_CHROMATICITY]) pparams.labCurve.chromaticity = 0; if (options.baBehav[ADDSET_SHARP_AMOUNT]) pparams.sharpening.amount = 0; if (options.baBehav[ADDSET_SHARPENEDGE_AMOUNT]) pparams.sharpenEdge.amount = 0; diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc new file mode 100644 index 000000000..3fa76593e --- /dev/null +++ b/rtgui/coloredbar.cc @@ -0,0 +1,135 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +#include "coloredbar.h" + +ColoredBar::ColoredBar (eRTOrientation orient) { + orientation = orient; + dirty = true; + cp = NULL; + this->x = this->y = this->w = this->h = 0; +} + +void ColoredBar::setColorProvider (ColorProvider* p) { + cp = p; +} + +/* + * Redraw the bar to a Cairo::Surface + */ +void ColoredBar::expose(Cairo::RefPtr destSurface) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !destSurface) + return; + draw(); + copySurface(destSurface); +} + +/* + * Redraw the bar to a Gdk::Window + */ +void ColoredBar::expose(Glib::RefPtr destWindow) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !destWindow) + return; + draw(); + copySurface(destWindow); +} + +/* + * Redraw the bar to a Gdk::Window + */ +void ColoredBar::expose(BackBuffer *backBuffer) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !backBuffer) + return; + draw(); + copySurface(backBuffer); +} + +void ColoredBar::draw() { + if (isDirty()) { + Cairo::RefPtr cr = getContext(); + // the bar has to be drawn to the Surface first + if (!bgGradient.empty()) { + // a gradient has been set, we use it + cr->set_line_width(0.); + + // gradient background + Cairo::RefPtr< Cairo::LinearGradient > bggradient; + switch (orientation) { + case (RTO_Left2Right): + bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.); + break; + case (RTO_Right2Left): + bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.); + break; + case (RTO_Bottom2Top): + bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.); + break; + case (RTO_Top2Bottom): + default: + bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h)); + break; + } + + for (std::vector::iterator i=bgGradient.begin(); i!=bgGradient.end(); i++) { + bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b); + } + cr->set_source (bggradient); + cr->rectangle(0, 0, w, h); + cr->fill(); + } + else { + // ask the ColorProvider to provide colors :) for each pixels + if (cp) { + cr->set_antialias(Cairo::ANTIALIAS_NONE); + cr->set_line_width(1.); + for (int x=0; xcolorForValue (x01, y01); + cr->set_source_rgb(cp->red, cp->green, cp->blue); + cr->move_to(x2, y2); + cr->stroke(); + } + } + } + } + // has it been updated or not, we assume that the Surface has been correctly set (we don't handle allocation error) + setDirty(false); + } +} + +void ColoredBar::setBgGradient (const std::vector &milestones) { + bgGradient = milestones; + setDirty(true); +} + +void ColoredBar::clearBgGradient () { + bgGradient.clear(); + setDirty(true); +} + +bool ColoredBar::canGetColors() { + return cp!=NULL || bgGradient.size()>0; +} diff --git a/rtgui/coloredbar.h b/rtgui/coloredbar.h new file mode 100644 index 000000000..fcd437f11 --- /dev/null +++ b/rtgui/coloredbar.h @@ -0,0 +1,56 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _COLOREDBAR_ +#define _COLOREDBAR_ + +#include "colorprovider.h" +#include "guiutils.h" + +/* + * Parent class for all colored bar type; a ColorProvider has to be set + * thanks to "setColorProvider" to be able to display colors inside the bar + */ +class ColoredBar : public BackBuffer { + + private: + void draw(); + + protected: + ColorProvider* cp; + eRTOrientation orientation; + std::vector bgGradient; + + public: + ColoredBar (eRTOrientation orient); + + void expose(Glib::RefPtr destWindow); + void expose(Cairo::RefPtr destSurface); + void expose(BackBuffer *backBuffer); + + void setColorProvider (ColorProvider* p); + bool canGetColors(); + + // Method for convenience; if no Gradient provided, the ColoredBar will ask colors on a per pixel basis + void setBgGradient (const std::vector &milestones); + // by clearing the gradient, the ColorProvider will have to provide colors on a per pixel basis if a ColorProvider + // has been set, through ColorProvider::colorForValue on next ColoredBar::expose + void clearBgGradient (); +}; + +#endif diff --git a/rtgui/colorprovider.h b/rtgui/colorprovider.h index d4b44aa79..922eb869f 100644 --- a/rtgui/colorprovider.h +++ b/rtgui/colorprovider.h @@ -19,15 +19,22 @@ #ifndef _COLORPROVIDER_ #define _COLORPROVIDER_ +/* + * Use it to let your widget feed a colored bar or graph lines with the wanted colors + * If you doesn't need to dynamically feed a widget with colors (e.g. curve's graph), + * you don't need to declare the instanciator class as BEING a ColorProvider, you'll + * still be able to set gradients for e.g. ColoredBar(s) + */ class ColorProvider { - public: + public: double red; double green; double blue; - virtual void colorForValue (double valX, double valY) {} - + ColorProvider() { red = green = blue = 0.0; }; + virtual ~ColorProvider() {}; + virtual void colorForValue (double valX, double valY) {}; }; #endif diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc index ed4acc613..4a1e78bd8 100644 --- a/rtgui/curveeditor.cc +++ b/rtgui/curveeditor.cc @@ -8,7 +8,6 @@ * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * RawTherapee is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. @@ -26,8 +25,6 @@ #include -extern Glib::ustring argv0; - DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup) : CurveEditor::CurveEditor(text, static_cast(ceGroup), ceSubGroup) { // Order set in the same order than "enum DiagonalCurveType". Shouldn't change, for compatibility reason @@ -37,6 +34,15 @@ DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* curveType->addEntry("curveType-NURBS.png", M("CURVEEDITOR_NURBS")); // 3 NURBS curveType->setSelected(DCT_Linear); curveType->show(); + + rangeLabels[0] = M("CURVEEDITOR_SHADOWS"); + rangeLabels[1] = M("CURVEEDITOR_DARKS"); + rangeLabels[2] = M("CURVEEDITOR_LIGHTS"); + rangeLabels[3] = M("CURVEEDITOR_HIGHLIGHTS"); + + rangeMilestones[0] = 0.25; + rangeMilestones[1] = 0.50; + rangeMilestones[2] = 0.75; } std::vector DiagonalCurveEditor::getCurve () { @@ -56,6 +62,39 @@ std::vector DiagonalCurveEditor::getCurve () { } } +void DiagonalCurveEditor::setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) { + rangeLabels[0] = r1; + rangeLabels[1] = r2; + rangeLabels[2] = r3; + rangeLabels[3] = r4; +} + +void DiagonalCurveEditor::getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4) { + r1 = rangeLabels[0]; + r2 = rangeLabels[1]; + r3 = rangeLabels[2]; + r4 = rangeLabels[3]; +} + +/* + * Admittedly that this method is called just after the instantiation of this class, we set the shcselector's default values + */ +void DiagonalCurveEditor::setRangeDefaultMilestones(double m1, double m2, double m3) { + rangeMilestones[0] = m1; + rangeMilestones[1] = m2; + rangeMilestones[2] = m3; + + paramCurveEd.at(1) = m1; + paramCurveEd.at(2) = m2; + paramCurveEd.at(3) = m3; +} + +void DiagonalCurveEditor::getRangeDefaultMilestones(double &m1, double &m2, double &m3) { + m1 = rangeMilestones[0]; + m2 = rangeMilestones[1]; + m3 = rangeMilestones[2]; +} + FlatCurveEditor::FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup, bool isPeriodic) : CurveEditor::CurveEditor(text, static_cast(ceGroup), ceSubGroup) { periodic = isPeriodic; @@ -93,6 +132,9 @@ CurveEditor::CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEd bgHistValid = false; selected = DCT_Linear; + bottomBarCP = NULL; + leftBarCP = NULL; + curveCP = NULL; group = ceGroup; subGroup = ceSubGroup; @@ -161,3 +203,66 @@ bool CurveEditor::openIfNonlinear() { return nonLinear; } + +// Handles markup tooltips +void CurveEditor::setTooltip(Glib::ustring ttip) { + curveType->set_tooltip_text(ttip.empty() ? + Glib::ustring::compose("%1 ", M("CURVEEDITOR_TYPE")) : + Glib::ustring::compose("%1\n%2", ttip, M("CURVEEDITOR_TYPE"))); +} + +void CurveEditor::setLeftBarColorProvider(ColorProvider* cp) { + leftBarCP = cp; +} + +void CurveEditor::setBottomBarColorProvider(ColorProvider* cp) { + bottomBarCP = cp; +} + +void CurveEditor::setLeftBarBgGradient (const std::vector &milestones) { + leftBarBgGradient = milestones; +} + +void CurveEditor::setBottomBarBgGradient (const std::vector &milestones) { + bottomBarBgGradient = milestones; +} + +void CurveEditor::setCurveColorProvider(ColorProvider* cp) { + curveCP = cp; +} + +ColorProvider* CurveEditor::getLeftBarColorProvider() { + return leftBarCP; +} + +ColorProvider* CurveEditor::getBottomBarColorProvider() { + return bottomBarCP; +} + +ColorProvider* CurveEditor::getCurveColorProvider() { + return curveCP; +} + +std::vector CurveEditor::getBottomBarBgGradient () const { + return bottomBarBgGradient; +} + +std::vector CurveEditor::getLeftBarBgGradient () const { + return leftBarBgGradient; +} + +sigc::signal CurveEditor::signal_curvegraph_enter() { + return sig_curvegraph_enter; +} + +sigc::signal CurveEditor::signal_curvegraph_leave() { + return sig_curvegraph_leave; +} + +sigc::signal CurveEditor::signal_curvepoint_click() { + return sig_curvepoint_click; +} + +sigc::signal CurveEditor::signal_curvepoint_release() { + return sig_curvepoint_release; +} diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h index 668b20436..df0950434 100644 --- a/rtgui/curveeditor.h +++ b/rtgui/curveeditor.h @@ -21,6 +21,7 @@ #include "popuptogglebutton.h" #include "../rtengine/LUT.h" +#include "coloredbar.h" class CurveEditorGroup; class CurveEditorSubGroup; @@ -63,6 +64,17 @@ class CurveEditor { std::vector tempCurve; sigc::connection typeconn; + ColorProvider* bottomBarCP; + ColorProvider* leftBarCP; + ColorProvider* curveCP; + std::vector bottomBarBgGradient; + std::vector leftBarBgGradient; + + sigc::signal sig_curvegraph_enter; + sigc::signal sig_curvegraph_leave; + sigc::signal sig_curvepoint_click; + sigc::signal sig_curvepoint_release; + public: CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup); @@ -73,10 +85,27 @@ class CurveEditor { void setUnChanged (bool uc); void updateBackgroundHistogram (LUTu & hist); + void setLeftBarColorProvider(ColorProvider* cp); + void setBottomBarColorProvider(ColorProvider* cp); + void setCurveColorProvider(ColorProvider* cp); + void setBottomBarBgGradient (const std::vector &milestones); + void setLeftBarBgGradient (const std::vector &milestones); + ColorProvider* getLeftBarColorProvider(); + ColorProvider* getBottomBarColorProvider(); + ColorProvider* getCurveColorProvider(); + std::vector getBottomBarBgGradient () const; + std::vector getLeftBarBgGradient () const; + bool openIfNonlinear(); // Open up the curve if it has modifications and it's not already opened void setCurve (const std::vector& p); virtual std::vector getCurve () = 0; + void setTooltip(Glib::ustring ttip); + + sigc::signal signal_curvegraph_enter(); + sigc::signal signal_curvegraph_leave(); + sigc::signal signal_curvepoint_click(); + sigc::signal signal_curvepoint_release(); }; @@ -94,10 +123,16 @@ class DiagonalCurveEditor : public CurveEditor { std::vector customCurveEd; std::vector paramCurveEd; std::vector NURBSCurveEd; + Glib::ustring rangeLabels[4]; + double rangeMilestones[3]; public: DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup); std::vector getCurve (); + void setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); + void getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4); + void setRangeDefaultMilestones(double m1, double m2, double m3); + void getRangeDefaultMilestones(double &m1, double &m2, double &m3); }; diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc index aae30196a..721374108 100644 --- a/rtgui/curveeditorgroup.cc +++ b/rtgui/curveeditorgroup.cc @@ -27,9 +27,7 @@ #include "../rtengine/safegtk.h" #include "rtimage.h" -extern Glib::ustring argv0; - -CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), cl(NULL), cp(NULL) { +CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), cl(NULL) { curveEditors.clear(); displayedCurve = 0; numberOfPackedCurve = 0; @@ -121,12 +119,6 @@ void CurveEditorGroup::newLine() { void CurveEditorGroup::curveListComplete() { newLine(); - // Set the color provider - if (cp) { - if (flatSubGroup) flatSubGroup->setColorProvider(cp); - if (diagonalSubGroup) diagonalSubGroup->setColorProvider(cp); - } - // We check the length of the label ; if it contains only one char (':'), we set it to the right default string if (curveGroupLabel->get_label().size()==1) curveGroupLabel->set_label(M(curveEditors.size() > 1 ? "CURVEEDITOR_CURVES" : "CURVEEDITOR_CURVE") + ":"); @@ -294,8 +286,15 @@ void CurveEditorGroup::setUnChanged (bool uc, CurveEditor* ce) { } } -CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : - curveDir(curveDir), lastFilename("") { +CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), lastFilename("") { + leftBar = NULL; + bottomBar = NULL; + curveCP = NULL; +} + +CurveEditorSubGroup::~CurveEditorSubGroup() { + if (leftBar) delete leftBar; + if (bottomBar) delete bottomBar; } Glib::ustring CurveEditorSubGroup::outputFile () { diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h index 6cec43e0c..f63e33c20 100644 --- a/rtgui/curveeditorgroup.h +++ b/rtgui/curveeditorgroup.h @@ -58,7 +58,6 @@ protected: DiagonalCurveEditorSubGroup* diagonalSubGroup; CurveListener* cl; - ColorProvider* cp; unsigned int numberOfPackedCurve; @@ -68,6 +67,7 @@ public: * This variable will be updated with actions in the * dialogs. */ + CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); ~CurveEditorGroup(); void newLine(); @@ -75,7 +75,6 @@ public: void setBatchMode (bool batchMode); void setCurveExternal (CurveEditor* ce, const std::vector& c); void setCurveListener (CurveListener* l) { cl = l; } - void setColorProvider (ColorProvider* p) { cp = p; } CurveEditor* getDisplayedCurve () { return displayedCurve; } //void on_realize (); CurveEditor* addCurve(CurveType cType, Glib::ustring curveLabel, bool periodic = true); @@ -105,11 +104,16 @@ protected: int valUnchanged; CurveEditorGroup *parent; + ColoredBar* leftBar; + ColoredBar* bottomBar; + ColorProvider* curveCP; + + public: + ~CurveEditorSubGroup(); int getValUnchanged() { return valUnchanged; } int getValLinear() { return valLinear; } virtual void updateBackgroundHistogram (CurveEditor* ce) {} - virtual void setColorProvider (ColorProvider* p) = 0; protected: diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc index 515e89508..2c2deaf86 100644 --- a/rtgui/diagonalcurveeditorsubgroup.cc +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -51,7 +51,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Gtk::HBox* custombbox = Gtk::manage (new Gtk::HBox ()); custombbox->set_spacing(4); - pasteCustom = Gtk::manage (new Gtk::Button ()); + pasteCustom = Gtk::manage (new Gtk::Button ()); pasteCustom->add (*Gtk::manage (new RTImage ("edit-paste.png"))); copyCustom = Gtk::manage (new Gtk::Button ()); copyCustom->add (*Gtk::manage (new RTImage ("edit-copy.png"))); @@ -60,8 +60,8 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, loadCustom = Gtk::manage (new Gtk::Button ()); loadCustom->add (*Gtk::manage (new RTImage ("gtk-open.png"))); - custombbox->pack_end (*pasteCustom, Gtk::PACK_SHRINK, 0); - custombbox->pack_end (*copyCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_end (*pasteCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_end (*copyCustom, Gtk::PACK_SHRINK, 0); custombbox->pack_end (*saveCustom, Gtk::PACK_SHRINK, 0); custombbox->pack_end (*loadCustom, Gtk::PACK_SHRINK, 0); @@ -70,13 +70,13 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, saveCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); loadCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); - copyCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); - pasteCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + copyCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + pasteCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); saveCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); loadCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); - copyCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); - pasteCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + copyCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + pasteCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); // Custom curve end @@ -92,7 +92,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Gtk::HBox* NURBSbbox = Gtk::manage (new Gtk::HBox ()); NURBSbbox->set_spacing(4); - pasteNURBS = Gtk::manage (new Gtk::Button ()); + pasteNURBS = Gtk::manage (new Gtk::Button ()); pasteNURBS->add (*Gtk::manage (new RTImage ("edit-paste.png"))); copyNURBS = Gtk::manage (new Gtk::Button ()); copyNURBS->add (*Gtk::manage (new RTImage ("edit-copy.png"))); @@ -101,8 +101,8 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, loadNURBS = Gtk::manage (new Gtk::Button ()); loadNURBS->add (*Gtk::manage (new RTImage ("gtk-open.png"))); - NURBSbbox->pack_end (*pasteNURBS, Gtk::PACK_SHRINK, 0); - NURBSbbox->pack_end (*copyNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_end (*pasteNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_end (*copyNURBS, Gtk::PACK_SHRINK, 0); NURBSbbox->pack_end (*saveNURBS, Gtk::PACK_SHRINK, 0); NURBSbbox->pack_end (*loadNURBS, Gtk::PACK_SHRINK, 0); @@ -111,26 +111,26 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, saveNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); loadNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); - pasteNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); - copyNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + pasteNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + copyNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); saveNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); loadNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); - pasteNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); - copyNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + pasteNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + copyNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); // NURBS curve end // parametric curve paramCurveBox = new Gtk::VBox (); - paramCurveBox->set_spacing(4); + paramCurveBox->set_spacing(0); paramCurve = Gtk::manage (new MyDiagonalCurve ()); paramCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); paramCurve->setType (DCT_Parametric); shcSelector = Gtk::manage (new SHCSelector ()); - shcSelector->set_size_request (GRAPH_SIZE-100, 20); // width, height + shcSelector->set_size_request (GRAPH_SIZE-100, 12); // width, height //* shcSelector->set_size_request ((GRAPH_SIZE+2*RADIUS)-20, 20); paramCurveBox->pack_start (*paramCurve, Gtk::PACK_EXPAND_WIDGET, 0); @@ -138,7 +138,7 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Gtk::HBox* Parambbox = Gtk::manage (new Gtk::HBox ()); Parambbox->set_spacing(4); - pasteParam = Gtk::manage (new Gtk::Button ()); + pasteParam = Gtk::manage (new Gtk::Button ()); pasteParam->add (*Gtk::manage (new RTImage ("edit-paste.png"))); copyParam = Gtk::manage (new Gtk::Button ()); copyParam->add (*Gtk::manage (new RTImage ("edit-copy.png"))); @@ -147,22 +147,21 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, loadParam = Gtk::manage (new Gtk::Button ()); loadParam->add (*Gtk::manage (new RTImage ("gtk-open.png"))); - Parambbox->pack_end (*pasteParam, Gtk::PACK_SHRINK, 0); - Parambbox->pack_end (*copyParam, Gtk::PACK_SHRINK, 0); + Parambbox->pack_end (*pasteParam, Gtk::PACK_SHRINK, 0); + Parambbox->pack_end (*copyParam, Gtk::PACK_SHRINK, 0); Parambbox->pack_end (*saveParam, Gtk::PACK_SHRINK, 0); Parambbox->pack_end (*loadParam, Gtk::PACK_SHRINK, 0); saveParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); loadParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); - pasteParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); - copyParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + pasteParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + copyParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); saveParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); loadParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); - pasteParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); - copyParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + pasteParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + copyParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); - paramCurveBox->set_spacing(4); paramCurveBox->pack_end (*Parambbox, Gtk::PACK_EXPAND_WIDGET, 0); highlights = Gtk::manage (new Adjuster (M("CURVEEDITOR_HIGHLIGHTS"), -100, 100, 1, 0)); @@ -218,9 +217,9 @@ DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, } DiagonalCurveEditorSubGroup::~DiagonalCurveEditorSubGroup() { - delete customCurveBox; - delete paramCurveBox; - delete NURBSCurveBox; + delete customCurveBox; + delete paramCurveBox; + delete NURBSCurveBox; } /* @@ -253,30 +252,101 @@ void DiagonalCurveEditorSubGroup::switchGUI() { // Initializing GUI values + repacking the appropriated widget //dCurve->typeconn.block(true); + // first we update the colored bar + + ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider(); + std::vector bgGradient = dCurve->getLeftBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (leftBar) { + delete leftBar; + leftBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!leftBar) { + leftBar = new ColoredBar(RTO_Bottom2Top); + } + if (barColorProvider) { + bgGradient.clear(); + leftBar->setColorProvider(barColorProvider); + leftBar->setBgGradient (bgGradient); + } + else { + leftBar->setColorProvider(NULL); + leftBar->setBgGradient (bgGradient); + } + } + + barColorProvider = dCurve->getBottomBarColorProvider(); + bgGradient = dCurve->getBottomBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (bottomBar) { + delete bottomBar; + bottomBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!bottomBar) { + bottomBar = new ColoredBar(RTO_Left2Right); + } + if (barColorProvider) { + bgGradient.clear(); + bottomBar->setColorProvider(barColorProvider); + bottomBar->setBgGradient (bgGradient); + } + else { + bottomBar->setColorProvider(NULL); + bottomBar->setBgGradient (bgGradient); + } + } switch((DiagonalCurveType)(dCurve->curveType->getSelected())) { case (DCT_Spline): customCurve->setPoints (dCurve->customCurveEd); + customCurve->setColorProvider(dCurve->getCurveColorProvider()); + customCurve->setColoredBar(leftBar, bottomBar); parent->pack_start (*customCurveBox); customCurveBox->check_resize(); customCurve->forceResize(); break; case (DCT_Parametric): + { + Glib::ustring label[4]; + dCurve->getRangeLabels(label[0], label[1], label[2], label[3]); + double mileStone[3]; + dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]); paramCurve->setPoints (dCurve->paramCurveEd); + shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]); shcSelector->setPositions ( dCurve->paramCurveEd.at(1), dCurve->paramCurveEd.at(2), dCurve->paramCurveEd.at(3) ); + highlights->setValue (dCurve->paramCurveEd.at(4)); + highlights->setLabel(label[3]); lights->setValue (dCurve->paramCurveEd.at(5)); + lights->setLabel(label[2]); darks->setValue (dCurve->paramCurveEd.at(6)); + darks->setLabel(label[1]); shadows->setValue (dCurve->paramCurveEd.at(7)); + shadows->setLabel(label[0]); + shcSelector->setColorProvider(barColorProvider); + shcSelector->setBgGradient(bgGradient); + shcSelector->setMargins( (leftBar ? CBAR_WIDTH+CBAR_MARGIN : RADIUS), RADIUS ); + paramCurve->setColoredBar(leftBar, NULL); parent->pack_start (*paramCurveBox); paramCurve->forceResize(); break; + } case (DCT_NURBS): NURBSCurve->setPoints (dCurve->NURBSCurveEd); + NURBSCurve->setColorProvider(dCurve->getCurveColorProvider()); + NURBSCurve->setColoredBar(leftBar, bottomBar); parent->pack_start (*NURBSCurveBox); NURBSCurveBox->check_resize(); NURBSCurve->forceResize(); @@ -306,7 +376,7 @@ void DiagonalCurveEditorSubGroup::savePressed () { p = NURBSCurve->getPoints (); break; case DCT_Parametric: - p = paramCurve->getPoints (); + p = paramCurve->getPoints (); break; default: break; @@ -322,14 +392,14 @@ void DiagonalCurveEditorSubGroup::savePressed () { else if (p[ix]==(double)(DCT_Parametric)) f << "Parametric\n"; if (p[ix]==(double)(DCT_Parametric)) { - ix++; - for (unsigned int i=0; inotifyListener (); } else if (p[0] == (double)(DCT_Parametric)) { - shcSelector->setPositions ( - p[1], - p[2], - p[3] ); - highlights->setValue (p[4]); - lights->setValue (p[5]); - darks->setValue (p[6]); - shadows->setValue (p[7]); - paramCurve->setPoints (p); - paramCurve->queue_draw (); - paramCurve->notifyListener (); + shcSelector->setPositions ( p[1], p[2], p[3] ); + highlights->setValue (p[4]); + lights->setValue (p[5]); + darks->setValue (p[6]); + shadows->setValue (p[7]); + paramCurve->setPoints (p); + paramCurve->queue_draw (); + paramCurve->notifyListener (); } } - } + } } void DiagonalCurveEditorSubGroup::copyPressed () { // For compatibility use enum DiagonalCurveType here - std::vector curve; + std::vector curve; - switch (parent->displayedCurve->selected) { - case DCT_Spline: // custom - curve = customCurve->getPoints (); - clipboard.setCurveData (curve,DCT_Spline); - break; - case DCT_Parametric: // parametric - // ... do something, first add save/load functions - curve = paramCurve->getPoints (); - clipboard.setCurveData (curve,DCT_Parametric); - break; - case DCT_NURBS: // NURBS - curve = NURBSCurve->getPoints (); - clipboard.setCurveData (curve,DCT_NURBS); - break; - default: // (DCT_Linear, DCT_Unchanged) - // ... do nothing - break; - } + switch (parent->displayedCurve->selected) { + case DCT_Spline: // custom + curve = customCurve->getPoints (); + clipboard.setCurveData (curve,DCT_Spline); + break; + case DCT_Parametric: // parametric + // ... do something, first add save/load functions + curve = paramCurve->getPoints (); + clipboard.setCurveData (curve,DCT_Parametric); + break; + case DCT_NURBS: // NURBS + curve = NURBSCurve->getPoints (); + clipboard.setCurveData (curve,DCT_NURBS); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } } void DiagonalCurveEditorSubGroup::pastePressed () { // For compatibility use enum DiagonalCurveType here - std::vector curve; - DiagonalCurveType type; + std::vector curve; + DiagonalCurveType type; - type = clipboard.hasCurveData(); + type = clipboard.hasCurveData(); - if (type == (DiagonalCurveType)parent->displayedCurve->selected) { - curve = clipboard.getCurveData (); - switch (type) { - case DCT_Linear: // linear - break; - case DCT_Spline: // custom - customCurve->setPoints (curve); - customCurve->queue_draw (); - customCurve->notifyListener (); - break; - case DCT_Parametric: // parametric - // ... do something, first add save/load functions - shcSelector->setPositions ( - curve[1], - curve[2], - curve[3] ); - highlights->setValue (curve[4]); - lights->setValue (curve[5]); - darks->setValue (curve[6]); - shadows->setValue (curve[7]); - paramCurve->setPoints (curve); - paramCurve->queue_draw (); - paramCurve->notifyListener (); - break; - case DCT_NURBS: // NURBS - NURBSCurve->setPoints (curve); - NURBSCurve->queue_draw (); - NURBSCurve->notifyListener (); - break; - default: // (DCT_Linear, DCT_Unchanged) - // ... do nothing - break; - } - } - return; + if (type == (DiagonalCurveType)parent->displayedCurve->selected) { + curve = clipboard.getCurveData (); + switch (type) { + case DCT_Linear: // linear + break; + case DCT_Spline: // custom + customCurve->setPoints (curve); + customCurve->queue_draw (); + customCurve->notifyListener (); + break; + case DCT_Parametric: // parametric + // ... do something, first add save/load functions + shcSelector->setPositions ( + curve[1], + curve[2], + curve[3] ); + highlights->setValue (curve[4]); + lights->setValue (curve[5]); + darks->setValue (curve[6]); + shadows->setValue (curve[7]); + paramCurve->setPoints (curve); + paramCurve->queue_draw (); + paramCurve->notifyListener (); + break; + case DCT_NURBS: // NURBS + NURBSCurve->setPoints (curve); + NURBSCurve->queue_draw (); + NURBSCurve->notifyListener (); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + } + return; } @@ -529,9 +596,9 @@ const std::vector DiagonalCurveEditorSubGroup::getCurveFromGUI (int type return lcurve; } case (DCT_Spline): - return customCurve->getPoints (); + return customCurve->getPoints (); case (DCT_NURBS): - return NURBSCurve->getPoints (); + return NURBSCurve->getPoints (); default: { // linear and other solutions std::vector lcurve (1); @@ -561,18 +628,26 @@ bool DiagonalCurveEditorSubGroup::curveReset(int cType) { return true; break; case (DCT_Parametric) : + { + DiagonalCurveEditor* dCurve = static_cast(parent->displayedCurve); + double mileStone[3]; + dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]); + highlights->resetPressed(NULL); lights->resetPressed(NULL); darks->resetPressed(NULL); shadows->resetPressed(NULL); + shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]); shcSelector->reset(); paramCurve->reset (); return true; break; + } default: return false; break; } + return true; } void DiagonalCurveEditorSubGroup::setColorProvider (ColorProvider* p) { @@ -596,7 +671,7 @@ void DiagonalCurveEditorSubGroup::shcChanged () { */ void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval) { - paramCurve->setPoints (getCurveFromGUI(DCT_Parametric)); + paramCurve->setPoints (getCurveFromGUI(DCT_Parametric)); storeDisplayedCurve(); parent->curveChanged (); } @@ -606,11 +681,11 @@ void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval) { */ bool DiagonalCurveEditorSubGroup::adjusterEntered (GdkEventCrossing* ev, int ac) { - if (ev->detail != GDK_NOTIFY_INFERIOR) { - activeParamControl = ac; - paramCurve->setActiveParam (activeParamControl); - } - return true; + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = ac; + paramCurve->setActiveParam (activeParamControl); + } + return true; } /* @@ -618,11 +693,11 @@ bool DiagonalCurveEditorSubGroup::adjusterEntered (GdkEventCrossing* ev, int ac) */ bool DiagonalCurveEditorSubGroup::adjusterLeft (GdkEventCrossing* ev, int ac) { - if (ev->detail != GDK_NOTIFY_INFERIOR) { - activeParamControl = -1; - paramCurve->setActiveParam (activeParamControl); - } - return true; + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = -1; + paramCurve->setActiveParam (activeParamControl); + } + return true; } void DiagonalCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) { @@ -632,3 +707,10 @@ void DiagonalCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) { NURBSCurve->updateBackgroundHistogram (ce->histogram); } } + +void DiagonalCurveEditorSubGroup::setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) { + shadows->setLabel(r1); + darks->setLabel(r2); + lights->setLabel(r3); + highlights->setLabel(r4); +} diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h index fc5fb5a80..3b1be7254 100644 --- a/rtgui/diagonalcurveeditorsubgroup.h +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -66,6 +66,7 @@ public: virtual void updateBackgroundHistogram (CurveEditor* ce); virtual void setColorProvider (ColorProvider* p); + protected: void storeCurveValues (CurveEditor* ce, const std::vector& p); void storeDisplayedCurve (); @@ -82,6 +83,8 @@ protected: void adjusterChanged (Adjuster* a, double newval); bool adjusterEntered (GdkEventCrossing* ev, int ac); bool adjusterLeft (GdkEventCrossing* ev, int ac); + void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); + void setSubGroupBottomBarBgGradient(); }; #endif diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc index 5526bcdd7..d45f0ee03 100644 --- a/rtgui/flatcurveeditorsubgroup.cc +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -37,19 +37,19 @@ FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::u parent = prt; // ControlPoints curve - CPointsCurveBox = new Gtk::HBox (); + CPointsCurveBox = new Gtk::VBox (); CPointsCurveBox->set_spacing(4); CPointsCurve = Gtk::manage (new MyFlatCurve ()); - //CPointsCurve->set_size_request (GRAPH_SIZE+2*RADIUS+1, GRAPH_SIZE+2*RADIUS+1); + CPointsCurve->set_size_request (GRAPH_SIZE+2*RADIUS+1, GRAPH_SIZE+2*RADIUS+1); CPointsCurve->setType (FCT_MinMaxCPoints); CPointsCurveBox->pack_start (*CPointsCurve, Gtk::PACK_EXPAND_WIDGET, 0); - Gtk::VBox* CPointsbbox = Gtk::manage (new Gtk::VBox ()); + Gtk::HBox* CPointsbbox = Gtk::manage (new Gtk::HBox ()); CPointsbbox->set_spacing(4); saveCPoints = Gtk::manage (new Gtk::Button ()); - saveCPoints->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON))); + saveCPoints->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); loadCPoints = Gtk::manage (new Gtk::Button ()); - loadCPoints->add (*Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-open"), Gtk::ICON_SIZE_BUTTON))); + loadCPoints->add (*Gtk::manage (new RTImage ("gtk-open.png"))); CPointsbbox->pack_end (*saveCPoints, Gtk::PACK_SHRINK, 0); CPointsbbox->pack_end (*loadCPoints, Gtk::PACK_SHRINK, 0); @@ -97,10 +97,64 @@ void FlatCurveEditorSubGroup::switchGUI() { // Initializing GUI values + repacking the appropriated widget //dCurve->typeconn.block(true); + // first we update the colored bar + + ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider(); + std::vector bgGradient = dCurve->getLeftBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (leftBar) { + delete leftBar; + leftBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!leftBar) { + leftBar = new ColoredBar(RTO_Bottom2Top); + } + if (barColorProvider) { + bgGradient.clear(); + leftBar->setColorProvider(barColorProvider); + leftBar->setBgGradient (bgGradient); + } + else { + leftBar->setColorProvider(NULL); + leftBar->setBgGradient (bgGradient); + } + } + + barColorProvider = dCurve->getBottomBarColorProvider(); + bgGradient = dCurve->getBottomBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (bottomBar) { + delete bottomBar; + bottomBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!bottomBar) { + bottomBar = new ColoredBar(RTO_Left2Right); + } + if (barColorProvider) { + bgGradient.clear(); + bottomBar->setColorProvider(barColorProvider); + bottomBar->setBgGradient (bgGradient); + } + else { + bottomBar->setColorProvider(NULL); + bottomBar->setBgGradient (bgGradient); + } + } + switch((FlatCurveType)(dCurve->curveType->getSelected())) { case (FCT_MinMaxCPoints): CPointsCurve->setPeriodicity(dCurve->periodic); // Setting Periodicity before setting points CPointsCurve->setPoints (dCurve->controlPointsCurveEd); + CPointsCurve->setColorProvider(dCurve->getCurveColorProvider()); + CPointsCurve->setColoredBar(leftBar, bottomBar); parent->pack_start (*CPointsCurveBox); CPointsCurveBox->check_resize(); CPointsCurve->forceResize(); diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h index ed6628107..5b9e6a208 100644 --- a/rtgui/flatcurveeditorsubgroup.h +++ b/rtgui/flatcurveeditorsubgroup.h @@ -29,7 +29,7 @@ class FlatCurveEditorSubGroup: public CurveEditorSubGroup { friend class FlatCurveEditor; protected: - Gtk::HBox* CPointsCurveBox; + Gtk::VBox* CPointsCurveBox; MyFlatCurve* CPointsCurve; diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc index 1c4fb9683..1b105267e 100644 --- a/rtgui/guiutils.cc +++ b/rtgui/guiutils.cc @@ -497,3 +497,89 @@ void TextOrIcon::switchTo(TOITypes type) { } show_all(); } + +BackBuffer::BackBuffer() { + x = y = w = h = 0; + dirty = true; +} + +bool BackBuffer::setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int newH) { + bool newSize = w!=newW || h!=newH; + + x = newX; + y = newY; + w = newW; + h = newH; + + // WARNING: we're assuming that the surface type won't change during all the execution time of RT. I guess it may be wrong when the user change the gfx card display settings!? + if (newSize && window) { + // allocate a new Surface + if (newW>0 && newH>0) { + surface = window->create_similar_surface(Cairo::CONTENT_COLOR, w, h); + } + else { + // at least one dimension is null, so we delete the Surface + surface.clear(); + // and we reset all dimensions + x = y = w = h = 0; + } + dirty = true; + } + return dirty; +} + +/* + * Copy the backbuffer to a Gdk::Window + */ +void BackBuffer::copySurface(Glib::RefPtr window, GdkRectangle *rectangle) { + if (surface && window) { + // TODO: look out if window can be different on each call, and if not, store a reference to the window + Cairo::RefPtr crSrc = window->create_cairo_context(); + Cairo::RefPtr destSurface = crSrc->get_target(); + + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x, y); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + +/* + * Copy the BackBuffer to another BackBuffer + */ +void BackBuffer::copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle) { + if (surface && destBackBuffer) { + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destBackBuffer->getSurface()); + crDest->set_source(surface, x, y); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + +/* + * Copy the BackBuffer to another Cairo::Surface + */ +void BackBuffer::copySurface(Cairo::RefPtr destSurface, GdkRectangle *rectangle) { + if (surface && destSurface) { + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x, y); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h index 1f48502b5..392689c0c 100644 --- a/rtgui/guiutils.h +++ b/rtgui/guiutils.h @@ -173,6 +173,13 @@ private: }; +typedef enum RTOrientation { + RTO_Left2Right, + RTO_Bottom2Top, + RTO_Right2Left, + RTO_Top2Bottom +} eRTOrientation; + enum TOITypes { TOI_TEXT, TOI_ICON @@ -213,4 +220,60 @@ public: } }; +/** + * @brief Handle point coordinates + */ +template +class Point { +public: + T x, y; + Point() { + x = T(0); + y = T(0); + } + + Point(T coordX, T coordY) { + x = coordX; + y = coordY; + } + + void setCoords(T coordX, T coordY) { + x = coordX; + y = coordY; + } +}; + +/** + * @brief Handle backbuffers as automatically as possible + */ +class BackBuffer { + +protected: + int x, y, w, h; // Rectangle where the colored bar has to be drawn + Cairo::RefPtr surface; + bool dirty; // mean that the Surface has to be (re)allocated + +public: + BackBuffer(); + + // set the destination drawing rectangle; return true if the dimensions are different + bool setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int newH); + + void copySurface(Glib::RefPtr window, GdkRectangle *rectangle=NULL); + void copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle=NULL); + void copySurface(Cairo::RefPtr destSurface, GdkRectangle *rectangle=NULL); + + void setDirty(bool isDirty) { dirty = isDirty; if (!dirty && !surface) dirty = true; } + bool isDirty() { return dirty; } + // you have to check if the surface is created thanks to surfaceCreated before starting to draw on it + bool surfaceCreated() { return surface; } + Cairo::RefPtr getSurface() { return surface; } + void deleteSurface() { surface.clear(); dirty=true; } + // will let you get a Cairo::Context for Cairo drawing operations + Cairo::RefPtr getContext() { return Cairo::Context::create(surface); } + int getWidth() { return w; } + int getHeight() { return h; } +}; + + #endif diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc index b5e77f1b1..6d63f9429 100644 --- a/rtgui/hsvequalizer.cc +++ b/rtgui/hsvequalizer.cc @@ -27,13 +27,32 @@ using namespace rtengine::procparams; HSVEqualizer::HSVEqualizer () : Gtk::VBox(), FoldableToolPanel(this) { + std::vector bottomMilestones; + float R, G, B; + // -0.1 rad < Hue < 1.6 rad + for (int i=0; i<7; i++) { + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + curveEditorG = new CurveEditorGroup (options.lastHsvCurvesDir, M("TP_HSVEQUALIZER_CHANNEL")); curveEditorG->setCurveListener (this); - curveEditorG->setColorProvider (this); hshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_HUE"))); + hshape->setBottomBarBgGradient(bottomMilestones); + //hshape->setLeftBarColorProvider(this); Not working yet + hshape->setCurveColorProvider(this); + sshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_SAT"))); + sshape->setBottomBarBgGradient(bottomMilestones); + //sshape->setLeftBarColorProvider(this); Not working yet + sshape->setCurveColorProvider(this); + vshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_VAL"))); + vshape->setBottomBarBgGradient(bottomMilestones); + //vshape->setLeftBarColorProvider(this); Not working yet + vshape->setCurveColorProvider(this); // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index c245a1c3b..68286bf2d 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -18,15 +18,18 @@ */ #include "labcurve.h" #include +#include "../rtengine/improcfun.h" using namespace rtengine; using namespace rtengine::procparams; LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) { - brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100, 100, 1, 0)); - contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100, 100, 1, 0)); - saturation = Gtk::manage (new Adjuster (M("TP_LABCURVE_SATURATION"), -100, 100, 1, 5)); + std::vector bottomMilestones; + + brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); + contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); + chromaticity = Gtk::manage (new Adjuster (M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.)); pack_start (*brightness); brightness->show (); @@ -34,12 +37,12 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) { pack_start (*contrast); contrast->show (); - pack_start (*saturation); - saturation->show (); + pack_start (*chromaticity); + chromaticity->show (); brightness->setAdjusterListener (this); contrast->setAdjusterListener (this); - saturation->setAdjusterListener (this); + chromaticity->setAdjusterListener (this); //%%%%%%%%%%%%%%%%%% pack_start (*Gtk::manage (new Gtk::HSeparator())); @@ -48,24 +51,17 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) { bwtoning->set_tooltip_markup (M("TP_LABCURVE_BWTONING_TIP")); pack_start (*bwtoning); - avoidclip = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORCLIP"))); + avoidcolorshift = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORSHIFT"))); + avoidcolorshift->set_tooltip_text (M("TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP")); + pack_start (*avoidcolorshift, Gtk::PACK_SHRINK, 4); + + rstprotection = Gtk::manage ( new Adjuster (M("TP_LABCURVE_RSTPROTECTION"), 0., 100., 0.1, 0.) ); + pack_start (*rstprotection); + rstprotection->show (); - pack_start (*avoidclip); - pack_start (*Gtk::manage (new Gtk::HSeparator())); - - enablelimiter = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_ENABLESATLIMITER"))); - pack_start (*enablelimiter); - - saturationlimiter = Gtk::manage ( new Adjuster (M("TP_LABCURVE_SATLIMIT"), 0, 100, 1.0, 50) ); - pack_start (*saturationlimiter); - saturationlimiter->show (); - saturationlimiter->reference (); - - //saturation->setAdjusterListener (this); - saturationlimiter->setAdjusterListener (this); + rstprotection->setAdjusterListener (this); bwtconn= bwtoning->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::bwtoning_toggled) ); - acconn = avoidclip->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidclip_toggled) ); - elconn = enablelimiter->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::enablelimiter_toggled) ); + acconn = avoidcolorshift->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidcolorshift_toggled) ); //%%%%%%%%%%%%%%%%%%% Gtk::HSeparator *hsep3 = Gtk::manage (new Gtk::HSeparator()); @@ -74,17 +70,52 @@ LCurve::LCurve () : Gtk::VBox(), FoldableToolPanel(this) { curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); curveEditorG->setCurveListener (this); - curveEditorG->setColorProvider (this); + ccshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CC"))); + ccshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP")); + ccshape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE4") + ); + ccshape->setRangeDefaultMilestones(0.05, 0.2, 0.58); + //cbgshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CBG")); + //cbgshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CBG_TOOLTIP")); + // -0.1 rad < Hue < 1.6 rad + for (int i=0; i<7; i++) { + float R, G, B; + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + chshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_CH"))); + chshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP")); + chshape->setBottomBarBgGradient(bottomMilestones); + chshape->setCurveColorProvider(this); + + curveEditorG->newLine(); + + bottomMilestones.clear(); + bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) ); lshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "L")); + lshape->setBottomBarBgGradient(bottomMilestones); + lshape->setLeftBarBgGradient(bottomMilestones); ashape = static_cast(curveEditorG->addCurve(CT_Diagonal, "a")); + ashape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_A_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_A_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE4") + ); bshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "b")); + bshape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_B_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_B_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE4") + ); // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); - + } LCurve::~LCurve () { @@ -98,53 +129,63 @@ void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { if (pedited) { brightness->setEditedState (pedited->labCurve.brightness ? Edited : UnEdited); contrast->setEditedState (pedited->labCurve.contrast ? Edited : UnEdited); - saturation->setEditedState (pedited->labCurve.saturation ? Edited : UnEdited); + chromaticity->setEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); //%%%%%%%%%%%%%%%%%%%%%% - saturationlimiter->setEditedState (pedited->labCurve.saturationlimit ? Edited : UnEdited); + rstprotection->setEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); bwtoning->set_inconsistent (!pedited->labCurve.bwtoning); - avoidclip->set_inconsistent (!pedited->labCurve.avoidclip); - enablelimiter->set_inconsistent (!pedited->labCurve.enable_saturationlimiter); + avoidcolorshift->set_inconsistent (!pedited->labCurve.avoidcolorshift); //%%%%%%%%%%%%%%%%%%%%%% - lshape->setUnChanged (!pedited->labCurve.lcurve); - ashape->setUnChanged (!pedited->labCurve.acurve); - bshape->setUnChanged (!pedited->labCurve.bcurve); - + lshape->setUnChanged (!pedited->labCurve.lcurve); + ashape->setUnChanged (!pedited->labCurve.acurve); + bshape->setUnChanged (!pedited->labCurve.bcurve); + ccshape->setUnChanged (!pedited->labCurve.cccurve); + chshape->setUnChanged (!pedited->labCurve.chcurve); + //cbgshape->setUnChanged (!pedited->labCurve.cbgcurve); + } + else { + //if bwtoning is enabled, chromaticity value, avoid color shift and rstprotection has no effect + //ccshape->set_sensitive(!(!pp->labCurve.bwtoning)); + //chshape->set_sensitive(!(!pp->labCurve.bwtoning)); + chromaticity->set_sensitive(!pp->labCurve.bwtoning); + rstprotection->set_sensitive( !pp->labCurve.bwtoning && pp->labCurve.chromaticity!=0 ); + avoidcolorshift->set_sensitive(!pp->labCurve.bwtoning); } brightness->setValue (pp->labCurve.brightness); contrast->setValue (pp->labCurve.contrast); - saturation->setValue (pp->labCurve.saturation); + chromaticity->setValue (pp->labCurve.chromaticity); //%%%%%%%%%%%%%%%%%%%%%% - saturationlimiter->setValue (pp->labCurve.saturationlimit); + rstprotection->setValue (pp->labCurve.rstprotection); + + bwtconn.block (true); acconn.block (true); bwtoning->set_active (pp->labCurve.bwtoning); - saturation->set_sensitive(!(bwtoning->get_active ())); //at bwtoning enabled saturation value has no effect - avoidclip->set_active (pp->labCurve.avoidclip); + avoidcolorshift->set_active (pp->labCurve.avoidcolorshift); + bwtconn.block (false); acconn.block (false); - elconn.block (true); - enablelimiter->set_active (pp->labCurve.enable_saturationlimiter); - elconn.block (false); - - //removeIfThere (this, saturationlimiter, false); - // if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) - // pack_start (*saturationlimiter); - + lastBWTVal = pp->labCurve.bwtoning; - lastACVal = pp->labCurve.avoidclip; - lastELVal = pp->labCurve.enable_saturationlimiter; + lastACVal = pp->labCurve.avoidcolorshift; //%%%%%%%%%%%%%%%%%%%%%% - lshape->setCurve (pp->labCurve.lcurve); - ashape->setCurve (pp->labCurve.acurve); - bshape->setCurve (pp->labCurve.bcurve); + lshape->setCurve (pp->labCurve.lcurve); + ashape->setCurve (pp->labCurve.acurve); + bshape->setCurve (pp->labCurve.bcurve); + ccshape->setCurve (pp->labCurve.cccurve); + chshape->setCurve (pp->labCurve.chcurve); + //cbgshape->setCurve (pp->labCurve.cbgcurve); // Open up the first curve if selected bool active = lshape->openIfNonlinear(); if (!active) ashape->openIfNonlinear(); if (!active) bshape->openIfNonlinear(); + if (!active) ccshape->openIfNonlinear(); + if (!active) chshape->openIfNonlinear(); + + queue_draw(); enableListener (); } @@ -153,34 +194,38 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) { pp->labCurve.brightness = brightness->getValue (); pp->labCurve.contrast = (int)contrast->getValue (); - pp->labCurve.saturation = (int)saturation->getValue (); + pp->labCurve.chromaticity = (int)chromaticity->getValue (); //%%%%%%%%%%%%%%%%%%%%%% - pp->labCurve.bwtoning = bwtoning->get_active (); - pp->labCurve.avoidclip = avoidclip->get_active (); - pp->labCurve.enable_saturationlimiter = enablelimiter->get_active (); - pp->labCurve.saturationlimit = saturationlimiter->getValue (); + pp->labCurve.bwtoning = bwtoning->get_active (); + pp->labCurve.avoidcolorshift = avoidcolorshift->get_active (); + pp->labCurve.rstprotection = rstprotection->getValue (); //%%%%%%%%%%%%%%%%%%%%%% - pp->labCurve.lcurve = lshape->getCurve (); - pp->labCurve.acurve = ashape->getCurve (); - pp->labCurve.bcurve = bshape->getCurve (); + pp->labCurve.lcurve = lshape->getCurve (); + pp->labCurve.acurve = ashape->getCurve (); + pp->labCurve.bcurve = bshape->getCurve (); + pp->labCurve.cccurve = ccshape->getCurve (); + pp->labCurve.chcurve = chshape->getCurve (); + //pp->labCurve.cbgcurve = cbgshape->getCurve (); if (pedited) { - pedited->labCurve.brightness = brightness->getEditedState (); - pedited->labCurve.contrast = contrast->getEditedState (); - pedited->labCurve.saturation = saturation->getEditedState (); + pedited->labCurve.brightness = brightness->getEditedState (); + pedited->labCurve.contrast = contrast->getEditedState (); + pedited->labCurve.chromaticity = chromaticity->getEditedState (); //%%%%%%%%%%%%%%%%%%%%%% - pedited->labCurve.bwtoning = !bwtoning->get_inconsistent(); - pedited->labCurve.avoidclip = !avoidclip->get_inconsistent(); - pedited->labCurve.enable_saturationlimiter = !enablelimiter->get_inconsistent(); - pedited->labCurve.saturationlimit = saturationlimiter->getEditedState (); + pedited->labCurve.bwtoning = !bwtoning->get_inconsistent(); + pedited->labCurve.avoidcolorshift = !avoidcolorshift->get_inconsistent(); + pedited->labCurve.rstprotection = rstprotection->getEditedState (); //%%%%%%%%%%%%%%%%%%%%%% pedited->labCurve.lcurve = !lshape->isUnChanged (); pedited->labCurve.acurve = !ashape->isUnChanged (); pedited->labCurve.bcurve = !bshape->isUnChanged (); + pedited->labCurve.cccurve = !ccshape->isUnChanged (); + pedited->labCurve.chcurve = !chshape->isUnChanged (); + //pedited->labCurve.cbgcurve = !bshape->isUnChanged (); } } @@ -188,46 +233,46 @@ void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedit brightness->setDefault (defParams->labCurve.brightness); contrast->setDefault (defParams->labCurve.contrast); - saturation->setDefault (defParams->labCurve.saturation); - saturationlimiter->setDefault (defParams->labCurve.saturationlimit); + chromaticity->setDefault (defParams->labCurve.chromaticity); + rstprotection->setDefault (defParams->labCurve.rstprotection); if (pedited) { brightness->setDefaultEditedState (pedited->labCurve.brightness ? Edited : UnEdited); contrast->setDefaultEditedState (pedited->labCurve.contrast ? Edited : UnEdited); - saturation->setDefaultEditedState (pedited->labCurve.saturation ? Edited : UnEdited); - saturationlimiter->setDefaultEditedState (pedited->labCurve.saturationlimit ? Edited : UnEdited); + chromaticity->setDefaultEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); + rstprotection->setDefaultEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); } else { brightness->setDefaultEditedState (Irrelevant); contrast->setDefaultEditedState (Irrelevant); - saturation->setDefaultEditedState (Irrelevant); - saturationlimiter->setDefaultEditedState (Irrelevant); + chromaticity->setDefaultEditedState (Irrelevant); + rstprotection->setDefaultEditedState (Irrelevant); } } //%%%%%%%%%%%%%%%%%%%%%% -//Clipping control changed -void LCurve::avoidclip_toggled () { - +//Color shift control changed +void LCurve::avoidcolorshift_toggled () { + if (batchMode) { - if (avoidclip->get_inconsistent()) { - avoidclip->set_inconsistent (false); + if (avoidcolorshift->get_inconsistent()) { + avoidcolorshift->set_inconsistent (false); acconn.block (true); - avoidclip->set_active (false); + avoidcolorshift->set_active (false); acconn.block (false); } else if (lastACVal) - avoidclip->set_inconsistent (true); - - lastACVal = avoidclip->get_active (); + avoidcolorshift->set_inconsistent (true); + + lastACVal = avoidcolorshift->get_active (); } - + if (listener) { - if (avoidclip->get_active ()) - listener->panelChanged (EvLAvoidClip, M("GENERAL_ENABLED")); + if (avoidcolorshift->get_active ()) + listener->panelChanged (EvLAvoidColorShift, M("GENERAL_ENABLED")); else - listener->panelChanged (EvLAvoidClip, M("GENERAL_DISABLED")); + listener->panelChanged (EvLAvoidColorShift, M("GENERAL_DISABLED")); } } @@ -247,8 +292,13 @@ void LCurve::bwtoning_toggled () { lastBWTVal = bwtoning->get_active (); } - - saturation->set_sensitive(!(bwtoning->get_active ())); //at bwtoning enabled saturation value has no effect + else { + //ccshape->set_sensitive(!(!pp->labCurve.bwtoning)); + //chshape->set_sensitive(!(!pp->labCurve.bwtoning)); + chromaticity->set_sensitive( !(bwtoning->get_active ()) ); + rstprotection->set_sensitive( !(bwtoning->get_active ()) && chromaticity->getIntValue()!=0 ); + avoidcolorshift->set_sensitive( !(bwtoning->get_active ()) ); + } if (listener) { if (bwtoning->get_active ()) @@ -258,35 +308,8 @@ void LCurve::bwtoning_toggled () { } } -void LCurve::enablelimiter_toggled () { - - if (batchMode) { - if (enablelimiter->get_inconsistent()) { - enablelimiter->set_inconsistent (false); - elconn.block (true); - enablelimiter->set_active (false); - elconn.block (false); - } - else if (lastELVal) - enablelimiter->set_inconsistent (true); - - lastELVal = enablelimiter->get_active (); - } - - //removeIfThere (this, saturationlimiter, false); - //if (enablelimiter->get_active () || enablelimiter->get_inconsistent()) - // pack_start (*saturationlimiter); - - if (listener) { - if (enablelimiter->get_active ()) - listener->panelChanged (EvLSatLimiter, M("GENERAL_ENABLED")); - else - listener->panelChanged (EvLSatLimiter, M("GENERAL_DISABLED")); - } -} //%%%%%%%%%%%%%%%%%%%%%% - /* * Curve listener * @@ -296,13 +319,19 @@ void LCurve::enablelimiter_toggled () { void LCurve::curveChanged (CurveEditor* ce) { if (listener) { - if (ce == lshape) - listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE")); - if (ce == ashape) - listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE")); - if (ce == bshape) - listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE")); - } + if (ce == lshape) + listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == ashape) + listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == bshape) + listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == ccshape) + listener->panelChanged (EvLCCCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == chshape) + listener->panelChanged (EvLCHCurve, M("HISTORY_CUSTOMCURVE")); + //if (ce == cbgshape) + // listener->panelChanged (EvLCBGCurve, M("HISTORY_CUSTOMCURVE")); + } } void LCurve::adjusterChanged (Adjuster* a, double newval) { @@ -313,7 +342,7 @@ void LCurve::adjusterChanged (Adjuster* a, double newval) { Glib::ustring costr; if (a==brightness) costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); - else if (a==saturationlimiter) + else if (a==rstprotection) costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(1), a->getValue()); else costr = Glib::ustring::format ((int)a->getValue()); @@ -322,10 +351,14 @@ void LCurve::adjusterChanged (Adjuster* a, double newval) { listener->panelChanged (EvLBrightness, costr); else if (a==contrast) listener->panelChanged (EvLContrast, costr); - else if (a==saturation) + else if (a==chromaticity) { + if (!batchMode) { + rstprotection->set_sensitive( !(bwtoning->get_active ()) && chromaticity->getIntValue()!=0 ); + } listener->panelChanged (EvLSaturation, costr); - else if (a==saturationlimiter) - listener->panelChanged (EvLSatLimit, costr); + } + else if (a==rstprotection) + listener->panelChanged (EvLRSTProtection, costr); } void LCurve::colorForValue (double valX, double valY) { @@ -348,6 +381,22 @@ void LCurve::colorForValue (double valX, double valY) { green = (double)valY; blue = (double)valY; } + else if (ce == ccshape) { // c = f(c) + red = (double)valY; + green = (double)valY; + blue = (double)valY; + } + else if (ce == chshape) { // c = f(h) + + float r, g, b; + + Color::hsv2rgb01(float(valX), float(valY), 0.5f, r, g, b); + + red = double(r); + green = double(g); + blue = double(b); + } + else { printf("Error: no curve displayed!\n"); } @@ -356,31 +405,31 @@ void LCurve::colorForValue (double valX, double valY) { void LCurve::setBatchMode (bool batchMode) { - ToolPanel::setBatchMode (batchMode); - brightness->showEditedCB (); - contrast->showEditedCB (); - saturation->showEditedCB (); - saturationlimiter->showEditedCB (); + ToolPanel::setBatchMode (batchMode); + brightness->showEditedCB (); + contrast->showEditedCB (); + chromaticity->showEditedCB (); + rstprotection->showEditedCB (); - curveEditorG->setBatchMode (batchMode); + curveEditorG->setBatchMode (batchMode); } void LCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){ - lshape->updateBackgroundHistogram (histLCurve); + lshape->updateBackgroundHistogram (histLCurve); } void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) { brightness->setAddMode(bradd); contrast->setAddMode(contradd); - saturation->setAddMode(satadd); + chromaticity->setAddMode(satadd); } void LCurve::trimValues (rtengine::procparams::ProcParams* pp) { brightness->trimValue(pp->labCurve.brightness); contrast->trimValue(pp->labCurve.contrast); - saturation->trimValue(pp->labCurve.saturation); + chromaticity->trimValue(pp->labCurve.chromaticity); } diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index 2cbb786fc..d82d7a1f0 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -29,23 +29,24 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider { protected: - CurveEditorGroup* curveEditorG; + CurveEditorGroup* curveEditorG; Adjuster* brightness; Adjuster* contrast; - Adjuster* saturation; - DiagonalCurveEditor* lshape; - DiagonalCurveEditor* ashape; - DiagonalCurveEditor* bshape; - - //%%%%%%%%%%%%%%%% - Gtk::CheckButton* avoidclip; - Gtk::CheckButton* enablelimiter; + Adjuster* chromaticity; + DiagonalCurveEditor* lshape; + DiagonalCurveEditor* ashape; + DiagonalCurveEditor* bshape; + DiagonalCurveEditor* ccshape; + //DiagonalCurveEditor* cbgshape; + FlatCurveEditor* chshape; + + //%%%%%%%%%%%%%%%% + Gtk::CheckButton* avoidcolorshift; Gtk::CheckButton* bwtoning; - Adjuster* saturationlimiter; - bool cbAdd; - sigc::connection bwtconn, acconn, elconn; - bool lastBWTVal, lastACVal, lastELVal; - //%%%%%%%%%%%%%%%% + Adjuster* rstprotection; + sigc::connection bwtconn, acconn; + bool lastBWTVal, lastACVal; + //%%%%%%%%%%%%%%%% public: @@ -61,8 +62,7 @@ class LCurve : public Gtk::VBox, public AdjusterListener, public FoldableToolPan void curveChanged (CurveEditor* ce); void adjusterChanged (Adjuster* a, double newval); - void avoidclip_toggled (); - void enablelimiter_toggled (); + void avoidcolorshift_toggled (); void bwtoning_toggled(); void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc index 22b176e36..a43b01dc1 100644 --- a/rtgui/mycurve.cc +++ b/rtgui/mycurve.cc @@ -24,17 +24,21 @@ MyCurve::MyCurve () : listener(NULL) { cursor_type = CSArrow; - innerWidth = get_allocation().get_width() - RADIUS * 2; - innerHeight = get_allocation().get_height() - RADIUS * 2; - prevInnerHeight = innerHeight; + graphX = get_allocation().get_width() - RADIUS * 2; + graphY = get_allocation().get_height() - RADIUS * 2; + prevGraphW = graphW; + prevGraphH = graphH; buttonPressed = false; snapTo = ST_None; + leftBar = NULL; + bottomBar = NULL; colorProvider = NULL; sized = RS_Pending; snapToElmt = -100; set_extension_events(Gdk::EXTENSION_EVENTS_ALL); add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK); + signal_style_changed().connect( sigc::mem_fun(*this, &MyCurve::styleChanged) ); mcih = new MyCurveIdleHelper; mcih->myCurve = this; @@ -50,6 +54,28 @@ MyCurve::~MyCurve () { delete mcih; } +int MyCurve::calcDimensions () { + int newRequestedW, newRequestedH; + + newRequestedW = newRequestedH = get_allocation().get_width(); + if (leftBar && !bottomBar) + newRequestedH -= CBAR_WIDTH + CBAR_MARGIN - RADIUS; + if (!leftBar && bottomBar) + newRequestedH += CBAR_WIDTH + CBAR_MARGIN - RADIUS; + + graphW = newRequestedW - RADIUS - (leftBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS); + graphH = newRequestedH - RADIUS - (bottomBar ? (CBAR_WIDTH+CBAR_MARGIN) : RADIUS); + graphX = newRequestedW - RADIUS - graphW; + graphY = RADIUS + graphH; + + return newRequestedH; +} + +void MyCurve::setColoredBar (ColoredBar *left, ColoredBar *bottom) { + leftBar = left; + bottomBar = bottom; +} + void MyCurve::notifyListener () { if (listener) @@ -68,3 +94,9 @@ bool MyCurve::snapCoordinate(double testedVal, double realVal) { } return false; } + +void MyCurve::styleChanged (const Glib::RefPtr& style) { + setDirty(true); + queue_draw (); +} + diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h index 26f1108e2..e13ad458a 100644 --- a/rtgui/mycurve.h +++ b/rtgui/mycurve.h @@ -23,10 +23,13 @@ #include #include "curvelistener.h" #include "cursormanager.h" -#include "colorprovider.h" +#include "coloredbar.h" #include "../rtengine/LUT.h" +#include "guiutils.h" #define RADIUS 3 /* radius of the control points */ +#define CBAR_WIDTH 10 /* width of the colored bar (border included) */ +#define CBAR_MARGIN 2 /* spacing between the colored bar and the graph */ #define SQUARE 2 /* half length of the square shape of the tangent handles */ #define MIN_DISTANCE 5 /* min distance between control points */ #define GRAPH_SIZE 200 /* size of the curve editor graphic */ @@ -51,24 +54,24 @@ enum ResizeState { class MyCurveIdleHelper; -class MyCurve : public Gtk::DrawingArea { +class MyCurve : public Gtk::DrawingArea, public BackBuffer { friend class MyCurveIdleHelper; protected: CurveListener* listener; + ColoredBar *leftBar; + ColoredBar *bottomBar; ColorProvider* colorProvider; CursorShape cursor_type; - Glib::RefPtr pixmap; - int innerWidth; // inner width of the editor, allocated by the system - int innerHeight; // inner height of the editor, allocated by the system - int prevInnerHeight;// previous inner height of the editor + int graphX, graphY, graphW, graphH; // dimensions of the graphic area, excluding surrounding space for the points of for the colored bar + int prevGraphW, prevGraphH; // previous inner width and height of the editor Gdk::ModifierType mod_type; int cursorX; // X coordinate in the graph of the cursor int cursorY; // Y coordinate in the graph of the cursor - std::vector point; - std::vector upoint; - std::vector lpoint; + std::vector< Point > point; + std::vector< Point > upoint; + std::vector< Point > lpoint; bool buttonPressed; /* * snapToElmt must be interpreted like this: @@ -90,15 +93,20 @@ class MyCurve : public Gtk::DrawingArea { int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; } bool snapCoordinate(double testedVal, double realVal); + // return value = new requested height + int calcDimensions (); + public: MyCurve (); ~MyCurve (); void setCurveListener (CurveListener* cl) { listener = cl; } + void setColoredBar (ColoredBar *left, ColoredBar *bottom); void setColorProvider (ColorProvider* cp) { colorProvider = cp; } void notifyListener (); void updateBackgroundHistogram (LUTu & hist) {return;} ; void forceResize() { sized = RS_Force; } + void styleChanged (const Glib::RefPtr& style); virtual std::vector getPoints () = 0; virtual void setPoints (const std::vector& p) = 0; virtual bool handleEvents (GdkEvent* event) = 0; @@ -111,8 +119,7 @@ class MyCurveIdleHelper { bool destroyed; int pending; - void clearPixmap () { myCurve->pixmap.clear (); } - + void clearPixmap () { myCurve->setDirty(true); } }; #endif diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc index d7cd24771..b0fe4d66e 100644 --- a/rtgui/mydiagonalcurve.cc +++ b/rtgui/mydiagonalcurve.cc @@ -23,9 +23,10 @@ MyDiagonalCurve::MyDiagonalCurve () : activeParam(-1), bghistvalid(false) { - innerWidth = get_allocation().get_width() - RADIUS * 2; - innerHeight = get_allocation().get_height() - RADIUS * 2; - prevInnerHeight = innerHeight; + graphW = get_allocation().get_width() - RADIUS * 2; + graphH = get_allocation().get_height() - RADIUS * 2; + prevGraphW = graphW; + prevGraphH = graphH; grab_point = -1; lit_point = -1; buttonPressed = false; @@ -58,30 +59,30 @@ std::vector MyDiagonalCurve::get_vector (int veclen) { int active = 0; int firstact = -1; for (int i = 0; i < (int)curve.x.size(); ++i) - if (curve.x[i] > prev) { + if (curve.x.at(i) > prev) { if (firstact < 0) firstact = i; - prev = curve.x[i]; + prev = curve.x.at(i); ++active; } // handle degenerate case: if (active < 2) { double ry; if (active > 0) - ry = curve.y[firstact]; + ry = curve.y.at(firstact); else ry = 0.0; if (ry < 0.0) ry = 0.0; if (ry > 1.0) ry = 1.0; for (int x = 0; x < veclen; ++x) - vector[x] = ry; + vector.at(x) = ry; return vector; } } // calculate remaining points std::vector curveDescr = getPoints (); - rtengine::DiagonalCurve* rtcurve = new rtengine::DiagonalCurve (curveDescr, veclen*1.5); + rtengine::DiagonalCurve* rtcurve = new rtengine::DiagonalCurve (curveDescr, veclen*1.2); std::vector t; t.resize (veclen); for (int i = 0; i < veclen; i++) @@ -93,73 +94,89 @@ std::vector MyDiagonalCurve::get_vector (int veclen) { void MyDiagonalCurve::interpolate () { - prevInnerHeight = innerHeight; - point.resize (innerWidth); - std::vector vector = get_vector (innerWidth); - prevInnerHeight = innerHeight; - for (int i = 0; i < innerWidth; ++i) - point[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5)); + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = graphW-2; + point.resize (nbPoints); + std::vector vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } upoint.clear (); lpoint.clear (); if (curve.type==DCT_Parametric && activeParam>0) { - double tmp = curve.x[activeParam-1]; + double tmp = curve.x.at(activeParam-1); if (activeParam>=4) { - upoint.resize(innerWidth); - lpoint.resize(innerWidth); - curve.x[activeParam-1] = 100; - vector = get_vector (innerWidth); - for (int i = 0; i < innerWidth; ++i) - upoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5)); - curve.x[activeParam-1] = -100; - vector = get_vector (innerWidth); - for (int i = 0; i < innerWidth; ++i) - lpoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5)); - curve.x[activeParam-1] = tmp; + upoint.resize(nbPoints); + lpoint.resize(nbPoints); + curve.x.at(activeParam-1) = 100; + vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + upoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + curve.x.at(activeParam-1) = -100; + vector = get_vector (nbPoints); + for (int i = 0; i < nbPoints; ++i) { + float currX = float(i)/float(nbPoints-1); + lpoint.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } + curve.x.at(activeParam-1) = tmp; } } } void MyDiagonalCurve::draw (int handle) { - if (!pixmap) + if (!isDirty()) { + return; + } + + Glib::RefPtr win = get_window(); + if (!surfaceCreated() || !win) return; // re-calculate curve if dimensions changed - if (prevInnerHeight != innerHeight || (int)point.size() != innerWidth) + if (prevGraphW != graphW || prevGraphH != graphH || int(point.size()) != graphW/4) interpolate (); Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; Glib::RefPtr style = get_style (); - Cairo::RefPtr cr = pixmap->create_cairo_context(); + Cairo::RefPtr cr = getContext(); + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); - // bounding rectangle + // clear background Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - cr->rectangle (0, 0, innerWidth + RADIUS*2, innerHeight + RADIUS*2); + cr->rectangle (0., 0., double(getWidth()), double(getHeight())); cr->fill (); // histogram in the background if (bghistvalid) { // find highest bin - unsigned int histheight = 0; + unsigned int valMax = 0; for (int i=0; i<256; i++) - if (bghist[i]>histheight) - histheight = bghist[i]; + if (bghist[i]>valMax) + valMax = bghist[i]; // draw histogram cr->set_line_width (1.0); - double stepSize = (innerWidth-1) / 256.0; - cr->move_to (RADIUS, innerHeight-1+RADIUS); + double stepSize = (graphW-3) / 255.0; + cr->move_to ( double(graphX+1), double(graphY-1) ); c = style->get_fg (Gtk::STATE_INSENSITIVE); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); for (int i=0; i<256; i++) { - double val = bghist[i] * (double)(innerHeight-2) / (double)histheight; - if (val>innerHeight-1) - val = innerHeight-1; - if (i>0) - cr->line_to (i*stepSize+RADIUS, innerHeight-1+RADIUS-val); + double val = double(bghist[i]) * double(graphH-2) / double(valMax); + /* + if (val>graphH-2) + val = graphH-2; + */ + //if (i>0) + cr->line_to (double(graphX)+1.5+double(i)*stepSize, double(graphY-1)-val); } - cr->line_to (innerWidth-1+RADIUS, innerHeight-1+RADIUS); + cr->line_to (double(graphX)+1.5+255.*stepSize, double(graphY-1)); + cr->close_path(); cr->fill (); } @@ -168,17 +185,17 @@ void MyDiagonalCurve::draw (int handle) { c = style->get_dark (state); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); cr->set_antialias (Cairo::ANTIALIAS_NONE); - for (int i = 0; i < 5; i++) { // + 0.5 to align well with f(x)=x so it will cut through the center - cr->move_to (RADIUS, max(0.0, i * (innerHeight + 0.5) / 4) + RADIUS); - cr->line_to (innerWidth + RADIUS, max(0.0,i * (innerHeight + 0.5) / 4) + RADIUS); - cr->move_to (max(0,i * innerWidth / 4) + RADIUS, RADIUS); - cr->line_to (max(0,i * innerWidth / 4) + RADIUS, innerHeight + RADIUS); + for (int i = 0; i < 5; i++) { + // horizontal lines + cr->move_to (double(graphX)+0.5 , double(graphY) - max(0.5, double(graphH*i/4) - 0.5)); + cr->rel_line_to (double(graphW-1) , 0.); + // vertical lines + cr->move_to (double(graphX) + max(0.5, double(graphW*i/4) - 0.5), double(graphY)); + cr->rel_line_to (0. , double(-graphH+1)); } cr->stroke (); // draw f(x)=x line - //c = style->get_light (state); - c = style->get_fg (state); if (snapToElmt == -2) cr->set_source_rgb (1.0, 0.0, 0.0); else @@ -186,8 +203,8 @@ void MyDiagonalCurve::draw (int handle) { std::valarray ds (1); ds[0] = 4; cr->set_dash (ds, 0); - cr->move_to (RADIUS, innerHeight + RADIUS); - cr->line_to (innerWidth + RADIUS, RADIUS); + cr->move_to (double(graphX)+1.5, double(graphY)-1.5); + cr->rel_line_to (double(graphW-3), double(-graphH+3)); cr->stroke (); cr->unset_dash (); @@ -197,32 +214,35 @@ void MyDiagonalCurve::draw (int handle) { // draw upper and lower bounds if (curve.type==DCT_Parametric && activeParam>0 && lpoint.size()>1 && upoint.size()>1) { cr->set_source_rgba (0.0, 0.0, 0.0, 0.15); - cr->move_to (upoint[0].get_x(), upoint[0].get_y()); + cr->move_to (upoint[0].x, upoint[0].y); for (int i=1; i<(int)upoint.size(); i++) - cr->line_to (upoint[i].get_x(), upoint[i].get_y()); - cr->line_to (lpoint[lpoint.size()-1].get_x(), lpoint[lpoint.size()-1].get_y()); + cr->line_to (upoint[i].x, upoint[i].y); + cr->line_to (lpoint[lpoint.size()-1].x, lpoint[lpoint.size()-1].y); for (int i=(int)lpoint.size()-2; i>=0; i--) - cr->line_to (lpoint[i].get_x(), lpoint[i].get_y()); - cr->line_to (upoint[0].get_x(), upoint[0].get_y()); + cr->line_to (lpoint[i].x, lpoint[i].y); + cr->line_to (upoint[0].x, upoint[0].y); cr->fill (); } + c = style->get_fg (state); + // draw the cage of the NURBS curve if (curve.type==DCT_NURBS) { - unsigned int nbPoints; + unsigned int nbPoints; std::valarray ch_ds (1); ch_ds[0] = 2; cr->set_dash (ch_ds, 0); + cr->set_line_width (0.75); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); std::vector points = getPoints(); nbPoints = ((int)points.size()-1)/2; for (unsigned int i = 1; i < nbPoints; i++) { int pos = i*2+1; - double x1 = ((innerWidth-1) * points[pos-2] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth); - double y1 = innerHeight - ((innerHeight-1) * points[pos-1] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight); - double x2 = ((innerWidth-1) * points[pos] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth); - double y2 = innerHeight - ((innerHeight-1) * points[pos+1] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight); + double x1 = double(graphX)+1.5 + double(graphW-3)*points[pos-2]; // project (curve.x[i], 0, 1, graphW); + double y1 = double(graphY)-1.5 - double(graphH-3)*points[pos-1]; // project (curve.y[i], 0, 1, graphH); + double x2 = double(graphX)+0.5 + double(graphW-3)*points[pos]; // project (curve.x[i], 0, 1, graphW); + double y2 = double(graphY)-1.5 - double(graphH-3)*points[pos+1]; // project (curve.y[i], 0, 1, graphH); // set the color of the line when the point is snapped to the cage if (curve.x.size() == nbPoints && snapToElmt >= 1000 && ((i == (snapToElmt-1000)) || (i == (snapToElmt-999)))) @@ -234,17 +254,48 @@ void MyDiagonalCurve::draw (int handle) { cr->stroke (); } cr->unset_dash (); + cr->set_line_width (1.0); } // draw curve cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - cr->move_to (point[0].get_x(), point[0].get_y()); - for (int i=1; i<(int)point.size(); i++) - cr->line_to (point[i].get_x(), point[i].get_y()); + cr->move_to (double(point.at(0).x), double(point.at(0).y)); + for (int i=1; i<(int)point.size(); i++) { + cr->line_to (double(point.at(i).x), double(point.at(i).y)); + } cr->stroke (); + // draw the left colored bar + if (leftBar) { + // first the background + BackBuffer *bb = this; + leftBar->setDrawRectangle(win, 1, graphY-graphH+1, CBAR_WIDTH-2, graphH-2); + leftBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(0.5, graphY-graphH+0.5, CBAR_WIDTH-1, graphH-1); + cr->stroke(); + } + + // draw the bottom colored bar + if (bottomBar) { + // first the background + BackBuffer *bb = this; + bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, CBAR_WIDTH-2); + bottomBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, CBAR_WIDTH-1 ); + cr->stroke(); + } + // draw bullets - if (curve.type!=DCT_Parametric) + if (curve.type!=DCT_Parametric) { + c = style->get_fg (state); for (int i = 0; i < (int)curve.x.size(); ++i) { if (curve.x[i] == -1) continue; if (snapToElmt >= 1000) { @@ -261,14 +312,15 @@ void MyDiagonalCurve::draw (int handle) { cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); } - double x = ((innerWidth-1) * curve.x[i] + 0.5)+RADIUS; // project (curve.x[i], 0, 1, innerWidth); - double y = innerHeight - ((innerHeight-1) * curve.y[i] + 0.5)+RADIUS; // project (curve.y[i], 0, 1, innerHeight); + double x = double(graphX+1) + double((graphW-2) * curve.x[i]); // project (curve.x[i], 0, 1, graphW); + double y = double(graphY-1) - double((graphH-2) * curve.y[i]); // project (curve.y[i], 0, 1, graphH); cr->arc (x, y, RADIUS+0.5, 0, 2*M_PI); cr->fill (); } - - get_window()->draw_drawable (style->get_fg_gc (state), pixmap, 0, 0, 0, 0, innerWidth + RADIUS * 2, innerHeight + RADIUS * 2); + } + setDirty(false); + queue_draw(); } /*void MyDiagonalCurve::graphSizeRequest (Gtk::Requisition* req) { @@ -287,42 +339,42 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { bool retval = false; int num = (int)curve.x.size(); - /* innerWidth and innerHeight are the size of the graph */ - innerWidth = get_allocation().get_width() - RADIUS * 2; - innerHeight = get_allocation().get_height() - RADIUS * 2; + /* graphW and graphH are the size of the graph */ + calcDimensions(); - double minDistanceX = (double)(MIN_DISTANCE) / (double)(innerWidth-1); - double minDistanceY = (double)(MIN_DISTANCE) / (double)(innerHeight-1); + double minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + double minDistanceY = double(MIN_DISTANCE) / double(graphH-1); - if ((innerWidth < 0) || (innerHeight < 0)) + if ((graphW < 0) || (graphH < 0)) return false; switch (event->type) { case Gdk::CONFIGURE: { // Happen when the the window is resized if (sized & (RS_Pending | RS_Force)) { - int size = get_allocation().get_width(); - set_size_request(-1, size); + set_size_request(-1, calcDimensions()); sized = RS_Done; } - if (pixmap) - pixmap.clear (); retval = true; break; } case Gdk::EXPOSE: + { + Glib::RefPtr win = get_window(); if (sized & (RS_Pending | RS_Force)) { - int size = get_allocation().get_width(); - set_size_request(-1, size); + set_size_request(-1, calcDimensions()); } sized = RS_Pending; - if (!pixmap) { - pixmap = Gdk::Pixmap::create (get_window(), get_allocation().get_width(), get_allocation().get_height()); + // setDrawRectangle will allocate the backbuffer Surface + if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height())) interpolate (); - } draw (lit_point); + GdkRectangle *rectangle = &(event->expose.area); + copySurface(win, rectangle); + retval = true; break; + } case Gdk::BUTTON_PRESS: snapToElmt = -100; @@ -354,6 +406,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { curve.y[closest_point] = clampedY; interpolate (); + setDirty(true); draw (closest_point); notifyListener (); } @@ -395,6 +448,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { curve.x.push_back (0); curve.y.push_back (0); interpolate (); + setDirty(true); draw (lit_point); } } @@ -406,8 +460,10 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { new_type = CSPlus; lit_point = -1; } - if (lit_point != previous_lit_point) + if (lit_point != previous_lit_point) { + setDirty(true); draw (lit_point); + } grab_point = -1; retval = true; notifyListener (); @@ -422,6 +478,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { if (grab_point == -1) { new_type = CSArrow; lit_point = -1; + setDirty(true); draw (lit_point); } retval = true; @@ -442,7 +499,12 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { // there's no point currently being moved int previous_lit_point = lit_point; findClosestPoint(); - if (distanceX <= minDistanceX) { + if (cursorX<0 || cursorX>graphW || cursorY<0 || cursorY>graphH) { + // the cursor has left the graph area + new_type = CSArrow; + lit_point = -1; + } + else if (distanceX <= minDistanceX) { new_type = CSMove; lit_point = closest_point; } @@ -450,8 +512,10 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { new_type = CSPlus; lit_point = -1; } - if (lit_point != previous_lit_point) + if (lit_point != previous_lit_point) { + setDirty(true); draw (lit_point); + } } else { // a point is being moved @@ -533,6 +597,7 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { if (curve.x[grab_point] != prevPosX || curve.y[grab_point] != prevPosY) { // we recalculate the curve only if we have to interpolate (); + setDirty(true); draw (lit_point); notifyListener (); } @@ -555,8 +620,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) { void MyDiagonalCurve::getCursorPosition(GdkEvent* event) { int tx, ty; int prevCursorX, prevCursorY; - double incrementX = 1. / (double)(innerWidth-1); - double incrementY = 1. / (double)(innerHeight-1); + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); // getting the cursor position switch (event->type) { @@ -565,15 +630,15 @@ void MyDiagonalCurve::getCursorPosition(GdkEvent* event) { get_window()->get_pointer (tx, ty, mod_type); } else { - tx = (int)event->button.x; - ty = (int)event->button.y; + tx = int(event->button.x); + ty = int(event->button.y); mod_type = (Gdk::ModifierType)event->button.state; } break; case (Gdk::BUTTON_PRESS) : case (Gdk::BUTTON_RELEASE) : - tx = (int)event->button.x; - ty = (int)event->button.y; + tx = int(event->button.x); + ty = int(event->button.y); mod_type = (Gdk::ModifierType)event->button.state; break; default : @@ -585,32 +650,32 @@ void MyDiagonalCurve::getCursorPosition(GdkEvent* event) { if (grab_point != -1) { prevCursorX = cursorX; prevCursorY = cursorY; - } - cursorX = tx - RADIUS; - cursorY = (innerHeight-1) - (ty - RADIUS); + } + cursorX = tx - graphX; + cursorY = graphY - ty; - snapTo = ST_None; + snapTo = ST_None; - // update deltaX/Y if the user drags a point - if (grab_point != -1) { - // set the dragging factor - int control_key = mod_type & GDK_CONTROL_MASK; - int shift_key = mod_type & GDK_SHIFT_MASK; + // update deltaX/Y if the user drags a point + if (grab_point != -1) { + // set the dragging factor + int control_key = mod_type & GDK_CONTROL_MASK; + int shift_key = mod_type & GDK_SHIFT_MASK; - // the increment get smaller if modifier key are used, and "snap to" may be enabled - if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } - if (shift_key) { snapTo = true; } + // the increment get smaller if modifier key are used, and "snap to" may be enabled + if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } + if (shift_key) { snapTo = true; } - deltaX = (double)(cursorX - prevCursorX) * incrementX; - deltaY = (double)(cursorY - prevCursorY) * incrementY; - } - // otherwise set the position of the new point (modifier keys has no effect here) - else { + deltaX = double(cursorX - prevCursorX) * incrementX; + deltaY = double(cursorY - prevCursorY) * incrementY; + } + // otherwise set the position of the new point (modifier keys has no effect here) + else { double tempCursorX = cursorX * incrementX; double tempCursorY = cursorY * incrementY; clampedX = CLAMP (tempCursorX, 0., 1.); // X position of the pointer from the origin of the graph clampedY = CLAMP (tempCursorY, 0., 1.); // Y position of the pointer from the origin of the graph - } + } } @@ -630,9 +695,9 @@ void MyDiagonalCurve::findClosestPoint() { closest_point = i; } else if (currDistX == distanceX && currDistY < distanceY) { - // there is more than 1 point for that X coordinate, we select the closest point to the cursor - distanceY = currDistY; - closest_point = i; + // there is more than 1 point for that X coordinate, we select the closest point to the cursor + distanceY = currDistY; + closest_point = i; } } } @@ -647,13 +712,13 @@ std::vector MyDiagonalCurve::getPoints () { } } else { - // the first value gives the type of the curve + // the first value gives the type of the curve if (curve.type==DCT_Linear) - result.push_back ((double)(DCT_Linear)); + result.push_back (double(DCT_Linear)); else if (curve.type==DCT_Spline) - result.push_back ((double)(DCT_Spline)); + result.push_back (double(DCT_Spline)); else if (curve.type==DCT_NURBS) - result.push_back ((double)(DCT_NURBS)); + result.push_back (double(DCT_NURBS)); // then we push all the points coordinate for (int i=0; i<(int)curve.x.size(); i++) { if (curve.x[i]>=0) { @@ -672,32 +737,32 @@ void MyDiagonalCurve::setPoints (const std::vector& p) { if (t==DCT_Parametric) { curve.x.clear (); curve.y.clear (); - for (int i=1; i<(int)p.size(); i++) + for (size_t i=1; i MyFlatCurve::get_vector (int veclen) { - // Create the output variable + // Create the output variable std::vector convertedValues; // Get the curve control points std::vector curveDescr = getPoints (); - rtengine::FlatCurve* rtcurve = new rtengine::FlatCurve (curveDescr, periodic, veclen*1.5 > 5000 ? 5000 : veclen*1.5); + rtengine::FlatCurve* rtcurve = new rtengine::FlatCurve (curveDescr, periodic, veclen*1.2 > 5000 ? 5000 : veclen*1.2); // Create the sample values that will be converted std::vector samples; samples.resize (veclen); for (int i = 0; i < veclen; i++) - samples[i] = (double) i / (veclen - 1.0); + samples.at(i) = (double) i / (veclen - 1.0); // Converting the values rtcurve->getVal (samples, convertedValues); @@ -72,114 +73,57 @@ std::vector MyFlatCurve::get_vector (int veclen) { void MyFlatCurve::interpolate () { - prevInnerHeight = innerHeight; - point.resize (innerWidth+1); - std::vector vector = get_vector (innerWidth+1); - for (int i = 0; i <= innerWidth; ++i) - point[i] = Gdk::Point ((double)RADIUS+0.5 + i, (double)RADIUS+0.5 + (double)innerHeight*(1.-vector[i])); + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = graphW-2; + point.resize (nbPoints); + std::vector vector = get_vector (nbPoints); + for (int i = 0; i < int(point.size()); ++i) { + float currX = float(i)/float(nbPoints-1); + point.at(i).setCoords(float(graphX)+1.5f+float(graphW-3)*currX, float(graphY)-1.5f-float(graphH-3)*float(vector.at(i))); + } upoint.clear (); lpoint.clear (); - - /*if (curve.type==FCT_Parametric && activeParam>0) { - double tmp = curve.x[activeParam-1]; - if (activeParam>=4) { - upoint.resize(innerWidth); - lpoint.resize(innerWidth); - curve.x[activeParam-1] = 100; - vector = get_vector (innerWidth); - for (int i = 0; i < innerWidth; ++i) - upoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5)); - curve.x[activeParam-1] = -100; - vector = get_vector (innerWidth); - for (int i = 0; i < innerWidth; ++i) - lpoint[i] = Gdk::Point (RADIUS + i, RADIUS + innerHeight - (int)((innerHeight-1) * vector[i] + 0.5)); - curve.x[activeParam-1] = tmp; - } - }*/ } void MyFlatCurve::draw () { - if (!pixmap) + if (!isDirty()) { + return; + } + + Glib::RefPtr win = get_window(); + if (!surfaceCreated() || !win) return; // re-calculate curve if dimensions changed - if (prevInnerHeight != innerHeight || (int)point.size() != (innerWidth+1)) { + if (prevGraphW != graphW || prevGraphH != graphH || (int)point.size() != graphW/4) interpolate (); - } + double innerW = double(graphW-2); + double innerH = double(graphH-2); Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; Glib::RefPtr style = get_style (); - Cairo::RefPtr cr = pixmap->create_cairo_context(); - - // bounding rectangle - Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL); - cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - cr->rectangle (0, 0, innerWidth+RADIUS*2+1.5, innerHeight+RADIUS*2+1.5); - cr->fill (); - - // histogram in the background - /*if (bghistvalid) { - // find highest bin - unsigned int histheight = 0; - for (int i=0; i<256; i++) - if (bghist[i]>histheight) - histheight = bghist[i]; - // draw histogram - cr->set_line_width (1.0); - double stepSize = (innerWidth-1) / 256.0; - cr->move_to (RADIUS, innerHeight-1+RADIUS); - c = style->get_fg (Gtk::STATE_INSENSITIVE); - cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - for (int i=0; i<256; i++) { - double val = bghist[i] * (double)(innerHeight-2) / (double)histheight; - if (val>innerHeight-1) - val = innerHeight-1; - if (i>0) - cr->line_to (i*stepSize+RADIUS, innerHeight-1+RADIUS-val); - } - cr->line_to (innerWidth-1+RADIUS, innerHeight-1+RADIUS); - cr->fill (); - }*/ - + Cairo::RefPtr cr = getContext(); cr->set_line_cap(Cairo::LINE_CAP_SQUARE); - // draw the grid lines: - cr->set_line_width (1.0); - cr->set_antialias (Cairo::ANTIALIAS_NONE); - c = style->get_dark (state); + // clear background + Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0, 0, double(getWidth()), double(getHeight())); + cr->fill (); - double x0 = (double)RADIUS-0.5; - double x1 = (double)RADIUS-0.5 + (double)innerWidth + 2.; - double y0 = (double)RADIUS-0.5; - double y1 = (double)RADIUS-0.5 + (double)innerHeight + 2.; - for (int i = 0; i < 5; i++) { - cr->move_to (x0, y0); - cr->line_to (x0, y1); - cr->line_to (x1, y1); - cr->line_to (x1, y0); - cr->line_to (x0, y0); - } - /*for (int i = 0; i < 5; i++) { - double currX = (double)RADIUS-0.5 + (double)i*((double)innerWidth + 2.)/4.; - double currY = (double)RADIUS-0.5 + (double)i*((double)innerHeight + 2.)/4.; - cr->move_to (x0, currY); - cr->line_to (x1, currY); - cr->move_to (currX, y0); - cr->line_to (currX, y1); - }*/ - cr->stroke (); + cr->set_line_width (1.0); // draw f(x)=0.5 line - c = style->get_fg (state); + c = style->get_dark (state); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); std::valarray ds (1); ds[0] = 4; cr->set_dash (ds, 0); - cr->move_to (x0, (double)RADIUS+0.5 + (double)innerHeight/2.); - cr->line_to (x1, (double)RADIUS+0.5 + (double)innerHeight/2.); + cr->move_to (double(graphX)+1.5, double(graphY-graphH/2)-0.5); + cr->rel_line_to (double(graphW-3), 0.); cr->stroke (); cr->unset_dash (); @@ -188,6 +132,36 @@ void MyFlatCurve::draw () { cr->set_line_width (1.0); + // draw the left colored bar + if (leftBar) { + // first the background + BackBuffer *bb = this; + leftBar->setDrawRectangle(win, 1, graphY-graphH+1, CBAR_WIDTH-2, graphH-2); + leftBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(0.5, graphY-graphH+0.5, CBAR_WIDTH-1, graphH-1); + cr->stroke(); + } + + // draw the bottom colored bar + if (bottomBar) { + // first the background + BackBuffer *bb = this; + bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, CBAR_WIDTH-2); + bottomBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, CBAR_WIDTH-1 ); + cr->stroke(); + } + + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + // draw the color feedback of the control points if (colorProvider) { @@ -200,20 +174,18 @@ void MyFlatCurve::draw () { colorProvider->colorForValue(curve.x[i], 0.5); cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue); - double x = (double)RADIUS+0.5 + innerWidth*curve.x[i]; - - if (i == lit_point && editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX)) { + if ( i==lit_point && (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX)) ) { cr->set_line_width (4.0); } - cr->move_to (x, (double)RADIUS+0.5); - cr->line_to (x, (double)RADIUS+0.5 + innerHeight); + cr->move_to (double(graphX)+1 + innerW*curve.x[i], double(graphY-1)); + cr->rel_line_to (0., -innerH); cr->stroke (); cr->set_line_width (1.0); // draw the lit_point's horizontal line if (i == lit_point) { - if (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point) || editedHandle==FCT_EditedHandle_CPointUD) { + if ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD) { if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { cr->set_line_width (4.0); @@ -222,49 +194,52 @@ void MyFlatCurve::draw () { colorProvider->colorForValue(curve.x[i], curve.y[i]); cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue); - double y = (double)RADIUS+0.5 + (double)innerHeight*(1.-curve.y[lit_point]); - cr->move_to ( RADIUS, y); - cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, y); + cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y[lit_point]); + cr->rel_line_to (innerW, 0.); cr->stroke (); } } } } // endif - cr->set_line_width (1.0); + cr->set_line_width (1.0); } else { cr->set_source_rgb (0.5, 0.0, 0.0); - if (area==(FCT_Area_H|FCT_Area_V|FCT_Area_Point) || editedHandle==FCT_EditedHandle_CPointUD) { - double position; - + if ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD ) { // draw the lit_point's vertical line - if (editedHandle==(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { + if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { cr->set_line_width (2.0); } - position = (double)RADIUS+0.5 + (double)innerWidth*curve.x[lit_point]; - cr->move_to (position, (double)RADIUS+0.5); - cr->line_to (position, (double)RADIUS+0.5 + (double)innerHeight); + cr->move_to (double(graphX)+1 + innerW*curve.x[lit_point], double(graphY-1)); + cr->rel_line_to (0., -innerH); cr->stroke (); cr->set_line_width (1.0); // draw the lit_point's horizontal line - if (editedHandle==(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { + if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { cr->set_line_width (2.0); } - position = (double)RADIUS+0.5 + (double)innerHeight*(1.-curve.y[lit_point]); - cr->move_to ((double)RADIUS+0.5 , position); - cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, position); + cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y[lit_point]); + cr->rel_line_to (innerW, 0.); cr->stroke (); cr->set_line_width (1.0); } } - double lineMinLength = 1. / innerWidth * SQUARE * 0.9; + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + + // draw the graph's borders: + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(double(graphX)+0.5, double(graphY)-0.5, double(graphW-1), double(-graphH+1)); + cr->stroke (); + + double lineMinLength = 1. / graphW * SQUARE * 0.9; if (lit_point!=-1 && getHandles(lit_point) && curve.x[lit_point]!=-1.) { - double x = (double)RADIUS+0.5 + (double)innerWidth * curve.x[lit_point]; - double y = (double)RADIUS+0.5 + (double)innerHeight * (1.-curve.y[lit_point]); + double x = double(graphX+1) + innerW*curve.x[lit_point]; + double y = double(graphY) - innerH*curve.y[lit_point]; double x2; double square; bool crossingTheFrame; @@ -281,26 +256,22 @@ void MyFlatCurve::draw () { leftTanX += 1.0; crossingTheFrame = true; } - x2 = (double)RADIUS+0.5 + (double)innerWidth * leftTanX; + x2 = double(graphX+1) + innerW*leftTanX; if (curve.x[lit_point] - leftTanX > lineMinLength || crossingTheFrame) { // The left tangential vector reappear on the right side // draw the line cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to ((double)RADIUS+0.5, y); + cr->line_to (double(graphX+1), y); cr->stroke (); - cr->move_to ((double)RADIUS+0.5 + (double)innerWidth, y); + cr->move_to (double(graphX) + innerW, y); } cr->line_to (x2, y); cr->stroke (); } // draw tangential knot square = area == FCT_Area_LeftTan ? SQUARE*2. : SQUARE; - cr->move_to(x2-square, y+square); - cr->line_to(x2+square, y+square); - cr->line_to(x2+square, y-square); - cr->line_to(x2-square, y-square); - cr->line_to(x2-square, y+square); + cr->rectangle(x2-square, y-square, 2.*square, 2.*square); cr->fill(); // right handle is blue @@ -315,34 +286,31 @@ void MyFlatCurve::draw () { rightTanX -= 1.0; crossingTheFrame = true; } - x2 = (double)RADIUS+0.5 + (double)innerWidth * rightTanX; + x2 = double(graphX+1) +innerW*rightTanX; if (rightTanX - curve.x[lit_point] > lineMinLength || crossingTheFrame) { // The left tangential vector reappear on the right side // draw the line cr->move_to (x, y); if (crossingTheFrame) { - cr->line_to ((double)RADIUS+0.5 + (double)innerWidth, y); + cr->line_to (double(graphX) + innerW, y); cr->stroke (); - cr->move_to ((double)RADIUS+0.5, y); + cr->move_to (double(graphX+1), y); } cr->line_to (x2, y); cr->stroke (); } // draw tangential knot square = area == FCT_Area_RightTan ? SQUARE*2. : SQUARE; - cr->move_to(x2-square, y+square); - cr->line_to(x2+square, y+square); - cr->line_to(x2+square, y-square); - cr->line_to(x2-square, y-square); - cr->line_to(x2-square, y+square); + cr->rectangle(x2-square, y-square, 2.*square, 2.*square); cr->fill(); } // draw curve + c = style->get_fg (state); cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - cr->move_to (point[0].get_x(), point[0].get_y()); + cr->move_to (point.at(0).x, point.at(0).y); for (int i=1; i<(int)point.size(); i++) - cr->line_to (point[i].get_x(), point[i].get_y()); + cr->line_to (double(point.at(i).x), double(point.at(i).y)); cr->stroke (); // draw bullets @@ -350,12 +318,12 @@ void MyFlatCurve::draw () { for (int i = 0; i < (int)curve.x.size(); ++i) { if (curve.x[i] != -1.) { if (i == lit_point) { - if (colorProvider) { + if (colorProvider) { colorProvider->colorForValue(curve.x[i], curve.y[i]); cr->set_source_rgb (colorProvider->red, colorProvider->green, colorProvider->blue); - } - else - cr->set_source_rgb (1.0, 0.0, 0.0); + } + else + cr->set_source_rgb (1.0, 0.0, 0.0); } else if (i == snapToElmt) { cr->set_source_rgb (1.0, 0.0, 0.0); @@ -364,8 +332,9 @@ void MyFlatCurve::draw () { cr->set_source_rgb (0.0, 0.5, 0.0); else cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); - double x = (double)RADIUS+0.5 + (double)innerWidth * curve.x[i]; // project (curve.x[i], 0, 1, innerWidth); - double y = (double)RADIUS+0.5 + (double)innerHeight * (1.-curve.y[i]); // project (curve.y[i], 0, 1, innerHeight); + + double x = double(graphX+1) + innerW * curve.x[i]; // project (curve.x[i], 0, 1, graphW); + double y = double(graphY-1) - innerH * curve.y[i]; // project (curve.y[i], 0, 1, graphH); cr->arc (x, y, (double)RADIUS, 0, 2*M_PI); cr->fill (); @@ -375,47 +344,32 @@ void MyFlatCurve::draw () { // draw the left and right tangent handles if (tanHandlesDisplayed) { - double top, bottom, left, right; - double halfSquareSizeX, halfSquareSizeY; + double halfSquareSizeX = minDistanceX/2.; + double halfSquareSizeY = minDistanceY/2.; - // LEFT handle - halfSquareSizeX = minDistanceX/2.; - halfSquareSizeY = minDistanceY/2.; - //halfSquareSizeX = area == FCT_Area_LeftTan ? minDistanceX : minDistanceX/2.; - //halfSquareSizeY = area == FCT_Area_LeftTan ? minDistanceY : minDistanceY/2.; - top = leftTanHandle.centerY + halfSquareSizeY; - bottom = leftTanHandle.centerY - halfSquareSizeY; - left = leftTanHandle.centerX - halfSquareSizeX; - right = leftTanHandle.centerX + halfSquareSizeX; + // LEFT handle - // yellow + // yellow cr->set_source_rgb (1.0, 1.0, 0.0); - cr->move_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); + cr->rectangle(double(graphX+1) + innerW*(leftTanHandle.centerX-halfSquareSizeX), + double(graphY-1) - innerH*(leftTanHandle.centerY+halfSquareSizeY), + innerW*minDistanceX, + innerW*minDistanceY); cr->fill(); // RIGHT handle - //halfSquareSizeX = area == FCT_Area_RightTan ? minDistanceX : minDistanceX/2.; - //halfSquareSizeY = area == FCT_Area_RightTan ? minDistanceY : minDistanceY/2.; - top = rightTanHandle.centerY + halfSquareSizeY; - bottom = rightTanHandle.centerY - halfSquareSizeY; - left = rightTanHandle.centerX - halfSquareSizeX; - right = rightTanHandle.centerX + halfSquareSizeX; // blue cr->set_source_rgb (0.0, 0.0, 1.0); - cr->move_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * right, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-bottom)); - cr->line_to((double)RADIUS+0.5 + (double)innerWidth * left, (double)RADIUS+0.5 + (double)innerHeight * (1.-top)); + cr->rectangle(double(graphX+1) + innerW*(rightTanHandle.centerX-halfSquareSizeX), + double(graphY-1) - innerH*(rightTanHandle.centerY+halfSquareSizeY), + innerW*minDistanceX, + innerW*minDistanceY); cr->fill(); } - get_window()->draw_drawable (style->get_fg_gc (state), pixmap, 0, 0, 0, 0, innerWidth + RADIUS * 2 + 1, innerHeight + RADIUS * 2 + 1); + setDirty(false); + queue_draw(); } /* @@ -424,46 +378,28 @@ void MyFlatCurve::draw () { bool MyFlatCurve::getHandles(int n) { int N = curve.x.size(); double prevX, nextX; - double prevY, nextY; - double prevTan, nextTan; - double x, y, leftTan, rightTan; + double x, leftTan, rightTan; if (n == -1) return false; x = curve.x[n]; - y = curve.y[n]; leftTan = curve.leftTangent[n]; rightTan = curve.rightTangent[n]; if (!n) { // first point, the left handle is then computed with the last point's right handle prevX = curve.x[N-1]-1.0; - prevY = curve.y[N-1]; - prevTan = curve.rightTangent[N-1]; - nextX = curve.x[n+1]; - nextY = curve.y[n+1]; - nextTan = curve.leftTangent[n+1]; } else if (n == N-1) { // last point, the right handle is then computed with the first point's left handle prevX = curve.x[n-1]; - prevY = curve.y[n-1]; - prevTan = curve.rightTangent[n-1]; - nextX = curve.x[0]+1.0; - nextY = curve.y[0]; - nextTan = curve.leftTangent[0]; } else { // last point, the right handle is then computed with the first point's left handle prevX = curve.x[n-1]; - prevY = curve.y[n-1]; - prevTan = curve.rightTangent[n-1]; - nextX = curve.x[n+1]; - nextY = curve.y[n+1]; - nextTan = curve.leftTangent[n+1]; } if (leftTan == 0.0) leftTanX = x; @@ -490,42 +426,42 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { bool retval = false; int num = (int)curve.x.size(); - /* innerWidth and innerHeight are the size of the graph */ - innerWidth = get_allocation().get_width() - 2*RADIUS - 1; - innerHeight = get_allocation().get_height() - 2*RADIUS - 1; + /* graphW and graphH are the size of the graph */ + calcDimensions(); - minDistanceX = (double)(MIN_DISTANCE) / (double)innerWidth; - minDistanceY = (double)(MIN_DISTANCE) / (double)innerHeight; + minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + minDistanceY = double(MIN_DISTANCE) / double(graphH-1); - if ((innerWidth < 0) || (innerHeight < 0)) + if ((graphW < 0) || (graphH < 0)) return false; switch (event->type) { case Gdk::CONFIGURE: { // Happen when the the window is resized if (sized & (RS_Pending | RS_Force)) { - int size = get_allocation().get_width(); - set_size_request(-1, size); + set_size_request(-1, calcDimensions()); sized = RS_Done; } - if (pixmap) - pixmap.clear (); retval = true; break; } case Gdk::EXPOSE: + { + Glib::RefPtr win = get_window(); if (sized & (RS_Pending | RS_Force)) { - int size = get_allocation().get_width(); - set_size_request(-1, size); + set_size_request(-1, calcDimensions()); } sized = RS_Pending; - if (!pixmap) { - pixmap = Gdk::Pixmap::create (get_window(), get_allocation().get_width(), get_allocation().get_height()); + // setDrawRectangle will allocate the backbuffer Surface + if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height())) interpolate (); - } draw (); - retval = true; + GdkRectangle *rectangle = &(event->expose.area); + copySurface(win, rectangle); + + retval = true; break; + } case Gdk::BUTTON_PRESS: //if (curve.type!=FCT_Parametric) { @@ -569,6 +505,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { curve.rightTangent[closest_point] = 0.35; interpolate (); + setDirty(true); draw (); notifyListener (); @@ -698,8 +635,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { break; } - if ((lit_point != previous_lit_point) || (prevArea != area)) + if ((lit_point != previous_lit_point) || (prevArea != area)) { + setDirty(true); draw (); + } retval = true; //notifyListener (); } @@ -741,7 +680,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { case (FCT_EditedHandle_None): { - if ((lit_point != -1 && previous_lit_point != lit_point) && area & (FCT_Area_V|FCT_Area_Point)) { + if ((lit_point != -1 && previous_lit_point != lit_point) && (area&(FCT_Area_V|FCT_Area_Point))) { bool sameSide = false; @@ -821,8 +760,10 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { break; } - if ((lit_point != previous_lit_point) || (prevArea != area)) + if ((lit_point != previous_lit_point) || (prevArea != area)) { + setDirty(true); draw (); + } break; } @@ -856,6 +797,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { if (curve.leftTangent[lit_point] != prevValue) { interpolate (); + setDirty(true); draw (); notifyListener (); } @@ -880,6 +822,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { if (curve.rightTangent[lit_point] != prevValue) { interpolate (); + setDirty(true); draw (); notifyListener (); } @@ -904,6 +847,7 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) { new_type = CSArrow; lit_point = -1; tanHandlesDisplayed = false; + setDirty(true); draw (); } retval = true; @@ -1089,6 +1033,7 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) { if (curve.x[lit_point] != prevPosX || curve.y[lit_point] != prevPosY) { // we recompute the curve only if we have to interpolate (); + setDirty(true); draw (); notifyListener (); } @@ -1098,8 +1043,8 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) { void MyFlatCurve::getCursorPosition(GdkEvent* event) { int tx, ty; int prevCursorX, prevCursorY; - double incrementX = 1. / (double)innerWidth; - double incrementY = 1. / (double)innerHeight; + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); switch (event->type) { case (Gdk::MOTION_NOTIFY) : @@ -1127,33 +1072,33 @@ void MyFlatCurve::getCursorPosition(GdkEvent* event) { if (editedHandle != FCT_EditedHandle_None) { prevCursorX = cursorX; prevCursorY = cursorY; - } - cursorX = tx - RADIUS; - cursorY = innerHeight - (ty - RADIUS); + } + cursorX = tx - graphX; + cursorY = graphY - ty; - preciseCursorX = cursorX * incrementX; - preciseCursorY = cursorY * incrementY; + preciseCursorX = cursorX * incrementX; + preciseCursorY = cursorY * incrementY; - snapTo = false; + snapTo = false; - // update deltaX/Y if the user drags a point - if (editedHandle != FCT_EditedHandle_None) { - // set the dragging factor - int control_key = mod_type & GDK_CONTROL_MASK; - int shift_key = mod_type & GDK_SHIFT_MASK; + // update deltaX/Y if the user drags a point + if (editedHandle != FCT_EditedHandle_None) { + // set the dragging factor + int control_key = mod_type & GDK_CONTROL_MASK; + int shift_key = mod_type & GDK_SHIFT_MASK; - // the increment get smaller if modifier key are used, and "snap to" may be enabled - if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } - if (shift_key) { snapTo = true; } + // the increment get smaller if modifier key are used, and "snap to" may be enabled + if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } + if (shift_key) { snapTo = true; } - deltaX = (double)(cursorX - prevCursorX) * incrementX; - deltaY = (double)(cursorY - prevCursorY) * incrementY; - } - // otherwise set the position of the new point (modifier keys has no effect here) - else { + deltaX = (double)(cursorX - prevCursorX) * incrementX; + deltaY = (double)(cursorY - prevCursorY) * incrementY; + } + // otherwise set the position of the new point (modifier keys has no effect here) + else { clampedX = CLAMP (preciseCursorX, 0., 1.); // X position of the pointer from the origin of the graph clampedY = CLAMP (preciseCursorY, 0., 1.); // Y position of the pointer from the origin of the graph - } + } } @@ -1235,7 +1180,7 @@ std::vector MyFlatCurve::getPoints () { } } else {*/ - // the first value gives the type of the curve + // the first value gives the type of the curve if (curve.type==FCT_Linear) result.push_back ((double)(FCT_Linear)); else if (curve.type==FCT_MinMaxCPoints) @@ -1269,47 +1214,47 @@ void MyFlatCurve::setPoints (const std::vector& p) { curve.rightTangent.push_back (p[ix++]); } } - pixmap.clear (); + setDirty(true); queue_draw (); } void MyFlatCurve::setType (FlatCurveType t) { curve.type = t; - pixmap.clear (); + setDirty(true); } void MyFlatCurve::reset() { - innerWidth = get_allocation().get_width() - RADIUS * 2; - innerHeight = get_allocation().get_height() - RADIUS * 2; + calcDimensions(); - switch (curve.type) { - case FCT_MinMaxCPoints : - defaultCurve(); - lit_point = -1; + switch (curve.type) { + case FCT_MinMaxCPoints : + defaultCurve(); + lit_point = -1; interpolate (); - break; - //case Parametric : - // Nothing to do (?) - default: - break; - } - draw(); + break; + //case Parametric : + // Nothing to do (?) + default: + break; + } + setDirty(true); + draw(); } void MyFlatCurve::defaultCurve () { - curve.x.clear(); - curve.y.clear(); + curve.x.clear(); + curve.y.clear(); curve.leftTangent.clear(); curve.rightTangent.clear(); // Point for RGBCMY colors for (int i=0; i<6; i++) { - curve.x.push_back((1./6.)*i); - curve.y.push_back(0.5); - curve.leftTangent.push_back(0.35); - curve.rightTangent.push_back(0.35); + curve.x.push_back((1./6.)*i); + curve.y.push_back(0.5); + curve.leftTangent.push_back(0.35); + curve.rightTangent.push_back(0.35); } } diff --git a/rtgui/options.cc b/rtgui/options.cc index 7135f7f3c..95c719a1d 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -155,6 +155,8 @@ void Options::updatePaths() { lastToneCurvesDir = preferredPath; if (lastProfilingReferenceDir.empty() || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) lastProfilingReferenceDir = preferredPath; + if (lastVibranceCurvesDir.empty() || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastVibranceCurvesDir = preferredPath; } Glib::ustring Options::getPreferredProfilePath() { @@ -369,7 +371,7 @@ void Options::setDefaults () { 0, // ADDSET_PERSPECTIVE 0, // ADDSET_CA 0, // ADDSET_VIGN_AMOUNT - 0, // ADDSET_LC_SATURATION + 0, // ADDSET_LC_CHROMATICITY 0, // ADDSET_TC_SATURATION 0, // ADDSET_TC_HLCOMPAMOUNT 0, // ADDSET_TC_HLCOMPTHRESH @@ -420,7 +422,10 @@ void Options::setDefaults () { rtSettings.beta = "BetaRGB"; rtSettings.best = "BestRGB"; rtSettings.verbose = false; - rtSettings.gamutICC = true; + rtSettings.gamutICC = true; + rtSettings.gamutLch = true; + rtSettings.protectred = 60; + rtSettings.protectredh = 0.4; lastIccDir = rtSettings.iccDirectory; lastDarkframeDir = rtSettings.darkFramesPath; @@ -435,6 +440,7 @@ void Options::setDefaults () { lastLabCurvesDir = ""; lastHsvCurvesDir = ""; lastToneCurvesDir = ""; + lastVibranceCurvesDir = ""; lastProfilingReferenceDir = ""; } @@ -638,6 +644,9 @@ if (keyFile.has_group ("Color Management")) { if( keyFile.has_key ("Color Management", "Beta")) rtSettings.beta = keyFile.get_string("Color Management", "Beta"); if( keyFile.has_key ("Color Management", "Best")) rtSettings.best = keyFile.get_string("Color Management", "Best"); if( keyFile.has_key ("Color Management", "Bruce")) rtSettings.bruce = keyFile.get_string("Color Management", "Bruce"); + if( keyFile.has_key ("Color Management", "GamutLch")) rtSettings.gamutLch = keyFile.get_boolean("Color Management", "GamutLch"); + if( keyFile.has_key ("Color Management", "ProtectRed")) rtSettings.protectred = keyFile.get_integer("Color Management", "ProtectRed"); + if( keyFile.has_key ("Color Management", "ProtectRedH")) rtSettings.protectredh = keyFile.get_double("Color Management", "ProtectRedH"); } if (keyFile.has_group ("Batch Processing")) { @@ -692,6 +701,7 @@ if (keyFile.has_group ("Dialogs")) { safeDirGet(keyFile, "Dialogs", "LastLabCurvesDir", lastLabCurvesDir); safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); safeDirGet(keyFile, "Dialogs", "LastToneCurvesDir", lastToneCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); } @@ -873,6 +883,9 @@ 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", "GamutLch", rtSettings.gamutLch); + keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); + keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); @@ -921,6 +934,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir); + keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); FILE *f = safe_g_fopen (fname, "wt"); diff --git a/rtgui/options.h b/rtgui/options.h index 2f586c34a..d5a0e8312 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -238,6 +238,7 @@ class Options { Glib::ustring lastLabCurvesDir; Glib::ustring lastHsvCurvesDir; Glib::ustring lastToneCurvesDir; + Glib::ustring lastVibranceCurvesDir; Glib::ustring lastProfilingReferenceDir; Options (); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 14e91c88e..da5a2dc77 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -46,16 +46,18 @@ void ParamsEdited::set (bool v) { labCurve.lcurve = v; labCurve.acurve = v; labCurve.bcurve = v; + labCurve.cccurve = v; + labCurve.chcurve = v; + //labCurve.cbgcurve = v; labCurve.brightness = v; labCurve.contrast = v; - labCurve.saturation = v; - labCurve.avoidclip = v; - labCurve.enable_saturationlimiter = v; - labCurve.saturationlimit = v; - labCurve.bwtoning =v; - rgbCurves.rcurve = v; - rgbCurves.gcurve = v; - rgbCurves.bcurve = v; + labCurve.chromaticity = v; + labCurve.avoidcolorshift = v; + labCurve.rstprotection = v; + labCurve.bwtoning = v; + rgbCurves.rcurve = v; + rgbCurves.gcurve = v; + rgbCurves.bcurve = v; sharpening.enabled = v; sharpening.radius = v; sharpening.amount = v; @@ -85,6 +87,7 @@ void ParamsEdited::set (bool v) { vibrance.protectskins = v; vibrance.avoidcolorshift = v; vibrance.pastsattog = v; + vibrance.skintonescurve = v; //colorBoost.amount = v; //colorBoost.avoidclip = v; //colorBoost.enable_saturationlimiter = v; @@ -239,12 +242,14 @@ void ParamsEdited::initFrom (const std::vector labCurve.lcurve = labCurve.lcurve && p.labCurve.lcurve == other.labCurve.lcurve; labCurve.acurve = labCurve.acurve && p.labCurve.acurve == other.labCurve.acurve; labCurve.bcurve = labCurve.bcurve && p.labCurve.bcurve == other.labCurve.bcurve; + labCurve.cccurve = labCurve.cccurve && p.labCurve.cccurve == other.labCurve.cccurve; + labCurve.chcurve = labCurve.chcurve && p.labCurve.chcurve == other.labCurve.chcurve; + //labCurve.cbgcurve = labCurve.cbgcurve && p.labCurve.cbgcurve == other.labCurve.cbgcurve; labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness; labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast; - labCurve.saturation = labCurve.saturation && p.labCurve.saturation == other.labCurve.saturation; - labCurve.avoidclip = labCurve.avoidclip && p.labCurve.avoidclip == other.labCurve.avoidclip; - labCurve.enable_saturationlimiter = labCurve.enable_saturationlimiter && p.labCurve.enable_saturationlimiter == other.labCurve.enable_saturationlimiter; - labCurve.saturationlimit = labCurve.saturationlimit && p.labCurve.saturationlimit == other.labCurve.saturationlimit; + labCurve.chromaticity = labCurve.chromaticity && p.labCurve.chromaticity == other.labCurve.chromaticity; + labCurve.avoidcolorshift = labCurve.avoidcolorshift && p.labCurve.avoidcolorshift == other.labCurve.avoidcolorshift; + labCurve.rstprotection = labCurve.rstprotection && p.labCurve.rstprotection == other.labCurve.rstprotection; labCurve.bwtoning = labCurve.bwtoning && p.labCurve.bwtoning == other.labCurve.bwtoning; rgbCurves.rcurve = rgbCurves.rcurve && p.rgbCurves.rcurve == other.rgbCurves.rcurve; rgbCurves.gcurve = rgbCurves.gcurve && p.rgbCurves.gcurve == other.rgbCurves.gcurve; @@ -278,6 +283,7 @@ void ParamsEdited::initFrom (const std::vector vibrance.protectskins = vibrance.protectskins && p.vibrance.protectskins == other.vibrance.protectskins; vibrance.avoidcolorshift = vibrance.avoidcolorshift && p.vibrance.avoidcolorshift == other.vibrance.avoidcolorshift; vibrance.pastsattog = vibrance.pastsattog && p.vibrance.pastsattog == other.vibrance.pastsattog; + vibrance.skintonescurve = vibrance.skintonescurve && p.vibrance.skintonescurve == other.vibrance.skintonescurve; //colorBoost.amount = colorBoost.amount && p.colorBoost.amount == other.colorBoost.amount; //colorBoost.avoidclip = colorBoost.avoidclip && p.colorBoost.avoidclip == other.colorBoost.avoidclip; //colorBoost.enable_saturationlimiter = colorBoost.enable_saturationlimiter && p.colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter; @@ -431,17 +437,19 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.lcurve) toEdit.labCurve.lcurve = mods.labCurve.lcurve; if (labCurve.acurve) toEdit.labCurve.acurve = mods.labCurve.acurve; if (labCurve.bcurve) toEdit.labCurve.bcurve = mods.labCurve.bcurve; - if (labCurve.brightness) toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; - if (labCurve.contrast) toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; - if (labCurve.saturation) toEdit.labCurve.saturation = dontforceSet && options.baBehav[ADDSET_LC_SATURATION] ? toEdit.labCurve.saturation + mods.labCurve.saturation : mods.labCurve.saturation; - if (labCurve.avoidclip) toEdit.labCurve.avoidclip = mods.labCurve.avoidclip; - if (labCurve.enable_saturationlimiter) toEdit.labCurve.enable_saturationlimiter = mods.labCurve.enable_saturationlimiter; - if (labCurve.saturationlimit) toEdit.labCurve.saturationlimit = mods.labCurve.saturationlimit; - if (labCurve.bwtoning) toEdit.labCurve.bwtoning = mods.labCurve.bwtoning; + if (labCurve.cccurve) toEdit.labCurve.cccurve = mods.labCurve.cccurve; + if (labCurve.chcurve) toEdit.labCurve.chcurve = mods.labCurve.chcurve; + //if (labCurve.cbgcurve) toEdit.labCurve.cbgcurve = mods.labCurve.cbgcurve; + if (labCurve.brightness) toEdit.labCurve.brightness = dontforceSet && options.baBehav[ADDSET_LC_BRIGHTNESS] ? toEdit.labCurve.brightness + mods.labCurve.brightness : mods.labCurve.brightness; + if (labCurve.contrast) toEdit.labCurve.contrast = dontforceSet && options.baBehav[ADDSET_LC_CONTRAST] ? toEdit.labCurve.contrast + mods.labCurve.contrast : mods.labCurve.contrast; + if (labCurve.chromaticity) toEdit.labCurve.chromaticity = dontforceSet && options.baBehav[ADDSET_LC_CHROMATICITY] ? toEdit.labCurve.chromaticity + mods.labCurve.chromaticity : mods.labCurve.chromaticity; + if (labCurve.avoidcolorshift) toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift; + if (labCurve.rstprotection) toEdit.labCurve.rstprotection = mods.labCurve.rstprotection; + if (labCurve.bwtoning) toEdit.labCurve.bwtoning = mods.labCurve.bwtoning; - if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; - if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; - if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; + if (rgbCurves.rcurve) toEdit.rgbCurves.rcurve = mods.rgbCurves.rcurve; + if (rgbCurves.gcurve) toEdit.rgbCurves.gcurve = mods.rgbCurves.gcurve; + if (rgbCurves.bcurve) toEdit.rgbCurves.bcurve = mods.rgbCurves.bcurve; if (sharpenEdge.enabled) toEdit.sharpenEdge.enabled = mods.sharpenEdge.enabled; if (sharpenEdge.passes) toEdit.sharpenEdge.passes = dontforceSet && options.baBehav[ADDSET_SHARPENEDGE_PASS] ? toEdit.sharpenEdge.passes + mods.sharpenEdge.passes : mods.sharpenEdge.passes; @@ -480,6 +488,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (vibrance.protectskins) toEdit.vibrance.protectskins = mods.vibrance.protectskins; if (vibrance.avoidcolorshift) toEdit.vibrance.avoidcolorshift = mods.vibrance.avoidcolorshift; if (vibrance.pastsattog) toEdit.vibrance.pastsattog = mods.vibrance.pastsattog; + if (vibrance.skintonescurve) toEdit.vibrance.skintonescurve = mods.vibrance.skintonescurve; //if (colorBoost.amount) toEdit.colorBoost.amount = dontforceSet && options.baBehav[ADDSET_CBOOST_AMOUNT] ? toEdit.colorBoost.amount + mods.colorBoost.amount : mods.colorBoost.amount; //if (colorBoost.avoidclip) toEdit.colorBoost.avoidclip = mods.colorBoost.avoidclip; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index a27b2765f..a210507e2 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -53,14 +53,16 @@ class LCurveParamsEdited { public: bool brightness; bool contrast; - bool saturation; - bool avoidclip; - bool enable_saturationlimiter; - bool saturationlimit; + bool chromaticity; + bool avoidcolorshift; + bool rstprotection; bool lcurve; bool acurve; bool bcurve; bool bwtoning; + bool cccurve; + bool chcurve; + //bool cbgcurve; }; class RGBCurvesParamsEdited { @@ -118,6 +120,7 @@ class VibranceParamsEdited { bool protectskins; bool avoidcolorshift; bool pastsattog; + bool skintonescurve; }; /*class ColorBoostParamsEdited { @@ -126,7 +129,7 @@ class VibranceParamsEdited { bool amount; bool avoidclip; bool enable_saturationlimiter; - bool saturationlimit; + bool rstprotection; };*/ class WBParamsEdited { diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc index 45678b0ab..b4ae794d9 100644 --- a/rtgui/popupcommon.cc +++ b/rtgui/popupcommon.cc @@ -24,8 +24,6 @@ #include "../rtengine/safegtk.h" #include "rtimage.h" -extern Glib::ustring argv0; - PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) { button = thisButton; hasMenu = false; @@ -140,9 +138,9 @@ void PopUpCommon::show() { } void PopUpCommon::setButtonHint() { - Glib::ustring hint = buttonHint.size() ? buttonHint + " " + sItems.at(selected) : sItems.at(selected); + Glib::ustring hint = !buttonHint.empty() ? buttonHint + " " + sItems.at(selected) : sItems.at(selected); // if (hasMenu) hint += "\n(" + M("POPUPBUTTON_SELECTOPTIONHINT") + ")"; - button->set_tooltip_text(hint); + button->set_tooltip_markup(hint); } void PopUpCommon::showMenu(GdkEventButton* event) { diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index fa5125c0f..0dc3a2e9f 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -2,7 +2,7 @@ #define _PPVERSION_ // This number have to be incremented whenever the PP3 file format is modified -#define PPVERSION 302 +#define PPVERSION 303 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified #endif diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index 37b282938..3e507b482 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -165,7 +165,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () { mi->set_value (behavColumns.label, M("TP_LABCURVE_LABEL")); appendBehavList (mi, M("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false); appendBehavList (mi, M("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false); - appendBehavList (mi, M("TP_LABCURVE_SATURATION"), ADDSET_LC_SATURATION, false); + appendBehavList (mi, M("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false); mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_SHARPENING_LABEL")); diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc index 5c534228b..38950567c 100644 --- a/rtgui/rgbcurves.cc +++ b/rtgui/rgbcurves.cc @@ -24,13 +24,26 @@ using namespace rtengine::procparams; RGBCurves::RGBCurves () : Gtk::VBox(), FoldableToolPanel(this) { + std::vector milestones; + curveEditorG = new CurveEditorGroup (options.lastRgbCurvesDir, M("TP_RGBCURVES_CHANNEL")); curveEditorG->setCurveListener (this); - curveEditorG->setColorProvider (this); Rshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_RED"))); + milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) ); + milestones.push_back( GradientMilestone(1.0, 1.0, 0.0, 0.0) ); + Rshape->setBottomBarBgGradient(milestones); + Rshape->setLeftBarBgGradient(milestones); + + milestones[1].r = 0.0; milestones[1].g = 1.0; Gshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_GREEN"))); + Gshape->setBottomBarBgGradient(milestones); + Gshape->setLeftBarBgGradient(milestones); + + milestones[1].g = 0.0; milestones[1].b = 1.0; Bshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_BLUE"))); + Bshape->setBottomBarBgGradient(milestones); + Bshape->setLeftBarBgGradient(milestones); // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc index 76ecdafbd..70ae7bbfa 100644 --- a/rtgui/shcselector.cc +++ b/rtgui/shcselector.cc @@ -18,14 +18,34 @@ */ #include "shcselector.h" +#include "multilangmgr.h" #include #include "mycurve.h" -SHCSelector::SHCSelector() : movingPosition(-1), cl(NULL) { +SHCSelector::SHCSelector() : ColoredBar(RTO_Left2Right), movingPosition(-1), cl(NULL) { - positions[0] = 0.25; - positions[1] = 0.5; - positions[2] = 0.75; + positions[0] = defaults[0] = 0.25; + positions[1] = defaults[1] = 0.5; + positions[2] = defaults[2] = 0.75; + leftMargin = RADIUS; + rightMargin = RADIUS; + + // TODO: This is a hack :) ; change this name to a specific one and create a new entry in all gtkrc theme files + set_name("ThresholdSelector"); + set_can_focus(false); + set_size_request (-1, 12); + set_tooltip_text(M("SHCSELECTOR_TOOLTIP")); +} + +void SHCSelector::setMargins(int left, int right) { + leftMargin = left; + rightMargin = right; +} + +void SHCSelector::setDefaults (double spos, double cpos, double hpos) { + defaults[0] = spos; + defaults[1] = cpos; + defaults[2] = hpos; } void SHCSelector::setPositions (double spos, double cpos, double hpos) { @@ -53,46 +73,64 @@ void SHCSelector::on_realize() { bool SHCSelector::on_expose_event(GdkEventExpose* event) { + Gdk::Color c; Cairo::RefPtr cr = get_window()->create_cairo_context(); - int w = get_width () - RADIUS*2; + int w = get_width () - leftMargin - rightMargin; int h = get_height (); - wslider = h *2.0 / 5.0; + wslider = std::max(int(h / 5), 10); + double hwslider = double(wslider)/2.; - Gdk::Color bgc = get_style()->get_bg (Gtk::STATE_NORMAL); - Gdk::Color fgc = get_style()->get_text (Gtk::STATE_NORMAL); + Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; + Glib::RefPtr style = get_style(); // clear bg - cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); - cr->rectangle (0, 0, w, h); - cr->fill(); - // draw gradient background - Cairo::RefPtr< Cairo::LinearGradient > bggradient = Cairo::LinearGradient::create (0, 0, w, 0); - bggradient->add_color_stop_rgb (0, 0, 0, 0); - bggradient->add_color_stop_rgb (1, 1, 1, 1); + // set the box's colors + cr->set_line_width (1.0); + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + if (is_sensitive() && canGetColors()) { + // gradient background + Glib::RefPtr win = get_window(); + // this will eventually create/update the off-screen pixmap + setDrawRectangle(win, leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f)); + // that we're displaying here + ColoredBar::expose(win); + } + else { + // solid background + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); - cr->set_line_width (1.0); - cr->set_source (bggradient); - cr->rectangle (0.5+RADIUS, h*2.0/7.0 + 0.5, w-0.5, h*3.0/7.0-0.5); - cr->fill_preserve(); - cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); - cr->stroke (); + // draw the box's background + cr->rectangle (leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f)); + cr->fill(); + } + + // draw the box's borders + cr->set_line_width (1.); + cr->rectangle (leftMargin+0.5, 0.5, w-1, int(float(h)*5.5f/7.f+0.5f)+1); + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); // draw sliders - cr->set_line_width (1.0); + //cr->set_line_width (1.0); for (int i=0; i<3; i++) { - cr->move_to (RADIUS+w*positions[i]-wslider/2+0.5, h-0.5); - cr->line_to (RADIUS+w*positions[i]-wslider/2+0.5, wslider/2 + 0.5); - cr->line_to (RADIUS+w*positions[i], 0.5); - cr->line_to (RADIUS+w*positions[i]+wslider/2-0.5, wslider/2 + 0.5); - cr->line_to (RADIUS+w*positions[i]+wslider/2-0.5, h-0.5); - cr->line_to (RADIUS+w*positions[i]-wslider/2+0.5, h-0.5); - cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); - cr->fill_preserve (); - cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); - cr->stroke (); + cr->move_to (leftMargin+0.5+(w-1)*positions[i]+hwslider, double(h)-0.5); + cr->rel_line_to (0., double(-h/3)); + cr->rel_line_to (-hwslider, double(-h/3)); + cr->rel_line_to (-hwslider, double(h/3)); + cr->rel_line_to (0., double(h/3)); + cr->close_path(); + // normal + c = style->get_bg (is_sensitive() ? Gtk::STATE_ACTIVE : Gtk::STATE_INSENSITIVE); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill_preserve (); + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); } // draw text for the slider that is being moved @@ -104,21 +142,20 @@ bool SHCSelector::on_expose_event(GdkEventExpose* event) { int layout_width, layout_height; Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); layout->get_pixel_size(layout_width, layout_height); - offset = positions[i] > 0.5 ? -layout_width-1-wslider/2 : 1+wslider/2; - cr->move_to (RADIUS+w*positions[i]+offset-0.5, 0); - cr->set_source_rgb (bgc.get_red_p(), bgc.get_green_p(), bgc.get_blue_p()); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); - cr->move_to (RADIUS+w*positions[i]+offset+0.5, 1); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); - cr->set_source_rgb (fgc.get_red_p(), fgc.get_green_p(), fgc.get_blue_p()); - cr->move_to (RADIUS+w*positions[i]+offset, 0.5); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); + offset = positions[i] > 0.5 ? -layout_width-1-hwslider : 1+hwslider; + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + + cr->set_line_width(3.); + cr->set_line_join(Cairo::LINE_JOIN_ROUND); + cr->set_line_cap(Cairo::LINE_CAP_ROUND); + + cr->move_to (leftMargin+w*positions[i]+offset, 0.); + layout->add_to_cairo_context (cr); + cr->stroke_preserve(); + c = style->get_fg (Gtk::STATE_PRELIGHT); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill (); } return true; } @@ -126,10 +163,10 @@ bool SHCSelector::on_expose_event(GdkEventExpose* event) { bool SHCSelector::on_button_press_event (GdkEventButton* event) { // check if a slider is under the cursor - int w = get_width (); + double w = double(get_width ()-leftMargin-rightMargin); movingPosition = -1; for (int i=0; i<3; i++) - if (event->x > w*positions[i]-wslider/2 && event->x < w*positions[i]+wslider/2) { + if (event->x > double(leftMargin)+w*positions[i]-wslider/2. && event->x < double(leftMargin)+w*positions[i]+wslider/2) { movingPosition = i; tmpX = event->x; tmpPos = positions[i]; @@ -141,9 +178,21 @@ bool SHCSelector::on_button_press_event (GdkEventButton* event) { bool SHCSelector::on_button_release_event (GdkEventButton* event) { - if (movingPosition >= 0) { - movingPosition = -1; - queue_draw (); + if (event->button == 1) { + if (movingPosition >= 0) { + movingPosition = -1; + queue_draw (); + } + } + else if (event->button == 3) { + if (movingPosition >= 0) + movingPosition = -1; + // right mouse button reset the selector to the stored default values + if (reset()) { + // rest has modified the values + if (cl) + cl->shcChanged (); + } } return true; } @@ -174,9 +223,17 @@ void SHCSelector::styleChanged (const Glib::RefPtr& style) { queue_draw (); } -void SHCSelector::reset () { // : movingPosition(-1), cl(NULL) { - positions[0] = 0.25; - positions[1] = 0.5; - positions[2] = 0.75; - queue_draw (); +bool SHCSelector::reset () { // : movingPosition(-1), cl(NULL) { + if ( positions[0] != defaults[0] || + positions[1] != defaults[1] || + positions[2] != defaults[2] + ) { + + positions[0] = defaults[0]; + positions[1] = defaults[1]; + positions[2] = defaults[2]; + queue_draw (); + return true; + } + return false; } diff --git a/rtgui/shcselector.h b/rtgui/shcselector.h index 17e177a64..4c4b3057d 100644 --- a/rtgui/shcselector.h +++ b/rtgui/shcselector.h @@ -20,26 +20,34 @@ #define _SHCSELECTOR_ #include +#include "coloredbar.h" class SHCListener { public: + virtual ~SHCListener() {} virtual void shcChanged () {} }; -class SHCSelector : public Gtk::DrawingArea { +class SHCSelector : public Gtk::DrawingArea, public ColoredBar { protected: - Glib::RefPtr gc_; - Glib::RefPtr backBuffer; - int movingPosition; double tmpX, tmpPos; + double defaults[3]; double positions[3]; double wslider; - SHCListener* cl; + // left margin, essentially a workaround to take care of an eventual right colored bar (e.g. for curves) + int leftMargin; + // right margin, essentially a workaround to take care of an eventual right colored bar + int rightMargin; + + const static int hb = 3; // horizontal border + const static int vb = 2; // vertical border + + SHCListener* cl; public: @@ -47,6 +55,8 @@ class SHCSelector : public Gtk::DrawingArea { void setSHCListener (SHCListener* l) { cl = l;; } + void setMargins(int left, int right); + void setDefaults (double spos, double cpos, double hpos); void setPositions (double spos, double cpos, double hpos); void getPositions (double& spos, double& cpos, double& hpos); void on_realize(); @@ -55,7 +65,7 @@ class SHCSelector : public Gtk::DrawingArea { bool on_button_release_event (GdkEventButton* event); bool on_motion_notify_event (GdkEventMotion* event); void styleChanged (const Glib::RefPtr& style); - void reset (); + bool reset (); }; #endif diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc index ce04e90ff..9969cb015 100644 --- a/rtgui/thresholdselector.cc +++ b/rtgui/thresholdselector.cc @@ -24,7 +24,9 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, - ThresholdCurveProvider* curveProvider) { + ThresholdCurveProvider* curveProvider) + : ColoredBar(RTO_Left2Right) +{ positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = 0; // unused @@ -47,7 +49,10 @@ ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBotto initValues (); } -ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottom, double defTop, unsigned int precision, bool startAtOne) { +ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottom, + double defTop, unsigned int precision, bool startAtOne) + : ColoredBar(RTO_Left2Right) +{ positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = maxValue; @@ -83,7 +88,10 @@ ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double de } -ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft, double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne) { +ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft, + double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne) + : ColoredBar(RTO_Left2Right) +{ positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottomLeft; positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTopLeft; positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = defBottomRight; @@ -178,11 +186,6 @@ void ThresholdSelector::setDefaults (double bottomLeft, double topLeft, double b } } -void ThresholdSelector::setBgGradient (const std::vector &milestones) { - bgGradient.clear(); - bgGradient = milestones; -} - void ThresholdSelector::on_realize() { Gtk::DrawingArea::on_realize(); @@ -202,8 +205,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) { wslider = std::max(int(h / 5), 10); int hwslider = wslider/2; - - int iw = w-wslider-2*hb; // inner width (excluding padding for tabs) + int iw = w-wslider-2*hb; // inner width (excluding padding for sliders) positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT); positions01[TS_TOPLEFT] = to01(TS_TOPLEFT); @@ -216,19 +218,15 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) { // set the box's colors cr->set_line_width (1.0); cr->set_line_cap(Cairo::LINE_CAP_BUTT); - if (is_sensitive() && bgGradient.size()>1) { + if (is_sensitive() && canGetColors()) { // gradient background - Cairo::RefPtr< Cairo::LinearGradient > bggradient = Cairo::LinearGradient::create (hwslider, 0, hwslider+iw, 0); - for (std::vector::iterator i=bgGradient.begin(); i!=bgGradient.end(); i++) { - bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b); - } - cr->set_source (bggradient); - - // draw the box's background - cr->rectangle (hb+hwslider-0.5, double(int(float(h)*1.5f/7.f))+0.5, iw+1, double(int(float(h)*4.f/7.f))); - cr->fill(); + Glib::RefPtr win = get_window(); + // this will eventually create/update the off-screen Surface + setDrawRectangle(win, hb+hwslider, int(float(h)*1.5f/7.f+0.5f), iw+1, int(float(h)*4.f/7.f+0.5f)); + // that we're displaying here + ColoredBar::expose(win); } - else if (is_sensitive()) { + else { // solid background c = style->get_bg (state); cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); @@ -314,7 +312,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) { // draw sliders //if (!(litCursor == TS_UNDEFINED && movedCursor == TS_UNDEFINED)) { - cr->set_line_width (1.); + //cr->set_line_width (1.); for (int i=0; i<(doubleThresh?4:2); i++) { double posX = hb+hwslider+iw*positions01[i]+0.5; double arrowY = i==0 || i==2 ? h-(h*2.5/7.-0.5)-vb : h*2.5/7.-0.5+vb; @@ -357,35 +355,7 @@ bool ThresholdSelector::on_expose_event(GdkEventExpose* event) { } } //} - //printf("\n\n"); - // draw text for the slider that is being moved - /* - * Original code from shcselector.cc - * - Glib::RefPtr context = get_pango_context () ; - cr->set_line_width (0.5); - if (litCursor != TS_UNDEFINED) { - int offset; - int layout_width, layout_height; - Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions01[litCursor])); - layout->get_pixel_size(layout_width, layout_height); - offset = positions01[litCursor] > 0.5 ? -layout_width-1-wslider/2 : 1+wslider/2; - cr->move_to (w*positions01[litCursor]+offset-0.5, 0); - cr->set_source_rgb (bgnc.get_red_p(), bgnc.get_green_p(), bgnc.get_blue_p()); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); - cr->move_to (w*positions01[litCursor]+offset+0.5, 1); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); - cr->set_source_rgb (fgnc.get_red_p(), fgnc.get_green_p(), fgnc.get_blue_p()); - cr->move_to (w*positions01[litCursor]+offset, 0.5); - layout->add_to_cairo_context (cr); - cr->fill_preserve (); - cr->stroke (); - }*/ return true; } diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h index 482213e94..e17aca595 100644 --- a/rtgui/thresholdselector.h +++ b/rtgui/thresholdselector.h @@ -21,6 +21,7 @@ #include "guiutils.h" #include "../rtengine/procparams.h" +#include "coloredbar.h" #include class ThresholdSelector; @@ -30,6 +31,7 @@ class ThresholdSelector; */ class ThresholdCurveProvider { public: + virtual ~ThresholdCurveProvider() {}; /* * The curve provider has to send back a list of point (at least 2 points) in the [0.0 ; 1.0] range * for both X and Y axis; X and Y values are streamlined ( X1, Y1, X2, Y2, X3, Y3, ...) @@ -57,7 +59,7 @@ class ThresholdCurveProvider { * have to provide through the * */ -class ThresholdSelector : public Gtk::DrawingArea { +class ThresholdSelector : public Gtk::DrawingArea, public ColoredBar { public: @@ -74,9 +76,6 @@ class ThresholdSelector : public Gtk::DrawingArea { sigc::signal sig_val_changed; - Glib::RefPtr gc_; - Glib::RefPtr backBuffer; - std::vector bgGradient; ThresholdCurveProvider* bgCurveProvider; Glib::ustring additionalTTip; @@ -183,7 +182,6 @@ class ThresholdSelector : public Gtk::DrawingArea { void setSeparatedSliders(bool separated); bool getSeparatedSliders(); - void setBgGradient (const std::vector &milestones); void setBgCurveProvider (ThresholdCurveProvider* provider); bool isStartAtOne() { return initalEq1; } bool isDouble() { return doubleThresh; } diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc index 9f8ac8b07..b8f55ab09 100644 --- a/rtgui/tonecurve.cc +++ b/rtgui/tonecurve.cc @@ -27,6 +27,10 @@ using namespace rtengine::procparams; ToneCurve::ToneCurve () : Gtk::VBox(), FoldableToolPanel(this) { + std::vector bottomMilestones; + bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + //----------- Auto Levels ---------------------------------- abox = Gtk::manage (new Gtk::HBox ()); abox->set_border_width (2); @@ -89,6 +93,9 @@ ToneCurve::ToneCurve () : Gtk::VBox(), FoldableToolPanel(this) { curveEditorG->setCurveListener (this); shape = static_cast(curveEditorG->addCurve(CT_Diagonal, "")); + shape->setBottomBarBgGradient(bottomMilestones); + shape->setLeftBarBgGradient(bottomMilestones); + // This will add the reset button at the end of the curveType buttons curveEditorG->curveListComplete(); diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc index 0d3b05410..4c5ab0031 100644 --- a/rtgui/vibrance.cc +++ b/rtgui/vibrance.cc @@ -18,23 +18,33 @@ */ #include "vibrance.h" +#include "../rtengine/color.h" +#include using namespace rtengine; using namespace rtengine::procparams; Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) { + std::vector milestones; + float R, G, B; + // -0.1 rad < Hue < 1.6 rad + Color::hsv2rgb01(0.92f, 0.45f, 0.6f, R, G, B); + milestones.push_back( GradientMilestone(0.0, double(R), double(G), double(B)) ); + Color::hsv2rgb01(0.14056f, 0.45f, 0.6f, R, G, B); + milestones.push_back( GradientMilestone(1.0, double(R), double(G), double(B)) ); + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); enabled->set_active (false); pack_start(*enabled, Gtk::PACK_SHRINK, 0); - saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100,100,1,50)); + saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100.,100.,1.,0.)); saturated->setAdjusterListener (this); saturated->set_sensitive(false); //if (saturated->delay < 1000) saturated->delay = 1000; pack_start( *saturated, Gtk::PACK_SHRINK, 0); - pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100,100,1,50)); + pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100.,100.,1.,0.)); pastels->setAdjusterListener (this); //if (pastels->delay < 1000) pastels->delay = 1000; pack_start( *pastels, Gtk::PACK_SHRINK, 0); @@ -58,6 +68,22 @@ Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) { pastSatTog->set_active (true); pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0); + curveEditorGG = new CurveEditorGroup (options.lastVibranceCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL")); + curveEditorGG->setCurveListener (this); + + skinTonesCurve = static_cast(curveEditorGG->addCurve(CT_Diagonal, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES"))); + skinTonesCurve->setTooltip(M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP")); + skinTonesCurve->setBottomBarBgGradient(milestones); + skinTonesCurve->setLeftBarBgGradient(milestones); + skinTonesCurve->setRangeLabels( + M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2"), + M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4") + ); + skinTonesCurve->setRangeDefaultMilestones(0.1, 0.4, 0.85); + curveEditorGG->curveListComplete(); + + pack_start (*curveEditorGG, Gtk::PACK_SHRINK, 4); + show (); enaconn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::enabled_toggled) ); @@ -66,6 +92,10 @@ Vibrance::Vibrance () : Gtk::VBox(), FoldableToolPanel(this) { pastsattogconn = pastSatTog->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::pastsattog_toggled) ); } +Vibrance::~Vibrance () { + delete curveEditorGG; +} + void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) { disableListener (); @@ -76,7 +106,8 @@ void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) { psThreshold->setEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited); protectSkins->set_inconsistent (!pedited->vibrance.protectskins); avoidColorShift->set_inconsistent (!pedited->vibrance.avoidcolorshift); - pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog); + pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog); + skinTonesCurve->setUnChanged (!pedited->vibrance.skintonescurve); } enaconn.block (true); @@ -114,6 +145,8 @@ void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) { saturated->set_sensitive(true); saturated->setValue (pp->vibrance.saturated); // Pastels and Saturated are separate } + skinTonesCurve->setCurve (pp->vibrance.skintonescurve); + skinTonesCurve->openIfNonlinear(); enableListener (); } @@ -126,6 +159,7 @@ void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) { pp->vibrance.protectskins = protectSkins->get_active (); pp->vibrance.avoidcolorshift = avoidColorShift->get_active (); pp->vibrance.pastsattog = pastSatTog->get_active (); + pp->vibrance.skintonescurve = skinTonesCurve->getCurve (); if (pedited) { pedited->vibrance.enabled = !enabled->get_inconsistent(); @@ -135,9 +169,14 @@ void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) { pedited->vibrance.protectskins = !protectSkins->get_inconsistent(); pedited->vibrance.avoidcolorshift = !avoidColorShift->get_inconsistent(); pedited->vibrance.pastsattog = !pastSatTog->get_inconsistent(); + pedited->vibrance.skintonescurve = !skinTonesCurve->isUnChanged (); } } +void Vibrance::curveChanged () { + + if (listener && enabled->get_active()) listener->panelChanged (EvVibranceSkinTonesCurve, M("HISTORY_CUSTOMCURVE")); +} void Vibrance::enabled_toggled () { if (batchMode) { @@ -252,8 +291,6 @@ void Vibrance::adjusterChanged (Adjuster* a, double newval) { else if (a == saturated && !pastSatTog->get_active()) listener->panelChanged (EvVibranceSaturated, value ); } - if (pastSatTog->get_active()) - psThreshold->queue_draw(); } void Vibrance::adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop) { @@ -270,6 +307,8 @@ void Vibrance::setBatchMode(bool batchMode) { pastels->showEditedCB (); saturated->showEditedCB (); psThreshold->showEditedCB (); + + curveEditorGG->setBatchMode (batchMode); } void Vibrance::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { @@ -294,6 +333,20 @@ void Vibrance::setAdjusterBehavior (bool pastelsadd, bool saturatedadd, bool pst saturated->setAddMode (saturatedadd); } +void Vibrance::colorForValue (double valX, double valY) { + CurveEditor* ce = curveEditorGG->getDisplayedCurve(); + + if (ce == skinTonesCurve) { // L = f(L) + red = double(valY); + green = double(valY); + blue = double(valY); + } + else { + printf("Error: no curve displayed!\n"); + } +} + + void Vibrance::trimValues (ProcParams* pp) { pastels->trimValue (pp->vibrance.pastels); saturated->trimValue (pp->vibrance.saturated); diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h index a53599f89..7aba484f7 100644 --- a/rtgui/vibrance.h +++ b/rtgui/vibrance.h @@ -22,11 +22,17 @@ #include #include "adjuster.h" #include "thresholdadjuster.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" #include "toolpanel.h" -class Vibrance : public Gtk::VBox, public AdjusterListener, public ThresholdAdjusterListener, public FoldableToolPanel, public ThresholdCurveProvider { +class Vibrance : public Gtk::VBox, public AdjusterListener, public ThresholdCurveProvider, public ThresholdAdjusterListener, + public FoldableToolPanel, public CurveListener, public ColorProvider +{ protected: + CurveEditorGroup* curveEditorGG; + Gtk::CheckButton* enabled; Adjuster* pastels; Adjuster* saturated; @@ -34,7 +40,9 @@ protected: Gtk::CheckButton* protectSkins; Gtk::CheckButton* avoidColorShift; Gtk::CheckButton* pastSatTog; - bool lastEnabled; + DiagonalCurveEditor* skinTonesCurve; + + bool lastEnabled; bool lastProtectSkins; bool lastAvoidColorShift; bool lastPastSatTog; @@ -47,6 +55,7 @@ protected: public: Vibrance (); + ~Vibrance (); void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); @@ -56,12 +65,14 @@ public: void setAdjusterBehavior (bool amountadd, bool passadd, bool psthreshdadd); void adjusterChanged (Adjuster* a, double newval); void adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop); + void curveChanged (); void enabled_toggled (); void protectskins_toggled (); void avoidcolorshift_toggled (); void pastsattog_toggled (); std::vector getCurvePoints(ThresholdSelector* tAdjuster) const; + virtual void colorForValue (double valX, double valY); };